2 * Copyright © 2017 Intel Corporation
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:
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
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
26 #include "common/gen_device_info.h"
27 #include "genxml/gen_macros.h"
29 #include "brw_context.h"
30 #include "brw_state.h"
32 #include "intel_batchbuffer.h"
33 #include "intel_fbo.h"
35 #include "main/fbobject.h"
36 #include "main/framebuffer.h"
37 #include "main/stencil.h"
40 emit_dwords(struct brw_context
*brw
, unsigned n
)
42 intel_batchbuffer_begin(brw
, n
, RENDER_RING
);
43 uint32_t *map
= brw
->batch
.map_next
;
44 brw
->batch
.map_next
+= n
;
45 intel_batchbuffer_advance(brw
);
51 uint32_t read_domains
;
52 uint32_t write_domain
;
57 emit_reloc(struct brw_context
*brw
,
58 void *location
, struct brw_address address
, uint32_t delta
)
60 uint32_t offset
= (char *) location
- (char *) brw
->batch
.map
;
62 return brw_emit_reloc(&brw
->batch
, offset
, address
.bo
,
63 address
.offset
+ delta
,
65 address
.write_domain
);
68 #define __gen_address_type struct brw_address
69 #define __gen_user_data struct brw_context
72 __gen_combine_address(struct brw_context
*brw
, void *location
,
73 struct brw_address address
, uint32_t delta
)
75 if (address
.bo
== NULL
) {
76 return address
.offset
+ delta
;
78 return emit_reloc(brw
, location
, address
, delta
);
82 #include "genxml/genX_pack.h"
84 #define _brw_cmd_length(cmd) cmd ## _length
85 #define _brw_cmd_length_bias(cmd) cmd ## _length_bias
86 #define _brw_cmd_header(cmd) cmd ## _header
87 #define _brw_cmd_pack(cmd) cmd ## _pack
89 #define brw_batch_emit(brw, cmd, name) \
90 for (struct cmd name = { _brw_cmd_header(cmd) }, \
91 *_dst = emit_dwords(brw, _brw_cmd_length(cmd)); \
92 __builtin_expect(_dst != NULL, 1); \
93 _brw_cmd_pack(cmd)(brw, (void *)_dst, &name), \
96 #define brw_batch_emitn(brw, cmd, n) ({ \
97 uint32_t *_dw = emit_dwords(brw, n); \
98 struct cmd template = { \
99 _brw_cmd_header(cmd), \
100 .DWordLength = n - _brw_cmd_length_bias(cmd), \
102 _brw_cmd_pack(cmd)(brw, _dw, &template); \
103 _dw + 1; /* Array starts at dw[1] */ \
106 #define brw_state_emit(brw, cmd, align, offset, name) \
107 for (struct cmd name = { 0, }, \
108 *_dst = brw_state_batch(brw, _brw_cmd_length(cmd) * 4, \
110 __builtin_expect(_dst != NULL, 1); \
111 _brw_cmd_pack(cmd)(brw, (void *)_dst, &name), \
114 /* ---------------------------------------------------------------------- */
118 /* ---------------------------------------------------------------------- */
121 genX(upload_depth_stencil_state
)(struct brw_context
*brw
)
123 struct gl_context
*ctx
= &brw
->ctx
;
126 struct intel_renderbuffer
*depth_irb
=
127 intel_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_DEPTH
);
130 struct gl_depthbuffer_attrib
*depth
= &ctx
->Depth
;
133 struct gl_stencil_attrib
*stencil
= &ctx
->Stencil
;
134 const int b
= stencil
->_BackFace
;
137 brw_batch_emit(brw
, GENX(3DSTATE_WM_DEPTH_STENCIL
), wmds
) {
140 brw_state_emit(brw
, GENX(DEPTH_STENCIL_STATE
), 64, &ds_offset
, wmds
) {
142 if (depth
->Test
&& depth_irb
) {
143 wmds
.DepthTestEnable
= true;
144 wmds
.DepthBufferWriteEnable
= brw_depth_writes_enabled(brw
);
145 wmds
.DepthTestFunction
= intel_translate_compare_func(depth
->Func
);
148 if (stencil
->_Enabled
) {
149 wmds
.StencilTestEnable
= true;
150 wmds
.StencilWriteMask
= stencil
->WriteMask
[0] & 0xff;
151 wmds
.StencilTestMask
= stencil
->ValueMask
[0] & 0xff;
153 wmds
.StencilTestFunction
=
154 intel_translate_compare_func(stencil
->Function
[0]);
156 intel_translate_stencil_op(stencil
->FailFunc
[0]);
157 wmds
.StencilPassDepthPassOp
=
158 intel_translate_stencil_op(stencil
->ZPassFunc
[0]);
159 wmds
.StencilPassDepthFailOp
=
160 intel_translate_stencil_op(stencil
->ZFailFunc
[0]);
162 wmds
.StencilBufferWriteEnable
= stencil
->_WriteEnabled
;
164 if (stencil
->_TestTwoSide
) {
165 wmds
.DoubleSidedStencilEnable
= true;
166 wmds
.BackfaceStencilWriteMask
= stencil
->WriteMask
[b
] & 0xff;
167 wmds
.BackfaceStencilTestMask
= stencil
->ValueMask
[b
] & 0xff;
169 wmds
.BackfaceStencilTestFunction
=
170 intel_translate_compare_func(stencil
->Function
[b
]);
171 wmds
.BackfaceStencilFailOp
=
172 intel_translate_stencil_op(stencil
->FailFunc
[b
]);
173 wmds
.BackfaceStencilPassDepthPassOp
=
174 intel_translate_stencil_op(stencil
->ZPassFunc
[b
]);
175 wmds
.BackfaceStencilPassDepthFailOp
=
176 intel_translate_stencil_op(stencil
->ZFailFunc
[b
]);
180 wmds
.StencilReferenceValue
= _mesa_get_stencil_ref(ctx
, 0);
181 wmds
.BackfaceStencilReferenceValue
= _mesa_get_stencil_ref(ctx
, b
);
187 brw_batch_emit(brw
, GENX(3DSTATE_CC_STATE_POINTERS
), ptr
) {
188 ptr
.PointertoDEPTH_STENCIL_STATE
= ds_offset
;
189 ptr
.DEPTH_STENCIL_STATEChange
= true;
192 brw_batch_emit(brw
, GENX(3DSTATE_DEPTH_STENCIL_STATE_POINTERS
), ptr
) {
193 ptr
.PointertoDEPTH_STENCIL_STATE
= ds_offset
;
198 static const struct brw_tracked_state
genX(depth_stencil_state
) = {
200 .mesa
= _NEW_BUFFERS
|
203 .brw
= BRW_NEW_BLORP
|
204 (GEN_GEN
>= 8 ? BRW_NEW_CONTEXT
206 BRW_NEW_STATE_BASE_ADDRESS
),
208 .emit
= genX(upload_depth_stencil_state
),
211 /* ---------------------------------------------------------------------- */
214 genX(upload_clip_state
)(struct brw_context
*brw
)
216 struct gl_context
*ctx
= &brw
->ctx
;
219 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
221 /* BRW_NEW_FS_PROG_DATA */
222 struct brw_wm_prog_data
*wm_prog_data
=
223 brw_wm_prog_data(brw
->wm
.base
.prog_data
);
225 brw_batch_emit(brw
, GENX(3DSTATE_CLIP
), clip
) {
226 clip
.StatisticsEnable
= !brw
->meta_in_progress
;
228 if (wm_prog_data
->barycentric_interp_modes
&
229 BRW_BARYCENTRIC_NONPERSPECTIVE_BITS
)
230 clip
.NonPerspectiveBarycentricEnable
= true;
233 clip
.EarlyCullEnable
= true;
237 clip
.FrontWinding
= ctx
->Polygon
._FrontBit
== _mesa_is_user_fbo(fb
);
239 if (ctx
->Polygon
.CullFlag
) {
240 switch (ctx
->Polygon
.CullFaceMode
) {
242 clip
.CullMode
= CULLMODE_FRONT
;
245 clip
.CullMode
= CULLMODE_BACK
;
247 case GL_FRONT_AND_BACK
:
248 clip
.CullMode
= CULLMODE_BOTH
;
251 unreachable("Should not get here: invalid CullFlag");
254 clip
.CullMode
= CULLMODE_NONE
;
259 clip
.UserClipDistanceCullTestEnableBitmask
=
260 brw_vue_prog_data(brw
->vs
.base
.prog_data
)->cull_distance_mask
;
262 clip
.ViewportZClipTestEnable
= !ctx
->Transform
.DepthClamp
;
266 if (ctx
->Light
.ProvokingVertex
== GL_FIRST_VERTEX_CONVENTION
) {
267 clip
.TriangleStripListProvokingVertexSelect
= 0;
268 clip
.TriangleFanProvokingVertexSelect
= 1;
269 clip
.LineStripListProvokingVertexSelect
= 0;
271 clip
.TriangleStripListProvokingVertexSelect
= 2;
272 clip
.TriangleFanProvokingVertexSelect
= 2;
273 clip
.LineStripListProvokingVertexSelect
= 1;
277 clip
.UserClipDistanceClipTestEnableBitmask
=
278 ctx
->Transform
.ClipPlanesEnabled
;
281 clip
.ForceUserClipDistanceClipTestEnableBitmask
= true;
284 if (ctx
->Transform
.ClipDepthMode
== GL_ZERO_TO_ONE
)
285 clip
.APIMode
= APIMODE_D3D
;
287 clip
.APIMode
= APIMODE_OGL
;
289 clip
.GuardbandClipTestEnable
= true;
291 /* BRW_NEW_VIEWPORT_COUNT */
292 const unsigned viewport_count
= brw
->clip
.viewport_count
;
294 if (ctx
->RasterDiscard
) {
295 clip
.ClipMode
= CLIPMODE_REJECT_ALL
;
297 perf_debug("Rasterizer discard is currently implemented via the "
298 "clipper; having the GS not write primitives would "
299 "likely be faster.\n");
302 clip
.ClipMode
= CLIPMODE_NORMAL
;
305 clip
.ClipEnable
= brw
->primitive
!= _3DPRIM_RECTLIST
;
308 * BRW_NEW_GEOMETRY_PROGRAM | BRW_NEW_TES_PROG_DATA | BRW_NEW_PRIMITIVE
310 if (!brw_is_drawing_points(brw
) && !brw_is_drawing_lines(brw
))
311 clip
.ViewportXYClipTestEnable
= true;
313 clip
.MinimumPointWidth
= 0.125;
314 clip
.MaximumPointWidth
= 255.875;
315 clip
.MaximumVPIndex
= viewport_count
- 1;
316 if (_mesa_geometric_layers(fb
) == 0)
317 clip
.ForceZeroRTAIndexEnable
= true;
321 static const struct brw_tracked_state
genX(clip_state
) = {
323 .mesa
= _NEW_BUFFERS
|
327 .brw
= BRW_NEW_BLORP
|
329 BRW_NEW_FS_PROG_DATA
|
330 BRW_NEW_GS_PROG_DATA
|
331 BRW_NEW_VS_PROG_DATA
|
332 BRW_NEW_META_IN_PROGRESS
|
334 BRW_NEW_RASTERIZER_DISCARD
|
335 BRW_NEW_TES_PROG_DATA
|
336 BRW_NEW_VIEWPORT_COUNT
,
338 .emit
= genX(upload_clip_state
),
341 /* ---------------------------------------------------------------------- */
346 genX(init_atoms
)(struct brw_context
*brw
)
349 static const struct brw_tracked_state
*render_atoms
[] =
351 /* Once all the programs are done, we know how large urb entry
352 * sizes need to be and can decide if we need to change the urb
356 &brw_recalculate_urb_fence
,
361 /* Surface state setup. Must come before the VS/WM unit. The binding
362 * table upload must be last.
364 &brw_vs_pull_constants
,
365 &brw_wm_pull_constants
,
366 &brw_renderbuffer_surfaces
,
367 &brw_renderbuffer_read_surfaces
,
368 &brw_texture_surfaces
,
369 &brw_vs_binding_table
,
370 &brw_wm_binding_table
,
375 /* These set up state for brw_psp_urb_cbs */
379 &brw_vs_unit
, /* always required, enabled or not */
385 &brw_invariant_state
,
387 &brw_binding_table_pointers
,
388 &brw_blend_constant_color
,
392 &brw_polygon_stipple
,
393 &brw_polygon_stipple_offset
,
400 &brw_indices
, /* must come before brw_vertices */
407 static const struct brw_tracked_state
*render_atoms
[] =
409 &gen6_sf_and_clip_viewports
,
411 /* Command packets: */
414 &gen6_viewport_state
, /* must do after *_vp stages */
417 &gen6_blend_state
, /* must do before cc unit */
418 &gen6_color_calc_state
, /* must do before cc unit */
419 &gen6_depth_stencil_state
, /* must do before cc unit */
421 &gen6_vs_push_constants
, /* Before vs_state */
422 &gen6_gs_push_constants
, /* Before gs_state */
423 &gen6_wm_push_constants
, /* Before wm_state */
425 /* Surface state setup. Must come before the VS/WM unit. The binding
426 * table upload must be last.
428 &brw_vs_pull_constants
,
429 &brw_vs_ubo_surfaces
,
430 &brw_gs_pull_constants
,
431 &brw_gs_ubo_surfaces
,
432 &brw_wm_pull_constants
,
433 &brw_wm_ubo_surfaces
,
434 &gen6_renderbuffer_surfaces
,
435 &brw_renderbuffer_read_surfaces
,
436 &brw_texture_surfaces
,
438 &brw_vs_binding_table
,
439 &gen6_gs_binding_table
,
440 &brw_wm_binding_table
,
446 &gen6_multisample_state
,
456 &gen6_binding_table_pointers
,
460 &brw_polygon_stipple
,
461 &brw_polygon_stipple_offset
,
467 &brw_indices
, /* must come before brw_vertices */
472 static const struct brw_tracked_state
*render_atoms
[] =
474 /* Command packets: */
477 &gen7_sf_clip_viewport
,
480 &gen7_push_constant_space
,
482 &gen6_blend_state
, /* must do before cc unit */
483 &gen6_color_calc_state
, /* must do before cc unit */
484 &genX(depth_stencil_state
), /* must do before cc unit */
486 &brw_vs_image_surfaces
, /* Before vs push/pull constants and binding table */
487 &brw_tcs_image_surfaces
, /* Before tcs push/pull constants and binding table */
488 &brw_tes_image_surfaces
, /* Before tes push/pull constants and binding table */
489 &brw_gs_image_surfaces
, /* Before gs push/pull constants and binding table */
490 &brw_wm_image_surfaces
, /* Before wm push/pull constants and binding table */
492 &gen6_vs_push_constants
, /* Before vs_state */
493 &gen7_tcs_push_constants
,
494 &gen7_tes_push_constants
,
495 &gen6_gs_push_constants
, /* Before gs_state */
496 &gen6_wm_push_constants
, /* Before wm_surfaces and constant_buffer */
498 /* Surface state setup. Must come before the VS/WM unit. The binding
499 * table upload must be last.
501 &brw_vs_pull_constants
,
502 &brw_vs_ubo_surfaces
,
503 &brw_vs_abo_surfaces
,
504 &brw_tcs_pull_constants
,
505 &brw_tcs_ubo_surfaces
,
506 &brw_tcs_abo_surfaces
,
507 &brw_tes_pull_constants
,
508 &brw_tes_ubo_surfaces
,
509 &brw_tes_abo_surfaces
,
510 &brw_gs_pull_constants
,
511 &brw_gs_ubo_surfaces
,
512 &brw_gs_abo_surfaces
,
513 &brw_wm_pull_constants
,
514 &brw_wm_ubo_surfaces
,
515 &brw_wm_abo_surfaces
,
516 &gen6_renderbuffer_surfaces
,
517 &brw_renderbuffer_read_surfaces
,
518 &brw_texture_surfaces
,
519 &brw_vs_binding_table
,
520 &brw_tcs_binding_table
,
521 &brw_tes_binding_table
,
522 &brw_gs_binding_table
,
523 &brw_wm_binding_table
,
530 &gen6_multisample_state
,
548 &brw_polygon_stipple
,
549 &brw_polygon_stipple_offset
,
555 &brw_indices
, /* must come before brw_vertices */
562 static const struct brw_tracked_state
*render_atoms
[] =
565 &gen8_sf_clip_viewport
,
568 &gen7_push_constant_space
,
571 &gen6_color_calc_state
,
573 &brw_vs_image_surfaces
, /* Before vs push/pull constants and binding table */
574 &brw_tcs_image_surfaces
, /* Before tcs push/pull constants and binding table */
575 &brw_tes_image_surfaces
, /* Before tes push/pull constants and binding table */
576 &brw_gs_image_surfaces
, /* Before gs push/pull constants and binding table */
577 &brw_wm_image_surfaces
, /* Before wm push/pull constants and binding table */
579 &gen6_vs_push_constants
, /* Before vs_state */
580 &gen7_tcs_push_constants
,
581 &gen7_tes_push_constants
,
582 &gen6_gs_push_constants
, /* Before gs_state */
583 &gen6_wm_push_constants
, /* Before wm_surfaces and constant_buffer */
585 /* Surface state setup. Must come before the VS/WM unit. The binding
586 * table upload must be last.
588 &brw_vs_pull_constants
,
589 &brw_vs_ubo_surfaces
,
590 &brw_vs_abo_surfaces
,
591 &brw_tcs_pull_constants
,
592 &brw_tcs_ubo_surfaces
,
593 &brw_tcs_abo_surfaces
,
594 &brw_tes_pull_constants
,
595 &brw_tes_ubo_surfaces
,
596 &brw_tes_abo_surfaces
,
597 &brw_gs_pull_constants
,
598 &brw_gs_ubo_surfaces
,
599 &brw_gs_abo_surfaces
,
600 &brw_wm_pull_constants
,
601 &brw_wm_ubo_surfaces
,
602 &brw_wm_abo_surfaces
,
603 &gen6_renderbuffer_surfaces
,
604 &brw_renderbuffer_read_surfaces
,
605 &brw_texture_surfaces
,
606 &brw_vs_binding_table
,
607 &brw_tcs_binding_table
,
608 &brw_tes_binding_table
,
609 &brw_gs_binding_table
,
610 &brw_wm_binding_table
,
617 &gen8_multisample_state
,
632 &genX(depth_stencil_state
),
639 &brw_polygon_stipple
,
640 &brw_polygon_stipple_offset
,
657 STATIC_ASSERT(ARRAY_SIZE(render_atoms
) <= ARRAY_SIZE(brw
->render_atoms
));
658 brw_copy_pipeline_atoms(brw
, BRW_RENDER_PIPELINE
,
659 render_atoms
, ARRAY_SIZE(render_atoms
));
662 static const struct brw_tracked_state
*compute_atoms
[] =
665 &brw_cs_image_surfaces
,
666 &gen7_cs_push_constants
,
667 &brw_cs_pull_constants
,
668 &brw_cs_ubo_surfaces
,
669 &brw_cs_abo_surfaces
,
670 &brw_cs_texture_surfaces
,
671 &brw_cs_work_groups_surface
,
676 STATIC_ASSERT(ARRAY_SIZE(compute_atoms
) <= ARRAY_SIZE(brw
->compute_atoms
));
677 brw_copy_pipeline_atoms(brw
, BRW_COMPUTE_PIPELINE
,
678 compute_atoms
, ARRAY_SIZE(compute_atoms
));