2 * Copyright (C) 2016 Rob Clark <robclark@freedesktop.org>
3 * Copyright © 2018 Google, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Rob Clark <robclark@freedesktop.org>
30 #include "pipe/p_state.h"
31 #include "util/u_string.h"
32 #include "util/u_memory.h"
33 #include "util/u_inlines.h"
34 #include "util/u_format.h"
36 #include "freedreno_draw.h"
37 #include "freedreno_state.h"
38 #include "freedreno_resource.h"
41 #include "fd6_context.h"
44 #include "fd6_program.h"
45 #include "fd6_format.h"
48 /* some bits in common w/ a4xx: */
49 #include "a4xx/fd4_draw.h"
52 emit_mrt(struct fd_ringbuffer
*ring
, unsigned nr_bufs
,
53 struct pipe_surface
**bufs
, struct fd_gmem_stateobj
*gmem
)
55 enum a6xx_tile_mode tile_mode
;
56 unsigned srgb_cntl
= 0;
59 for (i
= 0; i
< nr_bufs
; i
++) {
60 enum a6xx_color_fmt format
= 0;
61 enum a3xx_color_swap swap
= WZYX
;
62 bool sint
= false, uint
= false;
63 struct fd_resource
*rsc
= NULL
;
64 struct fd_resource_slice
*slice
= NULL
;
71 tile_mode
= TILE6_LINEAR
;
77 struct pipe_surface
*psurf
= bufs
[i
];
78 enum pipe_format pformat
= psurf
->format
;
79 rsc
= fd_resource(psurf
->texture
);
83 uint32_t base
= gmem
? gmem
->cbuf_base
[i
] : 0;
84 slice
= fd_resource_slice(rsc
, psurf
->u
.tex
.level
);
85 format
= fd6_pipe2color(pformat
);
86 swap
= fd6_pipe2swap(pformat
);
87 sint
= util_format_is_pure_sint(pformat
);
88 uint
= util_format_is_pure_uint(pformat
);
90 if (util_format_is_srgb(pformat
))
91 srgb_cntl
|= (1 << i
);
93 offset
= fd_resource_offset(rsc
, psurf
->u
.tex
.level
,
94 psurf
->u
.tex
.first_layer
);
96 stride
= slice
->pitch
* rsc
->cpp
;
98 debug_assert(psurf
->u
.tex
.first_layer
== psurf
->u
.tex
.last_layer
);
99 debug_assert((offset
+ slice
->size0
) <= fd_bo_size(rsc
->bo
));
101 OUT_PKT4(ring
, REG_A6XX_RB_MRT_BUF_INFO(i
), 6);
102 OUT_RING(ring
, A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format
) |
103 A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(rsc
->tile_mode
) |
104 A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap
));
105 OUT_RING(ring
, A6XX_RB_MRT_PITCH(stride
));
106 OUT_RING(ring
, A6XX_RB_MRT_ARRAY_PITCH(slice
->size0
));
107 OUT_RELOCW(ring
, rsc
->bo
, offset
, 0, 0); /* BASE_LO/HI */
108 OUT_RING(ring
, base
); /* RB_MRT[i].BASE_GMEM */
109 OUT_PKT4(ring
, REG_A6XX_SP_FS_MRT_REG(i
), 1);
110 OUT_RING(ring
, A6XX_SP_FS_MRT_REG_COLOR_FORMAT(format
) |
111 COND(sint
, A6XX_SP_FS_MRT_REG_COLOR_SINT
) |
112 COND(uint
, A6XX_SP_FS_MRT_REG_COLOR_UINT
));
115 /* when we support UBWC, these would be the system memory
118 OUT_PKT4(ring
, REG_A6XX_RB_MRT_FLAG_BUFFER(i
), 4);
119 OUT_RING(ring
, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */
120 OUT_RING(ring
, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */
121 OUT_RING(ring
, A6XX_RB_MRT_FLAG_BUFFER_PITCH(0));
122 OUT_RING(ring
, A6XX_RB_MRT_FLAG_BUFFER_ARRAY_PITCH(0));
126 OUT_PKT4(ring
, REG_A6XX_RB_SRGB_CNTL
, 1);
127 OUT_RING(ring
, srgb_cntl
);
129 OUT_PKT4(ring
, REG_A6XX_SP_SRGB_CNTL
, 1);
130 OUT_RING(ring
, srgb_cntl
);
134 emit_zs(struct fd_ringbuffer
*ring
, struct pipe_surface
*zsbuf
,
135 struct fd_gmem_stateobj
*gmem
)
138 struct fd_resource
*rsc
= fd_resource(zsbuf
->texture
);
139 enum a6xx_depth_format fmt
= fd6_pipe2depth(zsbuf
->format
);
140 struct fd_resource_slice
*slice
= fd_resource_slice(rsc
, 0);
141 uint32_t stride
= slice
->pitch
* rsc
->cpp
;
142 uint32_t size
= slice
->size0
;
143 uint32_t base
= gmem
? gmem
->zsbuf_base
[0] : 0;
145 OUT_PKT4(ring
, REG_A6XX_RB_DEPTH_BUFFER_INFO
, 6);
146 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt
));
147 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_PITCH(stride
));
148 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(size
));
149 OUT_RELOCW(ring
, rsc
->bo
, 0, 0, 0); /* RB_DEPTH_BUFFER_BASE_LO/HI */
150 OUT_RING(ring
, base
); /* RB_DEPTH_BUFFER_BASE_GMEM */
152 OUT_PKT4(ring
, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO
, 1);
153 OUT_RING(ring
, A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt
));
155 OUT_PKT4(ring
, REG_A6XX_RB_DEPTH_FLAG_BUFFER_BASE_LO
, 3);
156 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_LO */
157 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_HI */
158 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_PITCH */
161 OUT_PKT4(ring
, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO
, 5);
162 OUT_RELOCW(ring
, rsc
->lrz
, 0x1000, 0, 0);
163 OUT_RING(ring
, A6XX_GRAS_LRZ_BUFFER_PITCH_PITCH(rsc
->lrz_pitch
));
164 OUT_RELOCW(ring
, rsc
->lrz
, 0, 0, 0); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO/HI */
166 OUT_PKT4(ring
, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO
, 5);
167 OUT_RING(ring
, 0x00000000);
168 OUT_RING(ring
, 0x00000000);
169 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_BUFFER_PITCH */
170 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO */
171 OUT_RING(ring
, 0x00000000);
175 struct fd_resource_slice
*slice
= fd_resource_slice(rsc
->stencil
, 0);
176 stride
= slice
->pitch
* rsc
->cpp
;
178 uint32_t base
= gmem
? gmem
->zsbuf_base
[1] : 0;
180 OUT_PKT4(ring
, REG_A6XX_RB_STENCIL_INFO
, 6);
181 OUT_RING(ring
, A6XX_RB_STENCIL_INFO_SEPARATE_STENCIL
);
182 OUT_RING(ring
, A6XX_RB_STENCIL_BUFFER_PITCH(stride
));
183 OUT_RING(ring
, A6XX_RB_STENCIL_BUFFER_ARRAY_PITCH(size
));
184 OUT_RELOCW(ring
, rsc
->stencil
->bo
, 0, 0, 0); /* RB_STENCIL_BASE_LO/HI */
185 OUT_RING(ring
, base
); /* RB_STENCIL_BASE_LO */
187 OUT_PKT4(ring
, REG_A6XX_RB_STENCIL_INFO
, 1);
188 OUT_RING(ring
, 0x00000000); /* RB_STENCIL_INFO */
191 OUT_PKT4(ring
, REG_A6XX_RB_DEPTH_BUFFER_INFO
, 6);
192 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(DEPTH6_NONE
));
193 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_PITCH */
194 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_ARRAY_PITCH */
195 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_BASE_LO */
196 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_BASE_HI */
197 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_BASE_GMEM */
199 OUT_PKT4(ring
, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO
, 1);
200 OUT_RING(ring
, A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(DEPTH6_NONE
));
202 OUT_PKT4(ring
, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO
, 5);
203 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_LO */
204 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_HI */
205 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_BUFFER_PITCH */
206 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO */
207 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_HI */
209 OUT_PKT4(ring
, REG_A6XX_RB_STENCIL_INFO
, 1);
210 OUT_RING(ring
, 0x00000000); /* RB_STENCIL_INFO */
215 use_hw_binning(struct fd_batch
*batch
)
217 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
219 // TODO figure out hw limits for binning
221 return fd_binning_enabled
&& ((gmem
->nbins_x
* gmem
->nbins_y
) > 2) &&
222 (batch
->num_draws
> 0);
226 patch_draws(struct fd_batch
*batch
, enum pc_di_vis_cull_mode vismode
)
229 for (i
= 0; i
< fd_patch_num_elements(&batch
->draw_patches
); i
++) {
230 struct fd_cs_patch
*patch
= fd_patch_element(&batch
->draw_patches
, i
);
231 *patch
->cs
= patch
->val
| DRAW4(0, 0, 0, vismode
);
233 util_dynarray_resize(&batch
->draw_patches
, 0);
237 patch_gmem_bases(struct fd_batch
*batch
)
239 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
242 for (i
= 0; i
< fd_patch_num_elements(&batch
->gmem_patches
); i
++) {
243 struct fd_cs_patch
*patch
= fd_patch_element(&batch
->gmem_patches
, i
);
244 if (patch
->val
< MAX_RENDER_TARGETS
)
245 *patch
->cs
= gmem
->cbuf_base
[patch
->val
];
247 *patch
->cs
= gmem
->zsbuf_base
[0];
249 util_dynarray_resize(&batch
->gmem_patches
, 0);
253 update_render_cntl(struct fd_batch
*batch
, bool binning
)
255 struct fd_ringbuffer
*ring
= batch
->gmem
;
258 cntl
|= A6XX_RB_RENDER_CNTL_UNK4
;
260 cntl
|= A6XX_RB_RENDER_CNTL_BINNING
;
262 OUT_PKT7(ring
, CP_REG_WRITE
, 3);
264 OUT_RING(ring
, REG_A6XX_RB_RENDER_CNTL
);
265 OUT_RING(ring
, cntl
);
269 update_vsc_pipe(struct fd_batch
*batch
)
271 struct fd_context
*ctx
= batch
->ctx
;
272 struct fd6_context
*fd6_ctx
= fd6_context(ctx
);
273 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
274 struct fd_ringbuffer
*ring
= batch
->gmem
;
275 unsigned n
= gmem
->nbins_x
* gmem
->nbins_y
;
278 OUT_PKT4(ring
, REG_A6XX_VSC_BIN_SIZE
, 3);
279 OUT_RING(ring
, A6XX_VSC_BIN_SIZE_WIDTH(gmem
->bin_w
) |
280 A6XX_VSC_BIN_SIZE_HEIGHT(gmem
->bin_h
));
281 OUT_RELOCW(ring
, fd6_ctx
->vsc_data
,
282 n
* A6XX_VSC_DATA_PITCH
, 0, 0); /* VSC_SIZE_ADDRESS_LO/HI */
284 OUT_PKT4(ring
, REG_A6XX_VSC_BIN_COUNT
, 1);
285 OUT_RING(ring
, A6XX_VSC_BIN_COUNT_NX(gmem
->nbins_x
) |
286 A6XX_VSC_BIN_COUNT_NY(gmem
->nbins_y
));
288 OUT_PKT4(ring
, REG_A6XX_VSC_PIPE_CONFIG_REG(0), 32);
289 for (i
= 0; i
< 32; i
++) {
290 struct fd_vsc_pipe
*pipe
= &ctx
->vsc_pipe
[i
];
291 OUT_RING(ring
, A6XX_VSC_PIPE_CONFIG_REG_X(pipe
->x
) |
292 A6XX_VSC_PIPE_CONFIG_REG_Y(pipe
->y
) |
293 A6XX_VSC_PIPE_CONFIG_REG_W(pipe
->w
) |
294 A6XX_VSC_PIPE_CONFIG_REG_H(pipe
->h
));
297 OUT_PKT4(ring
, REG_A6XX_VSC_PIPE_DATA2_ADDRESS_LO
, 4);
298 OUT_RELOCW(ring
, fd6_ctx
->vsc_data2
, 0, 0, 0);
299 OUT_RING(ring
, A6XX_VSC_DATA2_PITCH
);
300 OUT_RING(ring
, fd_bo_size(fd6_ctx
->vsc_data2
));
302 OUT_PKT4(ring
, REG_A6XX_VSC_PIPE_DATA_ADDRESS_LO
, 4);
303 OUT_RELOCW(ring
, fd6_ctx
->vsc_data
, 0, 0, 0);
304 OUT_RING(ring
, A6XX_VSC_DATA_PITCH
);
305 OUT_RING(ring
, fd_bo_size(fd6_ctx
->vsc_data
));
309 set_scissor(struct fd_ringbuffer
*ring
, uint32_t x1
, uint32_t y1
, uint32_t x2
, uint32_t y2
)
311 OUT_PKT4(ring
, REG_A6XX_GRAS_SC_WINDOW_SCISSOR_TL
, 2);
312 OUT_RING(ring
, A6XX_GRAS_SC_WINDOW_SCISSOR_TL_X(x1
) |
313 A6XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(y1
));
314 OUT_RING(ring
, A6XX_GRAS_SC_WINDOW_SCISSOR_BR_X(x2
) |
315 A6XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(y2
));
317 OUT_PKT4(ring
, REG_A6XX_GRAS_RESOLVE_CNTL_1
, 2);
318 OUT_RING(ring
, A6XX_GRAS_RESOLVE_CNTL_1_X(x1
) |
319 A6XX_GRAS_RESOLVE_CNTL_1_Y(y1
));
320 OUT_RING(ring
, A6XX_GRAS_RESOLVE_CNTL_2_X(x2
) |
321 A6XX_GRAS_RESOLVE_CNTL_2_Y(y2
));
325 set_bin_size(struct fd_ringbuffer
*ring
, uint32_t w
, uint32_t h
, uint32_t flag
)
327 OUT_PKT4(ring
, REG_A6XX_GRAS_BIN_CONTROL
, 1);
328 OUT_RING(ring
, A6XX_GRAS_BIN_CONTROL_BINW(w
) |
329 A6XX_GRAS_BIN_CONTROL_BINH(h
) | flag
);
331 OUT_PKT4(ring
, REG_A6XX_RB_BIN_CONTROL
, 1);
332 OUT_RING(ring
, A6XX_RB_BIN_CONTROL_BINW(w
) |
333 A6XX_RB_BIN_CONTROL_BINH(h
) | flag
);
335 /* no flag for RB_BIN_CONTROL2... */
336 OUT_PKT4(ring
, REG_A6XX_RB_BIN_CONTROL2
, 1);
337 OUT_RING(ring
, A6XX_RB_BIN_CONTROL2_BINW(w
) |
338 A6XX_RB_BIN_CONTROL2_BINH(h
));
342 emit_binning_pass(struct fd_batch
*batch
)
344 struct fd_context
*ctx
= batch
->ctx
;
345 struct fd_ringbuffer
*ring
= batch
->gmem
;
346 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
348 uint32_t x1
= gmem
->minx
;
349 uint32_t y1
= gmem
->miny
;
350 uint32_t x2
= gmem
->minx
+ gmem
->width
- 1;
351 uint32_t y2
= gmem
->miny
+ gmem
->height
- 1;
353 set_scissor(ring
, x1
, y1
, x2
, y2
);
355 emit_marker6(ring
, 7);
356 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
357 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_BINNING
));
358 emit_marker6(ring
, 7);
360 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
363 OUT_PKT7(ring
, CP_SET_MODE
, 1);
368 OUT_PKT4(ring
, REG_A6XX_VFD_MODE_CNTL
, 1);
369 OUT_RING(ring
, A6XX_VFD_MODE_CNTL_BINNING_PASS
);
371 update_vsc_pipe(batch
);
373 OUT_PKT4(ring
, REG_A6XX_PC_UNKNOWN_9805
, 1);
376 OUT_PKT4(ring
, REG_A6XX_SP_UNKNOWN_A0F8
, 1);
379 OUT_PKT7(ring
, CP_EVENT_WRITE
, 1);
380 OUT_RING(ring
, UNK_2C
);
382 OUT_PKT4(ring
, REG_A6XX_RB_WINDOW_OFFSET
, 1);
383 OUT_RING(ring
, A6XX_RB_WINDOW_OFFSET_X(0) |
384 A6XX_RB_WINDOW_OFFSET_Y(0));
386 OUT_PKT4(ring
, REG_A6XX_SP_TP_WINDOW_OFFSET
, 1);
387 OUT_RING(ring
, A6XX_SP_TP_WINDOW_OFFSET_X(0) |
388 A6XX_SP_TP_WINDOW_OFFSET_Y(0));
390 /* emit IB to binning drawcmds: */
391 ctx
->emit_ib(ring
, batch
->binning
);
395 OUT_PKT7(ring
, CP_SET_DRAW_STATE
, 3);
396 OUT_RING(ring
, CP_SET_DRAW_STATE__0_COUNT(0) |
397 CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS
|
398 CP_SET_DRAW_STATE__0_GROUP_ID(0));
399 OUT_RING(ring
, CP_SET_DRAW_STATE__1_ADDR_LO(0));
400 OUT_RING(ring
, CP_SET_DRAW_STATE__2_ADDR_HI(0));
402 OUT_PKT7(ring
, CP_EVENT_WRITE
, 1);
403 OUT_RING(ring
, UNK_2D
);
405 OUT_PKT7(ring
, CP_EVENT_WRITE
, 4);
406 OUT_RING(ring
, CACHE_FLUSH_TS
);
407 OUT_RELOCW(ring
, fd6_context(ctx
)->blit_mem
, 0, 0, 0); /* ADDR_LO/HI */
408 OUT_RING(ring
, 0x00000000);
414 disable_msaa(struct fd_ringbuffer
*ring
)
417 OUT_PKT4(ring
, REG_A6XX_SP_TP_RAS_MSAA_CNTL
, 2);
418 OUT_RING(ring
, A6XX_SP_TP_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE
));
419 OUT_RING(ring
, A6XX_SP_TP_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE
) |
420 A6XX_SP_TP_DEST_MSAA_CNTL_MSAA_DISABLE
);
422 OUT_PKT4(ring
, REG_A6XX_GRAS_RAS_MSAA_CNTL
, 2);
423 OUT_RING(ring
, A6XX_GRAS_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE
));
424 OUT_RING(ring
, A6XX_GRAS_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE
) |
425 A6XX_GRAS_DEST_MSAA_CNTL_MSAA_DISABLE
);
427 OUT_PKT4(ring
, REG_A6XX_RB_RAS_MSAA_CNTL
, 2);
428 OUT_RING(ring
, A6XX_RB_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE
));
429 OUT_RING(ring
, A6XX_RB_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE
) |
430 A6XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE
);
433 /* before first tile */
435 fd6_emit_tile_init(struct fd_batch
*batch
)
437 struct fd_context
*ctx
= batch
->ctx
;
438 struct fd_ringbuffer
*ring
= batch
->gmem
;
439 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
440 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
442 fd6_emit_restore(batch
, ring
);
444 if (batch
->lrz_clear
)
445 ctx
->emit_ib(ring
, batch
->lrz_clear
);
447 fd6_emit_lrz_flush(ring
);
449 fd6_cache_flush(batch
, ring
);
451 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
454 /* 0x10000000 for BYPASS.. 0x7c13c080 for GMEM: */
456 OUT_PKT4(ring
, REG_A6XX_RB_CCU_CNTL
, 1);
457 OUT_RING(ring
, 0x7c400004); /* RB_CCU_CNTL */
459 emit_zs(ring
, pfb
->zsbuf
, &ctx
->gmem
);
460 emit_mrt(ring
, pfb
->nr_cbufs
, pfb
->cbufs
, &ctx
->gmem
);
462 patch_gmem_bases(batch
);
466 if (use_hw_binning(batch
)) {
467 set_bin_size(ring
, gmem
->bin_w
, gmem
->bin_h
,
468 A6XX_RB_BIN_CONTROL_BINNING_PASS
| 0x6000000);
469 update_render_cntl(batch
, true);
470 emit_binning_pass(batch
);
471 fd6_emit_lrz_flush(ring
);
472 patch_draws(batch
, USE_VISIBILITY
);
474 set_bin_size(ring
, gmem
->bin_w
, gmem
->bin_h
,
475 A6XX_RB_BIN_CONTROL_USE_VIZ
| 0x6000000);
477 OUT_PKT4(ring
, REG_A6XX_VFD_MODE_CNTL
, 1);
480 set_bin_size(ring
, gmem
->bin_w
, gmem
->bin_h
, 0x6000000);
481 patch_draws(batch
, IGNORE_VISIBILITY
);
484 update_render_cntl(batch
, false);
488 set_window_offset(struct fd_ringbuffer
*ring
, uint32_t x1
, uint32_t y1
)
490 OUT_PKT4(ring
, REG_A6XX_RB_WINDOW_OFFSET
, 1);
491 OUT_RING(ring
, A6XX_RB_WINDOW_OFFSET_X(x1
) |
492 A6XX_RB_WINDOW_OFFSET_Y(y1
));
494 OUT_PKT4(ring
, REG_A6XX_RB_WINDOW_OFFSET2
, 1);
495 OUT_RING(ring
, A6XX_RB_WINDOW_OFFSET2_X(x1
) |
496 A6XX_RB_WINDOW_OFFSET2_Y(y1
));
498 OUT_PKT4(ring
, REG_A6XX_SP_WINDOW_OFFSET
, 1);
499 OUT_RING(ring
, A6XX_SP_WINDOW_OFFSET_X(x1
) |
500 A6XX_SP_WINDOW_OFFSET_Y(y1
));
502 OUT_PKT4(ring
, REG_A6XX_SP_TP_WINDOW_OFFSET
, 1);
503 OUT_RING(ring
, A6XX_SP_TP_WINDOW_OFFSET_X(x1
) |
504 A6XX_SP_TP_WINDOW_OFFSET_Y(y1
));
507 /* before mem2gmem */
509 fd6_emit_tile_prep(struct fd_batch
*batch
, struct fd_tile
*tile
)
511 struct fd_context
*ctx
= batch
->ctx
;
512 struct fd6_context
*fd6_ctx
= fd6_context(ctx
);
513 struct fd_ringbuffer
*ring
= batch
->gmem
;
515 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
516 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(0x7));
518 emit_marker6(ring
, 7);
519 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
520 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_GMEM
) | 0x10);
521 emit_marker6(ring
, 7);
523 uint32_t x1
= tile
->xoff
;
524 uint32_t y1
= tile
->yoff
;
525 uint32_t x2
= tile
->xoff
+ tile
->bin_w
- 1;
526 uint32_t y2
= tile
->yoff
+ tile
->bin_h
- 1;
528 set_scissor(ring
, x1
, y1
, x2
, y2
);
530 set_window_offset(ring
, x1
, y1
);
532 OUT_PKT4(ring
, REG_A6XX_VPC_SO_OVERRIDE
, 1);
533 OUT_RING(ring
, A6XX_VPC_SO_OVERRIDE_SO_DISABLE
);
535 if (use_hw_binning(batch
)) {
536 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
537 struct fd_vsc_pipe
*pipe
= &ctx
->vsc_pipe
[tile
->p
];
538 unsigned n
= gmem
->nbins_x
* gmem
->nbins_y
;
540 OUT_PKT7(ring
, CP_WAIT_FOR_ME
, 0);
542 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
545 OUT_PKT7(ring
, CP_SET_MODE
, 1);
548 OUT_PKT7(ring
, CP_SET_BIN_DATA5
, 7);
549 OUT_RING(ring
, CP_SET_BIN_DATA5_0_VSC_SIZE(pipe
->w
* pipe
->h
) |
550 CP_SET_BIN_DATA5_0_VSC_N(tile
->n
));
551 OUT_RELOC(ring
, fd6_ctx
->vsc_data
, /* VSC_PIPE[p].DATA_ADDRESS */
552 (tile
->p
* A6XX_VSC_DATA_PITCH
), 0, 0);
553 OUT_RELOC(ring
, fd6_ctx
->vsc_data
, /* VSC_SIZE_ADDRESS + (p * 4) */
554 (tile
->p
* 4) + (n
* A6XX_VSC_DATA_PITCH
), 0, 0);
555 OUT_RELOC(ring
, fd6_ctx
->vsc_data2
,
556 (tile
->p
* A6XX_VSC_DATA2_PITCH
), 0, 0);
558 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
561 OUT_PKT7(ring
, CP_SET_MODE
, 1);
567 set_blit_scissor(struct fd_batch
*batch
)
569 struct fd_ringbuffer
*ring
= batch
->gmem
;
570 struct pipe_scissor_state blit_scissor
;
571 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
573 blit_scissor
.minx
= batch
->max_scissor
.minx
;
574 blit_scissor
.miny
= batch
->max_scissor
.miny
;
575 blit_scissor
.maxx
= MIN2(pfb
->width
- 1, batch
->max_scissor
.maxx
);
576 blit_scissor
.maxy
= MIN2(pfb
->height
- 1, batch
->max_scissor
.maxy
);
578 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_SCISSOR_TL
, 2);
580 A6XX_RB_BLIT_SCISSOR_TL_X(blit_scissor
.minx
) |
581 A6XX_RB_BLIT_SCISSOR_TL_Y(blit_scissor
.miny
));
583 A6XX_RB_BLIT_SCISSOR_BR_X(blit_scissor
.maxx
- 1) |
584 A6XX_RB_BLIT_SCISSOR_BR_Y(blit_scissor
.maxy
- 1));
588 emit_blit(struct fd_batch
*batch
, uint32_t base
,
589 struct pipe_surface
*psurf
,
590 struct fd_resource
*rsc
)
592 struct fd_ringbuffer
*ring
= batch
->gmem
;
593 struct fd_resource_slice
*slice
;
596 slice
= fd_resource_slice(rsc
, psurf
->u
.tex
.level
);
597 offset
= fd_resource_offset(rsc
, psurf
->u
.tex
.level
,
598 psurf
->u
.tex
.first_layer
);
600 debug_assert(psurf
->u
.tex
.first_layer
== psurf
->u
.tex
.last_layer
);
602 enum pipe_format pfmt
= psurf
->format
;
603 enum a6xx_color_fmt format
= fd6_pipe2color(pfmt
);
604 uint32_t stride
= slice
->pitch
* rsc
->cpp
;
605 uint32_t size
= slice
->size0
;
606 enum a3xx_color_swap swap
= fd6_pipe2swap(pfmt
);
610 // tiled = rsc->tile_mode &&
611 // !fd_resource_level_linear(psurf->texture, psurf->u.tex.level);
613 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_DST_INFO
, 5);
615 A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR
) |
616 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format
) |
617 A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap
));
618 OUT_RELOCW(ring
, rsc
->bo
, offset
, 0, 0); /* RB_BLIT_DST_LO/HI */
619 OUT_RING(ring
, A6XX_RB_BLIT_DST_PITCH(stride
));
620 OUT_RING(ring
, A6XX_RB_BLIT_DST_ARRAY_PITCH(size
));
622 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_BASE_GMEM
, 1);
623 OUT_RING(ring
, base
);
625 fd6_emit_blit(batch
, ring
);
629 emit_restore_blit(struct fd_batch
*batch
, uint32_t base
,
630 struct pipe_surface
*psurf
,
631 struct fd_resource
*rsc
,
634 struct fd_ringbuffer
*ring
= batch
->gmem
;
638 case FD_BUFFER_COLOR
:
639 info
|= A6XX_RB_BLIT_INFO_UNK0
;
641 case FD_BUFFER_STENCIL
:
642 info
|= A6XX_RB_BLIT_INFO_UNK0
;
644 case FD_BUFFER_DEPTH
:
645 info
|= A6XX_RB_BLIT_INFO_DEPTH
| A6XX_RB_BLIT_INFO_UNK0
;
649 if (util_format_is_pure_integer(psurf
->format
))
650 info
|= A6XX_RB_BLIT_INFO_INTEGER
;
652 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_INFO
, 1);
653 OUT_RING(ring
, info
| A6XX_RB_BLIT_INFO_GMEM
);
655 emit_blit(batch
, base
, psurf
, rsc
);
659 * transfer from system memory to gmem
662 fd6_emit_tile_mem2gmem(struct fd_batch
*batch
, struct fd_tile
*tile
)
664 struct fd_context
*ctx
= batch
->ctx
;
665 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
666 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
668 set_blit_scissor(batch
);
670 if (fd_gmem_needs_restore(batch
, tile
, FD_BUFFER_COLOR
)) {
672 for (i
= 0; i
< pfb
->nr_cbufs
; i
++) {
675 if (!(batch
->restore
& (PIPE_CLEAR_COLOR0
<< i
)))
677 emit_restore_blit(batch
, gmem
->cbuf_base
[i
], pfb
->cbufs
[i
],
678 fd_resource(pfb
->cbufs
[i
]->texture
),
683 if (fd_gmem_needs_restore(batch
, tile
, FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
)) {
684 struct fd_resource
*rsc
= fd_resource(pfb
->zsbuf
->texture
);
686 if (!rsc
->stencil
|| fd_gmem_needs_restore(batch
, tile
, FD_BUFFER_DEPTH
)) {
687 emit_restore_blit(batch
, gmem
->zsbuf_base
[0], pfb
->zsbuf
, rsc
,
690 if (rsc
->stencil
&& fd_gmem_needs_restore(batch
, tile
, FD_BUFFER_STENCIL
)) {
691 emit_restore_blit(batch
, gmem
->zsbuf_base
[1], pfb
->zsbuf
, rsc
->stencil
,
697 /* before IB to rendering cmds: */
699 fd6_emit_tile_renderprep(struct fd_batch
*batch
, struct fd_tile
*tile
)
704 emit_resolve_blit(struct fd_batch
*batch
, uint32_t base
,
705 struct pipe_surface
*psurf
,
706 struct fd_resource
*rsc
,
709 struct fd_ringbuffer
*ring
= batch
->gmem
;
716 case FD_BUFFER_COLOR
:
718 case FD_BUFFER_STENCIL
:
719 info
|= A6XX_RB_BLIT_INFO_UNK0
;
721 case FD_BUFFER_DEPTH
:
722 info
|= A6XX_RB_BLIT_INFO_DEPTH
;
726 if (util_format_is_pure_integer(psurf
->format
))
727 info
|= A6XX_RB_BLIT_INFO_INTEGER
;
729 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_INFO
, 1);
730 OUT_RING(ring
, info
);
732 emit_blit(batch
, base
, psurf
, rsc
);
736 * transfer from gmem to system memory (ie. normal RAM)
740 fd6_emit_tile_gmem2mem(struct fd_batch
*batch
, struct fd_tile
*tile
)
742 struct fd_context
*ctx
= batch
->ctx
;
743 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
744 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
745 struct fd_ringbuffer
*ring
= batch
->gmem
;
747 if (use_hw_binning(batch
)) {
748 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
749 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(0x5) | 0x10);
752 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
755 emit_marker6(ring
, 7);
756 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
757 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_RESOLVE
) | 0x10);
758 emit_marker6(ring
, 7);
760 set_blit_scissor(batch
);
762 if (batch
->resolve
& (FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
)) {
763 struct fd_resource
*rsc
= fd_resource(pfb
->zsbuf
->texture
);
765 if (!rsc
->stencil
|| (batch
->resolve
& FD_BUFFER_DEPTH
)) {
766 emit_resolve_blit(batch
, gmem
->zsbuf_base
[0], pfb
->zsbuf
, rsc
,
769 if (rsc
->stencil
&& (batch
->resolve
& FD_BUFFER_STENCIL
)) {
770 emit_resolve_blit(batch
, gmem
->zsbuf_base
[1], pfb
->zsbuf
, rsc
->stencil
,
775 if (batch
->resolve
& FD_BUFFER_COLOR
) {
777 for (i
= 0; i
< pfb
->nr_cbufs
; i
++) {
780 if (!(batch
->resolve
& (PIPE_CLEAR_COLOR0
<< i
)))
782 emit_resolve_blit(batch
, gmem
->cbuf_base
[i
], pfb
->cbufs
[i
],
783 fd_resource(pfb
->cbufs
[i
]->texture
),
790 fd6_emit_tile_fini(struct fd_batch
*batch
)
792 struct fd_ringbuffer
*ring
= batch
->gmem
;
794 fd6_emit_lrz_flush(ring
);
796 fd6_event_write(batch
, ring
, CACHE_FLUSH_TS
, true);
800 fd6_emit_sysmem_prep(struct fd_batch
*batch
)
802 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
803 struct fd_ringbuffer
*ring
= batch
->gmem
;
805 fd6_emit_restore(batch
, ring
);
807 fd6_emit_lrz_flush(ring
);
809 emit_marker6(ring
, 7);
810 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
811 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_BYPASS
) | 0x10); /* | 0x10 ? */
812 emit_marker6(ring
, 7);
814 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
817 fd6_event_write(batch
, ring
, PC_CCU_INVALIDATE_COLOR
, false);
818 fd6_cache_flush(batch
, ring
);
821 OUT_PKT4(ring
, REG_A6XX_PC_POWER_CNTL
, 1);
822 OUT_RING(ring
, 0x00000003); /* PC_POWER_CNTL */
826 OUT_PKT4(ring
, REG_A6XX_VFD_POWER_CNTL
, 1);
827 OUT_RING(ring
, 0x00000003); /* VFD_POWER_CNTL */
830 /* 0x10000000 for BYPASS.. 0x7c13c080 for GMEM: */
832 OUT_PKT4(ring
, REG_A6XX_RB_CCU_CNTL
, 1);
833 OUT_RING(ring
, 0x10000000); /* RB_CCU_CNTL */
835 set_scissor(ring
, 0, 0, pfb
->width
- 1, pfb
->height
- 1);
837 set_window_offset(ring
, 0, 0);
839 set_bin_size(ring
, 0, 0, 0xc00000); /* 0xc00000 = BYPASS? */
841 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
844 patch_draws(batch
, IGNORE_VISIBILITY
);
846 emit_zs(ring
, pfb
->zsbuf
, NULL
);
847 emit_mrt(ring
, pfb
->nr_cbufs
, pfb
->cbufs
, NULL
);
853 fd6_emit_sysmem_fini(struct fd_batch
*batch
)
855 struct fd_ringbuffer
*ring
= batch
->gmem
;
857 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
860 fd6_emit_lrz_flush(ring
);
862 fd6_event_write(batch
, ring
, UNK_1D
, true);
866 fd6_gmem_init(struct pipe_context
*pctx
)
868 struct fd_context
*ctx
= fd_context(pctx
);
870 ctx
->emit_tile_init
= fd6_emit_tile_init
;
871 ctx
->emit_tile_prep
= fd6_emit_tile_prep
;
872 ctx
->emit_tile_mem2gmem
= fd6_emit_tile_mem2gmem
;
873 ctx
->emit_tile_renderprep
= fd6_emit_tile_renderprep
;
874 ctx
->emit_tile_gmem2mem
= fd6_emit_tile_gmem2mem
;
875 ctx
->emit_tile_fini
= fd6_emit_tile_fini
;
876 ctx
->emit_sysmem_prep
= fd6_emit_sysmem_prep
;
877 ctx
->emit_sysmem_fini
= fd6_emit_sysmem_fini
;