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 185a0982..e8c1c869 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 8f6cfaf9..1750e945 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 a966c032..b649e8a6 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 185a0982..e8c1c869 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 8f6cfaf9..1750e945 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 a966c032..b649e8a6 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 3499dead..fa1e55bf 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -17737,6 +17737,25 @@ void CompilerGLSL::cast_from_variable_load(uint32_t source_id, std::string &expr expr = bitcast_expression(expr_type, expected_type, expr); } +SPIRType::BaseType CompilerGLSL::get_builtin_basetype(BuiltIn builtin, SPIRType::BaseType default_type) +{ + // TODO: Fill in for more builtins. + switch (builtin) + { + case BuiltInLayer: + case BuiltInPrimitiveId: + case BuiltInViewportIndex: + case BuiltInFragStencilRefEXT: + case BuiltInSampleMask: + case BuiltInPrimitiveShadingRateKHR: + case BuiltInShadingRateKHR: + return SPIRType::Int; + + default: + 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); @@ -17748,24 +17767,7 @@ void CompilerGLSL::cast_to_variable_store(uint32_t target_id, std::string &expr, return; auto builtin = static_cast(get_decoration(target_id, DecorationBuiltIn)); - auto expected_type = expr_type.basetype; - - // TODO: Fill in for more builtins. - switch (builtin) - { - case BuiltInLayer: - case BuiltInPrimitiveId: - case BuiltInViewportIndex: - case BuiltInFragStencilRefEXT: - case BuiltInSampleMask: - case BuiltInPrimitiveShadingRateKHR: - case BuiltInShadingRateKHR: - expected_type = SPIRType::Int; - break; - - default: - break; - } + 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 8a841f34..a9fbb62c 100644 --- a/spirv_glsl.hpp +++ b/spirv_glsl.hpp @@ -993,6 +993,7 @@ protected: // 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 29b1e770..32ca72e9 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 a5d30b1b..bec458c6 100644 --- a/spirv_hlsl.hpp +++ b/spirv_hlsl.hpp @@ -126,7 +126,7 @@ public: // 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 @@ private: 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 @@ private: 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;