mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 04:50:11 +01:00
spirv: handle ray query intrinsics
v2: Fixup comment (Caio)
Use generated builders (Caio)
v3: Update spirv2dxil CI expectations
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13718>
This commit is contained in:
parent
0cbcc15afe
commit
4c703686db
4 changed files with 199 additions and 3 deletions
|
|
@ -805,6 +805,7 @@ vtn_types_compatible(struct vtn_builder *b,
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case vtn_base_type_accel_struct:
|
case vtn_base_type_accel_struct:
|
||||||
|
case vtn_base_type_ray_query:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case vtn_base_type_function:
|
case vtn_base_type_function:
|
||||||
|
|
@ -845,6 +846,7 @@ vtn_type_copy(struct vtn_builder *b, struct vtn_type *src)
|
||||||
case vtn_base_type_sampled_image:
|
case vtn_base_type_sampled_image:
|
||||||
case vtn_base_type_event:
|
case vtn_base_type_event:
|
||||||
case vtn_base_type_accel_struct:
|
case vtn_base_type_accel_struct:
|
||||||
|
case vtn_base_type_ray_query:
|
||||||
/* Nothing more to do */
|
/* Nothing more to do */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1810,11 +1812,30 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
||||||
val->type->type = glsl_uint64_t_type();
|
val->type->type = glsl_uint64_t_type();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SpvOpTypeOpaque:
|
|
||||||
|
case SpvOpTypeOpaque: {
|
||||||
val->type->base_type = vtn_base_type_struct;
|
val->type->base_type = vtn_base_type_struct;
|
||||||
const char *name = vtn_string_literal(b, &w[2], count - 2, NULL);
|
const char *name = vtn_string_literal(b, &w[2], count - 2, NULL);
|
||||||
val->type->type = glsl_struct_type(NULL, 0, name, false);
|
val->type->type = glsl_struct_type(NULL, 0, name, false);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SpvOpTypeRayQueryKHR: {
|
||||||
|
val->type->base_type = vtn_base_type_ray_query;
|
||||||
|
const char *name = "RayQueryKHR";
|
||||||
|
val->type->type = glsl_struct_type(NULL, 0, name, false);
|
||||||
|
/* We may need to run queries on helper invocations. Here the parser
|
||||||
|
* doesn't go through a deeper analysis on whether the result of a query
|
||||||
|
* will be used in derivative instructions.
|
||||||
|
*
|
||||||
|
* An implementation willing to optimize this would look through the IR
|
||||||
|
* and check if any derivative instruction uses the result of a query
|
||||||
|
* and drop this flag if not.
|
||||||
|
*/
|
||||||
|
if (b->shader->info.stage == MESA_SHADER_FRAGMENT)
|
||||||
|
val->type->access = ACCESS_INCLUDE_HELPERS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SpvOpTypeEvent:
|
case SpvOpTypeEvent:
|
||||||
val->type->base_type = vtn_base_type_event;
|
val->type->base_type = vtn_base_type_event;
|
||||||
|
|
@ -5290,6 +5311,7 @@ vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||||
case SpvOpTypeQueue:
|
case SpvOpTypeQueue:
|
||||||
case SpvOpTypePipe:
|
case SpvOpTypePipe:
|
||||||
case SpvOpTypeAccelerationStructureKHR:
|
case SpvOpTypeAccelerationStructureKHR:
|
||||||
|
case SpvOpTypeRayQueryKHR:
|
||||||
vtn_handle_type(b, opcode, w, count);
|
vtn_handle_type(b, opcode, w, count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -5577,6 +5599,146 @@ vtn_handle_write_packed_primitive_indices(struct vtn_builder *b, SpvOp opcode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ray_query_value {
|
||||||
|
nir_ray_query_value nir_value;
|
||||||
|
const struct glsl_type *glsl_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ray_query_value
|
||||||
|
spirv_to_nir_type_ray_query_intrinsic(struct vtn_builder *b,
|
||||||
|
SpvOp opcode)
|
||||||
|
{
|
||||||
|
switch (opcode) {
|
||||||
|
#define CASE(_spv, _nir, _type) case SpvOpRayQueryGet##_spv: \
|
||||||
|
return (struct ray_query_value) { .nir_value = nir_ray_query_value_##_nir, .glsl_type = _type }
|
||||||
|
CASE(RayTMinKHR, tmin, glsl_floatN_t_type(32));
|
||||||
|
CASE(RayFlagsKHR, flags, glsl_uint_type());
|
||||||
|
CASE(WorldRayDirectionKHR, world_ray_direction, glsl_vec_type(3));
|
||||||
|
CASE(WorldRayOriginKHR, world_ray_origin, glsl_vec_type(3));
|
||||||
|
CASE(IntersectionTypeKHR, intersection_type, glsl_uint_type());
|
||||||
|
CASE(IntersectionTKHR, intersection_t, glsl_floatN_t_type(32));
|
||||||
|
CASE(IntersectionInstanceCustomIndexKHR, intersection_instance_custom_index, glsl_int_type());
|
||||||
|
CASE(IntersectionInstanceIdKHR, intersection_instance_id, glsl_int_type());
|
||||||
|
CASE(IntersectionInstanceShaderBindingTableRecordOffsetKHR, intersection_instance_sbt_index, glsl_uint_type());
|
||||||
|
CASE(IntersectionGeometryIndexKHR, intersection_geometry_index, glsl_int_type());
|
||||||
|
CASE(IntersectionPrimitiveIndexKHR, intersection_primitive_index, glsl_int_type());
|
||||||
|
CASE(IntersectionBarycentricsKHR, intersection_barycentrics, glsl_vec_type(2));
|
||||||
|
CASE(IntersectionFrontFaceKHR, intersection_front_face, glsl_bool_type());
|
||||||
|
CASE(IntersectionCandidateAABBOpaqueKHR, intersection_candidate_aabb_opaque, glsl_bool_type());
|
||||||
|
CASE(IntersectionObjectToWorldKHR, intersection_object_to_world, glsl_matrix_type(glsl_get_base_type(glsl_float_type()), 3, 4));
|
||||||
|
CASE(IntersectionWorldToObjectKHR, intersection_world_to_object, glsl_matrix_type(glsl_get_base_type(glsl_float_type()), 3, 4));
|
||||||
|
CASE(IntersectionObjectRayOriginKHR, intersection_object_ray_origin, glsl_vec_type(3));
|
||||||
|
CASE(IntersectionObjectRayDirectionKHR, intersection_object_ray_direction, glsl_vec_type(3));
|
||||||
|
#undef CASE
|
||||||
|
default:
|
||||||
|
vtn_fail_with_opcode("Unhandled opcode", opcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ray_query_load_intrinsic_create(struct vtn_builder *b, SpvOp opcode,
|
||||||
|
const uint32_t *w, nir_ssa_def *src0,
|
||||||
|
nir_ssa_def *src1)
|
||||||
|
{
|
||||||
|
struct ray_query_value value =
|
||||||
|
spirv_to_nir_type_ray_query_intrinsic(b, opcode);
|
||||||
|
|
||||||
|
if (glsl_type_is_matrix(value.glsl_type)) {
|
||||||
|
const struct glsl_type *elem_type = glsl_get_array_element(value.glsl_type);
|
||||||
|
const unsigned elems = glsl_get_length(value.glsl_type);
|
||||||
|
|
||||||
|
struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, value.glsl_type);
|
||||||
|
for (unsigned i = 0; i < elems; i++) {
|
||||||
|
ssa->elems[i]->def =
|
||||||
|
nir_build_rq_load(&b->nb,
|
||||||
|
glsl_get_vector_elements(elem_type),
|
||||||
|
glsl_get_bit_size(elem_type),
|
||||||
|
src0, src1,
|
||||||
|
.base = value.nir_value,
|
||||||
|
.column = i);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtn_push_ssa_value(b, w[2], ssa);
|
||||||
|
} else {
|
||||||
|
assert(glsl_type_is_vector_or_scalar(value.glsl_type));
|
||||||
|
|
||||||
|
vtn_push_nir_ssa(b, w[2],
|
||||||
|
nir_rq_load(&b->nb,
|
||||||
|
glsl_get_vector_elements(value.glsl_type),
|
||||||
|
glsl_get_bit_size(value.glsl_type),
|
||||||
|
src0, src1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vtn_handle_ray_query_intrinsic(struct vtn_builder *b, SpvOp opcode,
|
||||||
|
const uint32_t *w, unsigned count)
|
||||||
|
{
|
||||||
|
switch (opcode) {
|
||||||
|
case SpvOpRayQueryInitializeKHR: {
|
||||||
|
nir_intrinsic_instr *intrin =
|
||||||
|
nir_intrinsic_instr_create(b->nb.shader,
|
||||||
|
nir_intrinsic_rq_initialize);
|
||||||
|
/* The sources are in the same order in the NIR intrinsic */
|
||||||
|
for (unsigned i = 0; i < 8; i++)
|
||||||
|
intrin->src[i] = nir_src_for_ssa(vtn_ssa_value(b, w[i + 1])->def);
|
||||||
|
nir_builder_instr_insert(&b->nb, &intrin->instr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SpvOpRayQueryTerminateKHR:
|
||||||
|
nir_rq_terminate(&b->nb, vtn_ssa_value(b, w[1])->def);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SpvOpRayQueryProceedKHR:
|
||||||
|
vtn_push_nir_ssa(b, w[2],
|
||||||
|
nir_rq_proceed(&b->nb, 1, vtn_ssa_value(b, w[3])->def));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SpvOpRayQueryGenerateIntersectionKHR:
|
||||||
|
nir_rq_generate_intersection(&b->nb,
|
||||||
|
vtn_ssa_value(b, w[1])->def,
|
||||||
|
vtn_ssa_value(b, w[2])->def);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SpvOpRayQueryConfirmIntersectionKHR:
|
||||||
|
nir_rq_confirm_intersection(&b->nb, vtn_ssa_value(b, w[1])->def);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SpvOpRayQueryGetIntersectionTKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionTypeKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionInstanceIdKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionGeometryIndexKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionBarycentricsKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionFrontFaceKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionObjectRayOriginKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionObjectToWorldKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionWorldToObjectKHR:
|
||||||
|
ray_query_load_intrinsic_create(b, opcode, w,
|
||||||
|
vtn_ssa_value(b, w[3])->def,
|
||||||
|
nir_i2b1(&b->nb, vtn_ssa_value(b, w[4])->def));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SpvOpRayQueryGetRayTMinKHR:
|
||||||
|
case SpvOpRayQueryGetRayFlagsKHR:
|
||||||
|
case SpvOpRayQueryGetWorldRayDirectionKHR:
|
||||||
|
case SpvOpRayQueryGetWorldRayOriginKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR:
|
||||||
|
ray_query_load_intrinsic_create(b, opcode, w,
|
||||||
|
vtn_ssa_value(b, w[3])->def,
|
||||||
|
/* Committed value is ignored for these */
|
||||||
|
nir_imm_bool(&b->nb, false));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vtn_fail_with_opcode("Unhandled opcode", opcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
|
vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||||
const uint32_t *w, unsigned count)
|
const uint32_t *w, unsigned count)
|
||||||
|
|
@ -6006,6 +6168,32 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||||
vtn_handle_ray_intrinsic(b, opcode, w, count);
|
vtn_handle_ray_intrinsic(b, opcode, w, count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SpvOpRayQueryInitializeKHR:
|
||||||
|
case SpvOpRayQueryTerminateKHR:
|
||||||
|
case SpvOpRayQueryGenerateIntersectionKHR:
|
||||||
|
case SpvOpRayQueryConfirmIntersectionKHR:
|
||||||
|
case SpvOpRayQueryProceedKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionTypeKHR:
|
||||||
|
case SpvOpRayQueryGetRayTMinKHR:
|
||||||
|
case SpvOpRayQueryGetRayFlagsKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionTKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionInstanceIdKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionGeometryIndexKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionBarycentricsKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionFrontFaceKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionObjectRayOriginKHR:
|
||||||
|
case SpvOpRayQueryGetWorldRayDirectionKHR:
|
||||||
|
case SpvOpRayQueryGetWorldRayOriginKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionObjectToWorldKHR:
|
||||||
|
case SpvOpRayQueryGetIntersectionWorldToObjectKHR:
|
||||||
|
vtn_handle_ray_query_intrinsic(b, opcode, w, count);
|
||||||
|
break;
|
||||||
|
|
||||||
case SpvOpLifetimeStart:
|
case SpvOpLifetimeStart:
|
||||||
case SpvOpLifetimeStop:
|
case SpvOpLifetimeStop:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -336,6 +336,7 @@ enum vtn_base_type {
|
||||||
vtn_base_type_sampler,
|
vtn_base_type_sampler,
|
||||||
vtn_base_type_sampled_image,
|
vtn_base_type_sampled_image,
|
||||||
vtn_base_type_accel_struct,
|
vtn_base_type_accel_struct,
|
||||||
|
vtn_base_type_ray_query,
|
||||||
vtn_base_type_function,
|
vtn_base_type_function,
|
||||||
vtn_base_type_event,
|
vtn_base_type_event,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1791,6 +1791,12 @@ vtn_get_call_payload_for_location(struct vtn_builder *b, uint32_t location_id)
|
||||||
"or RayPayloadKHR and location %d", location);
|
"or RayPayloadKHR and location %d", location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
vtn_type_is_ray_query(struct vtn_type *type)
|
||||||
|
{
|
||||||
|
return vtn_type_without_array(type)->base_type == vtn_base_type_ray_query;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
||||||
struct vtn_type *ptr_type, SpvStorageClass storage_class,
|
struct vtn_type *ptr_type, SpvStorageClass storage_class,
|
||||||
|
|
@ -1887,6 +1893,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
||||||
|
|
||||||
var->var->data.mode = nir_mode;
|
var->var->data.mode = nir_mode;
|
||||||
var->var->data.location = -1;
|
var->var->data.location = -1;
|
||||||
|
var->var->data.ray_query = vtn_type_is_ray_query(var->type);
|
||||||
var->var->interface_type = NULL;
|
var->var->interface_type = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1272,11 +1272,11 @@ Test:SpvParserTest_Impl_GenericVulkanShader_GLSL450MemoryModel.spvasm:main|GLCom
|
||||||
Test:SpvParserTest_Impl_GenericVulkanShader_SimpleMemoryModel.spvasm:main|GLCompute: Pass
|
Test:SpvParserTest_Impl_GenericVulkanShader_SimpleMemoryModel.spvasm:main|GLCompute: Pass
|
||||||
Test:SpvParserTest_Impl_GenericVulkanShader_VulkanMemoryModel.spvasm:main|GLCompute: Fail
|
Test:SpvParserTest_Impl_GenericVulkanShader_VulkanMemoryModel.spvasm:main|GLCompute: Fail
|
||||||
SPIR-V WARNING:
|
SPIR-V WARNING:
|
||||||
In file ../src/compiler/spirv/spirv_to_nir.c:4687
|
In file ../src/compiler/spirv/spirv_to_nir.c:4708
|
||||||
Unsupported SPIR-V capability: SpvCapabilityVulkanMemoryModel (5345)
|
Unsupported SPIR-V capability: SpvCapabilityVulkanMemoryModel (5345)
|
||||||
28 bytes into the SPIR-V binary
|
28 bytes into the SPIR-V binary
|
||||||
SPIR-V parsing FAILED:
|
SPIR-V parsing FAILED:
|
||||||
In file ../src/compiler/spirv/spirv_to_nir.c:4841
|
In file ../src/compiler/spirv/spirv_to_nir.c:4862
|
||||||
Vulkan memory model is unsupported by this driver
|
Vulkan memory model is unsupported by this driver
|
||||||
68 bytes into the SPIR-V binary
|
68 bytes into the SPIR-V binary
|
||||||
Compilation failed
|
Compilation failed
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue