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_inlines.h"
  33. #include "util/u_format.h"
  34.  
  35. #include "freedreno_draw.h"
  36. #include "freedreno_state.h"
  37. #include "freedreno_resource.h"
  38.  
  39. #include "fd3_gmem.h"
  40. #include "fd3_context.h"
  41. #include "fd3_emit.h"
  42. #include "fd3_program.h"
  43. #include "fd3_format.h"
  44. #include "fd3_zsa.h"
  45.  
  46. static void
  47. emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
  48.                  struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w,
  49.                  bool decode_srgb)
  50. {
  51.         enum a3xx_tile_mode tile_mode;
  52.         unsigned i;
  53.  
  54.         if (bin_w) {
  55.                 tile_mode = TILE_32X32;
  56.         } else {
  57.                 tile_mode = LINEAR;
  58.         }
  59.  
  60.         for (i = 0; i < 4; i++) {
  61.                 enum pipe_format pformat = 0;
  62.                 enum a3xx_color_fmt format = 0;
  63.                 enum a3xx_color_swap swap = WZYX;
  64.                 bool srgb = false;
  65.                 struct fd_resource *rsc = NULL;
  66.                 struct fd_resource_slice *slice = NULL;
  67.                 uint32_t stride = 0;
  68.                 uint32_t base = 0;
  69.                 uint32_t offset = 0;
  70.  
  71.                 if ((i < nr_bufs) && bufs[i]) {
  72.                         struct pipe_surface *psurf = bufs[i];
  73.  
  74.                         rsc = fd_resource(psurf->texture);
  75.                         pformat = psurf->format;
  76.                         /* In case we're drawing to Z32F_S8, the "color" actually goes to
  77.                          * the stencil
  78.                          */
  79.                         if (rsc->stencil) {
  80.                                 rsc = rsc->stencil;
  81.                                 pformat = rsc->base.b.format;
  82.                                 bases++;
  83.                         }
  84.                         slice = fd_resource_slice(rsc, psurf->u.tex.level);
  85.                         format = fd3_pipe2color(pformat);
  86.                         swap = fd3_pipe2swap(pformat);
  87.                         if (decode_srgb)
  88.                                 srgb = util_format_is_srgb(pformat);
  89.                         else
  90.                                 pformat = util_format_linear(pformat);
  91.  
  92.                         debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
  93.  
  94.                         offset = fd_resource_offset(rsc, psurf->u.tex.level,
  95.                                         psurf->u.tex.first_layer);
  96.  
  97.                         if (bin_w) {
  98.                                 stride = bin_w * rsc->cpp;
  99.  
  100.                                 if (bases) {
  101.                                         base = bases[i];
  102.                                 }
  103.                         } else {
  104.                                 stride = slice->pitch * rsc->cpp;
  105.                         }
  106.                 } else if (i < nr_bufs && bases) {
  107.                         base = bases[i];
  108.                 }
  109.  
  110.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_BUF_INFO(i), 2);
  111.                 OUT_RING(ring, A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
  112.                                 A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
  113.                                 A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) |
  114.                                 A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap) |
  115.                                 COND(srgb, A3XX_RB_MRT_BUF_INFO_COLOR_SRGB));
  116.                 if (bin_w || (i >= nr_bufs) || !bufs[i]) {
  117.                         OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base));
  118.                 } else {
  119.                         OUT_RELOCW(ring, rsc->bo, offset, 0, -1);
  120.                 }
  121.  
  122.                 OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1);
  123.                 OUT_RING(ring, COND((i < nr_bufs) && bufs[i],
  124.                                                         A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT(
  125.                                                                         fd3_fs_output_format(pformat))));
  126.         }
  127. }
  128.  
  129. static bool
  130. use_hw_binning(struct fd_context *ctx)
  131. {
  132.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  133.  
  134.         /* workaround: combining scissor optimization and hw binning
  135.          * seems problematic.  Seems like we end up with a mismatch
  136.          * between binning pass and rendering pass, wrt. where the hw
  137.          * thinks the vertices belong.  And the blob driver doesn't
  138.          * seem to implement anything like scissor optimization, so
  139.          * not entirely sure what I might be missing.
  140.          *
  141.          * But scissor optimization is mainly for window managers,
  142.          * which don't have many vertices (and therefore doesn't
  143.          * benefit much from binning pass).
  144.          *
  145.          * So for now just disable binning if scissor optimization is
  146.          * used.
  147.          */
  148.         if (gmem->minx || gmem->miny)
  149.                 return false;
  150.  
  151.         return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) > 2);
  152. }
  153.  
  154. /* workaround for (hlsq?) lockup with hw binning on a3xx patchlevel 0 */
  155. static void update_vsc_pipe(struct fd_context *ctx);
  156. static void
  157. emit_binning_workaround(struct fd_context *ctx)
  158. {
  159.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  160.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  161.         struct fd_ringbuffer *ring = ctx->ring;
  162.         struct fd3_emit emit = {
  163.                         .vtx = &fd3_ctx->solid_vbuf_state,
  164.                         .prog = &ctx->solid_prog,
  165.                         .key = {
  166.                                 .half_precision = true,
  167.                         },
  168.         };
  169.  
  170.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 2);
  171.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  172.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  173.                         A3XX_RB_MODE_CONTROL_MRT(0));
  174.         OUT_RING(ring, A3XX_RB_RENDER_CONTROL_BIN_WIDTH(32) |
  175.                         A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE |
  176.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER));
  177.  
  178.         OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4);
  179.         OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
  180.                         A3XX_RB_COPY_CONTROL_MODE(0) |
  181.                         A3XX_RB_COPY_CONTROL_GMEM_BASE(0));
  182.         OUT_RELOCW(ring, fd_resource(fd3_ctx->solid_vbuf)->bo, 0x20, 0, -1);  /* RB_COPY_DEST_BASE */
  183.         OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(128));
  184.         OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) |
  185.                         A3XX_RB_COPY_DEST_INFO_FORMAT(RB_R8G8B8A8_UNORM) |
  186.                         A3XX_RB_COPY_DEST_INFO_SWAP(WZYX) |
  187.                         A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
  188.                         A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE));
  189.  
  190.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  191.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  192.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  193.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  194.  
  195.         fd3_program_emit(ring, &emit, 0, NULL);
  196.         fd3_emit_vertex_bufs(ring, &emit);
  197.  
  198.         OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 4);
  199.         OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(FOUR_QUADS) |
  200.                         A3XX_HLSQ_CONTROL_0_REG_FSSUPERTHREADENABLE |
  201.                         A3XX_HLSQ_CONTROL_0_REG_RESERVED2 |
  202.                         A3XX_HLSQ_CONTROL_0_REG_SPCONSTFULLUPDATE);
  203.         OUT_RING(ring, A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(TWO_QUADS) |
  204.                         A3XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE);
  205.         OUT_RING(ring, A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(31));
  206.         OUT_RING(ring, 0); /* HLSQ_CONTROL_3_REG */
  207.  
  208.         OUT_PKT0(ring, REG_A3XX_HLSQ_CONST_FSPRESV_RANGE_REG, 1);
  209.         OUT_RING(ring, A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY(0x20) |
  210.                         A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY(0x20));
  211.  
  212.         OUT_PKT0(ring, REG_A3XX_RB_MSAA_CONTROL, 1);
  213.         OUT_RING(ring, A3XX_RB_MSAA_CONTROL_DISABLE |
  214.                         A3XX_RB_MSAA_CONTROL_SAMPLES(MSAA_ONE) |
  215.                         A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(0xffff));
  216.  
  217.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  218.         OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
  219.  
  220.         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  221.         OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
  222.                         A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  223.                         A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  224.                         A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  225.                         A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  226.                         A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  227.                         A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  228.                         A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  229.  
  230.         OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
  231.         OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0.0));
  232.  
  233.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  234.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  235.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  236.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  237.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  238.  
  239.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  240.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
  241.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  242.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  243.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  244.  
  245.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
  246.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  247.                         A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(1));
  248.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(0) |
  249.                         A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(1));
  250.  
  251.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  252.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  253.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  254.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(31) |
  255.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(0));
  256.  
  257.         fd_wfi(ctx, ring);
  258.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6);
  259.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET(0.0));
  260.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE(1.0));
  261.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET(0.0));
  262.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(1.0));
  263.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  264.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
  265.  
  266.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
  267.         OUT_RING(ring, A3XX_GRAS_CL_CLIP_CNTL_CLIP_DISABLE |
  268.                         A3XX_GRAS_CL_CLIP_CNTL_ZFAR_CLIP_DISABLE |
  269.                         A3XX_GRAS_CL_CLIP_CNTL_VP_CLIP_CODE_IGNORE |
  270.                         A3XX_GRAS_CL_CLIP_CNTL_VP_XFORM_DISABLE |
  271.                         A3XX_GRAS_CL_CLIP_CNTL_PERSP_DIVISION_DISABLE);
  272.  
  273.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_GB_CLIP_ADJ, 1);
  274.         OUT_RING(ring, A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ(0) |
  275.                         A3XX_GRAS_CL_GB_CLIP_ADJ_VERT(0));
  276.  
  277.         OUT_PKT3(ring, CP_DRAW_INDX_2, 5);
  278.         OUT_RING(ring, 0x00000000);   /* viz query info. */
  279.         OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_IMMEDIATE,
  280.                                                 INDEX_SIZE_32_BIT, IGNORE_VISIBILITY, 0));
  281.         OUT_RING(ring, 2);            /* NumIndices */
  282.         OUT_RING(ring, 2);
  283.         OUT_RING(ring, 1);
  284.         fd_reset_wfi(ctx);
  285.  
  286.         OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 1);
  287.         OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(TWO_QUADS));
  288.  
  289.         OUT_PKT0(ring, REG_A3XX_VFD_PERFCOUNTER0_SELECT, 1);
  290.         OUT_RING(ring, 0x00000000);
  291.  
  292.         fd_wfi(ctx, ring);
  293.         OUT_PKT0(ring, REG_A3XX_VSC_BIN_SIZE, 1);
  294.         OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
  295.                         A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
  296.  
  297.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  298.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  299.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  300.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  301.  
  302.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
  303.         OUT_RING(ring, 0x00000000);
  304. }
  305.  
  306. /* transfer from gmem to system memory (ie. normal RAM) */
  307.  
  308. static void
  309. emit_gmem2mem_surf(struct fd_context *ctx,
  310.                                    enum adreno_rb_copy_control_mode mode,
  311.                                    bool stencil,
  312.                                    uint32_t base, struct pipe_surface *psurf)
  313. {
  314.         struct fd_ringbuffer *ring = ctx->ring;
  315.         struct fd_resource *rsc = fd_resource(psurf->texture);
  316.         enum pipe_format format = psurf->format;
  317.         if (stencil) {
  318.                 rsc = rsc->stencil;
  319.                 format = rsc->base.b.format;
  320.         }
  321.         struct fd_resource_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level);
  322.         uint32_t offset = fd_resource_offset(rsc, psurf->u.tex.level,
  323.                         psurf->u.tex.first_layer);
  324.  
  325.         debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
  326.  
  327.         OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4);
  328.         OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
  329.                         A3XX_RB_COPY_CONTROL_MODE(mode) |
  330.                         A3XX_RB_COPY_CONTROL_GMEM_BASE(base) |
  331.                         COND(format == PIPE_FORMAT_Z32_FLOAT ||
  332.                                  format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT,
  333.                                  A3XX_RB_COPY_CONTROL_UNK12));
  334.  
  335.         OUT_RELOCW(ring, rsc->bo, offset, 0, -1);    /* RB_COPY_DEST_BASE */
  336.         OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(slice->pitch * rsc->cpp));
  337.         OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) |
  338.                         A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(format)) |
  339.                         A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
  340.                         A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE) |
  341.                         A3XX_RB_COPY_DEST_INFO_SWAP(fd3_pipe2swap(format)));
  342.  
  343.         fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
  344.                         DI_SRC_SEL_AUTO_INDEX, 2, 0, INDEX_SIZE_IGN, 0, 0, NULL);
  345. }
  346.  
  347. static void
  348. fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
  349. {
  350.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  351.         struct fd_ringbuffer *ring = ctx->ring;
  352.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  353.         struct fd3_emit emit = {
  354.                         .vtx = &fd3_ctx->solid_vbuf_state,
  355.                         .prog = &ctx->solid_prog,
  356.                         .key = {
  357.                                 .half_precision = true,
  358.                         },
  359.         };
  360.         int i;
  361.  
  362.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  363.         OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
  364.  
  365.         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  366.         OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
  367.                         A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  368.                         A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  369.                         A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  370.                         A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  371.                         A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  372.                         A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  373.                         A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  374.  
  375.         OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2);
  376.         OUT_RING(ring, 0xff000000 |
  377.                         A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  378.                         A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  379.                         A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  380.         OUT_RING(ring, 0xff000000 |
  381.                         A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  382.                         A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  383.                         A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  384.  
  385.         OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
  386.         OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
  387.  
  388.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
  389.         OUT_RING(ring, 0x00000000);   /* GRAS_CL_CLIP_CNTL */
  390.  
  391.         fd_wfi(ctx, ring);
  392.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6);
  393.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)pfb->width/2.0 - 0.5));
  394.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)pfb->width/2.0));
  395.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)pfb->height/2.0 - 0.5));
  396.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)pfb->height/2.0));
  397.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  398.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
  399.  
  400.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  401.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  402.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  403.                         A3XX_RB_MODE_CONTROL_MRT(0));
  404.  
  405.         OUT_PKT0(ring, REG_A3XX_RB_RENDER_CONTROL, 1);
  406.         OUT_RING(ring, A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE |
  407.                         A3XX_RB_RENDER_CONTROL_ENABLE_GMEM |
  408.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER) |
  409.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(ctx->gmem.bin_w));
  410.  
  411.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  412.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  413.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  414.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  415.  
  416.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  417.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
  418.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  419.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  420.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  421.  
  422.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
  423.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  424.                         A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  425.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(pfb->width - 1) |
  426.                         A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(pfb->height - 1));
  427.  
  428.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  429.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  430.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  431.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  432.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  433.  
  434.         fd3_program_emit(ring, &emit, 0, NULL);
  435.         fd3_emit_vertex_bufs(ring, &emit);
  436.  
  437.         if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
  438.                 struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
  439.                 if (!rsc->stencil || ctx->resolve & FD_BUFFER_DEPTH)
  440.                         emit_gmem2mem_surf(ctx, RB_COPY_DEPTH_STENCIL, false,
  441.                                                            ctx->gmem.zsbuf_base[0], pfb->zsbuf);
  442.                 if (rsc->stencil && ctx->resolve & FD_BUFFER_STENCIL)
  443.                         emit_gmem2mem_surf(ctx, RB_COPY_DEPTH_STENCIL, true,
  444.                                                            ctx->gmem.zsbuf_base[1], pfb->zsbuf);
  445.         }
  446.  
  447.         if (ctx->resolve & FD_BUFFER_COLOR) {
  448.                 for (i = 0; i < pfb->nr_cbufs; i++) {
  449.                         if (!pfb->cbufs[i])
  450.                                 continue;
  451.                         if (!(ctx->resolve & (PIPE_CLEAR_COLOR0 << i)))
  452.                                 continue;
  453.                         emit_gmem2mem_surf(ctx, RB_COPY_RESOLVE, false,
  454.                                                            ctx->gmem.cbuf_base[i], pfb->cbufs[i]);
  455.                 }
  456.         }
  457.  
  458.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  459.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  460.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  461.                         A3XX_RB_MODE_CONTROL_MRT(MAX2(1, pfb->nr_cbufs) - 1));
  462.  
  463.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  464.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  465.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  466.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  467. }
  468.  
  469. /* transfer from system memory to gmem */
  470.  
  471. static void
  472. emit_mem2gmem_surf(struct fd_context *ctx, uint32_t bases[],
  473.                 struct pipe_surface **psurf, uint32_t bufs, uint32_t bin_w)
  474. {
  475.         struct fd_ringbuffer *ring = ctx->ring;
  476.         struct pipe_surface *zsbufs[2];
  477.  
  478.         assert(bufs > 0);
  479.  
  480.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  481.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  482.                                    A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  483.                                    A3XX_RB_MODE_CONTROL_MRT(bufs - 1));
  484.  
  485.         emit_mrt(ring, bufs, psurf, bases, bin_w, false);
  486.  
  487.         if (psurf[0] && (psurf[0]->format == PIPE_FORMAT_Z32_FLOAT ||
  488.                                          psurf[0]->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)) {
  489.                 /* Depth is stored as unorm in gmem, so we have to write it in using a
  490.                  * special blit shader which writes depth.
  491.                  */
  492.                 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  493.                 OUT_RING(ring, (A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z |
  494.                                                 A3XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE |
  495.                                                 A3XX_RB_DEPTH_CONTROL_Z_ENABLE |
  496.                                                 A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE |
  497.                                                 A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_ALWAYS)));
  498.  
  499.                 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2);
  500.                 OUT_RING(ring, A3XX_RB_DEPTH_INFO_DEPTH_BASE(bases[0]) |
  501.                                  A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(DEPTHX_32));
  502.                 OUT_RING(ring, A3XX_RB_DEPTH_PITCH(4 * ctx->gmem.bin_w));
  503.  
  504.                 if (psurf[0]->format == PIPE_FORMAT_Z32_FLOAT) {
  505.                         OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(0), 1);
  506.                         OUT_RING(ring, 0);
  507.                 } else {
  508.                         /* The gmem_restore_tex logic will put the first buffer's stencil
  509.                          * as color. Supply it with the proper information to make that
  510.                          * happen.
  511.                          */
  512.                         zsbufs[0] = zsbufs[1] = psurf[0];
  513.                         psurf = zsbufs;
  514.                         bufs = 2;
  515.                 }
  516.         } else {
  517.                 OUT_PKT0(ring, REG_A3XX_SP_FS_OUTPUT_REG, 1);
  518.                 OUT_RING(ring, A3XX_SP_FS_OUTPUT_REG_MRT(bufs - 1));
  519.         }
  520.  
  521.         fd3_emit_gmem_restore_tex(ring, psurf, bufs);
  522.  
  523.         fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
  524.                         DI_SRC_SEL_AUTO_INDEX, 2, 0, INDEX_SIZE_IGN, 0, 0, NULL);
  525. }
  526.  
  527. static void
  528. fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
  529. {
  530.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  531.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  532.         struct fd_ringbuffer *ring = ctx->ring;
  533.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  534.         struct fd3_emit emit = {
  535.                         .vtx = &fd3_ctx->blit_vbuf_state,
  536.                         .sprite_coord_enable = 1,
  537.                         /* NOTE: They all use the same VP, this is for vtx bufs. */
  538.                         .prog = &ctx->blit_prog[0],
  539.                         .key = {
  540.                                 .half_precision = (fd3_half_precision(pfb->cbufs[0]) &&
  541.                                                                    fd3_half_precision(pfb->cbufs[1]) &&
  542.                                                                    fd3_half_precision(pfb->cbufs[2]) &&
  543.                                                                    fd3_half_precision(pfb->cbufs[3]))
  544.                         },
  545.         };
  546.         float x0, y0, x1, y1;
  547.         unsigned bin_w = tile->bin_w;
  548.         unsigned bin_h = tile->bin_h;
  549.         unsigned i;
  550.  
  551.         /* write texture coordinates to vertexbuf: */
  552.         x0 = ((float)tile->xoff) / ((float)pfb->width);
  553.         x1 = ((float)tile->xoff + bin_w) / ((float)pfb->width);
  554.         y0 = ((float)tile->yoff) / ((float)pfb->height);
  555.         y1 = ((float)tile->yoff + bin_h) / ((float)pfb->height);
  556.  
  557.         OUT_PKT3(ring, CP_MEM_WRITE, 5);
  558.         OUT_RELOCW(ring, fd_resource(fd3_ctx->blit_texcoord_vbuf)->bo, 0, 0, 0);
  559.         OUT_RING(ring, fui(x0));
  560.         OUT_RING(ring, fui(y0));
  561.         OUT_RING(ring, fui(x1));
  562.         OUT_RING(ring, fui(y1));
  563.  
  564.         for (i = 0; i < 4; i++) {
  565.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
  566.                 OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY) |
  567.                                 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE) |
  568.                                 A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
  569.  
  570.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1);
  571.                 OUT_RING(ring, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
  572.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  573.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
  574.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
  575.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  576.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO));
  577.         }
  578.  
  579.         OUT_PKT0(ring, REG_A3XX_RB_RENDER_CONTROL, 1);
  580.         OUT_RING(ring, A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS) |
  581.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
  582.  
  583.         fd_wfi(ctx, ring);
  584.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  585.         OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS));
  586.  
  587.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2);
  588.         OUT_RING(ring, 0);
  589.         OUT_RING(ring, 0);
  590.  
  591.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
  592.         OUT_RING(ring, A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER);   /* GRAS_CL_CLIP_CNTL */
  593.  
  594.         fd_wfi(ctx, ring);
  595.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6);
  596.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)bin_w/2.0 - 0.5));
  597.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)bin_w/2.0));
  598.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)bin_h/2.0 - 0.5));
  599.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)bin_h/2.0));
  600.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  601.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
  602.  
  603.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
  604.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  605.                         A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  606.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w - 1) |
  607.                         A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h - 1));
  608.  
  609.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  610.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  611.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  612.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w - 1) |
  613.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h - 1));
  614.  
  615.         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  616.         OUT_RING(ring, 0x2 |
  617.                         A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
  618.                         A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  619.                         A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  620.                         A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  621.                         A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_ALWAYS) |
  622.                         A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  623.                         A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  624.                         A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  625.  
  626.         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_INFO, 2);
  627.         OUT_RING(ring, 0); /* RB_STENCIL_INFO */
  628.         OUT_RING(ring, 0); /* RB_STENCIL_PITCH */
  629.  
  630.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  631.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  632.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  633.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  634.  
  635.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  636.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(2) |
  637.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  638.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  639.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  640.  
  641.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  642.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  643.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  644.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  645.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  646.  
  647.         fd3_emit_vertex_bufs(ring, &emit);
  648.  
  649.         /* for gmem pitch/base calculations, we need to use the non-
  650.          * truncated tile sizes:
  651.          */
  652.         bin_w = gmem->bin_w;
  653.         bin_h = gmem->bin_h;
  654.  
  655.         if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_COLOR)) {
  656.                 emit.prog = &ctx->blit_prog[pfb->nr_cbufs - 1];
  657.                 fd3_program_emit(ring, &emit, pfb->nr_cbufs, pfb->cbufs);
  658.                 emit_mem2gmem_surf(ctx, gmem->cbuf_base, pfb->cbufs, pfb->nr_cbufs, bin_w);
  659.         }
  660.  
  661.         if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
  662.                 if (pfb->zsbuf->format != PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
  663.                         pfb->zsbuf->format != PIPE_FORMAT_Z32_FLOAT) {
  664.                         /* Non-float can use a regular color write. It's split over 8-bit
  665.                          * components, so half precision is always sufficient.
  666.                          */
  667.                         emit.prog = &ctx->blit_prog[0];
  668.                         emit.key.half_precision = true;
  669.                 } else {
  670.                         /* Float depth needs special blit shader that writes depth */
  671.                         if (pfb->zsbuf->format == PIPE_FORMAT_Z32_FLOAT)
  672.                                 emit.prog = &ctx->blit_z;
  673.                         else
  674.                                 emit.prog = &ctx->blit_zs;
  675.                         emit.key.half_precision = false;
  676.                 }
  677.                 fd3_program_emit(ring, &emit, 1, &pfb->zsbuf);
  678.                 emit_mem2gmem_surf(ctx, gmem->zsbuf_base, &pfb->zsbuf, 1, bin_w);
  679.         }
  680.  
  681.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  682.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  683.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  684.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  685.  
  686.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  687.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  688.                                    A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  689.                                    A3XX_RB_MODE_CONTROL_MRT(MAX2(1, pfb->nr_cbufs) - 1));
  690. }
  691.  
  692. static void
  693. patch_draws(struct fd_context *ctx, enum pc_di_vis_cull_mode vismode)
  694. {
  695.         unsigned i;
  696.         for (i = 0; i < fd_patch_num_elements(&ctx->draw_patches); i++) {
  697.                 struct fd_cs_patch *patch = fd_patch_element(&ctx->draw_patches, i);
  698.                 *patch->cs = patch->val | DRAW(0, 0, 0, vismode, 0);
  699.         }
  700.         util_dynarray_resize(&ctx->draw_patches, 0);
  701. }
  702.  
  703. static void
  704. patch_rbrc(struct fd_context *ctx, uint32_t val)
  705. {
  706.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  707.         unsigned i;
  708.         for (i = 0; i < fd_patch_num_elements(&fd3_ctx->rbrc_patches); i++) {
  709.                 struct fd_cs_patch *patch = fd_patch_element(&fd3_ctx->rbrc_patches, i);
  710.                 *patch->cs = patch->val | val;
  711.         }
  712.         util_dynarray_resize(&fd3_ctx->rbrc_patches, 0);
  713. }
  714.  
  715. /* for rendering directly to system memory: */
  716. static void
  717. fd3_emit_sysmem_prep(struct fd_context *ctx)
  718. {
  719.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  720.         struct fd_ringbuffer *ring = ctx->ring;
  721.         uint32_t i, pitch = 0;
  722.  
  723.         for (i = 0; i < pfb->nr_cbufs; i++) {
  724.                 struct pipe_surface *psurf = pfb->cbufs[i];
  725.                 if (!psurf)
  726.                         continue;
  727.                 pitch = fd_resource(psurf->texture)->slices[psurf->u.tex.level].pitch;
  728.         }
  729.  
  730.         fd3_emit_restore(ctx);
  731.  
  732.         OUT_PKT0(ring, REG_A3XX_RB_FRAME_BUFFER_DIMENSION, 1);
  733.         OUT_RING(ring, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) |
  734.                         A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height));
  735.  
  736.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0, true);
  737.  
  738.         /* setup scissor/offset for current tile: */
  739.         OUT_PKT0(ring, REG_A3XX_RB_WINDOW_OFFSET, 1);
  740.         OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(0) |
  741.                         A3XX_RB_WINDOW_OFFSET_Y(0));
  742.  
  743.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  744.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  745.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  746.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb->width - 1) |
  747.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1));
  748.  
  749.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  750.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  751.                         A3XX_RB_MODE_CONTROL_GMEM_BYPASS |
  752.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  753.                         A3XX_RB_MODE_CONTROL_MRT(MAX2(1, pfb->nr_cbufs) - 1));
  754.  
  755.         patch_draws(ctx, IGNORE_VISIBILITY);
  756.         patch_rbrc(ctx, A3XX_RB_RENDER_CONTROL_BIN_WIDTH(pitch));
  757. }
  758.  
  759. static void
  760. update_vsc_pipe(struct fd_context *ctx)
  761. {
  762.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  763.         struct fd_ringbuffer *ring = ctx->ring;
  764.         int i;
  765.  
  766.         OUT_PKT0(ring, REG_A3XX_VSC_SIZE_ADDRESS, 1);
  767.         OUT_RELOCW(ring, fd3_ctx->vsc_size_mem, 0, 0, 0); /* VSC_SIZE_ADDRESS */
  768.  
  769.         for (i = 0; i < 8; i++) {
  770.                 struct fd_vsc_pipe *pipe = &ctx->pipe[i];
  771.  
  772.                 if (!pipe->bo) {
  773.                         pipe->bo = fd_bo_new(ctx->dev, 0x40000,
  774.                                         DRM_FREEDRENO_GEM_TYPE_KMEM);
  775.                 }
  776.  
  777.                 OUT_PKT0(ring, REG_A3XX_VSC_PIPE(i), 3);
  778.                 OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(pipe->x) |
  779.                                 A3XX_VSC_PIPE_CONFIG_Y(pipe->y) |
  780.                                 A3XX_VSC_PIPE_CONFIG_W(pipe->w) |
  781.                                 A3XX_VSC_PIPE_CONFIG_H(pipe->h));
  782.                 OUT_RELOCW(ring, pipe->bo, 0, 0, 0);       /* VSC_PIPE[i].DATA_ADDRESS */
  783.                 OUT_RING(ring, fd_bo_size(pipe->bo) - 32); /* VSC_PIPE[i].DATA_LENGTH */
  784.         }
  785. }
  786.  
  787. static void
  788. emit_binning_pass(struct fd_context *ctx)
  789. {
  790.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  791.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  792.         struct fd_ringbuffer *ring = ctx->ring;
  793.         int i;
  794.  
  795.         uint32_t x1 = gmem->minx;
  796.         uint32_t y1 = gmem->miny;
  797.         uint32_t x2 = gmem->minx + gmem->width - 1;
  798.         uint32_t y2 = gmem->miny + gmem->height - 1;
  799.  
  800.         if (ctx->screen->gpu_id == 320) {
  801.                 emit_binning_workaround(ctx);
  802.                 fd_wfi(ctx, ring);
  803.                 OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
  804.                 OUT_RING(ring, 0x00007fff);
  805.         }
  806.  
  807.         OUT_PKT0(ring, REG_A3XX_VSC_BIN_CONTROL, 1);
  808.         OUT_RING(ring, A3XX_VSC_BIN_CONTROL_BINNING_ENABLE);
  809.  
  810.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  811.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_TILING_PASS) |
  812.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  813.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  814.  
  815.         OUT_PKT0(ring, REG_A3XX_RB_FRAME_BUFFER_DIMENSION, 1);
  816.         OUT_RING(ring, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) |
  817.                         A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height));
  818.  
  819.         OUT_PKT0(ring, REG_A3XX_RB_RENDER_CONTROL, 1);
  820.         OUT_RING(ring, A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER) |
  821.                         A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE |
  822.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
  823.  
  824.         /* setup scissor/offset for whole screen: */
  825.         OUT_PKT0(ring, REG_A3XX_RB_WINDOW_OFFSET, 1);
  826.         OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(x1) |
  827.                         A3XX_RB_WINDOW_OFFSET_Y(y1));
  828.  
  829.         OUT_PKT0(ring, REG_A3XX_RB_LRZ_VSC_CONTROL, 1);
  830.         OUT_RING(ring, A3XX_RB_LRZ_VSC_CONTROL_BINNING_ENABLE);
  831.  
  832.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  833.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) |
  834.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1));
  835.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) |
  836.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2));
  837.  
  838.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  839.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_TILING_PASS) |
  840.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  841.                         A3XX_RB_MODE_CONTROL_MRT(0));
  842.  
  843.         for (i = 0; i < 4; i++) {
  844.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
  845.                 OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_CLEAR) |
  846.                                 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE) |
  847.                                 A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0));
  848.         }
  849.  
  850.         OUT_PKT0(ring, REG_A3XX_PC_VSTREAM_CONTROL, 1);
  851.         OUT_RING(ring, A3XX_PC_VSTREAM_CONTROL_SIZE(1) |
  852.                         A3XX_PC_VSTREAM_CONTROL_N(0));
  853.  
  854.         /* emit IB to binning drawcmds: */
  855.         OUT_IB(ring, ctx->binning_start, ctx->binning_end);
  856.         fd_reset_wfi(ctx);
  857.  
  858.         fd_wfi(ctx, ring);
  859.  
  860.         /* and then put stuff back the way it was: */
  861.  
  862.         OUT_PKT0(ring, REG_A3XX_VSC_BIN_CONTROL, 1);
  863.         OUT_RING(ring, 0x00000000);
  864.  
  865.         OUT_PKT0(ring, REG_A3XX_SP_SP_CTRL_REG, 1);
  866.         OUT_RING(ring, A3XX_SP_SP_CTRL_REG_RESOLVE |
  867.                         A3XX_SP_SP_CTRL_REG_CONSTMODE(1) |
  868.                         A3XX_SP_SP_CTRL_REG_SLEEPMODE(1) |
  869.                         A3XX_SP_SP_CTRL_REG_L0MODE(0));
  870.  
  871.         OUT_PKT0(ring, REG_A3XX_RB_LRZ_VSC_CONTROL, 1);
  872.         OUT_RING(ring, 0x00000000);
  873.  
  874.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  875.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  876.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  877.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  878.  
  879.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 2);
  880.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  881.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  882.                         A3XX_RB_MODE_CONTROL_MRT(pfb->nr_cbufs - 1));
  883.         OUT_RING(ring, A3XX_RB_RENDER_CONTROL_ENABLE_GMEM |
  884.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER) |
  885.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
  886.  
  887.         fd_event_write(ctx, ring, CACHE_FLUSH);
  888.         fd_wfi(ctx, ring);
  889.  
  890.         if (ctx->screen->gpu_id == 320) {
  891.                 /* dummy-draw workaround: */
  892.                 OUT_PKT3(ring, CP_DRAW_INDX, 3);
  893.                 OUT_RING(ring, 0x00000000);
  894.                 OUT_RING(ring, DRAW(1, DI_SRC_SEL_AUTO_INDEX,
  895.                                                         INDEX_SIZE_IGN, IGNORE_VISIBILITY, 0));
  896.                 OUT_RING(ring, 0);             /* NumIndices */
  897.                 fd_reset_wfi(ctx);
  898.         }
  899.  
  900.         OUT_PKT3(ring, CP_NOP, 4);
  901.         OUT_RING(ring, 0x00000000);
  902.         OUT_RING(ring, 0x00000000);
  903.         OUT_RING(ring, 0x00000000);
  904.         OUT_RING(ring, 0x00000000);
  905.  
  906.         fd_wfi(ctx, ring);
  907.  
  908.         if (ctx->screen->gpu_id == 320) {
  909.                 emit_binning_workaround(ctx);
  910.         }
  911. }
  912.  
  913. /* before first tile */
  914. static void
  915. fd3_emit_tile_init(struct fd_context *ctx)
  916. {
  917.         struct fd_ringbuffer *ring = ctx->ring;
  918.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  919.         uint32_t rb_render_control;
  920.  
  921.         fd3_emit_restore(ctx);
  922.  
  923.         /* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated
  924.          * at the right and bottom edge tiles
  925.          */
  926.         OUT_PKT0(ring, REG_A3XX_VSC_BIN_SIZE, 1);
  927.         OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
  928.                         A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
  929.  
  930.         update_vsc_pipe(ctx);
  931.  
  932.         if (use_hw_binning(ctx)) {
  933.                 /* mark the end of the binning cmds: */
  934.                 fd_ringmarker_mark(ctx->binning_end);
  935.  
  936.                 /* emit hw binning pass: */
  937.                 emit_binning_pass(ctx);
  938.  
  939.                 patch_draws(ctx, USE_VISIBILITY);
  940.         } else {
  941.                 patch_draws(ctx, IGNORE_VISIBILITY);
  942.         }
  943.  
  944.         rb_render_control = A3XX_RB_RENDER_CONTROL_ENABLE_GMEM |
  945.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w);
  946.  
  947.         patch_rbrc(ctx, rb_render_control);
  948. }
  949.  
  950. /* before mem2gmem */
  951. static void
  952. fd3_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile)
  953. {
  954.         struct fd_ringbuffer *ring = ctx->ring;
  955.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  956.  
  957.         if (ctx->needs_rb_fbd) {
  958.                 fd_wfi(ctx, ring);
  959.                 OUT_PKT0(ring, REG_A3XX_RB_FRAME_BUFFER_DIMENSION, 1);
  960.                 OUT_RING(ring, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) |
  961.                                 A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height));
  962.                 ctx->needs_rb_fbd = false;
  963.         }
  964.  
  965.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  966.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  967.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE |
  968.                         A3XX_RB_MODE_CONTROL_MRT(MAX2(1, pfb->nr_cbufs) - 1));
  969. }
  970.  
  971. /* before IB to rendering cmds: */
  972. static void
  973. fd3_emit_tile_renderprep(struct fd_context *ctx, struct fd_tile *tile)
  974. {
  975.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  976.         struct fd_ringbuffer *ring = ctx->ring;
  977.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  978.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  979.  
  980.         uint32_t x1 = tile->xoff;
  981.         uint32_t y1 = tile->yoff;
  982.         uint32_t x2 = tile->xoff + tile->bin_w - 1;
  983.         uint32_t y2 = tile->yoff + tile->bin_h - 1;
  984.  
  985.         uint32_t reg;
  986.  
  987.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2);
  988.         reg = A3XX_RB_DEPTH_INFO_DEPTH_BASE(gmem->zsbuf_base[0]);
  989.         if (pfb->zsbuf) {
  990.                 reg |= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
  991.         }
  992.         OUT_RING(ring, reg);
  993.         if (pfb->zsbuf) {
  994.                 struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
  995.                 OUT_RING(ring, A3XX_RB_DEPTH_PITCH(rsc->cpp * gmem->bin_w));
  996.                 if (rsc->stencil) {
  997.                         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_INFO, 2);
  998.                         OUT_RING(ring, A3XX_RB_STENCIL_INFO_STENCIL_BASE(gmem->zsbuf_base[1]));
  999.                         OUT_RING(ring, A3XX_RB_STENCIL_PITCH(rsc->stencil->cpp * gmem->bin_w));
  1000.                 }
  1001.         } else {
  1002.                 OUT_RING(ring, 0x00000000);
  1003.         }
  1004.  
  1005.         if (use_hw_binning(ctx)) {
  1006.                 struct fd_vsc_pipe *pipe = &ctx->pipe[tile->p];
  1007.  
  1008.                 assert(pipe->w * pipe->h);
  1009.  
  1010.                 fd_event_write(ctx, ring, HLSQ_FLUSH);
  1011.                 fd_wfi(ctx, ring);
  1012.  
  1013.                 OUT_PKT0(ring, REG_A3XX_PC_VSTREAM_CONTROL, 1);
  1014.                 OUT_RING(ring, A3XX_PC_VSTREAM_CONTROL_SIZE(pipe->w * pipe->h) |
  1015.                                 A3XX_PC_VSTREAM_CONTROL_N(tile->n));
  1016.  
  1017.  
  1018.                 OUT_PKT3(ring, CP_SET_BIN_DATA, 2);
  1019.                 OUT_RELOC(ring, pipe->bo, 0, 0, 0);    /* BIN_DATA_ADDR <- VSC_PIPE[p].DATA_ADDRESS */
  1020.                 OUT_RELOC(ring, fd3_ctx->vsc_size_mem, /* BIN_SIZE_ADDR <- VSC_SIZE_ADDRESS + (p * 4) */
  1021.                                 (tile->p * 4), 0, 0);
  1022.         } else {
  1023.                 OUT_PKT0(ring, REG_A3XX_PC_VSTREAM_CONTROL, 1);
  1024.                 OUT_RING(ring, 0x00000000);
  1025.         }
  1026.  
  1027.         OUT_PKT3(ring, CP_SET_BIN, 3);
  1028.         OUT_RING(ring, 0x00000000);
  1029.         OUT_RING(ring, CP_SET_BIN_1_X1(x1) | CP_SET_BIN_1_Y1(y1));
  1030.         OUT_RING(ring, CP_SET_BIN_2_X2(x2) | CP_SET_BIN_2_Y2(y2));
  1031.  
  1032.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, gmem->cbuf_base, gmem->bin_w, true);
  1033.  
  1034.         /* setup scissor/offset for current tile: */
  1035.         OUT_PKT0(ring, REG_A3XX_RB_WINDOW_OFFSET, 1);
  1036.         OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(tile->xoff) |
  1037.                         A3XX_RB_WINDOW_OFFSET_Y(tile->yoff));
  1038.  
  1039.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  1040.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) |
  1041.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1));
  1042.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) |
  1043.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2));
  1044. }
  1045.  
  1046. void
  1047. fd3_gmem_init(struct pipe_context *pctx)
  1048. {
  1049.         struct fd_context *ctx = fd_context(pctx);
  1050.  
  1051.         ctx->emit_sysmem_prep = fd3_emit_sysmem_prep;
  1052.         ctx->emit_tile_init = fd3_emit_tile_init;
  1053.         ctx->emit_tile_prep = fd3_emit_tile_prep;
  1054.         ctx->emit_tile_mem2gmem = fd3_emit_tile_mem2gmem;
  1055.         ctx->emit_tile_renderprep = fd3_emit_tile_renderprep;
  1056.         ctx->emit_tile_gmem2mem = fd3_emit_tile_gmem2mem;
  1057. }
  1058.