2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2015 LunarG, Inc.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "ilo_debug.h"
29 #include "ilo_state_cc.h"
32 cc_validate_gen6_stencil(const struct ilo_dev
*dev
,
33 const struct ilo_state_cc_info
*info
)
35 const struct ilo_state_cc_stencil_info
*stencil
= &info
->stencil
;
37 ILO_DEV_ASSERT(dev
, 6, 8);
40 * From the Sandy Bridge PRM, volume 2 part 1, page 359:
42 * "If the Depth Buffer is either undefined or does not have a surface
43 * format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate
44 * stencil buffer is disabled, Stencil Test Enable must be DISABLED"
46 * From the Sandy Bridge PRM, volume 2 part 1, page 370:
48 * "This field (Stencil Test Enable) cannot be enabled if Surface
49 * Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
51 if (stencil
->test_enable
)
52 assert(stencil
->cv_has_buffer
);
58 cc_validate_gen6_depth(const struct ilo_dev
*dev
,
59 const struct ilo_state_cc_info
*info
)
61 const struct ilo_state_cc_depth_info
*depth
= &info
->depth
;
63 ILO_DEV_ASSERT(dev
, 6, 8);
66 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
68 * "Enabling the Depth Test function without defining a Depth Buffer is
71 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
73 * "A Depth Buffer must be defined before enabling writes to it, or
74 * operation is UNDEFINED."
76 if (depth
->test_enable
|| depth
->write_enable
)
77 assert(depth
->cv_has_buffer
);
83 cc_set_gen6_DEPTH_STENCIL_STATE(struct ilo_state_cc
*cc
,
84 const struct ilo_dev
*dev
,
85 const struct ilo_state_cc_info
*info
)
87 const struct ilo_state_cc_stencil_info
*stencil
= &info
->stencil
;
88 const struct ilo_state_cc_depth_info
*depth
= &info
->depth
;
89 const struct ilo_state_cc_params_info
*params
= &info
->params
;
90 uint32_t dw0
, dw1
, dw2
;
92 ILO_DEV_ASSERT(dev
, 6, 7.5);
94 if (!cc_validate_gen6_stencil(dev
, info
) ||
95 !cc_validate_gen6_depth(dev
, info
))
100 if (stencil
->test_enable
) {
101 const struct ilo_state_cc_stencil_op_info
*front
= &stencil
->front
;
102 const struct ilo_state_cc_stencil_params_info
*front_p
=
103 ¶ms
->stencil_front
;
104 const struct ilo_state_cc_stencil_op_info
*back
;
105 const struct ilo_state_cc_stencil_params_info
*back_p
;
107 dw0
|= GEN6_ZS_DW0_STENCIL_TEST_ENABLE
;
109 if (stencil
->twosided_enable
) {
110 dw0
|= GEN6_ZS_DW0_STENCIL1_ENABLE
;
112 back
= &stencil
->back
;
113 back_p
= ¶ms
->stencil_back
;
115 back
= &stencil
->front
;
116 back_p
= ¶ms
->stencil_front
;
119 dw0
|= front
->test_func
<< GEN6_ZS_DW0_STENCIL_FUNC__SHIFT
|
120 front
->fail_op
<< GEN6_ZS_DW0_STENCIL_FAIL_OP__SHIFT
|
121 front
->zfail_op
<< GEN6_ZS_DW0_STENCIL_ZFAIL_OP__SHIFT
|
122 front
->zpass_op
<< GEN6_ZS_DW0_STENCIL_ZPASS_OP__SHIFT
|
123 back
->test_func
<< GEN6_ZS_DW0_STENCIL1_FUNC__SHIFT
|
124 back
->fail_op
<< GEN6_ZS_DW0_STENCIL1_FAIL_OP__SHIFT
|
125 back
->zfail_op
<< GEN6_ZS_DW0_STENCIL1_ZFAIL_OP__SHIFT
|
126 back
->zpass_op
<< GEN6_ZS_DW0_STENCIL1_ZPASS_OP__SHIFT
;
129 * From the Ivy Bridge PRM, volume 2 part 1, page 363:
131 * "If this field (Stencil Buffer Write Enable) is enabled, Stencil
132 * Test Enable must also be enabled."
134 * This is different from depth write enable, which is independent from
137 if (front_p
->write_mask
|| back_p
->write_mask
)
138 dw0
|= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE
;
140 dw1
|= front_p
->test_mask
<< GEN6_ZS_DW1_STENCIL_TEST_MASK__SHIFT
|
141 front_p
->write_mask
<< GEN6_ZS_DW1_STENCIL_WRITE_MASK__SHIFT
|
142 back_p
->test_mask
<< GEN6_ZS_DW1_STENCIL1_TEST_MASK__SHIFT
|
143 back_p
->write_mask
<< GEN6_ZS_DW1_STENCIL1_WRITE_MASK__SHIFT
;
147 if (depth
->test_enable
) {
148 dw2
|= GEN6_ZS_DW2_DEPTH_TEST_ENABLE
|
149 depth
->test_func
<< GEN6_ZS_DW2_DEPTH_FUNC__SHIFT
;
151 dw2
|= GEN6_COMPAREFUNCTION_ALWAYS
<< GEN6_ZS_DW2_DEPTH_FUNC__SHIFT
;
154 /* independent from depth->test_enable */
155 if (depth
->write_enable
)
156 dw2
|= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE
;
158 STATIC_ASSERT(ARRAY_SIZE(cc
->ds
) >= 3);
167 cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_state_cc
*cc
,
168 const struct ilo_dev
*dev
,
169 const struct ilo_state_cc_info
*info
)
171 const struct ilo_state_cc_stencil_info
*stencil
= &info
->stencil
;
172 const struct ilo_state_cc_depth_info
*depth
= &info
->depth
;
173 const struct ilo_state_cc_params_info
*params
= &info
->params
;
176 ILO_DEV_ASSERT(dev
, 8, 8);
178 if (!cc_validate_gen6_stencil(dev
, info
) ||
179 !cc_validate_gen6_depth(dev
, info
))
184 if (stencil
->test_enable
) {
185 const struct ilo_state_cc_stencil_op_info
*front
= &stencil
->front
;
186 const struct ilo_state_cc_stencil_params_info
*front_p
=
187 ¶ms
->stencil_front
;
188 const struct ilo_state_cc_stencil_op_info
*back
;
189 const struct ilo_state_cc_stencil_params_info
*back_p
;
191 dw1
|= GEN8_ZS_DW1_STENCIL_TEST_ENABLE
;
193 if (stencil
->twosided_enable
) {
194 dw1
|= GEN8_ZS_DW1_STENCIL1_ENABLE
;
196 back
= &stencil
->back
;
197 back_p
= ¶ms
->stencil_back
;
199 back
= &stencil
->front
;
200 back_p
= ¶ms
->stencil_front
;
203 dw1
|= front
->fail_op
<< GEN8_ZS_DW1_STENCIL_FAIL_OP__SHIFT
|
204 front
->zfail_op
<< GEN8_ZS_DW1_STENCIL_ZFAIL_OP__SHIFT
|
205 front
->zpass_op
<< GEN8_ZS_DW1_STENCIL_ZPASS_OP__SHIFT
|
206 back
->test_func
<< GEN8_ZS_DW1_STENCIL1_FUNC__SHIFT
|
207 back
->fail_op
<< GEN8_ZS_DW1_STENCIL1_FAIL_OP__SHIFT
|
208 back
->zfail_op
<< GEN8_ZS_DW1_STENCIL1_ZFAIL_OP__SHIFT
|
209 back
->zpass_op
<< GEN8_ZS_DW1_STENCIL1_ZPASS_OP__SHIFT
|
210 front
->test_func
<< GEN8_ZS_DW1_STENCIL_FUNC__SHIFT
;
212 if (front_p
->write_mask
|| back_p
->write_mask
)
213 dw1
|= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE
;
215 dw2
|= front_p
->test_mask
<< GEN8_ZS_DW2_STENCIL_TEST_MASK__SHIFT
|
216 front_p
->write_mask
<< GEN8_ZS_DW2_STENCIL_WRITE_MASK__SHIFT
|
217 back_p
->test_mask
<< GEN8_ZS_DW2_STENCIL1_TEST_MASK__SHIFT
|
218 back_p
->write_mask
<< GEN8_ZS_DW2_STENCIL1_WRITE_MASK__SHIFT
;
221 if (depth
->test_enable
) {
222 dw1
|= GEN8_ZS_DW1_DEPTH_TEST_ENABLE
|
223 depth
->test_func
<< GEN8_ZS_DW1_DEPTH_FUNC__SHIFT
;
225 dw1
|= GEN6_COMPAREFUNCTION_ALWAYS
<< GEN8_ZS_DW1_DEPTH_FUNC__SHIFT
;
228 if (depth
->write_enable
)
229 dw1
|= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE
;
231 STATIC_ASSERT(ARRAY_SIZE(cc
->ds
) >= 2);
239 is_dual_source_blend_factor(enum gen_blend_factor factor
)
242 case GEN6_BLENDFACTOR_SRC1_COLOR
:
243 case GEN6_BLENDFACTOR_SRC1_ALPHA
:
244 case GEN6_BLENDFACTOR_INV_SRC1_COLOR
:
245 case GEN6_BLENDFACTOR_INV_SRC1_ALPHA
:
253 cc_get_gen6_dual_source_blending(const struct ilo_dev
*dev
,
254 const struct ilo_state_cc_info
*info
)
256 const struct ilo_state_cc_blend_info
*blend
= &info
->blend
;
257 bool dual_source_blending
;
260 ILO_DEV_ASSERT(dev
, 6, 8);
262 dual_source_blending
= (blend
->rt_count
&&
263 (is_dual_source_blend_factor(blend
->rt
[0].rgb_src
) ||
264 is_dual_source_blend_factor(blend
->rt
[0].rgb_dst
) ||
265 is_dual_source_blend_factor(blend
->rt
[0].a_src
) ||
266 is_dual_source_blend_factor(blend
->rt
[0].a_dst
)));
269 * From the Ivy Bridge PRM, volume 2 part 1, page 356:
271 * "Dual Source Blending: When using "Dual Source" Render Target
272 * Write messages, the Source1 pixel color+alpha passed in the
273 * message can be selected as a src/dst blend factor. See Color
274 * Buffer Blending. In single-source mode, those blend factor
275 * selections are invalid. If SRC1 is included in a src/dst blend
276 * factor and a DualSource RT Write message is not utilized,
277 * results are UNDEFINED. (This reflects the same restriction in DX
278 * APIs, where undefined results are produced if "o1" is not
279 * written by a PS - there are no default values defined). If SRC1
280 * is not included in a src/dst blend factor, dual source blending
283 * From the Ivy Bridge PRM, volume 4 part 1, page 356:
285 * "The single source message will not cause a write to the render
286 * target if Dual Source Blend Enable in 3DSTATE_WM is enabled."
288 * "The dual source message will revert to a single source message
289 * using source 0 if Dual Source Blend Enable in 3DSTATE_WM is
292 * Dual source blending must be enabled or disabled universally.
294 for (i
= 1; i
< blend
->rt_count
; i
++) {
295 assert(dual_source_blending
==
296 (is_dual_source_blend_factor(blend
->rt
[i
].rgb_src
) ||
297 is_dual_source_blend_factor(blend
->rt
[i
].rgb_dst
) ||
298 is_dual_source_blend_factor(blend
->rt
[i
].a_src
) ||
299 is_dual_source_blend_factor(blend
->rt
[i
].a_dst
)));
302 return dual_source_blending
;
306 cc_validate_gen6_alpha(const struct ilo_dev
*dev
,
307 const struct ilo_state_cc_info
*info
)
309 const struct ilo_state_cc_alpha_info
*alpha
= &info
->alpha
;
311 ILO_DEV_ASSERT(dev
, 6, 8);
314 * From the Sandy Bridge PRM, volume 2 part 1, page 356:
316 * "Alpha values from the pixel shader are treated as FLOAT32 format
317 * for computing the AlphaToCoverage Mask."
319 * From the Sandy Bridge PRM, volume 2 part 1, page 378:
321 * "If set (AlphaToCoverage Enable), Source0 Alpha is converted to a
322 * temporary 1/2/4-bit coverage mask and the mask bit corresponding to
323 * the sample# ANDed with the sample mask bit. If set, sample coverage
324 * is computed based on src0 alpha value. Value of 0 disables all
325 * samples and value of 1 enables all samples for that pixel. The same
326 * coverage needs to apply to all the RTs in MRT case. Further, any
327 * value of src0 alpha between 0 and 1 monotonically increases the
328 * number of enabled pixels.
330 * The same coverage needs to be applied to all the RTs in MRT case."
332 * "If set (AlphaToOne Enable), Source0 Alpha is set to 1.0f after
333 * (possibly) being used to generate the AlphaToCoverage coverage
336 * The same coverage needs to be applied to all the RTs in MRT case.
338 * If Dual Source Blending is enabled, this bit must be disabled."
340 * From the Sandy Bridge PRM, volume 2 part 1, page 382:
342 * "Alpha Test can only be enabled if Pixel Shader outputs a float
345 * Alpha Test is applied independently on each render target by
346 * comparing that render target's alpha value against the alpha
347 * reference value. If the alpha test fails, the corresponding pixel
348 * write will be supressed only for that render target. The
349 * depth/stencil update will occur if alpha test passes for any render
352 * From the Sandy Bridge PRM, volume 4 part 1, page 194:
354 * "Multiple render targets are supported with the single source and
355 * replicate data messages. Each render target is accessed with a
356 * separate Render Target Write message, each with a different surface
357 * indicated (different binding table index). The depth buffer is
358 * written only by the message(s) to the last render target, indicated
359 * by the Last Render Target Select bit set to clear the pixel
362 * When AlphaToCoverage/AlphaToOne/AlphaTest is enabled, it is
363 * required/desirable for the RT write messages to set "Source0 Alpha
364 * Present to RenderTarget" in the MRT case. It is also required/desirable
365 * for the alpha values to be FLOAT32.
367 if (alpha
->alpha_to_coverage
|| alpha
->alpha_to_one
|| alpha
->test_enable
)
368 assert(alpha
->cv_float_source0_alpha
);
371 * From the Sandy Bridge PRM, volume 2 part 1, page 356:
373 * "[DevSNB]: When NumSamples = 1, AlphaToCoverage and AlphaTo
374 * Coverage Dither both must be disabled."
376 if (ilo_dev_gen(dev
) == ILO_GEN(6) && alpha
->alpha_to_coverage
)
377 assert(alpha
->cv_sample_count_one
);
380 * From the Sandy Bridge PRM, volume 2 part 1, page 378:
382 * "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
385 if (alpha
->alpha_to_one
)
386 assert(!cc_get_gen6_dual_source_blending(dev
, info
));
392 cc_validate_gen6_blend(const struct ilo_dev
*dev
,
393 const struct ilo_state_cc_info
*info
)
395 const struct ilo_state_cc_blend_info
*blend
= &info
->blend
;
397 ILO_DEV_ASSERT(dev
, 6, 8);
399 assert(blend
->rt_count
<= ILO_STATE_CC_BLEND_MAX_RT_COUNT
);
404 static enum gen_blend_factor
405 get_dst_alpha_one_blend_factor(enum gen_blend_factor factor
, bool is_rgb
)
408 case GEN6_BLENDFACTOR_DST_ALPHA
:
409 return GEN6_BLENDFACTOR_ONE
;
410 case GEN6_BLENDFACTOR_INV_DST_ALPHA
:
411 return GEN6_BLENDFACTOR_ZERO
;
412 case GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE
:
413 return (is_rgb
) ? GEN6_BLENDFACTOR_ZERO
: GEN6_BLENDFACTOR_ONE
;
420 cc_get_gen6_effective_rt(const struct ilo_dev
*dev
,
421 const struct ilo_state_cc_info
*info
,
423 struct ilo_state_cc_blend_rt_info
*dst
)
425 const struct ilo_state_cc_blend_rt_info
*rt
= &info
->blend
.rt
[rt_index
];
427 if (rt
->logicop_enable
|| rt
->blend_enable
||
428 rt
->argb_write_disables
!= 0xf)
429 assert(rt
->cv_has_buffer
);
432 * From the Sandy Bridge PRM, volume 2 part 1, page 365:
434 * "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
435 * variants), otherwise Logic Ops must be DISABLED."
437 * From the Broadwell PRM, volume 7, page 671:
439 * "Logic Ops are supported on all blendable render targets and render
440 * targets with *INT formats."
442 if (ilo_dev_gen(dev
) < ILO_GEN(8) && rt
->logicop_enable
)
443 assert(rt
->cv_is_unorm
);
446 * From the Sandy Bridge PRM, volume 2 part 1, page 361:
448 * "Only certain surface formats support Color Buffer Blending. Refer
449 * to the Surface Format tables in Sampling Engine. Blending must be
450 * disabled on a RenderTarget if blending is not supported."
452 * From the Sandy Bridge PRM, volume 2 part 1, page 365:
454 * "Color Buffer Blending and Logic Ops must not be enabled
455 * simultaneously, or behavior is UNDEFINED."
457 if (rt
->blend_enable
)
458 assert(!rt
->cv_is_integer
&& !rt
->logicop_enable
);
461 if (rt
->blend_enable
) {
462 /* 0x0 is reserved in enum gen_blend_factor */
463 assert(rt
->rgb_src
&& rt
->rgb_dst
&& rt
->a_src
&& rt
->a_dst
);
465 if (rt
->force_dst_alpha_one
) {
466 dst
->rgb_src
= get_dst_alpha_one_blend_factor(rt
->rgb_src
, true);
467 dst
->rgb_dst
= get_dst_alpha_one_blend_factor(rt
->rgb_dst
, true);
468 dst
->a_src
= get_dst_alpha_one_blend_factor(rt
->a_src
, false);
469 dst
->a_dst
= get_dst_alpha_one_blend_factor(rt
->a_dst
, false);
470 dst
->force_dst_alpha_one
= false;
473 dst
->rgb_src
= GEN6_BLENDFACTOR_ONE
;
474 dst
->rgb_dst
= GEN6_BLENDFACTOR_ZERO
;
475 dst
->rgb_func
= GEN6_BLENDFUNCTION_ADD
;
476 dst
->a_src
= dst
->rgb_src
;
477 dst
->a_dst
= dst
->rgb_dst
;
478 dst
->a_func
= dst
->rgb_func
;
483 cc_set_gen6_BLEND_STATE(struct ilo_state_cc
*cc
,
484 const struct ilo_dev
*dev
,
485 const struct ilo_state_cc_info
*info
)
487 const struct ilo_state_cc_alpha_info
*alpha
= &info
->alpha
;
488 const struct ilo_state_cc_blend_info
*blend
= &info
->blend
;
489 uint32_t dw_rt
[2 * ILO_STATE_CC_BLEND_MAX_RT_COUNT
], dw1_invariant
;
493 ILO_DEV_ASSERT(dev
, 6, 7.5);
495 if (!cc_validate_gen6_alpha(dev
, info
) ||
496 !cc_validate_gen6_blend(dev
, info
))
500 * According to the Sandy Bridge PRM, volume 2 part 1, page 360, pre-blend
501 * and post-blend color clamps must be enabled in most cases. For the
502 * other cases, they are either desirable or ignored. We can enable them
505 dw1
= GEN6_RT_DW1_COLORCLAMP_RTFORMAT
|
506 GEN6_RT_DW1_PRE_BLEND_CLAMP
|
507 GEN6_RT_DW1_POST_BLEND_CLAMP
;
509 if (alpha
->alpha_to_coverage
) {
510 dw1
|= GEN6_RT_DW1_ALPHA_TO_COVERAGE
;
513 * From the Sandy Bridge PRM, volume 2 part 1, page 379:
515 * "[DevSNB]: This bit (AlphaToCoverage Dither Enable) must be
518 if (ilo_dev_gen(dev
) >= ILO_GEN(7))
519 dw1
|= GEN6_RT_DW1_ALPHA_TO_COVERAGE_DITHER
;
522 if (alpha
->alpha_to_one
)
523 dw1
|= GEN6_RT_DW1_ALPHA_TO_ONE
;
525 if (alpha
->test_enable
) {
526 dw1
|= GEN6_RT_DW1_ALPHA_TEST_ENABLE
|
527 alpha
->test_func
<< GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT
;
530 * From the Ivy Bridge PRM, volume 2 part 1, page 371:
532 * "When Alpha Test is disabled, Alpha Test Function must be
533 * COMPAREFUNCTION_ALWAYS."
535 dw1
|= GEN6_COMPAREFUNCTION_ALWAYS
<<
536 GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT
;
539 if (blend
->dither_enable
)
540 dw1
|= GEN6_RT_DW1_DITHER_ENABLE
;
544 for (i
= 0; i
< blend
->rt_count
; i
++) {
545 struct ilo_state_cc_blend_rt_info rt
;
547 cc_get_gen6_effective_rt(dev
, info
, i
, &rt
);
549 /* 0x0 is reserved for blend factors and we have to set them all */
550 dw0
= rt
.a_func
<< GEN6_RT_DW0_ALPHA_FUNC__SHIFT
|
551 rt
.a_src
<< GEN6_RT_DW0_SRC_ALPHA_FACTOR__SHIFT
|
552 rt
.a_dst
<< GEN6_RT_DW0_DST_ALPHA_FACTOR__SHIFT
|
553 rt
.rgb_func
<< GEN6_RT_DW0_COLOR_FUNC__SHIFT
|
554 rt
.rgb_src
<< GEN6_RT_DW0_SRC_COLOR_FACTOR__SHIFT
|
555 rt
.rgb_dst
<< GEN6_RT_DW0_DST_COLOR_FACTOR__SHIFT
;
557 if (rt
.blend_enable
) {
558 dw0
|= GEN6_RT_DW0_BLEND_ENABLE
;
560 if (rt
.a_src
!= rt
.rgb_src
||
561 rt
.a_dst
!= rt
.rgb_dst
||
562 rt
.a_func
!= rt
.rgb_func
)
563 dw0
|= GEN6_RT_DW0_INDEPENDENT_ALPHA_ENABLE
;
566 dw1
= dw1_invariant
|
567 rt
.argb_write_disables
<< GEN6_RT_DW1_WRITE_DISABLES__SHIFT
;
569 if (rt
.logicop_enable
) {
570 dw1
|= GEN6_RT_DW1_LOGICOP_ENABLE
|
571 rt
.logicop_func
<< GEN6_RT_DW1_LOGICOP_FUNC__SHIFT
;
574 dw_rt
[2 * i
+ 0] = dw0
;
575 dw_rt
[2 * i
+ 1] = dw1
;
579 STATIC_ASSERT(ARRAY_SIZE(cc
->blend
) >= ARRAY_SIZE(dw_rt
));
580 memcpy(&cc
->blend
[0], dw_rt
, sizeof(uint32_t) * 2 * blend
->rt_count
);
581 cc
->blend_state_count
= info
->blend
.rt_count
;
587 cc_set_gen8_BLEND_STATE(struct ilo_state_cc
*cc
,
588 const struct ilo_dev
*dev
,
589 const struct ilo_state_cc_info
*info
)
591 const struct ilo_state_cc_alpha_info
*alpha
= &info
->alpha
;
592 const struct ilo_state_cc_blend_info
*blend
= &info
->blend
;
593 uint32_t dw_rt
[2 * ILO_STATE_CC_BLEND_MAX_RT_COUNT
], dw0
, dw1
;
594 bool indep_alpha_enable
;
597 ILO_DEV_ASSERT(dev
, 8, 8);
599 if (!cc_validate_gen6_alpha(dev
, info
) ||
600 !cc_validate_gen6_blend(dev
, info
))
603 indep_alpha_enable
= false;
604 for (i
= 0; i
< blend
->rt_count
; i
++) {
605 struct ilo_state_cc_blend_rt_info rt
;
607 cc_get_gen6_effective_rt(dev
, info
, i
, &rt
);
609 dw0
= rt
.rgb_src
<< GEN8_RT_DW0_SRC_COLOR_FACTOR__SHIFT
|
610 rt
.rgb_dst
<< GEN8_RT_DW0_DST_COLOR_FACTOR__SHIFT
|
611 rt
.rgb_func
<< GEN8_RT_DW0_COLOR_FUNC__SHIFT
|
612 rt
.a_src
<< GEN8_RT_DW0_SRC_ALPHA_FACTOR__SHIFT
|
613 rt
.a_dst
<< GEN8_RT_DW0_DST_ALPHA_FACTOR__SHIFT
|
614 rt
.a_func
<< GEN8_RT_DW0_ALPHA_FUNC__SHIFT
|
615 rt
.argb_write_disables
<< GEN8_RT_DW0_WRITE_DISABLES__SHIFT
;
617 if (rt
.blend_enable
) {
618 dw0
|= GEN8_RT_DW0_BLEND_ENABLE
;
620 if (rt
.a_src
!= rt
.rgb_src
||
621 rt
.a_dst
!= rt
.rgb_dst
||
622 rt
.a_func
!= rt
.rgb_func
)
623 indep_alpha_enable
= true;
626 dw1
= GEN8_RT_DW1_COLORCLAMP_RTFORMAT
|
627 GEN8_RT_DW1_PRE_BLEND_CLAMP
|
628 GEN8_RT_DW1_POST_BLEND_CLAMP
;
630 if (rt
.logicop_enable
) {
631 dw1
|= GEN8_RT_DW1_LOGICOP_ENABLE
|
632 rt
.logicop_func
<< GEN8_RT_DW1_LOGICOP_FUNC__SHIFT
;
635 dw_rt
[2 * i
+ 0] = dw0
;
636 dw_rt
[2 * i
+ 1] = dw1
;
641 if (alpha
->alpha_to_coverage
) {
642 dw0
|= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE
|
643 GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER
;
646 if (indep_alpha_enable
)
647 dw0
|= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE
;
649 if (alpha
->alpha_to_one
)
650 dw0
|= GEN8_BLEND_DW0_ALPHA_TO_ONE
;
652 if (alpha
->test_enable
) {
653 dw0
|= GEN8_BLEND_DW0_ALPHA_TEST_ENABLE
|
654 alpha
->test_func
<< GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT
;
656 dw0
|= GEN6_COMPAREFUNCTION_ALWAYS
<<
657 GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT
;
660 if (blend
->dither_enable
)
661 dw0
|= GEN8_BLEND_DW0_DITHER_ENABLE
;
663 STATIC_ASSERT(ARRAY_SIZE(cc
->blend
) >= 2 + ARRAY_SIZE(dw_rt
));
665 memcpy(&cc
->blend
[2], dw_rt
, sizeof(uint32_t) * 2 * blend
->rt_count
);
666 cc
->blend_state_count
= info
->blend
.rt_count
;
672 cc_set_gen8_3DSTATE_PS_BLEND(struct ilo_state_cc
*cc
,
673 const struct ilo_dev
*dev
,
674 const struct ilo_state_cc_info
*info
)
676 const struct ilo_state_cc_alpha_info
*alpha
= &info
->alpha
;
677 const struct ilo_state_cc_blend_info
*blend
= &info
->blend
;
680 ILO_DEV_ASSERT(dev
, 8, 8);
684 if (alpha
->alpha_to_coverage
)
685 dw1
|= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE
;
687 if (alpha
->test_enable
)
688 dw1
|= GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE
;
690 if (blend
->rt_count
) {
691 struct ilo_state_cc_blend_rt_info rt0
;
694 cc_get_gen6_effective_rt(dev
, info
, 0, &rt0
);
696 /* 0x0 is reserved for blend factors and we have to set them all */
697 dw1
|= rt0
.a_src
<< GEN8_PS_BLEND_DW1_SRC_ALPHA_FACTOR__SHIFT
|
698 rt0
.a_dst
<< GEN8_PS_BLEND_DW1_DST_ALPHA_FACTOR__SHIFT
|
699 rt0
.rgb_src
<< GEN8_PS_BLEND_DW1_SRC_COLOR_FACTOR__SHIFT
|
700 rt0
.rgb_dst
<< GEN8_PS_BLEND_DW1_DST_COLOR_FACTOR__SHIFT
;
702 for (i
= 0; i
< blend
->rt_count
; i
++) {
703 if (blend
->rt
[i
].argb_write_disables
!= 0xf) {
704 dw1
|= GEN8_PS_BLEND_DW1_WRITABLE_RT
;
709 if (rt0
.blend_enable
) {
710 dw1
|= GEN8_PS_BLEND_DW1_BLEND_ENABLE
;
712 if (rt0
.a_src
!= rt0
.rgb_src
|| rt0
.a_dst
!= rt0
.rgb_dst
)
713 dw1
|= GEN8_PS_BLEND_DW1_INDEPENDENT_ALPHA_ENABLE
;
717 STATIC_ASSERT(ARRAY_SIZE(cc
->blend
) >= 1);
724 cc_params_set_gen6_COLOR_CALC_STATE(struct ilo_state_cc
*cc
,
725 const struct ilo_dev
*dev
,
726 const struct ilo_state_cc_params_info
*params
)
730 ILO_DEV_ASSERT(dev
, 6, 8);
732 dw0
= params
->stencil_front
.test_ref
<< GEN6_CC_DW0_STENCIL_REF__SHIFT
|
733 params
->stencil_back
.test_ref
<< GEN6_CC_DW0_STENCIL1_REF__SHIFT
|
734 GEN6_CC_DW0_ALPHATEST_FLOAT32
;
736 STATIC_ASSERT(ARRAY_SIZE(cc
->cc
) >= 6);
738 cc
->cc
[1] = fui(params
->alpha_ref
);
739 cc
->cc
[2] = fui(params
->blend_rgba
[0]);
740 cc
->cc
[3] = fui(params
->blend_rgba
[1]);
741 cc
->cc
[4] = fui(params
->blend_rgba
[2]);
742 cc
->cc
[5] = fui(params
->blend_rgba
[3]);
748 ilo_state_cc_init(struct ilo_state_cc
*cc
,
749 const struct ilo_dev
*dev
,
750 const struct ilo_state_cc_info
*info
)
752 assert(ilo_is_zeroed(cc
, sizeof(*cc
)));
753 return ilo_state_cc_set_info(cc
, dev
, info
);
757 ilo_state_cc_set_info(struct ilo_state_cc
*cc
,
758 const struct ilo_dev
*dev
,
759 const struct ilo_state_cc_info
*info
)
763 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
764 ret
&= cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL(cc
, dev
, info
);
765 ret
&= cc_set_gen8_BLEND_STATE(cc
, dev
, info
);
766 ret
&= cc_set_gen8_3DSTATE_PS_BLEND(cc
, dev
, info
);
768 ret
&= cc_set_gen6_DEPTH_STENCIL_STATE(cc
, dev
, info
);
769 ret
&= cc_set_gen6_BLEND_STATE(cc
, dev
, info
);
772 ret
&= cc_params_set_gen6_COLOR_CALC_STATE(cc
, dev
, &info
->params
);
780 ilo_state_cc_set_params(struct ilo_state_cc
*cc
,
781 const struct ilo_dev
*dev
,
782 const struct ilo_state_cc_params_info
*params
)
784 /* modify stencil masks */
785 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
786 uint32_t dw1
= cc
->ds
[0];
787 uint32_t dw2
= cc
->ds
[1];
789 if (dw1
& GEN8_ZS_DW1_STENCIL_TEST_ENABLE
) {
790 const bool twosided_enable
= (dw1
& GEN8_ZS_DW1_STENCIL1_ENABLE
);
791 const struct ilo_state_cc_stencil_params_info
*front_p
=
792 ¶ms
->stencil_front
;
793 const struct ilo_state_cc_stencil_params_info
*back_p
=
794 (twosided_enable
) ? ¶ms
->stencil_back
:
795 ¶ms
->stencil_front
;
797 if (front_p
->write_mask
|| back_p
->write_mask
)
798 dw1
|= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE
;
800 dw1
&= ~GEN8_ZS_DW1_STENCIL_WRITE_ENABLE
;
803 front_p
->test_mask
<< GEN8_ZS_DW2_STENCIL_TEST_MASK__SHIFT
|
804 front_p
->write_mask
<< GEN8_ZS_DW2_STENCIL_WRITE_MASK__SHIFT
|
805 back_p
->test_mask
<< GEN8_ZS_DW2_STENCIL1_TEST_MASK__SHIFT
|
806 back_p
->write_mask
<< GEN8_ZS_DW2_STENCIL1_WRITE_MASK__SHIFT
;
812 uint32_t dw0
= cc
->ds
[0];
813 uint32_t dw1
= cc
->ds
[1];
815 if (dw0
& GEN6_ZS_DW0_STENCIL_TEST_ENABLE
) {
816 const bool twosided_enable
= (dw0
& GEN6_ZS_DW0_STENCIL1_ENABLE
);
817 const struct ilo_state_cc_stencil_params_info
*front_p
=
818 ¶ms
->stencil_front
;
819 const struct ilo_state_cc_stencil_params_info
*back_p
=
820 (twosided_enable
) ? ¶ms
->stencil_back
:
821 ¶ms
->stencil_front
;
823 if (front_p
->write_mask
|| back_p
->write_mask
)
824 dw0
|= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE
;
826 dw0
&= ~GEN6_ZS_DW0_STENCIL_WRITE_ENABLE
;
829 front_p
->test_mask
<< GEN6_ZS_DW1_STENCIL_TEST_MASK__SHIFT
|
830 front_p
->write_mask
<< GEN6_ZS_DW1_STENCIL_WRITE_MASK__SHIFT
|
831 back_p
->test_mask
<< GEN6_ZS_DW1_STENCIL1_TEST_MASK__SHIFT
|
832 back_p
->write_mask
<< GEN6_ZS_DW1_STENCIL1_WRITE_MASK__SHIFT
;
839 /* modify COLOR_CALC_STATE */
840 cc_params_set_gen6_COLOR_CALC_STATE(cc
, dev
, params
);
846 ilo_state_cc_full_delta(const struct ilo_state_cc
*cc
,
847 const struct ilo_dev
*dev
,
848 struct ilo_state_cc_delta
*delta
)
850 delta
->dirty
= ILO_STATE_CC_BLEND_STATE
|
851 ILO_STATE_CC_COLOR_CALC_STATE
;
853 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
854 delta
->dirty
|= ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL
|
855 ILO_STATE_CC_3DSTATE_PS_BLEND
;
857 delta
->dirty
|= ILO_STATE_CC_DEPTH_STENCIL_STATE
;
862 ilo_state_cc_get_delta(const struct ilo_state_cc
*cc
,
863 const struct ilo_dev
*dev
,
864 const struct ilo_state_cc
*old
,
865 struct ilo_state_cc_delta
*delta
)
869 if (memcmp(cc
->ds
, old
->ds
, sizeof(cc
->ds
))) {
870 if (ilo_dev_gen(dev
) >= ILO_GEN(8))
871 delta
->dirty
|= ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL
;
873 delta
->dirty
|= ILO_STATE_CC_DEPTH_STENCIL_STATE
;
876 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
877 if (cc
->blend
[0] != old
->blend
[0])
878 delta
->dirty
|= ILO_STATE_CC_3DSTATE_PS_BLEND
;
880 if (memcmp(&cc
->blend
[1], &old
->blend
[1],
881 sizeof(uint32_t) * (1 + 2 * cc
->blend_state_count
)))
882 delta
->dirty
|= ILO_STATE_CC_BLEND_STATE
;
883 } else if (memcmp(cc
->blend
, old
->blend
,
884 sizeof(uint32_t) * 2 * cc
->blend_state_count
)) {
885 delta
->dirty
|= ILO_STATE_CC_BLEND_STATE
;
888 if (memcmp(cc
->cc
, old
->cc
, sizeof(cc
->cc
)))
889 delta
->dirty
|= ILO_STATE_CC_COLOR_CALC_STATE
;