@@ -654,6 +654,20 @@ void CompilerGLSL::find_static_extensions()
654654 ray_tracing_is_khr = true;
655655 break;
656656
657+ case CapabilityRayQueryPositionFetchKHR:
658+ if (options.es || options.version < 460 || !options.vulkan_semantics)
659+ SPIRV_CROSS_THROW("RayQuery Position Fetch requires Vulkan GLSL 460.");
660+ require_extension_internal("GL_EXT_ray_tracing_position_fetch");
661+ ray_tracing_is_khr = true;
662+ break;
663+
664+ case CapabilityRayTracingPositionFetchKHR:
665+ if (options.es || options.version < 460 || !options.vulkan_semantics)
666+ SPIRV_CROSS_THROW("Ray Tracing Position Fetch requires Vulkan GLSL 460.");
667+ require_extension_internal("GL_EXT_ray_tracing_position_fetch");
668+ ray_tracing_is_khr = true;
669+ break;
670+
657671 case CapabilityRayTraversalPrimitiveCullingKHR:
658672 if (options.es || options.version < 460 || !options.vulkan_semantics)
659673 SPIRV_CROSS_THROW("RayQuery requires Vulkan GLSL 460.");
@@ -5040,10 +5054,10 @@ void CompilerGLSL::emit_polyfills(uint32_t polyfills, bool relaxed)
50405054// Returns a string representation of the ID, usable as a function arg.
50415055// Default is to simply return the expression representation fo the arg ID.
50425056// Subclasses may override to modify the return value.
5043- string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &, uint32_t id)
5057+ string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &arg , uint32_t id)
50445058{
50455059 // BDA expects pointers through function interface.
5046- if (is_physical_pointer (expression_type(id)))
5060+ if (!arg.alias_global_variable && is_physical_or_buffer_pointer (expression_type(id)))
50475061 return to_pointer_expression(id);
50485062
50495063 // Make sure that we use the name of the original variable, and not the parameter alias.
@@ -6885,6 +6899,16 @@ void CompilerGLSL::emit_uninitialized_temporary(uint32_t result_type, uint32_t r
68856899 }
68866900}
68876901
6902+ bool CompilerGLSL::can_declare_inline_temporary(uint32_t id) const
6903+ {
6904+ if (!block_temporary_hoisting && current_continue_block && !hoisted_temporaries.count(id))
6905+ return false;
6906+ if (hoisted_temporaries.count(id))
6907+ return false;
6908+
6909+ return true;
6910+ }
6911+
68886912string CompilerGLSL::declare_temporary(uint32_t result_type, uint32_t result_id)
68896913{
68906914 auto &type = get<SPIRType>(result_type);
@@ -6962,6 +6986,42 @@ SPIRExpression &CompilerGLSL::emit_op(uint32_t result_type, uint32_t result_id,
69626986 }
69636987}
69646988
6989+ void CompilerGLSL::emit_transposed_op(uint32_t result_type, uint32_t result_id, const string &rhs, bool forwarding)
6990+ {
6991+ if (forwarding && (forced_temporaries.find(result_id) == end(forced_temporaries)))
6992+ {
6993+ // Just forward it without temporary.
6994+ // If the forward is trivial, we do not force flushing to temporary for this expression.
6995+ forwarded_temporaries.insert(result_id);
6996+ auto &e = set<SPIRExpression>(result_id, rhs, result_type, true);
6997+ e.need_transpose = true;
6998+ }
6999+ else if (can_declare_inline_temporary(result_id))
7000+ {
7001+ // If expression isn't immutable, bind it to a temporary and make the new temporary immutable (they always are).
7002+ // Since the expression is transposed, we have to ensure the temporary is the transposed type.
7003+
7004+ auto &transposed_type_id = extra_sub_expressions[result_id];
7005+ if (!transposed_type_id)
7006+ {
7007+ auto dummy_type = get<SPIRType>(result_type);
7008+ std::swap(dummy_type.columns, dummy_type.vecsize);
7009+ transposed_type_id = ir.increase_bound_by(1);
7010+ set<SPIRType>(transposed_type_id, dummy_type);
7011+ }
7012+
7013+ statement(declare_temporary(transposed_type_id, result_id), rhs, ";");
7014+ auto &e = set<SPIRExpression>(result_id, to_name(result_id), result_type, true);
7015+ e.need_transpose = true;
7016+ }
7017+ else
7018+ {
7019+ // If we cannot declare the temporary because it's already been hoisted, we don't have the
7020+ // chance to override the temporary type ourselves. Just transpose() the expression.
7021+ emit_op(result_type, result_id, join("transpose(", rhs, ")"), forwarding);
7022+ }
7023+ }
7024+
69657025void CompilerGLSL::emit_unary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op)
69667026{
69677027 bool forward = should_forward(op0);
@@ -10402,6 +10462,14 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
1040210462 case BuiltInCullPrimitiveEXT:
1040310463 return "gl_CullPrimitiveEXT";
1040410464
10465+ case BuiltInHitTriangleVertexPositionsKHR:
10466+ {
10467+ if (!options.vulkan_semantics)
10468+ SPIRV_CROSS_THROW("Need Vulkan semantics for EXT_ray_tracing_position_fetch.");
10469+ require_extension_internal("GL_EXT_ray_tracing_position_fetch");
10470+ return "gl_HitTriangleVertexPositionsEXT";
10471+ }
10472+
1040510473 case BuiltInClusterIDNV:
1040610474 {
1040710475 if (!options.vulkan_semantics)
@@ -11564,7 +11632,7 @@ bool CompilerGLSL::should_dereference(uint32_t id)
1156411632 // If id is a variable but not a phi variable, we should not dereference it.
1156511633 // BDA passed around as parameters are always pointers.
1156611634 if (auto *var = maybe_get<SPIRVariable>(id))
11567- return (var->parameter && is_physical_pointer (type)) || var->phi_variable;
11635+ return (var->parameter && is_physical_or_buffer_pointer (type)) || var->phi_variable;
1156811636
1156911637 if (auto *expr = maybe_get<SPIRExpression>(id))
1157011638 {
@@ -11600,8 +11668,8 @@ bool CompilerGLSL::should_dereference(uint32_t id)
1160011668bool CompilerGLSL::should_dereference_caller_param(uint32_t id)
1160111669{
1160211670 const auto &type = expression_type(id);
11603- // BDA is always passed around as pointers.
11604- if (is_physical_pointer (type))
11671+ // BDA is always passed around as pointers. Similarly, we need to pass variable buffer pointers as pointers.
11672+ if (is_physical_or_buffer_pointer (type))
1160511673 return false;
1160611674
1160711675 return should_dereference(id);
@@ -13490,8 +13558,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1349013558 auto expr = join(enclose_expression(to_unpacked_row_major_matrix_expression(ops[3])), " * ",
1349113559 enclose_expression(to_unpacked_row_major_matrix_expression(ops[2])));
1349213560 bool forward = should_forward(ops[2]) && should_forward(ops[3]);
13493- auto &e = emit_op(ops[0], ops[1], expr, forward);
13494- e.need_transpose = true;
13561+ emit_transposed_op(ops[0], ops[1], expr, forward);
1349513562 a->need_transpose = true;
1349613563 b->need_transpose = true;
1349713564 inherit_expression_dependencies(ops[1], ops[2]);
@@ -13514,8 +13581,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1351413581 auto expr = join(enclose_expression(to_unpacked_row_major_matrix_expression(ops[2])), " * ",
1351513582 to_enclosed_unpacked_expression(ops[3]));
1351613583 bool forward = should_forward(ops[2]) && should_forward(ops[3]);
13517- auto &e = emit_op(ops[0], ops[1], expr, forward);
13518- e.need_transpose = true;
13584+ emit_transposed_op(ops[0], ops[1], expr, forward);
1351913585 a->need_transpose = true;
1352013586 inherit_expression_dependencies(ops[1], ops[2]);
1352113587 inherit_expression_dependencies(ops[1], ops[3]);
@@ -15535,6 +15601,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
1553515601 flush_variable_declaration(ops[0]);
1553615602 statement("rayQueryConfirmIntersectionEXT(", to_expression(ops[0]), ");");
1553715603 break;
15604+ case OpRayQueryGetIntersectionTriangleVertexPositionsKHR:
15605+ flush_variable_declaration(ops[1]);
15606+ emit_uninitialized_temporary_expression(ops[0], ops[1]);
15607+ statement("rayQueryGetIntersectionTriangleVertexPositionsEXT(", to_expression(ops[2]), ", bool(", to_expression(ops[3]), "), ", to_expression(ops[1]), ");");
15608+ break;
1553815609#define GLSL_RAY_QUERY_GET_OP(op) \
1553915610 case OpRayQueryGet##op##KHR: \
1554015611 flush_variable_declaration(ops[2]); \
0 commit comments