Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ |
2 | |||
3 | /* |
||
4 | * Copyright (C) 2013 Rob Clark |
||
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 |
||
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_state.h" |
||
36 | #include "freedreno_resource.h" |
||
37 | |||
38 | #include "fd3_gmem.h" |
||
39 | #include "fd3_context.h" |
||
40 | #include "fd3_emit.h" |
||
41 | #include "fd3_program.h" |
||
42 | #include "fd3_util.h" |
||
43 | #include "fd3_zsa.h" |
||
44 | |||
45 | |||
46 | static void |
||
47 | emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, |
||
48 | struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w) |
||
49 | { |
||
50 | enum a3xx_tile_mode tile_mode; |
||
51 | unsigned i; |
||
52 | |||
53 | if (bin_w) { |
||
54 | tile_mode = TILE_32X32; |
||
55 | } else { |
||
56 | tile_mode = LINEAR; |
||
57 | } |
||
58 | |||
59 | for (i = 0; i < 4; i++) { |
||
60 | enum a3xx_color_fmt format = 0; |
||
61 | enum a3xx_color_swap swap = WZYX; |
||
62 | struct fd_resource *res = NULL; |
||
63 | uint32_t stride = 0; |
||
64 | uint32_t base = 0; |
||
65 | |||
66 | if (i < nr_bufs) { |
||
67 | struct pipe_surface *psurf = bufs[i]; |
||
68 | |||
69 | res = fd_resource(psurf->texture); |
||
70 | format = fd3_pipe2color(psurf->format); |
||
71 | swap = fd3_pipe2swap(psurf->format); |
||
72 | |||
73 | if (bin_w) { |
||
74 | stride = bin_w * res->cpp; |
||
75 | |||
76 | if (bases) { |
||
77 | base = bases[i] * res->cpp; |
||
78 | } |
||
79 | } else { |
||
80 | stride = res->pitch * res->cpp; |
||
81 | } |
||
82 | } |
||
83 | |||
84 | OUT_PKT0(ring, REG_A3XX_RB_MRT_BUF_INFO(i), 2); |
||
85 | OUT_RING(ring, A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) | |
||
86 | A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) | |
||
87 | A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) | |
||
88 | A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap)); |
||
89 | if (bin_w || (i >= nr_bufs)) { |
||
90 | OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base)); |
||
91 | } else { |
||
4401 | Serge | 92 | OUT_RELOCW(ring, res->bo, 0, 0, -1); |
4358 | Serge | 93 | } |
94 | |||
95 | OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1); |
||
96 | OUT_RING(ring, A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT(format)); |
||
97 | } |
||
98 | } |
||
99 | |||
100 | static uint32_t |
||
101 | depth_base(struct fd_gmem_stateobj *gmem) |
||
102 | { |
||
103 | return align(gmem->bin_w * gmem->bin_h, 0x4000); |
||
104 | } |
||
105 | |||
106 | /* transfer from gmem to system memory (ie. normal RAM) */ |
||
107 | |||
108 | static void |
||
109 | emit_gmem2mem_surf(struct fd_ringbuffer *ring, |
||
110 | enum adreno_rb_copy_control_mode mode, |
||
111 | uint32_t base, struct pipe_surface *psurf) |
||
112 | { |
||
113 | struct fd_resource *rsc = fd_resource(psurf->texture); |
||
114 | |||
115 | OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4); |
||
116 | OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) | |
||
117 | A3XX_RB_COPY_CONTROL_MODE(mode) | |
||
118 | A3XX_RB_COPY_CONTROL_GMEM_BASE(base)); |
||
4401 | Serge | 119 | OUT_RELOCW(ring, rsc->bo, 0, 0, -1); /* RB_COPY_DEST_BASE */ |
4358 | Serge | 120 | OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(rsc->pitch * rsc->cpp)); |
121 | OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) | |
||
122 | A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(psurf->format)) | |
||
123 | A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) | |
||
124 | A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE) | |
||
125 | A3XX_RB_COPY_DEST_INFO_SWAP(fd3_pipe2swap(psurf->format))); |
||
126 | |||
127 | OUT_PKT3(ring, CP_DRAW_INDX, 3); |
||
128 | OUT_RING(ring, 0x00000000); |
||
129 | OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX, |
||
130 | INDEX_SIZE_IGN, IGNORE_VISIBILITY)); |
||
131 | OUT_RING(ring, 2); /* NumIndices */ |
||
132 | } |
||
133 | |||
134 | static void |
||
135 | fd3_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff, |
||
136 | uint32_t bin_w, uint32_t bin_h) |
||
137 | { |
||
138 | struct fd3_context *fd3_ctx = fd3_context(ctx); |
||
139 | struct fd_ringbuffer *ring = ctx->ring; |
||
140 | struct pipe_framebuffer_state *pfb = &ctx->framebuffer; |
||
141 | |||
142 | OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1); |
||
143 | OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER)); |
||
144 | |||
145 | OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1); |
||
146 | OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) | |
||
147 | A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) | |
||
148 | A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) | |
||
149 | A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) | |
||
150 | A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) | |
||
151 | A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) | |
||
152 | A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) | |
||
153 | A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP)); |
||
154 | |||
155 | OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2); |
||
156 | OUT_RING(ring, 0xff000000 | |
||
157 | A3XX_RB_STENCILREFMASK_STENCILREF(0) | |
||
158 | A3XX_RB_STENCILREFMASK_STENCILMASK(0) | |
||
159 | A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff)); |
||
160 | OUT_RING(ring, 0xff000000 | |
||
161 | A3XX_RB_STENCILREFMASK_STENCILREF(0) | |
||
162 | A3XX_RB_STENCILREFMASK_STENCILMASK(0) | |
||
163 | A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff)); |
||
164 | |||
165 | OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1); |
||
166 | OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0)); |
||
167 | |||
168 | OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1); |
||
169 | OUT_RING(ring, 0x00000000); /* GRAS_CL_CLIP_CNTL */ |
||
170 | |||
4401 | Serge | 171 | OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6); |
172 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)pfb->width/2.0 - 0.5)); |
||
173 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)pfb->width/2.0)); |
||
174 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)pfb->height/2.0 - 0.5)); |
||
175 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)pfb->height/2.0)); |
||
176 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0)); |
||
177 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0)); |
||
178 | |||
4358 | Serge | 179 | OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1); |
180 | OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) | |
||
181 | A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE); |
||
182 | |||
183 | fd3_emit_rbrc_draw_state(ring, |
||
184 | A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE | |
||
185 | A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER)); |
||
186 | |||
187 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1); |
||
188 | OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) | |
||
189 | A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | |
||
190 | A3XX_GRAS_SC_CONTROL_RASTER_MODE(1)); |
||
191 | |||
192 | OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1); |
||
193 | OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) | |
||
194 | A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) | |
||
195 | A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) | |
||
196 | A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST); |
||
197 | |||
198 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2); |
||
199 | OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) | |
||
200 | A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0)); |
||
201 | OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(pfb->width - 1) | |
||
202 | A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(pfb->height - 1)); |
||
203 | |||
204 | OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4); |
||
205 | OUT_RING(ring, 0); /* VFD_INDEX_MIN */ |
||
206 | OUT_RING(ring, 2); /* VFD_INDEX_MAX */ |
||
207 | OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */ |
||
208 | OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */ |
||
209 | |||
210 | fd3_program_emit(ring, &ctx->solid_prog); |
||
211 | |||
212 | fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) { |
||
213 | { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT }, |
||
214 | }, 1); |
||
215 | |||
216 | if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { |
||
4401 | Serge | 217 | uint32_t base = 0; |
218 | if (pfb->cbufs[0]) { |
||
219 | struct fd_resource *rsc = |
||
220 | fd_resource(pfb->cbufs[0]->texture); |
||
221 | base = depth_base(&ctx->gmem) * rsc->cpp; |
||
222 | } |
||
4358 | Serge | 223 | emit_gmem2mem_surf(ring, RB_COPY_DEPTH_STENCIL, base, pfb->zsbuf); |
224 | } |
||
225 | |||
226 | if (ctx->resolve & FD_BUFFER_COLOR) { |
||
227 | emit_gmem2mem_surf(ring, RB_COPY_RESOLVE, 0, pfb->cbufs[0]); |
||
228 | } |
||
229 | |||
230 | OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1); |
||
231 | OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | |
||
232 | A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE); |
||
233 | |||
234 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1); |
||
235 | OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | |
||
236 | A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | |
||
237 | A3XX_GRAS_SC_CONTROL_RASTER_MODE(0)); |
||
238 | } |
||
239 | |||
240 | /* transfer from system memory to gmem */ |
||
241 | |||
242 | static void |
||
243 | emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base, |
||
244 | struct pipe_surface *psurf, uint32_t bin_w) |
||
245 | { |
||
246 | emit_mrt(ring, 1, &psurf, &base, bin_w); |
||
247 | |||
248 | fd3_emit_gmem_restore_tex(ring, psurf); |
||
249 | |||
250 | OUT_PKT3(ring, CP_DRAW_INDX, 3); |
||
251 | OUT_RING(ring, 0x00000000); |
||
252 | OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX, |
||
253 | INDEX_SIZE_IGN, IGNORE_VISIBILITY)); |
||
254 | OUT_RING(ring, 2); /* NumIndices */ |
||
255 | } |
||
256 | |||
257 | static void |
||
258 | fd3_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff, |
||
259 | uint32_t bin_w, uint32_t bin_h) |
||
260 | { |
||
261 | struct fd3_context *fd3_ctx = fd3_context(ctx); |
||
262 | struct fd_gmem_stateobj *gmem = &ctx->gmem; |
||
263 | struct fd_ringbuffer *ring = ctx->ring; |
||
264 | struct pipe_framebuffer_state *pfb = &ctx->framebuffer; |
||
265 | float x0, y0, x1, y1; |
||
266 | unsigned i; |
||
267 | |||
268 | /* write texture coordinates to vertexbuf: */ |
||
269 | x0 = ((float)xoff) / ((float)pfb->width); |
||
270 | x1 = ((float)xoff + bin_w) / ((float)pfb->width); |
||
271 | y0 = ((float)yoff) / ((float)pfb->height); |
||
272 | y1 = ((float)yoff + bin_h) / ((float)pfb->height); |
||
273 | |||
274 | OUT_PKT3(ring, CP_MEM_WRITE, 5); |
||
4401 | Serge | 275 | OUT_RELOC(ring, fd_resource(fd3_ctx->blit_texcoord_vbuf)->bo, 0, 0, 0); |
4358 | Serge | 276 | OUT_RING(ring, fui(x0)); |
277 | OUT_RING(ring, fui(y0)); |
||
278 | OUT_RING(ring, fui(x1)); |
||
279 | OUT_RING(ring, fui(y1)); |
||
280 | |||
281 | for (i = 0; i < 4; i++) { |
||
282 | OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1); |
||
283 | OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(12) | |
||
284 | A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE) | |
||
285 | A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf)); |
||
286 | |||
287 | OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1); |
||
288 | OUT_RING(ring, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) | |
||
289 | A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) | |
||
290 | A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) | |
||
291 | A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) | |
||
292 | A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) | |
||
293 | A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO) | |
||
294 | A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE); |
||
295 | } |
||
296 | |||
297 | fd3_emit_rbrc_tile_state(ring, |
||
298 | A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w)); |
||
299 | |||
300 | OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1); |
||
301 | OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS)); |
||
302 | |||
303 | OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1); |
||
304 | OUT_RING(ring, A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER); /* GRAS_CL_CLIP_CNTL */ |
||
305 | |||
306 | OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6); |
||
307 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)bin_w/2.0 - 0.5)); |
||
308 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)bin_w/2.0)); |
||
309 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)bin_h/2.0 - 0.5)); |
||
310 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)bin_h/2.0)); |
||
311 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0)); |
||
312 | OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0)); |
||
313 | |||
314 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2); |
||
315 | OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) | |
||
316 | A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0)); |
||
317 | OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w - 1) | |
||
318 | A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h - 1)); |
||
319 | |||
320 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2); |
||
321 | OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) | |
||
322 | A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0)); |
||
323 | OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w - 1) | |
||
324 | A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h - 1)); |
||
325 | |||
326 | OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1); |
||
327 | OUT_RING(ring, 0x2 | |
||
328 | A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) | |
||
329 | A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) | |
||
330 | A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) | |
||
331 | A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) | |
||
332 | A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_ALWAYS) | |
||
333 | A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) | |
||
334 | A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) | |
||
335 | A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP)); |
||
336 | |||
337 | fd3_emit_rbrc_draw_state(ring, |
||
338 | A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS)); |
||
339 | |||
340 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1); |
||
341 | OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | |
||
342 | A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | |
||
343 | A3XX_GRAS_SC_CONTROL_RASTER_MODE(1)); |
||
344 | |||
345 | OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1); |
||
346 | OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(2) | |
||
347 | A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) | |
||
348 | A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) | |
||
349 | A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST); |
||
350 | |||
351 | OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4); |
||
352 | OUT_RING(ring, 0); /* VFD_INDEX_MIN */ |
||
353 | OUT_RING(ring, 2); /* VFD_INDEX_MAX */ |
||
354 | OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */ |
||
355 | OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */ |
||
356 | |||
357 | fd3_program_emit(ring, &ctx->blit_prog); |
||
358 | |||
359 | fd3_emit_vertex_bufs(ring, &ctx->blit_prog, (struct fd3_vertex_buf[]) { |
||
360 | { .prsc = fd3_ctx->blit_texcoord_vbuf, .stride = 8, .format = PIPE_FORMAT_R32G32_FLOAT }, |
||
361 | { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT }, |
||
362 | }, 2); |
||
363 | |||
364 | /* for gmem pitch/base calculations, we need to use the non- |
||
365 | * truncated tile sizes: |
||
366 | */ |
||
367 | bin_w = gmem->bin_w; |
||
368 | bin_h = gmem->bin_h; |
||
369 | |||
370 | if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) |
||
371 | emit_mem2gmem_surf(ring, depth_base(gmem), pfb->zsbuf, bin_w); |
||
372 | |||
373 | if (ctx->restore & FD_BUFFER_COLOR) |
||
374 | emit_mem2gmem_surf(ring, 0, pfb->cbufs[0], bin_w); |
||
375 | |||
376 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1); |
||
377 | OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | |
||
378 | A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | |
||
379 | A3XX_GRAS_SC_CONTROL_RASTER_MODE(0)); |
||
380 | } |
||
381 | |||
382 | static void |
||
383 | update_vsc_pipe(struct fd_context *ctx) |
||
384 | { |
||
385 | struct fd_ringbuffer *ring = ctx->ring; |
||
386 | struct fd_gmem_stateobj *gmem = &ctx->gmem; |
||
387 | struct fd_bo *bo = fd3_context(ctx)->vsc_pipe_mem; |
||
388 | int i; |
||
389 | |||
390 | /* since we aren't using binning, just try to assign all bins |
||
391 | * to same pipe for now: |
||
392 | */ |
||
393 | OUT_PKT0(ring, REG_A3XX_VSC_PIPE(0), 3); |
||
394 | OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) | |
||
395 | A3XX_VSC_PIPE_CONFIG_Y(0) | |
||
396 | A3XX_VSC_PIPE_CONFIG_W(gmem->nbins_x) | |
||
397 | A3XX_VSC_PIPE_CONFIG_H(gmem->nbins_y)); |
||
4401 | Serge | 398 | OUT_RELOC(ring, bo, 0, 0, 0); /* VSC_PIPE[0].DATA_ADDRESS */ |
4358 | Serge | 399 | OUT_RING(ring, fd_bo_size(bo) - 32); /* VSC_PIPE[0].DATA_LENGTH */ |
400 | |||
401 | for (i = 1; i < 8; i++) { |
||
402 | OUT_PKT0(ring, REG_A3XX_VSC_PIPE(i), 3); |
||
403 | OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) | |
||
404 | A3XX_VSC_PIPE_CONFIG_Y(0) | |
||
405 | A3XX_VSC_PIPE_CONFIG_W(0) | |
||
406 | A3XX_VSC_PIPE_CONFIG_H(0)); |
||
407 | OUT_RING(ring, 0x00000000); /* VSC_PIPE[i].DATA_ADDRESS */ |
||
408 | OUT_RING(ring, 0x00000000); /* VSC_PIPE[i].DATA_LENGTH */ |
||
409 | } |
||
410 | } |
||
411 | |||
412 | /* for rendering directly to system memory: */ |
||
413 | static void |
||
414 | fd3_emit_sysmem_prep(struct fd_context *ctx) |
||
415 | { |
||
416 | struct pipe_framebuffer_state *pfb = &ctx->framebuffer; |
||
417 | struct fd_ringbuffer *ring = ctx->ring; |
||
4401 | Serge | 418 | uint32_t pitch = 0; |
4358 | Serge | 419 | |
4401 | Serge | 420 | if (pfb->cbufs[0]) |
421 | pitch = fd_resource(pfb->cbufs[0]->texture)->pitch; |
||
422 | |||
4358 | Serge | 423 | fd3_emit_restore(ctx); |
424 | |||
425 | OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1); |
||
426 | OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) | |
||
427 | A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height)); |
||
428 | |||
429 | emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0); |
||
430 | |||
431 | fd3_emit_rbrc_tile_state(ring, |
||
4401 | Serge | 432 | A3XX_RB_RENDER_CONTROL_BIN_WIDTH(pitch)); |
4358 | Serge | 433 | |
434 | /* setup scissor/offset for current tile: */ |
||
435 | OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1); |
||
436 | OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(0) | |
||
437 | A3XX_PA_SC_WINDOW_OFFSET_Y(0)); |
||
438 | |||
439 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2); |
||
440 | OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) | |
||
441 | A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0)); |
||
442 | OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb->width - 1) | |
||
443 | A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1)); |
||
444 | |||
445 | OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1); |
||
446 | OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | |
||
447 | A3XX_RB_MODE_CONTROL_GMEM_BYPASS | |
||
448 | A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE); |
||
449 | } |
||
450 | |||
451 | /* before first tile */ |
||
452 | static void |
||
453 | fd3_emit_tile_init(struct fd_context *ctx) |
||
454 | { |
||
455 | struct fd_ringbuffer *ring = ctx->ring; |
||
456 | struct fd_gmem_stateobj *gmem = &ctx->gmem; |
||
457 | |||
458 | fd3_emit_restore(ctx); |
||
459 | |||
460 | /* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated |
||
461 | * at the right and bottom edge tiles |
||
462 | */ |
||
463 | OUT_PKT0(ring, REG_A3XX_VSC_BIN_SIZE, 1); |
||
464 | OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) | |
||
465 | A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h)); |
||
466 | |||
467 | /* TODO we only need to do this if gmem stateobj changes.. or in |
||
468 | * particular if the # of bins changes.. |
||
469 | */ |
||
470 | update_vsc_pipe(ctx); |
||
471 | } |
||
472 | |||
473 | /* before mem2gmem */ |
||
474 | static void |
||
475 | fd3_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff, |
||
476 | uint32_t bin_w, uint32_t bin_h) |
||
477 | { |
||
478 | struct fd_ringbuffer *ring = ctx->ring; |
||
479 | struct pipe_framebuffer_state *pfb = &ctx->framebuffer; |
||
480 | struct fd_gmem_stateobj *gmem = &ctx->gmem; |
||
481 | uint32_t reg; |
||
482 | |||
483 | |||
484 | OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2); |
||
485 | reg = A3XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(gmem)); |
||
486 | if (pfb->zsbuf) { |
||
487 | reg |= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format)); |
||
488 | } |
||
489 | OUT_RING(ring, reg); |
||
490 | if (pfb->zsbuf) { |
||
491 | uint32_t cpp = util_format_get_blocksize(pfb->zsbuf->format); |
||
492 | OUT_RING(ring, A3XX_RB_DEPTH_PITCH(cpp * gmem->bin_w)); |
||
493 | } else { |
||
494 | OUT_RING(ring, 0x00000000); |
||
495 | } |
||
496 | |||
497 | OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1); |
||
498 | OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) | |
||
499 | A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height)); |
||
500 | |||
501 | OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1); |
||
502 | OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | |
||
503 | A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE); |
||
504 | } |
||
505 | |||
506 | /* before IB to rendering cmds: */ |
||
507 | static void |
||
508 | fd3_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff, |
||
509 | uint32_t bin_w, uint32_t bin_h) |
||
510 | { |
||
511 | struct fd_ringbuffer *ring = ctx->ring; |
||
512 | struct fd_gmem_stateobj *gmem = &ctx->gmem; |
||
513 | struct pipe_framebuffer_state *pfb = &ctx->framebuffer; |
||
514 | |||
515 | uint32_t x1 = xoff; |
||
516 | uint32_t y1 = yoff; |
||
517 | uint32_t x2 = xoff + bin_w - 1; |
||
518 | uint32_t y2 = yoff + bin_h - 1; |
||
519 | |||
520 | OUT_PKT3(ring, CP_SET_BIN, 3); |
||
521 | OUT_RING(ring, 0x00000000); |
||
522 | OUT_RING(ring, CP_SET_BIN_1_X1(x1) | CP_SET_BIN_1_Y1(y1)); |
||
523 | OUT_RING(ring, CP_SET_BIN_2_X2(x2) | CP_SET_BIN_2_Y2(y2)); |
||
524 | |||
525 | emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, gmem->bin_w); |
||
526 | |||
527 | fd3_emit_rbrc_tile_state(ring, |
||
528 | A3XX_RB_RENDER_CONTROL_ENABLE_GMEM | |
||
529 | A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w)); |
||
530 | |||
531 | /* setup scissor/offset for current tile: */ |
||
532 | OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1); |
||
533 | OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(xoff) | |
||
534 | A3XX_PA_SC_WINDOW_OFFSET_Y(yoff)); |
||
535 | |||
536 | OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2); |
||
537 | OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) | |
||
538 | A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1)); |
||
539 | OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) | |
||
540 | A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2)); |
||
541 | } |
||
542 | |||
543 | void |
||
544 | fd3_gmem_init(struct pipe_context *pctx) |
||
545 | { |
||
546 | struct fd_context *ctx = fd_context(pctx); |
||
547 | |||
548 | ctx->emit_sysmem_prep = fd3_emit_sysmem_prep; |
||
549 | ctx->emit_tile_init = fd3_emit_tile_init; |
||
550 | ctx->emit_tile_prep = fd3_emit_tile_prep; |
||
551 | ctx->emit_tile_mem2gmem = fd3_emit_tile_mem2gmem; |
||
552 | ctx->emit_tile_renderprep = fd3_emit_tile_renderprep; |
||
553 | ctx->emit_tile_gmem2mem = fd3_emit_tile_gmem2mem; |
||
554 | }>>>> |