1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 2 3 /* 4 * Copyright (C) 2012 Rob Clark <robclark (at) 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 (at) 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_batch *batch, uint32_t base, 60 struct pipe_surface *psurf) 61 { 62 struct fd_ringbuffer *ring = batch->gmem; 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(batch, 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_batch *batch, struct fd_tile *tile) 99 { 100 struct fd_context *ctx = batch->ctx; 101 struct fd2_context *fd2_ctx = fd2_context(ctx); 102 struct fd_ringbuffer *ring = batch->gmem; 103 struct pipe_framebuffer_state *pfb = &batch->framebuffer; 104 105 fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) { 106 { .prsc = fd2_ctx->solid_vertexbuf, .size = 48 }, 107 }, 1); 108 109 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 110 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET)); 111 OUT_RING(ring, 0x00000000); /* PA_SC_WINDOW_OFFSET */ 112 113 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 114 OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET)); 115 OUT_RING(ring, 0); 116 117 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 118 OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); 119 OUT_RING(ring, 0x0000028f); 120 121 fd2_program_emit(ring, &ctx->solid_prog); 122 123 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 124 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK)); 125 OUT_RING(ring, 0x0000ffff); 126 127 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 128 OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL)); 129 OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE); 130 131 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 132 OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL)); 133 OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | /* PA_SU_SC_MODE_CNTL */ 134 A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) | 135 A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES)); 136 137 OUT_PKT3(ring, CP_SET_CONSTANT, 3); 138 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL)); 139 OUT_RING(ring, xy2d(0, 0)); /* PA_SC_WINDOW_SCISSOR_TL */ 140 OUT_RING(ring, xy2d(pfb->width, pfb->height)); /* PA_SC_WINDOW_SCISSOR_BR */ 141 142 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 143 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL)); 144 OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT | 145 A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA | 146 A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA | 147 A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA | 148 A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA); 149 150 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 151 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL)); 152 OUT_RING(ring, 0x00000000); 153 154 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 155 OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL)); 156 OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(EDRAM_COPY)); 157 158 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 159 OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_OFFSET)); 160 OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(tile->xoff) | 161 A2XX_RB_COPY_DEST_OFFSET_Y(tile->yoff)); 162 163 if (batch->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) 164 emit_gmem2mem_surf(batch, tile->bin_w * tile->bin_h, pfb->zsbuf); 165 166 if (batch->resolve & FD_BUFFER_COLOR) 167 emit_gmem2mem_surf(batch, 0, pfb->cbufs[0]); 168 169 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 170 OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL)); 171 OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH)); 172 } 173 174 /* transfer from system memory to gmem */ 175 176 static void 177 emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base, 178 struct pipe_surface *psurf) 179 { 180 struct fd_ringbuffer *ring = batch->gmem; 181 struct fd_resource *rsc = fd_resource(psurf->texture); 182 uint32_t swiz; 183 184 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 185 OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO)); 186 OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(psurf->format)) | 187 A2XX_RB_COLOR_INFO_BASE(base) | 188 A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(psurf->format))); 189 190 swiz = fd2_tex_swiz(psurf->format, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, 191 PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W); 192 193 /* emit fb as a texture: */ 194 OUT_PKT3(ring, CP_SET_CONSTANT, 7); 195 OUT_RING(ring, 0x00010000); 196 OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) | 197 A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) | 198 A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) | 199 A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch)); 200 OUT_RELOC(ring, rsc->bo, 0, 201 fd2_pipe2surface(psurf->format) | 0x800, 0); 202 OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) | 203 A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1)); 204 OUT_RING(ring, 0x01000000 | // XXX 205 swiz | 206 A2XX_SQ_TEX_3_XY_MAG_FILTER(SQ_TEX_FILTER_POINT) | 207 A2XX_SQ_TEX_3_XY_MIN_FILTER(SQ_TEX_FILTER_POINT)); 208 OUT_RING(ring, 0x00000000); 209 OUT_RING(ring, 0x00000200); 210 211 OUT_PKT3(ring, CP_SET_CONSTANT, 3); 212 OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); 213 OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */ 214 OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */ 215 216 fd_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, 217 DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL); 218 } 219 220 static void 221 fd2_emit_tile_mem2gmem(struct fd_batch *batch, struct fd_tile *tile) 222 { 223 struct fd_context *ctx = batch->ctx; 224 struct fd2_context *fd2_ctx = fd2_context(ctx); 225 struct fd_ringbuffer *ring = batch->gmem; 226 struct pipe_framebuffer_state *pfb = &batch->framebuffer; 227 unsigned bin_w = tile->bin_w; 228 unsigned bin_h = tile->bin_h; 229 float x0, y0, x1, y1; 230 231 fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) { 232 { .prsc = fd2_ctx->solid_vertexbuf, .size = 48, .offset = 0x30 }, 233 { .prsc = fd2_ctx->solid_vertexbuf, .size = 32, .offset = 0x60 }, 234 }, 2); 235 236 /* write texture coordinates to vertexbuf: */ 237 x0 = ((float)tile->xoff) / ((float)pfb->width); 238 x1 = ((float)tile->xoff + bin_w) / ((float)pfb->width); 239 y0 = ((float)tile->yoff) / ((float)pfb->height); 240 y1 = ((float)tile->yoff + bin_h) / ((float)pfb->height); 241 OUT_PKT3(ring, CP_MEM_WRITE, 9); 242 OUT_RELOC(ring, fd_resource(fd2_ctx->solid_vertexbuf)->bo, 0x60, 0, 0); 243 OUT_RING(ring, fui(x0)); 244 OUT_RING(ring, fui(y0)); 245 OUT_RING(ring, fui(x1)); 246 OUT_RING(ring, fui(y0)); 247 OUT_RING(ring, fui(x0)); 248 OUT_RING(ring, fui(y1)); 249 OUT_RING(ring, fui(x1)); 250 OUT_RING(ring, fui(y1)); 251 252 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 253 OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET)); 254 OUT_RING(ring, 0); 255 256 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 257 OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); 258 OUT_RING(ring, 0x0000003b); 259 260 fd2_program_emit(ring, &ctx->blit_prog[0]); 261 262 OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1); 263 OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE); 264 265 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 266 OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL)); 267 OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE); 268 269 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 270 OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL)); 271 OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | 272 A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) | 273 A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES)); 274 275 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 276 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK)); 277 OUT_RING(ring, 0x0000ffff); 278 279 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 280 OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL)); 281 OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(PIPE_FUNC_ALWAYS) | 282 A2XX_RB_COLORCONTROL_BLEND_DISABLE | 283 A2XX_RB_COLORCONTROL_ROP_CODE(12) | 284 A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) | 285 A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL)); 286 287 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 288 OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL)); 289 OUT_RING(ring, A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(FACTOR_ONE) | 290 A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND_DST_PLUS_SRC) | 291 A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(FACTOR_ZERO) | 292 A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(FACTOR_ONE) | 293 A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND_DST_PLUS_SRC) | 294 A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(FACTOR_ZERO)); 295 296 OUT_PKT3(ring, CP_SET_CONSTANT, 3); 297 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL)); 298 OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_DISABLE | 299 xy2d(0,0)); /* PA_SC_WINDOW_SCISSOR_TL */ 300 OUT_RING(ring, xy2d(bin_w, bin_h)); /* PA_SC_WINDOW_SCISSOR_BR */ 301 302 OUT_PKT3(ring, CP_SET_CONSTANT, 5); 303 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE)); 304 OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XSCALE */ 305 OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XOFFSET */ 306 OUT_RING(ring, fui(-(float)bin_h/2.0)); /* PA_CL_VPORT_YSCALE */ 307 OUT_RING(ring, fui((float)bin_h/2.0)); /* PA_CL_VPORT_YOFFSET */ 308 309 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 310 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL)); 311 OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT | 312 A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT | // XXX check this??? 313 A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA | 314 A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA | 315 A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA | 316 A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA); 317 318 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 319 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL)); 320 OUT_RING(ring, 0x00000000); 321 322 if (fd_gmem_needs_restore(batch, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) 323 emit_mem2gmem_surf(batch, bin_w * bin_h, pfb->zsbuf); 324 325 if (fd_gmem_needs_restore(batch, tile, FD_BUFFER_COLOR)) 326 emit_mem2gmem_surf(batch, 0, pfb->cbufs[0]); 327 328 /* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */ 329 } 330 331 /* before first tile */ 332 static void 333 fd2_emit_tile_init(struct fd_batch *batch) 334 { 335 struct fd_context *ctx = batch->ctx; 336 struct fd_ringbuffer *ring = batch->gmem; 337 struct pipe_framebuffer_state *pfb = &batch->framebuffer; 338 struct fd_gmem_stateobj *gmem = &ctx->gmem; 339 enum pipe_format format = pipe_surface_format(pfb->cbufs[0]); 340 uint32_t reg; 341 342 fd2_emit_restore(ctx, ring); 343 344 OUT_PKT3(ring, CP_SET_CONSTANT, 4); 345 OUT_RING(ring, CP_REG(REG_A2XX_RB_SURFACE_INFO)); 346 OUT_RING(ring, gmem->bin_w); /* RB_SURFACE_INFO */ 347 OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) | 348 A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format))); 349 reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(align(gmem->bin_w * gmem->bin_h, 4)); 350 if (pfb->zsbuf) 351 reg |= A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format)); 352 OUT_RING(ring, reg); /* RB_DEPTH_INFO */ 353 } 354 355 /* before mem2gmem */ 356 static void 357 fd2_emit_tile_prep(struct fd_batch *batch, struct fd_tile *tile) 358 { 359 struct fd_ringbuffer *ring = batch->gmem; 360 struct pipe_framebuffer_state *pfb = &batch->framebuffer; 361 enum pipe_format format = pipe_surface_format(pfb->cbufs[0]); 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, A2XX_PA_SC_SCREEN_SCISSOR_TL_X(0) | 372 A2XX_PA_SC_SCREEN_SCISSOR_TL_Y(0)); 373 OUT_RING(ring, A2XX_PA_SC_SCREEN_SCISSOR_BR_X(tile->bin_w) | 374 A2XX_PA_SC_SCREEN_SCISSOR_BR_Y(tile->bin_h)); 375 } 376 377 /* before IB to rendering cmds: */ 378 static void 379 fd2_emit_tile_renderprep(struct fd_batch *batch, struct fd_tile *tile) 380 { 381 struct fd_ringbuffer *ring = batch->gmem; 382 struct pipe_framebuffer_state *pfb = &batch->framebuffer; 383 enum pipe_format format = pipe_surface_format(pfb->cbufs[0]); 384 385 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 386 OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO)); 387 OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(format)) | 388 A2XX_RB_COLOR_INFO_FORMAT(fd2_pipe2color(format))); 389 390 /* setup window scissor and offset for current tile (different 391 * from mem2gmem): 392 */ 393 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 394 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET)); 395 OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-tile->xoff) | 396 A2XX_PA_SC_WINDOW_OFFSET_Y(-tile->yoff)); 397 } 398 399 void 400 fd2_gmem_init(struct pipe_context *pctx) 401 { 402 struct fd_context *ctx = fd_context(pctx); 403 404 ctx->emit_tile_init = fd2_emit_tile_init; 405 ctx->emit_tile_prep = fd2_emit_tile_prep; 406 ctx->emit_tile_mem2gmem = fd2_emit_tile_mem2gmem; 407 ctx->emit_tile_renderprep = fd2_emit_tile_renderprep; 408 ctx->emit_tile_gmem2mem = fd2_emit_tile_gmem2mem; 409 } 410