aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2020-01-24 10:55:55 +0100
committerMarge Bot <[email protected]>2020-01-29 09:49:50 +0000
commit531a26d5aa03d8f4499f901f040132c5f712219a (patch)
treeb6316ab46be173ac652bd8d9a08c00d4d637c27d /src
parentcf6cae832c9e7c95e2df88b4e86886d1310c505a (diff)
spirv: implement SPV_AMD_shader_explicit_vertex_parameter
Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3578>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/shader_info.h1
-rw-r--r--src/compiler/spirv/spirv_to_nir.c3
-rw-r--r--src/compiler/spirv/vtn_amd.c64
-rw-r--r--src/compiler/spirv/vtn_private.h5
4 files changed, 73 insertions, 0 deletions
diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
index 4aa138943a7..d13e51a47a6 100644
--- a/src/compiler/shader_info.h
+++ b/src/compiler/shader_info.h
@@ -84,6 +84,7 @@ struct spirv_supported_capabilities {
bool amd_shader_ballot;
bool amd_trinary_minmax;
bool amd_image_read_write_lod;
+ bool amd_shader_explicit_vertex_parameter;
};
typedef struct shader_info {
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 258e33b723b..411212c6b8f 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -398,6 +398,9 @@ vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
} else if ((strcmp(ext, "SPV_AMD_shader_trinary_minmax") == 0)
&& (b->options && b->options->caps.amd_trinary_minmax)) {
val->ext_handler = vtn_handle_amd_shader_trinary_minmax_instruction;
+ } else if ((strcmp(ext, "SPV_AMD_shader_explicit_vertex_parameter") == 0)
+ && (b->options && b->options->caps.amd_shader_explicit_vertex_parameter)) {
+ val->ext_handler = vtn_handle_amd_shader_explicit_vertex_parameter_instruction;
} else if (strcmp(ext, "OpenCL.std") == 0) {
val->ext_handler = vtn_handle_opencl_instruction;
} else if (strstr(ext, "NonSemantic.") == ext) {
diff --git a/src/compiler/spirv/vtn_amd.c b/src/compiler/spirv/vtn_amd.c
index efdcfdb514c..55f87c2f98e 100644
--- a/src/compiler/spirv/vtn_amd.c
+++ b/src/compiler/spirv/vtn_amd.c
@@ -168,3 +168,67 @@ vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ex
return true;
}
+
+bool
+vtn_handle_amd_shader_explicit_vertex_parameter_instruction(struct vtn_builder *b, SpvOp ext_opcode,
+ const uint32_t *w, unsigned count)
+{
+ const struct glsl_type *dest_type =
+ vtn_value(b, w[1], vtn_value_type_type)->type->type;
+
+ struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+ val->ssa = vtn_create_ssa_value(b, dest_type);
+
+ nir_intrinsic_op op;
+ switch ((enum ShaderExplicitVertexParameterAMD)ext_opcode) {
+ case InterpolateAtVertexAMD:
+ op = nir_intrinsic_interp_deref_at_vertex;
+ break;
+ default:
+ unreachable("unknown opcode");
+ }
+
+ nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->nb.shader, op);
+
+ struct vtn_pointer *ptr =
+ vtn_value(b, w[5], vtn_value_type_pointer)->pointer;
+ nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr);
+
+ /* If the value we are interpolating has an index into a vector then
+ * interpolate the vector and index the result of that instead. This is
+ * necessary because the index will get generated as a series of nir_bcsel
+ * instructions so it would no longer be an input variable.
+ */
+ const bool vec_array_deref = deref->deref_type == nir_deref_type_array &&
+ glsl_type_is_vector(nir_deref_instr_parent(deref)->type);
+
+ nir_deref_instr *vec_deref = NULL;
+ if (vec_array_deref) {
+ vec_deref = deref;
+ deref = nir_deref_instr_parent(deref);
+ }
+ intrin->src[0] = nir_src_for_ssa(&deref->dest.ssa);
+ intrin->src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
+
+ intrin->num_components = glsl_get_vector_elements(deref->type);
+ nir_ssa_dest_init(&intrin->instr, &intrin->dest,
+ glsl_get_vector_elements(deref->type),
+ glsl_get_bit_size(deref->type), NULL);
+
+ nir_builder_instr_insert(&b->nb, &intrin->instr);
+
+ if (vec_array_deref) {
+ assert(vec_deref);
+ if (nir_src_is_const(vec_deref->arr.index)) {
+ val->ssa->def = vtn_vector_extract(b, &intrin->dest.ssa,
+ nir_src_as_uint(vec_deref->arr.index));
+ } else {
+ val->ssa->def = vtn_vector_extract_dynamic(b, &intrin->dest.ssa,
+ vec_deref->arr.index.ssa);
+ }
+ } else {
+ val->ssa->def = &intrin->dest.ssa;
+ }
+
+ return true;
+}
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 92daf1352bd..4b2d28978d9 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -891,6 +891,11 @@ bool vtn_handle_amd_shader_ballot_instruction(struct vtn_builder *b, SpvOp ext_o
bool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode,
const uint32_t *words, unsigned count);
+bool vtn_handle_amd_shader_explicit_vertex_parameter_instruction(struct vtn_builder *b,
+ SpvOp ext_opcode,
+ const uint32_t *words,
+ unsigned count);
+
SpvMemorySemanticsMask vtn_storage_class_to_memory_semantics(SpvStorageClass sc);
void vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope,