2
* Copyright 2023 Valve Corporation
3
* Copyright 2023 Alyssa Rosenzweig
4
* SPDX-License-Identifier: MIT
7
#include "agx_tilebuffer.h"
8
#include "nir_builder.h"
11
mask_by_sample_id(nir_builder *b, nir_ssa_def *mask)
13
nir_ssa_def *id_mask =
14
nir_ishl(b, nir_imm_intN_t(b, 1, mask->bit_size), nir_load_sample_id(b));
15
return nir_iand(b, mask, id_mask);
19
lower_to_sample(nir_builder *b, nir_instr *instr, void *_)
21
if (instr->type != nir_instr_type_intrinsic)
24
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
25
b->cursor = nir_before_instr(instr);
27
switch (intr->intrinsic) {
28
case nir_intrinsic_load_sample_pos: {
29
/* Lower sample positions to decode the packed fixed-point register:
31
* uint32_t packed = load_sample_positions();
32
* uint32_t shifted = packed >> (sample_id * 8);
34
* for (i = 0; i < 2; ++i) {
35
* uint8_t nibble = (shifted >> (i * 4)) & 0xF;
36
* xy[component] = ((float)nibble) / 16.0;
39
nir_ssa_def *packed = nir_load_sample_positions_agx(b);
41
/* The n'th sample is the in the n'th byte of the register */
42
nir_ssa_def *shifted = nir_ushr(
43
b, packed, nir_u2u32(b, nir_imul_imm(b, nir_load_sample_id(b), 8)));
46
for (unsigned i = 0; i < 2; ++i) {
47
/* Get the appropriate nibble */
49
nir_iand_imm(b, nir_ushr_imm(b, shifted, i * 4), 0xF);
51
/* Convert it from fixed point to float */
52
xy[i] = nir_fmul_imm(b, nir_u2f16(b, nibble), 1.0 / 16.0);
54
/* Upconvert if necessary */
55
xy[i] = nir_f2fN(b, xy[i], nir_dest_bit_size(intr->dest));
58
/* Collect and rewrite */
59
nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_vec2(b, xy[0], xy[1]));
60
nir_instr_remove(instr);
64
case nir_intrinsic_load_sample_mask_in: {
65
/* In OpenGL, gl_SampleMaskIn is only supposed to have the single bit set
66
* of the sample currently being shaded when sample shading is used. Mask
67
* by the sample ID to make that happen.
69
b->cursor = nir_after_instr(instr);
70
nir_ssa_def *old = &intr->dest.ssa;
71
nir_ssa_def *lowered = mask_by_sample_id(b, old);
72
nir_ssa_def_rewrite_uses_after(old, lowered, lowered->parent_instr);
76
case nir_intrinsic_load_barycentric_sample: {
77
/* Lower fragment varyings with "sample" interpolation to
78
* interpolateAtSample() with the sample ID
80
b->cursor = nir_after_instr(instr);
81
nir_ssa_def *old = &intr->dest.ssa;
83
nir_ssa_def *lowered = nir_load_barycentric_at_sample(
84
b, nir_dest_bit_size(intr->dest), nir_load_sample_id(b),
85
.interp_mode = nir_intrinsic_interp_mode(intr));
87
nir_ssa_def_rewrite_uses_after(old, lowered, lowered->parent_instr);
97
* In a fragment shader using sample shading, lower intrinsics like
98
* load_sample_position to variants in terms of load_sample_id. Except for a
99
* possible API bit to force sample shading in shaders that don't otherwise need
100
* it, this pass does not depend on the shader key. In particular, it does not
101
* depend on the sample count. So it runs on fragment shaders at compile-time.
102
* The load_sample_id intrinsics themselves are lowered later, with different
103
* lowerings for monolithic vs epilogs.
105
* Note that fragment I/O (like store_local_pixel_agx and discard_agx) does not
106
* get lowered here, because that lowering is different for monolithic vs FS
107
* epilogs even though there's no dependency on sample count.
110
agx_nir_lower_sample_intrinsics(nir_shader *shader)
112
/* If sample shading is disabled, the unlowered shader will broadcast pixel
113
* values across the sample (the default). By definition, there are no sample
114
* position or sample barycentrics, as these trigger sample shading.
116
if (!shader->info.fs.uses_sample_shading)
119
return nir_shader_instructions_pass(
120
shader, lower_to_sample,
121
nir_metadata_block_index | nir_metadata_dominance, NULL);