1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
4 * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
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:
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
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
26 * Rob Clark <robclark@freedesktop.org>
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"
35 #include "freedreno_state.h"
36 #include "freedreno_resource.h"
39 #include "fd3_context.h"
41 #include "fd3_program.h"
47 emit_mrt(struct fd_ringbuffer
*ring
, unsigned nr_bufs
,
48 struct pipe_surface
**bufs
, uint32_t *bases
, uint32_t bin_w
)
50 enum a3xx_tile_mode tile_mode
;
54 tile_mode
= TILE_32X32
;
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
;
67 struct pipe_surface
*psurf
= bufs
[i
];
69 res
= fd_resource(psurf
->texture
);
70 format
= fd3_pipe2color(psurf
->format
);
71 swap
= fd3_pipe2swap(psurf
->format
);
74 stride
= bin_w
* res
->cpp
;
77 base
= bases
[i
] * res
->cpp
;
80 stride
= res
->pitch
* res
->cpp
;
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
));
92 OUT_RELOCW(ring
, res
->bo
, 0, 0, -1);
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
));
101 depth_base(struct fd_gmem_stateobj
*gmem
)
103 return align(gmem
->bin_w
* gmem
->bin_h
, 0x4000);
106 /* transfer from gmem to system memory (ie. normal RAM) */
109 emit_gmem2mem_surf(struct fd_ringbuffer
*ring
,
110 enum adreno_rb_copy_control_mode mode
,
111 uint32_t base
, struct pipe_surface
*psurf
)
113 struct fd_resource
*rsc
= fd_resource(psurf
->texture
);
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
)));
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 */
135 fd3_emit_tile_gmem2mem(struct fd_context
*ctx
, uint32_t xoff
, uint32_t yoff
,
136 uint32_t bin_w
, uint32_t bin_h
)
138 struct fd3_context
*fd3_ctx
= fd3_context(ctx
);
139 struct fd_ringbuffer
*ring
= ctx
->ring
;
140 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
142 OUT_PKT0(ring
, REG_A3XX_RB_DEPTH_CONTROL
, 1);
143 OUT_RING(ring
, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER
));
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
));
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));
165 OUT_PKT0(ring
, REG_A3XX_GRAS_SU_MODE_CONTROL
, 1);
166 OUT_RING(ring
, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
168 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_CLIP_CNTL
, 1);
169 OUT_RING(ring
, 0x00000000); /* GRAS_CL_CLIP_CNTL */
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));
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
);
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
));
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));
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
);
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));
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 */
210 fd3_program_emit(ring
, &ctx
->solid_prog
);
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
},
216 if (ctx
->resolve
& (FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
)) {
219 struct fd_resource
*rsc
=
220 fd_resource(pfb
->cbufs
[0]->texture
);
221 base
= depth_base(&ctx
->gmem
) * rsc
->cpp
;
223 emit_gmem2mem_surf(ring
, RB_COPY_DEPTH_STENCIL
, base
, pfb
->zsbuf
);
226 if (ctx
->resolve
& FD_BUFFER_COLOR
) {
227 emit_gmem2mem_surf(ring
, RB_COPY_RESOLVE
, 0, pfb
->cbufs
[0]);
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
);
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));
240 /* transfer from system memory to gmem */
243 emit_mem2gmem_surf(struct fd_ringbuffer
*ring
, uint32_t base
,
244 struct pipe_surface
*psurf
, uint32_t bin_w
)
246 emit_mrt(ring
, 1, &psurf
, &base
, bin_w
);
248 fd3_emit_gmem_restore_tex(ring
, psurf
);
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 */
258 fd3_emit_tile_mem2gmem(struct fd_context
*ctx
, uint32_t xoff
, uint32_t yoff
,
259 uint32_t bin_w
, uint32_t bin_h
)
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
;
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
);
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
));
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));
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
);
297 fd3_emit_rbrc_tile_state(ring
,
298 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem
->bin_w
));
300 OUT_PKT0(ring
, REG_A3XX_RB_DEPTH_CONTROL
, 1);
301 OUT_RING(ring
, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS
));
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 */
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));
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));
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));
326 OUT_PKT0(ring
, REG_A3XX_RB_STENCIL_CONTROL
, 1);
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
));
337 fd3_emit_rbrc_draw_state(ring
,
338 A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS
));
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));
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
);
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 */
357 fd3_program_emit(ring
, &ctx
->blit_prog
);
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
},
364 /* for gmem pitch/base calculations, we need to use the non-
365 * truncated tile sizes:
370 if (ctx
->restore
& (FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
))
371 emit_mem2gmem_surf(ring
, depth_base(gmem
), pfb
->zsbuf
, bin_w
);
373 if (ctx
->restore
& FD_BUFFER_COLOR
)
374 emit_mem2gmem_surf(ring
, 0, pfb
->cbufs
[0], bin_w
);
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));
383 update_vsc_pipe(struct fd_context
*ctx
)
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
;
390 /* since we aren't using binning, just try to assign all bins
391 * to same pipe for now:
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 */
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 */
412 /* for rendering directly to system memory: */
414 fd3_emit_sysmem_prep(struct fd_context
*ctx
)
416 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
417 struct fd_ringbuffer
*ring
= ctx
->ring
;
421 pitch
= fd_resource(pfb
->cbufs
[0]->texture
)->pitch
;
423 fd3_emit_restore(ctx
);
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
));
429 emit_mrt(ring
, pfb
->nr_cbufs
, pfb
->cbufs
, NULL
, 0);
431 fd3_emit_rbrc_tile_state(ring
,
432 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(pitch
));
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));
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));
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
);
451 /* before first tile */
453 fd3_emit_tile_init(struct fd_context
*ctx
)
455 struct fd_ringbuffer
*ring
= ctx
->ring
;
456 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
458 fd3_emit_restore(ctx
);
460 /* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated
461 * at the right and bottom edge tiles
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
));
467 /* TODO we only need to do this if gmem stateobj changes.. or in
468 * particular if the # of bins changes..
470 update_vsc_pipe(ctx
);
473 /* before mem2gmem */
475 fd3_emit_tile_prep(struct fd_context
*ctx
, uint32_t xoff
, uint32_t yoff
,
476 uint32_t bin_w
, uint32_t bin_h
)
478 struct fd_ringbuffer
*ring
= ctx
->ring
;
479 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
480 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
484 OUT_PKT0(ring
, REG_A3XX_RB_DEPTH_INFO
, 2);
485 reg
= A3XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(gmem
));
487 reg
|= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb
->zsbuf
->format
));
491 uint32_t cpp
= util_format_get_blocksize(pfb
->zsbuf
->format
);
492 OUT_RING(ring
, A3XX_RB_DEPTH_PITCH(cpp
* gmem
->bin_w
));
494 OUT_RING(ring
, 0x00000000);
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
));
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
);
506 /* before IB to rendering cmds: */
508 fd3_emit_tile_renderprep(struct fd_context
*ctx
, uint32_t xoff
, uint32_t yoff
,
509 uint32_t bin_w
, uint32_t bin_h
)
511 struct fd_ringbuffer
*ring
= ctx
->ring
;
512 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
513 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
517 uint32_t x2
= xoff
+ bin_w
- 1;
518 uint32_t y2
= yoff
+ bin_h
- 1;
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
));
525 emit_mrt(ring
, pfb
->nr_cbufs
, pfb
->cbufs
, NULL
, gmem
->bin_w
);
527 fd3_emit_rbrc_tile_state(ring
,
528 A3XX_RB_RENDER_CONTROL_ENABLE_GMEM
|
529 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem
->bin_w
));
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
));
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
));
544 fd3_gmem_init(struct pipe_context
*pctx
)
546 struct fd_context
*ctx
= fd_context(pctx
);
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
;