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) 2013 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. #include "util/u_format.h"
  34.  
  35. #include "freedreno_state.h"
  36. #include "freedreno_resource.h"
  37.  
  38. #include "fd3_draw.h"
  39. #include "fd3_context.h"
  40. #include "fd3_emit.h"
  41. #include "fd3_program.h"
  42. #include "fd3_format.h"
  43. #include "fd3_zsa.h"
  44.  
  45. static inline uint32_t
  46. add_sat(uint32_t a, int32_t b)
  47. {
  48.         int64_t ret = (uint64_t)a + (int64_t)b;
  49.         if (ret > ~0U)
  50.                 return ~0U;
  51.         if (ret < 0)
  52.                 return 0;
  53.         return (uint32_t)ret;
  54. }
  55.  
  56. static void
  57. draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
  58.                 struct fd3_emit *emit)
  59. {
  60.         const struct pipe_draw_info *info = emit->info;
  61.         enum pc_di_primtype primtype = ctx->primtypes[info->mode];
  62.  
  63.         fd3_emit_state(ctx, ring, emit);
  64.  
  65.         if (emit->dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
  66.                 fd3_emit_vertex_bufs(ring, emit);
  67.  
  68.         OUT_PKT0(ring, REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL, 1);
  69.         OUT_RING(ring, 0x0000000b);             /* PC_VERTEX_REUSE_BLOCK_CNTL */
  70.  
  71.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  72.         OUT_RING(ring, add_sat(info->min_index, info->index_bias)); /* VFD_INDEX_MIN */
  73.         OUT_RING(ring, add_sat(info->max_index, info->index_bias)); /* VFD_INDEX_MAX */
  74.         OUT_RING(ring, info->start_instance);   /* VFD_INSTANCEID_OFFSET */
  75.         OUT_RING(ring, info->indexed ? info->index_bias : info->start); /* VFD_INDEX_OFFSET */
  76.  
  77.         OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
  78.         OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
  79.                         info->restart_index : 0xffffffff);
  80.  
  81.         if (ctx->rasterizer && ctx->rasterizer->point_size_per_vertex &&
  82.                 info->mode == PIPE_PRIM_POINTS)
  83.                 primtype = DI_PT_POINTLIST_A2XX;
  84.  
  85.         fd_draw_emit(ctx, ring,
  86.                         primtype,
  87.                         emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
  88.                         info);
  89. }
  90.  
  91. /* fixup dirty shader state in case some "unrelated" (from the state-
  92.  * tracker's perspective) state change causes us to switch to a
  93.  * different variant.
  94.  */
  95. static void
  96. fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
  97. {
  98.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  99.         struct ir3_shader_key *last_key = &fd3_ctx->last_key;
  100.  
  101.         if (!ir3_shader_key_equal(last_key, key)) {
  102.                 ctx->dirty |= FD_DIRTY_PROG;
  103.  
  104.                 if (last_key->has_per_samp || key->has_per_samp) {
  105.                         if ((last_key->vsaturate_s != key->vsaturate_s) ||
  106.                                         (last_key->vsaturate_t != key->vsaturate_t) ||
  107.                                         (last_key->vsaturate_r != key->vsaturate_r) ||
  108.                                         (last_key->vinteger_s != key->vinteger_s))
  109.                                 ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
  110.  
  111.                         if ((last_key->fsaturate_s != key->fsaturate_s) ||
  112.                                         (last_key->fsaturate_t != key->fsaturate_t) ||
  113.                                         (last_key->fsaturate_r != key->fsaturate_r) ||
  114.                                         (last_key->finteger_s != key->finteger_s))
  115.                                 ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
  116.                 }
  117.  
  118.                 if (last_key->color_two_side != key->color_two_side)
  119.                         ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
  120.  
  121.                 if (last_key->half_precision != key->half_precision)
  122.                         ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
  123.  
  124.                 fd3_ctx->last_key = *key;
  125.         }
  126. }
  127.  
  128. static void
  129. fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
  130. {
  131.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  132.         struct fd3_emit emit = {
  133.                 .vtx  = &ctx->vtx,
  134.                 .prog = &ctx->prog,
  135.                 .info = info,
  136.                 .key = {
  137.                         /* do binning pass first: */
  138.                         .binning_pass = true,
  139.                         .color_two_side = ctx->rasterizer ? ctx->rasterizer->light_twoside : false,
  140.                         // TODO set .half_precision based on render target format,
  141.                         // ie. float16 and smaller use half, float32 use full..
  142.                         .half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
  143.                         .has_per_samp = (fd3_ctx->fsaturate || fd3_ctx->vsaturate ||
  144.                                                          fd3_ctx->vinteger_s || fd3_ctx->finteger_s),
  145.                         .vsaturate_s = fd3_ctx->vsaturate_s,
  146.                         .vsaturate_t = fd3_ctx->vsaturate_t,
  147.                         .vsaturate_r = fd3_ctx->vsaturate_r,
  148.                         .fsaturate_s = fd3_ctx->fsaturate_s,
  149.                         .fsaturate_t = fd3_ctx->fsaturate_t,
  150.                         .fsaturate_r = fd3_ctx->fsaturate_r,
  151.                         .vinteger_s = fd3_ctx->vinteger_s,
  152.                         .finteger_s = fd3_ctx->finteger_s,
  153.                 },
  154.                 .rasterflat = ctx->rasterizer && ctx->rasterizer->flatshade,
  155.                 .sprite_coord_enable = ctx->rasterizer ? ctx->rasterizer->sprite_coord_enable : 0,
  156.                 .sprite_coord_mode = ctx->rasterizer ? ctx->rasterizer->sprite_coord_mode : false,
  157.         };
  158.         unsigned dirty;
  159.  
  160.         fixup_shader_state(ctx, &emit.key);
  161.  
  162.         dirty = ctx->dirty;
  163.         emit.dirty = dirty & ~(FD_DIRTY_BLEND);
  164.         draw_impl(ctx, ctx->binning_ring, &emit);
  165.  
  166.         /* and now regular (non-binning) pass: */
  167.         emit.key.binning_pass = false;
  168.         emit.dirty = dirty;
  169.         emit.vp = NULL;   /* we changed key so need to refetch vp */
  170.         draw_impl(ctx, ctx->ring, &emit);
  171. }
  172.  
  173. /* clear operations ignore viewport state, so we need to reset it
  174.  * based on framebuffer state:
  175.  */
  176. static void
  177. reset_viewport(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb)
  178. {
  179.         float half_width = pfb->width * 0.5f;
  180.         float half_height = pfb->height * 0.5f;
  181.  
  182.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 4);
  183.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET(half_width - 0.5));
  184.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE(half_width));
  185.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET(half_height - 0.5));
  186.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-half_height));
  187. }
  188.  
  189. /* binning pass cmds for a clear:
  190.  * NOTE: newer blob drivers don't use binning for clear, which is probably
  191.  * preferable since it is low vtx count.  However that doesn't seem to
  192.  * actually work for me.  Not sure if it is depending on support for
  193.  * clear pass (rather than using solid-fill shader), or something else
  194.  * that newer blob is doing differently.  Once that is figured out, we
  195.  * can remove fd3_clear_binning().
  196.  */
  197. static void
  198. fd3_clear_binning(struct fd_context *ctx, unsigned dirty)
  199. {
  200.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  201.         struct fd_ringbuffer *ring = ctx->binning_ring;
  202.         struct fd3_emit emit = {
  203.                 .vtx  = &fd3_ctx->solid_vbuf_state,
  204.                 .prog = &ctx->solid_prog,
  205.                 .key = {
  206.                         .binning_pass = true,
  207.                         .half_precision = true,
  208.                 },
  209.                 .dirty = dirty,
  210.         };
  211.  
  212.         fd3_emit_state(ctx, ring, &emit);
  213.         fd3_emit_vertex_bufs(ring, &emit);
  214.         reset_viewport(ring, &ctx->framebuffer);
  215.  
  216.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  217.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
  218.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  219.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  220.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  221.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  222.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  223.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  224.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  225.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  226.         OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
  227.         OUT_RING(ring, 0xffffffff);   /* PC_RESTART_INDEX */
  228.  
  229.         fd_event_write(ctx, ring, PERFCOUNTER_STOP);
  230.  
  231.         fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
  232.                         DI_SRC_SEL_AUTO_INDEX, 2, 0, INDEX_SIZE_IGN, 0, 0, NULL);
  233. }
  234.  
  235. static void
  236. fd3_clear(struct fd_context *ctx, unsigned buffers,
  237.                 const union pipe_color_union *color, double depth, unsigned stencil)
  238. {
  239.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  240.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  241.         struct fd_ringbuffer *ring = ctx->ring;
  242.         unsigned dirty = ctx->dirty;
  243.         unsigned i;
  244.         struct fd3_emit emit = {
  245.                 .vtx  = &fd3_ctx->solid_vbuf_state,
  246.                 .prog = &ctx->solid_prog,
  247.                 .key = {
  248.                         .half_precision = (fd3_half_precision(pfb->cbufs[0]) &&
  249.                                                            fd3_half_precision(pfb->cbufs[1]) &&
  250.                                                            fd3_half_precision(pfb->cbufs[2]) &&
  251.                                                            fd3_half_precision(pfb->cbufs[3])),
  252.                 },
  253.         };
  254.  
  255.         dirty &= FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
  256.         dirty |= FD_DIRTY_PROG;
  257.         emit.dirty = dirty;
  258.  
  259.         fd3_clear_binning(ctx, dirty);
  260.  
  261.         /* emit generic state now: */
  262.         fd3_emit_state(ctx, ring, &emit);
  263.         reset_viewport(ring, &ctx->framebuffer);
  264.  
  265.         OUT_PKT0(ring, REG_A3XX_RB_BLEND_ALPHA, 1);
  266.         OUT_RING(ring, A3XX_RB_BLEND_ALPHA_UINT(0xff) |
  267.                         A3XX_RB_BLEND_ALPHA_FLOAT(1.0));
  268.  
  269.         OUT_PKT0(ring, REG_A3XX_RB_RENDER_CONTROL, 1);
  270.         OUT_RINGP(ring, A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER),
  271.                         &fd3_ctx->rbrc_patches);
  272.  
  273.         if (buffers & PIPE_CLEAR_DEPTH) {
  274.                 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  275.                 OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE |
  276.                                 A3XX_RB_DEPTH_CONTROL_Z_ENABLE |
  277.                                 A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_ALWAYS));
  278.  
  279.                 fd_wfi(ctx, ring);
  280.                 OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_ZOFFSET, 2);
  281.                 OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  282.                 OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(depth));
  283.                 ctx->dirty |= FD_DIRTY_VIEWPORT;
  284.         } else {
  285.                 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  286.                 OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
  287.         }
  288.  
  289.         if (buffers & PIPE_CLEAR_STENCIL) {
  290.                 OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2);
  291.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_STENCILREF(stencil) |
  292.                                 A3XX_RB_STENCILREFMASK_STENCILMASK(stencil) |
  293.                                 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  294.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  295.                                 A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  296.                                 0xff000000 | // XXX ???
  297.                                 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  298.  
  299.                 OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  300.                 OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
  301.                                 A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
  302.                                 A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  303.                                 A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_REPLACE) |
  304.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  305.                                 A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  306.                                 A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  307.                                 A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  308.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  309.         } else {
  310.                 OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2);
  311.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  312.                                 A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  313.                                 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0));
  314.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_BF_STENCILREF(0) |
  315.                                 A3XX_RB_STENCILREFMASK_BF_STENCILMASK(0) |
  316.                                 A3XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0));
  317.  
  318.                 OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  319.                 OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
  320.                                 A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  321.                                 A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  322.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  323.                                 A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  324.                                 A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  325.                                 A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  326.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  327.         }
  328.  
  329.         for (i = 0; i < 4; i++) {
  330.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
  331.                 OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY) |
  332.                                 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_ALWAYS) |
  333.                                 COND(buffers & (PIPE_CLEAR_COLOR0 << i),
  334.                                          A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf)));
  335.  
  336.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1);
  337.                 OUT_RING(ring, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
  338.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  339.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
  340.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
  341.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  342.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO));
  343.         }
  344.  
  345.         OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
  346.         OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
  347.  
  348.         fd3_emit_vertex_bufs(ring, &emit);
  349.  
  350.         fd3_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);
  351.  
  352.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  353.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
  354.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  355.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  356.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  357.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  358.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  359.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  360.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  361.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  362.         OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
  363.         OUT_RING(ring, 0xffffffff);   /* PC_RESTART_INDEX */
  364.  
  365.         fd_event_write(ctx, ring, PERFCOUNTER_STOP);
  366.  
  367.         fd_draw(ctx, ring, DI_PT_RECTLIST, USE_VISIBILITY,
  368.                         DI_SRC_SEL_AUTO_INDEX, 2, 0, INDEX_SIZE_IGN, 0, 0, NULL);
  369. }
  370.  
  371. void
  372. fd3_draw_init(struct pipe_context *pctx)
  373. {
  374.         struct fd_context *ctx = fd_context(pctx);
  375.         ctx->draw_vbo = fd3_draw_vbo;
  376.         ctx->clear = fd3_clear;
  377. }
  378.