1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2015 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 "ilo_debug.h"
29 #include "ilo_state_cc.h"
30
31 static bool
cc_validate_gen6_stencil(const struct ilo_dev * dev,const struct ilo_state_cc_info * info)32 cc_validate_gen6_stencil(const struct ilo_dev *dev,
33 const struct ilo_state_cc_info *info)
34 {
35 const struct ilo_state_cc_stencil_info *stencil = &info->stencil;
36
37 ILO_DEV_ASSERT(dev, 6, 8);
38
39 /*
40 * From the Sandy Bridge PRM, volume 2 part 1, page 359:
41 *
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"
45 *
46 * From the Sandy Bridge PRM, volume 2 part 1, page 370:
47 *
48 * "This field (Stencil Test Enable) cannot be enabled if Surface
49 * Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
50 */
51 if (stencil->test_enable)
52 assert(stencil->cv_has_buffer);
53
54 return true;
55 }
56
57 static bool
cc_validate_gen6_depth(const struct ilo_dev * dev,const struct ilo_state_cc_info * info)58 cc_validate_gen6_depth(const struct ilo_dev *dev,
59 const struct ilo_state_cc_info *info)
60 {
61 const struct ilo_state_cc_depth_info *depth = &info->depth;
62
63 ILO_DEV_ASSERT(dev, 6, 8);
64
65 /*
66 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
67 *
68 * "Enabling the Depth Test function without defining a Depth Buffer is
69 * UNDEFINED."
70 *
71 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
72 *
73 * "A Depth Buffer must be defined before enabling writes to it, or
74 * operation is UNDEFINED."
75 */
76 if (depth->test_enable || depth->write_enable)
77 assert(depth->cv_has_buffer);
78
79 return true;
80 }
81
82 static bool
cc_set_gen6_DEPTH_STENCIL_STATE(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_info * info)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)
86 {
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;
91
92 ILO_DEV_ASSERT(dev, 6, 7.5);
93
94 if (!cc_validate_gen6_stencil(dev, info) ||
95 !cc_validate_gen6_depth(dev, info))
96 return false;
97
98 dw0 = 0;
99 dw1 = 0;
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;
106
107 dw0 |= GEN6_ZS_DW0_STENCIL_TEST_ENABLE;
108
109 if (stencil->twosided_enable) {
110 dw0 |= GEN6_ZS_DW0_STENCIL1_ENABLE;
111
112 back = &stencil->back;
113 back_p = ¶ms->stencil_back;
114 } else {
115 back = &stencil->front;
116 back_p = ¶ms->stencil_front;
117 }
118
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;
127
128 /*
129 * From the Ivy Bridge PRM, volume 2 part 1, page 363:
130 *
131 * "If this field (Stencil Buffer Write Enable) is enabled, Stencil
132 * Test Enable must also be enabled."
133 *
134 * This is different from depth write enable, which is independent from
135 * depth test enable.
136 */
137 if (front_p->write_mask || back_p->write_mask)
138 dw0 |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
139
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;
144 }
145
146 dw2 = 0;
147 if (depth->test_enable) {
148 dw2 |= GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
149 depth->test_func << GEN6_ZS_DW2_DEPTH_FUNC__SHIFT;
150 } else {
151 dw2 |= GEN6_COMPAREFUNCTION_ALWAYS << GEN6_ZS_DW2_DEPTH_FUNC__SHIFT;
152 }
153
154 /* independent from depth->test_enable */
155 if (depth->write_enable)
156 dw2 |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
157
158 STATIC_ASSERT(ARRAY_SIZE(cc->ds) >= 3);
159 cc->ds[0] = dw0;
160 cc->ds[1] = dw1;
161 cc->ds[2] = dw2;
162
163 return true;
164 }
165
166 static bool
cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_info * info)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)
170 {
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;
174 uint32_t dw1, dw2;
175
176 ILO_DEV_ASSERT(dev, 8, 8);
177
178 if (!cc_validate_gen6_stencil(dev, info) ||
179 !cc_validate_gen6_depth(dev, info))
180 return false;
181
182 dw1 = 0;
183 dw2 = 0;
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;
190
191 dw1 |= GEN8_ZS_DW1_STENCIL_TEST_ENABLE;
192
193 if (stencil->twosided_enable) {
194 dw1 |= GEN8_ZS_DW1_STENCIL1_ENABLE;
195
196 back = &stencil->back;
197 back_p = ¶ms->stencil_back;
198 } else {
199 back = &stencil->front;
200 back_p = ¶ms->stencil_front;
201 }
202
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;
211
212 if (front_p->write_mask || back_p->write_mask)
213 dw1 |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
214
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;
219 }
220
221 if (depth->test_enable) {
222 dw1 |= GEN8_ZS_DW1_DEPTH_TEST_ENABLE |
223 depth->test_func << GEN8_ZS_DW1_DEPTH_FUNC__SHIFT;
224 } else {
225 dw1 |= GEN6_COMPAREFUNCTION_ALWAYS << GEN8_ZS_DW1_DEPTH_FUNC__SHIFT;
226 }
227
228 if (depth->write_enable)
229 dw1 |= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE;
230
231 STATIC_ASSERT(ARRAY_SIZE(cc->ds) >= 2);
232 cc->ds[0] = dw1;
233 cc->ds[1] = dw2;
234
235 return true;
236 }
237
238 static bool
is_dual_source_blend_factor(enum gen_blend_factor factor)239 is_dual_source_blend_factor(enum gen_blend_factor factor)
240 {
241 switch (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:
246 return true;
247 default:
248 return false;
249 }
250 }
251
252 static bool
cc_get_gen6_dual_source_blending(const struct ilo_dev * dev,const struct ilo_state_cc_info * info)253 cc_get_gen6_dual_source_blending(const struct ilo_dev *dev,
254 const struct ilo_state_cc_info *info)
255 {
256 const struct ilo_state_cc_blend_info *blend = &info->blend;
257 bool dual_source_blending;
258 uint8_t i;
259
260 ILO_DEV_ASSERT(dev, 6, 8);
261
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)));
267
268 /*
269 * From the Ivy Bridge PRM, volume 2 part 1, page 356:
270 *
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
281 * must be disabled."
282 *
283 * From the Ivy Bridge PRM, volume 4 part 1, page 356:
284 *
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."
287 *
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
290 * disabled."
291 *
292 * Dual source blending must be enabled or disabled universally.
293 */
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)));
300 }
301
302 return dual_source_blending;
303 }
304
305 static bool
cc_validate_gen6_alpha(const struct ilo_dev * dev,const struct ilo_state_cc_info * info)306 cc_validate_gen6_alpha(const struct ilo_dev *dev,
307 const struct ilo_state_cc_info *info)
308 {
309 const struct ilo_state_cc_alpha_info *alpha = &info->alpha;
310
311 ILO_DEV_ASSERT(dev, 6, 8);
312
313 /*
314 * From the Sandy Bridge PRM, volume 2 part 1, page 356:
315 *
316 * "Alpha values from the pixel shader are treated as FLOAT32 format
317 * for computing the AlphaToCoverage Mask."
318 *
319 * From the Sandy Bridge PRM, volume 2 part 1, page 378:
320 *
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.
329 *
330 * The same coverage needs to be applied to all the RTs in MRT case."
331 *
332 * "If set (AlphaToOne Enable), Source0 Alpha is set to 1.0f after
333 * (possibly) being used to generate the AlphaToCoverage coverage
334 * mask.
335 *
336 * The same coverage needs to be applied to all the RTs in MRT case.
337 *
338 * If Dual Source Blending is enabled, this bit must be disabled."
339 *
340 * From the Sandy Bridge PRM, volume 2 part 1, page 382:
341 *
342 * "Alpha Test can only be enabled if Pixel Shader outputs a float
343 * alpha value.
344 *
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
350 * target."
351 *
352 * From the Sandy Bridge PRM, volume 4 part 1, page 194:
353 *
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
360 * scoreboard bits."
361 *
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.
366 */
367 if (alpha->alpha_to_coverage || alpha->alpha_to_one || alpha->test_enable)
368 assert(alpha->cv_float_source0_alpha);
369
370 /*
371 * From the Sandy Bridge PRM, volume 2 part 1, page 356:
372 *
373 * "[DevSNB]: When NumSamples = 1, AlphaToCoverage and AlphaTo
374 * Coverage Dither both must be disabled."
375 */
376 if (ilo_dev_gen(dev) == ILO_GEN(6) && alpha->alpha_to_coverage)
377 assert(alpha->cv_sample_count_one);
378
379 /*
380 * From the Sandy Bridge PRM, volume 2 part 1, page 378:
381 *
382 * "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
383 * must be disabled."
384 */
385 if (alpha->alpha_to_one)
386 assert(!cc_get_gen6_dual_source_blending(dev, info));
387
388 return true;
389 }
390
391 static bool
cc_validate_gen6_blend(const struct ilo_dev * dev,const struct ilo_state_cc_info * info)392 cc_validate_gen6_blend(const struct ilo_dev *dev,
393 const struct ilo_state_cc_info *info)
394 {
395 const struct ilo_state_cc_blend_info *blend = &info->blend;
396
397 ILO_DEV_ASSERT(dev, 6, 8);
398
399 assert(blend->rt_count <= ILO_STATE_CC_BLEND_MAX_RT_COUNT);
400
401 return true;
402 }
403
404 static enum gen_blend_factor
get_dst_alpha_one_blend_factor(enum gen_blend_factor factor,bool is_rgb)405 get_dst_alpha_one_blend_factor(enum gen_blend_factor factor, bool is_rgb)
406 {
407 switch (factor) {
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;
414 default:
415 return factor;
416 }
417 }
418
419 static void
cc_get_gen6_effective_rt(const struct ilo_dev * dev,const struct ilo_state_cc_info * info,uint8_t rt_index,struct ilo_state_cc_blend_rt_info * dst)420 cc_get_gen6_effective_rt(const struct ilo_dev *dev,
421 const struct ilo_state_cc_info *info,
422 uint8_t rt_index,
423 struct ilo_state_cc_blend_rt_info *dst)
424 {
425 const struct ilo_state_cc_blend_rt_info *rt = &info->blend.rt[rt_index];
426
427 if (rt->logicop_enable || rt->blend_enable ||
428 rt->argb_write_disables != 0xf)
429 assert(rt->cv_has_buffer);
430
431 /*
432 * From the Sandy Bridge PRM, volume 2 part 1, page 365:
433 *
434 * "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
435 * variants), otherwise Logic Ops must be DISABLED."
436 *
437 * From the Broadwell PRM, volume 7, page 671:
438 *
439 * "Logic Ops are supported on all blendable render targets and render
440 * targets with *INT formats."
441 */
442 if (ilo_dev_gen(dev) < ILO_GEN(8) && rt->logicop_enable)
443 assert(rt->cv_is_unorm);
444
445 /*
446 * From the Sandy Bridge PRM, volume 2 part 1, page 361:
447 *
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."
451 *
452 * From the Sandy Bridge PRM, volume 2 part 1, page 365:
453 *
454 * "Color Buffer Blending and Logic Ops must not be enabled
455 * simultaneously, or behavior is UNDEFINED."
456 */
457 if (rt->blend_enable)
458 assert(!rt->cv_is_integer && !rt->logicop_enable);
459
460 *dst = *rt;
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);
464
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;
471 }
472 } else {
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;
479 }
480 }
481
482 static bool
cc_set_gen6_BLEND_STATE(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_info * info)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)
486 {
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;
490 uint32_t dw0, dw1;
491 uint8_t i;
492
493 ILO_DEV_ASSERT(dev, 6, 7.5);
494
495 if (!cc_validate_gen6_alpha(dev, info) ||
496 !cc_validate_gen6_blend(dev, info))
497 return false;
498
499 /*
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
503 * unconditionally.
504 */
505 dw1 = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
506 GEN6_RT_DW1_PRE_BLEND_CLAMP |
507 GEN6_RT_DW1_POST_BLEND_CLAMP;
508
509 if (alpha->alpha_to_coverage) {
510 dw1 |= GEN6_RT_DW1_ALPHA_TO_COVERAGE;
511
512 /*
513 * From the Sandy Bridge PRM, volume 2 part 1, page 379:
514 *
515 * "[DevSNB]: This bit (AlphaToCoverage Dither Enable) must be
516 * disabled."
517 */
518 if (ilo_dev_gen(dev) >= ILO_GEN(7))
519 dw1 |= GEN6_RT_DW1_ALPHA_TO_COVERAGE_DITHER;
520 }
521
522 if (alpha->alpha_to_one)
523 dw1 |= GEN6_RT_DW1_ALPHA_TO_ONE;
524
525 if (alpha->test_enable) {
526 dw1 |= GEN6_RT_DW1_ALPHA_TEST_ENABLE |
527 alpha->test_func << GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT;
528 } else {
529 /*
530 * From the Ivy Bridge PRM, volume 2 part 1, page 371:
531 *
532 * "When Alpha Test is disabled, Alpha Test Function must be
533 * COMPAREFUNCTION_ALWAYS."
534 */
535 dw1 |= GEN6_COMPAREFUNCTION_ALWAYS <<
536 GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT;
537 }
538
539 if (blend->dither_enable)
540 dw1 |= GEN6_RT_DW1_DITHER_ENABLE;
541
542 dw1_invariant = dw1;
543
544 for (i = 0; i < blend->rt_count; i++) {
545 struct ilo_state_cc_blend_rt_info rt;
546
547 cc_get_gen6_effective_rt(dev, info, i, &rt);
548
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;
556
557 if (rt.blend_enable) {
558 dw0 |= GEN6_RT_DW0_BLEND_ENABLE;
559
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;
564 }
565
566 dw1 = dw1_invariant |
567 rt.argb_write_disables << GEN6_RT_DW1_WRITE_DISABLES__SHIFT;
568
569 if (rt.logicop_enable) {
570 dw1 |= GEN6_RT_DW1_LOGICOP_ENABLE |
571 rt.logicop_func << GEN6_RT_DW1_LOGICOP_FUNC__SHIFT;
572 }
573
574 dw_rt[2 * i + 0] = dw0;
575 dw_rt[2 * i + 1] = dw1;
576 }
577
578
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;
582
583 return true;
584 }
585
586 static bool
cc_set_gen8_BLEND_STATE(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_info * info)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)
590 {
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;
595 uint8_t i;
596
597 ILO_DEV_ASSERT(dev, 8, 8);
598
599 if (!cc_validate_gen6_alpha(dev, info) ||
600 !cc_validate_gen6_blend(dev, info))
601 return false;
602
603 indep_alpha_enable = false;
604 for (i = 0; i < blend->rt_count; i++) {
605 struct ilo_state_cc_blend_rt_info rt;
606
607 cc_get_gen6_effective_rt(dev, info, i, &rt);
608
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;
616
617 if (rt.blend_enable) {
618 dw0 |= GEN8_RT_DW0_BLEND_ENABLE;
619
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;
624 }
625
626 dw1 = GEN8_RT_DW1_COLORCLAMP_RTFORMAT |
627 GEN8_RT_DW1_PRE_BLEND_CLAMP |
628 GEN8_RT_DW1_POST_BLEND_CLAMP;
629
630 if (rt.logicop_enable) {
631 dw1 |= GEN8_RT_DW1_LOGICOP_ENABLE |
632 rt.logicop_func << GEN8_RT_DW1_LOGICOP_FUNC__SHIFT;
633 }
634
635 dw_rt[2 * i + 0] = dw0;
636 dw_rt[2 * i + 1] = dw1;
637 }
638
639 dw0 = 0;
640
641 if (alpha->alpha_to_coverage) {
642 dw0 |= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE |
643 GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER;
644 }
645
646 if (indep_alpha_enable)
647 dw0 |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
648
649 if (alpha->alpha_to_one)
650 dw0 |= GEN8_BLEND_DW0_ALPHA_TO_ONE;
651
652 if (alpha->test_enable) {
653 dw0 |= GEN8_BLEND_DW0_ALPHA_TEST_ENABLE |
654 alpha->test_func << GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT;
655 } else {
656 dw0 |= GEN6_COMPAREFUNCTION_ALWAYS <<
657 GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT;
658 }
659
660 if (blend->dither_enable)
661 dw0 |= GEN8_BLEND_DW0_DITHER_ENABLE;
662
663 STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= 2 + ARRAY_SIZE(dw_rt));
664 cc->blend[1] = dw0;
665 memcpy(&cc->blend[2], dw_rt, sizeof(uint32_t) * 2 * blend->rt_count);
666 cc->blend_state_count = info->blend.rt_count;
667
668 return true;
669 }
670
671 static bool
cc_set_gen8_3DSTATE_PS_BLEND(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_info * info)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)
675 {
676 const struct ilo_state_cc_alpha_info *alpha = &info->alpha;
677 const struct ilo_state_cc_blend_info *blend = &info->blend;
678 uint32_t dw1;
679
680 ILO_DEV_ASSERT(dev, 8, 8);
681
682 dw1 = 0;
683
684 if (alpha->alpha_to_coverage)
685 dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE;
686
687 if (alpha->test_enable)
688 dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE;
689
690 if (blend->rt_count) {
691 struct ilo_state_cc_blend_rt_info rt0;
692 uint8_t i;
693
694 cc_get_gen6_effective_rt(dev, info, 0, &rt0);
695
696 /* 0x0 is reserved for blend factors and we have to set them all */
697 dw1 |= rt0.a_src << GEN8_PS_BLEND_DW1_RT0_SRC_ALPHA_FACTOR__SHIFT |
698 rt0.a_dst << GEN8_PS_BLEND_DW1_RT0_DST_ALPHA_FACTOR__SHIFT |
699 rt0.rgb_src << GEN8_PS_BLEND_DW1_RT0_SRC_COLOR_FACTOR__SHIFT |
700 rt0.rgb_dst << GEN8_PS_BLEND_DW1_RT0_DST_COLOR_FACTOR__SHIFT;
701
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;
705 break;
706 }
707 }
708
709 if (rt0.blend_enable) {
710 dw1 |= GEN8_PS_BLEND_DW1_RT0_BLEND_ENABLE;
711
712 if (rt0.a_src != rt0.rgb_src || rt0.a_dst != rt0.rgb_dst)
713 dw1 |= GEN8_PS_BLEND_DW1_RT0_INDEPENDENT_ALPHA_ENABLE;
714 }
715 }
716
717 STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= 1);
718 cc->blend[0] = dw1;
719
720 return true;
721 }
722
723 static bool
cc_params_set_gen6_COLOR_CALC_STATE(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_params_info * params)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)
727 {
728 uint32_t dw0;
729
730 ILO_DEV_ASSERT(dev, 6, 8);
731
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;
735
736 STATIC_ASSERT(ARRAY_SIZE(cc->cc) >= 6);
737 cc->cc[0] = dw0;
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]);
743
744 return true;
745 }
746
747 bool
ilo_state_cc_init(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_info * info)748 ilo_state_cc_init(struct ilo_state_cc *cc,
749 const struct ilo_dev *dev,
750 const struct ilo_state_cc_info *info)
751 {
752 assert(ilo_is_zeroed(cc, sizeof(*cc)));
753 return ilo_state_cc_set_info(cc, dev, info);
754 }
755
756 bool
ilo_state_cc_set_info(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_info * 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)
760 {
761 bool ret = true;
762
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);
767 } else {
768 ret &= cc_set_gen6_DEPTH_STENCIL_STATE(cc, dev, info);
769 ret &= cc_set_gen6_BLEND_STATE(cc, dev, info);
770 }
771
772 ret &= cc_params_set_gen6_COLOR_CALC_STATE(cc, dev, &info->params);
773
774 assert(ret);
775
776 return ret;
777 }
778
779 bool
ilo_state_cc_set_params(struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc_params_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)
783 {
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];
788
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;
796
797 if (front_p->write_mask || back_p->write_mask)
798 dw1 |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
799 else
800 dw1 &= ~GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
801
802 dw2 =
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;
807 }
808
809 cc->ds[0] = dw1;
810 cc->ds[1] = dw2;
811 } else {
812 uint32_t dw0 = cc->ds[0];
813 uint32_t dw1 = cc->ds[1];
814
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;
822
823 if (front_p->write_mask || back_p->write_mask)
824 dw0 |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
825 else
826 dw0 &= ~GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
827
828 dw1 =
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;
833 }
834
835 cc->ds[0] = dw0;
836 cc->ds[1] = dw1;
837 }
838
839 /* modify COLOR_CALC_STATE */
840 cc_params_set_gen6_COLOR_CALC_STATE(cc, dev, params);
841
842 return true;
843 }
844
845 void
ilo_state_cc_full_delta(const struct ilo_state_cc * cc,const struct ilo_dev * dev,struct ilo_state_cc_delta * delta)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)
849 {
850 delta->dirty = ILO_STATE_CC_BLEND_STATE |
851 ILO_STATE_CC_COLOR_CALC_STATE;
852
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;
856 } else {
857 delta->dirty |= ILO_STATE_CC_DEPTH_STENCIL_STATE;
858 }
859 }
860
861 void
ilo_state_cc_get_delta(const struct ilo_state_cc * cc,const struct ilo_dev * dev,const struct ilo_state_cc * old,struct ilo_state_cc_delta * delta)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)
866 {
867 delta->dirty = 0;
868
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;
872 else
873 delta->dirty |= ILO_STATE_CC_DEPTH_STENCIL_STATE;
874 }
875
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;
879
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;
886 }
887
888 if (memcmp(cc->cc, old->cc, sizeof(cc->cc)))
889 delta->dirty |= ILO_STATE_CC_COLOR_CALC_STATE;
890 }
891