freedreno/a3xx: add shader variants
[mesa.git] / src / gallium / drivers / freedreno / a3xx / fd3_gmem.c
1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3 /*
4 * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 * Rob Clark <robclark@freedesktop.org>
27 */
28
29 #include "pipe/p_state.h"
30 #include "util/u_string.h"
31 #include "util/u_memory.h"
32 #include "util/u_inlines.h"
33 #include "util/u_format.h"
34
35 #include "freedreno_draw.h"
36 #include "freedreno_state.h"
37 #include "freedreno_resource.h"
38
39 #include "fd3_gmem.h"
40 #include "fd3_context.h"
41 #include "fd3_emit.h"
42 #include "fd3_program.h"
43 #include "fd3_util.h"
44 #include "fd3_zsa.h"
45
46 static const struct fd3_shader_key key = {
47 };
48
49 static void
50 emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
51 struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w)
52 {
53 enum a3xx_tile_mode tile_mode;
54 unsigned i;
55
56 if (bin_w) {
57 tile_mode = TILE_32X32;
58 } else {
59 tile_mode = LINEAR;
60 }
61
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;
67 uint32_t stride = 0;
68 uint32_t base = 0;
69
70 if ((i < nr_bufs) && bufs[i]) {
71 struct pipe_surface *psurf = bufs[i];
72
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);
77
78 if (bin_w) {
79 stride = bin_w * rsc->cpp;
80
81 if (bases) {
82 base = bases[i] * rsc->cpp;
83 }
84 } else {
85 stride = slice->pitch * rsc->cpp;
86 }
87 }
88
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));
96 } else {
97 OUT_RELOCW(ring, rsc->bo, slice->offset, 0, -1);
98 }
99
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));
102 }
103 }
104
105 static uint32_t
106 depth_base(struct fd_gmem_stateobj *gmem)
107 {
108 return align(gmem->bin_w * gmem->bin_h, 0x4000);
109 }
110
111 static bool
112 use_hw_binning(struct fd_context *ctx)
113 {
114 struct fd_gmem_stateobj *gmem = &ctx->gmem;
115 return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) > 2);
116 }
117
118 /* workaround for (hlsq?) lockup with hw binning on a3xx patchlevel 0 */
119 static void update_vsc_pipe(struct fd_context *ctx);
120 static void
121 emit_binning_workaround(struct fd_context *ctx)
122 {
123 struct fd3_context *fd3_ctx = fd3_context(ctx);
124 struct fd_gmem_stateobj *gmem = &ctx->gmem;
125 struct fd_ringbuffer *ring = ctx->ring;
126
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));
133
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));
145
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));
150
151 fd_wfi(ctx, ring);
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,
156 .stride = 12,
157 .format = PIPE_FORMAT_R32G32B32_FLOAT,
158 }}, 1);
159
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 */
169
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));
173
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));
178
179 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
180 OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
181
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));
191
192 OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
193 OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0.0));
194
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 */
200
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);
206
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));
212
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));
218
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));
226
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);
233
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));
237
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 */
243 OUT_RING(ring, 2);
244 OUT_RING(ring, 1);
245 fd_reset_wfi(ctx);
246
247 OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 1);
248 OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(TWO_QUADS));
249
250 OUT_PKT0(ring, REG_A3XX_VFD_PERFCOUNTER0_SELECT, 1);
251 OUT_RING(ring, 0x00000000);
252
253 fd_wfi(ctx, ring);
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));
257
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));
262
263 OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
264 OUT_RING(ring, 0x00000000);
265 }
266
267 /* transfer from gmem to system memory (ie. normal RAM) */
268
269 static void
270 emit_gmem2mem_surf(struct fd_context *ctx,
271 enum adreno_rb_copy_control_mode mode,
272 uint32_t base, struct pipe_surface *psurf)
273 {
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];
277
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)));
289
290 fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
291 DI_SRC_SEL_AUTO_INDEX, 2, INDEX_SIZE_IGN, 0, 0, NULL);
292 }
293
294 static void
295 fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
296 {
297 struct fd3_context *fd3_ctx = fd3_context(ctx);
298 struct fd_ringbuffer *ring = ctx->ring;
299 struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
300
301 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
302 OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
303
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));
313
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));
323
324 OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
325 OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
326
327 OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
328 OUT_RING(ring, 0x00000000); /* GRAS_CL_CLIP_CNTL */
329
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));
337
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);
341
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));
347
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));
352
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);
358
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));
364
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 */
370
371 fd_wfi(ctx, ring);
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,
376 .stride = 12,
377 .format = PIPE_FORMAT_R32G32B32_FLOAT,
378 }}, 1);
379
380 if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
381 uint32_t base = 0;
382 if (pfb->cbufs[0]) {
383 struct fd_resource *rsc =
384 fd_resource(pfb->cbufs[0]->texture);
385 base = depth_base(&ctx->gmem) * rsc->cpp;
386 }
387 emit_gmem2mem_surf(ctx, RB_COPY_DEPTH_STENCIL, base, pfb->zsbuf);
388 }
389
390 if (ctx->resolve & FD_BUFFER_COLOR) {
391 emit_gmem2mem_surf(ctx, RB_COPY_RESOLVE, 0, pfb->cbufs[0]);
392 }
393
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);
397
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));
402 }
403
404 /* transfer from system memory to gmem */
405
406 static void
407 emit_mem2gmem_surf(struct fd_context *ctx, uint32_t base,
408 struct pipe_surface *psurf, uint32_t bin_w)
409 {
410 struct fd_ringbuffer *ring = ctx->ring;
411
412 emit_mrt(ring, 1, &psurf, &base, bin_w);
413
414 fd_wfi(ctx, ring);
415 fd3_emit_gmem_restore_tex(ring, psurf);
416
417 fd_draw(ctx, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
418 DI_SRC_SEL_AUTO_INDEX, 2, INDEX_SIZE_IGN, 0, 0, NULL);
419 }
420
421 static void
422 fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
423 {
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;
431 unsigned i;
432
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);
438
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));
445
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));
451
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);
460 }
461
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));
465
466 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
467 OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS));
468
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 */
471
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));
479
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));
485
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));
491
492 OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
493 OUT_RING(ring, 0x2 |
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));
502
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));
507
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);
513
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 */
519
520 fd_wfi(ctx, ring);
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,
525 .stride = 8,
526 .format = PIPE_FORMAT_R32G32_FLOAT,
527 }, {
528 .prsc = fd3_ctx->solid_vbuf,
529 .stride = 12,
530 .format = PIPE_FORMAT_R32G32B32_FLOAT,
531 }}, 2);
532
533 /* for gmem pitch/base calculations, we need to use the non-
534 * truncated tile sizes:
535 */
536 bin_w = gmem->bin_w;
537 bin_h = gmem->bin_h;
538
539 if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
540 emit_mem2gmem_surf(ctx, depth_base(gmem), pfb->zsbuf, bin_w);
541
542 if (ctx->restore & FD_BUFFER_COLOR)
543 emit_mem2gmem_surf(ctx, 0, pfb->cbufs[0], bin_w);
544
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));
549 }
550
551 static void
552 patch_draws(struct fd_context *ctx, enum pc_di_vis_cull_mode vismode)
553 {
554 unsigned i;
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);
558 }
559 util_dynarray_resize(&ctx->draw_patches, 0);
560 }
561
562 static void
563 patch_rbrc(struct fd_context *ctx, uint32_t val)
564 {
565 struct fd3_context *fd3_ctx = fd3_context(ctx);
566 unsigned i;
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;
570 }
571 util_dynarray_resize(&fd3_ctx->rbrc_patches, 0);
572 }
573
574 /* for rendering directly to system memory: */
575 static void
576 fd3_emit_sysmem_prep(struct fd_context *ctx)
577 {
578 struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
579 struct fd_ringbuffer *ring = ctx->ring;
580 uint32_t pitch = 0;
581
582 if (pfb->cbufs[0])
583 pitch = fd_resource(pfb->cbufs[0]->texture)->slices[0].pitch;
584
585 fd3_emit_restore(ctx);
586
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));
590
591 emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0);
592
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));
597
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));
603
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);
608
609 patch_draws(ctx, IGNORE_VISIBILITY);
610 patch_rbrc(ctx, A3XX_RB_RENDER_CONTROL_BIN_WIDTH(pitch));
611 }
612
613 static void
614 update_vsc_pipe(struct fd_context *ctx)
615 {
616 struct fd3_context *fd3_ctx = fd3_context(ctx);
617 struct fd_ringbuffer *ring = ctx->ring;
618 int i;
619
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 */
622
623 for (i = 0; i < 8; i++) {
624 struct fd_vsc_pipe *pipe = &ctx->pipe[i];
625
626 if (!pipe->bo) {
627 pipe->bo = fd_bo_new(ctx->dev, 0x40000,
628 DRM_FREEDRENO_GEM_TYPE_KMEM);
629 }
630
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 */
638 }
639 }
640
641 static void
642 emit_binning_pass(struct fd_context *ctx)
643 {
644 struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
645 struct fd_ringbuffer *ring = ctx->ring;
646 int i;
647
648 if (ctx->screen->gpu_id == 320) {
649 emit_binning_workaround(ctx);
650
651 OUT_PKT3(ring, CP_INVALIDATE_STATE, 1);
652 OUT_RING(ring, 0x00007fff);
653 }
654
655 OUT_PKT0(ring, REG_A3XX_VSC_BIN_CONTROL, 1);
656 OUT_RING(ring, A3XX_VSC_BIN_CONTROL_BINNING_ENABLE);
657
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));
662
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));
666
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));
671
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));
676
677 OUT_PKT0(ring, REG_A3XX_RB_LRZ_VSC_CONTROL, 1);
678 OUT_RING(ring, A3XX_RB_LRZ_VSC_CONTROL_BINNING_ENABLE);
679
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));
685
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);
689
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));
695 }
696
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));
700
701 /* emit IB to binning drawcmds: */
702 OUT_IB(ring, ctx->binning_start, ctx->binning_end);
703 fd_reset_wfi(ctx);
704
705 fd_wfi(ctx, ring);
706
707 /* and then put stuff back the way it was: */
708
709 OUT_PKT0(ring, REG_A3XX_VSC_BIN_CONTROL, 1);
710 OUT_RING(ring, 0x00000000);
711
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));
717
718 OUT_PKT0(ring, REG_A3XX_RB_LRZ_VSC_CONTROL, 1);
719 OUT_RING(ring, 0x00000000);
720
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));
725
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));
732
733 OUT_PKT3(ring, CP_EVENT_WRITE, 1);
734 OUT_RING(ring, CACHE_FLUSH);
735
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 */
743 fd_reset_wfi(ctx);
744 }
745
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);
751
752 fd_wfi(ctx, ring);
753
754 if (ctx->screen->gpu_id == 320) {
755 emit_binning_workaround(ctx);
756 }
757 }
758
759 /* before first tile */
760 static void
761 fd3_emit_tile_init(struct fd_context *ctx)
762 {
763 struct fd_ringbuffer *ring = ctx->ring;
764 struct fd_gmem_stateobj *gmem = &ctx->gmem;
765
766 fd3_emit_restore(ctx);
767
768 /* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated
769 * at the right and bottom edge tiles
770 */
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));
774
775 update_vsc_pipe(ctx);
776
777 if (use_hw_binning(ctx)) {
778 /* mark the end of the binning cmds: */
779 fd_ringmarker_mark(ctx->binning_end);
780
781 /* emit hw binning pass: */
782 emit_binning_pass(ctx);
783
784 patch_draws(ctx, USE_VISIBILITY);
785 } else {
786 patch_draws(ctx, IGNORE_VISIBILITY);
787 }
788
789 patch_rbrc(ctx, A3XX_RB_RENDER_CONTROL_ENABLE_GMEM |
790 A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
791 }
792
793 /* before mem2gmem */
794 static void
795 fd3_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile)
796 {
797 struct fd_ringbuffer *ring = ctx->ring;
798 struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
799 struct fd_gmem_stateobj *gmem = &ctx->gmem;
800 uint32_t reg;
801
802 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2);
803 reg = A3XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(gmem));
804 if (pfb->zsbuf) {
805 reg |= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
806 }
807 OUT_RING(ring, reg);
808 if (pfb->zsbuf) {
809 uint32_t cpp = util_format_get_blocksize(pfb->zsbuf->format);
810 OUT_RING(ring, A3XX_RB_DEPTH_PITCH(cpp * gmem->bin_w));
811 } else {
812 OUT_RING(ring, 0x00000000);
813 }
814
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));
818
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);
822 }
823
824 /* before IB to rendering cmds: */
825 static void
826 fd3_emit_tile_renderprep(struct fd_context *ctx, struct fd_tile *tile)
827 {
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;
832
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;
837
838 if (use_hw_binning(ctx)) {
839 struct fd_vsc_pipe *pipe = &ctx->pipe[tile->p];
840
841 assert(pipe->w * pipe->h);
842
843 OUT_PKT3(ring, CP_EVENT_WRITE, 1);
844 OUT_RING(ring, HLSQ_FLUSH);
845
846 OUT_WFI(ring);
847
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));
851
852 OUT_PKT3(ring, CP_EVENT_WRITE, 1);
853 OUT_RING(ring, CACHE_FLUSH);
854
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);
859 } else {
860 OUT_PKT0(ring, REG_A3XX_PC_VSTREAM_CONTROL, 1);
861 OUT_RING(ring, 0x00000000);
862 }
863
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));
868
869 emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, gmem->bin_w);
870
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));
875
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));
881 }
882
883 void
884 fd3_gmem_init(struct pipe_context *pctx)
885 {
886 struct fd_context *ctx = fd_context(pctx);
887
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;
894 }