i965/blorp: Add driver mocs settings to the context
[mesa.git] / src / mesa / drivers / dri / i965 / genX_blorp_exec.c
1 /*
2 * Copyright © 2011 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25
26 #include "intel_batchbuffer.h"
27 #include "intel_mipmap_tree.h"
28
29 #include "brw_context.h"
30 #include "brw_state.h"
31
32 #include "blorp_priv.h"
33
34 #include "genxml/gen_macros.h"
35
36 static void *
37 blorp_emit_dwords(struct brw_context *brw, unsigned n)
38 {
39 intel_batchbuffer_begin(brw, n, RENDER_RING);
40 uint32_t *map = brw->batch.map_next;
41 brw->batch.map_next += n;
42 intel_batchbuffer_advance(brw);
43 return map;
44 }
45
46 struct blorp_address {
47 drm_intel_bo *buffer;
48 uint32_t read_domains;
49 uint32_t write_domain;
50 uint32_t offset;
51 };
52
53 static uint64_t
54 blorp_emit_reloc(struct brw_context *brw, void *location,
55 struct blorp_address address, uint32_t delta)
56 {
57 uint32_t offset = (char *)location - (char *)brw->batch.map;
58 if (brw->gen >= 8) {
59 return intel_batchbuffer_reloc64(brw, address.buffer, offset,
60 address.read_domains,
61 address.write_domain,
62 address.offset + delta);
63 } else {
64 return intel_batchbuffer_reloc(brw, address.buffer, offset,
65 address.read_domains,
66 address.write_domain,
67 address.offset + delta);
68 }
69 }
70
71 static void *
72 blorp_alloc_dynamic_state(struct blorp_context *blorp,
73 enum aub_state_struct_type type,
74 uint32_t size,
75 uint32_t alignment,
76 uint32_t *offset)
77 {
78 struct brw_context *brw = blorp->driver_ctx;
79 return brw_state_batch(brw, type, size, alignment, offset);
80 }
81
82 static void *
83 blorp_alloc_vertex_buffer(struct blorp_context *blorp, uint32_t size,
84 struct blorp_address *addr)
85 {
86 struct brw_context *brw = blorp->driver_ctx;
87
88 uint32_t offset;
89 void *data = brw_state_batch(brw, AUB_TRACE_VERTEX_BUFFER,
90 size, 32, &offset);
91
92 *addr = (struct blorp_address) {
93 .buffer = brw->batch.bo,
94 .read_domains = I915_GEM_DOMAIN_VERTEX,
95 .write_domain = 0,
96 .offset = offset,
97 };
98
99 return data;
100 }
101
102 static void
103 blorp_emit_urb_config(struct brw_context *brw, unsigned vs_entry_size)
104 {
105 #if GEN_GEN >= 7
106 if (!(brw->ctx.NewDriverState & (BRW_NEW_CONTEXT | BRW_NEW_URB_SIZE)) &&
107 brw->urb.vsize >= vs_entry_size)
108 return;
109
110 brw->ctx.NewDriverState |= BRW_NEW_URB_SIZE;
111
112 gen7_upload_urb(brw, vs_entry_size, false, false);
113 #else
114 gen6_upload_urb(brw, vs_entry_size, false, 0);
115 #endif
116 }
117
118 static void
119 blorp_emit_3dstate_multisample(struct brw_context *brw, unsigned samples)
120 {
121 #if GEN_GEN >= 8
122 gen8_emit_3dstate_multisample(brw, samples);
123 #else
124 gen6_emit_3dstate_multisample(brw, samples);
125 #endif
126 }
127
128 #define __gen_address_type struct blorp_address
129 #define __gen_user_data struct brw_context
130
131 static uint64_t
132 __gen_combine_address(struct brw_context *brw, void *location,
133 struct blorp_address address, uint32_t delta)
134 {
135 if (address.buffer == NULL) {
136 return address.offset + delta;
137 } else {
138 return blorp_emit_reloc(brw, location, address, delta);
139 }
140 }
141
142 #include "genxml/genX_pack.h"
143
144 #define _blorp_cmd_length(cmd) cmd ## _length
145 #define _blorp_cmd_length_bias(cmd) cmd ## _length_bias
146 #define _blorp_cmd_header(cmd) cmd ## _header
147 #define _blorp_cmd_pack(cmd) cmd ## _pack
148
149 #define blorp_emit(brw, cmd, name) \
150 for (struct cmd name = { _blorp_cmd_header(cmd) }, \
151 *_dst = blorp_emit_dwords(brw, _blorp_cmd_length(cmd)); \
152 __builtin_expect(_dst != NULL, 1); \
153 _blorp_cmd_pack(cmd)(brw, (void *)_dst, &name), \
154 _dst = NULL)
155
156 #define blorp_emitn(batch, cmd, n) ({ \
157 uint32_t *_dw = blorp_emit_dwords(batch, n); \
158 struct cmd template = { \
159 _blorp_cmd_header(cmd), \
160 .DWordLength = n - _blorp_cmd_length_bias(cmd), \
161 }; \
162 _blorp_cmd_pack(cmd)(batch, _dw, &template); \
163 _dw + 1; /* Array starts at dw[1] */ \
164 })
165
166 /* Once vertex fetcher has written full VUE entries with complete
167 * header the space requirement is as follows per vertex (in bytes):
168 *
169 * Header Position Program constants
170 * +--------+------------+-------------------+
171 * | 16 | 16 | n x 16 |
172 * +--------+------------+-------------------+
173 *
174 * where 'n' stands for number of varying inputs expressed as vec4s.
175 *
176 * The URB size is in turn expressed in 64 bytes (512 bits).
177 */
178 static inline unsigned
179 gen7_blorp_get_vs_entry_size(const struct brw_blorp_params *params)
180 {
181 const unsigned num_varyings =
182 params->wm_prog_data ? params->wm_prog_data->num_varying_inputs : 0;
183 const unsigned total_needed = 16 + 16 + num_varyings * 16;
184
185 return DIV_ROUND_UP(total_needed, 64);
186 }
187
188 /* 3DSTATE_URB
189 * 3DSTATE_URB_VS
190 * 3DSTATE_URB_HS
191 * 3DSTATE_URB_DS
192 * 3DSTATE_URB_GS
193 *
194 * Assign the entire URB to the VS. Even though the VS disabled, URB space
195 * is still needed because the clipper loads the VUE's from the URB. From
196 * the Sandybridge PRM, Volume 2, Part 1, Section 3DSTATE,
197 * Dword 1.15:0 "VS Number of URB Entries":
198 * This field is always used (even if VS Function Enable is DISABLED).
199 *
200 * The warning below appears in the PRM (Section 3DSTATE_URB), but we can
201 * safely ignore it because this batch contains only one draw call.
202 * Because of URB corruption caused by allocating a previous GS unit
203 * URB entry to the VS unit, software is required to send a “GS NULL
204 * Fence” (Send URB fence with VS URB size == 1 and GS URB size == 0)
205 * plus a dummy DRAW call before any case where VS will be taking over
206 * GS URB space.
207 *
208 * If the 3DSTATE_URB_VS is emitted, than the others must be also.
209 * From the Ivybridge PRM, Volume 2 Part 1, section 1.7.1 3DSTATE_URB_VS:
210 *
211 * 3DSTATE_URB_HS, 3DSTATE_URB_DS, and 3DSTATE_URB_GS must also be
212 * programmed in order for the programming of this state to be
213 * valid.
214 */
215 static void
216 emit_urb_config(struct brw_context *brw,
217 const struct brw_blorp_params *params)
218 {
219 blorp_emit_urb_config(brw, gen7_blorp_get_vs_entry_size(params));
220 }
221
222 static void
223 blorp_emit_vertex_data(struct brw_context *brw,
224 const struct brw_blorp_params *params,
225 struct blorp_address *addr,
226 uint32_t *size)
227 {
228 const float vertices[] = {
229 /* v0 */ (float)params->x0, (float)params->y1,
230 /* v1 */ (float)params->x1, (float)params->y1,
231 /* v2 */ (float)params->x0, (float)params->y0,
232 };
233
234 void *data = blorp_alloc_vertex_buffer(&brw->blorp, sizeof(vertices), addr);
235 memcpy(data, vertices, sizeof(vertices));
236 *size = sizeof(vertices);
237 }
238
239 static void
240 blorp_emit_input_varying_data(struct brw_context *brw,
241 const struct brw_blorp_params *params,
242 struct blorp_address *addr,
243 uint32_t *size)
244 {
245 const unsigned vec4_size_in_bytes = 4 * sizeof(float);
246 const unsigned max_num_varyings =
247 DIV_ROUND_UP(sizeof(params->wm_inputs), vec4_size_in_bytes);
248 const unsigned num_varyings = params->wm_prog_data->num_varying_inputs;
249
250 *size = num_varyings * vec4_size_in_bytes;
251
252 const float *const inputs_src = (const float *)&params->wm_inputs;
253 float *inputs = blorp_alloc_vertex_buffer(&brw->blorp, *size, addr);
254
255 /* Walk over the attribute slots, determine if the attribute is used by
256 * the program and when necessary copy the values from the input storage to
257 * the vertex data buffer.
258 */
259 for (unsigned i = 0; i < max_num_varyings; i++) {
260 const gl_varying_slot attr = VARYING_SLOT_VAR0 + i;
261
262 if (!(params->wm_prog_data->inputs_read & BITFIELD64_BIT(attr)))
263 continue;
264
265 memcpy(inputs, inputs_src + i * 4, vec4_size_in_bytes);
266
267 inputs += 4;
268 }
269 }
270
271 static void
272 blorp_emit_vertex_buffers(struct brw_context *brw,
273 const struct brw_blorp_params *params)
274 {
275 struct GENX(VERTEX_BUFFER_STATE) vb[2];
276 memset(vb, 0, sizeof(vb));
277
278 unsigned num_buffers = 1;
279
280 uint32_t size;
281 blorp_emit_vertex_data(brw, params, &vb[0].BufferStartingAddress, &size);
282 vb[0].VertexBufferIndex = 0;
283 vb[0].BufferPitch = 2 * sizeof(float);
284 vb[0].VertexBufferMOCS = brw->blorp.mocs.vb;
285 #if GEN_GEN >= 7
286 vb[0].AddressModifyEnable = true;
287 #endif
288 #if GEN_GEN >= 8
289 vb[0].BufferSize = size;
290 #else
291 vb[0].BufferAccessType = VERTEXDATA;
292 vb[0].EndAddress = vb[0].BufferStartingAddress;
293 vb[0].EndAddress.offset += size - 1;
294 #endif
295
296 if (params->wm_prog_data && params->wm_prog_data->num_varying_inputs) {
297 blorp_emit_input_varying_data(brw, params,
298 &vb[1].BufferStartingAddress, &size);
299 vb[1].VertexBufferIndex = 1;
300 vb[1].BufferPitch = 0;
301 vb[1].VertexBufferMOCS = brw->blorp.mocs.vb;
302 #if GEN_GEN >= 7
303 vb[1].AddressModifyEnable = true;
304 #endif
305 #if GEN_GEN >= 8
306 vb[1].BufferSize = size;
307 #else
308 vb[1].BufferAccessType = INSTANCEDATA;
309 vb[1].EndAddress = vb[1].BufferStartingAddress;
310 vb[1].EndAddress.offset += size - 1;
311 #endif
312 num_buffers++;
313 }
314
315 const unsigned num_dwords =
316 1 + GENX(VERTEX_BUFFER_STATE_length) * num_buffers;
317 uint32_t *dw = blorp_emitn(brw, GENX(3DSTATE_VERTEX_BUFFERS), num_dwords);
318
319 for (unsigned i = 0; i < num_buffers; i++) {
320 GENX(VERTEX_BUFFER_STATE_pack)(brw, dw, &vb[i]);
321 dw += GENX(VERTEX_BUFFER_STATE_length);
322 }
323 }
324
325 static void
326 blorp_emit_vertex_elements(struct brw_context *brw,
327 const struct brw_blorp_params *params)
328 {
329 const unsigned num_varyings =
330 params->wm_prog_data ? params->wm_prog_data->num_varying_inputs : 0;
331 const unsigned num_elements = 2 + num_varyings;
332
333 struct GENX(VERTEX_ELEMENT_STATE) ve[num_elements];
334 memset(ve, 0, num_elements * sizeof(*ve));
335
336 /* Setup VBO for the rectangle primitive..
337 *
338 * A rectangle primitive (3DPRIM_RECTLIST) consists of only three
339 * vertices. The vertices reside in screen space with DirectX
340 * coordinates (that is, (0, 0) is the upper left corner).
341 *
342 * v2 ------ implied
343 * | |
344 * | |
345 * v0 ----- v1
346 *
347 * Since the VS is disabled, the clipper loads each VUE directly from
348 * the URB. This is controlled by the 3DSTATE_VERTEX_BUFFERS and
349 * 3DSTATE_VERTEX_ELEMENTS packets below. The VUE contents are as follows:
350 * dw0: Reserved, MBZ.
351 * dw1: Render Target Array Index. The HiZ op does not use indexed
352 * vertices, so set the dword to 0.
353 * dw2: Viewport Index. The HiZ op disables viewport mapping and
354 * scissoring, so set the dword to 0.
355 * dw3: Point Width: The HiZ op does not emit the POINTLIST primitive,
356 * so set the dword to 0.
357 * dw4: Vertex Position X.
358 * dw5: Vertex Position Y.
359 * dw6: Vertex Position Z.
360 * dw7: Vertex Position W.
361 *
362 * dw8: Flat vertex input 0
363 * dw9: Flat vertex input 1
364 * ...
365 * dwn: Flat vertex input n - 8
366 *
367 * For details, see the Sandybridge PRM, Volume 2, Part 1, Section 1.5.1
368 * "Vertex URB Entry (VUE) Formats".
369 *
370 * Only vertex position X and Y are going to be variable, Z is fixed to
371 * zero and W to one. Header words dw0-3 are all zero. There is no need to
372 * include the fixed values in the vertex buffer. Vertex fetcher can be
373 * instructed to fill vertex elements with constant values of one and zero
374 * instead of reading them from the buffer.
375 * Flat inputs are program constants that are not interpolated. Moreover
376 * their values will be the same between vertices.
377 *
378 * See the vertex element setup below.
379 */
380 ve[0].VertexBufferIndex = 0;
381 ve[0].Valid = true;
382 ve[0].SourceElementFormat = ISL_FORMAT_R32G32B32A32_FLOAT;
383 ve[0].SourceElementOffset = 0;
384 ve[0].Component0Control = VFCOMP_STORE_0;
385 ve[0].Component1Control = VFCOMP_STORE_0;
386 ve[0].Component2Control = VFCOMP_STORE_0;
387 ve[0].Component3Control = VFCOMP_STORE_0;
388
389 ve[1].VertexBufferIndex = 0;
390 ve[1].Valid = true;
391 ve[1].SourceElementFormat = ISL_FORMAT_R32G32_FLOAT;
392 ve[1].SourceElementOffset = 0;
393 ve[1].Component0Control = VFCOMP_STORE_SRC;
394 ve[1].Component1Control = VFCOMP_STORE_SRC;
395 ve[1].Component2Control = VFCOMP_STORE_0;
396 ve[1].Component3Control = VFCOMP_STORE_1_FP;
397
398 for (unsigned i = 0; i < num_varyings; ++i) {
399 ve[i + 2].VertexBufferIndex = 1;
400 ve[i + 2].Valid = true;
401 ve[i + 2].SourceElementFormat = ISL_FORMAT_R32G32B32A32_FLOAT;
402 ve[i + 2].SourceElementOffset = i * 4 * sizeof(float);
403 ve[i + 2].Component0Control = VFCOMP_STORE_SRC;
404 ve[i + 2].Component1Control = VFCOMP_STORE_SRC;
405 ve[i + 2].Component2Control = VFCOMP_STORE_SRC;
406 ve[i + 2].Component3Control = VFCOMP_STORE_SRC;
407 }
408
409 const unsigned num_dwords =
410 1 + GENX(VERTEX_ELEMENT_STATE_length) * num_elements;
411 uint32_t *dw = blorp_emitn(brw, GENX(3DSTATE_VERTEX_ELEMENTS), num_dwords);
412
413 for (unsigned i = 0; i < num_elements; i++) {
414 GENX(VERTEX_ELEMENT_STATE_pack)(brw, dw, &ve[i]);
415 dw += GENX(VERTEX_ELEMENT_STATE_length);
416 }
417
418 #if GEN_GEN >= 8
419 blorp_emit(brw, GENX(3DSTATE_VF_SGVS), sgvs);
420
421 for (unsigned i = 0; i < num_elements; i++) {
422 blorp_emit(brw, GENX(3DSTATE_VF_INSTANCING), vf) {
423 vf.VertexElementIndex = i;
424 vf.InstancingEnable = false;
425 }
426 }
427
428 blorp_emit(brw, GENX(3DSTATE_VF_TOPOLOGY), topo) {
429 topo.PrimitiveTopologyType = _3DPRIM_RECTLIST;
430 }
431 #endif
432 }
433
434 static void
435 blorp_emit_sf_config(struct brw_context *brw,
436 const struct brw_blorp_params *params)
437 {
438 const struct brw_blorp_prog_data *prog_data = params->wm_prog_data;
439
440 /* 3DSTATE_SF
441 *
442 * Disable ViewportTransformEnable (dw2.1)
443 *
444 * From the SandyBridge PRM, Volume 2, Part 1, Section 1.3, "3D
445 * Primitives Overview":
446 * RECTLIST: Viewport Mapping must be DISABLED (as is typical with the
447 * use of screen- space coordinates).
448 *
449 * A solid rectangle must be rendered, so set FrontFaceFillMode (dw2.4:3)
450 * and BackFaceFillMode (dw2.5:6) to SOLID(0).
451 *
452 * From the Sandy Bridge PRM, Volume 2, Part 1, Section
453 * 6.4.1.1 3DSTATE_SF, Field FrontFaceFillMode:
454 * SOLID: Any triangle or rectangle object found to be front-facing
455 * is rendered as a solid object. This setting is required when
456 * (rendering rectangle (RECTLIST) objects.
457 */
458
459 #if GEN_GEN >= 8
460
461 blorp_emit(brw, GENX(3DSTATE_SF), sf);
462
463 blorp_emit(brw, GENX(3DSTATE_RASTER), raster) {
464 raster.CullMode = CULLMODE_NONE;
465 }
466
467 blorp_emit(brw, GENX(3DSTATE_SBE), sbe) {
468 sbe.VertexURBEntryReadOffset = BRW_SF_URB_ENTRY_READ_OFFSET;
469 sbe.NumberofSFOutputAttributes = prog_data->num_varying_inputs;
470 sbe.VertexURBEntryReadLength = brw_blorp_get_urb_length(prog_data);
471 sbe.ForceVertexURBEntryReadLength = true;
472 sbe.ForceVertexURBEntryReadOffset = true;
473 sbe.ConstantInterpolationEnable = prog_data->flat_inputs;
474
475 #if GEN_GEN >= 9
476 for (unsigned i = 0; i < 32; i++)
477 sbe.AttributeActiveComponentFormat[i] = ACF_XYZW;
478 #endif
479 }
480
481 #elif GEN_GEN >= 7
482
483 blorp_emit(brw, GENX(3DSTATE_SF), sf) {
484 sf.FrontFaceFillMode = FILL_MODE_SOLID;
485 sf.BackFaceFillMode = FILL_MODE_SOLID;
486
487 sf.MultisampleRasterizationMode = params->dst.surf.samples > 1 ?
488 MSRASTMODE_ON_PATTERN : MSRASTMODE_OFF_PIXEL;
489
490 #if GEN_GEN == 7
491 sf.DepthBufferSurfaceFormat = params->depth_format;
492 #endif
493 }
494
495 blorp_emit(brw, GENX(3DSTATE_SBE), sbe) {
496 sbe.VertexURBEntryReadOffset = BRW_SF_URB_ENTRY_READ_OFFSET;
497 if (prog_data) {
498 sbe.NumberofSFOutputAttributes = prog_data->num_varying_inputs;
499 sbe.VertexURBEntryReadLength = brw_blorp_get_urb_length(prog_data);
500 sbe.ConstantInterpolationEnable = prog_data->flat_inputs;
501 } else {
502 sbe.NumberofSFOutputAttributes = 0;
503 sbe.VertexURBEntryReadLength = 1;
504 }
505 }
506
507 #else /* GEN_GEN <= 6 */
508
509 blorp_emit(brw, GENX(3DSTATE_SF), sf) {
510 sf.FrontFaceFillMode = FILL_MODE_SOLID;
511 sf.BackFaceFillMode = FILL_MODE_SOLID;
512
513 sf.MultisampleRasterizationMode = params->dst.surf.samples > 1 ?
514 MSRASTMODE_ON_PATTERN : MSRASTMODE_OFF_PIXEL;
515
516 sf.VertexURBEntryReadOffset = BRW_SF_URB_ENTRY_READ_OFFSET;
517 if (prog_data) {
518 sf.NumberofSFOutputAttributes = prog_data->num_varying_inputs;
519 sf.VertexURBEntryReadLength = brw_blorp_get_urb_length(prog_data);
520 sf.ConstantInterpolationEnable = prog_data->flat_inputs;
521 } else {
522 sf.NumberofSFOutputAttributes = 0;
523 sf.VertexURBEntryReadLength = 1;
524 }
525 }
526
527 #endif /* GEN_GEN */
528 }
529
530 static void
531 blorp_emit_ps_config(struct brw_context *brw,
532 const struct brw_blorp_params *params)
533 {
534 const struct brw_blorp_prog_data *prog_data = params->wm_prog_data;
535
536 /* Even when thread dispatch is disabled, max threads (dw5.25:31) must be
537 * nonzero to prevent the GPU from hanging. While the documentation doesn't
538 * mention this explicitly, it notes that the valid range for the field is
539 * [1,39] = [2,40] threads, which excludes zero.
540 *
541 * To be safe (and to minimize extraneous code) we go ahead and fully
542 * configure the WM state whether or not there is a WM program.
543 */
544
545 #if GEN_GEN >= 8
546
547 blorp_emit(brw, GENX(3DSTATE_WM), wm);
548
549 blorp_emit(brw, GENX(3DSTATE_PS), ps) {
550 if (params->src.bo) {
551 ps.SamplerCount = 1; /* Up to 4 samplers */
552 ps.BindingTableEntryCount = 2;
553 } else {
554 ps.BindingTableEntryCount = 1;
555 }
556
557 ps.DispatchGRFStartRegisterForConstantSetupData0 =
558 prog_data->first_curbe_grf_0;
559 ps.DispatchGRFStartRegisterForConstantSetupData2 =
560 prog_data->first_curbe_grf_2;
561
562 ps._8PixelDispatchEnable = prog_data->dispatch_8;
563 ps._16PixelDispatchEnable = prog_data->dispatch_16;
564
565 ps.KernelStartPointer0 = params->wm_prog_kernel;
566 ps.KernelStartPointer2 =
567 params->wm_prog_kernel + prog_data->ksp_offset_2;
568
569 /* 3DSTATE_PS expects the number of threads per PSD, which is always 64;
570 * it implicitly scales for different GT levels (which have some # of
571 * PSDs).
572 *
573 * In Gen8 the format is U8-2 whereas in Gen9 it is U8-1.
574 */
575 if (GEN_GEN >= 9)
576 ps.MaximumNumberofThreadsPerPSD = 64 - 1;
577 else
578 ps.MaximumNumberofThreadsPerPSD = 64 - 2;
579
580 switch (params->fast_clear_op) {
581 #if GEN_GEN >= 9
582 case (1 << 6): /* GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE */
583 ps.RenderTargetResolveType = RESOLVE_PARTIAL;
584 break;
585 case (3 << 6): /* GEN9_PS_RENDER_TARGET_RESOLVE_FULL */
586 ps.RenderTargetResolveType = RESOLVE_FULL;
587 break;
588 #else
589 case (1 << 6): /* GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE */
590 ps.RenderTargetResolveEnable = true;
591 break;
592 #endif
593 case (1 << 8): /* GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE */
594 ps.RenderTargetFastClearEnable = true;
595 break;
596 }
597 }
598
599 blorp_emit(brw, GENX(3DSTATE_PS_EXTRA), psx) {
600 psx.PixelShaderValid = true;
601
602 if (params->src.bo)
603 psx.PixelShaderKillsPixel = true;
604
605 psx.AttributeEnable = prog_data->num_varying_inputs > 0;
606
607 if (prog_data && prog_data->persample_msaa_dispatch)
608 psx.PixelShaderIsPerSample = true;
609 }
610
611 #elif GEN_GEN >= 7
612
613 blorp_emit(brw, GENX(3DSTATE_WM), wm) {
614 switch (params->hiz_op) {
615 case GEN6_HIZ_OP_DEPTH_CLEAR:
616 wm.DepthBufferClear = true;
617 break;
618 case GEN6_HIZ_OP_DEPTH_RESOLVE:
619 wm.DepthBufferResolveEnable = true;
620 break;
621 case GEN6_HIZ_OP_HIZ_RESOLVE:
622 wm.HierarchicalDepthBufferResolveEnable = true;
623 break;
624 case GEN6_HIZ_OP_NONE:
625 break;
626 default:
627 unreachable("not reached");
628 }
629
630 if (prog_data)
631 wm.ThreadDispatchEnable = true;
632
633 if (params->src.bo)
634 wm.PixelShaderKillPixel = true;
635
636 if (params->dst.surf.samples > 1) {
637 wm.MultisampleRasterizationMode = MSRASTMODE_ON_PATTERN;
638 wm.MultisampleDispatchMode =
639 (prog_data && prog_data->persample_msaa_dispatch) ?
640 MSDISPMODE_PERSAMPLE : MSDISPMODE_PERPIXEL;
641 } else {
642 wm.MultisampleRasterizationMode = MSRASTMODE_OFF_PIXEL;
643 wm.MultisampleDispatchMode = MSDISPMODE_PERSAMPLE;
644 }
645 }
646
647 blorp_emit(brw, GENX(3DSTATE_PS), ps) {
648 ps.MaximumNumberofThreads = brw->max_wm_threads - 1;
649
650 #if GEN_IS_HASWELL
651 ps.SampleMask = 1;
652 #endif
653
654 if (prog_data) {
655 ps.DispatchGRFStartRegisterforConstantSetupData0 =
656 prog_data->first_curbe_grf_0;
657 ps.DispatchGRFStartRegisterforConstantSetupData2 =
658 prog_data->first_curbe_grf_2;
659
660 ps.KernelStartPointer0 = params->wm_prog_kernel;
661 ps.KernelStartPointer2 =
662 params->wm_prog_kernel + prog_data->ksp_offset_2;
663
664 ps._8PixelDispatchEnable = prog_data->dispatch_8;
665 ps._16PixelDispatchEnable = prog_data->dispatch_16;
666
667 ps.AttributeEnable = prog_data->num_varying_inputs > 0;
668 } else {
669 /* Gen7 hardware gets angry if we don't enable at least one dispatch
670 * mode, so just enable 16-pixel dispatch if we don't have a program.
671 */
672 ps._16PixelDispatchEnable = true;
673 }
674
675 if (params->src.bo)
676 ps.SamplerCount = 1; /* Up to 4 samplers */
677
678 switch (params->fast_clear_op) {
679 case (1 << 6): /* GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE */
680 ps.RenderTargetResolveEnable = true;
681 break;
682 case (1 << 8): /* GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE */
683 ps.RenderTargetFastClearEnable = true;
684 break;
685 }
686 }
687
688 #else /* GEN_GEN <= 6 */
689
690 blorp_emit(brw, GENX(3DSTATE_WM), wm) {
691 wm.MaximumNumberofThreads = brw->max_wm_threads - 1;
692
693 switch (params->hiz_op) {
694 case GEN6_HIZ_OP_DEPTH_CLEAR:
695 wm.DepthBufferClear = true;
696 break;
697 case GEN6_HIZ_OP_DEPTH_RESOLVE:
698 wm.DepthBufferResolveEnable = true;
699 break;
700 case GEN6_HIZ_OP_HIZ_RESOLVE:
701 wm.HierarchicalDepthBufferResolveEnable = true;
702 break;
703 case GEN6_HIZ_OP_NONE:
704 break;
705 default:
706 unreachable("not reached");
707 }
708
709 if (prog_data) {
710 wm.ThreadDispatchEnable = true;
711
712 wm.DispatchGRFStartRegisterforConstantSetupData0 =
713 prog_data->first_curbe_grf_0;
714 wm.DispatchGRFStartRegisterforConstantSetupData2 =
715 prog_data->first_curbe_grf_2;
716
717 wm.KernelStartPointer0 = params->wm_prog_kernel;
718 wm.KernelStartPointer2 =
719 params->wm_prog_kernel + prog_data->ksp_offset_2;
720
721 wm._8PixelDispatchEnable = prog_data->dispatch_8;
722 wm._16PixelDispatchEnable = prog_data->dispatch_16;
723
724 wm.NumberofSFOutputAttributes = prog_data->num_varying_inputs;
725 }
726
727 if (params->src.bo) {
728 wm.SamplerCount = 1; /* Up to 4 samplers */
729 wm.PixelShaderKillPixel = true; /* TODO: temporarily smash on */
730 }
731
732 if (params->dst.surf.samples > 1) {
733 wm.MultisampleRasterizationMode = MSRASTMODE_ON_PATTERN;
734 wm.MultisampleDispatchMode =
735 (prog_data && prog_data->persample_msaa_dispatch) ?
736 MSDISPMODE_PERSAMPLE : MSDISPMODE_PERPIXEL;
737 } else {
738 wm.MultisampleRasterizationMode = MSRASTMODE_OFF_PIXEL;
739 wm.MultisampleDispatchMode = MSDISPMODE_PERSAMPLE;
740 }
741 }
742
743 #endif /* GEN_GEN */
744 }
745
746
747 static void
748 blorp_emit_depth_stencil_config(struct brw_context *brw,
749 const struct brw_blorp_params *params)
750 {
751 brw_emit_depth_stall_flushes(brw);
752
753 #if GEN_GEN >= 7
754 const uint32_t mocs = 1; /* GEN7_MOCS_L3 */
755 #else
756 const uint32_t mocs = 0;
757 #endif
758
759 blorp_emit(brw, GENX(3DSTATE_DEPTH_BUFFER), db) {
760 switch (params->depth.surf.dim) {
761 case ISL_SURF_DIM_1D:
762 db.SurfaceType = SURFTYPE_1D;
763 break;
764 case ISL_SURF_DIM_2D:
765 db.SurfaceType = SURFTYPE_2D;
766 break;
767 case ISL_SURF_DIM_3D:
768 db.SurfaceType = SURFTYPE_3D;
769 break;
770 }
771
772 db.SurfaceFormat = params->depth_format;
773
774 #if GEN_GEN >= 7
775 db.DepthWriteEnable = true;
776 #endif
777
778 #if GEN_GEN <= 6
779 db.TiledSurface = true;
780 db.TileWalk = TILEWALK_YMAJOR;
781 db.MIPMapLayoutMode = MIPLAYOUT_BELOW;
782 db.SeparateStencilBufferEnable = true;
783 #endif
784
785 db.HierarchicalDepthBufferEnable = true;
786
787 db.Width = params->depth.surf.logical_level0_px.width - 1;
788 db.Height = params->depth.surf.logical_level0_px.height - 1;
789 db.RenderTargetViewExtent = db.Depth =
790 MAX2(params->depth.surf.logical_level0_px.depth,
791 params->depth.surf.logical_level0_px.array_len) - 1;
792
793 db.LOD = params->depth.view.base_level;
794 db.MinimumArrayElement = params->depth.view.base_array_layer;
795
796 db.SurfacePitch = params->depth.surf.row_pitch - 1;
797 db.SurfaceBaseAddress = (struct blorp_address) {
798 .buffer = params->depth.bo,
799 .read_domains = I915_GEM_DOMAIN_RENDER,
800 .write_domain = I915_GEM_DOMAIN_RENDER,
801 .offset = params->depth.offset,
802 };
803 db.DepthBufferMOCS = mocs;
804 }
805
806 blorp_emit(brw, GENX(3DSTATE_HIER_DEPTH_BUFFER), hiz) {
807 hiz.SurfacePitch = params->depth.aux_surf.row_pitch - 1;
808 hiz.SurfaceBaseAddress = (struct blorp_address) {
809 .buffer = params->depth.aux_bo,
810 .read_domains = I915_GEM_DOMAIN_RENDER,
811 .write_domain = I915_GEM_DOMAIN_RENDER,
812 .offset = params->depth.aux_offset,
813 };
814 hiz.HierarchicalDepthBufferMOCS = mocs;
815 }
816
817 blorp_emit(brw, GENX(3DSTATE_STENCIL_BUFFER), sb);
818 }
819
820 static uint32_t
821 blorp_emit_blend_state(struct brw_context *brw,
822 const struct brw_blorp_params *params)
823 {
824 struct GENX(BLEND_STATE) blend;
825 memset(&blend, 0, sizeof(blend));
826
827 for (unsigned i = 0; i < params->num_draw_buffers; ++i) {
828 blend.Entry[i].PreBlendColorClampEnable = true;
829 blend.Entry[i].PostBlendColorClampEnable = true;
830 blend.Entry[i].ColorClampRange = COLORCLAMP_RTFORMAT;
831
832 blend.Entry[i].WriteDisableRed = params->color_write_disable[0];
833 blend.Entry[i].WriteDisableGreen = params->color_write_disable[1];
834 blend.Entry[i].WriteDisableBlue = params->color_write_disable[2];
835 blend.Entry[i].WriteDisableAlpha = params->color_write_disable[3];
836 }
837
838 uint32_t offset;
839 void *state = blorp_alloc_dynamic_state(&brw->blorp,
840 AUB_TRACE_BLEND_STATE,
841 GENX(BLEND_STATE_length) * 4,
842 64, &offset);
843 GENX(BLEND_STATE_pack)(NULL, state, &blend);
844
845 #if GEN_GEN >= 7
846 blorp_emit(brw, GENX(3DSTATE_BLEND_STATE_POINTERS), sp) {
847 sp.BlendStatePointer = offset;
848 #if GEN_GEN >= 8
849 sp.BlendStatePointerValid = true;
850 #endif
851 }
852 #endif
853
854 #if GEN_GEN >= 8
855 blorp_emit(brw, GENX(3DSTATE_PS_BLEND), ps_blend) {
856 ps_blend.HasWriteableRT = true;
857 }
858 #endif
859
860 return offset;
861 }
862
863 static uint32_t
864 blorp_emit_color_calc_state(struct brw_context *brw,
865 const struct brw_blorp_params *params)
866 {
867 uint32_t offset;
868 void *state = blorp_alloc_dynamic_state(&brw->blorp,
869 AUB_TRACE_CC_STATE,
870 GENX(COLOR_CALC_STATE_length) * 4,
871 64, &offset);
872 memset(state, 0, GENX(COLOR_CALC_STATE_length) * 4);
873
874 #if GEN_GEN >= 7
875 blorp_emit(brw, GENX(3DSTATE_CC_STATE_POINTERS), sp) {
876 sp.ColorCalcStatePointer = offset;
877 #if GEN_GEN >= 8
878 sp.ColorCalcStatePointerValid = true;
879 #endif
880 }
881 #endif
882
883 return offset;
884 }
885
886 static uint32_t
887 blorp_emit_depth_stencil_state(struct brw_context *brw,
888 const struct brw_blorp_params *params)
889 {
890 #if GEN_GEN >= 8
891
892 /* On gen8+, DEPTH_STENCIL state is simply an instruction */
893 blorp_emit(brw, GENX(3DSTATE_WM_DEPTH_STENCIL), ds);
894 return 0;
895
896 #else /* GEN_GEN <= 7 */
897
898 /* See the following sections of the Sandy Bridge PRM, Volume 1, Part2:
899 * - 7.5.3.1 Depth Buffer Clear
900 * - 7.5.3.2 Depth Buffer Resolve
901 * - 7.5.3.3 Hierarchical Depth Buffer Resolve
902 */
903 struct GENX(DEPTH_STENCIL_STATE) ds = {
904 .DepthBufferWriteEnable = true,
905 };
906
907 if (params->hiz_op == GEN6_HIZ_OP_DEPTH_RESOLVE) {
908 ds.DepthTestEnable = true;
909 ds.DepthTestFunction = COMPAREFUNCTION_NEVER;
910 }
911
912 uint32_t offset;
913 void *state = blorp_alloc_dynamic_state(&brw->blorp,
914 AUB_TRACE_DEPTH_STENCIL_STATE,
915 GENX(DEPTH_STENCIL_STATE_length) * 4,
916 64, &offset);
917 GENX(DEPTH_STENCIL_STATE_pack)(NULL, state, &ds);
918
919 #if GEN_GEN >= 7
920 blorp_emit(brw, GENX(3DSTATE_DEPTH_STENCIL_STATE_POINTERS), sp) {
921 sp.PointertoDEPTH_STENCIL_STATE = offset;
922 }
923 #endif
924
925 return offset;
926
927 #endif /* GEN_GEN */
928 }
929
930 static void
931 blorp_emit_surface_states(struct brw_context *brw,
932 const struct brw_blorp_params *params)
933 {
934 uint32_t bind_offset;
935 uint32_t *bind =
936 brw_state_batch(brw, AUB_TRACE_BINDING_TABLE,
937 sizeof(uint32_t) * BRW_BLORP_NUM_BINDING_TABLE_ENTRIES,
938 32, /* alignment */ &bind_offset);
939
940 bind[BRW_BLORP_RENDERBUFFER_BINDING_TABLE_INDEX] =
941 brw_blorp_emit_surface_state(brw, &params->dst,
942 I915_GEM_DOMAIN_RENDER,
943 I915_GEM_DOMAIN_RENDER, true);
944 if (params->src.bo) {
945 bind[BRW_BLORP_TEXTURE_BINDING_TABLE_INDEX] =
946 brw_blorp_emit_surface_state(brw, &params->src,
947 I915_GEM_DOMAIN_SAMPLER, 0, false);
948 }
949
950 #if GEN_GEN >= 7
951 blorp_emit(brw, GENX(3DSTATE_BINDING_TABLE_POINTERS_PS), bt) {
952 bt.PointertoPSBindingTable = bind_offset;
953 }
954 #else
955 blorp_emit(brw, GENX(3DSTATE_BINDING_TABLE_POINTERS), bt) {
956 bt.PSBindingTableChange = true;
957 bt.PointertoPSBindingTable = bind_offset;
958 }
959 #endif
960 }
961
962 static void
963 blorp_emit_sampler_state(struct brw_context *brw,
964 const struct brw_blorp_params *params)
965 {
966 struct GENX(SAMPLER_STATE) sampler = {
967 .MipModeFilter = MIPFILTER_NONE,
968 .MagModeFilter = MAPFILTER_LINEAR,
969 .MinModeFilter = MAPFILTER_LINEAR,
970 .MinLOD = 0,
971 .MaxLOD = 0,
972 .TCXAddressControlMode = TCM_CLAMP,
973 .TCYAddressControlMode = TCM_CLAMP,
974 .TCZAddressControlMode = TCM_CLAMP,
975 .MaximumAnisotropy = RATIO21,
976 .RAddressMinFilterRoundingEnable = true,
977 .RAddressMagFilterRoundingEnable = true,
978 .VAddressMinFilterRoundingEnable = true,
979 .VAddressMagFilterRoundingEnable = true,
980 .UAddressMinFilterRoundingEnable = true,
981 .UAddressMagFilterRoundingEnable = true,
982 .NonnormalizedCoordinateEnable = true,
983 };
984
985 uint32_t offset;
986 void *state = blorp_alloc_dynamic_state(&brw->blorp,
987 AUB_TRACE_SAMPLER_STATE,
988 GENX(SAMPLER_STATE_length) * 4,
989 32, &offset);
990 GENX(SAMPLER_STATE_pack)(NULL, state, &sampler);
991
992 #if GEN_GEN >= 7
993 blorp_emit(brw, GENX(3DSTATE_SAMPLER_STATE_POINTERS_PS), ssp) {
994 ssp.PointertoPSSamplerState = offset;
995 }
996 #else
997 blorp_emit(brw, GENX(3DSTATE_SAMPLER_STATE_POINTERS), ssp) {
998 ssp.VSSamplerStateChange = true;
999 ssp.GSSamplerStateChange = true;
1000 ssp.PSSamplerStateChange = true;
1001 ssp.PointertoPSSamplerState = offset;
1002 }
1003 #endif
1004 }
1005
1006 /* 3DSTATE_VIEWPORT_STATE_POINTERS */
1007 static void
1008 blorp_emit_viewport_state(struct brw_context *brw,
1009 const struct brw_blorp_params *params)
1010 {
1011 uint32_t cc_vp_offset;
1012
1013 void *state = blorp_alloc_dynamic_state(&brw->blorp,
1014 AUB_TRACE_CC_VP_STATE,
1015 GENX(CC_VIEWPORT_length) * 4, 32,
1016 &cc_vp_offset);
1017
1018 GENX(CC_VIEWPORT_pack)(brw, state,
1019 &(struct GENX(CC_VIEWPORT)) {
1020 .MinimumDepth = 0.0,
1021 .MaximumDepth = 1.0,
1022 });
1023
1024 #if GEN_GEN >= 7
1025 blorp_emit(brw, GENX(3DSTATE_VIEWPORT_STATE_POINTERS_CC), vsp) {
1026 vsp.CCViewportPointer = cc_vp_offset;
1027 }
1028 #else
1029 blorp_emit(brw, GENX(3DSTATE_VIEWPORT_STATE_POINTERS), vsp) {
1030 vsp.CCViewportStateChange = true;
1031 vsp.PointertoCC_VIEWPORT = cc_vp_offset;
1032 }
1033 #endif
1034 }
1035
1036
1037 /**
1038 * \brief Execute a blit or render pass operation.
1039 *
1040 * To execute the operation, this function manually constructs and emits a
1041 * batch to draw a rectangle primitive. The batchbuffer is flushed before
1042 * constructing and after emitting the batch.
1043 *
1044 * This function alters no GL state.
1045 */
1046 void
1047 genX(blorp_exec)(struct brw_context *brw,
1048 const struct brw_blorp_params *params)
1049 {
1050 uint32_t blend_state_offset = 0;
1051 uint32_t color_calc_state_offset = 0;
1052 uint32_t depth_stencil_state_offset;
1053
1054 #if GEN_GEN == 6
1055 /* Emit workaround flushes when we switch from drawing to blorping. */
1056 brw_emit_post_sync_nonzero_flush(brw);
1057 #endif
1058
1059 brw_upload_state_base_address(brw);
1060
1061 #if GEN_GEN >= 8
1062 gen7_l3_state.emit(brw);
1063 #endif
1064
1065 blorp_emit_vertex_buffers(brw, params);
1066 blorp_emit_vertex_elements(brw, params);
1067
1068 emit_urb_config(brw, params);
1069
1070 if (params->wm_prog_data) {
1071 blend_state_offset = blorp_emit_blend_state(brw, params);
1072 color_calc_state_offset = blorp_emit_color_calc_state(brw, params);
1073 }
1074 depth_stencil_state_offset = blorp_emit_depth_stencil_state(brw, params);
1075
1076 #if GEN_GEN <= 6
1077 /* 3DSTATE_CC_STATE_POINTERS
1078 *
1079 * The pointer offsets are relative to
1080 * CMD_STATE_BASE_ADDRESS.DynamicStateBaseAddress.
1081 *
1082 * The HiZ op doesn't use BLEND_STATE or COLOR_CALC_STATE.
1083 *
1084 * The dynamic state emit helpers emit their own STATE_POINTERS packets on
1085 * gen7+. However, on gen6 and earlier, they're all lumpped together in
1086 * one CC_STATE_POINTERS packet so we have to emit that here.
1087 */
1088 blorp_emit(brw, GENX(3DSTATE_CC_STATE_POINTERS), cc) {
1089 cc.BLEND_STATEChange = true;
1090 cc.COLOR_CALC_STATEChange = true;
1091 cc.DEPTH_STENCIL_STATEChange = true;
1092 cc.PointertoBLEND_STATE = blend_state_offset;
1093 cc.PointertoCOLOR_CALC_STATE = color_calc_state_offset;
1094 cc.PointertoDEPTH_STENCIL_STATE = depth_stencil_state_offset;
1095 }
1096 #else
1097 (void)blend_state_offset;
1098 (void)color_calc_state_offset;
1099 (void)depth_stencil_state_offset;
1100 #endif
1101
1102 blorp_emit(brw, GENX(3DSTATE_CONSTANT_VS), vs);
1103 #if GEN_GEN >= 7
1104 blorp_emit(brw, GENX(3DSTATE_CONSTANT_HS), hs);
1105 blorp_emit(brw, GENX(3DSTATE_CONSTANT_DS), DS);
1106 #endif
1107 blorp_emit(brw, GENX(3DSTATE_CONSTANT_GS), gs);
1108 blorp_emit(brw, GENX(3DSTATE_CONSTANT_PS), ps);
1109
1110 if (brw->use_resource_streamer)
1111 gen7_disable_hw_binding_tables(brw);
1112
1113 if (params->wm_prog_data)
1114 blorp_emit_surface_states(brw, params);
1115
1116 if (params->src.bo)
1117 blorp_emit_sampler_state(brw, params);
1118
1119 blorp_emit_3dstate_multisample(brw, params->dst.surf.samples);
1120
1121 blorp_emit(brw, GENX(3DSTATE_SAMPLE_MASK), mask) {
1122 mask.SampleMask = (1 << params->dst.surf.samples) - 1;
1123 }
1124
1125 /* From the BSpec, 3D Pipeline > Geometry > Vertex Shader > State,
1126 * 3DSTATE_VS, Dword 5.0 "VS Function Enable":
1127 *
1128 * [DevSNB] A pipeline flush must be programmed prior to a
1129 * 3DSTATE_VS command that causes the VS Function Enable to
1130 * toggle. Pipeline flush can be executed by sending a PIPE_CONTROL
1131 * command with CS stall bit set and a post sync operation.
1132 *
1133 * We've already done one at the start of the BLORP operation.
1134 */
1135 blorp_emit(brw, GENX(3DSTATE_VS), vs);
1136 #if GEN_GEN >= 7
1137 blorp_emit(brw, GENX(3DSTATE_HS), hs);
1138 blorp_emit(brw, GENX(3DSTATE_TE), te);
1139 blorp_emit(brw, GENX(3DSTATE_DS), DS);
1140 blorp_emit(brw, GENX(3DSTATE_STREAMOUT), so);
1141 #endif
1142 blorp_emit(brw, GENX(3DSTATE_GS), gs);
1143
1144 blorp_emit(brw, GENX(3DSTATE_CLIP), clip) {
1145 clip.PerspectiveDivideDisable = true;
1146 }
1147
1148 blorp_emit_sf_config(brw, params);
1149 blorp_emit_ps_config(brw, params);
1150
1151 blorp_emit_viewport_state(brw, params);
1152
1153 if (params->depth.bo) {
1154 blorp_emit_depth_stencil_config(brw, params);
1155 } else {
1156 brw_emit_depth_stall_flushes(brw);
1157
1158 blorp_emit(brw, GENX(3DSTATE_DEPTH_BUFFER), db) {
1159 db.SurfaceType = SURFTYPE_NULL;
1160 db.SurfaceFormat = D32_FLOAT;
1161 }
1162 blorp_emit(brw, GENX(3DSTATE_HIER_DEPTH_BUFFER), hiz);
1163 blorp_emit(brw, GENX(3DSTATE_STENCIL_BUFFER), sb);
1164 }
1165
1166 /* 3DSTATE_CLEAR_PARAMS
1167 *
1168 * From the Sandybridge PRM, Volume 2, Part 1, Section 3DSTATE_CLEAR_PARAMS:
1169 * [DevSNB] 3DSTATE_CLEAR_PARAMS packet must follow the DEPTH_BUFFER_STATE
1170 * packet when HiZ is enabled and the DEPTH_BUFFER_STATE changes.
1171 */
1172 blorp_emit(brw, GENX(3DSTATE_CLEAR_PARAMS), clear) {
1173 clear.DepthClearValueValid = true;
1174 clear.DepthClearValue = params->depth.clear_color.u32[0];
1175 }
1176
1177 blorp_emit(brw, GENX(3DSTATE_DRAWING_RECTANGLE), rect) {
1178 rect.ClippedDrawingRectangleXMax = MAX2(params->x1, params->x0) - 1;
1179 rect.ClippedDrawingRectangleYMax = MAX2(params->y1, params->y0) - 1;
1180 }
1181
1182 blorp_emit(brw, GENX(3DPRIMITIVE), prim) {
1183 prim.VertexAccessType = SEQUENTIAL;
1184 prim.PrimitiveTopologyType = _3DPRIM_RECTLIST;
1185 prim.VertexCountPerInstance = 3;
1186 prim.InstanceCount = params->num_layers;
1187 }
1188 }