ilo: embed ilo_state_raster in ilo_rasterizer_state
[mesa.git] / src / gallium / drivers / ilo / core / ilo_state_3d_bottom.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "genhw/genhw.h"
29 #include "util/u_dual_blend.h"
30 #include "util/u_framebuffer.h"
31 #include "util/u_half.h"
32
33 #include "ilo_format.h"
34 #include "ilo_image.h"
35 #include "ilo_state_3d.h"
36 #include "../ilo_shader.h"
37
38 static void
39 fs_init_cso_gen6(const struct ilo_dev *dev,
40 const struct ilo_shader_state *fs,
41 struct ilo_shader_cso *cso)
42 {
43 int start_grf, input_count, sampler_count, max_threads;
44 uint32_t dw2, dw4, dw5, dw6;
45
46 ILO_DEV_ASSERT(dev, 6, 6);
47
48 start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
49 input_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT);
50 sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
51
52 /* see brwCreateContext() */
53 max_threads = (dev->gt == 2) ? 80 : 40;
54
55 dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
56 dw2 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
57
58 dw4 = start_grf << GEN6_WM_DW4_URB_GRF_START0__SHIFT |
59 0 << GEN6_WM_DW4_URB_GRF_START1__SHIFT |
60 0 << GEN6_WM_DW4_URB_GRF_START2__SHIFT;
61
62 dw5 = (max_threads - 1) << GEN6_WM_DW5_MAX_THREADS__SHIFT;
63
64 /*
65 * From the Sandy Bridge PRM, volume 2 part 1, page 275:
66 *
67 * "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that the
68 * PS kernel or color calculator has the ability to kill (discard)
69 * pixels or samples, other than due to depth or stencil testing.
70 * This bit is required to be ENABLED in the following situations:
71 *
72 * The API pixel shader program contains "killpix" or "discard"
73 * instructions, or other code in the pixel shader kernel that can
74 * cause the final pixel mask to differ from the pixel mask received
75 * on dispatch.
76 *
77 * A sampler with chroma key enabled with kill pixel mode is used by
78 * the pixel shader.
79 *
80 * Any render target has Alpha Test Enable or AlphaToCoverage Enable
81 * enabled.
82 *
83 * The pixel shader kernel generates and outputs oMask.
84 *
85 * Note: As ClipDistance clipping is fully supported in hardware and
86 * therefore not via PS instructions, there should be no need to
87 * ENABLE this bit due to ClipDistance clipping."
88 */
89 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
90 dw5 |= GEN6_WM_DW5_PS_KILL_PIXEL;
91
92 /*
93 * From the Sandy Bridge PRM, volume 2 part 1, page 275:
94 *
95 * "If a NULL Depth Buffer is selected, the Pixel Shader Computed Depth
96 * field must be set to disabled."
97 *
98 * TODO This is not checked yet.
99 */
100 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
101 dw5 |= GEN6_WM_DW5_PS_COMPUTE_DEPTH;
102
103 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
104 dw5 |= GEN6_WM_DW5_PS_USE_DEPTH;
105
106 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
107 dw5 |= GEN6_WM_DW5_PS_USE_W;
108
109 /*
110 * TODO set this bit only when
111 *
112 * a) fs writes colors and color is not masked, or
113 * b) fs writes depth, or
114 * c) fs or cc kills
115 */
116 if (true)
117 dw5 |= GEN6_WM_DW5_PS_DISPATCH_ENABLE;
118
119 assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
120 dw5 |= GEN6_PS_DISPATCH_8 << GEN6_WM_DW5_PS_DISPATCH_MODE__SHIFT;
121
122 dw6 = input_count << GEN6_WM_DW6_SF_ATTR_COUNT__SHIFT |
123 GEN6_POSOFFSET_NONE << GEN6_WM_DW6_PS_POSOFFSET__SHIFT;
124
125 STATIC_ASSERT(Elements(cso->payload) >= 4);
126 cso->payload[0] = dw2;
127 cso->payload[1] = dw4;
128 cso->payload[2] = dw5;
129 cso->payload[3] = dw6;
130 }
131
132 static uint32_t
133 fs_get_wm_gen7(const struct ilo_dev *dev,
134 const struct ilo_shader_state *fs)
135 {
136 uint32_t dw;
137
138 ILO_DEV_ASSERT(dev, 7, 7.5);
139
140 dw = 0;
141
142 /*
143 * TODO set this bit only when
144 *
145 * a) fs writes colors and color is not masked, or
146 * b) fs writes depth, or
147 * c) fs or cc kills
148 */
149 dw |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
150
151 /*
152 * From the Ivy Bridge PRM, volume 2 part 1, page 278:
153 *
154 * "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
155 * the PS kernel or color calculator has the ability to kill
156 * (discard) pixels or samples, other than due to depth or stencil
157 * testing. This bit is required to be ENABLED in the following
158 * situations:
159 *
160 * - The API pixel shader program contains "killpix" or "discard"
161 * instructions, or other code in the pixel shader kernel that
162 * can cause the final pixel mask to differ from the pixel mask
163 * received on dispatch.
164 *
165 * - A sampler with chroma key enabled with kill pixel mode is used
166 * by the pixel shader.
167 *
168 * - Any render target has Alpha Test Enable or AlphaToCoverage
169 * Enable enabled.
170 *
171 * - The pixel shader kernel generates and outputs oMask.
172 *
173 * Note: As ClipDistance clipping is fully supported in hardware
174 * and therefore not via PS instructions, there should be no need
175 * to ENABLE this bit due to ClipDistance clipping."
176 */
177 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
178 dw |= GEN7_WM_DW1_PS_KILL_PIXEL;
179
180 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
181 dw |= GEN7_PSCDEPTH_ON << GEN7_WM_DW1_PSCDEPTH__SHIFT;
182
183 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
184 dw |= GEN7_WM_DW1_PS_USE_DEPTH;
185
186 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
187 dw |= GEN7_WM_DW1_PS_USE_W;
188
189 return dw;
190 }
191
192 static void
193 fs_init_cso_gen7(const struct ilo_dev *dev,
194 const struct ilo_shader_state *fs,
195 struct ilo_shader_cso *cso)
196 {
197 int start_grf, sampler_count, max_threads;
198 uint32_t dw2, dw4, dw5;
199
200 ILO_DEV_ASSERT(dev, 7, 7.5);
201
202 start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
203 sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
204
205 dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
206 dw2 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
207
208 dw4 = GEN6_POSOFFSET_NONE << GEN7_PS_DW4_POSOFFSET__SHIFT;
209
210 /* see brwCreateContext() */
211 switch (ilo_dev_gen(dev)) {
212 case ILO_GEN(7.5):
213 max_threads = (dev->gt == 3) ? 408 : (dev->gt == 2) ? 204 : 102;
214 dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
215 dw4 |= 1 << GEN75_PS_DW4_SAMPLE_MASK__SHIFT;
216 break;
217 case ILO_GEN(7):
218 default:
219 max_threads = (dev->gt == 2) ? 172 : 48;
220 dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
221 break;
222 }
223
224 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
225 dw4 |= GEN7_PS_DW4_PUSH_CONSTANT_ENABLE;
226
227 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
228 dw4 |= GEN7_PS_DW4_ATTR_ENABLE;
229
230 assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
231 dw4 |= GEN6_PS_DISPATCH_8 << GEN7_PS_DW4_DISPATCH_MODE__SHIFT;
232
233 dw5 = start_grf << GEN7_PS_DW5_URB_GRF_START0__SHIFT |
234 0 << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
235 0 << GEN7_PS_DW5_URB_GRF_START2__SHIFT;
236
237 STATIC_ASSERT(Elements(cso->payload) >= 4);
238 cso->payload[0] = dw2;
239 cso->payload[1] = dw4;
240 cso->payload[2] = dw5;
241 cso->payload[3] = fs_get_wm_gen7(dev, fs);
242 }
243
244 static uint32_t
245 fs_get_psx_gen8(const struct ilo_dev *dev,
246 const struct ilo_shader_state *fs)
247 {
248 uint32_t dw;
249
250 ILO_DEV_ASSERT(dev, 8, 8);
251
252 dw = GEN8_PSX_DW1_VALID;
253
254 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
255 dw |= GEN8_PSX_DW1_KILL_PIXEL;
256 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
257 dw |= GEN7_PSCDEPTH_ON << GEN8_PSX_DW1_PSCDEPTH__SHIFT;
258 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
259 dw |= GEN8_PSX_DW1_USE_DEPTH;
260 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
261 dw |= GEN8_PSX_DW1_USE_W;
262 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
263 dw |= GEN8_PSX_DW1_ATTR_ENABLE;
264
265 return dw;
266 }
267
268 static void
269 fs_init_cso_gen8(const struct ilo_dev *dev,
270 const struct ilo_shader_state *fs,
271 struct ilo_shader_cso *cso)
272 {
273 int start_grf, sampler_count;
274 uint32_t dw3, dw6, dw7;
275
276 ILO_DEV_ASSERT(dev, 8, 8);
277
278 start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
279 sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
280
281 dw3 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
282 dw3 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
283
284 /* always 64? */
285 dw6 = (64 - 2) << GEN8_PS_DW6_MAX_THREADS__SHIFT |
286 GEN6_POSOFFSET_NONE << GEN8_PS_DW6_POSOFFSET__SHIFT;
287 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
288 dw6 |= GEN8_PS_DW6_PUSH_CONSTANT_ENABLE;
289
290 assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
291 dw6 |= GEN6_PS_DISPATCH_8 << GEN8_PS_DW6_DISPATCH_MODE__SHIFT;
292
293 dw7 = start_grf << GEN8_PS_DW7_URB_GRF_START0__SHIFT |
294 0 << GEN8_PS_DW7_URB_GRF_START1__SHIFT |
295 0 << GEN8_PS_DW7_URB_GRF_START2__SHIFT;
296
297 STATIC_ASSERT(Elements(cso->payload) >= 4);
298 cso->payload[0] = dw3;
299 cso->payload[1] = dw6;
300 cso->payload[2] = dw7;
301 cso->payload[3] = fs_get_psx_gen8(dev, fs);
302 }
303
304 void
305 ilo_gpe_init_fs_cso(const struct ilo_dev *dev,
306 const struct ilo_shader_state *fs,
307 struct ilo_shader_cso *cso)
308 {
309 if (ilo_dev_gen(dev) >= ILO_GEN(8))
310 fs_init_cso_gen8(dev, fs, cso);
311 else if (ilo_dev_gen(dev) >= ILO_GEN(7))
312 fs_init_cso_gen7(dev, fs, cso);
313 else
314 fs_init_cso_gen6(dev, fs, cso);
315 }
316
317 /**
318 * Translate a pipe logicop to the matching hardware logicop.
319 */
320 static int
321 gen6_translate_pipe_logicop(unsigned logicop)
322 {
323 switch (logicop) {
324 case PIPE_LOGICOP_CLEAR: return GEN6_LOGICOP_CLEAR;
325 case PIPE_LOGICOP_NOR: return GEN6_LOGICOP_NOR;
326 case PIPE_LOGICOP_AND_INVERTED: return GEN6_LOGICOP_AND_INVERTED;
327 case PIPE_LOGICOP_COPY_INVERTED: return GEN6_LOGICOP_COPY_INVERTED;
328 case PIPE_LOGICOP_AND_REVERSE: return GEN6_LOGICOP_AND_REVERSE;
329 case PIPE_LOGICOP_INVERT: return GEN6_LOGICOP_INVERT;
330 case PIPE_LOGICOP_XOR: return GEN6_LOGICOP_XOR;
331 case PIPE_LOGICOP_NAND: return GEN6_LOGICOP_NAND;
332 case PIPE_LOGICOP_AND: return GEN6_LOGICOP_AND;
333 case PIPE_LOGICOP_EQUIV: return GEN6_LOGICOP_EQUIV;
334 case PIPE_LOGICOP_NOOP: return GEN6_LOGICOP_NOOP;
335 case PIPE_LOGICOP_OR_INVERTED: return GEN6_LOGICOP_OR_INVERTED;
336 case PIPE_LOGICOP_COPY: return GEN6_LOGICOP_COPY;
337 case PIPE_LOGICOP_OR_REVERSE: return GEN6_LOGICOP_OR_REVERSE;
338 case PIPE_LOGICOP_OR: return GEN6_LOGICOP_OR;
339 case PIPE_LOGICOP_SET: return GEN6_LOGICOP_SET;
340 default:
341 assert(!"unknown logicop function");
342 return GEN6_LOGICOP_CLEAR;
343 }
344 }
345
346 /**
347 * Translate a pipe blend function to the matching hardware blend function.
348 */
349 static int
350 gen6_translate_pipe_blend(unsigned blend)
351 {
352 switch (blend) {
353 case PIPE_BLEND_ADD: return GEN6_BLENDFUNCTION_ADD;
354 case PIPE_BLEND_SUBTRACT: return GEN6_BLENDFUNCTION_SUBTRACT;
355 case PIPE_BLEND_REVERSE_SUBTRACT: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
356 case PIPE_BLEND_MIN: return GEN6_BLENDFUNCTION_MIN;
357 case PIPE_BLEND_MAX: return GEN6_BLENDFUNCTION_MAX;
358 default:
359 assert(!"unknown blend function");
360 return GEN6_BLENDFUNCTION_ADD;
361 };
362 }
363
364 /**
365 * Translate a pipe blend factor to the matching hardware blend factor.
366 */
367 static int
368 gen6_translate_pipe_blendfactor(unsigned blendfactor)
369 {
370 switch (blendfactor) {
371 case PIPE_BLENDFACTOR_ONE: return GEN6_BLENDFACTOR_ONE;
372 case PIPE_BLENDFACTOR_SRC_COLOR: return GEN6_BLENDFACTOR_SRC_COLOR;
373 case PIPE_BLENDFACTOR_SRC_ALPHA: return GEN6_BLENDFACTOR_SRC_ALPHA;
374 case PIPE_BLENDFACTOR_DST_ALPHA: return GEN6_BLENDFACTOR_DST_ALPHA;
375 case PIPE_BLENDFACTOR_DST_COLOR: return GEN6_BLENDFACTOR_DST_COLOR;
376 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
377 case PIPE_BLENDFACTOR_CONST_COLOR: return GEN6_BLENDFACTOR_CONST_COLOR;
378 case PIPE_BLENDFACTOR_CONST_ALPHA: return GEN6_BLENDFACTOR_CONST_ALPHA;
379 case PIPE_BLENDFACTOR_SRC1_COLOR: return GEN6_BLENDFACTOR_SRC1_COLOR;
380 case PIPE_BLENDFACTOR_SRC1_ALPHA: return GEN6_BLENDFACTOR_SRC1_ALPHA;
381 case PIPE_BLENDFACTOR_ZERO: return GEN6_BLENDFACTOR_ZERO;
382 case PIPE_BLENDFACTOR_INV_SRC_COLOR: return GEN6_BLENDFACTOR_INV_SRC_COLOR;
383 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
384 case PIPE_BLENDFACTOR_INV_DST_ALPHA: return GEN6_BLENDFACTOR_INV_DST_ALPHA;
385 case PIPE_BLENDFACTOR_INV_DST_COLOR: return GEN6_BLENDFACTOR_INV_DST_COLOR;
386 case PIPE_BLENDFACTOR_INV_CONST_COLOR: return GEN6_BLENDFACTOR_INV_CONST_COLOR;
387 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
388 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
389 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
390 default:
391 assert(!"unknown blend factor");
392 return GEN6_BLENDFACTOR_ONE;
393 };
394 }
395
396 /**
397 * Translate a pipe stencil op to the matching hardware stencil op.
398 */
399 static int
400 gen6_translate_pipe_stencil_op(unsigned stencil_op)
401 {
402 switch (stencil_op) {
403 case PIPE_STENCIL_OP_KEEP: return GEN6_STENCILOP_KEEP;
404 case PIPE_STENCIL_OP_ZERO: return GEN6_STENCILOP_ZERO;
405 case PIPE_STENCIL_OP_REPLACE: return GEN6_STENCILOP_REPLACE;
406 case PIPE_STENCIL_OP_INCR: return GEN6_STENCILOP_INCRSAT;
407 case PIPE_STENCIL_OP_DECR: return GEN6_STENCILOP_DECRSAT;
408 case PIPE_STENCIL_OP_INCR_WRAP: return GEN6_STENCILOP_INCR;
409 case PIPE_STENCIL_OP_DECR_WRAP: return GEN6_STENCILOP_DECR;
410 case PIPE_STENCIL_OP_INVERT: return GEN6_STENCILOP_INVERT;
411 default:
412 assert(!"unknown stencil op");
413 return GEN6_STENCILOP_KEEP;
414 }
415 }
416
417 static int
418 gen6_blend_factor_dst_alpha_forced_one(int factor)
419 {
420 switch (factor) {
421 case GEN6_BLENDFACTOR_DST_ALPHA:
422 return GEN6_BLENDFACTOR_ONE;
423 case GEN6_BLENDFACTOR_INV_DST_ALPHA:
424 case GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE:
425 return GEN6_BLENDFACTOR_ZERO;
426 default:
427 return factor;
428 }
429 }
430
431 static uint32_t
432 blend_get_rt_blend_enable_gen6(const struct ilo_dev *dev,
433 const struct pipe_rt_blend_state *rt,
434 bool dst_alpha_forced_one)
435 {
436 int rgb_src, rgb_dst, a_src, a_dst;
437 uint32_t dw;
438
439 ILO_DEV_ASSERT(dev, 6, 7.5);
440
441 if (!rt->blend_enable)
442 return 0;
443
444 rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor);
445 rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor);
446 a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor);
447 a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor);
448
449 if (dst_alpha_forced_one) {
450 rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src);
451 rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst);
452 a_src = gen6_blend_factor_dst_alpha_forced_one(a_src);
453 a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst);
454 }
455
456 dw = GEN6_RT_DW0_BLEND_ENABLE |
457 gen6_translate_pipe_blend(rt->alpha_func) << 26 |
458 a_src << 20 |
459 a_dst << 15 |
460 gen6_translate_pipe_blend(rt->rgb_func) << 11 |
461 rgb_src << 5 |
462 rgb_dst;
463
464 if (rt->rgb_func != rt->alpha_func ||
465 rgb_src != a_src || rgb_dst != a_dst)
466 dw |= GEN6_RT_DW0_INDEPENDENT_ALPHA_ENABLE;
467
468 return dw;
469 }
470
471 static uint32_t
472 blend_get_rt_blend_enable_gen8(const struct ilo_dev *dev,
473 const struct pipe_rt_blend_state *rt,
474 bool dst_alpha_forced_one,
475 bool *independent_alpha)
476 {
477 int rgb_src, rgb_dst, a_src, a_dst;
478 uint32_t dw;
479
480 ILO_DEV_ASSERT(dev, 8, 8);
481
482 if (!rt->blend_enable) {
483 *independent_alpha = false;
484 return 0;
485 }
486
487 rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor);
488 rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor);
489 a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor);
490 a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor);
491
492 if (dst_alpha_forced_one) {
493 rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src);
494 rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst);
495 a_src = gen6_blend_factor_dst_alpha_forced_one(a_src);
496 a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst);
497 }
498
499 dw = GEN8_RT_DW0_BLEND_ENABLE |
500 rgb_src << 26 |
501 rgb_dst << 21 |
502 gen6_translate_pipe_blend(rt->rgb_func) << 18 |
503 a_src << 13 |
504 a_dst << 8 |
505 gen6_translate_pipe_blend(rt->alpha_func) << 5;
506
507 *independent_alpha = (rt->rgb_func != rt->alpha_func ||
508 rgb_src != a_src ||
509 rgb_dst != a_dst);
510
511 return dw;
512 }
513
514 static void
515 blend_init_cso_gen6(const struct ilo_dev *dev,
516 const struct pipe_blend_state *state,
517 struct ilo_blend_state *blend,
518 unsigned index)
519 {
520 const struct pipe_rt_blend_state *rt = &state->rt[index];
521 struct ilo_blend_cso *cso = &blend->cso[index];
522
523 ILO_DEV_ASSERT(dev, 6, 7.5);
524
525 cso->payload[0] = 0;
526 cso->payload[1] = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
527 GEN6_RT_DW1_PRE_BLEND_CLAMP |
528 GEN6_RT_DW1_POST_BLEND_CLAMP;
529
530 if (!(rt->colormask & PIPE_MASK_A))
531 cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_A;
532 if (!(rt->colormask & PIPE_MASK_R))
533 cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_R;
534 if (!(rt->colormask & PIPE_MASK_G))
535 cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_G;
536 if (!(rt->colormask & PIPE_MASK_B))
537 cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_B;
538
539 /*
540 * From the Sandy Bridge PRM, volume 2 part 1, page 365:
541 *
542 * "Color Buffer Blending and Logic Ops must not be enabled
543 * simultaneously, or behavior is UNDEFINED."
544 *
545 * Since state->logicop_enable takes precedence over rt->blend_enable,
546 * no special care is needed.
547 */
548 if (state->logicop_enable) {
549 cso->dw_blend = 0;
550 cso->dw_blend_dst_alpha_forced_one = 0;
551 } else {
552 cso->dw_blend = blend_get_rt_blend_enable_gen6(dev, rt, false);
553 cso->dw_blend_dst_alpha_forced_one =
554 blend_get_rt_blend_enable_gen6(dev, rt, true);
555 }
556 }
557
558 static bool
559 blend_init_cso_gen8(const struct ilo_dev *dev,
560 const struct pipe_blend_state *state,
561 struct ilo_blend_state *blend,
562 unsigned index)
563 {
564 const struct pipe_rt_blend_state *rt = &state->rt[index];
565 struct ilo_blend_cso *cso = &blend->cso[index];
566 bool independent_alpha = false;
567
568 ILO_DEV_ASSERT(dev, 8, 8);
569
570 cso->payload[0] = 0;
571 cso->payload[1] = GEN8_RT_DW1_COLORCLAMP_RTFORMAT |
572 GEN8_RT_DW1_PRE_BLEND_CLAMP |
573 GEN8_RT_DW1_POST_BLEND_CLAMP;
574
575 if (!(rt->colormask & PIPE_MASK_A))
576 cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_A;
577 if (!(rt->colormask & PIPE_MASK_R))
578 cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_R;
579 if (!(rt->colormask & PIPE_MASK_G))
580 cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_G;
581 if (!(rt->colormask & PIPE_MASK_B))
582 cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_B;
583
584 if (state->logicop_enable) {
585 cso->dw_blend = 0;
586 cso->dw_blend_dst_alpha_forced_one = 0;
587 } else {
588 bool tmp[2];
589
590 cso->dw_blend = blend_get_rt_blend_enable_gen8(dev, rt, false, &tmp[0]);
591 cso->dw_blend_dst_alpha_forced_one =
592 blend_get_rt_blend_enable_gen8(dev, rt, true, &tmp[1]);
593
594 if (tmp[0] || tmp[1])
595 independent_alpha = true;
596 }
597
598 return independent_alpha;
599 }
600
601 static uint32_t
602 blend_get_logicop_enable_gen6(const struct ilo_dev *dev,
603 const struct pipe_blend_state *state)
604 {
605 ILO_DEV_ASSERT(dev, 6, 7.5);
606
607 if (!state->logicop_enable)
608 return 0;
609
610 return GEN6_RT_DW1_LOGICOP_ENABLE |
611 gen6_translate_pipe_logicop(state->logicop_func) << 18;
612 }
613
614 static uint32_t
615 blend_get_logicop_enable_gen8(const struct ilo_dev *dev,
616 const struct pipe_blend_state *state)
617 {
618 ILO_DEV_ASSERT(dev, 8, 8);
619
620 if (!state->logicop_enable)
621 return 0;
622
623 return GEN8_RT_DW1_LOGICOP_ENABLE |
624 gen6_translate_pipe_logicop(state->logicop_func) << 27;
625 }
626
627 static uint32_t
628 blend_get_alpha_mod_gen6(const struct ilo_dev *dev,
629 const struct pipe_blend_state *state,
630 bool dual_blend)
631 {
632 uint32_t dw = 0;
633
634 ILO_DEV_ASSERT(dev, 6, 7.5);
635
636 if (state->alpha_to_coverage) {
637 dw |= GEN6_RT_DW1_ALPHA_TO_COVERAGE;
638 if (ilo_dev_gen(dev) >= ILO_GEN(7))
639 dw |= GEN6_RT_DW1_ALPHA_TO_COVERAGE_DITHER;
640 }
641 /*
642 * From the Sandy Bridge PRM, volume 2 part 1, page 378:
643 *
644 * "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
645 * must be disabled."
646 */
647 if (state->alpha_to_one && !dual_blend)
648 dw |= GEN6_RT_DW1_ALPHA_TO_ONE;
649
650 return dw;
651 }
652
653 static uint32_t
654 blend_get_alpha_mod_gen8(const struct ilo_dev *dev,
655 const struct pipe_blend_state *state,
656 bool dual_blend)
657 {
658 uint32_t dw = 0;
659
660 ILO_DEV_ASSERT(dev, 8, 8);
661
662 if (state->alpha_to_coverage) {
663 dw |= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE |
664 GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER;
665 }
666
667 if (state->alpha_to_one && !dual_blend)
668 dw |= GEN8_BLEND_DW0_ALPHA_TO_ONE;
669
670 return dw;
671 }
672
673 static uint32_t
674 blend_get_ps_blend_gen8(const struct ilo_dev *dev, uint32_t rt_dw0)
675 {
676 int rgb_src, rgb_dst, a_src, a_dst;
677 uint32_t dw;
678
679 ILO_DEV_ASSERT(dev, 8, 8);
680
681 if (!(rt_dw0 & GEN8_RT_DW0_BLEND_ENABLE))
682 return 0;
683
684 a_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_ALPHA_FACTOR);
685 a_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_ALPHA_FACTOR);
686 rgb_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_COLOR_FACTOR);
687 rgb_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_COLOR_FACTOR);
688
689 dw = GEN8_PS_BLEND_DW1_BLEND_ENABLE;
690 dw |= GEN_SHIFT32(a_src, GEN8_PS_BLEND_DW1_SRC_ALPHA_FACTOR);
691 dw |= GEN_SHIFT32(a_dst, GEN8_PS_BLEND_DW1_DST_ALPHA_FACTOR);
692 dw |= GEN_SHIFT32(rgb_src, GEN8_PS_BLEND_DW1_SRC_COLOR_FACTOR);
693 dw |= GEN_SHIFT32(rgb_dst, GEN8_PS_BLEND_DW1_DST_COLOR_FACTOR);
694
695 if (a_src != rgb_src || a_dst != rgb_dst)
696 dw |= GEN8_PS_BLEND_DW1_INDEPENDENT_ALPHA_ENABLE;
697
698 return dw;
699 }
700
701 void
702 ilo_gpe_init_blend(const struct ilo_dev *dev,
703 const struct pipe_blend_state *state,
704 struct ilo_blend_state *blend)
705 {
706 unsigned i;
707
708 ILO_DEV_ASSERT(dev, 6, 8);
709
710 blend->dual_blend = (util_blend_state_is_dual(state, 0) &&
711 state->rt[0].blend_enable &&
712 !state->logicop_enable);
713 blend->alpha_to_coverage = state->alpha_to_coverage;
714
715 if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
716 bool independent_alpha;
717
718 blend->dw_alpha_mod =
719 blend_get_alpha_mod_gen8(dev, state, blend->dual_blend);
720 blend->dw_logicop = blend_get_logicop_enable_gen8(dev, state);
721 blend->dw_shared = (state->dither) ? GEN8_BLEND_DW0_DITHER_ENABLE : 0;
722
723 independent_alpha = blend_init_cso_gen8(dev, state, blend, 0);
724 if (independent_alpha)
725 blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
726
727 blend->dw_ps_blend = blend_get_ps_blend_gen8(dev,
728 blend->cso[0].dw_blend);
729 blend->dw_ps_blend_dst_alpha_forced_one = blend_get_ps_blend_gen8(dev,
730 blend->cso[0].dw_blend_dst_alpha_forced_one);
731
732 if (state->independent_blend_enable) {
733 for (i = 1; i < Elements(blend->cso); i++) {
734 independent_alpha = blend_init_cso_gen8(dev, state, blend, i);
735 if (independent_alpha)
736 blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
737 }
738 } else {
739 for (i = 1; i < Elements(blend->cso); i++)
740 blend->cso[i] = blend->cso[0];
741 }
742 } else {
743 blend->dw_alpha_mod =
744 blend_get_alpha_mod_gen6(dev, state, blend->dual_blend);
745 blend->dw_logicop = blend_get_logicop_enable_gen6(dev, state);
746 blend->dw_shared = (state->dither) ? GEN6_RT_DW1_DITHER_ENABLE : 0;
747
748 blend->dw_ps_blend = 0;
749 blend->dw_ps_blend_dst_alpha_forced_one = 0;
750
751 blend_init_cso_gen6(dev, state, blend, 0);
752 if (state->independent_blend_enable) {
753 for (i = 1; i < Elements(blend->cso); i++)
754 blend_init_cso_gen6(dev, state, blend, i);
755 } else {
756 for (i = 1; i < Elements(blend->cso); i++)
757 blend->cso[i] = blend->cso[0];
758 }
759 }
760 }
761
762 /**
763 * Translate a pipe DSA test function to the matching hardware compare
764 * function.
765 */
766 static int
767 gen6_translate_dsa_func(unsigned func)
768 {
769 switch (func) {
770 case PIPE_FUNC_NEVER: return GEN6_COMPAREFUNCTION_NEVER;
771 case PIPE_FUNC_LESS: return GEN6_COMPAREFUNCTION_LESS;
772 case PIPE_FUNC_EQUAL: return GEN6_COMPAREFUNCTION_EQUAL;
773 case PIPE_FUNC_LEQUAL: return GEN6_COMPAREFUNCTION_LEQUAL;
774 case PIPE_FUNC_GREATER: return GEN6_COMPAREFUNCTION_GREATER;
775 case PIPE_FUNC_NOTEQUAL: return GEN6_COMPAREFUNCTION_NOTEQUAL;
776 case PIPE_FUNC_GEQUAL: return GEN6_COMPAREFUNCTION_GEQUAL;
777 case PIPE_FUNC_ALWAYS: return GEN6_COMPAREFUNCTION_ALWAYS;
778 default:
779 assert(!"unknown depth/stencil/alpha test function");
780 return GEN6_COMPAREFUNCTION_NEVER;
781 }
782 }
783
784 static uint32_t
785 dsa_get_stencil_enable_gen6(const struct ilo_dev *dev,
786 const struct pipe_stencil_state *stencil0,
787 const struct pipe_stencil_state *stencil1)
788 {
789 uint32_t dw;
790
791 ILO_DEV_ASSERT(dev, 6, 7.5);
792
793 if (!stencil0->enabled)
794 return 0;
795
796 /*
797 * From the Sandy Bridge PRM, volume 2 part 1, page 359:
798 *
799 * "If the Depth Buffer is either undefined or does not have a surface
800 * format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate
801 * stencil buffer is disabled, Stencil Test Enable must be DISABLED"
802 *
803 * From the Sandy Bridge PRM, volume 2 part 1, page 370:
804 *
805 * "This field (Stencil Test Enable) cannot be enabled if
806 * Surface Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
807 *
808 * TODO We do not check these yet.
809 */
810 dw = GEN6_ZS_DW0_STENCIL_TEST_ENABLE |
811 gen6_translate_dsa_func(stencil0->func) << 28 |
812 gen6_translate_pipe_stencil_op(stencil0->fail_op) << 25 |
813 gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 22 |
814 gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 19;
815 if (stencil0->writemask)
816 dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
817
818 if (stencil1->enabled) {
819 dw |= GEN6_ZS_DW0_STENCIL1_ENABLE |
820 gen6_translate_dsa_func(stencil1->func) << 12 |
821 gen6_translate_pipe_stencil_op(stencil1->fail_op) << 9 |
822 gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 6 |
823 gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 3;
824 if (stencil1->writemask)
825 dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
826 }
827
828 return dw;
829 }
830
831 static uint32_t
832 dsa_get_stencil_enable_gen8(const struct ilo_dev *dev,
833 const struct pipe_stencil_state *stencil0,
834 const struct pipe_stencil_state *stencil1)
835 {
836 uint32_t dw;
837
838 ILO_DEV_ASSERT(dev, 8, 8);
839
840 if (!stencil0->enabled)
841 return 0;
842
843 dw = gen6_translate_pipe_stencil_op(stencil0->fail_op) << 29 |
844 gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 26 |
845 gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 23 |
846 gen6_translate_dsa_func(stencil0->func) << 8 |
847 GEN8_ZS_DW1_STENCIL_TEST_ENABLE;
848 if (stencil0->writemask)
849 dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
850
851 if (stencil1->enabled) {
852 dw |= gen6_translate_dsa_func(stencil1->func) << 20 |
853 gen6_translate_pipe_stencil_op(stencil1->fail_op) << 17 |
854 gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 14 |
855 gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 11 |
856 GEN8_ZS_DW1_STENCIL1_ENABLE;
857 if (stencil1->writemask)
858 dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
859 }
860
861 return dw;
862 }
863
864 static uint32_t
865 dsa_get_depth_enable_gen6(const struct ilo_dev *dev,
866 const struct pipe_depth_state *state)
867 {
868 uint32_t dw;
869
870 ILO_DEV_ASSERT(dev, 6, 7.5);
871
872 /*
873 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
874 *
875 * "Enabling the Depth Test function without defining a Depth Buffer is
876 * UNDEFINED."
877 *
878 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
879 *
880 * "A Depth Buffer must be defined before enabling writes to it, or
881 * operation is UNDEFINED."
882 *
883 * TODO We do not check these yet.
884 */
885 if (state->enabled) {
886 dw = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
887 gen6_translate_dsa_func(state->func) << 27;
888 } else {
889 dw = GEN6_COMPAREFUNCTION_ALWAYS << 27;
890 }
891
892 if (state->writemask)
893 dw |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
894
895 return dw;
896 }
897
898 static uint32_t
899 dsa_get_depth_enable_gen8(const struct ilo_dev *dev,
900 const struct pipe_depth_state *state)
901 {
902 uint32_t dw;
903
904 ILO_DEV_ASSERT(dev, 8, 8);
905
906 if (state->enabled) {
907 dw = GEN8_ZS_DW1_DEPTH_TEST_ENABLE |
908 gen6_translate_dsa_func(state->func) << 5;
909 } else {
910 dw = GEN6_COMPAREFUNCTION_ALWAYS << 5;
911 }
912
913 if (state->writemask)
914 dw |= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE;
915
916 return dw;
917 }
918
919 static uint32_t
920 dsa_get_alpha_enable_gen6(const struct ilo_dev *dev,
921 const struct pipe_alpha_state *state)
922 {
923 uint32_t dw;
924
925 ILO_DEV_ASSERT(dev, 6, 7.5);
926
927 if (!state->enabled)
928 return 0;
929
930 /* this will be ORed to BLEND_STATE */
931 dw = GEN6_RT_DW1_ALPHA_TEST_ENABLE |
932 gen6_translate_dsa_func(state->func) << 13;
933
934 return dw;
935 }
936
937 static uint32_t
938 dsa_get_alpha_enable_gen8(const struct ilo_dev *dev,
939 const struct pipe_alpha_state *state)
940 {
941 uint32_t dw;
942
943 ILO_DEV_ASSERT(dev, 8, 8);
944
945 if (!state->enabled)
946 return 0;
947
948 /* this will be ORed to BLEND_STATE */
949 dw = GEN8_BLEND_DW0_ALPHA_TEST_ENABLE |
950 gen6_translate_dsa_func(state->func) << 24;
951
952 return dw;
953 }
954
955 void
956 ilo_gpe_init_dsa(const struct ilo_dev *dev,
957 const struct pipe_depth_stencil_alpha_state *state,
958 struct ilo_dsa_state *dsa)
959 {
960 ILO_DEV_ASSERT(dev, 6, 8);
961
962 STATIC_ASSERT(Elements(dsa->payload) >= 3);
963
964 if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
965 const uint32_t dw_stencil = dsa_get_stencil_enable_gen8(dev,
966 &state->stencil[0], &state->stencil[1]);
967 const uint32_t dw_depth = dsa_get_depth_enable_gen8(dev, &state->depth);
968
969 assert(!(dw_stencil & dw_depth));
970 dsa->payload[0] = dw_stencil | dw_depth;
971
972 dsa->dw_blend_alpha = dsa_get_alpha_enable_gen8(dev, &state->alpha);
973 dsa->dw_ps_blend_alpha = (state->alpha.enabled) ?
974 GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE : 0;
975 } else {
976 dsa->payload[0] = dsa_get_stencil_enable_gen6(dev,
977 &state->stencil[0], &state->stencil[1]);
978 dsa->payload[2] = dsa_get_depth_enable_gen6(dev, &state->depth);
979
980 dsa->dw_blend_alpha = dsa_get_alpha_enable_gen6(dev, &state->alpha);
981 dsa->dw_ps_blend_alpha = 0;
982 }
983
984 dsa->payload[1] = state->stencil[0].valuemask << 24 |
985 state->stencil[0].writemask << 16 |
986 state->stencil[1].valuemask << 8 |
987 state->stencil[1].writemask;
988
989 dsa->alpha_ref = float_to_ubyte(state->alpha.ref_value);
990 }
991
992 static void
993 fb_set_blend_caps(const struct ilo_dev *dev,
994 enum pipe_format format,
995 struct ilo_fb_blend_caps *caps)
996 {
997 const struct util_format_description *desc =
998 util_format_description(format);
999 const int ch = util_format_get_first_non_void_channel(format);
1000
1001 memset(caps, 0, sizeof(*caps));
1002
1003 if (format == PIPE_FORMAT_NONE || desc->is_mixed)
1004 return;
1005
1006 caps->is_unorm = (ch >= 0 && desc->channel[ch].normalized &&
1007 desc->channel[ch].type == UTIL_FORMAT_TYPE_UNSIGNED &&
1008 desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB);
1009 caps->is_integer = util_format_is_pure_integer(format);
1010
1011 /*
1012 * From the Sandy Bridge PRM, volume 2 part 1, page 365:
1013 *
1014 * "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
1015 * variants), otherwise Logic Ops must be DISABLED."
1016 *
1017 * According to the classic driver, this is lifted on Gen8+.
1018 */
1019 caps->can_logicop = (ilo_dev_gen(dev) >= ILO_GEN(8) || caps->is_unorm);
1020
1021 /* no blending for pure integer formats */
1022 caps->can_blend = !caps->is_integer;
1023
1024 /*
1025 * From the Sandy Bridge PRM, volume 2 part 1, page 382:
1026 *
1027 * "Alpha Test can only be enabled if Pixel Shader outputs a float
1028 * alpha value."
1029 */
1030 caps->can_alpha_test = !caps->is_integer;
1031
1032 caps->dst_alpha_forced_one =
1033 (ilo_format_translate_render(dev, format) !=
1034 ilo_format_translate_color(dev, format));
1035
1036 /* sanity check */
1037 if (caps->dst_alpha_forced_one) {
1038 enum pipe_format render_format;
1039
1040 switch (format) {
1041 case PIPE_FORMAT_B8G8R8X8_UNORM:
1042 render_format = PIPE_FORMAT_B8G8R8A8_UNORM;
1043 break;
1044 default:
1045 render_format = PIPE_FORMAT_NONE;
1046 break;
1047 }
1048
1049 assert(ilo_format_translate_render(dev, format) ==
1050 ilo_format_translate_color(dev, render_format));
1051 }
1052 }
1053
1054 void
1055 ilo_gpe_set_fb(const struct ilo_dev *dev,
1056 const struct pipe_framebuffer_state *state,
1057 struct ilo_fb_state *fb)
1058 {
1059 const struct pipe_surface *first_surf = NULL;
1060 int i;
1061
1062 ILO_DEV_ASSERT(dev, 6, 8);
1063
1064 util_copy_framebuffer_state(&fb->state, state);
1065
1066 fb->has_integer_rt = false;
1067 for (i = 0; i < state->nr_cbufs; i++) {
1068 if (state->cbufs[i]) {
1069 fb_set_blend_caps(dev, state->cbufs[i]->format, &fb->blend_caps[i]);
1070
1071 fb->has_integer_rt |= fb->blend_caps[i].is_integer;
1072
1073 if (!first_surf)
1074 first_surf = state->cbufs[i];
1075 } else {
1076 fb_set_blend_caps(dev, PIPE_FORMAT_NONE, &fb->blend_caps[i]);
1077 }
1078 }
1079
1080 if (!first_surf && state->zsbuf)
1081 first_surf = state->zsbuf;
1082
1083 fb->num_samples = (first_surf) ? first_surf->texture->nr_samples : 1;
1084 if (!fb->num_samples)
1085 fb->num_samples = 1;
1086
1087 if (state->zsbuf) {
1088 const struct ilo_surface_cso *cso =
1089 (const struct ilo_surface_cso *) state->zsbuf;
1090
1091 fb->has_hiz = cso->u.zs.hiz_bo;
1092 fb->depth_offset_format =
1093 ilo_state_zs_get_depth_format(&cso->u.zs, dev);
1094 } else {
1095 fb->has_hiz = false;
1096 fb->depth_offset_format = GEN6_ZFORMAT_D32_FLOAT;
1097 }
1098
1099 /*
1100 * The PRMs list several restrictions when the framebuffer has more than
1101 * one surface. It seems they are actually lifted on GEN6+.
1102 */
1103 }