diff --git a/reference/opt/shaders-hlsl/frag/sample-mask-in-and-out.frag b/reference/opt/shaders-hlsl/frag/sample-mask-in-and-out.frag index 185a09821..e8c1c8698 100644 --- a/reference/opt/shaders-hlsl/frag/sample-mask-in-and-out.frag +++ b/reference/opt/shaders-hlsl/frag/sample-mask-in-and-out.frag @@ -1,5 +1,5 @@ -static int gl_SampleMaskIn; -static int gl_SampleMask; +static uint gl_SampleMaskIn[1]; +static uint gl_SampleMask[1]; static float4 FragColor; struct SPIRV_Cross_Input @@ -16,15 +16,15 @@ struct SPIRV_Cross_Output void frag_main() { FragColor = 1.0f.xxxx; - gl_SampleMask = gl_SampleMaskIn; + gl_SampleMask[0] = uint(gl_SampleMaskIn[0]); } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { - gl_SampleMaskIn = stage_input.gl_SampleMaskIn; + gl_SampleMaskIn[0] = stage_input.gl_SampleMaskIn; frag_main(); SPIRV_Cross_Output stage_output; - stage_output.gl_SampleMask = gl_SampleMask; + stage_output.gl_SampleMask = gl_SampleMask[0]; stage_output.FragColor = FragColor; return stage_output; } diff --git a/reference/opt/shaders-hlsl/frag/sample-mask-in.frag b/reference/opt/shaders-hlsl/frag/sample-mask-in.frag index 8f6cfaf9e..1750e945a 100644 --- a/reference/opt/shaders-hlsl/frag/sample-mask-in.frag +++ b/reference/opt/shaders-hlsl/frag/sample-mask-in.frag @@ -1,5 +1,5 @@ static int gl_SampleID; -static int gl_SampleMaskIn; +static uint gl_SampleMaskIn[1]; static float4 FragColor; struct SPIRV_Cross_Input @@ -15,7 +15,7 @@ struct SPIRV_Cross_Output void frag_main() { - if ((gl_SampleMaskIn & (1 << gl_SampleID)) != 0) + if ((gl_SampleMaskIn[0] & (1 << gl_SampleID)) != 0) { FragColor = 1.0f.xxxx; } @@ -24,7 +24,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_SampleID = stage_input.gl_SampleID; - gl_SampleMaskIn = stage_input.gl_SampleMaskIn; + gl_SampleMaskIn[0] = stage_input.gl_SampleMaskIn; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/opt/shaders-hlsl/frag/sample-mask-out.frag b/reference/opt/shaders-hlsl/frag/sample-mask-out.frag index a966c0321..b649e8a62 100644 --- a/reference/opt/shaders-hlsl/frag/sample-mask-out.frag +++ b/reference/opt/shaders-hlsl/frag/sample-mask-out.frag @@ -1,4 +1,4 @@ -static int gl_SampleMask; +static uint gl_SampleMask[1]; static float4 FragColor; struct SPIRV_Cross_Output @@ -10,14 +10,14 @@ struct SPIRV_Cross_Output void frag_main() { FragColor = 1.0f.xxxx; - gl_SampleMask = 0; + gl_SampleMask[0] = uint(0); } SPIRV_Cross_Output main() { frag_main(); SPIRV_Cross_Output stage_output; - stage_output.gl_SampleMask = gl_SampleMask; + stage_output.gl_SampleMask = gl_SampleMask[0]; stage_output.FragColor = FragColor; return stage_output; } diff --git a/reference/shaders-hlsl/frag/sample-mask-in-and-out.frag b/reference/shaders-hlsl/frag/sample-mask-in-and-out.frag index 185a09821..e8c1c8698 100644 --- a/reference/shaders-hlsl/frag/sample-mask-in-and-out.frag +++ b/reference/shaders-hlsl/frag/sample-mask-in-and-out.frag @@ -1,5 +1,5 @@ -static int gl_SampleMaskIn; -static int gl_SampleMask; +static uint gl_SampleMaskIn[1]; +static uint gl_SampleMask[1]; static float4 FragColor; struct SPIRV_Cross_Input @@ -16,15 +16,15 @@ struct SPIRV_Cross_Output void frag_main() { FragColor = 1.0f.xxxx; - gl_SampleMask = gl_SampleMaskIn; + gl_SampleMask[0] = uint(gl_SampleMaskIn[0]); } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { - gl_SampleMaskIn = stage_input.gl_SampleMaskIn; + gl_SampleMaskIn[0] = stage_input.gl_SampleMaskIn; frag_main(); SPIRV_Cross_Output stage_output; - stage_output.gl_SampleMask = gl_SampleMask; + stage_output.gl_SampleMask = gl_SampleMask[0]; stage_output.FragColor = FragColor; return stage_output; } diff --git a/reference/shaders-hlsl/frag/sample-mask-in.frag b/reference/shaders-hlsl/frag/sample-mask-in.frag index 8f6cfaf9e..1750e945a 100644 --- a/reference/shaders-hlsl/frag/sample-mask-in.frag +++ b/reference/shaders-hlsl/frag/sample-mask-in.frag @@ -1,5 +1,5 @@ static int gl_SampleID; -static int gl_SampleMaskIn; +static uint gl_SampleMaskIn[1]; static float4 FragColor; struct SPIRV_Cross_Input @@ -15,7 +15,7 @@ struct SPIRV_Cross_Output void frag_main() { - if ((gl_SampleMaskIn & (1 << gl_SampleID)) != 0) + if ((gl_SampleMaskIn[0] & (1 << gl_SampleID)) != 0) { FragColor = 1.0f.xxxx; } @@ -24,7 +24,7 @@ void frag_main() SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { gl_SampleID = stage_input.gl_SampleID; - gl_SampleMaskIn = stage_input.gl_SampleMaskIn; + gl_SampleMaskIn[0] = stage_input.gl_SampleMaskIn; frag_main(); SPIRV_Cross_Output stage_output; stage_output.FragColor = FragColor; diff --git a/reference/shaders-hlsl/frag/sample-mask-out.frag b/reference/shaders-hlsl/frag/sample-mask-out.frag index a966c0321..b649e8a62 100644 --- a/reference/shaders-hlsl/frag/sample-mask-out.frag +++ b/reference/shaders-hlsl/frag/sample-mask-out.frag @@ -1,4 +1,4 @@ -static int gl_SampleMask; +static uint gl_SampleMask[1]; static float4 FragColor; struct SPIRV_Cross_Output @@ -10,14 +10,14 @@ struct SPIRV_Cross_Output void frag_main() { FragColor = 1.0f.xxxx; - gl_SampleMask = 0; + gl_SampleMask[0] = uint(0); } SPIRV_Cross_Output main() { frag_main(); SPIRV_Cross_Output stage_output; - stage_output.gl_SampleMask = gl_SampleMask; + stage_output.gl_SampleMask = gl_SampleMask[0]; stage_output.FragColor = FragColor; return stage_output; } diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 56639f0c0..935e60755 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -17718,19 +17718,8 @@ void CompilerGLSL::cast_from_variable_load(uint32_t source_id, std::string &expr expr = bitcast_expression(expr_type, expected_type, expr); } -void CompilerGLSL::cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) +SPIRType::BaseType CompilerGLSL::get_builtin_basetype(BuiltIn builtin, SPIRType::BaseType default_type) { - auto *var = maybe_get_backing_variable(target_id); - if (var) - target_id = var->self; - - // Only interested in standalone builtin variables. - if (!has_decoration(target_id, DecorationBuiltIn)) - return; - - auto builtin = static_cast(get_decoration(target_id, DecorationBuiltIn)); - auto expected_type = expr_type.basetype; - // TODO: Fill in for more builtins. switch (builtin) { @@ -17741,12 +17730,25 @@ void CompilerGLSL::cast_to_variable_store(uint32_t target_id, std::string &expr, case BuiltInSampleMask: case BuiltInPrimitiveShadingRateKHR: case BuiltInShadingRateKHR: - expected_type = SPIRType::Int; - break; + return SPIRType::Int; default: - break; + return default_type; } +} + +void CompilerGLSL::cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) +{ + auto *var = maybe_get_backing_variable(target_id); + if (var) + target_id = var->self; + + // Only interested in standalone builtin variables. + if (!has_decoration(target_id, DecorationBuiltIn)) + return; + + auto builtin = static_cast(get_decoration(target_id, DecorationBuiltIn)); + auto expected_type = get_builtin_basetype(builtin, expr_type.basetype); if (expected_type != expr_type.basetype) { diff --git a/spirv_glsl.hpp b/spirv_glsl.hpp index 8a841f34e..a9fbb62c0 100644 --- a/spirv_glsl.hpp +++ b/spirv_glsl.hpp @@ -993,6 +993,7 @@ class CompilerGLSL : public Compiler // Builtins in GLSL are always specific signedness, but the SPIR-V can declare them // as either unsigned or signed. // Sometimes we will need to automatically perform casts on load and store to make this work. + virtual SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type); virtual void cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type); virtual void cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type); void unroll_array_from_complex_load(uint32_t target_id, uint32_t source_id, std::string &expr); diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 29b1e7709..32ca72e94 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -1288,7 +1288,8 @@ void CompilerHLSL::emit_builtin_variables() break; case BuiltInSampleMask: - type = "int"; + type = "uint"; + array_size = 1; break; case BuiltInPrimitiveId: @@ -1322,7 +1323,10 @@ void CompilerHLSL::emit_builtin_variables() // declared the input variable and we need to add the output one now. if (builtin == BuiltInSampleMask && storage == StorageClassInput && this->active_output_builtins.get(i)) { - statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), init_expr, ";"); + if (array_size) + statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), "[", array_size, "]", init_expr, ";"); + else + statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), init_expr, ";"); } }); @@ -1536,6 +1540,17 @@ void CompilerHLSL::replace_illegal_names() CompilerGLSL::replace_illegal_names(); } +SPIRType::BaseType CompilerHLSL::get_builtin_basetype(BuiltIn builtin, SPIRType::BaseType default_type) +{ + switch (builtin) + { + case BuiltInSampleMask: + return SPIRType::UInt; + default: + return CompilerGLSL::get_builtin_basetype(builtin, default_type); + } +} + void CompilerHLSL::emit_resources() { auto &execution = get_entry_point(); @@ -3121,6 +3136,10 @@ void CompilerHLSL::emit_hlsl_entry_point() statement(builtin, " = int(stage_input.", builtin, ");"); break; + case BuiltInSampleMask: + statement(builtin, "[0] = stage_input.", builtin, ";"); + break; + case BuiltInNumWorkgroups: case BuiltInPointCoord: case BuiltInSubgroupSize: @@ -3295,6 +3314,10 @@ void CompilerHLSL::emit_hlsl_entry_point() cull, "];"); break; + case BuiltInSampleMask: + statement("stage_output.gl_SampleMask = gl_SampleMask[0];"); + break; + default: { auto builtin_expr = builtin_to_glsl(static_cast(i), StorageClassOutput); @@ -6751,11 +6774,6 @@ void CompilerHLSL::set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint3 force_uav_buffer_bindings.insert(pair); } -bool CompilerHLSL::builtin_translates_to_nonarray(spv::BuiltIn builtin) const -{ - return (builtin == BuiltInSampleMask); -} - bool CompilerHLSL::is_user_type_structured(uint32_t id) const { if (hlsl_options.preserve_structured_buffers) diff --git a/spirv_hlsl.hpp b/spirv_hlsl.hpp index a5d30b1b2..bec458c61 100644 --- a/spirv_hlsl.hpp +++ b/spirv_hlsl.hpp @@ -126,7 +126,7 @@ class CompilerHLSL : public CompilerGLSL // By default, a readonly storage buffer will be declared as ByteAddressBuffer (SRV) instead. // Alternatively, use set_hlsl_force_storage_buffer_as_uav to specify individually. bool force_storage_buffer_as_uav = false; - + // Forces any storage image type marked as NonWritable to be considered an SRV instead. // For this to work with function call parameters, NonWritable must be considered to be part of the type system // so that NonWritable image arguments are also translated to Texture rather than RWTexture. @@ -290,6 +290,8 @@ class CompilerHLSL : public CompilerGLSL const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override; void replace_illegal_names() override; + SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type) override; + bool is_hlsl_force_storage_buffer_as_uav(ID id) const; Options hlsl_options; @@ -400,9 +402,6 @@ class CompilerHLSL : public CompilerGLSL bool used = false; } base_vertex_info; - // Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL. - bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override; - // Returns true if the specified ID has a UserTypeGOOGLE decoration for StructuredBuffer or RWStructuredBuffer resources. bool is_user_type_structured(uint32_t id) const override;