diff --git a/reference/opt/shaders-hlsl/frag/switch-unsigned-case.frag b/reference/opt/shaders-hlsl/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..d7ec92f0 --- /dev/null +++ b/reference/opt/shaders-hlsl/frag/switch-unsigned-case.frag @@ -0,0 +1,38 @@ +cbuffer Buff : register(b0) +{ + uint _15_TestVal : packoffset(c0); +}; + + +static float4 fsout_Color; + +struct SPIRV_Cross_Output +{ + float4 fsout_Color : SV_Target0; +}; + +void frag_main() +{ + fsout_Color = 1.0f.xxxx; + switch (_15_TestVal) + { + case 0u: + { + fsout_Color = 0.100000001490116119384765625f.xxxx; + break; + } + case 1u: + { + fsout_Color = 0.20000000298023223876953125f.xxxx; + break; + } + } +} + +SPIRV_Cross_Output main() +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.fsout_Color = fsout_Color; + return stage_output; +} diff --git a/reference/opt/shaders-msl/frag/switch-unsigned-case.frag b/reference/opt/shaders-msl/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..4cd2b685 --- /dev/null +++ b/reference/opt/shaders-msl/frag/switch-unsigned-case.frag @@ -0,0 +1,35 @@ +#include +#include + +using namespace metal; + +struct Buff +{ + uint TestVal; +}; + +struct main0_out +{ + float4 fsout_Color [[color(0)]]; +}; + +fragment main0_out main0(constant Buff& _15 [[buffer(0)]]) +{ + main0_out out = {}; + out.fsout_Color = float4(1.0); + switch (_15.TestVal) + { + case 0u: + { + out.fsout_Color = float4(0.100000001490116119384765625); + break; + } + case 1u: + { + out.fsout_Color = float4(0.20000000298023223876953125); + break; + } + } + return out; +} + diff --git a/reference/opt/shaders/frag/switch-unsigned-case.frag b/reference/opt/shaders/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..4177f9e9 --- /dev/null +++ b/reference/opt/shaders/frag/switch-unsigned-case.frag @@ -0,0 +1,29 @@ +#version 310 es +precision mediump float; +precision highp int; + +layout(binding = 0, std140) uniform Buff +{ + mediump uint TestVal; +} _15; + +layout(location = 0) out vec4 fsout_Color; + +void main() +{ + fsout_Color = vec4(1.0); + switch (_15.TestVal) + { + case 0u: + { + fsout_Color = vec4(0.100000001490116119384765625); + break; + } + case 1u: + { + fsout_Color = vec4(0.20000000298023223876953125); + break; + } + } +} + diff --git a/reference/shaders-hlsl/frag/switch-unsigned-case.frag b/reference/shaders-hlsl/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..d7ec92f0 --- /dev/null +++ b/reference/shaders-hlsl/frag/switch-unsigned-case.frag @@ -0,0 +1,38 @@ +cbuffer Buff : register(b0) +{ + uint _15_TestVal : packoffset(c0); +}; + + +static float4 fsout_Color; + +struct SPIRV_Cross_Output +{ + float4 fsout_Color : SV_Target0; +}; + +void frag_main() +{ + fsout_Color = 1.0f.xxxx; + switch (_15_TestVal) + { + case 0u: + { + fsout_Color = 0.100000001490116119384765625f.xxxx; + break; + } + case 1u: + { + fsout_Color = 0.20000000298023223876953125f.xxxx; + break; + } + } +} + +SPIRV_Cross_Output main() +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.fsout_Color = fsout_Color; + return stage_output; +} diff --git a/reference/shaders-msl/frag/switch-unsigned-case.frag b/reference/shaders-msl/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..4cd2b685 --- /dev/null +++ b/reference/shaders-msl/frag/switch-unsigned-case.frag @@ -0,0 +1,35 @@ +#include +#include + +using namespace metal; + +struct Buff +{ + uint TestVal; +}; + +struct main0_out +{ + float4 fsout_Color [[color(0)]]; +}; + +fragment main0_out main0(constant Buff& _15 [[buffer(0)]]) +{ + main0_out out = {}; + out.fsout_Color = float4(1.0); + switch (_15.TestVal) + { + case 0u: + { + out.fsout_Color = float4(0.100000001490116119384765625); + break; + } + case 1u: + { + out.fsout_Color = float4(0.20000000298023223876953125); + break; + } + } + return out; +} + diff --git a/reference/shaders/frag/switch-unsigned-case.frag b/reference/shaders/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..4177f9e9 --- /dev/null +++ b/reference/shaders/frag/switch-unsigned-case.frag @@ -0,0 +1,29 @@ +#version 310 es +precision mediump float; +precision highp int; + +layout(binding = 0, std140) uniform Buff +{ + mediump uint TestVal; +} _15; + +layout(location = 0) out vec4 fsout_Color; + +void main() +{ + fsout_Color = vec4(1.0); + switch (_15.TestVal) + { + case 0u: + { + fsout_Color = vec4(0.100000001490116119384765625); + break; + } + case 1u: + { + fsout_Color = vec4(0.20000000298023223876953125); + break; + } + } +} + diff --git a/shaders-hlsl/frag/switch-unsigned-case.frag b/shaders-hlsl/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..d8aee43a --- /dev/null +++ b/shaders-hlsl/frag/switch-unsigned-case.frag @@ -0,0 +1,26 @@ +#version 310 es +precision mediump float; + +#define ENUM_0 0u +#define ENUM_1 1u + +layout(set = 0, binding = 0) uniform Buff +{ + uint TestVal; +}; + +layout(location = 0) out vec4 fsout_Color; + +void main() +{ + fsout_Color = vec4(1.0); + switch (TestVal) + { + case ENUM_0: + fsout_Color = vec4(0.1); + break; + case ENUM_1: + fsout_Color = vec4(0.2); + break; + } +} diff --git a/shaders-msl/frag/switch-unsigned-case.frag b/shaders-msl/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..d8aee43a --- /dev/null +++ b/shaders-msl/frag/switch-unsigned-case.frag @@ -0,0 +1,26 @@ +#version 310 es +precision mediump float; + +#define ENUM_0 0u +#define ENUM_1 1u + +layout(set = 0, binding = 0) uniform Buff +{ + uint TestVal; +}; + +layout(location = 0) out vec4 fsout_Color; + +void main() +{ + fsout_Color = vec4(1.0); + switch (TestVal) + { + case ENUM_0: + fsout_Color = vec4(0.1); + break; + case ENUM_1: + fsout_Color = vec4(0.2); + break; + } +} diff --git a/shaders/frag/switch-unsigned-case.frag b/shaders/frag/switch-unsigned-case.frag new file mode 100644 index 00000000..d8aee43a --- /dev/null +++ b/shaders/frag/switch-unsigned-case.frag @@ -0,0 +1,26 @@ +#version 310 es +precision mediump float; + +#define ENUM_0 0u +#define ENUM_1 1u + +layout(set = 0, binding = 0) uniform Buff +{ + uint TestVal; +}; + +layout(location = 0) out vec4 fsout_Color; + +void main() +{ + fsout_Color = vec4(1.0); + switch (TestVal) + { + case ENUM_0: + fsout_Color = vec4(0.1); + break; + case ENUM_1: + fsout_Color = vec4(0.2); + break; + } +} diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 0f50b4af..e0ea30c4 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -10217,6 +10217,20 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) auto &type = expression_type(block.condition); bool unsigned_case = type.basetype == SPIRType::UInt || type.basetype == SPIRType::UShort; + if (type.basetype == SPIRType::UInt64 || type.basetype == SPIRType::Int64) + { + // SPIR-V spec suggests this is allowed, but we cannot support it in higher level languages. + SPIRV_CROSS_THROW("Cannot use 64-bit switch selectors."); + } + + const char *label_suffix = ""; + if (type.basetype == SPIRType::UInt && backend.uint32_t_literal_suffix) + label_suffix = "u"; + else if (type.basetype == SPIRType::UShort) + label_suffix = backend.uint16_t_literal_suffix; + else if (type.basetype == SPIRType::Short) + label_suffix = backend.int16_t_literal_suffix; + SPIRBlock *old_emitting_switch = current_emitting_switch; current_emitting_switch = █ @@ -10242,9 +10256,10 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) { if (other_case.block == c.block) { + // The case label value must be sign-extended properly in SPIR-V, so we can assume 32-bit values here. auto case_value = unsigned_case ? convert_to_string(uint32_t(other_case.value)) : convert_to_string(int32_t(other_case.value)); - statement("case ", case_value, ":"); + statement("case ", case_value, label_suffix, ":"); } }