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_draw.h"
36 #include "freedreno_state.h"
37 #include "freedreno_resource.h"
40 #include "fd3_context.h"
42 #include "fd3_program.h"
46 static const struct fd3_shader_key key
= {
50 emit_mrt(struct fd_ringbuffer
*ring
, unsigned nr_bufs
,
51 struct pipe_surface
**bufs
, uint32_t *bases
, uint32_t bin_w
)
53 enum a3xx_tile_mode tile_mode
;
57 tile_mode
= TILE_32X32
;
62 for (i
= 0; i
< 4; i
++) {
63 enum a3xx_color_fmt format
= 0;
64 enum a3xx_color_swap swap
= WZYX
;
65 struct fd_resource
*rsc
= NULL
;
66 struct fd_resource_slice
*slice
= NULL
;
70 if ((i
< nr_bufs
) && bufs
[i
]) {
71 struct pipe_surface
*psurf
= bufs
[i
];
73 rsc
= fd_resource(psurf
->texture
);
74 slice
= &rsc
->slices
[psurf
->u
.tex
.level
];
75 format
= fd3_pipe2color(psurf
->format
);
76 swap
= fd3_pipe2swap(psurf
->format
);
79 stride
= bin_w
* rsc
->cpp
;
82 base
= bases
[i
] * rsc
->cpp
;
85 stride
= slice
->pitch
* rsc
->cpp
;
89 OUT_PKT0(ring
, REG_A3XX_RB_MRT_BUF_INFO(i
), 2);
90 OUT_RING(ring
, A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format
) |
91 A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode
) |
92 A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride
) |
93 A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap
));
94 if (bin_w
|| (i
>= nr_bufs
)) {
95 OUT_RING(ring
, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base
));
97 OUT_RELOCW(ring
, rsc
->bo
, slice
->offset
, 0, -1);
100 OUT_PKT0(ring
, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i
), 1);
101 OUT_RING(ring
, A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT(format
));
106 depth_base(struct fd_gmem_stateobj
*gmem
)
108 return align(gmem
->bin_w
* gmem
->bin_h
, 0x4000);
112 use_hw_binning(struct fd_context
*ctx
)
114 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
115 return fd_binning_enabled
&& ((gmem
->nbins_x
* gmem
->nbins_y
) > 2);
118 /* workaround for (hlsq?) lockup with hw binning on a3xx patchlevel 0 */
119 static void update_vsc_pipe(struct fd_context
*ctx
);
121 emit_binning_workaround(struct fd_context
*ctx
)
123 struct fd3_context
*fd3_ctx
= fd3_context(ctx
);
124 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
125 struct fd_ringbuffer
*ring
= ctx
->ring
;
127 OUT_PKT0(ring
, REG_A3XX_RB_MODE_CONTROL
, 2);
128 OUT_RING(ring
, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS
) |
129 A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE
);
130 OUT_RING(ring
, A3XX_RB_RENDER_CONTROL_BIN_WIDTH(32) |
131 A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE
|
132 A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER
));
134 OUT_PKT0(ring
, REG_A3XX_RB_COPY_CONTROL
, 4);
135 OUT_RING(ring
, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE
) |
136 A3XX_RB_COPY_CONTROL_MODE(0) |
137 A3XX_RB_COPY_CONTROL_GMEM_BASE(0));
138 OUT_RELOC(ring
, fd_resource(fd3_ctx
->solid_vbuf
)->bo
, 0x20, 0, -1); /* RB_COPY_DEST_BASE */
139 OUT_RING(ring
, A3XX_RB_COPY_DEST_PITCH_PITCH(128));
140 OUT_RING(ring
, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR
) |
141 A3XX_RB_COPY_DEST_INFO_FORMAT(RB_R8G8B8A8_UNORM
) |
142 A3XX_RB_COPY_DEST_INFO_SWAP(WZYX
) |
143 A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
144 A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE
));
146 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
147 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS
) |
148 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
149 A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
152 fd3_program_emit(ring
, &ctx
->solid_prog
, key
);
153 fd3_emit_vertex_bufs(ring
, fd3_shader_variant(ctx
->solid_prog
.vp
, key
),
154 (struct fd3_vertex_buf
[]) {{
155 .prsc
= fd3_ctx
->solid_vbuf
,
157 .format
= PIPE_FORMAT_R32G32B32_FLOAT
,
160 OUT_PKT0(ring
, REG_A3XX_HLSQ_CONTROL_0_REG
, 4);
161 OUT_RING(ring
, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(FOUR_QUADS
) |
162 A3XX_HLSQ_CONTROL_0_REG_FSSUPERTHREADENABLE
|
163 A3XX_HLSQ_CONTROL_0_REG_RESERVED2
|
164 A3XX_HLSQ_CONTROL_0_REG_SPCONSTFULLUPDATE
);
165 OUT_RING(ring
, A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(TWO_QUADS
) |
166 A3XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE
);
167 OUT_RING(ring
, A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(31));
168 OUT_RING(ring
, 0); /* HLSQ_CONTROL_3_REG */
170 OUT_PKT0(ring
, REG_A3XX_HLSQ_CONST_FSPRESV_RANGE_REG
, 1);
171 OUT_RING(ring
, A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY(0x20) |
172 A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY(0x20));
174 OUT_PKT0(ring
, REG_A3XX_RB_MSAA_CONTROL
, 1);
175 OUT_RING(ring
, A3XX_RB_MSAA_CONTROL_DISABLE
|
176 A3XX_RB_MSAA_CONTROL_SAMPLES(MSAA_ONE
) |
177 A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(0xffff));
179 OUT_PKT0(ring
, REG_A3XX_RB_DEPTH_CONTROL
, 1);
180 OUT_RING(ring
, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER
));
182 OUT_PKT0(ring
, REG_A3XX_RB_STENCIL_CONTROL
, 1);
183 OUT_RING(ring
, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER
) |
184 A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP
) |
185 A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP
) |
186 A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP
) |
187 A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER
) |
188 A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP
) |
189 A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP
) |
190 A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP
));
192 OUT_PKT0(ring
, REG_A3XX_GRAS_SU_MODE_CONTROL
, 1);
193 OUT_RING(ring
, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0.0));
195 OUT_PKT0(ring
, REG_A3XX_VFD_INDEX_MIN
, 4);
196 OUT_RING(ring
, 0); /* VFD_INDEX_MIN */
197 OUT_RING(ring
, 2); /* VFD_INDEX_MAX */
198 OUT_RING(ring
, 0); /* VFD_INSTANCEID_OFFSET */
199 OUT_RING(ring
, 0); /* VFD_INDEX_OFFSET */
201 OUT_PKT0(ring
, REG_A3XX_PC_PRIM_VTX_CNTL
, 1);
202 OUT_RING(ring
, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
203 A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES
) |
204 A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES
) |
205 A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST
);
207 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL
, 2);
208 OUT_RING(ring
, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
209 A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(1));
210 OUT_RING(ring
, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(0) |
211 A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(1));
213 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL
, 2);
214 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
215 A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
216 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(31) |
217 A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(0));
219 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_VPORT_XOFFSET
, 6);
220 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_XOFFSET(0.0));
221 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_XSCALE(1.0));
222 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_YOFFSET(0.0));
223 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_YSCALE(1.0));
224 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
225 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
227 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_CLIP_CNTL
, 1);
228 OUT_RING(ring
, A3XX_GRAS_CL_CLIP_CNTL_CLIP_DISABLE
|
229 A3XX_GRAS_CL_CLIP_CNTL_ZFAR_CLIP_DISABLE
|
230 A3XX_GRAS_CL_CLIP_CNTL_VP_CLIP_CODE_IGNORE
|
231 A3XX_GRAS_CL_CLIP_CNTL_VP_XFORM_DISABLE
|
232 A3XX_GRAS_CL_CLIP_CNTL_PERSP_DIVISION_DISABLE
);
234 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_GB_CLIP_ADJ
, 1);
235 OUT_RING(ring
, A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ(0) |
236 A3XX_GRAS_CL_GB_CLIP_ADJ_VERT(0));
238 OUT_PKT3(ring
, CP_DRAW_INDX_2
, 5);
239 OUT_RING(ring
, 0x00000000); /* viz query info. */
240 OUT_RING(ring
, DRAW(DI_PT_RECTLIST
, DI_SRC_SEL_IMMEDIATE
,
241 INDEX_SIZE_32_BIT
, IGNORE_VISIBILITY
));
242 OUT_RING(ring
, 2); /* NumIndices */
247 OUT_PKT0(ring
, REG_A3XX_HLSQ_CONTROL_0_REG
, 1);
248 OUT_RING(ring
, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(TWO_QUADS
));
250 OUT_PKT0(ring
, REG_A3XX_VFD_PERFCOUNTER0_SELECT
, 1);
251 OUT_RING(ring
, 0x00000000);
254 OUT_PKT0(ring
, REG_A3XX_VSC_BIN_SIZE
, 1);
255 OUT_RING(ring
, A3XX_VSC_BIN_SIZE_WIDTH(gmem
->bin_w
) |
256 A3XX_VSC_BIN_SIZE_HEIGHT(gmem
->bin_h
));
258 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
259 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
260 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
261 A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
263 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_CLIP_CNTL
, 1);
264 OUT_RING(ring
, 0x00000000);
267 /* transfer from gmem to system memory (ie. normal RAM) */
270 emit_gmem2mem_surf(struct fd_context
*ctx
,
271 enum adreno_rb_copy_control_mode mode
,
272 uint32_t base
, struct pipe_surface
*psurf
)
274 struct fd_ringbuffer
*ring
= ctx
->ring
;
275 struct fd_resource
*rsc
= fd_resource(psurf
->texture
);
276 struct fd_resource_slice
*slice
= &rsc
->slices
[psurf
->u
.tex
.level
];
278 OUT_PKT0(ring
, REG_A3XX_RB_COPY_CONTROL
, 4);
279 OUT_RING(ring
, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE
) |
280 A3XX_RB_COPY_CONTROL_MODE(mode
) |
281 A3XX_RB_COPY_CONTROL_GMEM_BASE(base
));
282 OUT_RELOCW(ring
, rsc
->bo
, slice
->offset
, 0, -1); /* RB_COPY_DEST_BASE */
283 OUT_RING(ring
, A3XX_RB_COPY_DEST_PITCH_PITCH(slice
->pitch
* rsc
->cpp
));
284 OUT_RING(ring
, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR
) |
285 A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(psurf
->format
)) |
286 A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
287 A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE
) |
288 A3XX_RB_COPY_DEST_INFO_SWAP(fd3_pipe2swap(psurf
->format
)));
290 fd_draw(ctx
, ring
, DI_PT_RECTLIST
, IGNORE_VISIBILITY
,
291 DI_SRC_SEL_AUTO_INDEX
, 2, INDEX_SIZE_IGN
, 0, 0, NULL
);
295 fd3_emit_tile_gmem2mem(struct fd_context
*ctx
, struct fd_tile
*tile
)
297 struct fd3_context
*fd3_ctx
= fd3_context(ctx
);
298 struct fd_ringbuffer
*ring
= ctx
->ring
;
299 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
301 OUT_PKT0(ring
, REG_A3XX_RB_DEPTH_CONTROL
, 1);
302 OUT_RING(ring
, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER
));
304 OUT_PKT0(ring
, REG_A3XX_RB_STENCIL_CONTROL
, 1);
305 OUT_RING(ring
, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER
) |
306 A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP
) |
307 A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP
) |
308 A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP
) |
309 A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER
) |
310 A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP
) |
311 A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP
) |
312 A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP
));
314 OUT_PKT0(ring
, REG_A3XX_RB_STENCILREFMASK
, 2);
315 OUT_RING(ring
, 0xff000000 |
316 A3XX_RB_STENCILREFMASK_STENCILREF(0) |
317 A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
318 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
319 OUT_RING(ring
, 0xff000000 |
320 A3XX_RB_STENCILREFMASK_STENCILREF(0) |
321 A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
322 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
324 OUT_PKT0(ring
, REG_A3XX_GRAS_SU_MODE_CONTROL
, 1);
325 OUT_RING(ring
, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
327 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_CLIP_CNTL
, 1);
328 OUT_RING(ring
, 0x00000000); /* GRAS_CL_CLIP_CNTL */
330 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_VPORT_XOFFSET
, 6);
331 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_XOFFSET((float)pfb
->width
/2.0 - 0.5));
332 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_XSCALE((float)pfb
->width
/2.0));
333 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_YOFFSET((float)pfb
->height
/2.0 - 0.5));
334 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_YSCALE(-(float)pfb
->height
/2.0));
335 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
336 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
338 OUT_PKT0(ring
, REG_A3XX_RB_MODE_CONTROL
, 1);
339 OUT_RING(ring
, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS
) |
340 A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE
);
342 OUT_PKT0(ring
, REG_A3XX_RB_RENDER_CONTROL
, 1);
343 OUT_RING(ring
, A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE
|
344 A3XX_RB_RENDER_CONTROL_ENABLE_GMEM
|
345 A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER
) |
346 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(ctx
->gmem
.bin_w
));
348 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
349 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS
) |
350 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
351 A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
353 OUT_PKT0(ring
, REG_A3XX_PC_PRIM_VTX_CNTL
, 1);
354 OUT_RING(ring
, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
355 A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES
) |
356 A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES
) |
357 A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST
);
359 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL
, 2);
360 OUT_RING(ring
, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
361 A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
362 OUT_RING(ring
, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(pfb
->width
- 1) |
363 A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(pfb
->height
- 1));
365 OUT_PKT0(ring
, REG_A3XX_VFD_INDEX_MIN
, 4);
366 OUT_RING(ring
, 0); /* VFD_INDEX_MIN */
367 OUT_RING(ring
, 2); /* VFD_INDEX_MAX */
368 OUT_RING(ring
, 0); /* VFD_INSTANCEID_OFFSET */
369 OUT_RING(ring
, 0); /* VFD_INDEX_OFFSET */
372 fd3_program_emit(ring
, &ctx
->solid_prog
, key
);
373 fd3_emit_vertex_bufs(ring
, fd3_shader_variant(ctx
->solid_prog
.vp
, key
),
374 (struct fd3_vertex_buf
[]) {{
375 .prsc
= fd3_ctx
->solid_vbuf
,
377 .format
= PIPE_FORMAT_R32G32B32_FLOAT
,
380 if (ctx
->resolve
& (FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
)) {
383 struct fd_resource
*rsc
=
384 fd_resource(pfb
->cbufs
[0]->texture
);
385 base
= depth_base(&ctx
->gmem
) * rsc
->cpp
;
387 emit_gmem2mem_surf(ctx
, RB_COPY_DEPTH_STENCIL
, base
, pfb
->zsbuf
);
390 if (ctx
->resolve
& FD_BUFFER_COLOR
) {
391 emit_gmem2mem_surf(ctx
, RB_COPY_RESOLVE
, 0, pfb
->cbufs
[0]);
394 OUT_PKT0(ring
, REG_A3XX_RB_MODE_CONTROL
, 1);
395 OUT_RING(ring
, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
396 A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE
);
398 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
399 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
400 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
401 A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
404 /* transfer from system memory to gmem */
407 emit_mem2gmem_surf(struct fd_context
*ctx
, uint32_t base
,
408 struct pipe_surface
*psurf
, uint32_t bin_w
)
410 struct fd_ringbuffer
*ring
= ctx
->ring
;
412 emit_mrt(ring
, 1, &psurf
, &base
, bin_w
);
415 fd3_emit_gmem_restore_tex(ring
, psurf
);
417 fd_draw(ctx
, ring
, DI_PT_RECTLIST
, IGNORE_VISIBILITY
,
418 DI_SRC_SEL_AUTO_INDEX
, 2, INDEX_SIZE_IGN
, 0, 0, NULL
);
422 fd3_emit_tile_mem2gmem(struct fd_context
*ctx
, struct fd_tile
*tile
)
424 struct fd3_context
*fd3_ctx
= fd3_context(ctx
);
425 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
426 struct fd_ringbuffer
*ring
= ctx
->ring
;
427 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
428 float x0
, y0
, x1
, y1
;
429 unsigned bin_w
= tile
->bin_w
;
430 unsigned bin_h
= tile
->bin_h
;
433 /* write texture coordinates to vertexbuf: */
434 x0
= ((float)tile
->xoff
) / ((float)pfb
->width
);
435 x1
= ((float)tile
->xoff
+ bin_w
) / ((float)pfb
->width
);
436 y0
= ((float)tile
->yoff
) / ((float)pfb
->height
);
437 y1
= ((float)tile
->yoff
+ bin_h
) / ((float)pfb
->height
);
439 OUT_PKT3(ring
, CP_MEM_WRITE
, 5);
440 OUT_RELOC(ring
, fd_resource(fd3_ctx
->blit_texcoord_vbuf
)->bo
, 0, 0, 0);
441 OUT_RING(ring
, fui(x0
));
442 OUT_RING(ring
, fui(y0
));
443 OUT_RING(ring
, fui(x1
));
444 OUT_RING(ring
, fui(y1
));
446 for (i
= 0; i
< 4; i
++) {
447 OUT_PKT0(ring
, REG_A3XX_RB_MRT_CONTROL(i
), 1);
448 OUT_RING(ring
, A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY
) |
449 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE
) |
450 A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
452 OUT_PKT0(ring
, REG_A3XX_RB_MRT_BLEND_CONTROL(i
), 1);
453 OUT_RING(ring
, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE
) |
454 A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC
) |
455 A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO
) |
456 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE
) |
457 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC
) |
458 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO
) |
459 A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE
);
462 OUT_PKT0(ring
, REG_A3XX_RB_RENDER_CONTROL
, 1);
463 OUT_RING(ring
, A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS
) |
464 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem
->bin_w
));
466 OUT_PKT0(ring
, REG_A3XX_RB_DEPTH_CONTROL
, 1);
467 OUT_RING(ring
, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS
));
469 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_CLIP_CNTL
, 1);
470 OUT_RING(ring
, A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER
); /* GRAS_CL_CLIP_CNTL */
472 OUT_PKT0(ring
, REG_A3XX_GRAS_CL_VPORT_XOFFSET
, 6);
473 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_XOFFSET((float)bin_w
/2.0 - 0.5));
474 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_XSCALE((float)bin_w
/2.0));
475 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_YOFFSET((float)bin_h
/2.0 - 0.5));
476 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_YSCALE(-(float)bin_h
/2.0));
477 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
478 OUT_RING(ring
, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
480 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL
, 2);
481 OUT_RING(ring
, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
482 A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
483 OUT_RING(ring
, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w
- 1) |
484 A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h
- 1));
486 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL
, 2);
487 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
488 A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
489 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w
- 1) |
490 A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h
- 1));
492 OUT_PKT0(ring
, REG_A3XX_RB_STENCIL_CONTROL
, 1);
494 A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS
) |
495 A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP
) |
496 A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP
) |
497 A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP
) |
498 A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_ALWAYS
) |
499 A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP
) |
500 A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP
) |
501 A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP
));
503 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
504 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
505 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
506 A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
508 OUT_PKT0(ring
, REG_A3XX_PC_PRIM_VTX_CNTL
, 1);
509 OUT_RING(ring
, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(2) |
510 A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES
) |
511 A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES
) |
512 A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST
);
514 OUT_PKT0(ring
, REG_A3XX_VFD_INDEX_MIN
, 4);
515 OUT_RING(ring
, 0); /* VFD_INDEX_MIN */
516 OUT_RING(ring
, 2); /* VFD_INDEX_MAX */
517 OUT_RING(ring
, 0); /* VFD_INSTANCEID_OFFSET */
518 OUT_RING(ring
, 0); /* VFD_INDEX_OFFSET */
521 fd3_program_emit(ring
, &ctx
->blit_prog
, key
);
522 fd3_emit_vertex_bufs(ring
, fd3_shader_variant(ctx
->blit_prog
.vp
, key
),
523 (struct fd3_vertex_buf
[]) {{
524 .prsc
= fd3_ctx
->blit_texcoord_vbuf
,
526 .format
= PIPE_FORMAT_R32G32_FLOAT
,
528 .prsc
= fd3_ctx
->solid_vbuf
,
530 .format
= PIPE_FORMAT_R32G32B32_FLOAT
,
533 /* for gmem pitch/base calculations, we need to use the non-
534 * truncated tile sizes:
539 if (ctx
->restore
& (FD_BUFFER_DEPTH
| FD_BUFFER_STENCIL
))
540 emit_mem2gmem_surf(ctx
, depth_base(gmem
), pfb
->zsbuf
, bin_w
);
542 if (ctx
->restore
& FD_BUFFER_COLOR
)
543 emit_mem2gmem_surf(ctx
, 0, pfb
->cbufs
[0], bin_w
);
545 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
546 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
547 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
548 A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
552 patch_draws(struct fd_context
*ctx
, enum pc_di_vis_cull_mode vismode
)
555 for (i
= 0; i
< fd_patch_num_elements(&ctx
->draw_patches
); i
++) {
556 struct fd_cs_patch
*patch
= fd_patch_element(&ctx
->draw_patches
, i
);
557 *patch
->cs
= patch
->val
| DRAW(0, 0, 0, vismode
);
559 util_dynarray_resize(&ctx
->draw_patches
, 0);
563 patch_rbrc(struct fd_context
*ctx
, uint32_t val
)
565 struct fd3_context
*fd3_ctx
= fd3_context(ctx
);
567 for (i
= 0; i
< fd_patch_num_elements(&fd3_ctx
->rbrc_patches
); i
++) {
568 struct fd_cs_patch
*patch
= fd_patch_element(&fd3_ctx
->rbrc_patches
, i
);
569 *patch
->cs
= patch
->val
| val
;
571 util_dynarray_resize(&fd3_ctx
->rbrc_patches
, 0);
574 /* for rendering directly to system memory: */
576 fd3_emit_sysmem_prep(struct fd_context
*ctx
)
578 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
579 struct fd_ringbuffer
*ring
= ctx
->ring
;
583 pitch
= fd_resource(pfb
->cbufs
[0]->texture
)->slices
[0].pitch
;
585 fd3_emit_restore(ctx
);
587 OUT_PKT0(ring
, REG_A3XX_RB_FRAME_BUFFER_DIMENSION
, 1);
588 OUT_RING(ring
, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb
->width
) |
589 A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb
->height
));
591 emit_mrt(ring
, pfb
->nr_cbufs
, pfb
->cbufs
, NULL
, 0);
593 /* setup scissor/offset for current tile: */
594 OUT_PKT0(ring
, REG_A3XX_RB_WINDOW_OFFSET
, 1);
595 OUT_RING(ring
, A3XX_RB_WINDOW_OFFSET_X(0) |
596 A3XX_RB_WINDOW_OFFSET_Y(0));
598 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL
, 2);
599 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
600 A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
601 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb
->width
- 1) |
602 A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb
->height
- 1));
604 OUT_PKT0(ring
, REG_A3XX_RB_MODE_CONTROL
, 1);
605 OUT_RING(ring
, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
606 A3XX_RB_MODE_CONTROL_GMEM_BYPASS
|
607 A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE
);
609 patch_draws(ctx
, IGNORE_VISIBILITY
);
610 patch_rbrc(ctx
, A3XX_RB_RENDER_CONTROL_BIN_WIDTH(pitch
));
614 update_vsc_pipe(struct fd_context
*ctx
)
616 struct fd3_context
*fd3_ctx
= fd3_context(ctx
);
617 struct fd_ringbuffer
*ring
= ctx
->ring
;
620 OUT_PKT0(ring
, REG_A3XX_VSC_SIZE_ADDRESS
, 1);
621 OUT_RELOC(ring
, fd3_ctx
->vsc_size_mem
, 0, 0, 0); /* VSC_SIZE_ADDRESS */
623 for (i
= 0; i
< 8; i
++) {
624 struct fd_vsc_pipe
*pipe
= &ctx
->pipe
[i
];
627 pipe
->bo
= fd_bo_new(ctx
->dev
, 0x40000,
628 DRM_FREEDRENO_GEM_TYPE_KMEM
);
631 OUT_PKT0(ring
, REG_A3XX_VSC_PIPE(i
), 3);
632 OUT_RING(ring
, A3XX_VSC_PIPE_CONFIG_X(pipe
->x
) |
633 A3XX_VSC_PIPE_CONFIG_Y(pipe
->y
) |
634 A3XX_VSC_PIPE_CONFIG_W(pipe
->w
) |
635 A3XX_VSC_PIPE_CONFIG_H(pipe
->h
));
636 OUT_RELOC(ring
, pipe
->bo
, 0, 0, 0); /* VSC_PIPE[i].DATA_ADDRESS */
637 OUT_RING(ring
, fd_bo_size(pipe
->bo
) - 32); /* VSC_PIPE[i].DATA_LENGTH */
642 emit_binning_pass(struct fd_context
*ctx
)
644 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
645 struct fd_ringbuffer
*ring
= ctx
->ring
;
648 if (ctx
->screen
->gpu_id
== 320) {
649 emit_binning_workaround(ctx
);
651 OUT_PKT3(ring
, CP_INVALIDATE_STATE
, 1);
652 OUT_RING(ring
, 0x00007fff);
655 OUT_PKT0(ring
, REG_A3XX_VSC_BIN_CONTROL
, 1);
656 OUT_RING(ring
, A3XX_VSC_BIN_CONTROL_BINNING_ENABLE
);
658 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
659 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_TILING_PASS
) |
660 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
661 A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
663 OUT_PKT0(ring
, REG_A3XX_RB_FRAME_BUFFER_DIMENSION
, 1);
664 OUT_RING(ring
, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb
->width
) |
665 A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb
->height
));
667 OUT_PKT0(ring
, REG_A3XX_RB_RENDER_CONTROL
, 1);
668 OUT_RING(ring
, A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER
) |
669 A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE
|
670 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(ctx
->gmem
.bin_w
));
672 /* setup scissor/offset for whole screen: */
673 OUT_PKT0(ring
, REG_A3XX_RB_WINDOW_OFFSET
, 1);
674 OUT_RING(ring
, A3XX_RB_WINDOW_OFFSET_X(0) |
675 A3XX_RB_WINDOW_OFFSET_Y(0));
677 OUT_PKT0(ring
, REG_A3XX_RB_LRZ_VSC_CONTROL
, 1);
678 OUT_RING(ring
, A3XX_RB_LRZ_VSC_CONTROL_BINNING_ENABLE
);
680 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL
, 2);
681 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
682 A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
683 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb
->width
- 1) |
684 A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb
->height
- 1));
686 OUT_PKT0(ring
, REG_A3XX_RB_MODE_CONTROL
, 1);
687 OUT_RING(ring
, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_TILING_PASS
) |
688 A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE
);
690 for (i
= 0; i
< 4; i
++) {
691 OUT_PKT0(ring
, REG_A3XX_RB_MRT_CONTROL(i
), 1);
692 OUT_RING(ring
, A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_CLEAR
) |
693 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE
) |
694 A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0));
697 OUT_PKT0(ring
, REG_A3XX_PC_VSTREAM_CONTROL
, 1);
698 OUT_RING(ring
, A3XX_PC_VSTREAM_CONTROL_SIZE(1) |
699 A3XX_PC_VSTREAM_CONTROL_N(0));
701 /* emit IB to binning drawcmds: */
702 OUT_IB(ring
, ctx
->binning_start
, ctx
->binning_end
);
707 /* and then put stuff back the way it was: */
709 OUT_PKT0(ring
, REG_A3XX_VSC_BIN_CONTROL
, 1);
710 OUT_RING(ring
, 0x00000000);
712 OUT_PKT0(ring
, REG_A3XX_SP_SP_CTRL_REG
, 1);
713 OUT_RING(ring
, A3XX_SP_SP_CTRL_REG_RESOLVE
|
714 A3XX_SP_SP_CTRL_REG_CONSTMODE(1) |
715 A3XX_SP_SP_CTRL_REG_SLEEPMODE(1) |
716 A3XX_SP_SP_CTRL_REG_L0MODE(0));
718 OUT_PKT0(ring
, REG_A3XX_RB_LRZ_VSC_CONTROL
, 1);
719 OUT_RING(ring
, 0x00000000);
721 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_CONTROL
, 1);
722 OUT_RING(ring
, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
723 A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE
) |
724 A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
726 OUT_PKT0(ring
, REG_A3XX_RB_MODE_CONTROL
, 2);
727 OUT_RING(ring
, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
728 A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE
);
729 OUT_RING(ring
, A3XX_RB_RENDER_CONTROL_ENABLE_GMEM
|
730 A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER
) |
731 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(ctx
->gmem
.bin_w
));
733 OUT_PKT3(ring
, CP_EVENT_WRITE
, 1);
734 OUT_RING(ring
, CACHE_FLUSH
);
736 if (ctx
->screen
->gpu_id
== 320) {
737 /* dummy-draw workaround: */
738 OUT_PKT3(ring
, CP_DRAW_INDX
, 3);
739 OUT_RING(ring
, 0x00000000);
740 OUT_RING(ring
, DRAW(1, DI_SRC_SEL_AUTO_INDEX
,
741 INDEX_SIZE_IGN
, IGNORE_VISIBILITY
));
742 OUT_RING(ring
, 0); /* NumIndices */
746 OUT_PKT3(ring
, CP_NOP
, 4);
747 OUT_RING(ring
, 0x00000000);
748 OUT_RING(ring
, 0x00000000);
749 OUT_RING(ring
, 0x00000000);
750 OUT_RING(ring
, 0x00000000);
754 if (ctx
->screen
->gpu_id
== 320) {
755 emit_binning_workaround(ctx
);
759 /* before first tile */
761 fd3_emit_tile_init(struct fd_context
*ctx
)
763 struct fd_ringbuffer
*ring
= ctx
->ring
;
764 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
766 fd3_emit_restore(ctx
);
768 /* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated
769 * at the right and bottom edge tiles
771 OUT_PKT0(ring
, REG_A3XX_VSC_BIN_SIZE
, 1);
772 OUT_RING(ring
, A3XX_VSC_BIN_SIZE_WIDTH(gmem
->bin_w
) |
773 A3XX_VSC_BIN_SIZE_HEIGHT(gmem
->bin_h
));
775 update_vsc_pipe(ctx
);
777 if (use_hw_binning(ctx
)) {
778 /* mark the end of the binning cmds: */
779 fd_ringmarker_mark(ctx
->binning_end
);
781 /* emit hw binning pass: */
782 emit_binning_pass(ctx
);
784 patch_draws(ctx
, USE_VISIBILITY
);
786 patch_draws(ctx
, IGNORE_VISIBILITY
);
789 patch_rbrc(ctx
, A3XX_RB_RENDER_CONTROL_ENABLE_GMEM
|
790 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem
->bin_w
));
793 /* before mem2gmem */
795 fd3_emit_tile_prep(struct fd_context
*ctx
, struct fd_tile
*tile
)
797 struct fd_ringbuffer
*ring
= ctx
->ring
;
798 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
799 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
802 OUT_PKT0(ring
, REG_A3XX_RB_DEPTH_INFO
, 2);
803 reg
= A3XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(gmem
));
805 reg
|= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb
->zsbuf
->format
));
809 uint32_t cpp
= util_format_get_blocksize(pfb
->zsbuf
->format
);
810 OUT_RING(ring
, A3XX_RB_DEPTH_PITCH(cpp
* gmem
->bin_w
));
812 OUT_RING(ring
, 0x00000000);
815 OUT_PKT0(ring
, REG_A3XX_RB_FRAME_BUFFER_DIMENSION
, 1);
816 OUT_RING(ring
, A3XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(pfb
->width
) |
817 A3XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(pfb
->height
));
819 OUT_PKT0(ring
, REG_A3XX_RB_MODE_CONTROL
, 1);
820 OUT_RING(ring
, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS
) |
821 A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE
);
824 /* before IB to rendering cmds: */
826 fd3_emit_tile_renderprep(struct fd_context
*ctx
, struct fd_tile
*tile
)
828 struct fd3_context
*fd3_ctx
= fd3_context(ctx
);
829 struct fd_ringbuffer
*ring
= ctx
->ring
;
830 struct fd_gmem_stateobj
*gmem
= &ctx
->gmem
;
831 struct pipe_framebuffer_state
*pfb
= &ctx
->framebuffer
;
833 uint32_t x1
= tile
->xoff
;
834 uint32_t y1
= tile
->yoff
;
835 uint32_t x2
= tile
->xoff
+ tile
->bin_w
- 1;
836 uint32_t y2
= tile
->yoff
+ tile
->bin_h
- 1;
838 if (use_hw_binning(ctx
)) {
839 struct fd_vsc_pipe
*pipe
= &ctx
->pipe
[tile
->p
];
841 assert(pipe
->w
* pipe
->h
);
843 OUT_PKT3(ring
, CP_EVENT_WRITE
, 1);
844 OUT_RING(ring
, HLSQ_FLUSH
);
848 OUT_PKT0(ring
, REG_A3XX_PC_VSTREAM_CONTROL
, 1);
849 OUT_RING(ring
, A3XX_PC_VSTREAM_CONTROL_SIZE(pipe
->w
* pipe
->h
) |
850 A3XX_PC_VSTREAM_CONTROL_N(tile
->n
));
852 OUT_PKT3(ring
, CP_EVENT_WRITE
, 1);
853 OUT_RING(ring
, CACHE_FLUSH
);
855 OUT_PKT3(ring
, CP_SET_BIN_DATA
, 2);
856 OUT_RELOC(ring
, pipe
->bo
, 0, 0, 0); /* BIN_DATA_ADDR <- VSC_PIPE[p].DATA_ADDRESS */
857 OUT_RELOC(ring
, fd3_ctx
->vsc_size_mem
, /* BIN_SIZE_ADDR <- VSC_SIZE_ADDRESS + (p * 4) */
858 (tile
->p
* 4), 0, 0);
860 OUT_PKT0(ring
, REG_A3XX_PC_VSTREAM_CONTROL
, 1);
861 OUT_RING(ring
, 0x00000000);
864 OUT_PKT3(ring
, CP_SET_BIN
, 3);
865 OUT_RING(ring
, 0x00000000);
866 OUT_RING(ring
, CP_SET_BIN_1_X1(x1
) | CP_SET_BIN_1_Y1(y1
));
867 OUT_RING(ring
, CP_SET_BIN_2_X2(x2
) | CP_SET_BIN_2_Y2(y2
));
869 emit_mrt(ring
, pfb
->nr_cbufs
, pfb
->cbufs
, NULL
, gmem
->bin_w
);
871 /* setup scissor/offset for current tile: */
872 OUT_PKT0(ring
, REG_A3XX_RB_WINDOW_OFFSET
, 1);
873 OUT_RING(ring
, A3XX_RB_WINDOW_OFFSET_X(tile
->xoff
) |
874 A3XX_RB_WINDOW_OFFSET_Y(tile
->yoff
));
876 OUT_PKT0(ring
, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL
, 2);
877 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1
) |
878 A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1
));
879 OUT_RING(ring
, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2
) |
880 A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2
));
884 fd3_gmem_init(struct pipe_context
*pctx
)
886 struct fd_context
*ctx
= fd_context(pctx
);
888 ctx
->emit_sysmem_prep
= fd3_emit_sysmem_prep
;
889 ctx
->emit_tile_init
= fd3_emit_tile_init
;
890 ctx
->emit_tile_prep
= fd3_emit_tile_prep
;
891 ctx
->emit_tile_mem2gmem
= fd3_emit_tile_mem2gmem
;
892 ctx
->emit_tile_renderprep
= fd3_emit_tile_renderprep
;
893 ctx
->emit_tile_gmem2mem
= fd3_emit_tile_gmem2mem
;