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_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 "fd4_gmem.h"
  40. #include "fd4_context.h"
  41. #include "fd4_draw.h"
  42. #include "fd4_emit.h"
  43. #include "fd4_program.h"
  44. #include "fd4_format.h"
  45. #include "fd4_zsa.h"
  46.  
  47. static const struct ir3_shader_key key = {
  48.                 // XXX should set this based on render target format!  We don't
  49.                 // want half_precision if float32 render target!!!
  50.                 .half_precision = true,
  51. };
  52.  
  53. static void
  54. emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
  55.                 struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w)
  56. {
  57.         enum a4xx_tile_mode tile_mode;
  58.         unsigned i;
  59.  
  60.         if (bin_w) {
  61.                 tile_mode = 2;
  62.         } else {
  63.                 tile_mode = TILE4_LINEAR;
  64.         }
  65.  
  66.         for (i = 0; i < 8; i++) {
  67.                 enum a4xx_color_fmt format = 0;
  68.                 enum a3xx_color_swap swap = WZYX;
  69.                 struct fd_resource *rsc = NULL;
  70.                 struct fd_resource_slice *slice = NULL;
  71.                 uint32_t stride = 0;
  72.                 uint32_t base = 0;
  73.                 uint32_t offset = 0;
  74.  
  75.                 if ((i < nr_bufs) && bufs[i]) {
  76.                         struct pipe_surface *psurf = bufs[i];
  77.  
  78.                         rsc = fd_resource(psurf->texture);
  79.                         slice = fd_resource_slice(rsc, psurf->u.tex.level);
  80.                         format = fd4_pipe2color(psurf->format);
  81.                         swap = fd4_pipe2swap(psurf->format);
  82.  
  83.                         debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
  84.  
  85.                         offset = fd_resource_offset(rsc, psurf->u.tex.level,
  86.                                         psurf->u.tex.first_layer);
  87.  
  88.                         if (bin_w) {
  89.                                 stride = bin_w * rsc->cpp;
  90.  
  91.                                 if (bases) {
  92.                                         base = bases[i];
  93.                                 }
  94.                         } else {
  95.                                 stride = slice->pitch * rsc->cpp;
  96.                         }
  97.                 }
  98.  
  99.                 OUT_PKT0(ring, REG_A4XX_RB_MRT_BUF_INFO(i), 3);
  100.                 OUT_RING(ring, A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
  101.                                 A4XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
  102.                                 A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) |
  103.                                 A4XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap));
  104.                 if (bin_w || (i >= nr_bufs)) {
  105.                         OUT_RING(ring, base);
  106.                         OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(stride));
  107.                 } else {
  108.                         OUT_RELOCW(ring, rsc->bo, offset, 0, 0);
  109.                         /* RB_MRT[i].CONTROL3.STRIDE not emitted by c2d..
  110.                          * not sure if we need to skip it for bypass or
  111.                          * not.
  112.                          */
  113.                         OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(0));
  114.                 }
  115.         }
  116. }
  117.  
  118. static uint32_t
  119. depth_base(struct fd_context *ctx)
  120. {
  121.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  122.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  123.         uint32_t cpp = 4;
  124.         if (pfb->cbufs[0]) {
  125.                 struct fd_resource *rsc =
  126.                                 fd_resource(pfb->cbufs[0]->texture);
  127.                 cpp = rsc->cpp;
  128.         }
  129.         return align(gmem->bin_w * gmem->bin_h * cpp, 0x4000);
  130. }
  131.  
  132. /* transfer from gmem to system memory (ie. normal RAM) */
  133.  
  134. static void
  135. emit_gmem2mem_surf(struct fd_context *ctx,
  136.                 uint32_t base, struct pipe_surface *psurf)
  137. {
  138.         struct fd_ringbuffer *ring = ctx->ring;
  139.         struct fd_resource *rsc = fd_resource(psurf->texture);
  140.         struct fd_resource_slice *slice = &rsc->slices[psurf->u.tex.level];
  141.         uint32_t offset = fd_resource_offset(rsc, psurf->u.tex.level,
  142.                         psurf->u.tex.first_layer);
  143.  
  144.         debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
  145.  
  146.         OUT_PKT0(ring, REG_A4XX_RB_COPY_CONTROL, 4);
  147.         OUT_RING(ring, A4XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
  148.                         A4XX_RB_COPY_CONTROL_MODE(RB_COPY_RESOLVE) |
  149.                         A4XX_RB_COPY_CONTROL_GMEM_BASE(base));
  150.         OUT_RELOCW(ring, rsc->bo, offset, 0, 0);   /* RB_COPY_DEST_BASE */
  151.         OUT_RING(ring, A4XX_RB_COPY_DEST_PITCH_PITCH(slice->pitch * rsc->cpp));
  152.         OUT_RING(ring, A4XX_RB_COPY_DEST_INFO_TILE(TILE4_LINEAR) |
  153.                         A4XX_RB_COPY_DEST_INFO_FORMAT(fd4_pipe2color(psurf->format)) |
  154.                         A4XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
  155.                         A4XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE) |
  156.                         A4XX_RB_COPY_DEST_INFO_SWAP(fd4_pipe2swap(psurf->format)));
  157.  
  158.         fd4_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
  159.                         DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX_SIZE_IGN, 0, 0, NULL);
  160. }
  161.  
  162. static void
  163. fd4_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
  164. {
  165.         struct fd4_context *fd4_ctx = fd4_context(ctx);
  166.         struct fd_ringbuffer *ring = ctx->ring;
  167.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  168.         struct fd4_emit emit = {
  169.                         .vtx = &fd4_ctx->solid_vbuf_state,
  170.                         .prog = &ctx->solid_prog,
  171.                         .key = key,
  172.                         .format = fd4_emit_format(pfb->cbufs[0]),
  173.         };
  174.  
  175.         OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1);
  176.         OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
  177.  
  178.         OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2);
  179.         OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
  180.                         A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  181.                         A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  182.                         A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  183.                         A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  184.                         A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  185.                         A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  186.                         A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  187.         OUT_RING(ring, 0x00000000); /* RB_STENCIL_CONTROL2 */
  188.  
  189.         OUT_PKT0(ring, REG_A4XX_RB_STENCILREFMASK, 2);
  190.         OUT_RING(ring, 0xff000000 |
  191.                         A4XX_RB_STENCILREFMASK_STENCILREF(0) |
  192.                         A4XX_RB_STENCILREFMASK_STENCILMASK(0) |
  193.                         A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  194.         OUT_RING(ring, 0xff000000 |
  195.                         A4XX_RB_STENCILREFMASK_BF_STENCILREF(0) |
  196.                         A4XX_RB_STENCILREFMASK_BF_STENCILMASK(0) |
  197.                         A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0xff));
  198.  
  199.         OUT_PKT0(ring, REG_A4XX_GRAS_SU_MODE_CONTROL, 1);
  200.         OUT_RING(ring, A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
  201.  
  202.         fd_wfi(ctx, ring);
  203.  
  204.         OUT_PKT0(ring, REG_A4XX_GRAS_CL_CLIP_CNTL, 1);
  205.         OUT_RING(ring, 0x80000);      /* GRAS_CL_CLIP_CNTL */
  206.  
  207.         OUT_PKT0(ring, REG_A4XX_GRAS_CL_VPORT_XOFFSET_0, 6);
  208.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_XOFFSET_0((float)pfb->width/2.0));
  209.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_XSCALE_0((float)pfb->width/2.0));
  210.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_YOFFSET_0((float)pfb->height/2.0));
  211.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_YSCALE_0(-(float)pfb->height/2.0));
  212.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZOFFSET_0(0.0));
  213.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(1.0));
  214.  
  215.         OUT_PKT0(ring, REG_A4XX_RB_RENDER_CONTROL, 1);
  216.         OUT_RING(ring, A4XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE |
  217.                         0xa);       /* XXX */
  218.  
  219.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1);
  220.         OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  221.                         A4XX_GRAS_SC_CONTROL_MSAA_DISABLE |
  222.                         A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  223.                         A4XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  224.  
  225.         OUT_PKT0(ring, REG_A4XX_PC_PRIM_VTX_CNTL, 1);
  226.         OUT_RING(ring, A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  227.  
  228.         OUT_PKT0(ring, REG_A4XX_GRAS_ALPHA_CONTROL, 1);
  229.         OUT_RING(ring, 0x00000002);
  230.  
  231.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_WINDOW_SCISSOR_BR, 2);
  232.         OUT_RING(ring, A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X(pfb->width - 1) |
  233.                         A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(pfb->height - 1));
  234.         OUT_RING(ring, A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  235.                         A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  236.  
  237.         OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
  238.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  239.         OUT_RING(ring, 0);            /* ??? UNKNOWN_2209 */
  240.  
  241.         fd4_program_emit(ring, &emit);
  242.         fd4_emit_vertex_bufs(ring, &emit);
  243.  
  244.         if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
  245.                 uint32_t base = depth_base(ctx);
  246.                 emit_gmem2mem_surf(ctx, base, pfb->zsbuf);
  247.         }
  248.  
  249.         if (ctx->resolve & FD_BUFFER_COLOR) {
  250.                 emit_gmem2mem_surf(ctx, 0, pfb->cbufs[0]);
  251.         }
  252.  
  253.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1);
  254.         OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  255.                         A4XX_GRAS_SC_CONTROL_MSAA_DISABLE |
  256.                         A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  257.                         A4XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  258. }
  259.  
  260. /* transfer from system memory to gmem */
  261.  
  262. static void
  263. emit_mem2gmem_surf(struct fd_context *ctx, uint32_t base,
  264.                 struct pipe_surface *psurf, uint32_t bin_w)
  265. {
  266.         struct fd_ringbuffer *ring = ctx->ring;
  267.  
  268.         emit_mrt(ring, 1, &psurf, &base, bin_w);
  269.  
  270.         fd4_emit_gmem_restore_tex(ring, psurf);
  271.  
  272.         fd4_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
  273.                         DI_SRC_SEL_AUTO_INDEX, 2, 1, INDEX_SIZE_IGN, 0, 0, NULL);
  274. }
  275.  
  276. static void
  277. fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
  278. {
  279.         struct fd4_context *fd4_ctx = fd4_context(ctx);
  280.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  281.         struct fd_ringbuffer *ring = ctx->ring;
  282.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  283.         struct fd4_emit emit = {
  284.                         .vtx = &fd4_ctx->blit_vbuf_state,
  285.                         .prog = &ctx->blit_prog[0],
  286.                         .key = key,
  287.                         .format = fd4_emit_format(pfb->cbufs[0]),
  288.         };
  289.         float x0, y0, x1, y1;
  290.         unsigned bin_w = tile->bin_w;
  291.         unsigned bin_h = tile->bin_h;
  292.         unsigned i;
  293.  
  294.         /* write texture coordinates to vertexbuf: */
  295.         x0 = ((float)tile->xoff) / ((float)pfb->width);
  296.         x1 = ((float)tile->xoff + bin_w) / ((float)pfb->width);
  297.         y0 = ((float)tile->yoff) / ((float)pfb->height);
  298.         y1 = ((float)tile->yoff + bin_h) / ((float)pfb->height);
  299.  
  300.         OUT_PKT3(ring, CP_MEM_WRITE, 5);
  301.         OUT_RELOCW(ring, fd_resource(fd4_ctx->blit_texcoord_vbuf)->bo, 0, 0, 0);
  302.         OUT_RING(ring, fui(x0));
  303.         OUT_RING(ring, fui(y0));
  304.         OUT_RING(ring, fui(x1));
  305.         OUT_RING(ring, fui(y1));
  306.  
  307.         for (i = 0; i < 8; i++) {
  308.                 OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1);
  309.                 OUT_RING(ring, A4XX_RB_MRT_CONTROL_FASTCLEAR |
  310.                                 A4XX_RB_MRT_CONTROL_B11 |
  311.                                 A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
  312.  
  313.                 OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1);
  314.                 OUT_RING(ring, A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
  315.                                 A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  316.                                 A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
  317.                                 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
  318.                                 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  319.                                 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO));
  320.         }
  321.  
  322.         OUT_PKT0(ring, REG_A4XX_RB_RENDER_CONTROL, 1);
  323.         OUT_RING(ring, 0x8);          /* XXX RB_RENDER_CONTROL */
  324.  
  325.         OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1);
  326.         OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS));
  327.  
  328.         OUT_PKT0(ring, REG_A4XX_GRAS_CL_CLIP_CNTL, 1);
  329.         OUT_RING(ring, 0x280000);     /* XXX GRAS_CL_CLIP_CNTL */
  330.  
  331.         OUT_PKT0(ring, REG_A4XX_GRAS_SU_MODE_CONTROL, 1);
  332.         OUT_RING(ring, A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0) |
  333.                         A4XX_GRAS_SU_MODE_CONTROL_RENDERING_PASS);
  334.  
  335.         OUT_PKT0(ring, REG_A4XX_GRAS_CL_VPORT_XOFFSET_0, 6);
  336.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_XOFFSET_0((float)bin_w/2.0));
  337.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_XSCALE_0((float)bin_w/2.0));
  338.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_YOFFSET_0((float)bin_h/2.0));
  339.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_YSCALE_0(-(float)bin_h/2.0));
  340.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZOFFSET_0(0.0));
  341.         OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(1.0));
  342.  
  343.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_WINDOW_SCISSOR_BR, 2);
  344.         OUT_RING(ring, A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w - 1) |
  345.                         A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h - 1));
  346.         OUT_RING(ring, A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  347.                         A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  348.  
  349.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  350.         OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  351.                         A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  352.         OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w - 1) |
  353.                         A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h - 1));
  354.  
  355.         OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1);
  356.         OUT_RING(ring, A4XX_RB_MODE_CONTROL_WIDTH(gmem->bin_w) |
  357.                         A4XX_RB_MODE_CONTROL_HEIGHT(gmem->bin_h));
  358.  
  359.         OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2);
  360.         OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
  361.                         A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  362.                         A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  363.                         A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  364.                         A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_ALWAYS) |
  365.                         A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  366.                         A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  367.                         A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  368.         OUT_RING(ring, 0x00000000); /* RB_STENCIL_CONTROL2 */
  369.  
  370.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1);
  371.         OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  372.                         A4XX_GRAS_SC_CONTROL_MSAA_DISABLE |
  373.                         A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  374.                         A4XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  375.  
  376.         OUT_PKT0(ring, REG_A4XX_PC_PRIM_VTX_CNTL, 1);
  377.         OUT_RING(ring, A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST |
  378.                         A4XX_PC_PRIM_VTX_CNTL_VAROUT(1));
  379.  
  380.         OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
  381.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  382.         OUT_RING(ring, 0);            /* ??? UNKNOWN_2209 */
  383.  
  384.         fd4_program_emit(ring, &emit);
  385.         fd4_emit_vertex_bufs(ring, &emit);
  386.  
  387.         /* for gmem pitch/base calculations, we need to use the non-
  388.          * truncated tile sizes:
  389.          */
  390.         bin_w = gmem->bin_w;
  391.         bin_h = gmem->bin_h;
  392.  
  393.         if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
  394.                 emit_mem2gmem_surf(ctx, depth_base(ctx), pfb->zsbuf, bin_w);
  395.  
  396.         if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_COLOR))
  397.                 emit_mem2gmem_surf(ctx, 0, pfb->cbufs[0], bin_w);
  398.  
  399.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1);
  400.         OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  401.                         A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  402.                         A4XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  403.  
  404.         OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1);
  405.         OUT_RING(ring, A4XX_RB_MODE_CONTROL_WIDTH(gmem->bin_w) |
  406.                         A4XX_RB_MODE_CONTROL_HEIGHT(gmem->bin_h) |
  407.                         0x00010000);  /* XXX */
  408. }
  409.  
  410. static void
  411. patch_draws(struct fd_context *ctx, enum pc_di_vis_cull_mode vismode)
  412. {
  413.         unsigned i;
  414.         for (i = 0; i < fd_patch_num_elements(&ctx->draw_patches); i++) {
  415.                 struct fd_cs_patch *patch = fd_patch_element(&ctx->draw_patches, i);
  416.                 *patch->cs = patch->val | DRAW4(0, 0, 0, vismode);
  417.         }
  418.         util_dynarray_resize(&ctx->draw_patches, 0);
  419. }
  420.  
  421. static void
  422. patch_rbrc(struct fd_context *ctx, uint32_t val)
  423. {
  424.         struct fd4_context *fd4_ctx = fd4_context(ctx);
  425.         unsigned i;
  426.         for (i = 0; i < fd_patch_num_elements(&fd4_ctx->rbrc_patches); i++) {
  427.                 struct fd_cs_patch *patch = fd_patch_element(&fd4_ctx->rbrc_patches, i);
  428.                 *patch->cs = patch->val | val;
  429.         }
  430.         util_dynarray_resize(&fd4_ctx->rbrc_patches, 0);
  431. }
  432.  
  433. /* for rendering directly to system memory: */
  434. static void
  435. fd4_emit_sysmem_prep(struct fd_context *ctx)
  436. {
  437.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  438.         struct fd_ringbuffer *ring = ctx->ring;
  439.  
  440.         fd4_emit_restore(ctx);
  441.  
  442.         OUT_PKT0(ring, REG_A4XX_RB_FRAME_BUFFER_DIMENSION, 1);
  443.         OUT_RING(ring, A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) |
  444.                         A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height));
  445.  
  446.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0);
  447.  
  448.         /* setup scissor/offset for current tile: */
  449.         OUT_PKT0(ring, REG_A4XX_RB_BIN_OFFSET, 1);
  450.         OUT_RING(ring, A4XX_RB_BIN_OFFSET_X(0) |
  451.                         A4XX_RB_BIN_OFFSET_Y(0));
  452.  
  453.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  454.         OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  455.                         A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  456.         OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb->width - 1) |
  457.                         A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1));
  458.  
  459.         OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1);
  460.         OUT_RING(ring, A4XX_RB_MODE_CONTROL_WIDTH(0) |
  461.                         A4XX_RB_MODE_CONTROL_HEIGHT(0) |
  462.                         0x00c00000);  /* XXX */
  463.  
  464.         patch_draws(ctx, IGNORE_VISIBILITY);
  465.         patch_rbrc(ctx, 0);  // XXX
  466. }
  467.  
  468. static void
  469. update_vsc_pipe(struct fd_context *ctx)
  470. {
  471.         struct fd4_context *fd4_ctx = fd4_context(ctx);
  472.         struct fd_ringbuffer *ring = ctx->ring;
  473.         int i;
  474.  
  475.         OUT_PKT0(ring, REG_A4XX_VSC_SIZE_ADDRESS, 1);
  476.         OUT_RELOCW(ring, fd4_ctx->vsc_size_mem, 0, 0, 0); /* VSC_SIZE_ADDRESS */
  477.  
  478.         OUT_PKT0(ring, REG_A4XX_VSC_PIPE_CONFIG_REG(0), 8);
  479.         for (i = 0; i < 8; i++) {
  480.                 struct fd_vsc_pipe *pipe = &ctx->pipe[i];
  481.                 OUT_RING(ring, A4XX_VSC_PIPE_CONFIG_REG_X(pipe->x) |
  482.                                 A4XX_VSC_PIPE_CONFIG_REG_Y(pipe->y) |
  483.                                 A4XX_VSC_PIPE_CONFIG_REG_W(pipe->w) |
  484.                                 A4XX_VSC_PIPE_CONFIG_REG_H(pipe->h));
  485.         }
  486.  
  487.         OUT_PKT0(ring, REG_A4XX_VSC_PIPE_DATA_ADDRESS_REG(0), 8);
  488.         for (i = 0; i < 8; i++) {
  489.                 struct fd_vsc_pipe *pipe = &ctx->pipe[i];
  490.                 if (!pipe->bo) {
  491.                         pipe->bo = fd_bo_new(ctx->dev, 0x40000,
  492.                                         DRM_FREEDRENO_GEM_TYPE_KMEM);
  493.                 }
  494.                 OUT_RELOCW(ring, pipe->bo, 0, 0, 0);       /* VSC_PIPE_DATA_ADDRESS[i] */
  495.         }
  496.  
  497.         OUT_PKT0(ring, REG_A4XX_VSC_PIPE_DATA_LENGTH_REG(0), 8);
  498.         for (i = 0; i < 8; i++) {
  499.                 struct fd_vsc_pipe *pipe = &ctx->pipe[i];
  500.                 OUT_RING(ring, fd_bo_size(pipe->bo) - 32); /* VSC_PIPE_DATA_LENGTH[i] */
  501.         }
  502. }
  503.  
  504. /* before first tile */
  505. static void
  506. fd4_emit_tile_init(struct fd_context *ctx)
  507. {
  508.         struct fd_ringbuffer *ring = ctx->ring;
  509.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  510.         uint32_t rb_render_control;
  511.  
  512.         fd4_emit_restore(ctx);
  513.  
  514.         OUT_PKT0(ring, REG_A4XX_VSC_BIN_SIZE, 1);
  515.         OUT_RING(ring, A4XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
  516.                         A4XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
  517.  
  518.         OUT_PKT0(ring, REG_A4XX_RB_MODE_CONTROL, 1);
  519.         OUT_RING(ring, A4XX_RB_MODE_CONTROL_WIDTH(gmem->bin_w) |
  520.                         A4XX_RB_MODE_CONTROL_HEIGHT(gmem->bin_h) |
  521.                         0x00010000);  /* XXX */
  522.  
  523.         update_vsc_pipe(ctx);
  524.         patch_draws(ctx, IGNORE_VISIBILITY);
  525.  
  526.         rb_render_control = 0; // XXX or BINNING_PASS.. but maybe we can emit only from gmem
  527.         patch_rbrc(ctx, rb_render_control);
  528. }
  529.  
  530. /* before mem2gmem */
  531. static void
  532. fd4_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile)
  533. {
  534.         struct fd_ringbuffer *ring = ctx->ring;
  535.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  536.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  537.         uint32_t reg;
  538.  
  539.         OUT_PKT0(ring, REG_A4XX_RB_DEPTH_INFO, 3);
  540.         reg = A4XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(ctx));
  541.         if (pfb->zsbuf) {
  542.                 reg |= A4XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd4_pipe2depth(pfb->zsbuf->format));
  543.         }
  544.         OUT_RING(ring, reg);
  545.         if (pfb->zsbuf) {
  546.                 uint32_t cpp = util_format_get_blocksize(pfb->zsbuf->format);
  547.                 OUT_RING(ring, A4XX_RB_DEPTH_PITCH(cpp * gmem->bin_w));
  548.                 OUT_RING(ring, A4XX_RB_DEPTH_PITCH2(cpp * gmem->bin_w));
  549.         } else {
  550.                 OUT_RING(ring, 0x00000000);
  551.                 OUT_RING(ring, 0x00000000);
  552.         }
  553.  
  554.         OUT_PKT0(ring, REG_A4XX_GRAS_DEPTH_CONTROL, 1);
  555.         if (pfb->zsbuf) {
  556.                 OUT_RING(ring, A4XX_GRAS_DEPTH_CONTROL_FORMAT(
  557.                                 fd4_pipe2depth(pfb->zsbuf->format)));
  558.         } else {
  559.                 OUT_RING(ring, A4XX_GRAS_DEPTH_CONTROL_FORMAT(DEPTH4_NONE));
  560.         }
  561.  
  562.         if (ctx->needs_rb_fbd) {
  563.                 fd_wfi(ctx, ring);
  564.                 OUT_PKT0(ring, REG_A4XX_RB_FRAME_BUFFER_DIMENSION, 1);
  565.                 OUT_RING(ring, A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb->width) |
  566.                                 A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb->height));
  567.                 ctx->needs_rb_fbd = false;
  568.         }
  569. }
  570.  
  571. /* before IB to rendering cmds: */
  572. static void
  573. fd4_emit_tile_renderprep(struct fd_context *ctx, struct fd_tile *tile)
  574. {
  575.         struct fd_ringbuffer *ring = ctx->ring;
  576.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  577.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  578.  
  579.         uint32_t x1 = tile->xoff;
  580.         uint32_t y1 = tile->yoff;
  581.         uint32_t x2 = tile->xoff + tile->bin_w - 1;
  582.         uint32_t y2 = tile->yoff + tile->bin_h - 1;
  583.  
  584.         OUT_PKT3(ring, CP_SET_BIN, 3);
  585.         OUT_RING(ring, 0x00000000);
  586.         OUT_RING(ring, CP_SET_BIN_1_X1(x1) | CP_SET_BIN_1_Y1(y1));
  587.         OUT_RING(ring, CP_SET_BIN_2_X2(x2) | CP_SET_BIN_2_Y2(y2));
  588.  
  589.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, gmem->bin_w);
  590.  
  591.         /* setup scissor/offset for current tile: */
  592.         OUT_PKT0(ring, REG_A4XX_RB_BIN_OFFSET, 1);
  593.         OUT_RING(ring, A4XX_RB_BIN_OFFSET_X(tile->xoff) |
  594.                         A4XX_RB_BIN_OFFSET_Y(tile->yoff));
  595.  
  596.         OUT_PKT0(ring, REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  597.         OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) |
  598.                         A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1));
  599.         OUT_RING(ring, A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) |
  600.                         A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2));
  601. }
  602.  
  603. void
  604. fd4_gmem_init(struct pipe_context *pctx)
  605. {
  606.         struct fd_context *ctx = fd_context(pctx);
  607.  
  608.         ctx->emit_sysmem_prep = fd4_emit_sysmem_prep;
  609.         ctx->emit_tile_init = fd4_emit_tile_init;
  610.         ctx->emit_tile_prep = fd4_emit_tile_prep;
  611.         ctx->emit_tile_mem2gmem = fd4_emit_tile_mem2gmem;
  612.         ctx->emit_tile_renderprep = fd4_emit_tile_renderprep;
  613.         ctx->emit_tile_gmem2mem = fd4_emit_tile_gmem2mem;
  614. }
  615.