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