ilo: update rectlist command emission for Gen8
[mesa.git] / src / gallium / drivers / ilo / ilo_render_gen8.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2013 LunarG, Inc.
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 shall be included
14 * in all copies or substantial portions of the Software.
15 *
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
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "genhw/genhw.h"
29 #include "util/u_dual_blend.h"
30
31 #include "ilo_blitter.h"
32 #include "ilo_builder_3d.h"
33 #include "ilo_builder_render.h"
34 #include "ilo_shader.h"
35 #include "ilo_state.h"
36 #include "ilo_render_gen.h"
37
38 /**
39 * A wrapper for gen6_PIPE_CONTROL().
40 */
41 static void
42 gen8_pipe_control(struct ilo_render *r, uint32_t dw1)
43 {
44 struct intel_bo *bo = (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK) ?
45 r->workaround_bo : NULL;
46
47 ILO_DEV_ASSERT(r->dev, 8, 8);
48
49 if (dw1 & GEN6_PIPE_CONTROL_CS_STALL) {
50 /* CS stall cannot be set alone */
51 const uint32_t mask = GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
52 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
53 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
54 GEN6_PIPE_CONTROL_DEPTH_STALL |
55 GEN6_PIPE_CONTROL_WRITE__MASK;
56 if (!(dw1 & mask))
57 dw1 |= GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
58 }
59
60 gen6_PIPE_CONTROL(r->builder, dw1, bo, 0, 0);
61
62
63 r->state.current_pipe_control_dw1 |= dw1;
64 r->state.deferred_pipe_control_dw1 &= ~dw1;
65 }
66
67 static void
68 gen8_wa_pre_depth(struct ilo_render *r)
69 {
70 /*
71 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
72 *
73 * "Driver must send a least one PIPE_CONTROL command with CS Stall and
74 * a post sync operation prior to the group of depth
75 * commands(3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
76 * 3DSTATE_STENCIL_BUFFER, and 3DSTATE_HIER_DEPTH_BUFFER)."
77 */
78 const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL |
79 GEN6_PIPE_CONTROL_WRITE_IMM;
80
81 ILO_DEV_ASSERT(r->dev, 8, 8);
82
83 if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
84 gen8_pipe_control(r, dw1);
85
86 /*
87 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
88 *
89 * "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
90 * any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
91 * 3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
92 * issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
93 * set), followed by a pipelined depth cache flush (PIPE_CONTROL with
94 * Depth Flush Bit set, followed by another pipelined depth stall
95 * (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
96 * guarantee that the pipeline from WM onwards is already flushed
97 * (e.g., via a preceding MI_FLUSH)."
98 */
99 gen8_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
100 gen8_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
101 gen8_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
102 }
103
104 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
105
106 static void
107 gen8_draw_sf(struct ilo_render *r,
108 const struct ilo_state_vector *vec,
109 struct ilo_render_draw_session *session)
110 {
111 /* 3DSTATE_RASTER */
112 if (DIRTY(RASTERIZER)) {
113 gen8_3DSTATE_RASTER(r->builder, (vec->rasterizer) ?
114 &vec->rasterizer->sf : NULL);
115 }
116
117 /* 3DSTATE_SBE */
118 if (DIRTY(RASTERIZER) || DIRTY(FS)) {
119 gen8_3DSTATE_SBE(r->builder, vec->fs, (vec->rasterizer) ?
120 vec->rasterizer->state.sprite_coord_mode : 0);
121 }
122
123 /* 3DSTATE_SBE_SWIZ */
124 if (DIRTY(FS))
125 gen8_3DSTATE_SBE_SWIZ(r->builder, vec->fs);
126
127 /* 3DSTATE_SF */
128 if (DIRTY(RASTERIZER)) {
129 gen8_3DSTATE_SF(r->builder, (vec->rasterizer) ?
130 &vec->rasterizer->sf : NULL);
131 }
132 }
133
134 static void
135 gen8_draw_wm(struct ilo_render *r,
136 const struct ilo_state_vector *vec,
137 struct ilo_render_draw_session *session)
138 {
139 /* 3DSTATE_WM */
140 if (DIRTY(FS) || DIRTY(RASTERIZER))
141 gen8_3DSTATE_WM(r->builder, vec->fs, vec->rasterizer);
142
143 if (DIRTY(DSA))
144 gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, vec->dsa);
145
146 /* 3DSTATE_WM_HZ_OP and 3DSTATE_WM_CHROMAKEY */
147 if (r->hw_ctx_changed) {
148 gen8_disable_3DSTATE_WM_HZ_OP(r->builder);
149 gen8_3DSTATE_WM_CHROMAKEY(r->builder);
150 }
151
152 /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
153 if (session->binding_table_fs_changed) {
154 gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(r->builder,
155 r->state.wm.BINDING_TABLE_STATE);
156 }
157
158 /* 3DSTATE_SAMPLER_STATE_POINTERS_PS */
159 if (session->sampler_fs_changed) {
160 gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(r->builder,
161 r->state.wm.SAMPLER_STATE);
162 }
163
164 /* 3DSTATE_CONSTANT_PS */
165 if (session->pcb_fs_changed) {
166 gen7_3DSTATE_CONSTANT_PS(r->builder,
167 &r->state.wm.PUSH_CONSTANT_BUFFER,
168 &r->state.wm.PUSH_CONSTANT_BUFFER_size,
169 1);
170 }
171
172 /* 3DSTATE_PS */
173 if (DIRTY(FS) || r->instruction_bo_changed)
174 gen8_3DSTATE_PS(r->builder, vec->fs);
175
176 /* 3DSTATE_PS_EXTRA */
177 if (DIRTY(FS) || DIRTY(DSA) || DIRTY(BLEND)) {
178 const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
179 vec->blend->alpha_to_coverage);
180 gen8_3DSTATE_PS_EXTRA(r->builder, vec->fs, cc_may_kill, false);
181 }
182
183 /* 3DSTATE_PS_BLEND */
184 if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA))
185 gen8_3DSTATE_PS_BLEND(r->builder, vec->blend, &vec->fb, vec->dsa);
186
187 /* 3DSTATE_SCISSOR_STATE_POINTERS */
188 if (session->scissor_changed) {
189 gen6_3DSTATE_SCISSOR_STATE_POINTERS(r->builder,
190 r->state.SCISSOR_RECT);
191 }
192
193 /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
194 if (DIRTY(FB) || r->batch_bo_changed) {
195 const struct ilo_zs_surface *zs;
196 uint32_t clear_params;
197
198 if (vec->fb.state.zsbuf) {
199 const struct ilo_surface_cso *surface =
200 (const struct ilo_surface_cso *) vec->fb.state.zsbuf;
201 const struct ilo_texture_slice *slice =
202 ilo_texture_get_slice(ilo_texture(surface->base.texture),
203 surface->base.u.tex.level, surface->base.u.tex.first_layer);
204
205 assert(!surface->is_rt);
206 zs = &surface->u.zs;
207 clear_params = slice->clear_value;
208 }
209 else {
210 zs = &vec->fb.null_zs;
211 clear_params = 0;
212 }
213
214 gen8_wa_pre_depth(r);
215
216 gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs, false);
217 gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
218 gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
219 gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
220 }
221 }
222
223 static void
224 gen8_draw_wm_sample_pattern(struct ilo_render *r,
225 const struct ilo_state_vector *vec,
226 struct ilo_render_draw_session *session)
227 {
228 /* 3DSTATE_SAMPLE_PATTERN */
229 if (r->hw_ctx_changed) {
230 gen8_3DSTATE_SAMPLE_PATTERN(r->builder,
231 &r->sample_pattern_1x,
232 &r->sample_pattern_2x,
233 &r->sample_pattern_4x,
234 r->sample_pattern_8x,
235 r->sample_pattern_16x);
236 }
237 }
238
239 static void
240 gen8_draw_wm_multisample(struct ilo_render *r,
241 const struct ilo_state_vector *vec,
242 struct ilo_render_draw_session *session)
243 {
244 /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
245 if (DIRTY(SAMPLE_MASK) || DIRTY(FB) || DIRTY(RASTERIZER)) {
246 gen8_3DSTATE_MULTISAMPLE(r->builder, vec->fb.num_samples,
247 vec->rasterizer->state.half_pixel_center);
248
249 gen7_3DSTATE_SAMPLE_MASK(r->builder,
250 (vec->fb.num_samples > 1) ? vec->sample_mask : 0x1,
251 vec->fb.num_samples);
252 }
253 }
254
255 static void
256 gen8_draw_vf(struct ilo_render *r,
257 const struct ilo_state_vector *vec,
258 struct ilo_render_draw_session *session)
259 {
260 const int prim = gen6_3d_translate_pipe_prim(vec->draw->mode);
261 int i;
262
263 /* 3DSTATE_INDEX_BUFFER */
264 if (DIRTY(IB) || r->batch_bo_changed)
265 gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ib);
266
267 /* 3DSTATE_VF */
268 if (session->primitive_restart_changed) {
269 gen75_3DSTATE_VF(r->builder, vec->draw->primitive_restart,
270 vec->draw->restart_index);
271 }
272
273 /* 3DSTATE_VERTEX_BUFFERS */
274 if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed)
275 gen6_3DSTATE_VERTEX_BUFFERS(r->builder, vec->ve, &vec->vb);
276
277 /* 3DSTATE_VERTEX_ELEMENTS */
278 if (DIRTY(VE))
279 gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, vec->ve);
280
281 gen8_3DSTATE_VF_TOPOLOGY(r->builder, prim);
282
283 for (i = 0; i < vec->ve->vb_count; i++) {
284 gen8_3DSTATE_VF_INSTANCING(r->builder, i,
285 vec->ve->instance_divisors[i]);
286 }
287
288 gen8_3DSTATE_VF_SGVS(r->builder,
289 false, 0, 0,
290 false, 0, 0);
291 }
292
293 void
294 ilo_render_emit_draw_commands_gen8(struct ilo_render *render,
295 const struct ilo_state_vector *vec,
296 struct ilo_render_draw_session *session)
297 {
298 ILO_DEV_ASSERT(render->dev, 8, 8);
299
300 /*
301 * We try to keep the order of the commands match, as closely as possible,
302 * that of the classic i965 driver. It allows us to compare the command
303 * streams easily.
304 */
305 gen6_draw_common_select(render, vec, session);
306 gen6_draw_common_sip(render, vec, session);
307 gen6_draw_vf_statistics(render, vec, session);
308 gen8_draw_wm_sample_pattern(render, vec, session);
309 gen6_draw_common_base_address(render, vec, session);
310 gen7_draw_common_pointers_1(render, vec, session);
311 gen7_draw_common_pcb_alloc(render, vec, session);
312 gen7_draw_common_urb(render, vec, session);
313 gen7_draw_common_pointers_2(render, vec, session);
314 gen8_draw_wm_multisample(render, vec, session);
315 gen7_draw_gs(render, vec, session);
316 gen7_draw_hs(render, vec, session);
317 gen7_draw_te(render, vec, session);
318 gen7_draw_ds(render, vec, session);
319 gen7_draw_vs(render, vec, session);
320 gen7_draw_sol(render, vec, session);
321 gen6_draw_clip(render, vec, session);
322 gen8_draw_sf(render, vec, session);
323 gen8_draw_wm(render, vec, session);
324 gen6_draw_wm_raster(render, vec, session);
325 gen6_draw_sf_rect(render, vec, session);
326 gen8_draw_vf(render, vec, session);
327 gen7_draw_vf_draw(render, vec, session);
328 }
329
330 int
331 ilo_render_get_draw_commands_len_gen8(const struct ilo_render *render,
332 const struct ilo_state_vector *vec)
333 {
334 static int len;
335
336 ILO_DEV_ASSERT(render->dev, 8, 8);
337
338 if (!len) {
339 len += GEN7_3DSTATE_URB_ANY__SIZE * 4;
340 len += GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_ANY__SIZE * 5;
341 len += GEN6_3DSTATE_CONSTANT_ANY__SIZE * 5;
342 len += GEN7_3DSTATE_POINTERS_ANY__SIZE * (5 + 5 + 4);
343 len += GEN7_3DSTATE_SO_BUFFER__SIZE * 4;
344 len += GEN6_PIPE_CONTROL__SIZE * 5;
345
346 len +=
347 GEN6_STATE_BASE_ADDRESS__SIZE +
348 GEN6_STATE_SIP__SIZE +
349 GEN6_3DSTATE_VF_STATISTICS__SIZE +
350 GEN6_PIPELINE_SELECT__SIZE +
351 GEN6_3DSTATE_CLEAR_PARAMS__SIZE +
352 GEN6_3DSTATE_DEPTH_BUFFER__SIZE +
353 GEN6_3DSTATE_STENCIL_BUFFER__SIZE +
354 GEN6_3DSTATE_HIER_DEPTH_BUFFER__SIZE +
355 GEN6_3DSTATE_VERTEX_BUFFERS__SIZE +
356 GEN6_3DSTATE_VERTEX_ELEMENTS__SIZE +
357 GEN6_3DSTATE_INDEX_BUFFER__SIZE +
358 GEN75_3DSTATE_VF__SIZE +
359 GEN6_3DSTATE_VS__SIZE +
360 GEN6_3DSTATE_GS__SIZE +
361 GEN6_3DSTATE_CLIP__SIZE +
362 GEN6_3DSTATE_SF__SIZE +
363 GEN6_3DSTATE_WM__SIZE +
364 GEN6_3DSTATE_SAMPLE_MASK__SIZE +
365 GEN7_3DSTATE_HS__SIZE +
366 GEN7_3DSTATE_TE__SIZE +
367 GEN7_3DSTATE_DS__SIZE +
368 GEN7_3DSTATE_STREAMOUT__SIZE +
369 GEN7_3DSTATE_SBE__SIZE +
370 GEN7_3DSTATE_PS__SIZE +
371 GEN6_3DSTATE_DRAWING_RECTANGLE__SIZE +
372 GEN6_3DSTATE_POLY_STIPPLE_OFFSET__SIZE +
373 GEN6_3DSTATE_POLY_STIPPLE_PATTERN__SIZE +
374 GEN6_3DSTATE_LINE_STIPPLE__SIZE +
375 GEN6_3DSTATE_AA_LINE_PARAMETERS__SIZE +
376 GEN6_3DSTATE_MULTISAMPLE__SIZE +
377 GEN7_3DSTATE_SO_DECL_LIST__SIZE +
378 GEN6_3DPRIMITIVE__SIZE;
379
380 len +=
381 GEN8_3DSTATE_VF_INSTANCING__SIZE * 33 +
382 GEN8_3DSTATE_VF_SGVS__SIZE +
383 GEN8_3DSTATE_VF_TOPOLOGY__SIZE +
384 GEN8_3DSTATE_SBE_SWIZ__SIZE +
385 GEN8_3DSTATE_RASTER__SIZE +
386 GEN8_3DSTATE_WM_CHROMAKEY__SIZE +
387 GEN8_3DSTATE_WM_DEPTH_STENCIL__SIZE +
388 GEN8_3DSTATE_WM_HZ_OP__SIZE +
389 GEN8_3DSTATE_PS_EXTRA__SIZE +
390 GEN8_3DSTATE_PS_BLEND__SIZE +
391 GEN8_3DSTATE_SAMPLE_PATTERN__SIZE;
392 }
393
394 return len;
395 }
396
397 int
398 ilo_render_get_rectlist_commands_len_gen8(const struct ilo_render *render,
399 const struct ilo_blitter *blitter)
400 {
401 ILO_DEV_ASSERT(render->dev, 8, 8);
402
403 return 64;
404 }
405
406 void
407 ilo_render_emit_rectlist_commands_gen8(struct ilo_render *r,
408 const struct ilo_blitter *blitter,
409 const struct ilo_render_rectlist_session *session)
410 {
411 uint32_t op;
412
413 ILO_DEV_ASSERT(r->dev, 8, 8);
414
415 gen8_wa_pre_depth(r);
416
417 if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
418 ILO_BLITTER_USE_FB_STENCIL)) {
419 gen6_3DSTATE_DEPTH_BUFFER(r->builder,
420 &blitter->fb.dst.u.zs, true);
421 }
422
423 if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
424 gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
425 &blitter->fb.dst.u.zs);
426 }
427
428 if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) {
429 gen6_3DSTATE_STENCIL_BUFFER(r->builder,
430 &blitter->fb.dst.u.zs);
431 }
432
433 gen7_3DSTATE_CLEAR_PARAMS(r->builder,
434 blitter->depth_clear_value);
435
436 gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
437 blitter->fb.width, blitter->fb.height);
438
439 switch (blitter->op) {
440 case ILO_BLITTER_RECTLIST_CLEAR_ZS:
441 op = 0;
442 if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH)
443 op |= GEN8_WM_HZ_DW1_DEPTH_CLEAR;
444 if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL)
445 op |= GEN8_WM_HZ_DW1_STENCIL_CLEAR;
446 break;
447 case ILO_BLITTER_RECTLIST_RESOLVE_Z:
448 op = GEN8_WM_HZ_DW1_DEPTH_RESOLVE;
449 break;
450 case ILO_BLITTER_RECTLIST_RESOLVE_HIZ:
451 op = GEN8_WM_HZ_DW1_HIZ_RESOLVE;
452 break;
453 default:
454 op = 0;
455 break;
456 }
457
458 gen8_3DSTATE_WM_HZ_OP(r->builder, op, blitter->fb.width,
459 blitter->fb.height, blitter->fb.num_samples);
460
461 gen8_pipe_control(r, GEN6_PIPE_CONTROL_WRITE_IMM);
462
463 gen8_disable_3DSTATE_WM_HZ_OP(r->builder);
464 }