Updated spirv-cross.

This commit is contained in:
Бранимир Караџић
2022-04-03 18:45:21 -07:00
parent 0a26666409
commit 822dce26e5
5 changed files with 186 additions and 18 deletions

View File

@@ -4990,14 +4990,13 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c, bool inside_bloc
// Handles Arrays and structures.
string res;
// Only consider the decay if we are inside a struct scope.
// Outside a struct declaration, we can always bind to a constant array with templated type.
// Only consider the decay if we are inside a struct scope where we are emitting a member with Offset decoration.
// Outside a block-like struct declaration, we can always bind to a constant array with templated type.
// Should look at ArrayStride here as well, but it's possible to declare a constant struct
// with Offset = 0, using no ArrayStride on the enclosed array type.
// A particular CTS test hits this scenario.
bool array_type_decays = inside_block_like_struct_scope &&
!type.array.empty() && !backend.array_is_value_type_in_buffer_blocks &&
has_decoration(c.constant_type, DecorationArrayStride);
if (type.array.empty() && type.basetype == SPIRType::Struct && type_is_block_like(type))
inside_block_like_struct_scope = true;
!type.array.empty() && !backend.array_is_value_type_in_buffer_blocks;
// Allow Metal to use the array<T> template to make arrays a value type
bool needs_trailing_tracket = false;
@@ -5021,16 +5020,29 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c, bool inside_bloc
res = type_to_glsl_constructor(type) + "(";
}
uint32_t subconstant_index = 0;
for (auto &elem : c.subconstants)
{
auto &subc = get<SPIRConstant>(elem);
if (subc.specialization)
res += to_name(elem);
else
{
if (type.array.empty() && type.basetype == SPIRType::Struct)
{
// When we get down to emitting struct members, override the block-like information.
// For constants, we can freely mix and match block-like state.
inside_block_like_struct_scope =
has_member_decoration(type.self, subconstant_index, DecorationOffset);
}
res += constant_expression(subc, inside_block_like_struct_scope);
}
if (&elem != &c.subconstants.back())
res += ", ";
subconstant_index++;
}
res += backend.use_initializer_list ? " }" : ")";
@@ -9588,8 +9600,8 @@ bool CompilerGLSL::should_forward(uint32_t id) const
auto *var = maybe_get<SPIRVariable>(id);
if (var)
{
// Never forward volatile variables, e.g. SPIR-V 1.6 IsHelperInvocation.
return !has_decoration(id, DecorationVolatile);
// Never forward volatile builtin variables, e.g. SPIR-V 1.6 HelperInvocation.
return !(has_decoration(id, DecorationBuiltIn) && has_decoration(id, DecorationVolatile));
}
// For debugging emit temporary variables for all expressions
@@ -9603,9 +9615,11 @@ bool CompilerGLSL::should_forward(uint32_t id) const
if (expr && expr->expression_dependencies.size() >= max_expression_dependencies)
return false;
if (expr && expr->loaded_from && has_decoration(expr->loaded_from, DecorationVolatile))
if (expr && expr->loaded_from
&& has_decoration(expr->loaded_from, DecorationBuiltIn)
&& has_decoration(expr->loaded_from, DecorationVolatile))
{
// Never forward volatile variables.
// Never forward volatile builtin variables, e.g. SPIR-V 1.6 HelperInvocation.
return false;
}

View File

@@ -462,6 +462,10 @@ string CompilerHLSL::type_to_glsl(const SPIRType &type, uint32_t id)
if (hlsl_options.shader_model < 60)
SPIRV_CROSS_THROW("64-bit integers only supported in SM 6.0.");
return "uint64_t";
case SPIRType::AccelerationStructure:
return "RaytracingAccelerationStructure";
case SPIRType::RayQuery:
return "RayQuery<RAY_FLAG_NONE>";
default:
return "???";
}
@@ -2109,6 +2113,13 @@ void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type
variable_decl(membertype, to_member_name(type, index)), packing_offset, ";");
}
void CompilerHLSL::emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops)
{
flush_variable_declaration(ops[0]);
uint32_t is_commited = evaluate_constant_u32(ops[3]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), is_commited ? commited : candidate), false);
}
void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
{
auto &type = get<SPIRType>(var.basetype);
@@ -3289,6 +3300,11 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
resource_flags = HLSL_BINDING_AUTO_SAMPLER_BIT;
break;
case SPIRType::AccelerationStructure:
space = 't'; // SRV
resource_flags = HLSL_BINDING_AUTO_SRV_BIT;
break;
case SPIRType::Struct:
{
auto storage = type.storage;
@@ -5616,6 +5632,143 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
SPIRV_CROSS_THROW("Rasterizer order views require Shader Model 5.1.");
break; // Nothing to do in the body
case OpRayQueryInitializeKHR:
{
flush_variable_declaration(ops[0]);
std::string ray_desc_name = get_unique_identifier();
statement("RayDesc ", ray_desc_name, " = {", to_expression(ops[4]), ", ", to_expression(ops[5]), ", ",
to_expression(ops[6]), ", ", to_expression(ops[7]), "};");
statement(to_expression(ops[0]), ".TraceRayInline(",
to_expression(ops[1]), ", ", // acc structure
to_expression(ops[2]), ", ", // ray flags
to_expression(ops[3]), ", ", // mask
ray_desc_name, ");"); // ray
break;
}
case OpRayQueryProceedKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".Proceed()"), false);
break;
}
case OpRayQueryTerminateKHR:
{
flush_variable_declaration(ops[0]);
statement(to_expression(ops[0]), ".Abort();");
break;
}
case OpRayQueryGenerateIntersectionKHR:
{
flush_variable_declaration(ops[0]);
statement(to_expression(ops[0]), ".CommitProceduralPrimitiveHit(", ops[1], ");");
break;
}
case OpRayQueryConfirmIntersectionKHR:
{
flush_variable_declaration(ops[0]);
statement(to_expression(ops[0]), ".CommitNonOpaqueTriangleHit();");
break;
}
case OpRayQueryGetIntersectionTypeKHR:
{
emit_rayquery_function(".CommittedStatus()", ".CandidateType()", ops);
break;
}
case OpRayQueryGetIntersectionTKHR:
{
emit_rayquery_function(".CommittedRayT()", ".CandidateTriangleRayT()", ops);
break;
}
case OpRayQueryGetIntersectionInstanceCustomIndexKHR:
{
emit_rayquery_function(".CommittedInstanceID()", ".CandidateInstanceID()", ops);
break;
}
case OpRayQueryGetIntersectionInstanceIdKHR:
{
emit_rayquery_function(".CommittedInstanceIndex()", ".CandidateInstanceIndex()", ops);
break;
}
case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR:
{
emit_rayquery_function(".CommittedInstanceContributionToHitGroupIndex()",
".CandidateInstanceContributionToHitGroupIndex()", ops);
break;
}
case OpRayQueryGetIntersectionGeometryIndexKHR:
{
emit_rayquery_function(".CommittedGeometryIndex()",
".CandidateGeometryIndex()", ops);
break;
}
case OpRayQueryGetIntersectionPrimitiveIndexKHR:
{
emit_rayquery_function(".CommittedPrimitiveIndex()", ".CandidatePrimitiveIndex()", ops);
break;
}
case OpRayQueryGetIntersectionBarycentricsKHR:
{
emit_rayquery_function(".CommittedTriangleBarycentrics()", ".CandidateTriangleBarycentrics()", ops);
break;
}
case OpRayQueryGetIntersectionFrontFaceKHR:
{
emit_rayquery_function(".CommittedTriangleFrontFace()", ".CandidateTriangleFrontFace()", ops);
break;
}
case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".CandidateProceduralPrimitiveNonOpaque()"), false);
break;
}
case OpRayQueryGetIntersectionObjectRayDirectionKHR:
{
emit_rayquery_function(".CommittedObjectRayDirection()", ".CandidateObjectRayDirection()", ops);
break;
}
case OpRayQueryGetIntersectionObjectRayOriginKHR:
{
flush_variable_declaration(ops[0]);
emit_rayquery_function(".CommittedObjectRayOrigin()", ".CandidateObjectRayOrigin()", ops);
break;
}
case OpRayQueryGetIntersectionObjectToWorldKHR:
{
emit_rayquery_function(".CommittedObjectToWorld4x3()", ".CandidateObjectToWorld4x3()", ops);
break;
}
case OpRayQueryGetIntersectionWorldToObjectKHR:
{
emit_rayquery_function(".CommittedWorldToObject4x3()", ".CandidateWorldToObject4x3()", ops);
break;
}
case OpRayQueryGetRayFlagsKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".RayFlags()"), false);
break;
}
case OpRayQueryGetRayTMinKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".RayTMin()"), false);
break;
}
case OpRayQueryGetWorldRayOriginKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".WorldRayOrigin()"), false);
break;
}
case OpRayQueryGetWorldRayDirectionKHR:
{
flush_variable_declaration(ops[0]);
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".WorldRayDirection()"), false);
break;
}
default:
CompilerGLSL::emit_instruction(instruction);
break;

View File

@@ -267,6 +267,7 @@ private:
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier,
uint32_t base_offset = 0) override;
void emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops);
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
void replace_illegal_names() override;

View File

@@ -4951,7 +4951,7 @@ void CompilerMSL::emit_custom_functions()
for (uint32_t variant = 0; variant < 12; variant++)
{
uint32_t dimensions = spv_func - SPVFuncImplArrayCopyMultidimBase;
uint8_t dimensions = spv_func - SPVFuncImplArrayCopyMultidimBase;
string tmp = "template<typename T";
for (uint8_t i = 0; i < dimensions; i++)
{
@@ -8532,8 +8532,8 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
#define MSL_RAY_QUERY_IS_OP2(op, msl_op) MSL_RAY_QUERY_OP_INNER2(op, .is, msl_op)
MSL_RAY_QUERY_GET_OP(RayTMin, ray_min_distance);
MSL_RAY_QUERY_GET_OP(WorldRayOrigin, world_space_ray_direction);
MSL_RAY_QUERY_GET_OP(WorldRayDirection, world_space_ray_origin);
MSL_RAY_QUERY_GET_OP(WorldRayOrigin, world_space_ray_origin);
MSL_RAY_QUERY_GET_OP(WorldRayDirection, world_space_ray_direction);
MSL_RAY_QUERY_GET_OP2(IntersectionInstanceId, instance_id);
MSL_RAY_QUERY_GET_OP2(IntersectionInstanceCustomIndex, user_instance_id);
MSL_RAY_QUERY_GET_OP2(IntersectionBarycentrics, triangle_barycentric_coord);
@@ -13603,14 +13603,14 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
break;
case SPIRType::AccelerationStructure:
if (msl_options.supports_msl_version(2, 4))
type_name = "acceleration_structure<instancing>";
type_name = "raytracing::acceleration_structure<raytracing::instancing>";
else if (msl_options.supports_msl_version(2, 3))
type_name = "instance_acceleration_structure";
type_name = "raytracing::instance_acceleration_structure";
else
SPIRV_CROSS_THROW("Acceleration Structure Type is supported in MSL 2.3 and above.");
break;
case SPIRType::RayQuery:
return "intersection_query<instancing, triangle_data>";
return "raytracing::intersection_query<raytracing::instancing, raytracing::triangle_data>";
default:
return "unknown_type";

View File

@@ -638,7 +638,7 @@ public:
protected:
// An enum of SPIR-V functions that are implemented in additional
// source code that is added to the shader if necessary.
enum SPVFuncImpl
enum SPVFuncImpl : uint8_t
{
SPVFuncImplNone,
SPVFuncImplMod,