Subversion Repositories Kolibri OS

Rev

Rev 4358 | 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_RELOCW(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_RELOCW(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_GRAS_CL_VPORT_XOFFSET, 6);
  172.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)pfb->width/2.0 - 0.5));
  173.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)pfb->width/2.0));
  174.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)pfb->height/2.0 - 0.5));
  175.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)pfb->height/2.0));
  176.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  177.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
  178.  
  179.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  180.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  181.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  182.  
  183.         fd3_emit_rbrc_draw_state(ring,
  184.                         A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE |
  185.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER));
  186.  
  187.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  188.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
  189.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  190.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  191.  
  192.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  193.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
  194.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  195.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  196.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  197.  
  198.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
  199.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  200.                         A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  201.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(pfb->width - 1) |
  202.                         A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(pfb->height - 1));
  203.  
  204.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  205.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  206.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  207.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  208.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  209.  
  210.         fd3_program_emit(ring, &ctx->solid_prog);
  211.  
  212.         fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
  213.                         { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
  214.                 }, 1);
  215.  
  216.         if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
  217.                 uint32_t base = 0;
  218.                 if (pfb->cbufs[0]) {
  219.                         struct fd_resource *rsc =
  220.                                         fd_resource(pfb->cbufs[0]->texture);
  221.                         base = depth_base(&ctx->gmem) * rsc->cpp;
  222.                 }
  223.                 emit_gmem2mem_surf(ring, RB_COPY_DEPTH_STENCIL, base, pfb->zsbuf);
  224.         }
  225.  
  226.         if (ctx->resolve & FD_BUFFER_COLOR) {
  227.                 emit_gmem2mem_surf(ring, RB_COPY_RESOLVE, 0, pfb->cbufs[0]);
  228.         }
  229.  
  230.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  231.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  232.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  233.  
  234.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  235.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  236.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  237.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  238. }
  239.  
  240. /* transfer from system memory to gmem */
  241.  
  242. static void
  243. emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
  244.                 struct pipe_surface *psurf, uint32_t bin_w)
  245. {
  246.         emit_mrt(ring, 1, &psurf, &base, bin_w);
  247.  
  248.         fd3_emit_gmem_restore_tex(ring, psurf);
  249.  
  250.         OUT_PKT3(ring, CP_DRAW_INDX, 3);
  251.         OUT_RING(ring, 0x00000000);
  252.         OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
  253.                         INDEX_SIZE_IGN, IGNORE_VISIBILITY));
  254.         OUT_RING(ring, 2);                                      /* NumIndices */
  255. }
  256.  
  257. static void
  258. fd3_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
  259.                 uint32_t bin_w, uint32_t bin_h)
  260. {
  261.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  262.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  263.         struct fd_ringbuffer *ring = ctx->ring;
  264.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  265.         float x0, y0, x1, y1;
  266.         unsigned i;
  267.  
  268.         /* write texture coordinates to vertexbuf: */
  269.         x0 = ((float)xoff) / ((float)pfb->width);
  270.         x1 = ((float)xoff + bin_w) / ((float)pfb->width);
  271.         y0 = ((float)yoff) / ((float)pfb->height);
  272.         y1 = ((float)yoff + bin_h) / ((float)pfb->height);
  273.  
  274.         OUT_PKT3(ring, CP_MEM_WRITE, 5);
  275.         OUT_RELOC(ring, fd_resource(fd3_ctx->blit_texcoord_vbuf)->bo, 0, 0, 0);
  276.         OUT_RING(ring, fui(x0));
  277.         OUT_RING(ring, fui(y0));
  278.         OUT_RING(ring, fui(x1));
  279.         OUT_RING(ring, fui(y1));
  280.  
  281.         for (i = 0; i < 4; i++) {
  282.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
  283.                 OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(12) |
  284.                                 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE) |
  285.                                 A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
  286.  
  287.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1);
  288.                 OUT_RING(ring, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
  289.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  290.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
  291.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
  292.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  293.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO) |
  294.                                 A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE);
  295.         }
  296.  
  297.         fd3_emit_rbrc_tile_state(ring,
  298.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
  299.  
  300.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  301.         OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS));
  302.  
  303.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
  304.         OUT_RING(ring, A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER);   /* GRAS_CL_CLIP_CNTL */
  305.  
  306.         OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6);
  307.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)bin_w/2.0 - 0.5));
  308.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)bin_w/2.0));
  309.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)bin_h/2.0 - 0.5));
  310.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)bin_h/2.0));
  311.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  312.         OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
  313.  
  314.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
  315.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
  316.                         A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
  317.         OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w - 1) |
  318.                         A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h - 1));
  319.  
  320.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  321.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  322.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  323.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w - 1) |
  324.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h - 1));
  325.  
  326.         OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  327.         OUT_RING(ring, 0x2 |
  328.                         A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
  329.                         A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  330.                         A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  331.                         A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  332.                         A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_ALWAYS) |
  333.                         A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  334.                         A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  335.                         A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  336.  
  337.         fd3_emit_rbrc_draw_state(ring,
  338.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS));
  339.  
  340.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  341.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  342.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  343.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
  344.  
  345.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  346.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(2) |
  347.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  348.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  349.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  350.  
  351.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  352.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  353.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  354.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  355.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  356.  
  357.         fd3_program_emit(ring, &ctx->blit_prog);
  358.  
  359.         fd3_emit_vertex_bufs(ring, &ctx->blit_prog, (struct fd3_vertex_buf[]) {
  360.                         { .prsc = fd3_ctx->blit_texcoord_vbuf, .stride = 8, .format = PIPE_FORMAT_R32G32_FLOAT },
  361.                         { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
  362.                 }, 2);
  363.  
  364.         /* for gmem pitch/base calculations, we need to use the non-
  365.          * truncated tile sizes:
  366.          */
  367.         bin_w = gmem->bin_w;
  368.         bin_h = gmem->bin_h;
  369.  
  370.         if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
  371.                 emit_mem2gmem_surf(ring, depth_base(gmem), pfb->zsbuf, bin_w);
  372.  
  373.         if (ctx->restore & FD_BUFFER_COLOR)
  374.                 emit_mem2gmem_surf(ring, 0, pfb->cbufs[0], bin_w);
  375.  
  376.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
  377.         OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  378.                         A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
  379.                         A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
  380. }
  381.  
  382. static void
  383. update_vsc_pipe(struct fd_context *ctx)
  384. {
  385.         struct fd_ringbuffer *ring = ctx->ring;
  386.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  387.         struct fd_bo *bo = fd3_context(ctx)->vsc_pipe_mem;
  388.         int i;
  389.  
  390.         /* since we aren't using binning, just try to assign all bins
  391.          * to same pipe for now:
  392.          */
  393.         OUT_PKT0(ring, REG_A3XX_VSC_PIPE(0), 3);
  394.         OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
  395.                         A3XX_VSC_PIPE_CONFIG_Y(0) |
  396.                         A3XX_VSC_PIPE_CONFIG_W(gmem->nbins_x) |
  397.                         A3XX_VSC_PIPE_CONFIG_H(gmem->nbins_y));
  398.         OUT_RELOC(ring, bo, 0, 0, 0);           /* VSC_PIPE[0].DATA_ADDRESS */
  399.         OUT_RING(ring, fd_bo_size(bo) - 32);    /* VSC_PIPE[0].DATA_LENGTH */
  400.  
  401.         for (i = 1; i < 8; i++) {
  402.                 OUT_PKT0(ring, REG_A3XX_VSC_PIPE(i), 3);
  403.                 OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
  404.                                 A3XX_VSC_PIPE_CONFIG_Y(0) |
  405.                                 A3XX_VSC_PIPE_CONFIG_W(0) |
  406.                                 A3XX_VSC_PIPE_CONFIG_H(0));
  407.                 OUT_RING(ring, 0x00000000);         /* VSC_PIPE[i].DATA_ADDRESS */
  408.                 OUT_RING(ring, 0x00000000);         /* VSC_PIPE[i].DATA_LENGTH */
  409.         }
  410. }
  411.  
  412. /* for rendering directly to system memory: */
  413. static void
  414. fd3_emit_sysmem_prep(struct fd_context *ctx)
  415. {
  416.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  417.         struct fd_ringbuffer *ring = ctx->ring;
  418.         uint32_t pitch = 0;
  419.  
  420.         if (pfb->cbufs[0])
  421.                 pitch = fd_resource(pfb->cbufs[0]->texture)->pitch;
  422.  
  423.         fd3_emit_restore(ctx);
  424.  
  425.         OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1);
  426.         OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) |
  427.                         A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height));
  428.  
  429.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0);
  430.  
  431.         fd3_emit_rbrc_tile_state(ring,
  432.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(pitch));
  433.  
  434.         /* setup scissor/offset for current tile: */
  435.         OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1);
  436.         OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(0) |
  437.                         A3XX_PA_SC_WINDOW_OFFSET_Y(0));
  438.  
  439.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  440.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
  441.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
  442.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb->width - 1) |
  443.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1));
  444.  
  445.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  446.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  447.                         A3XX_RB_MODE_CONTROL_GMEM_BYPASS |
  448.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  449. }
  450.  
  451. /* before first tile */
  452. static void
  453. fd3_emit_tile_init(struct fd_context *ctx)
  454. {
  455.         struct fd_ringbuffer *ring = ctx->ring;
  456.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  457.  
  458.         fd3_emit_restore(ctx);
  459.  
  460.         /* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated
  461.          * at the right and bottom edge tiles
  462.          */
  463.         OUT_PKT0(ring, REG_A3XX_VSC_BIN_SIZE, 1);
  464.         OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
  465.                         A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
  466.  
  467.         /* TODO we only need to do this if gmem stateobj changes.. or in
  468.          * particular if the # of bins changes..
  469.          */
  470.         update_vsc_pipe(ctx);
  471. }
  472.  
  473. /* before mem2gmem */
  474. static void
  475. fd3_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
  476.                 uint32_t bin_w, uint32_t bin_h)
  477. {
  478.         struct fd_ringbuffer *ring = ctx->ring;
  479.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  480.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  481.         uint32_t reg;
  482.  
  483.  
  484.         OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2);
  485.         reg = A3XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(gmem));
  486.         if (pfb->zsbuf) {
  487.                 reg |= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
  488.         }
  489.         OUT_RING(ring, reg);
  490.         if (pfb->zsbuf) {
  491.                 uint32_t cpp = util_format_get_blocksize(pfb->zsbuf->format);
  492.                 OUT_RING(ring, A3XX_RB_DEPTH_PITCH(cpp * gmem->bin_w));
  493.         } else {
  494.                 OUT_RING(ring, 0x00000000);
  495.         }
  496.  
  497.         OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1);
  498.         OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) |
  499.                         A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height));
  500.  
  501.         OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
  502.         OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
  503.                         A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
  504. }
  505.  
  506. /* before IB to rendering cmds: */
  507. static void
  508. fd3_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
  509.                 uint32_t bin_w, uint32_t bin_h)
  510. {
  511.         struct fd_ringbuffer *ring = ctx->ring;
  512.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  513.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  514.  
  515.         uint32_t x1 = xoff;
  516.         uint32_t y1 = yoff;
  517.         uint32_t x2 = xoff + bin_w - 1;
  518.         uint32_t y2 = yoff + bin_h - 1;
  519.  
  520.         OUT_PKT3(ring, CP_SET_BIN, 3);
  521.         OUT_RING(ring, 0x00000000);
  522.         OUT_RING(ring, CP_SET_BIN_1_X1(x1) | CP_SET_BIN_1_Y1(y1));
  523.         OUT_RING(ring, CP_SET_BIN_2_X2(x2) | CP_SET_BIN_2_Y2(y2));
  524.  
  525.         emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, gmem->bin_w);
  526.  
  527.         fd3_emit_rbrc_tile_state(ring,
  528.                         A3XX_RB_RENDER_CONTROL_ENABLE_GMEM |
  529.                         A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
  530.  
  531.         /* setup scissor/offset for current tile: */
  532.         OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1);
  533.         OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(xoff) |
  534.                         A3XX_PA_SC_WINDOW_OFFSET_Y(yoff));
  535.  
  536.         OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
  537.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) |
  538.                         A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1));
  539.         OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) |
  540.                         A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2));
  541. }
  542.  
  543. void
  544. fd3_gmem_init(struct pipe_context *pctx)
  545. {
  546.         struct fd_context *ctx = fd_context(pctx);
  547.  
  548.         ctx->emit_sysmem_prep = fd3_emit_sysmem_prep;
  549.         ctx->emit_tile_init = fd3_emit_tile_init;
  550.         ctx->emit_tile_prep = fd3_emit_tile_prep;
  551.         ctx->emit_tile_mem2gmem = fd3_emit_tile_mem2gmem;
  552.         ctx->emit_tile_renderprep = fd3_emit_tile_renderprep;
  553.         ctx->emit_tile_gmem2mem = fd3_emit_tile_gmem2mem;
  554. }
  555.