spirv: implement SPV_AMD_shader_explicit_vertex_parameter
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3578>
This commit is contained in:

committed by
Marge Bot

parent
cf6cae832c
commit
531a26d5aa
@@ -84,6 +84,7 @@ struct spirv_supported_capabilities {
|
|||||||
bool amd_shader_ballot;
|
bool amd_shader_ballot;
|
||||||
bool amd_trinary_minmax;
|
bool amd_trinary_minmax;
|
||||||
bool amd_image_read_write_lod;
|
bool amd_image_read_write_lod;
|
||||||
|
bool amd_shader_explicit_vertex_parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct shader_info {
|
typedef struct shader_info {
|
||||||
|
@@ -398,6 +398,9 @@ vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
|
|||||||
} else if ((strcmp(ext, "SPV_AMD_shader_trinary_minmax") == 0)
|
} else if ((strcmp(ext, "SPV_AMD_shader_trinary_minmax") == 0)
|
||||||
&& (b->options && b->options->caps.amd_trinary_minmax)) {
|
&& (b->options && b->options->caps.amd_trinary_minmax)) {
|
||||||
val->ext_handler = vtn_handle_amd_shader_trinary_minmax_instruction;
|
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) {
|
} else if (strcmp(ext, "OpenCL.std") == 0) {
|
||||||
val->ext_handler = vtn_handle_opencl_instruction;
|
val->ext_handler = vtn_handle_opencl_instruction;
|
||||||
} else if (strstr(ext, "NonSemantic.") == ext) {
|
} else if (strstr(ext, "NonSemantic.") == ext) {
|
||||||
|
@@ -168,3 +168,67 @@ vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ex
|
|||||||
|
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
@@ -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,
|
bool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode,
|
||||||
const uint32_t *words, unsigned count);
|
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);
|
SpvMemorySemanticsMask vtn_storage_class_to_memory_semantics(SpvStorageClass sc);
|
||||||
|
|
||||||
void vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope,
|
void vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope,
|
||||||
|
Reference in New Issue
Block a user