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
, struct pipe_framebuffer_state
*pfb
,
53 struct fd_gmem_stateobj
*gmem
)
55 unsigned char mrt_comp
[A6XX_MAX_RENDER_TARGETS
] = {0};
56 unsigned srgb_cntl
= 0;
59 for (i
= 0; i
< pfb
->nr_cbufs
; 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
;
74 struct pipe_surface
*psurf
= pfb
->cbufs
[i
];
75 enum pipe_format pformat
= psurf
->format
;
76 rsc
= fd_resource(psurf
->texture
);
80 uint32_t base
= gmem
? gmem
->cbuf_base
[i
] : 0;
81 slice
= fd_resource_slice(rsc
, psurf
->u
.tex
.level
);
82 format
= fd6_pipe2color(pformat
);
83 sint
= util_format_is_pure_sint(pformat
);
84 uint
= util_format_is_pure_uint(pformat
);
86 if (util_format_is_srgb(pformat
))
87 srgb_cntl
|= (1 << i
);
89 offset
= fd_resource_offset(rsc
, psurf
->u
.tex
.level
,
90 psurf
->u
.tex
.first_layer
);
92 stride
= slice
->pitch
* rsc
->cpp
* pfb
->samples
;
93 swap
= rsc
->tile_mode
? WZYX
: fd6_pipe2swap(pformat
);
96 fd_resource_level_linear(psurf
->texture
, psurf
->u
.tex
.level
))
97 tile_mode
= TILE6_LINEAR
;
99 tile_mode
= rsc
->tile_mode
;
101 if (rsc
->tile_mode
&&
102 fd_resource_level_linear(psurf
->texture
, psurf
->u
.tex
.level
))
103 tile_mode
= TILE6_LINEAR
;
105 tile_mode
= rsc
->tile_mode
;
107 debug_assert(psurf
->u
.tex
.first_layer
== psurf
->u
.tex
.last_layer
);
108 debug_assert((offset
+ slice
->size0
) <= fd_bo_size(rsc
->bo
));
110 OUT_PKT4(ring
, REG_A6XX_RB_MRT_BUF_INFO(i
), 6);
111 OUT_RING(ring
, A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format
) |
112 A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode
) |
113 A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap
));
114 OUT_RING(ring
, A6XX_RB_MRT_PITCH(stride
));
115 OUT_RING(ring
, A6XX_RB_MRT_ARRAY_PITCH(slice
->size0
));
116 OUT_RELOCW(ring
, rsc
->bo
, offset
+ rsc
->offset
, 0, 0); /* BASE_LO/HI */
117 OUT_RING(ring
, base
); /* RB_MRT[i].BASE_GMEM */
118 OUT_PKT4(ring
, REG_A6XX_SP_FS_MRT_REG(i
), 1);
119 OUT_RING(ring
, A6XX_SP_FS_MRT_REG_COLOR_FORMAT(format
) |
120 COND(sint
, A6XX_SP_FS_MRT_REG_COLOR_SINT
) |
121 COND(uint
, A6XX_SP_FS_MRT_REG_COLOR_UINT
));
123 OUT_PKT4(ring
, REG_A6XX_RB_MRT_FLAG_BUFFER(i
), 3);
124 if (fd6_ubwc_enabled(rsc
, tile_mode
)) {
125 OUT_RELOCW(ring
, rsc
->bo
, offset
+ rsc
->ubwc_offset
, 0, 0); /* BASE_LO/HI */
126 OUT_RING(ring
, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc
->ubwc_pitch
) |
127 A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc
->ubwc_size
));
129 OUT_RING(ring
, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */
130 OUT_RING(ring
, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */
131 OUT_RING(ring
, 0x00000000);
135 OUT_PKT4(ring
, REG_A6XX_RB_SRGB_CNTL
, 1);
136 OUT_RING(ring
, srgb_cntl
);
138 OUT_PKT4(ring
, REG_A6XX_SP_SRGB_CNTL
, 1);
139 OUT_RING(ring
, srgb_cntl
);
141 OUT_PKT4(ring
, REG_A6XX_RB_RENDER_COMPONENTS
, 1);
142 OUT_RING(ring
, A6XX_RB_RENDER_COMPONENTS_RT0(mrt_comp
[0]) |
143 A6XX_RB_RENDER_COMPONENTS_RT1(mrt_comp
[1]) |
144 A6XX_RB_RENDER_COMPONENTS_RT2(mrt_comp
[2]) |
145 A6XX_RB_RENDER_COMPONENTS_RT3(mrt_comp
[3]) |
146 A6XX_RB_RENDER_COMPONENTS_RT4(mrt_comp
[4]) |
147 A6XX_RB_RENDER_COMPONENTS_RT5(mrt_comp
[5]) |
148 A6XX_RB_RENDER_COMPONENTS_RT6(mrt_comp
[6]) |
149 A6XX_RB_RENDER_COMPONENTS_RT7(mrt_comp
[7]));
151 OUT_PKT4(ring
, REG_A6XX_SP_FS_RENDER_COMPONENTS
, 1);
153 A6XX_SP_FS_RENDER_COMPONENTS_RT0(mrt_comp
[0]) |
154 A6XX_SP_FS_RENDER_COMPONENTS_RT1(mrt_comp
[1]) |
155 A6XX_SP_FS_RENDER_COMPONENTS_RT2(mrt_comp
[2]) |
156 A6XX_SP_FS_RENDER_COMPONENTS_RT3(mrt_comp
[3]) |
157 A6XX_SP_FS_RENDER_COMPONENTS_RT4(mrt_comp
[4]) |
158 A6XX_SP_FS_RENDER_COMPONENTS_RT5(mrt_comp
[5]) |
159 A6XX_SP_FS_RENDER_COMPONENTS_RT6(mrt_comp
[6]) |
160 A6XX_SP_FS_RENDER_COMPONENTS_RT7(mrt_comp
[7]));
164 emit_zs(struct fd_ringbuffer
*ring
, struct pipe_surface
*zsbuf
,
165 struct fd_gmem_stateobj
*gmem
)
168 struct fd_resource
*rsc
= fd_resource(zsbuf
->texture
);
169 enum a6xx_depth_format fmt
= fd6_pipe2depth(zsbuf
->format
);
170 struct fd_resource_slice
*slice
= fd_resource_slice(rsc
, 0);
171 uint32_t stride
= slice
->pitch
* rsc
->cpp
;
172 uint32_t size
= slice
->size0
;
173 uint32_t base
= gmem
? gmem
->zsbuf_base
[0] : 0;
176 !fd_resource_level_linear(zsbuf
->texture
, zsbuf
->u
.tex
.level
) && rsc
->ubwc_size
;
178 OUT_PKT4(ring
, REG_A6XX_RB_DEPTH_BUFFER_INFO
, 6);
179 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt
));
180 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_PITCH(stride
));
181 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(size
));
182 OUT_RELOCW(ring
, rsc
->bo
, rsc
->offset
, 0, 0); /* RB_DEPTH_BUFFER_BASE_LO/HI */
183 OUT_RING(ring
, base
); /* RB_DEPTH_BUFFER_BASE_GMEM */
185 OUT_PKT4(ring
, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO
, 1);
186 OUT_RING(ring
, A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt
));
188 OUT_PKT4(ring
, REG_A6XX_RB_DEPTH_FLAG_BUFFER_BASE_LO
, 3);
190 OUT_RELOCW(ring
, rsc
->bo
, rsc
->ubwc_offset
, 0, 0); /* BASE_LO/HI */
191 OUT_RING(ring
, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc
->ubwc_pitch
) |
192 A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc
->ubwc_size
));
194 OUT_RING(ring
, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */
195 OUT_RING(ring
, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */
196 OUT_RING(ring
, 0x00000000);
200 OUT_PKT4(ring
, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO
, 5);
201 OUT_RELOCW(ring
, rsc
->lrz
, 0, 0, 0);
202 OUT_RING(ring
, A6XX_GRAS_LRZ_BUFFER_PITCH_PITCH(rsc
->lrz_pitch
));
203 //OUT_RELOCW(ring, rsc->lrz, 0, 0, 0); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO/HI */
204 // XXX a6xx seems to use a different buffer here.. not sure what for..
205 OUT_RING(ring
, 0x00000000);
206 OUT_RING(ring
, 0x00000000);
208 OUT_PKT4(ring
, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO
, 5);
209 OUT_RING(ring
, 0x00000000);
210 OUT_RING(ring
, 0x00000000);
211 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_BUFFER_PITCH */
212 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO */
213 OUT_RING(ring
, 0x00000000);
217 struct fd_resource_slice
*slice
= fd_resource_slice(rsc
->stencil
, 0);
218 stride
= slice
->pitch
* rsc
->stencil
->cpp
;
220 uint32_t base
= gmem
? gmem
->zsbuf_base
[1] : 0;
222 OUT_PKT4(ring
, REG_A6XX_RB_STENCIL_INFO
, 6);
223 OUT_RING(ring
, A6XX_RB_STENCIL_INFO_SEPARATE_STENCIL
);
224 OUT_RING(ring
, A6XX_RB_STENCIL_BUFFER_PITCH(stride
));
225 OUT_RING(ring
, A6XX_RB_STENCIL_BUFFER_ARRAY_PITCH(size
));
226 OUT_RELOCW(ring
, rsc
->stencil
->bo
, 0, 0, 0); /* RB_STENCIL_BASE_LO/HI */
227 OUT_RING(ring
, base
); /* RB_STENCIL_BASE_LO */
229 OUT_PKT4(ring
, REG_A6XX_RB_STENCIL_INFO
, 1);
230 OUT_RING(ring
, 0x00000000); /* RB_STENCIL_INFO */
233 OUT_PKT4(ring
, REG_A6XX_RB_DEPTH_BUFFER_INFO
, 6);
234 OUT_RING(ring
, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(DEPTH6_NONE
));
235 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_PITCH */
236 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_ARRAY_PITCH */
237 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_BASE_LO */
238 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_BASE_HI */
239 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_BUFFER_BASE_GMEM */
241 OUT_PKT4(ring
, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO
, 1);
242 OUT_RING(ring
, A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(DEPTH6_NONE
));
244 OUT_PKT4(ring
, REG_A6XX_GRAS_LRZ_BUFFER_BASE_LO
, 5);
245 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_LO */
246 OUT_RING(ring
, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_HI */
247 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_BUFFER_PITCH */
248 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO */
249 OUT_RING(ring
, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_HI */
251 OUT_PKT4(ring
, REG_A6XX_RB_STENCIL_INFO
, 1);
252 OUT_RING(ring
, 0x00000000); /* RB_STENCIL_INFO */
257 use_hw_binning(struct fd_batch
*batch
)
259 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
261 // TODO figure out hw limits for binning
263 return fd_binning_enabled
&& ((gmem
->nbins_x
* gmem
->nbins_y
) > 2) &&
264 (batch
->num_draws
> 0);
268 patch_draws(struct fd_batch
*batch
, enum pc_di_vis_cull_mode vismode
)
271 for (i
= 0; i
< fd_patch_num_elements(&batch
->draw_patches
); i
++) {
272 struct fd_cs_patch
*patch
= fd_patch_element(&batch
->draw_patches
, i
);
273 *patch
->cs
= patch
->val
| DRAW4(0, 0, 0, vismode
);
275 util_dynarray_resize(&batch
->draw_patches
, 0);
279 update_render_cntl(struct fd_batch
*batch
, struct pipe_framebuffer_state
*pfb
, bool binning
)
281 struct fd_ringbuffer
*ring
= batch
->gmem
;
283 bool depth_ubwc_enable
= false;
284 uint32_t mrts_ubwc_enable
= 0;
288 struct fd_resource
*rsc
= fd_resource(pfb
->zsbuf
->texture
);
290 !fd_resource_level_linear(pfb
->zsbuf
->texture
, pfb
->zsbuf
->u
.tex
.level
) && rsc
->ubwc_size
;
293 for (i
= 0; i
< pfb
->nr_cbufs
; i
++) {
297 struct pipe_surface
*psurf
= pfb
->cbufs
[i
];
298 struct fd_resource
*rsc
= fd_resource(psurf
->texture
);
302 if (fd6_ubwc_enabled(rsc
, rsc
->tile_mode
))
303 mrts_ubwc_enable
|= 1 << i
;
306 cntl
|= A6XX_RB_RENDER_CNTL_UNK4
;
308 cntl
|= A6XX_RB_RENDER_CNTL_BINNING
;
310 OUT_PKT7(ring
, CP_REG_WRITE
, 3);
312 OUT_RING(ring
, REG_A6XX_RB_RENDER_CNTL
);
313 OUT_RING(ring
, cntl
|
314 COND(depth_ubwc_enable
, A6XX_RB_RENDER_CNTL_FLAG_DEPTH
) |
315 A6XX_RB_RENDER_CNTL_FLAG_MRTS(mrts_ubwc_enable
));
319 update_vsc_pipe(struct fd_batch
*batch
)
321 struct fd_context
*ctx
= batch
->ctx
;
322 struct fd6_context
*fd6_ctx
= fd6_context(ctx
);
323 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
324 struct fd_ringbuffer
*ring
= batch
->gmem
;
327 OUT_PKT4(ring
, REG_A6XX_VSC_BIN_SIZE
, 3);
328 OUT_RING(ring
, A6XX_VSC_BIN_SIZE_WIDTH(gmem
->bin_w
) |
329 A6XX_VSC_BIN_SIZE_HEIGHT(gmem
->bin_h
));
330 OUT_RELOCW(ring
, fd6_ctx
->vsc_data
,
331 32 * A6XX_VSC_DATA_PITCH
, 0, 0); /* VSC_SIZE_ADDRESS_LO/HI */
333 OUT_PKT4(ring
, REG_A6XX_VSC_BIN_COUNT
, 1);
334 OUT_RING(ring
, A6XX_VSC_BIN_COUNT_NX(gmem
->nbins_x
) |
335 A6XX_VSC_BIN_COUNT_NY(gmem
->nbins_y
));
337 OUT_PKT4(ring
, REG_A6XX_VSC_PIPE_CONFIG_REG(0), 32);
338 for (i
= 0; i
< 32; i
++) {
339 struct fd_vsc_pipe
*pipe
= &ctx
->vsc_pipe
[i
];
340 OUT_RING(ring
, A6XX_VSC_PIPE_CONFIG_REG_X(pipe
->x
) |
341 A6XX_VSC_PIPE_CONFIG_REG_Y(pipe
->y
) |
342 A6XX_VSC_PIPE_CONFIG_REG_W(pipe
->w
) |
343 A6XX_VSC_PIPE_CONFIG_REG_H(pipe
->h
));
346 OUT_PKT4(ring
, REG_A6XX_VSC_PIPE_DATA2_ADDRESS_LO
, 4);
347 OUT_RELOCW(ring
, fd6_ctx
->vsc_data2
, 0, 0, 0);
348 OUT_RING(ring
, A6XX_VSC_DATA2_PITCH
);
349 OUT_RING(ring
, fd_bo_size(fd6_ctx
->vsc_data2
));
351 OUT_PKT4(ring
, REG_A6XX_VSC_PIPE_DATA_ADDRESS_LO
, 4);
352 OUT_RELOCW(ring
, fd6_ctx
->vsc_data
, 0, 0, 0);
353 OUT_RING(ring
, A6XX_VSC_DATA_PITCH
);
354 OUT_RING(ring
, fd_bo_size(fd6_ctx
->vsc_data
));
358 set_scissor(struct fd_ringbuffer
*ring
, uint32_t x1
, uint32_t y1
, uint32_t x2
, uint32_t y2
)
360 OUT_PKT4(ring
, REG_A6XX_GRAS_SC_WINDOW_SCISSOR_TL
, 2);
361 OUT_RING(ring
, A6XX_GRAS_SC_WINDOW_SCISSOR_TL_X(x1
) |
362 A6XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(y1
));
363 OUT_RING(ring
, A6XX_GRAS_SC_WINDOW_SCISSOR_BR_X(x2
) |
364 A6XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(y2
));
366 OUT_PKT4(ring
, REG_A6XX_GRAS_RESOLVE_CNTL_1
, 2);
367 OUT_RING(ring
, A6XX_GRAS_RESOLVE_CNTL_1_X(x1
) |
368 A6XX_GRAS_RESOLVE_CNTL_1_Y(y1
));
369 OUT_RING(ring
, A6XX_GRAS_RESOLVE_CNTL_2_X(x2
) |
370 A6XX_GRAS_RESOLVE_CNTL_2_Y(y2
));
374 set_bin_size(struct fd_ringbuffer
*ring
, uint32_t w
, uint32_t h
, uint32_t flag
)
376 OUT_PKT4(ring
, REG_A6XX_GRAS_BIN_CONTROL
, 1);
377 OUT_RING(ring
, A6XX_GRAS_BIN_CONTROL_BINW(w
) |
378 A6XX_GRAS_BIN_CONTROL_BINH(h
) | flag
);
380 OUT_PKT4(ring
, REG_A6XX_RB_BIN_CONTROL
, 1);
381 OUT_RING(ring
, A6XX_RB_BIN_CONTROL_BINW(w
) |
382 A6XX_RB_BIN_CONTROL_BINH(h
) | flag
);
384 /* no flag for RB_BIN_CONTROL2... */
385 OUT_PKT4(ring
, REG_A6XX_RB_BIN_CONTROL2
, 1);
386 OUT_RING(ring
, A6XX_RB_BIN_CONTROL2_BINW(w
) |
387 A6XX_RB_BIN_CONTROL2_BINH(h
));
391 emit_binning_pass(struct fd_batch
*batch
)
393 struct fd_context
*ctx
= batch
->ctx
;
394 struct fd_ringbuffer
*ring
= batch
->gmem
;
395 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
397 uint32_t x1
= gmem
->minx
;
398 uint32_t y1
= gmem
->miny
;
399 uint32_t x2
= gmem
->minx
+ gmem
->width
- 1;
400 uint32_t y2
= gmem
->miny
+ gmem
->height
- 1;
402 set_scissor(ring
, x1
, y1
, x2
, y2
);
404 emit_marker6(ring
, 7);
405 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
406 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_BINNING
));
407 emit_marker6(ring
, 7);
409 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
412 OUT_PKT7(ring
, CP_SET_MODE
, 1);
417 OUT_PKT4(ring
, REG_A6XX_VFD_MODE_CNTL
, 1);
418 OUT_RING(ring
, A6XX_VFD_MODE_CNTL_BINNING_PASS
);
420 update_vsc_pipe(batch
);
422 OUT_PKT4(ring
, REG_A6XX_PC_UNKNOWN_9805
, 1);
425 OUT_PKT4(ring
, REG_A6XX_SP_UNKNOWN_A0F8
, 1);
428 OUT_PKT7(ring
, CP_EVENT_WRITE
, 1);
429 OUT_RING(ring
, UNK_2C
);
431 OUT_PKT4(ring
, REG_A6XX_RB_WINDOW_OFFSET
, 1);
432 OUT_RING(ring
, A6XX_RB_WINDOW_OFFSET_X(0) |
433 A6XX_RB_WINDOW_OFFSET_Y(0));
435 OUT_PKT4(ring
, REG_A6XX_SP_TP_WINDOW_OFFSET
, 1);
436 OUT_RING(ring
, A6XX_SP_TP_WINDOW_OFFSET_X(0) |
437 A6XX_SP_TP_WINDOW_OFFSET_Y(0));
439 /* emit IB to binning drawcmds: */
440 fd6_emit_ib(ring
, batch
->draw
);
444 OUT_PKT7(ring
, CP_SET_DRAW_STATE
, 3);
445 OUT_RING(ring
, CP_SET_DRAW_STATE__0_COUNT(0) |
446 CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS
|
447 CP_SET_DRAW_STATE__0_GROUP_ID(0));
448 OUT_RING(ring
, CP_SET_DRAW_STATE__1_ADDR_LO(0));
449 OUT_RING(ring
, CP_SET_DRAW_STATE__2_ADDR_HI(0));
451 OUT_PKT7(ring
, CP_EVENT_WRITE
, 1);
452 OUT_RING(ring
, UNK_2D
);
454 OUT_PKT7(ring
, CP_EVENT_WRITE
, 4);
455 OUT_RING(ring
, CACHE_FLUSH_TS
);
456 OUT_RELOCW(ring
, fd6_context(ctx
)->blit_mem
, 0, 0, 0); /* ADDR_LO/HI */
457 OUT_RING(ring
, 0x00000000);
463 emit_msaa(struct fd_ringbuffer
*ring
, unsigned nr
)
465 enum a3xx_msaa_samples samples
= fd_msaa_samples(nr
);
467 OUT_PKT4(ring
, REG_A6XX_SP_TP_RAS_MSAA_CNTL
, 2);
468 OUT_RING(ring
, A6XX_SP_TP_RAS_MSAA_CNTL_SAMPLES(samples
));
469 OUT_RING(ring
, A6XX_SP_TP_DEST_MSAA_CNTL_SAMPLES(samples
) |
470 COND(samples
== MSAA_ONE
, A6XX_SP_TP_DEST_MSAA_CNTL_MSAA_DISABLE
));
472 OUT_PKT4(ring
, REG_A6XX_GRAS_RAS_MSAA_CNTL
, 2);
473 OUT_RING(ring
, A6XX_GRAS_RAS_MSAA_CNTL_SAMPLES(samples
));
474 OUT_RING(ring
, A6XX_GRAS_DEST_MSAA_CNTL_SAMPLES(samples
) |
475 COND(samples
== MSAA_ONE
, A6XX_GRAS_DEST_MSAA_CNTL_MSAA_DISABLE
));
477 OUT_PKT4(ring
, REG_A6XX_RB_RAS_MSAA_CNTL
, 2);
478 OUT_RING(ring
, A6XX_RB_RAS_MSAA_CNTL_SAMPLES(samples
));
479 OUT_RING(ring
, A6XX_RB_DEST_MSAA_CNTL_SAMPLES(samples
) |
480 COND(samples
== MSAA_ONE
, A6XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE
));
482 OUT_PKT4(ring
, REG_A6XX_RB_MSAA_CNTL
, 1);
483 OUT_RING(ring
, A6XX_RB_MSAA_CNTL_SAMPLES(samples
));
486 static void prepare_tile_setup_ib(struct fd_batch
*batch
);
487 static void prepare_tile_fini_ib(struct fd_batch
*batch
);
489 /* before first tile */
491 fd6_emit_tile_init(struct fd_batch
*batch
)
493 struct fd_context
*ctx
= batch
->ctx
;
494 struct fd_ringbuffer
*ring
= batch
->gmem
;
495 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
496 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
498 fd6_emit_restore(batch
, ring
);
500 fd6_emit_lrz_flush(ring
);
502 if (batch
->lrz_clear
)
503 fd6_emit_ib(ring
, batch
->lrz_clear
);
505 fd6_cache_inv(batch
, ring
);
507 prepare_tile_setup_ib(batch
);
508 prepare_tile_fini_ib(batch
);
510 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
513 /* 0x10000000 for BYPASS.. 0x7c13c080 for GMEM: */
515 OUT_PKT4(ring
, REG_A6XX_RB_CCU_CNTL
, 1);
516 OUT_RING(ring
, 0x7c400004); /* RB_CCU_CNTL */
518 emit_zs(ring
, pfb
->zsbuf
, &ctx
->gmem
);
519 emit_mrt(ring
, pfb
, &ctx
->gmem
);
520 emit_msaa(ring
, pfb
->samples
);
522 if (use_hw_binning(batch
)) {
523 set_bin_size(ring
, gmem
->bin_w
, gmem
->bin_h
,
524 A6XX_RB_BIN_CONTROL_BINNING_PASS
| 0x6000000);
525 update_render_cntl(batch
, pfb
, true);
526 emit_binning_pass(batch
);
527 patch_draws(batch
, USE_VISIBILITY
);
529 set_bin_size(ring
, gmem
->bin_w
, gmem
->bin_h
,
530 A6XX_RB_BIN_CONTROL_USE_VIZ
| 0x6000000);
532 OUT_PKT4(ring
, REG_A6XX_VFD_MODE_CNTL
, 1);
535 set_bin_size(ring
, gmem
->bin_w
, gmem
->bin_h
, 0x6000000);
536 patch_draws(batch
, IGNORE_VISIBILITY
);
539 update_render_cntl(batch
, pfb
, false);
543 set_window_offset(struct fd_ringbuffer
*ring
, uint32_t x1
, uint32_t y1
)
545 OUT_PKT4(ring
, REG_A6XX_RB_WINDOW_OFFSET
, 1);
546 OUT_RING(ring
, A6XX_RB_WINDOW_OFFSET_X(x1
) |
547 A6XX_RB_WINDOW_OFFSET_Y(y1
));
549 OUT_PKT4(ring
, REG_A6XX_RB_WINDOW_OFFSET2
, 1);
550 OUT_RING(ring
, A6XX_RB_WINDOW_OFFSET2_X(x1
) |
551 A6XX_RB_WINDOW_OFFSET2_Y(y1
));
553 OUT_PKT4(ring
, REG_A6XX_SP_WINDOW_OFFSET
, 1);
554 OUT_RING(ring
, A6XX_SP_WINDOW_OFFSET_X(x1
) |
555 A6XX_SP_WINDOW_OFFSET_Y(y1
));
557 OUT_PKT4(ring
, REG_A6XX_SP_TP_WINDOW_OFFSET
, 1);
558 OUT_RING(ring
, A6XX_SP_TP_WINDOW_OFFSET_X(x1
) |
559 A6XX_SP_TP_WINDOW_OFFSET_Y(y1
));
562 /* before mem2gmem */
564 fd6_emit_tile_prep(struct fd_batch
*batch
, struct fd_tile
*tile
)
566 struct fd_context
*ctx
= batch
->ctx
;
567 struct fd6_context
*fd6_ctx
= fd6_context(ctx
);
568 struct fd_ringbuffer
*ring
= batch
->gmem
;
570 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
571 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(0x7));
573 emit_marker6(ring
, 7);
574 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
575 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_GMEM
) | 0x10);
576 emit_marker6(ring
, 7);
578 uint32_t x1
= tile
->xoff
;
579 uint32_t y1
= tile
->yoff
;
580 uint32_t x2
= tile
->xoff
+ tile
->bin_w
- 1;
581 uint32_t y2
= tile
->yoff
+ tile
->bin_h
- 1;
583 set_scissor(ring
, x1
, y1
, x2
, y2
);
585 set_window_offset(ring
, x1
, y1
);
587 OUT_PKT4(ring
, REG_A6XX_VPC_SO_OVERRIDE
, 1);
588 OUT_RING(ring
, A6XX_VPC_SO_OVERRIDE_SO_DISABLE
);
590 if (use_hw_binning(batch
)) {
591 struct fd_vsc_pipe
*pipe
= &ctx
->vsc_pipe
[tile
->p
];
593 OUT_PKT7(ring
, CP_WAIT_FOR_ME
, 0);
595 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
598 OUT_PKT7(ring
, CP_SET_MODE
, 1);
601 OUT_PKT7(ring
, CP_SET_BIN_DATA5
, 7);
602 OUT_RING(ring
, CP_SET_BIN_DATA5_0_VSC_SIZE(pipe
->w
* pipe
->h
) |
603 CP_SET_BIN_DATA5_0_VSC_N(tile
->n
));
604 OUT_RELOC(ring
, fd6_ctx
->vsc_data
, /* VSC_PIPE[p].DATA_ADDRESS */
605 (tile
->p
* A6XX_VSC_DATA_PITCH
), 0, 0);
606 OUT_RELOC(ring
, fd6_ctx
->vsc_data
, /* VSC_SIZE_ADDRESS + (p * 4) */
607 (tile
->p
* 4) + (32 * A6XX_VSC_DATA_PITCH
), 0, 0);
608 OUT_RELOC(ring
, fd6_ctx
->vsc_data2
,
609 (tile
->p
* A6XX_VSC_DATA2_PITCH
), 0, 0);
611 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
614 OUT_PKT7(ring
, CP_SET_MODE
, 1);
620 set_blit_scissor(struct fd_batch
*batch
, struct fd_ringbuffer
*ring
)
622 struct pipe_scissor_state blit_scissor
;
623 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
625 blit_scissor
.minx
= batch
->max_scissor
.minx
;
626 blit_scissor
.miny
= batch
->max_scissor
.miny
;
627 blit_scissor
.maxx
= MIN2(pfb
->width
, batch
->max_scissor
.maxx
);
628 blit_scissor
.maxy
= MIN2(pfb
->height
, batch
->max_scissor
.maxy
);
630 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_SCISSOR_TL
, 2);
632 A6XX_RB_BLIT_SCISSOR_TL_X(blit_scissor
.minx
) |
633 A6XX_RB_BLIT_SCISSOR_TL_Y(blit_scissor
.miny
));
635 A6XX_RB_BLIT_SCISSOR_BR_X(blit_scissor
.maxx
- 1) |
636 A6XX_RB_BLIT_SCISSOR_BR_Y(blit_scissor
.maxy
- 1));
640 emit_blit(struct fd_batch
*batch
,
641 struct fd_ringbuffer
*ring
,
643 struct pipe_surface
*psurf
,
646 struct fd_resource_slice
*slice
;
647 struct fd_resource
*rsc
= fd_resource(psurf
->texture
);
648 enum pipe_format pfmt
= psurf
->format
;
651 /* separate stencil case: */
654 pfmt
= rsc
->base
.format
;
657 slice
= fd_resource_slice(rsc
, psurf
->u
.tex
.level
);
658 offset
= fd_resource_offset(rsc
, psurf
->u
.tex
.level
,
659 psurf
->u
.tex
.first_layer
);
661 debug_assert(psurf
->u
.tex
.first_layer
== psurf
->u
.tex
.last_layer
);
663 enum a6xx_color_fmt format
= fd6_pipe2color(pfmt
);
664 uint32_t stride
= slice
->pitch
* rsc
->cpp
;
665 uint32_t size
= slice
->size0
;
666 enum a3xx_color_swap swap
= rsc
->tile_mode
? WZYX
: fd6_pipe2swap(pfmt
);
667 enum a3xx_msaa_samples samples
=
668 fd_msaa_samples(rsc
->base
.nr_samples
);
671 if (rsc
->tile_mode
&&
672 fd_resource_level_linear(&rsc
->base
, psurf
->u
.tex
.level
))
673 tile_mode
= TILE6_LINEAR
;
675 tile_mode
= rsc
->tile_mode
;
677 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_DST_INFO
, 5);
679 A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode
) |
680 A6XX_RB_BLIT_DST_INFO_SAMPLES(samples
) |
681 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format
) |
682 A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap
) |
683 COND(fd6_ubwc_enabled(rsc
, tile_mode
), A6XX_RB_BLIT_DST_INFO_FLAGS
));
684 OUT_RELOCW(ring
, rsc
->bo
, offset
+ rsc
->offset
, 0, 0); /* RB_BLIT_DST_LO/HI */
685 OUT_RING(ring
, A6XX_RB_BLIT_DST_PITCH(stride
));
686 OUT_RING(ring
, A6XX_RB_BLIT_DST_ARRAY_PITCH(size
));
688 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_BASE_GMEM
, 1);
689 OUT_RING(ring
, base
);
691 if (fd6_ubwc_enabled(rsc
, tile_mode
)) {
692 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_FLAG_DST_LO
, 3);
693 OUT_RELOCW(ring
, rsc
->bo
, offset
+ rsc
->ubwc_offset
, 0, 0);
694 OUT_RING(ring
, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc
->ubwc_pitch
) |
695 A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc
->ubwc_size
));
698 fd6_emit_blit(batch
, ring
);
702 emit_restore_blit(struct fd_batch
*batch
,
703 struct fd_ringbuffer
*ring
,
705 struct pipe_surface
*psurf
,
709 bool stencil
= false;
712 case FD_BUFFER_COLOR
:
713 info
|= A6XX_RB_BLIT_INFO_UNK0
;
715 case FD_BUFFER_STENCIL
:
716 info
|= A6XX_RB_BLIT_INFO_UNK0
;
719 case FD_BUFFER_DEPTH
:
720 info
|= A6XX_RB_BLIT_INFO_DEPTH
| A6XX_RB_BLIT_INFO_UNK0
;
724 if (util_format_is_pure_integer(psurf
->format
))
725 info
|= A6XX_RB_BLIT_INFO_INTEGER
;
727 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_INFO
, 1);
728 OUT_RING(ring
, info
| A6XX_RB_BLIT_INFO_GMEM
);
730 emit_blit(batch
, ring
, base
, psurf
, stencil
);
734 emit_clears(struct fd_batch
*batch
, struct fd_ringbuffer
*ring
)
736 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
737 struct fd_gmem_stateobj
*gmem
= &batch
->ctx
->gmem
;
738 enum a3xx_msaa_samples samples
= fd_msaa_samples(pfb
->samples
);
740 uint32_t buffers
= batch
->fast_cleared
;
742 if (buffers
& PIPE_CLEAR_COLOR
) {
744 for (int i
= 0; i
< pfb
->nr_cbufs
; i
++) {
745 union pipe_color_union
*color
= &batch
->clear_color
[i
];
746 union util_color uc
= {0};
751 if (!(buffers
& (PIPE_CLEAR_COLOR0
<< i
)))
754 enum pipe_format pfmt
= pfb
->cbufs
[i
]->format
;
756 // XXX I think RB_CLEAR_COLOR_DWn wants to take into account SWAP??
757 union pipe_color_union swapped
;
758 switch (fd6_pipe2swap(pfmt
)) {
760 swapped
.ui
[0] = color
->ui
[0];
761 swapped
.ui
[1] = color
->ui
[1];
762 swapped
.ui
[2] = color
->ui
[2];
763 swapped
.ui
[3] = color
->ui
[3];
766 swapped
.ui
[2] = color
->ui
[0];
767 swapped
.ui
[1] = color
->ui
[1];
768 swapped
.ui
[0] = color
->ui
[2];
769 swapped
.ui
[3] = color
->ui
[3];
772 swapped
.ui
[3] = color
->ui
[0];
773 swapped
.ui
[0] = color
->ui
[1];
774 swapped
.ui
[1] = color
->ui
[2];
775 swapped
.ui
[2] = color
->ui
[3];
778 swapped
.ui
[3] = color
->ui
[0];
779 swapped
.ui
[2] = color
->ui
[1];
780 swapped
.ui
[1] = color
->ui
[2];
781 swapped
.ui
[0] = color
->ui
[3];
785 if (util_format_is_pure_uint(pfmt
)) {
786 util_format_write_4ui(pfmt
, swapped
.ui
, 0, &uc
, 0, 0, 0, 1, 1);
787 } else if (util_format_is_pure_sint(pfmt
)) {
788 util_format_write_4i(pfmt
, swapped
.i
, 0, &uc
, 0, 0, 0, 1, 1);
790 util_pack_color(swapped
.f
, pfmt
, &uc
);
793 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_DST_INFO
, 1);
794 OUT_RING(ring
, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR
) |
795 A6XX_RB_BLIT_DST_INFO_SAMPLES(samples
) |
796 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(fd6_pipe2color(pfmt
)));
798 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_INFO
, 1);
799 OUT_RING(ring
, A6XX_RB_BLIT_INFO_GMEM
|
800 A6XX_RB_BLIT_INFO_CLEAR_MASK(0xf));
802 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_BASE_GMEM
, 1);
803 OUT_RING(ring
, gmem
->cbuf_base
[i
]);
805 OUT_PKT4(ring
, REG_A6XX_RB_UNKNOWN_88D0
, 1);
808 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0
, 4);
809 OUT_RING(ring
, uc
.ui
[0]);
810 OUT_RING(ring
, uc
.ui
[1]);
811 OUT_RING(ring
, uc
.ui
[2]);
812 OUT_RING(ring
, uc
.ui
[3]);
814 fd6_emit_blit(batch
, ring
);
818 const bool has_depth
= pfb
->zsbuf
;
819 const bool has_separate_stencil
=
820 has_depth
&& fd_resource(pfb
->zsbuf
->texture
)->stencil
;
822 /* First clear depth or combined depth/stencil. */
823 if ((has_depth
&& (buffers
& PIPE_CLEAR_DEPTH
)) ||
824 (!has_separate_stencil
&& (buffers
& PIPE_CLEAR_STENCIL
))) {
825 enum pipe_format pfmt
= pfb
->zsbuf
->format
;
826 uint32_t clear_value
;
829 if (has_separate_stencil
) {
830 pfmt
= util_format_get_depth_only(pfb
->zsbuf
->format
);
831 clear_value
= util_pack_z(pfmt
, batch
->clear_depth
);
833 pfmt
= pfb
->zsbuf
->format
;
834 clear_value
= util_pack_z_stencil(pfmt
, batch
->clear_depth
,
835 batch
->clear_stencil
);
838 if (buffers
& PIPE_CLEAR_DEPTH
)
841 if (!has_separate_stencil
&& (buffers
& PIPE_CLEAR_STENCIL
))
844 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_DST_INFO
, 1);
845 OUT_RING(ring
, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR
) |
846 A6XX_RB_BLIT_DST_INFO_SAMPLES(samples
) |
847 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(fd6_pipe2color(pfmt
)));
849 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_INFO
, 1);
850 OUT_RING(ring
, A6XX_RB_BLIT_INFO_GMEM
|
851 // XXX UNK0 for separate stencil ??
852 A6XX_RB_BLIT_INFO_DEPTH
|
853 A6XX_RB_BLIT_INFO_CLEAR_MASK(mask
));
855 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_BASE_GMEM
, 1);
856 OUT_RING(ring
, gmem
->zsbuf_base
[0]);
858 OUT_PKT4(ring
, REG_A6XX_RB_UNKNOWN_88D0
, 1);
861 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0
, 1);
862 OUT_RING(ring
, clear_value
);
864 fd6_emit_blit(batch
, ring
);
867 /* Then clear the separate stencil buffer in case of 32 bit depth
868 * formats with separate stencil. */
869 if (has_separate_stencil
&& (buffers
& PIPE_CLEAR_STENCIL
)) {
870 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_DST_INFO
, 1);
871 OUT_RING(ring
, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR
) |
872 A6XX_RB_BLIT_DST_INFO_SAMPLES(samples
) |
873 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(RB6_R8_UINT
));
875 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_INFO
, 1);
876 OUT_RING(ring
, A6XX_RB_BLIT_INFO_GMEM
|
877 //A6XX_RB_BLIT_INFO_UNK0 |
878 A6XX_RB_BLIT_INFO_DEPTH
|
879 A6XX_RB_BLIT_INFO_CLEAR_MASK(0x1));
881 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_BASE_GMEM
, 1);
882 OUT_RING(ring
, gmem
->zsbuf_base
[1]);
884 OUT_PKT4(ring
, REG_A6XX_RB_UNKNOWN_88D0
, 1);
887 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0
, 1);
888 OUT_RING(ring
, batch
->clear_stencil
& 0xff);
890 fd6_emit_blit(batch
, ring
);
895 * transfer from system memory to gmem
898 emit_restore_blits(struct fd_batch
*batch
, struct fd_ringbuffer
*ring
)
900 struct fd_context
*ctx
= batch
->ctx
;
901 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
902 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
904 if (batch
->restore
& FD_BUFFER_COLOR
) {
906 for (i
= 0; i
< pfb
->nr_cbufs
; i
++) {
909 if (!(batch
->restore
& (PIPE_CLEAR_COLOR0
<< i
)))
911 emit_restore_blit(batch
, ring
, gmem
->cbuf_base
[i
], pfb
->cbufs
[i
],
916 if (batch
->restore
& (FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
)) {
917 struct fd_resource
*rsc
= fd_resource(pfb
->zsbuf
->texture
);
919 if (!rsc
->stencil
|| (batch
->restore
& FD_BUFFER_DEPTH
)) {
920 emit_restore_blit(batch
, ring
, gmem
->zsbuf_base
[0], pfb
->zsbuf
,
923 if (rsc
->stencil
&& (batch
->restore
& FD_BUFFER_STENCIL
)) {
924 emit_restore_blit(batch
, ring
, gmem
->zsbuf_base
[1], pfb
->zsbuf
,
931 prepare_tile_setup_ib(struct fd_batch
*batch
)
933 batch
->tile_setup
= fd_submit_new_ringbuffer(batch
->submit
, 0x1000,
934 FD_RINGBUFFER_STREAMING
);
936 set_blit_scissor(batch
, batch
->tile_setup
);
938 emit_restore_blits(batch
, batch
->tile_setup
);
939 emit_clears(batch
, batch
->tile_setup
);
943 * transfer from system memory to gmem
946 fd6_emit_tile_mem2gmem(struct fd_batch
*batch
, struct fd_tile
*tile
)
950 /* before IB to rendering cmds: */
952 fd6_emit_tile_renderprep(struct fd_batch
*batch
, struct fd_tile
*tile
)
954 fd6_emit_ib(batch
->gmem
, batch
->tile_setup
);
958 emit_resolve_blit(struct fd_batch
*batch
,
959 struct fd_ringbuffer
*ring
,
961 struct pipe_surface
*psurf
,
965 bool stencil
= false;
967 if (!fd_resource(psurf
->texture
)->valid
)
971 case FD_BUFFER_COLOR
:
973 case FD_BUFFER_STENCIL
:
974 info
|= A6XX_RB_BLIT_INFO_UNK0
;
977 case FD_BUFFER_DEPTH
:
978 info
|= A6XX_RB_BLIT_INFO_DEPTH
;
982 if (util_format_is_pure_integer(psurf
->format
))
983 info
|= A6XX_RB_BLIT_INFO_INTEGER
;
985 OUT_PKT4(ring
, REG_A6XX_RB_BLIT_INFO
, 1);
986 OUT_RING(ring
, info
);
988 emit_blit(batch
, ring
, base
, psurf
, stencil
);
992 * transfer from gmem to system memory (ie. normal RAM)
996 prepare_tile_fini_ib(struct fd_batch
*batch
)
998 struct fd_context
*ctx
= batch
->ctx
;
999 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
1000 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
1001 struct fd_ringbuffer
*ring
;
1003 batch
->tile_fini
= fd_submit_new_ringbuffer(batch
->submit
, 0x1000,
1004 FD_RINGBUFFER_STREAMING
);
1005 ring
= batch
->tile_fini
;
1007 if (use_hw_binning(batch
)) {
1008 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
1009 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(0x5) | 0x10);
1012 OUT_PKT7(ring
, CP_SET_DRAW_STATE
, 3);
1013 OUT_RING(ring
, CP_SET_DRAW_STATE__0_COUNT(0) |
1014 CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS
|
1015 CP_SET_DRAW_STATE__0_GROUP_ID(0));
1016 OUT_RING(ring
, CP_SET_DRAW_STATE__1_ADDR_LO(0));
1017 OUT_RING(ring
, CP_SET_DRAW_STATE__2_ADDR_HI(0));
1019 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
1020 OUT_RING(ring
, 0x0);
1022 emit_marker6(ring
, 7);
1023 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
1024 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_RESOLVE
) | 0x10);
1025 emit_marker6(ring
, 7);
1027 set_blit_scissor(batch
, ring
);
1029 if (batch
->resolve
& (FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
)) {
1030 struct fd_resource
*rsc
= fd_resource(pfb
->zsbuf
->texture
);
1032 if (!rsc
->stencil
|| (batch
->resolve
& FD_BUFFER_DEPTH
)) {
1033 emit_resolve_blit(batch
, ring
,
1034 gmem
->zsbuf_base
[0], pfb
->zsbuf
,
1037 if (rsc
->stencil
&& (batch
->resolve
& FD_BUFFER_STENCIL
)) {
1038 emit_resolve_blit(batch
, ring
,
1039 gmem
->zsbuf_base
[1], pfb
->zsbuf
,
1044 if (batch
->resolve
& FD_BUFFER_COLOR
) {
1046 for (i
= 0; i
< pfb
->nr_cbufs
; i
++) {
1049 if (!(batch
->resolve
& (PIPE_CLEAR_COLOR0
<< i
)))
1051 emit_resolve_blit(batch
, ring
, gmem
->cbuf_base
[i
], pfb
->cbufs
[i
],
1058 fd6_emit_tile_gmem2mem(struct fd_batch
*batch
, struct fd_tile
*tile
)
1060 fd6_emit_ib(batch
->gmem
, batch
->tile_fini
);
1064 fd6_emit_tile_fini(struct fd_batch
*batch
)
1066 struct fd_ringbuffer
*ring
= batch
->gmem
;
1068 OUT_PKT4(ring
, REG_A6XX_GRAS_LRZ_CNTL
, 1);
1069 OUT_RING(ring
, A6XX_GRAS_LRZ_CNTL_ENABLE
| A6XX_GRAS_LRZ_CNTL_UNK3
);
1071 fd6_emit_lrz_flush(ring
);
1073 fd6_event_write(batch
, ring
, CACHE_FLUSH_TS
, true);
1077 fd6_emit_sysmem_prep(struct fd_batch
*batch
)
1079 struct pipe_framebuffer_state
*pfb
= &batch
->framebuffer
;
1080 struct fd_ringbuffer
*ring
= batch
->gmem
;
1082 fd6_emit_restore(batch
, ring
);
1084 fd6_emit_lrz_flush(ring
);
1086 emit_marker6(ring
, 7);
1087 OUT_PKT7(ring
, CP_SET_MARKER
, 1);
1088 OUT_RING(ring
, A2XX_CP_SET_MARKER_0_MODE(RM6_BYPASS
) | 0x10); /* | 0x10 ? */
1089 emit_marker6(ring
, 7);
1091 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
1092 OUT_RING(ring
, 0x0);
1094 fd6_event_write(batch
, ring
, PC_CCU_INVALIDATE_COLOR
, false);
1095 fd6_cache_inv(batch
, ring
);
1098 OUT_PKT4(ring
, REG_A6XX_PC_POWER_CNTL
, 1);
1099 OUT_RING(ring
, 0x00000003); /* PC_POWER_CNTL */
1103 OUT_PKT4(ring
, REG_A6XX_VFD_POWER_CNTL
, 1);
1104 OUT_RING(ring
, 0x00000003); /* VFD_POWER_CNTL */
1107 /* 0x10000000 for BYPASS.. 0x7c13c080 for GMEM: */
1108 fd_wfi(batch
, ring
);
1109 OUT_PKT4(ring
, REG_A6XX_RB_CCU_CNTL
, 1);
1110 OUT_RING(ring
, 0x10000000); /* RB_CCU_CNTL */
1112 set_scissor(ring
, 0, 0, pfb
->width
- 1, pfb
->height
- 1);
1114 set_window_offset(ring
, 0, 0);
1116 set_bin_size(ring
, 0, 0, 0xc00000); /* 0xc00000 = BYPASS? */
1118 OUT_PKT7(ring
, CP_SET_VISIBILITY_OVERRIDE
, 1);
1119 OUT_RING(ring
, 0x1);
1121 patch_draws(batch
, IGNORE_VISIBILITY
);
1123 emit_zs(ring
, pfb
->zsbuf
, NULL
);
1124 emit_mrt(ring
, pfb
, NULL
);
1125 emit_msaa(ring
, pfb
->samples
);
1127 update_render_cntl(batch
, pfb
, false);
1131 fd6_emit_sysmem_fini(struct fd_batch
*batch
)
1133 struct fd_ringbuffer
*ring
= batch
->gmem
;
1135 OUT_PKT7(ring
, CP_SKIP_IB2_ENABLE_GLOBAL
, 1);
1136 OUT_RING(ring
, 0x0);
1138 fd6_emit_lrz_flush(ring
);
1140 fd6_event_write(batch
, ring
, UNK_1D
, true);
1144 fd6_gmem_init(struct pipe_context
*pctx
)
1146 struct fd_context
*ctx
= fd_context(pctx
);
1148 ctx
->emit_tile_init
= fd6_emit_tile_init
;
1149 ctx
->emit_tile_prep
= fd6_emit_tile_prep
;
1150 ctx
->emit_tile_mem2gmem
= fd6_emit_tile_mem2gmem
;
1151 ctx
->emit_tile_renderprep
= fd6_emit_tile_renderprep
;
1152 ctx
->emit_tile_gmem2mem
= fd6_emit_tile_gmem2mem
;
1153 ctx
->emit_tile_fini
= fd6_emit_tile_fini
;
1154 ctx
->emit_sysmem_prep
= fd6_emit_sysmem_prep
;
1155 ctx
->emit_sysmem_fini
= fd6_emit_sysmem_fini
;