2 * Copyright © 2015 Broadcom
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * Implements most of the fixed function fragment pipeline in shader code.
27 * VC4 doesn't have any hardware support for blending, alpha test, logic ops,
28 * or color mask. Instead, you read the current contents of the destination
29 * from the tile buffer after having waited for the scoreboard (which is
30 * handled by vc4_qpu_emit.c), then do math using your output color and that
31 * destination value, and update the output color appropriately.
33 * Once this pass is done, the color write will either have one component (for
34 * single sample) with packed argb8888, or 4 components with the per-sample
39 * Lowers fixed-function blending to a load of the destination color and a
40 * series of ALU operations before the store of the output.
42 #include "util/u_format.h"
44 #include "compiler/nir/nir_builder.h"
45 #include "vc4_context.h"
48 blend_depends_on_dst_color(struct vc4_compile
*c
)
50 return (c
->fs_key
->blend
.blend_enable
||
51 c
->fs_key
->blend
.colormask
!= 0xf ||
52 c
->fs_key
->logicop_func
!= PIPE_LOGICOP_COPY
);
55 /** Emits a load of the previous fragment color from the tile buffer. */
57 vc4_nir_get_dst_color(nir_builder
*b
, int sample
)
59 nir_intrinsic_instr
*load
=
60 nir_intrinsic_instr_create(b
->shader
,
61 nir_intrinsic_load_input
);
62 load
->num_components
= 1;
63 load
->const_index
[0] = VC4_NIR_TLB_COLOR_READ_INPUT
+ sample
;
64 load
->src
[0] = nir_src_for_ssa(nir_imm_int(b
, 0));
65 nir_ssa_dest_init(&load
->instr
, &load
->dest
, 1, NULL
);
66 nir_builder_instr_insert(b
, &load
->instr
);
67 return &load
->dest
.ssa
;
71 vc4_nir_srgb_decode(nir_builder
*b
, nir_ssa_def
*srgb
)
73 nir_ssa_def
*is_low
= nir_flt(b
, srgb
, nir_imm_float(b
, 0.04045));
74 nir_ssa_def
*low
= nir_fmul(b
, srgb
, nir_imm_float(b
, 1.0 / 12.92));
75 nir_ssa_def
*high
= nir_fpow(b
,
78 nir_imm_float(b
, 0.055)),
79 nir_imm_float(b
, 1.0 / 1.055)),
80 nir_imm_float(b
, 2.4));
82 return nir_bcsel(b
, is_low
, low
, high
);
86 vc4_nir_srgb_encode(nir_builder
*b
, nir_ssa_def
*linear
)
88 nir_ssa_def
*is_low
= nir_flt(b
, linear
, nir_imm_float(b
, 0.0031308));
89 nir_ssa_def
*low
= nir_fmul(b
, linear
, nir_imm_float(b
, 12.92));
90 nir_ssa_def
*high
= nir_fsub(b
,
92 nir_imm_float(b
, 1.055),
95 nir_imm_float(b
, 0.41666))),
96 nir_imm_float(b
, 0.055));
98 return nir_bcsel(b
, is_low
, low
, high
);
102 vc4_blend_channel_f(nir_builder
*b
,
109 case PIPE_BLENDFACTOR_ONE
:
110 return nir_imm_float(b
, 1.0);
111 case PIPE_BLENDFACTOR_SRC_COLOR
:
113 case PIPE_BLENDFACTOR_SRC_ALPHA
:
115 case PIPE_BLENDFACTOR_DST_ALPHA
:
117 case PIPE_BLENDFACTOR_DST_COLOR
:
119 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
124 nir_imm_float(b
, 1.0),
127 return nir_imm_float(b
, 1.0);
129 case PIPE_BLENDFACTOR_CONST_COLOR
:
130 return vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_X
+ channel
);
131 case PIPE_BLENDFACTOR_CONST_ALPHA
:
132 return vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_W
);
133 case PIPE_BLENDFACTOR_ZERO
:
134 return nir_imm_float(b
, 0.0);
135 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
136 return nir_fsub(b
, nir_imm_float(b
, 1.0), src
[channel
]);
137 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
138 return nir_fsub(b
, nir_imm_float(b
, 1.0), src
[3]);
139 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
140 return nir_fsub(b
, nir_imm_float(b
, 1.0), dst
[3]);
141 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
142 return nir_fsub(b
, nir_imm_float(b
, 1.0), dst
[channel
]);
143 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
144 return nir_fsub(b
, nir_imm_float(b
, 1.0),
145 vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_X
+ channel
));
146 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
147 return nir_fsub(b
, nir_imm_float(b
, 1.0),
148 vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_W
));
151 case PIPE_BLENDFACTOR_SRC1_COLOR
:
152 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
153 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
154 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
156 fprintf(stderr
, "Unknown blend factor %d\n", factor
);
157 return nir_imm_float(b
, 1.0);
162 vc4_nir_set_packed_chan(nir_builder
*b
, nir_ssa_def
*src0
, nir_ssa_def
*src1
,
165 unsigned chan_mask
= 0xff << (chan
* 8);
167 nir_iand(b
, src0
, nir_imm_int(b
, ~chan_mask
)),
168 nir_iand(b
, src1
, nir_imm_int(b
, chan_mask
)));
172 vc4_blend_channel_i(nir_builder
*b
,
181 case PIPE_BLENDFACTOR_ONE
:
182 return nir_imm_int(b
, ~0);
183 case PIPE_BLENDFACTOR_SRC_COLOR
:
185 case PIPE_BLENDFACTOR_SRC_ALPHA
:
187 case PIPE_BLENDFACTOR_DST_ALPHA
:
189 case PIPE_BLENDFACTOR_DST_COLOR
:
191 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
192 return vc4_nir_set_packed_chan(b
,
198 case PIPE_BLENDFACTOR_CONST_COLOR
:
199 return vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_RGBA
);
200 case PIPE_BLENDFACTOR_CONST_ALPHA
:
201 return vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_AAAA
);
202 case PIPE_BLENDFACTOR_ZERO
:
203 return nir_imm_int(b
, 0);
204 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
205 return nir_inot(b
, src
);
206 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
207 return nir_inot(b
, src_a
);
208 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
209 return nir_inot(b
, dst_a
);
210 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
211 return nir_inot(b
, dst
);
212 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
213 return nir_inot(b
, vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_RGBA
));
214 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
215 return nir_inot(b
, vc4_nir_get_state_uniform(b
, QUNIFORM_BLEND_CONST_COLOR_AAAA
));
218 case PIPE_BLENDFACTOR_SRC1_COLOR
:
219 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
220 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
221 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
223 fprintf(stderr
, "Unknown blend factor %d\n", factor
);
224 return nir_imm_int(b
, ~0);
229 vc4_blend_func_f(nir_builder
*b
, nir_ssa_def
*src
, nir_ssa_def
*dst
,
234 return nir_fadd(b
, src
, dst
);
235 case PIPE_BLEND_SUBTRACT
:
236 return nir_fsub(b
, src
, dst
);
237 case PIPE_BLEND_REVERSE_SUBTRACT
:
238 return nir_fsub(b
, dst
, src
);
240 return nir_fmin(b
, src
, dst
);
242 return nir_fmax(b
, src
, dst
);
246 fprintf(stderr
, "Unknown blend func %d\n", func
);
253 vc4_blend_func_i(nir_builder
*b
, nir_ssa_def
*src
, nir_ssa_def
*dst
,
258 return nir_usadd_4x8(b
, src
, dst
);
259 case PIPE_BLEND_SUBTRACT
:
260 return nir_ussub_4x8(b
, src
, dst
);
261 case PIPE_BLEND_REVERSE_SUBTRACT
:
262 return nir_ussub_4x8(b
, dst
, src
);
264 return nir_umin_4x8(b
, src
, dst
);
266 return nir_umax_4x8(b
, src
, dst
);
270 fprintf(stderr
, "Unknown blend func %d\n", func
);
277 vc4_do_blending_f(struct vc4_compile
*c
, nir_builder
*b
, nir_ssa_def
**result
,
278 nir_ssa_def
**src_color
, nir_ssa_def
**dst_color
)
280 struct pipe_rt_blend_state
*blend
= &c
->fs_key
->blend
;
282 if (!blend
->blend_enable
) {
283 for (int i
= 0; i
< 4; i
++)
284 result
[i
] = src_color
[i
];
288 /* Clamp the src color to [0, 1]. Dest is already clamped. */
289 for (int i
= 0; i
< 4; i
++)
290 src_color
[i
] = nir_fsat(b
, src_color
[i
]);
292 nir_ssa_def
*src_blend
[4], *dst_blend
[4];
293 for (int i
= 0; i
< 4; i
++) {
294 int src_factor
= ((i
!= 3) ? blend
->rgb_src_factor
:
295 blend
->alpha_src_factor
);
296 int dst_factor
= ((i
!= 3) ? blend
->rgb_dst_factor
:
297 blend
->alpha_dst_factor
);
298 src_blend
[i
] = nir_fmul(b
, src_color
[i
],
299 vc4_blend_channel_f(b
,
300 src_color
, dst_color
,
302 dst_blend
[i
] = nir_fmul(b
, dst_color
[i
],
303 vc4_blend_channel_f(b
,
304 src_color
, dst_color
,
308 for (int i
= 0; i
< 4; i
++) {
309 result
[i
] = vc4_blend_func_f(b
, src_blend
[i
], dst_blend
[i
],
310 ((i
!= 3) ? blend
->rgb_func
:
316 vc4_nir_splat(nir_builder
*b
, nir_ssa_def
*src
)
318 nir_ssa_def
*or1
= nir_ior(b
, src
, nir_ishl(b
, src
, nir_imm_int(b
, 8)));
319 return nir_ior(b
, or1
, nir_ishl(b
, or1
, nir_imm_int(b
, 16)));
323 vc4_do_blending_i(struct vc4_compile
*c
, nir_builder
*b
,
324 nir_ssa_def
*src_color
, nir_ssa_def
*dst_color
,
325 nir_ssa_def
*src_float_a
)
327 struct pipe_rt_blend_state
*blend
= &c
->fs_key
->blend
;
329 if (!blend
->blend_enable
)
332 enum pipe_format color_format
= c
->fs_key
->color_format
;
333 const uint8_t *format_swiz
= vc4_get_format_swizzle(color_format
);
334 nir_ssa_def
*imm_0xff
= nir_imm_int(b
, 0xff);
335 nir_ssa_def
*src_a
= nir_pack_unorm_4x8(b
, src_float_a
);
338 for (alpha_chan
= 0; alpha_chan
< 4; alpha_chan
++) {
339 if (format_swiz
[alpha_chan
] == 3)
342 if (alpha_chan
!= 4) {
343 nir_ssa_def
*shift
= nir_imm_int(b
, alpha_chan
* 8);
344 dst_a
= vc4_nir_splat(b
, nir_iand(b
, nir_ushr(b
, dst_color
,
347 dst_a
= nir_imm_int(b
, ~0);
350 nir_ssa_def
*src_factor
= vc4_blend_channel_i(b
,
351 src_color
, dst_color
,
353 blend
->rgb_src_factor
,
355 nir_ssa_def
*dst_factor
= vc4_blend_channel_i(b
,
356 src_color
, dst_color
,
358 blend
->rgb_dst_factor
,
361 if (alpha_chan
!= 4 &&
362 blend
->alpha_src_factor
!= blend
->rgb_src_factor
) {
363 nir_ssa_def
*src_alpha_factor
=
364 vc4_blend_channel_i(b
,
365 src_color
, dst_color
,
367 blend
->alpha_src_factor
,
369 src_factor
= vc4_nir_set_packed_chan(b
, src_factor
,
373 if (alpha_chan
!= 4 &&
374 blend
->alpha_dst_factor
!= blend
->rgb_dst_factor
) {
375 nir_ssa_def
*dst_alpha_factor
=
376 vc4_blend_channel_i(b
,
377 src_color
, dst_color
,
379 blend
->alpha_dst_factor
,
381 dst_factor
= vc4_nir_set_packed_chan(b
, dst_factor
,
385 nir_ssa_def
*src_blend
= nir_umul_unorm_4x8(b
, src_color
, src_factor
);
386 nir_ssa_def
*dst_blend
= nir_umul_unorm_4x8(b
, dst_color
, dst_factor
);
388 nir_ssa_def
*result
=
389 vc4_blend_func_i(b
, src_blend
, dst_blend
, blend
->rgb_func
);
390 if (alpha_chan
!= 4 && blend
->alpha_func
!= blend
->rgb_func
) {
391 nir_ssa_def
*result_a
= vc4_blend_func_i(b
,
395 result
= vc4_nir_set_packed_chan(b
, result
, result_a
,
402 vc4_logicop(nir_builder
*b
, int logicop_func
,
403 nir_ssa_def
*src
, nir_ssa_def
*dst
)
405 switch (logicop_func
) {
406 case PIPE_LOGICOP_CLEAR
:
407 return nir_imm_int(b
, 0);
408 case PIPE_LOGICOP_NOR
:
409 return nir_inot(b
, nir_ior(b
, src
, dst
));
410 case PIPE_LOGICOP_AND_INVERTED
:
411 return nir_iand(b
, nir_inot(b
, src
), dst
);
412 case PIPE_LOGICOP_COPY_INVERTED
:
413 return nir_inot(b
, src
);
414 case PIPE_LOGICOP_AND_REVERSE
:
415 return nir_iand(b
, src
, nir_inot(b
, dst
));
416 case PIPE_LOGICOP_INVERT
:
417 return nir_inot(b
, dst
);
418 case PIPE_LOGICOP_XOR
:
419 return nir_ixor(b
, src
, dst
);
420 case PIPE_LOGICOP_NAND
:
421 return nir_inot(b
, nir_iand(b
, src
, dst
));
422 case PIPE_LOGICOP_AND
:
423 return nir_iand(b
, src
, dst
);
424 case PIPE_LOGICOP_EQUIV
:
425 return nir_inot(b
, nir_ixor(b
, src
, dst
));
426 case PIPE_LOGICOP_NOOP
:
428 case PIPE_LOGICOP_OR_INVERTED
:
429 return nir_ior(b
, nir_inot(b
, src
), dst
);
430 case PIPE_LOGICOP_OR_REVERSE
:
431 return nir_ior(b
, src
, nir_inot(b
, dst
));
432 case PIPE_LOGICOP_OR
:
433 return nir_ior(b
, src
, dst
);
434 case PIPE_LOGICOP_SET
:
435 return nir_imm_int(b
, ~0);
437 fprintf(stderr
, "Unknown logic op %d\n", logicop_func
);
439 case PIPE_LOGICOP_COPY
:
445 vc4_nir_pipe_compare_func(nir_builder
*b
, int func
,
446 nir_ssa_def
*src0
, nir_ssa_def
*src1
)
450 fprintf(stderr
, "Unknown compare func %d\n", func
);
452 case PIPE_FUNC_NEVER
:
453 return nir_imm_int(b
, 0);
454 case PIPE_FUNC_ALWAYS
:
455 return nir_imm_int(b
, ~0);
456 case PIPE_FUNC_EQUAL
:
457 return nir_feq(b
, src0
, src1
);
458 case PIPE_FUNC_NOTEQUAL
:
459 return nir_fne(b
, src0
, src1
);
460 case PIPE_FUNC_GREATER
:
461 return nir_flt(b
, src1
, src0
);
462 case PIPE_FUNC_GEQUAL
:
463 return nir_fge(b
, src0
, src1
);
465 return nir_flt(b
, src0
, src1
);
466 case PIPE_FUNC_LEQUAL
:
467 return nir_fge(b
, src1
, src0
);
472 vc4_nir_emit_alpha_test_discard(struct vc4_compile
*c
, nir_builder
*b
,
475 if (!c
->fs_key
->alpha_test
)
478 nir_ssa_def
*alpha_ref
=
479 vc4_nir_get_state_uniform(b
, QUNIFORM_ALPHA_REF
);
480 nir_ssa_def
*condition
=
481 vc4_nir_pipe_compare_func(b
, c
->fs_key
->alpha_test_func
,
484 nir_intrinsic_instr
*discard
=
485 nir_intrinsic_instr_create(b
->shader
,
486 nir_intrinsic_discard_if
);
487 discard
->num_components
= 1;
488 discard
->src
[0] = nir_src_for_ssa(nir_inot(b
, condition
));
489 nir_builder_instr_insert(b
, &discard
->instr
);
493 vc4_nir_swizzle_and_pack(struct vc4_compile
*c
, nir_builder
*b
,
494 nir_ssa_def
**colors
)
496 enum pipe_format color_format
= c
->fs_key
->color_format
;
497 const uint8_t *format_swiz
= vc4_get_format_swizzle(color_format
);
499 nir_ssa_def
*swizzled
[4];
500 for (int i
= 0; i
< 4; i
++) {
501 swizzled
[i
] = vc4_nir_get_swizzled_channel(b
, colors
,
505 return nir_pack_unorm_4x8(b
,
507 swizzled
[0], swizzled
[1],
508 swizzled
[2], swizzled
[3]));
513 vc4_nir_blend_pipeline(struct vc4_compile
*c
, nir_builder
*b
, nir_ssa_def
*src
,
516 enum pipe_format color_format
= c
->fs_key
->color_format
;
517 const uint8_t *format_swiz
= vc4_get_format_swizzle(color_format
);
518 bool srgb
= util_format_is_srgb(color_format
);
520 /* Pull out the float src/dst color components. */
521 nir_ssa_def
*packed_dst_color
= vc4_nir_get_dst_color(b
, sample
);
522 nir_ssa_def
*dst_vec4
= nir_unpack_unorm_4x8(b
, packed_dst_color
);
523 nir_ssa_def
*src_color
[4], *unpacked_dst_color
[4];
524 for (unsigned i
= 0; i
< 4; i
++) {
525 src_color
[i
] = nir_channel(b
, src
, i
);
526 unpacked_dst_color
[i
] = nir_channel(b
, dst_vec4
, i
);
529 if (c
->fs_key
->sample_alpha_to_one
&& c
->fs_key
->msaa
)
530 src_color
[3] = nir_imm_float(b
, 1.0);
532 vc4_nir_emit_alpha_test_discard(c
, b
, src_color
[3]);
534 nir_ssa_def
*packed_color
;
536 /* Unswizzle the destination color. */
537 nir_ssa_def
*dst_color
[4];
538 for (unsigned i
= 0; i
< 4; i
++) {
539 dst_color
[i
] = vc4_nir_get_swizzled_channel(b
,
544 /* Turn dst color to linear. */
545 for (int i
= 0; i
< 3; i
++)
546 dst_color
[i
] = vc4_nir_srgb_decode(b
, dst_color
[i
]);
548 nir_ssa_def
*blend_color
[4];
549 vc4_do_blending_f(c
, b
, blend_color
, src_color
, dst_color
);
551 /* sRGB encode the output color */
552 for (int i
= 0; i
< 3; i
++)
553 blend_color
[i
] = vc4_nir_srgb_encode(b
, blend_color
[i
]);
555 packed_color
= vc4_nir_swizzle_and_pack(c
, b
, blend_color
);
557 nir_ssa_def
*packed_src_color
=
558 vc4_nir_swizzle_and_pack(c
, b
, src_color
);
561 vc4_do_blending_i(c
, b
,
562 packed_src_color
, packed_dst_color
,
566 packed_color
= vc4_logicop(b
, c
->fs_key
->logicop_func
,
567 packed_color
, packed_dst_color
);
569 /* If the bit isn't set in the color mask, then just return the
570 * original dst color, instead.
572 uint32_t colormask
= 0xffffffff;
573 for (int i
= 0; i
< 4; i
++) {
574 if (format_swiz
[i
] < 4 &&
575 !(c
->fs_key
->blend
.colormask
& (1 << format_swiz
[i
]))) {
576 colormask
&= ~(0xff << (i
* 8));
581 nir_iand(b
, packed_color
,
582 nir_imm_int(b
, colormask
)),
583 nir_iand(b
, packed_dst_color
,
584 nir_imm_int(b
, ~colormask
)));
588 vc4_nir_next_output_driver_location(nir_shader
*s
)
592 nir_foreach_variable(var
, &s
->outputs
)
593 maxloc
= MAX2(maxloc
, (int)var
->data
.driver_location
);
599 vc4_nir_store_sample_mask(struct vc4_compile
*c
, nir_builder
*b
,
602 nir_variable
*sample_mask
= nir_variable_create(c
->s
, nir_var_shader_out
,
605 sample_mask
->data
.driver_location
=
606 vc4_nir_next_output_driver_location(c
->s
);
607 sample_mask
->data
.location
= FRAG_RESULT_SAMPLE_MASK
;
609 nir_intrinsic_instr
*intr
=
610 nir_intrinsic_instr_create(c
->s
, nir_intrinsic_store_output
);
611 intr
->num_components
= 1;
612 intr
->const_index
[0] = sample_mask
->data
.driver_location
;
614 intr
->src
[0] = nir_src_for_ssa(val
);
615 intr
->src
[1] = nir_src_for_ssa(nir_imm_int(b
, 0));
616 nir_builder_instr_insert(b
, &intr
->instr
);
620 vc4_nir_lower_blend_instr(struct vc4_compile
*c
, nir_builder
*b
,
621 nir_intrinsic_instr
*intr
)
623 nir_ssa_def
*frag_color
= intr
->src
[0].ssa
;
625 if (c
->fs_key
->sample_coverage
) {
626 nir_intrinsic_instr
*load
=
627 nir_intrinsic_instr_create(b
->shader
,
628 nir_intrinsic_load_sample_mask_in
);
629 load
->num_components
= 1;
630 nir_ssa_dest_init(&load
->instr
, &load
->dest
, 1, NULL
);
631 nir_builder_instr_insert(b
, &load
->instr
);
633 nir_ssa_def
*bitmask
= &load
->dest
.ssa
;
635 vc4_nir_store_sample_mask(c
, b
, bitmask
);
636 } else if (c
->fs_key
->sample_alpha_to_coverage
) {
637 nir_ssa_def
*a
= nir_channel(b
, frag_color
, 3);
639 /* XXX: We should do a nice dither based on the fragment
640 * coordinate, instead.
642 nir_ssa_def
*num_samples
= nir_imm_float(b
, VC4_MAX_SAMPLES
);
643 nir_ssa_def
*num_bits
= nir_f2i(b
, nir_fmul(b
, a
, num_samples
));
644 nir_ssa_def
*bitmask
= nir_isub(b
,
649 vc4_nir_store_sample_mask(c
, b
, bitmask
);
652 /* The TLB color read returns each sample in turn, so if our blending
653 * depends on the destination color, we're going to have to run the
654 * blending function separately for each destination sample value, and
655 * then output the per-sample color using TLB_COLOR_MS.
657 nir_ssa_def
*blend_output
;
658 if (c
->fs_key
->msaa
&& blend_depends_on_dst_color(c
)) {
659 c
->msaa_per_sample_output
= true;
661 nir_ssa_def
*samples
[4];
662 for (int i
= 0; i
< VC4_MAX_SAMPLES
; i
++)
663 samples
[i
] = vc4_nir_blend_pipeline(c
, b
, frag_color
, i
);
664 blend_output
= nir_vec4(b
,
665 samples
[0], samples
[1],
666 samples
[2], samples
[3]);
668 blend_output
= vc4_nir_blend_pipeline(c
, b
, frag_color
, 0);
671 nir_instr_rewrite_src(&intr
->instr
, &intr
->src
[0],
672 nir_src_for_ssa(blend_output
));
673 intr
->num_components
= blend_output
->num_components
;
677 vc4_nir_lower_blend_block(nir_block
*block
, void *state
)
679 struct vc4_compile
*c
= state
;
681 nir_foreach_instr_safe(block
, instr
) {
682 if (instr
->type
!= nir_instr_type_intrinsic
)
684 nir_intrinsic_instr
*intr
= nir_instr_as_intrinsic(instr
);
685 if (intr
->intrinsic
!= nir_intrinsic_store_output
)
688 nir_variable
*output_var
= NULL
;
689 nir_foreach_variable(var
, &c
->s
->outputs
) {
690 if (var
->data
.driver_location
== intr
->const_index
[0]) {
697 if (output_var
->data
.location
!= FRAG_RESULT_COLOR
&&
698 output_var
->data
.location
!= FRAG_RESULT_DATA0
) {
702 nir_function_impl
*impl
=
703 nir_cf_node_get_function(&block
->cf_node
);
705 nir_builder_init(&b
, impl
);
706 b
.cursor
= nir_before_instr(&intr
->instr
);
707 vc4_nir_lower_blend_instr(c
, &b
, intr
);
713 vc4_nir_lower_blend(struct vc4_compile
*c
)
715 nir_foreach_function(c
->s
, function
) {
716 if (function
->impl
) {
717 nir_foreach_block(function
->impl
,
718 vc4_nir_lower_blend_block
, c
);
720 nir_metadata_preserve(function
->impl
,
721 nir_metadata_block_index
|
722 nir_metadata_dominance
);