Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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_state.h"
  36. #include "freedreno_resource.h"
  37.  
  38. #include "fd3_gmem.h"
  39. #include "fd3_context.h"
  40. #include "fd3_emit.h"
  41. #include "fd3_program.h"
  42. #include "fd3_util.h"
  43. #include "fd3_zsa.h"
  44.  
  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. {
  50.         enum a3xx_tile_mode tile_mode;
  51.         unsigned i;
  52.  
  53.         if (bin_w) {
  54.                 tile_mode = TILE_32X32;
  55.         } else {
  56.                 tile_mode = LINEAR;
  57.         }
  58.  
  59.         for (i = 0; i < 4; i++) {
  60.                 enum a3xx_color_fmt format = 0;
  61.                 enum a3xx_color_swap swap = WZYX;
  62.                 struct fd_resource *res = NULL;
  63.                 uint32_t stride = 0;
  64.                 uint32_t base = 0;
  65.  
  66.                 if (i < nr_bufs) {
  67.                         struct pipe_surface *psurf = bufs[i];
  68.  
  69.                         res = fd_resource(psurf->texture);
  70.                         format = fd3_pipe2color(psurf->format);
  71.                         swap = fd3_pipe2swap(psurf->format);
  72.  
  73.                         if (bin_w) {
  74.                                 stride = bin_w * res->cpp;
  75.  
  76.                                 if (bases) {
  77.                                         base = bases[i] * res->cpp;
  78.                                 }
  79.                         } else {
  80.                                 stride = res->pitch * res->cpp;
  81.                         }
  82.                 }
  83.  
  84.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_BUF_INFO(i), 2);
  85.                 OUT_RING(ring, A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
  86.                                 A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
  87.                                 A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) |
  88.                                 A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap));
  89.                 if (bin_w || (i >= nr_bufs)) {
  90.                         OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base));
  91.                 } else {
  92.                         OUT_RELOCS(ring, res->bo, 0, 0, -1);
  93.                 }
  94.  
  95.                 OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1);
  96.                 OUT_RING(ring, A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT(format));
  97.         }
  98. }
  99.  
  100. static uint32_t
  101. depth_base(struct fd_gmem_stateobj *gmem)
  102. {
  103.         return align(gmem->bin_w * gmem->bin_h, 0x4000);
  104. }
  105.  
  106. /* transfer from gmem to system memory (ie. normal RAM) */
  107.  
  108. static void
  109. emit_gmem2mem_surf(struct fd_ringbuffer *ring,
  110.                 enum adreno_rb_copy_control_mode mode,
  111.                 uint32_t base, struct pipe_surface *psurf)
  112. {
  113.         struct fd_resource *rsc = fd_resource(psurf->texture);
  114.  
  115.         OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4);
  116.         OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
  117.                         A3XX_RB_COPY_CONTROL_MODE(mode) |
  118.                         A3XX_RB_COPY_CONTROL_GMEM_BASE(base));
  119.         OUT_RELOCS(ring, rsc->bo, 0, 0, -1);    /* RB_COPY_DEST_BASE */
  120.         OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(rsc->pitch * rsc->cpp));
  121.         OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) |
  122.                         A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(psurf->format)) |
  123.                         A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
  124.                         A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE) |
  125.                         A3XX_RB_COPY_DEST_INFO_SWAP(fd3_pipe2swap(psurf->format)));
  126.  
  127.         OUT_PKT3(ring, CP_DRAW_INDX, 3);
  128.         OUT_RING(ring, 0x00000000);
  129.         OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
  130.                         INDEX_SIZE_IGN, IGNORE_VISIBILITY));
  131.         OUT_RING(ring, 2);                                      /* NumIndices */
  132. }
  133.  
  134. static void
  135. fd3_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
  136.                 uint32_t bin_w, uint32_t bin_h)
  137. {
  138.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  139.         struct fd_ringbuffer *ring = ctx->ring;
  140.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  141.  
  142.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  143.         OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
  144.  
  145.         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  146.         OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
  147.                         A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  148.                         A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  149.                         A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  150.                         A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  151.                         A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  152.                         A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  153.                         A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  154.  
  155.         OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2);
  156.         OUT_RING(ring, 0xff000000 |
  157.                         A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  158.                         A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  159.                         A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  160.         OUT_RING(ring, 0xff000000 |
  161.                         A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  162.                         A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  163.                         A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  164.  
  165.         OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
  166.         OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
  167.  
  168.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
  169.         OUT_RING(ring, 0x00000000);   /* GRAS_CL_CLIP_CNTL */
  170.  
  171.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  172.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  173.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  174.  
  175.         fd3_emit_rbrc_draw_state(ring,
  176.                         A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE |
  177.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER));
  178.  
  179.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  180.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  181.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  182.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  183.  
  184.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  185.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
  186.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  187.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  188.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  189.  
  190.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
  191.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  192.                         A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  193.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(pfb->width - 1) |
  194.                         A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(pfb->height - 1));
  195.  
  196.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  197.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  198.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  199.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  200.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  201.  
  202.         fd3_program_emit(ring, &ctx->solid_prog);
  203.  
  204.         fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
  205.                         { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
  206.                 }, 1);
  207.  
  208.         if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
  209.                 uint32_t base = depth_base(&ctx->gmem) *
  210.                                 fd_resource(pfb->cbufs[0]->texture)->cpp;
  211.                 emit_gmem2mem_surf(ring, RB_COPY_DEPTH_STENCIL, base, pfb->zsbuf);
  212.         }
  213.  
  214.         if (ctx->resolve & FD_BUFFER_COLOR) {
  215.                 emit_gmem2mem_surf(ring, RB_COPY_RESOLVE, 0, pfb->cbufs[0]);
  216.         }
  217.  
  218.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  219.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  220.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  221.  
  222.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  223.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  224.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  225.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  226. }
  227.  
  228. /* transfer from system memory to gmem */
  229.  
  230. static void
  231. emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
  232.                 struct pipe_surface *psurf, uint32_t bin_w)
  233. {
  234.         emit_mrt(ring, 1, &psurf, &base, bin_w);
  235.  
  236.         fd3_emit_gmem_restore_tex(ring, psurf);
  237.  
  238.         OUT_PKT3(ring, CP_DRAW_INDX, 3);
  239.         OUT_RING(ring, 0x00000000);
  240.         OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
  241.                         INDEX_SIZE_IGN, IGNORE_VISIBILITY));
  242.         OUT_RING(ring, 2);                                      /* NumIndices */
  243. }
  244.  
  245. static void
  246. fd3_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
  247.                 uint32_t bin_w, uint32_t bin_h)
  248. {
  249.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  250.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  251.         struct fd_ringbuffer *ring = ctx->ring;
  252.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  253.         float x0, y0, x1, y1;
  254.         unsigned i;
  255.  
  256.         /* write texture coordinates to vertexbuf: */
  257.         x0 = ((float)xoff) / ((float)pfb->width);
  258.         x1 = ((float)xoff + bin_w) / ((float)pfb->width);
  259.         y0 = ((float)yoff) / ((float)pfb->height);
  260.         y1 = ((float)yoff + bin_h) / ((float)pfb->height);
  261.  
  262.         OUT_PKT3(ring, CP_MEM_WRITE, 5);
  263.         OUT_RELOC(ring, fd_resource(fd3_ctx->blit_texcoord_vbuf)->bo, 0, 0);
  264.         OUT_RING(ring, fui(x0));
  265.         OUT_RING(ring, fui(y0));
  266.         OUT_RING(ring, fui(x1));
  267.         OUT_RING(ring, fui(y1));
  268.  
  269.         for (i = 0; i < 4; i++) {
  270.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
  271.                 OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(12) |
  272.                                 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE) |
  273.                                 A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
  274.  
  275.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1);
  276.                 OUT_RING(ring, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
  277.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  278.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
  279.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
  280.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  281.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO) |
  282.                                 A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE);
  283.         }
  284.  
  285.         fd3_emit_rbrc_tile_state(ring,
  286.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
  287.  
  288.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  289.         OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS));
  290.  
  291.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
  292.         OUT_RING(ring, A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER);   /* GRAS_CL_CLIP_CNTL */
  293.  
  294.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6);
  295.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)bin_w/2.0 - 0.5));
  296.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)bin_w/2.0));
  297.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)bin_h/2.0 - 0.5));
  298.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)bin_h/2.0));
  299.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  300.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
  301.  
  302.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
  303.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  304.                         A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  305.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w - 1) |
  306.                         A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h - 1));
  307.  
  308.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  309.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  310.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  311.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w - 1) |
  312.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h - 1));
  313.  
  314.         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  315.         OUT_RING(ring, 0x2 |
  316.                         A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
  317.                         A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  318.                         A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  319.                         A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  320.                         A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_ALWAYS) |
  321.                         A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  322.                         A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  323.                         A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  324.  
  325.         fd3_emit_rbrc_draw_state(ring,
  326.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS));
  327.  
  328.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  329.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  330.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  331.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  332.  
  333.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  334.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(2) |
  335.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  336.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  337.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  338.  
  339.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  340.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  341.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  342.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  343.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  344.  
  345.         fd3_program_emit(ring, &ctx->blit_prog);
  346.  
  347.         fd3_emit_vertex_bufs(ring, &ctx->blit_prog, (struct fd3_vertex_buf[]) {
  348.                         { .prsc = fd3_ctx->blit_texcoord_vbuf, .stride = 8, .format = PIPE_FORMAT_R32G32_FLOAT },
  349.                         { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
  350.                 }, 2);
  351.  
  352.         /* for gmem pitch/base calculations, we need to use the non-
  353.          * truncated tile sizes:
  354.          */
  355.         bin_w = gmem->bin_w;
  356.         bin_h = gmem->bin_h;
  357.  
  358.         if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
  359.                 emit_mem2gmem_surf(ring, depth_base(gmem), pfb->zsbuf, bin_w);
  360.  
  361.         if (ctx->restore & FD_BUFFER_COLOR)
  362.                 emit_mem2gmem_surf(ring, 0, pfb->cbufs[0], bin_w);
  363.  
  364.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  365.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  366.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  367.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  368. }
  369.  
  370. static void
  371. update_vsc_pipe(struct fd_context *ctx)
  372. {
  373.         struct fd_ringbuffer *ring = ctx->ring;
  374.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  375.         struct fd_bo *bo = fd3_context(ctx)->vsc_pipe_mem;
  376.         int i;
  377.  
  378.         /* since we aren't using binning, just try to assign all bins
  379.          * to same pipe for now:
  380.          */
  381.         OUT_PKT0(ring, REG_A3XX_VSC_PIPE(0), 3);
  382.         OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
  383.                         A3XX_VSC_PIPE_CONFIG_Y(0) |
  384.                         A3XX_VSC_PIPE_CONFIG_W(gmem->nbins_x) |
  385.                         A3XX_VSC_PIPE_CONFIG_H(gmem->nbins_y));
  386.         OUT_RELOC(ring, bo, 0, 0);              /* VSC_PIPE[0].DATA_ADDRESS */
  387.         OUT_RING(ring, fd_bo_size(bo) - 32);    /* VSC_PIPE[0].DATA_LENGTH */
  388.  
  389.         for (i = 1; i < 8; i++) {
  390.                 OUT_PKT0(ring, REG_A3XX_VSC_PIPE(i), 3);
  391.                 OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
  392.                                 A3XX_VSC_PIPE_CONFIG_Y(0) |
  393.                                 A3XX_VSC_PIPE_CONFIG_W(0) |
  394.                                 A3XX_VSC_PIPE_CONFIG_H(0));
  395.                 OUT_RING(ring, 0x00000000);         /* VSC_PIPE[i].DATA_ADDRESS */
  396.                 OUT_RING(ring, 0x00000000);         /* VSC_PIPE[i].DATA_LENGTH */
  397.         }
  398. }
  399.  
  400. /* for rendering directly to system memory: */
  401. static void
  402. fd3_emit_sysmem_prep(struct fd_context *ctx)
  403. {
  404.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  405.         struct fd_resource *rsc = fd_resource(pfb->cbufs[0]->texture);
  406.         struct fd_ringbuffer *ring = ctx->ring;
  407.  
  408.         fd3_emit_restore(ctx);
  409.  
  410.         OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1);
  411.         OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) |
  412.                         A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height));
  413.  
  414.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0);
  415.  
  416.         fd3_emit_rbrc_tile_state(ring,
  417.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(rsc->pitch));
  418.  
  419.         /* setup scissor/offset for current tile: */
  420.         OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1);
  421.         OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(0) |
  422.                         A3XX_PA_SC_WINDOW_OFFSET_Y(0));
  423.  
  424.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  425.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  426.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  427.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb->width - 1) |
  428.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1));
  429.  
  430.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  431.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  432.                         A3XX_RB_MODE_CONTROL_GMEM_BYPASS |
  433.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  434. }
  435.  
  436. /* before first tile */
  437. static void
  438. fd3_emit_tile_init(struct fd_context *ctx)
  439. {
  440.         struct fd_ringbuffer *ring = ctx->ring;
  441.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  442.  
  443.         fd3_emit_restore(ctx);
  444.  
  445.         /* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated
  446.          * at the right and bottom edge tiles
  447.          */
  448.         OUT_PKT0(ring, REG_A3XX_VSC_BIN_SIZE, 1);
  449.         OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
  450.                         A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
  451.  
  452.         /* TODO we only need to do this if gmem stateobj changes.. or in
  453.          * particular if the # of bins changes..
  454.          */
  455.         update_vsc_pipe(ctx);
  456. }
  457.  
  458. /* before mem2gmem */
  459. static void
  460. fd3_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
  461.                 uint32_t bin_w, uint32_t bin_h)
  462. {
  463.         struct fd_ringbuffer *ring = ctx->ring;
  464.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  465.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  466.         uint32_t reg;
  467.  
  468.  
  469.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2);
  470.         reg = A3XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(gmem));
  471.         if (pfb->zsbuf) {
  472.                 reg |= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
  473.         }
  474.         OUT_RING(ring, reg);
  475.         if (pfb->zsbuf) {
  476.                 uint32_t cpp = util_format_get_blocksize(pfb->zsbuf->format);
  477.                 OUT_RING(ring, A3XX_RB_DEPTH_PITCH(cpp * gmem->bin_w));
  478.         } else {
  479.                 OUT_RING(ring, 0x00000000);
  480.         }
  481.  
  482.         OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1);
  483.         OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) |
  484.                         A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height));
  485.  
  486.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  487.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  488.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  489. }
  490.  
  491. /* before IB to rendering cmds: */
  492. static void
  493. fd3_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
  494.                 uint32_t bin_w, uint32_t bin_h)
  495. {
  496.         struct fd_ringbuffer *ring = ctx->ring;
  497.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  498.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  499.  
  500.         uint32_t x1 = xoff;
  501.         uint32_t y1 = yoff;
  502.         uint32_t x2 = xoff + bin_w - 1;
  503.         uint32_t y2 = yoff + bin_h - 1;
  504.  
  505.         OUT_PKT3(ring, CP_SET_BIN, 3);
  506.         OUT_RING(ring, 0x00000000);
  507.         OUT_RING(ring, CP_SET_BIN_1_X1(x1) | CP_SET_BIN_1_Y1(y1));
  508.         OUT_RING(ring, CP_SET_BIN_2_X2(x2) | CP_SET_BIN_2_Y2(y2));
  509.  
  510.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, gmem->bin_w);
  511.  
  512.         fd3_emit_rbrc_tile_state(ring,
  513.                         A3XX_RB_RENDER_CONTROL_ENABLE_GMEM |
  514.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
  515.  
  516.         /* setup scissor/offset for current tile: */
  517.         OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1);
  518.         OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(xoff) |
  519.                         A3XX_PA_SC_WINDOW_OFFSET_Y(yoff));
  520.  
  521.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  522.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) |
  523.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1));
  524.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) |
  525.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2));
  526. }
  527.  
  528. void
  529. fd3_gmem_init(struct pipe_context *pctx)
  530. {
  531.         struct fd_context *ctx = fd_context(pctx);
  532.  
  533.         ctx->emit_sysmem_prep = fd3_emit_sysmem_prep;
  534.         ctx->emit_tile_init = fd3_emit_tile_init;
  535.         ctx->emit_tile_prep = fd3_emit_tile_prep;
  536.         ctx->emit_tile_mem2gmem = fd3_emit_tile_mem2gmem;
  537.         ctx->emit_tile_renderprep = fd3_emit_tile_renderprep;
  538.         ctx->emit_tile_gmem2mem = fd3_emit_tile_gmem2mem;
  539. }
  540.