From 822dce26e5d318aaa1ff7f9ce861c4a905731405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Sun, 3 Apr 2022 18:45:21 -0700 Subject: [PATCH] Updated spirv-cross. --- 3rdparty/spirv-cross/spirv_glsl.cpp | 36 +++++-- 3rdparty/spirv-cross/spirv_hlsl.cpp | 153 ++++++++++++++++++++++++++++ 3rdparty/spirv-cross/spirv_hlsl.hpp | 1 + 3rdparty/spirv-cross/spirv_msl.cpp | 12 +-- 3rdparty/spirv-cross/spirv_msl.hpp | 2 +- 5 files changed, 186 insertions(+), 18 deletions(-) diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index f25c3b42c..4051dd654 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -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 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(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(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; } diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index e44ed846c..8bb6b69f0 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -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"; 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(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; diff --git a/3rdparty/spirv-cross/spirv_hlsl.hpp b/3rdparty/spirv-cross/spirv_hlsl.hpp index 54a49dafa..23b97f112 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.hpp +++ b/3rdparty/spirv-cross/spirv_hlsl.hpp @@ -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; diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index 75551b46e..04555f43c 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -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"; + return "raytracing::intersection_query"; default: return "unknown_type"; diff --git a/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/spirv-cross/spirv_msl.hpp index b3b706ec7..b1abd12af 100644 --- a/3rdparty/spirv-cross/spirv_msl.hpp +++ b/3rdparty/spirv-cross/spirv_msl.hpp @@ -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,