2 * Copyright © 2018 Valve Corporation
3 * Copyright © 2017 Red Hat
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
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 DEALINGS
26 #include "vtn_private.h"
27 #include "GLSL.ext.AMD.h"
30 vtn_handle_amd_gcn_shader_instruction(struct vtn_builder
*b
, SpvOp ext_opcode
,
31 const uint32_t *w
, unsigned count
)
34 switch ((enum GcnShaderAMD
)ext_opcode
) {
35 case CubeFaceIndexAMD
:
36 def
= nir_cube_face_index(&b
->nb
, vtn_get_nir_ssa(b
, w
[5]));
38 case CubeFaceCoordAMD
:
39 def
= nir_cube_face_coord(&b
->nb
, vtn_get_nir_ssa(b
, w
[5]));
42 nir_intrinsic_instr
*intrin
= nir_intrinsic_instr_create(b
->nb
.shader
,
43 nir_intrinsic_shader_clock
);
44 nir_ssa_dest_init(&intrin
->instr
, &intrin
->dest
, 2, 32, NULL
);
45 nir_intrinsic_set_memory_scope(intrin
, NIR_SCOPE_SUBGROUP
);
46 nir_builder_instr_insert(&b
->nb
, &intrin
->instr
);
47 def
= nir_pack_64_2x32(&b
->nb
, &intrin
->dest
.ssa
);
51 unreachable("Invalid opcode");
54 vtn_push_nir_ssa(b
, w
[2], def
);
60 vtn_handle_amd_shader_ballot_instruction(struct vtn_builder
*b
, SpvOp ext_opcode
,
61 const uint32_t *w
, unsigned count
)
65 switch ((enum ShaderBallotAMD
)ext_opcode
) {
66 case SwizzleInvocationsAMD
:
68 op
= nir_intrinsic_quad_swizzle_amd
;
70 case SwizzleInvocationsMaskedAMD
:
72 op
= nir_intrinsic_masked_swizzle_amd
;
74 case WriteInvocationAMD
:
76 op
= nir_intrinsic_write_invocation_amd
;
80 op
= nir_intrinsic_mbcnt_amd
;
83 unreachable("Invalid opcode");
86 const struct glsl_type
*dest_type
= vtn_get_type(b
, w
[1])->type
;
87 nir_intrinsic_instr
*intrin
= nir_intrinsic_instr_create(b
->nb
.shader
, op
);
88 nir_ssa_dest_init_for_type(&intrin
->instr
, &intrin
->dest
, dest_type
, NULL
);
89 if (nir_intrinsic_infos
[op
].src_components
[0] == 0)
90 intrin
->num_components
= intrin
->dest
.ssa
.num_components
;
92 for (unsigned i
= 0; i
< num_args
; i
++)
93 intrin
->src
[i
] = nir_src_for_ssa(vtn_get_nir_ssa(b
, w
[i
+ 5]));
95 if (intrin
->intrinsic
== nir_intrinsic_quad_swizzle_amd
) {
96 struct vtn_value
*val
= vtn_value(b
, w
[6], vtn_value_type_constant
);
97 unsigned mask
= val
->constant
->values
[0].u32
|
98 val
->constant
->values
[1].u32
<< 2 |
99 val
->constant
->values
[2].u32
<< 4 |
100 val
->constant
->values
[3].u32
<< 6;
101 nir_intrinsic_set_swizzle_mask(intrin
, mask
);
103 } else if (intrin
->intrinsic
== nir_intrinsic_masked_swizzle_amd
) {
104 struct vtn_value
*val
= vtn_value(b
, w
[6], vtn_value_type_constant
);
105 unsigned mask
= val
->constant
->values
[0].u32
|
106 val
->constant
->values
[1].u32
<< 5 |
107 val
->constant
->values
[2].u32
<< 10;
108 nir_intrinsic_set_swizzle_mask(intrin
, mask
);
111 nir_builder_instr_insert(&b
->nb
, &intrin
->instr
);
112 vtn_push_nir_ssa(b
, w
[2], &intrin
->dest
.ssa
);
118 vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder
*b
, SpvOp ext_opcode
,
119 const uint32_t *w
, unsigned count
)
121 struct nir_builder
*nb
= &b
->nb
;
123 unsigned num_inputs
= count
- 5;
124 assert(num_inputs
== 3);
125 nir_ssa_def
*src
[3] = { NULL
, };
126 for (unsigned i
= 0; i
< num_inputs
; i
++)
127 src
[i
] = vtn_get_nir_ssa(b
, w
[i
+ 5]);
130 switch ((enum ShaderTrinaryMinMaxAMD
)ext_opcode
) {
132 def
= nir_fmin3(nb
, src
[0], src
[1], src
[2]);
135 def
= nir_umin3(nb
, src
[0], src
[1], src
[2]);
138 def
= nir_imin3(nb
, src
[0], src
[1], src
[2]);
141 def
= nir_fmax3(nb
, src
[0], src
[1], src
[2]);
144 def
= nir_umax3(nb
, src
[0], src
[1], src
[2]);
147 def
= nir_imax3(nb
, src
[0], src
[1], src
[2]);
150 def
= nir_fmed3(nb
, src
[0], src
[1], src
[2]);
153 def
= nir_umed3(nb
, src
[0], src
[1], src
[2]);
156 def
= nir_imed3(nb
, src
[0], src
[1], src
[2]);
159 unreachable("unknown opcode\n");
163 vtn_push_nir_ssa(b
, w
[2], def
);
169 vtn_handle_amd_shader_explicit_vertex_parameter_instruction(struct vtn_builder
*b
, SpvOp ext_opcode
,
170 const uint32_t *w
, unsigned count
)
173 switch ((enum ShaderExplicitVertexParameterAMD
)ext_opcode
) {
174 case InterpolateAtVertexAMD
:
175 op
= nir_intrinsic_interp_deref_at_vertex
;
178 unreachable("unknown opcode");
181 nir_intrinsic_instr
*intrin
= nir_intrinsic_instr_create(b
->nb
.shader
, op
);
183 struct vtn_pointer
*ptr
=
184 vtn_value(b
, w
[5], vtn_value_type_pointer
)->pointer
;
185 nir_deref_instr
*deref
= vtn_pointer_to_deref(b
, ptr
);
187 /* If the value we are interpolating has an index into a vector then
188 * interpolate the vector and index the result of that instead. This is
189 * necessary because the index will get generated as a series of nir_bcsel
190 * instructions so it would no longer be an input variable.
192 const bool vec_array_deref
= deref
->deref_type
== nir_deref_type_array
&&
193 glsl_type_is_vector(nir_deref_instr_parent(deref
)->type
);
195 nir_deref_instr
*vec_deref
= NULL
;
196 if (vec_array_deref
) {
198 deref
= nir_deref_instr_parent(deref
);
200 intrin
->src
[0] = nir_src_for_ssa(&deref
->dest
.ssa
);
201 intrin
->src
[1] = nir_src_for_ssa(vtn_get_nir_ssa(b
, w
[6]));
203 intrin
->num_components
= glsl_get_vector_elements(deref
->type
);
204 nir_ssa_dest_init(&intrin
->instr
, &intrin
->dest
,
205 glsl_get_vector_elements(deref
->type
),
206 glsl_get_bit_size(deref
->type
), NULL
);
208 nir_builder_instr_insert(&b
->nb
, &intrin
->instr
);
211 if (vec_array_deref
) {
213 def
= nir_vector_extract(&b
->nb
, &intrin
->dest
.ssa
,
214 vec_deref
->arr
.index
.ssa
);
216 def
= &intrin
->dest
.ssa
;
218 vtn_push_nir_ssa(b
, w
[2], def
);