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) 2012 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.  
  34. #include "freedreno_draw.h"
  35. #include "freedreno_state.h"
  36. #include "freedreno_resource.h"
  37.  
  38. #include "fd2_gmem.h"
  39. #include "fd2_context.h"
  40. #include "fd2_emit.h"
  41. #include "fd2_program.h"
  42. #include "fd2_util.h"
  43. #include "fd2_zsa.h"
  44.  
  45. static uint32_t fmt2swap(enum pipe_format format)
  46. {
  47.         switch (format) {
  48.         case PIPE_FORMAT_B8G8R8A8_UNORM:
  49.         /* TODO probably some more.. */
  50.                 return 1;
  51.         default:
  52.                 return 0;
  53.         }
  54. }
  55.  
  56. /* transfer from gmem to system memory (ie. normal RAM) */
  57.  
  58. static void
  59. emit_gmem2mem_surf(struct fd_context *ctx, uint32_t base,
  60.                 struct pipe_surface *psurf)
  61. {
  62.         struct fd_ringbuffer *ring = ctx->ring;
  63.         struct fd_resource *rsc = fd_resource(psurf->texture);
  64.         uint32_t swap = fmt2swap(psurf->format);
  65.  
  66.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  67.         OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
  68.         OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(swap) |
  69.                         A2XX_RB_COLOR_INFO_BASE(base) |
  70.                         A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format)));
  71.  
  72.         OUT_PKT3(ring, CP_SET_CONSTANT, 5);
  73.         OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL));
  74.         OUT_RING(ring, 0x00000000);             /* RB_COPY_CONTROL */
  75.         OUT_RELOCW(ring, rsc->bo, 0, 0, 0);     /* RB_COPY_DEST_BASE */
  76.         OUT_RING(ring, rsc->slices[0].pitch >> 5); /* RB_COPY_DEST_PITCH */
  77.         OUT_RING(ring,                          /* RB_COPY_DEST_INFO */
  78.                         A2XX_RB_COPY_DEST_INFO_FORMAT(fd2_pipe2color(psurf->format)) |
  79.                         A2XX_RB_COPY_DEST_INFO_LINEAR |
  80.                         A2XX_RB_COPY_DEST_INFO_SWAP(swap) |
  81.                         A2XX_RB_COPY_DEST_INFO_WRITE_RED |
  82.                         A2XX_RB_COPY_DEST_INFO_WRITE_GREEN |
  83.                         A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
  84.                         A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
  85.  
  86.         OUT_WFI (ring);
  87.  
  88.         OUT_PKT3(ring, CP_SET_CONSTANT, 3);
  89.         OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
  90.         OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
  91.         OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
  92.  
  93.         fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
  94.                         DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL);
  95. }
  96.  
  97. static void
  98. fd2_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
  99. {
  100.         struct fd2_context *fd2_ctx = fd2_context(ctx);
  101.         struct fd_ringbuffer *ring = ctx->ring;
  102.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  103.  
  104.         fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
  105.                         { .prsc = fd2_ctx->solid_vertexbuf, .size = 48 },
  106.                 }, 1);
  107.  
  108.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  109.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
  110.         OUT_RING(ring, 0x00000000);          /* PA_SC_WINDOW_OFFSET */
  111.  
  112.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  113.         OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
  114.         OUT_RING(ring, 0);
  115.  
  116.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  117.         OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
  118.         OUT_RING(ring, 0x0000028f);
  119.  
  120.         fd2_program_emit(ring, &ctx->solid_prog);
  121.  
  122.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  123.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
  124.         OUT_RING(ring, 0x0000ffff);
  125.  
  126.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  127.         OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
  128.         OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
  129.  
  130.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  131.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
  132.         OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST |  /* PA_SU_SC_MODE_CNTL */
  133.                         A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  134.                         A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
  135.  
  136.         OUT_PKT3(ring, CP_SET_CONSTANT, 3);
  137.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
  138.         OUT_RING(ring, xy2d(0, 0));                       /* PA_SC_WINDOW_SCISSOR_TL */
  139.         OUT_RING(ring, xy2d(pfb->width, pfb->height));    /* PA_SC_WINDOW_SCISSOR_BR */
  140.  
  141.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  142.         OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
  143.         OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
  144.                         A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
  145.                         A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
  146.                         A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
  147.                         A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
  148.  
  149.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  150.         OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
  151.         OUT_RING(ring, 0x00000000);
  152.  
  153.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  154.         OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
  155.         OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(EDRAM_COPY));
  156.  
  157.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  158.         OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_OFFSET));
  159.         OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(tile->xoff) |
  160.                         A2XX_RB_COPY_DEST_OFFSET_Y(tile->yoff));
  161.  
  162.         if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
  163.                 emit_gmem2mem_surf(ctx, tile->bin_w * tile->bin_h, pfb->zsbuf);
  164.  
  165.         if (ctx->resolve & FD_BUFFER_COLOR)
  166.                 emit_gmem2mem_surf(ctx, 0, pfb->cbufs[0]);
  167.  
  168.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  169.         OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL));
  170.         OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH));
  171. }
  172.  
  173. /* transfer from system memory to gmem */
  174.  
  175. static void
  176. emit_mem2gmem_surf(struct fd_context *ctx, uint32_t base,
  177.                 struct pipe_surface *psurf)
  178. {
  179.         struct fd_ringbuffer *ring = ctx->ring;
  180.         struct fd_resource *rsc = fd_resource(psurf->texture);
  181.         uint32_t swiz;
  182.  
  183.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  184.         OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
  185.         OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(psurf->format)) |
  186.                         A2XX_RB_COLOR_INFO_BASE(base) |
  187.                         A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format)));
  188.  
  189.         swiz = fd2_tex_swiz(psurf->format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN,
  190.                         PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA);
  191.  
  192.         /* emit fb as a texture: */
  193.         OUT_PKT3(ring, CP_SET_CONSTANT, 7);
  194.         OUT_RING(ring, 0x00010000);
  195.         OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) |
  196.                         A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) |
  197.                         A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
  198.                         A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch));
  199.         OUT_RELOC(ring, rsc->bo, 0,
  200.                         fd2_pipe2surface(psurf->format) | 0x800, 0);
  201.         OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) |
  202.                         A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1));
  203.         OUT_RING(ring, 0x01000000 | // XXX
  204.                         swiz |
  205.                         A2XX_SQ_TEX_3_XY_MAG_FILTER(SQ_TEX_FILTER_POINT) |
  206.                         A2XX_SQ_TEX_3_XY_MIN_FILTER(SQ_TEX_FILTER_POINT));
  207.         OUT_RING(ring, 0x00000000);
  208.         OUT_RING(ring, 0x00000200);
  209.  
  210.         OUT_PKT3(ring, CP_SET_CONSTANT, 3);
  211.         OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
  212.         OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
  213.         OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
  214.  
  215.         fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
  216.                         DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL);
  217. }
  218.  
  219. static void
  220. fd2_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
  221. {
  222.         struct fd2_context *fd2_ctx = fd2_context(ctx);
  223.         struct fd_ringbuffer *ring = ctx->ring;
  224.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  225.         unsigned bin_w = tile->bin_w;
  226.         unsigned bin_h = tile->bin_h;
  227.         float x0, y0, x1, y1;
  228.  
  229.         fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
  230.                         { .prsc = fd2_ctx->solid_vertexbuf, .size = 48, .offset = 0x30 },
  231.                         { .prsc = fd2_ctx->solid_vertexbuf, .size = 32, .offset = 0x60 },
  232.                 }, 2);
  233.  
  234.         /* write texture coordinates to vertexbuf: */
  235.         x0 = ((float)tile->xoff) / ((float)pfb->width);
  236.         x1 = ((float)tile->xoff + bin_w) / ((float)pfb->width);
  237.         y0 = ((float)tile->yoff) / ((float)pfb->height);
  238.         y1 = ((float)tile->yoff + bin_h) / ((float)pfb->height);
  239.         OUT_PKT3(ring, CP_MEM_WRITE, 9);
  240.         OUT_RELOC(ring, fd_resource(fd2_ctx->solid_vertexbuf)->bo, 0x60, 0, 0);
  241.         OUT_RING(ring, fui(x0));
  242.         OUT_RING(ring, fui(y0));
  243.         OUT_RING(ring, fui(x1));
  244.         OUT_RING(ring, fui(y0));
  245.         OUT_RING(ring, fui(x0));
  246.         OUT_RING(ring, fui(y1));
  247.         OUT_RING(ring, fui(x1));
  248.         OUT_RING(ring, fui(y1));
  249.  
  250.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  251.         OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
  252.         OUT_RING(ring, 0);
  253.  
  254.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  255.         OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL));
  256.         OUT_RING(ring, 0x0000003b);
  257.  
  258.         fd2_program_emit(ring, &ctx->blit_prog[0]);
  259.  
  260.         OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
  261.         OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
  262.  
  263.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  264.         OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
  265.         OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE);
  266.  
  267.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  268.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL));
  269.         OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST |
  270.                         A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  271.                         A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES));
  272.  
  273.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  274.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
  275.         OUT_RING(ring, 0x0000ffff);
  276.  
  277.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  278.         OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
  279.         OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(PIPE_FUNC_ALWAYS) |
  280.                         A2XX_RB_COLORCONTROL_BLEND_DISABLE |
  281.                         A2XX_RB_COLORCONTROL_ROP_CODE(12) |
  282.                         A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) |
  283.                         A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL));
  284.  
  285.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  286.         OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
  287.         OUT_RING(ring, A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(FACTOR_ONE) |
  288.                         A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND_DST_PLUS_SRC) |
  289.                         A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(FACTOR_ZERO) |
  290.                         A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(FACTOR_ONE) |
  291.                         A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND_DST_PLUS_SRC) |
  292.                         A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(FACTOR_ZERO));
  293.  
  294.         OUT_PKT3(ring, CP_SET_CONSTANT, 3);
  295.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
  296.         OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_DISABLE |
  297.                         xy2d(0,0));                     /* PA_SC_WINDOW_SCISSOR_TL */
  298.         OUT_RING(ring, xy2d(bin_w, bin_h));     /* PA_SC_WINDOW_SCISSOR_BR */
  299.  
  300.         OUT_PKT3(ring, CP_SET_CONSTANT, 5);
  301.         OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
  302.         OUT_RING(ring, fui((float)bin_w/2.0));  /* PA_CL_VPORT_XSCALE */
  303.         OUT_RING(ring, fui((float)bin_w/2.0));  /* PA_CL_VPORT_XOFFSET */
  304.         OUT_RING(ring, fui(-(float)bin_h/2.0)); /* PA_CL_VPORT_YSCALE */
  305.         OUT_RING(ring, fui((float)bin_h/2.0));  /* PA_CL_VPORT_YOFFSET */
  306.  
  307.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  308.         OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
  309.         OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT |
  310.                         A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT |       // XXX check this???
  311.                         A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
  312.                         A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
  313.                         A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
  314.                         A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA);
  315.  
  316.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  317.         OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
  318.         OUT_RING(ring, 0x00000000);
  319.  
  320.         if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
  321.                 emit_mem2gmem_surf(ctx, bin_w * bin_h, pfb->zsbuf);
  322.  
  323.         if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_COLOR))
  324.                 emit_mem2gmem_surf(ctx, 0, pfb->cbufs[0]);
  325.  
  326.         /* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */
  327. }
  328.  
  329. /* before first tile */
  330. static void
  331. fd2_emit_tile_init(struct fd_context *ctx)
  332. {
  333.         struct fd_ringbuffer *ring = ctx->ring;
  334.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  335.         struct fd_gmem_stateobj *gmem = &ctx->gmem;
  336.         enum pipe_format format = pipe_surface_format(pfb->cbufs[0]);
  337.         uint32_t reg;
  338.  
  339.         OUT_PKT3(ring, CP_SET_CONSTANT, 4);
  340.         OUT_RING(ring, CP_REG(REG_A2XX_RB_SURFACE_INFO));
  341.         OUT_RING(ring, gmem->bin_w);                 /* RB_SURFACE_INFO */
  342.         OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) |
  343.                         A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
  344.         reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(align(gmem->bin_w * gmem->bin_h, 4));
  345.         if (pfb->zsbuf)
  346.                 reg |= A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
  347.         OUT_RING(ring, reg);                         /* RB_DEPTH_INFO */
  348. }
  349.  
  350. /* before mem2gmem */
  351. static void
  352. fd2_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile)
  353. {
  354.         struct fd_ringbuffer *ring = ctx->ring;
  355.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  356.         enum pipe_format format = pipe_surface_format(pfb->cbufs[0]);
  357.  
  358.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  359.         OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
  360.         OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(1) | /* RB_COLOR_INFO */
  361.                         A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
  362.  
  363.         /* setup screen scissor for current tile (same for mem2gmem): */
  364.         OUT_PKT3(ring, CP_SET_CONSTANT, 3);
  365.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_SCREEN_SCISSOR_TL));
  366.         OUT_RING(ring, A2XX_PA_SC_SCREEN_SCISSOR_TL_X(0) |
  367.                         A2XX_PA_SC_SCREEN_SCISSOR_TL_Y(0));
  368.         OUT_RING(ring, A2XX_PA_SC_SCREEN_SCISSOR_BR_X(tile->bin_w) |
  369.                         A2XX_PA_SC_SCREEN_SCISSOR_BR_Y(tile->bin_h));
  370. }
  371.  
  372. /* before IB to rendering cmds: */
  373. static void
  374. fd2_emit_tile_renderprep(struct fd_context *ctx, struct fd_tile *tile)
  375. {
  376.         struct fd_ringbuffer *ring = ctx->ring;
  377.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  378.         enum pipe_format format = pipe_surface_format(pfb->cbufs[0]);
  379.  
  380.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  381.         OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
  382.         OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) |
  383.                         A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format)));
  384.  
  385.         /* setup window scissor and offset for current tile (different
  386.          * from mem2gmem):
  387.          */
  388.         OUT_PKT3(ring, CP_SET_CONSTANT, 2);
  389.         OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET));
  390.         OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-tile->xoff) |
  391.                         A2XX_PA_SC_WINDOW_OFFSET_Y(-tile->yoff));
  392. }
  393.  
  394. void
  395. fd2_gmem_init(struct pipe_context *pctx)
  396. {
  397.         struct fd_context *ctx = fd_context(pctx);
  398.  
  399.         ctx->emit_tile_init = fd2_emit_tile_init;
  400.         ctx->emit_tile_prep = fd2_emit_tile_prep;
  401.         ctx->emit_tile_mem2gmem = fd2_emit_tile_mem2gmem;
  402.         ctx->emit_tile_renderprep = fd2_emit_tile_renderprep;
  403.         ctx->emit_tile_gmem2mem = fd2_emit_tile_gmem2mem;
  404. }
  405.