diff --git a/3rdparty/spirv-cross/spirv_cross.cpp b/3rdparty/spirv-cross/spirv_cross.cpp index 199d0fd25..f024fa78b 100644 --- a/3rdparty/spirv-cross/spirv_cross.cpp +++ b/3rdparty/spirv-cross/spirv_cross.cpp @@ -546,10 +546,16 @@ bool Compiler::is_hidden_variable(const SPIRVariable &var, bool include_builtins return false; } - bool hidden = false; - if (check_active_interface_variables && storage_class_is_interface(var.storage)) - hidden = active_interface_variables.find(var.self) == end(active_interface_variables); - return hidden; + // In SPIR-V 1.4 and up we must also use the active variable interface to disable global variables + // which are not part of the entry point. + if (ir.get_spirv_version() >= 0x10400 && var.storage != spv::StorageClassGeneric && + var.storage != spv::StorageClassFunction && !interface_variable_exists_in_entry_point(var.self)) + { + return true; + } + + return check_active_interface_variables && storage_class_is_interface(var.storage) && + active_interface_variables.find(var.self) == end(active_interface_variables); } bool Compiler::is_builtin_type(const SPIRType &type) const diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index 0b93413a6..ca8267ec1 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -538,9 +538,11 @@ void CompilerGLSL::ray_tracing_khr_fixup_locations() { uint32_t location = 0; ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { - if (var.storage != StorageClassRayPayloadKHR && var.storage != StorageClassCallableDataKHR) + // Incoming payload storage can also be used for tracing. + if (var.storage != StorageClassRayPayloadKHR && var.storage != StorageClassCallableDataKHR && + var.storage != StorageClassIncomingRayPayloadKHR && var.storage != StorageClassIncomingCallableDataKHR) return; - if (!interface_variable_exists_in_entry_point(var.self)) + if (is_hidden_variable(var)) return; set_decoration(var.self, DecorationLocation, location++); }); @@ -3451,6 +3453,9 @@ void CompilerGLSL::emit_resources() for (auto global : global_variables) { auto &var = get(global); + if (is_hidden_variable(var, true)) + continue; + if (var.storage != StorageClassOutput) { if (!variable_is_lut(var)) @@ -4283,6 +4288,44 @@ string CompilerGLSL::to_extract_component_expression(uint32_t id, uint32_t index return join(expr, ".", index_to_swizzle(index)); } +string CompilerGLSL::to_extract_constant_composite_expression(uint32_t result_type, const SPIRConstant &c, + const uint32_t *chain, uint32_t length) +{ + // It is kinda silly if application actually enter this path since they know the constant up front. + // It is useful here to extract the plain constant directly. + SPIRConstant tmp; + tmp.constant_type = result_type; + auto &composite_type = get(c.constant_type); + assert(composite_type.basetype != SPIRType::Struct && composite_type.array.empty()); + assert(!c.specialization); + + if (is_matrix(composite_type)) + { + if (length == 2) + { + tmp.m.c[0].vecsize = 1; + tmp.m.columns = 1; + tmp.m.c[0].r[0] = c.m.c[chain[0]].r[chain[1]]; + } + else + { + assert(length == 1); + tmp.m.c[0].vecsize = composite_type.vecsize; + tmp.m.columns = 1; + tmp.m.c[0] = c.m.c[chain[0]]; + } + } + else + { + assert(length == 1); + tmp.m.c[0].vecsize = 1; + tmp.m.columns = 1; + tmp.m.c[0].r[0] = c.m.c[0].r[chain[0]]; + } + + return constant_expression(tmp); +} + string CompilerGLSL::to_rerolled_array_expression(const string &base_expr, const SPIRType &type) { uint32_t size = to_array_size_literal(type); @@ -10179,7 +10222,8 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) // Do not allow base expression for struct members. We risk doing "swizzle" optimizations in this case. auto &composite_type = expression_type(ops[2]); - if (composite_type.basetype == SPIRType::Struct || !composite_type.array.empty()) + bool composite_type_is_complex = composite_type.basetype == SPIRType::Struct || !composite_type.array.empty(); + if (composite_type_is_complex) allow_base_expression = false; // Packed expressions or physical ID mapped expressions cannot be split up. @@ -10194,10 +10238,17 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) AccessChainMeta meta; SPIRExpression *e = nullptr; + auto *c = maybe_get(ops[2]); - // Only apply this optimization if result is scalar. - if (allow_base_expression && should_forward(ops[2]) && type.vecsize == 1 && type.columns == 1 && length == 1) + if (c && !c->specialization && !composite_type_is_complex) { + auto expr = to_extract_constant_composite_expression(result_type, *c, ops + 3, length); + e = &emit_op(result_type, id, expr, true, true); + } + else if (allow_base_expression && should_forward(ops[2]) && type.vecsize == 1 && type.columns == 1 && length == 1) + { + // Only apply this optimization if result is scalar. + // We want to split the access chain from the base. // This is so we can later combine different CompositeExtract results // with CompositeConstruct without emitting code like @@ -12216,6 +12267,8 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) flush_control_dependent_expressions(current_emitting_block->self); break; case OpTraceNV: + if (has_decoration(ops[0], DecorationNonUniformEXT)) + propagate_nonuniform_qualifier(ops[0]); statement("traceNV(", to_expression(ops[0]), ", ", to_expression(ops[1]), ", ", to_expression(ops[2]), ", ", to_expression(ops[3]), ", ", to_expression(ops[4]), ", ", to_expression(ops[5]), ", ", to_expression(ops[6]), ", ", to_expression(ops[7]), ", ", to_expression(ops[8]), ", ", @@ -12225,6 +12278,8 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) case OpTraceRayKHR: if (!has_decoration(ops[10], DecorationLocation)) SPIRV_CROSS_THROW("A memory declaration object must be used in TraceRayKHR."); + if (has_decoration(ops[0], DecorationNonUniformEXT)) + propagate_nonuniform_qualifier(ops[0]); statement("traceRayEXT(", to_expression(ops[0]), ", ", to_expression(ops[1]), ", ", to_expression(ops[2]), ", ", to_expression(ops[3]), ", ", to_expression(ops[4]), ", ", to_expression(ops[5]), ", ", to_expression(ops[6]), ", ", to_expression(ops[7]), ", ", to_expression(ops[8]), ", ", @@ -15009,7 +15064,7 @@ void CompilerGLSL::convert_non_uniform_expression(const SPIRType &type, std::str // Handle SPV_EXT_descriptor_indexing. if (type.basetype == SPIRType::Sampler || type.basetype == SPIRType::SampledImage || - type.basetype == SPIRType::Image) + type.basetype == SPIRType::Image || type.basetype == SPIRType::AccelerationStructure) { // The image/sampler ID must be declared as non-uniform. // However, it is not legal GLSL to have diff --git a/3rdparty/spirv-cross/spirv_glsl.hpp b/3rdparty/spirv-cross/spirv_glsl.hpp index beb8a8fb0..00b081973 100644 --- a/3rdparty/spirv-cross/spirv_glsl.hpp +++ b/3rdparty/spirv-cross/spirv_glsl.hpp @@ -701,6 +701,8 @@ protected: std::string to_pointer_expression(uint32_t id, bool register_expression_read = true); std::string to_enclosed_pointer_expression(uint32_t id, bool register_expression_read = true); std::string to_extract_component_expression(uint32_t id, uint32_t index); + std::string to_extract_constant_composite_expression(uint32_t result_type, const SPIRConstant &c, + const uint32_t *chain, uint32_t length); std::string enclose_expression(const std::string &expr); std::string dereference_expression(const SPIRType &expression_type, const std::string &expr); std::string address_of_expression(const std::string &expr); diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index c080ff663..c74fb5f6d 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -1362,7 +1362,8 @@ void CompilerHLSL::emit_resources() } if (var.storage != StorageClassFunction && !is_builtin_variable(var) && !var.remapped_variable && - type.pointer && (type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter)) + type.pointer && (type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter) && + !is_hidden_variable(var)) { emit_uniform(var); emitted = true; @@ -1516,6 +1517,9 @@ void CompilerHLSL::emit_resources() for (auto global : global_variables) { auto &var = get(global); + if (is_hidden_variable(var, true)) + continue; + if (var.storage != StorageClassOutput) { if (!variable_is_lut(var))