Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
  2.  
  3. /*
  4.  * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23.  * SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Rob Clark <robclark@freedesktop.org>
  27.  */
  28.  
  29. #include "pipe/p_state.h"
  30. #include "util/u_string.h"
  31. #include "util/u_memory.h"
  32. #include "util/u_prim.h"
  33.  
  34. #include "freedreno_state.h"
  35. #include "freedreno_resource.h"
  36.  
  37. #include "fd4_draw.h"
  38. #include "fd4_context.h"
  39. #include "fd4_emit.h"
  40. #include "fd4_program.h"
  41. #include "fd4_format.h"
  42. #include "fd4_zsa.h"
  43.  
  44.  
  45. static void
  46. draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
  47.                 struct fd4_emit *emit)
  48. {
  49.         const struct pipe_draw_info *info = emit->info;
  50.  
  51.         fd4_emit_state(ctx, ring, emit);
  52.  
  53.         if (emit->dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
  54.                 fd4_emit_vertex_bufs(ring, emit);
  55.  
  56.         OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
  57.         OUT_RING(ring, info->indexed ? info->index_bias : info->start); /* VFD_INDEX_OFFSET */
  58.         OUT_RING(ring, info->start_instance);   /* ??? UNKNOWN_2209 */
  59.  
  60.         OUT_PKT0(ring, REG_A4XX_PC_RESTART_INDEX, 1);
  61.         OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
  62.                         info->restart_index : 0xffffffff);
  63.  
  64.         fd4_draw_emit(ctx, ring,
  65.                         emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
  66.                         info);
  67. }
  68.  
  69. /* fixup dirty shader state in case some "unrelated" (from the state-
  70.  * tracker's perspective) state change causes us to switch to a
  71.  * different variant.
  72.  */
  73. static void
  74. fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
  75. {
  76.         struct fd4_context *fd4_ctx = fd4_context(ctx);
  77.         struct ir3_shader_key *last_key = &fd4_ctx->last_key;
  78.  
  79.         if (!ir3_shader_key_equal(last_key, key)) {
  80.                 ctx->dirty |= FD_DIRTY_PROG;
  81.  
  82.                 if (last_key->has_per_samp || key->has_per_samp) {
  83.                         if ((last_key->vsaturate_s != key->vsaturate_s) ||
  84.                                         (last_key->vsaturate_t != key->vsaturate_t) ||
  85.                                         (last_key->vsaturate_r != key->vsaturate_r) ||
  86.                                         (last_key->vinteger_s != key->vinteger_s))
  87.                                 ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
  88.  
  89.                         if ((last_key->fsaturate_s != key->fsaturate_s) ||
  90.                                         (last_key->fsaturate_t != key->fsaturate_t) ||
  91.                                         (last_key->fsaturate_r != key->fsaturate_r))
  92.                                 ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
  93.                 }
  94.  
  95.                 if (last_key->color_two_side != key->color_two_side)
  96.                         ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
  97.  
  98.                 if (last_key->half_precision != key->half_precision)
  99.                         ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
  100.  
  101.                 if (last_key->rasterflat != key->rasterflat)
  102.                         ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
  103.  
  104.                 fd4_ctx->last_key = *key;
  105.         }
  106. }
  107.  
  108. static void
  109. fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
  110. {
  111.         struct fd4_context *fd4_ctx = fd4_context(ctx);
  112.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  113.         struct fd4_emit emit = {
  114.                 .vtx  = &ctx->vtx,
  115.                 .prog = &ctx->prog,
  116.                 .info = info,
  117.                 .key = {
  118.                         /* do binning pass first: */
  119.                         .binning_pass = true,
  120.                         .color_two_side = ctx->rasterizer ? ctx->rasterizer->light_twoside : false,
  121.                         .rasterflat = ctx->rasterizer && ctx->rasterizer->flatshade,
  122.                         // TODO set .half_precision based on render target format,
  123.                         // ie. float16 and smaller use half, float32 use full..
  124.                         .half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
  125.                         .has_per_samp = (fd4_ctx->fsaturate || fd4_ctx->vsaturate ||
  126.                                         fd4_ctx->vinteger_s || fd4_ctx->finteger_s),
  127.                         .vsaturate_s = fd4_ctx->vsaturate_s,
  128.                         .vsaturate_t = fd4_ctx->vsaturate_t,
  129.                         .vsaturate_r = fd4_ctx->vsaturate_r,
  130.                         .fsaturate_s = fd4_ctx->fsaturate_s,
  131.                         .fsaturate_t = fd4_ctx->fsaturate_t,
  132.                         .fsaturate_r = fd4_ctx->fsaturate_r,
  133.                         .vinteger_s = fd4_ctx->vinteger_s,
  134.                         .finteger_s = fd4_ctx->finteger_s,
  135.                 },
  136.                 .format = fd4_emit_format(pfb->cbufs[0]),
  137.                 .pformat = pipe_surface_format(pfb->cbufs[0]),
  138.         };
  139.         unsigned dirty;
  140.  
  141.         fixup_shader_state(ctx, &emit.key);
  142.  
  143.         dirty = ctx->dirty;
  144.         emit.dirty = dirty & ~(FD_DIRTY_BLEND);
  145.         draw_impl(ctx, ctx->binning_ring, &emit);
  146.  
  147.         /* and now regular (non-binning) pass: */
  148.         emit.key.binning_pass = false;
  149.         emit.dirty = dirty;
  150.         emit.vp = NULL;   /* we changed key so need to refetch vp */
  151.         draw_impl(ctx, ctx->ring, &emit);
  152. }
  153.  
  154. /* clear operations ignore viewport state, so we need to reset it
  155.  * based on framebuffer state:
  156.  */
  157. static void
  158. reset_viewport(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb)
  159. {
  160.         float half_width = pfb->width * 0.5f;
  161.         float half_height = pfb->height * 0.5f;
  162.  
  163.         OUT_PKT0(ring, REG_A4XX_GRAS_CL_VPORT_XOFFSET_0, 4);
  164.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_XOFFSET_0(half_width));
  165.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_XSCALE_0(half_width));
  166.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_YOFFSET_0(half_height));
  167.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_YSCALE_0(-half_height));
  168. }
  169.  
  170. static void
  171. fd4_clear(struct fd_context *ctx, unsigned buffers,
  172.                 const union pipe_color_union *color, double depth, unsigned stencil)
  173. {
  174.         struct fd4_context *fd4_ctx = fd4_context(ctx);
  175.         struct fd_ringbuffer *ring = ctx->ring;
  176.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  177.         unsigned dirty = ctx->dirty;
  178.         unsigned ce, i;
  179.         struct fd4_emit emit = {
  180.                 .vtx  = &fd4_ctx->solid_vbuf_state,
  181.                 .prog = &ctx->solid_prog,
  182.                 .key = {
  183.                         .half_precision = true,
  184.                 },
  185.                 .format = fd4_emit_format(pfb->cbufs[0]),
  186.         };
  187.         uint32_t colr = 0;
  188.  
  189.         if ((buffers & PIPE_CLEAR_COLOR) && pfb->nr_cbufs)
  190.                 colr  = pack_rgba(pfb->cbufs[0]->format, color->f);
  191.  
  192.         dirty &= FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
  193.         dirty |= FD_DIRTY_PROG;
  194.         emit.dirty = dirty;
  195.  
  196.         OUT_PKT0(ring, REG_A4XX_PC_PRIM_VTX_CNTL, 1);
  197.         OUT_RING(ring, A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  198.  
  199.         /* emit generic state now: */
  200.         fd4_emit_state(ctx, ring, &emit);
  201.         reset_viewport(ring, pfb);
  202.  
  203.         if (buffers & PIPE_CLEAR_DEPTH) {
  204.                 OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1);
  205.                 OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE |
  206.                                 A4XX_RB_DEPTH_CONTROL_Z_ENABLE |
  207.                                 A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_ALWAYS));
  208.  
  209.                 fd_wfi(ctx, ring);
  210.                 OUT_PKT0(ring, REG_A4XX_GRAS_CL_VPORT_ZOFFSET_0, 2);
  211.                 OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZOFFSET_0(0.0));
  212.                 OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(depth));
  213.                 ctx->dirty |= FD_DIRTY_VIEWPORT;
  214.         } else {
  215.                 OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1);
  216.                 OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
  217.         }
  218.  
  219.         if (buffers & PIPE_CLEAR_STENCIL) {
  220.                 OUT_PKT0(ring, REG_A4XX_RB_STENCILREFMASK, 2);
  221.                 OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(stencil) |
  222.                                 A4XX_RB_STENCILREFMASK_STENCILMASK(stencil) |
  223.                                 A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  224.                 OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(0) |
  225.                                 A4XX_RB_STENCILREFMASK_STENCILMASK(0) |
  226.                                 0xff000000 | // XXX ???
  227.                                 A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  228.  
  229.                 OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2);
  230.                 OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
  231.                                 A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
  232.                                 A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  233.                                 A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_REPLACE) |
  234.                                 A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  235.                                 A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  236.                                 A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  237.                                 A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  238.                                 A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  239.                 OUT_RING(ring, A4XX_RB_STENCIL_CONTROL2_STENCIL_BUFFER);
  240.         } else {
  241.                 OUT_PKT0(ring, REG_A4XX_RB_STENCILREFMASK, 2);
  242.                 OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(0) |
  243.                                 A4XX_RB_STENCILREFMASK_STENCILMASK(0) |
  244.                                 A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0));
  245.                 OUT_RING(ring, A4XX_RB_STENCILREFMASK_BF_STENCILREF(0) |
  246.                                 A4XX_RB_STENCILREFMASK_BF_STENCILMASK(0) |
  247.                                 A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0));
  248.  
  249.                 OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2);
  250.                 OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
  251.                                 A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  252.                                 A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  253.                                 A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  254.                                 A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  255.                                 A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  256.                                 A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  257.                                 A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  258.                 OUT_RING(ring, 0x00000000); /* RB_STENCIL_CONTROL2 */
  259.         }
  260.  
  261.         if (buffers & PIPE_CLEAR_COLOR) {
  262.                 OUT_PKT0(ring, REG_A4XX_RB_ALPHA_CONTROL, 1);
  263.                 OUT_RING(ring, A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER));
  264.                 ce = 0xf;
  265.         } else {
  266.                 ce = 0x0;
  267.         }
  268.  
  269.         for (i = 0; i < 8; i++) {
  270.                 OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1);
  271.                 OUT_RING(ring, A4XX_RB_MRT_CONTROL_FASTCLEAR |
  272.                                 A4XX_RB_MRT_CONTROL_B11 |
  273.                                 A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(ce));
  274.  
  275.                 OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1);
  276.                 OUT_RING(ring, A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
  277.                                 A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  278.                                 A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
  279.                                 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
  280.                                 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  281.                                 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO));
  282.         }
  283.  
  284.         fd4_emit_vertex_bufs(ring, &emit);
  285.  
  286.         OUT_PKT0(ring, REG_A4XX_GRAS_ALPHA_CONTROL, 1);
  287.         OUT_RING(ring, 0x0);          /* XXX GRAS_ALPHA_CONTROL */
  288.  
  289.         OUT_PKT0(ring, REG_A4XX_GRAS_CLEAR_CNTL, 1);
  290.         OUT_RING(ring, 0x00000000);
  291.  
  292.         OUT_PKT0(ring, REG_A4XX_RB_CLEAR_COLOR_DW0, 4);
  293.         OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW0 */
  294.         OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW1 */
  295.         OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW2 */
  296.         OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW3 */
  297.  
  298.         /* until fastclear works: */
  299.         fd4_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);
  300.  
  301.         OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
  302.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  303.         OUT_RING(ring, 0);            /* ??? UNKNOWN_2209 */
  304.  
  305.         OUT_PKT0(ring, REG_A4XX_PC_RESTART_INDEX, 1);
  306.         OUT_RING(ring, 0xffffffff);   /* PC_RESTART_INDEX */
  307.  
  308.         OUT_PKT3(ring, CP_UNKNOWN_1A, 1);
  309.         OUT_RING(ring, 0x00000001);
  310.  
  311.         fd4_draw(ctx, ring, DI_PT_RECTLIST, USE_VISIBILITY,
  312.                         DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX_SIZE_IGN, 0, 0, NULL);
  313.  
  314.         OUT_PKT3(ring, CP_UNKNOWN_1A, 1);
  315.         OUT_RING(ring, 0x00000000);
  316.  
  317.         OUT_PKT0(ring, REG_A4XX_GRAS_CLEAR_CNTL, 1);
  318.         OUT_RING(ring, A4XX_GRAS_CLEAR_CNTL_NOT_FASTCLEAR);
  319.  
  320.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1);
  321.         OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  322.                         A4XX_GRAS_SC_CONTROL_MSAA_DISABLE |
  323.                         A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  324.                         A4XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  325. }
  326.  
  327. void
  328. fd4_draw_init(struct pipe_context *pctx)
  329. {
  330.         struct fd_context *ctx = fd_context(pctx);
  331.         ctx->draw_vbo = fd4_draw_vbo;
  332.         ctx->clear = fd4_clear;
  333. }
  334.