diff --git a/reference/shaders-hlsl/frag/image-query-selective.frag b/reference/shaders-hlsl/frag/image-query-selective.frag new file mode 100644 index 0000000..e611546 --- /dev/null +++ b/reference/shaders-hlsl/frag/image-query-selective.frag @@ -0,0 +1,145 @@ +Texture1D uSampler1DUint : register(t0); +SamplerState _uSampler1DUint_sampler : register(s0); +Texture1D uSampler1DInt : register(t0); +SamplerState _uSampler1DInt_sampler : register(s0); +Texture1D uSampler1DFloat : register(t0); +SamplerState _uSampler1DFloat_sampler : register(s0); +Texture2DArray uSampler2DArray : register(t2); +SamplerState _uSampler2DArray_sampler : register(s2); +Texture3D uSampler3D : register(t3); +SamplerState _uSampler3D_sampler : register(s3); +TextureCube uSamplerCube : register(t4); +SamplerState _uSamplerCube_sampler : register(s4); +TextureCubeArray uSamplerCubeArray : register(t5); +SamplerState _uSamplerCubeArray_sampler : register(s5); +Buffer uSamplerBuffer : register(t6); +Texture2DMS uSamplerMS : register(t7); +SamplerState _uSamplerMS_sampler : register(s7); +Texture2DMSArray uSamplerMSArray : register(t8); +SamplerState _uSamplerMSArray_sampler : register(s8); +Texture2D uSampler2D : register(t1); +SamplerState _uSampler2D_sampler : register(s1); + +uint SPIRV_Cross_textureSize(Texture1D Tex, uint Level, out uint Param) +{ + uint ret; + Tex.GetDimensions(Level, ret.x, Param); + return ret; +} + +uint SPIRV_Cross_textureSize(Texture1D Tex, uint Level, out uint Param) +{ + uint ret; + Tex.GetDimensions(Level, ret.x, Param); + return ret; +} + +uint SPIRV_Cross_textureSize(Texture1D Tex, uint Level, out uint Param) +{ + uint ret; + Tex.GetDimensions(Level, ret.x, Param); + return ret; +} + +uint2 SPIRV_Cross_textureSize(Texture2D Tex, uint Level, out uint Param) +{ + uint2 ret; + Tex.GetDimensions(Level, ret.x, ret.y, Param); + return ret; +} + +uint3 SPIRV_Cross_textureSize(Texture2DArray Tex, uint Level, out uint Param) +{ + uint3 ret; + Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); + return ret; +} + +uint3 SPIRV_Cross_textureSize(Texture3D Tex, uint Level, out uint Param) +{ + uint3 ret; + Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); + return ret; +} + +uint SPIRV_Cross_textureSize(Buffer Tex, uint Level, out uint Param) +{ + uint ret; + Tex.GetDimensions(ret.x); + return ret; +} + +uint2 SPIRV_Cross_textureSize(TextureCube Tex, uint Level, out uint Param) +{ + uint2 ret; + Tex.GetDimensions(Level, ret.x, ret.y, Param); + return ret; +} + +uint3 SPIRV_Cross_textureSize(TextureCubeArray Tex, uint Level, out uint Param) +{ + uint3 ret; + Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); + return ret; +} + +uint2 SPIRV_Cross_textureSize(Texture2DMS Tex, uint Level, out uint Param) +{ + uint2 ret; + Tex.GetDimensions(ret.x, ret.y, Param); + return ret; +} + +uint3 SPIRV_Cross_textureSize(Texture2DMSArray Tex, uint Level, out uint Param) +{ + uint3 ret; + Tex.GetDimensions(ret.x, ret.y, ret.z, Param); + return ret; +} + +void frag_main() +{ + uint _17_dummy_parameter; + int a = int(SPIRV_Cross_textureSize(uSampler1DUint, uint(0), _17_dummy_parameter)); + uint _24_dummy_parameter; + a = int(SPIRV_Cross_textureSize(uSampler1DInt, uint(0), _24_dummy_parameter)); + uint _32_dummy_parameter; + a = int(SPIRV_Cross_textureSize(uSampler1DFloat, uint(0), _32_dummy_parameter)); + uint _42_dummy_parameter; + int3 c = int3(SPIRV_Cross_textureSize(uSampler2DArray, uint(0), _42_dummy_parameter)); + uint _50_dummy_parameter; + int3 d = int3(SPIRV_Cross_textureSize(uSampler3D, uint(0), _50_dummy_parameter)); + uint _60_dummy_parameter; + int2 e = int2(SPIRV_Cross_textureSize(uSamplerCube, uint(0), _60_dummy_parameter)); + uint _68_dummy_parameter; + int3 f = int3(SPIRV_Cross_textureSize(uSamplerCubeArray, uint(0), _68_dummy_parameter)); + uint _76_dummy_parameter; + int g = int(SPIRV_Cross_textureSize(uSamplerBuffer, 0u, _76_dummy_parameter)); + uint _84_dummy_parameter; + int2 h = int2(SPIRV_Cross_textureSize(uSamplerMS, 0u, _84_dummy_parameter)); + uint _92_dummy_parameter; + int3 i = int3(SPIRV_Cross_textureSize(uSamplerMSArray, 0u, _92_dummy_parameter)); + int _100; + SPIRV_Cross_textureSize(uSampler2D, 0u, _100); + int l1 = int(_100); + int _104; + SPIRV_Cross_textureSize(uSampler2DArray, 0u, _104); + int l2 = int(_104); + int _108; + SPIRV_Cross_textureSize(uSampler3D, 0u, _108); + int l3 = int(_108); + int _112; + SPIRV_Cross_textureSize(uSamplerCube, 0u, _112); + int l4 = int(_112); + int _116; + SPIRV_Cross_textureSize(uSamplerMS, 0u, _116); + int s0 = int(_116); + int _120; + SPIRV_Cross_textureSize(uSamplerMSArray, 0u, _120); + int s1 = int(_120); +} + +void main() +{ + frag_main(); +} diff --git a/reference/shaders-hlsl/frag/image-query.frag b/reference/shaders-hlsl/frag/image-query.frag index 5ce28bc..82977dd 100644 --- a/reference/shaders-hlsl/frag/image-query.frag +++ b/reference/shaders-hlsl/frag/image-query.frag @@ -11,9 +11,9 @@ SamplerState _uSamplerCube_sampler : register(s4); TextureCubeArray uSamplerCubeArray : register(t5); SamplerState _uSamplerCubeArray_sampler : register(s5); Buffer uSamplerBuffer : register(t6); -Texture2D uSamplerMS : register(t7); +Texture2DMS uSamplerMS : register(t7); SamplerState _uSamplerMS_sampler : register(s7); -Texture2DArray uSamplerMSArray : register(t8); +Texture2DMSArray uSamplerMSArray : register(t8); SamplerState _uSamplerMSArray_sampler : register(s8); uint SPIRV_Cross_textureSize(Texture1D Tex, uint Level, out uint Param) @@ -23,41 +23,6 @@ uint SPIRV_Cross_textureSize(Texture1D Tex, uint Level, out uint Param) return ret; } -uint SPIRV_Cross_textureSize(Texture1D Tex, uint Level, out uint Param) -{ - uint ret; - Tex.GetDimensions(Level, ret.x, Param); - return ret; -} - -uint SPIRV_Cross_textureSize(Texture1D Tex, uint Level, out uint Param) -{ - uint ret; - Tex.GetDimensions(Level, ret.x, Param); - return ret; -} - -uint2 SPIRV_Cross_textureSize(Texture1DArray Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(Level, ret.x, ret.y, Param); - return ret; -} - -uint2 SPIRV_Cross_textureSize(Texture1DArray Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(Level, ret.x, ret.y, Param); - return ret; -} - -uint2 SPIRV_Cross_textureSize(Texture1DArray Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(Level, ret.x, ret.y, Param); - return ret; -} - uint2 SPIRV_Cross_textureSize(Texture2D Tex, uint Level, out uint Param) { uint2 ret; @@ -65,20 +30,6 @@ uint2 SPIRV_Cross_textureSize(Texture2D Tex, uint Level, out uint Param) return ret; } -uint2 SPIRV_Cross_textureSize(Texture2D Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(Level, ret.x, ret.y, Param); - return ret; -} - -uint2 SPIRV_Cross_textureSize(Texture2D Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(Level, ret.x, ret.y, Param); - return ret; -} - uint3 SPIRV_Cross_textureSize(Texture2DArray Tex, uint Level, out uint Param) { uint3 ret; @@ -86,20 +37,6 @@ uint3 SPIRV_Cross_textureSize(Texture2DArray Tex, uint Level, out uint P return ret; } -uint3 SPIRV_Cross_textureSize(Texture2DArray Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); - return ret; -} - -uint3 SPIRV_Cross_textureSize(Texture2DArray Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); - return ret; -} - uint3 SPIRV_Cross_textureSize(Texture3D Tex, uint Level, out uint Param) { uint3 ret; @@ -107,20 +44,6 @@ uint3 SPIRV_Cross_textureSize(Texture3D Tex, uint Level, out uint Param) return ret; } -uint3 SPIRV_Cross_textureSize(Texture3D Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); - return ret; -} - -uint3 SPIRV_Cross_textureSize(Texture3D Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); - return ret; -} - uint SPIRV_Cross_textureSize(Buffer Tex, uint Level, out uint Param) { uint ret; @@ -128,20 +51,6 @@ uint SPIRV_Cross_textureSize(Buffer Tex, uint Level, out uint Param) return ret; } -uint SPIRV_Cross_textureSize(Buffer Tex, uint Level, out uint Param) -{ - uint ret; - Tex.GetDimensions(ret.x); - return ret; -} - -uint SPIRV_Cross_textureSize(Buffer Tex, uint Level, out uint Param) -{ - uint ret; - Tex.GetDimensions(ret.x); - return ret; -} - uint2 SPIRV_Cross_textureSize(TextureCube Tex, uint Level, out uint Param) { uint2 ret; @@ -149,20 +58,6 @@ uint2 SPIRV_Cross_textureSize(TextureCube Tex, uint Level, out uint Para return ret; } -uint2 SPIRV_Cross_textureSize(TextureCube Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(Level, ret.x, ret.y, Param); - return ret; -} - -uint2 SPIRV_Cross_textureSize(TextureCube Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(Level, ret.x, ret.y, Param); - return ret; -} - uint3 SPIRV_Cross_textureSize(TextureCubeArray Tex, uint Level, out uint Param) { uint3 ret; @@ -170,20 +65,6 @@ uint3 SPIRV_Cross_textureSize(TextureCubeArray Tex, uint Level, out uint return ret; } -uint3 SPIRV_Cross_textureSize(TextureCubeArray Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); - return ret; -} - -uint3 SPIRV_Cross_textureSize(TextureCubeArray Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(Level, ret.x, ret.y, ret.z, Param); - return ret; -} - uint2 SPIRV_Cross_textureSize(Texture2DMS Tex, uint Level, out uint Param) { uint2 ret; @@ -191,20 +72,6 @@ uint2 SPIRV_Cross_textureSize(Texture2DMS Tex, uint Level, out uint Para return ret; } -uint2 SPIRV_Cross_textureSize(Texture2DMS Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(ret.x, ret.y, Param); - return ret; -} - -uint2 SPIRV_Cross_textureSize(Texture2DMS Tex, uint Level, out uint Param) -{ - uint2 ret; - Tex.GetDimensions(ret.x, ret.y, Param); - return ret; -} - uint3 SPIRV_Cross_textureSize(Texture2DMSArray Tex, uint Level, out uint Param) { uint3 ret; @@ -212,20 +79,6 @@ uint3 SPIRV_Cross_textureSize(Texture2DMSArray Tex, uint Level, out uint return ret; } -uint3 SPIRV_Cross_textureSize(Texture2DMSArray Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(ret.x, ret.y, ret.z, Param); - return ret; -} - -uint3 SPIRV_Cross_textureSize(Texture2DMSArray Tex, uint Level, out uint Param) -{ - uint3 ret; - Tex.GetDimensions(ret.x, ret.y, ret.z, Param); - return ret; -} - void frag_main() { uint _17_dummy_parameter; diff --git a/shaders-hlsl/frag/image-query-selective.frag b/shaders-hlsl/frag/image-query-selective.frag new file mode 100644 index 0000000..bb595bc --- /dev/null +++ b/shaders-hlsl/frag/image-query-selective.frag @@ -0,0 +1,35 @@ +#version 450 + +layout(binding = 0) uniform usampler1D uSampler1DUint; +layout(binding = 0) uniform isampler1D uSampler1DInt; +layout(binding = 0) uniform sampler1D uSampler1DFloat; +layout(binding = 1) uniform sampler2D uSampler2D; +layout(binding = 2) uniform isampler2DArray uSampler2DArray; +layout(binding = 3) uniform sampler3D uSampler3D; +layout(binding = 4) uniform samplerCube uSamplerCube; +layout(binding = 5) uniform usamplerCubeArray uSamplerCubeArray; +layout(binding = 6) uniform samplerBuffer uSamplerBuffer; +layout(binding = 7) uniform isampler2DMS uSamplerMS; +layout(binding = 8) uniform sampler2DMSArray uSamplerMSArray; + +void main() +{ + int a = textureSize(uSampler1DUint, 0); + a = textureSize(uSampler1DInt, 0); + a = textureSize(uSampler1DFloat, 0); + + ivec3 c = textureSize(uSampler2DArray, 0); + ivec3 d = textureSize(uSampler3D, 0); + ivec2 e = textureSize(uSamplerCube, 0); + ivec3 f = textureSize(uSamplerCubeArray, 0); + int g = textureSize(uSamplerBuffer); + ivec2 h = textureSize(uSamplerMS); + ivec3 i = textureSize(uSamplerMSArray); + + int l1 = textureQueryLevels(uSampler2D); + int l2 = textureQueryLevels(uSampler2DArray); + int l3 = textureQueryLevels(uSampler3D); + int l4 = textureQueryLevels(uSamplerCube); + int s0 = textureSamples(uSamplerMS); + int s1 = textureSamples(uSamplerMSArray); +} diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index e02707f..f1e274b 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -83,7 +83,8 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type) SPIRV_CROSS_THROW("Invalid dimension."); } const char *arrayed = type.image.arrayed ? "Array" : ""; - return join("Texture", dim, arrayed, "<", type_to_glsl(imagetype), components, ">"); + const char *ms = type.image.ms ? "MS" : ""; + return join("Texture", dim, ms, arrayed, "<", type_to_glsl(imagetype), components, ">"); } string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type) @@ -939,30 +940,34 @@ void CompilerHLSL::emit_resources() } } - if (requires_textureSize) + if (required_textureSizeVariants != 0) { - static const char *types[] = { "float4", "int4", "uint4" }; - static const char *dims[] = { "Texture1D", "Texture1DArray", "Texture2D", "Texture2DArray", - "Texture3D", "Buffer", "TextureCube", "TextureCubeArray", - "Texture2DMS", "Texture2DMSArray" }; + static const char *types[QueryTypeCount] = { "float4", "int4", "uint4" }; + static const char *dims[QueryDimCount] = { "Texture1D", "Texture1DArray", "Texture2D", "Texture2DArray", + "Texture3D", "Buffer", "TextureCube", "TextureCubeArray", + "Texture2DMS", "Texture2DMSArray" }; - static const bool has_lod[] = { true, true, true, true, true, false, true, true, false, false }; + static const bool has_lod[QueryDimCount] = { true, true, true, true, true, false, true, true, false, false }; - static const char *ret_types[] = { + static const char *ret_types[QueryDimCount] = { "uint", "uint2", "uint2", "uint3", "uint3", "uint", "uint2", "uint3", "uint2", "uint3", }; - static const uint32_t return_arguments[] = { + static const uint32_t return_arguments[QueryDimCount] = { 1, 2, 2, 3, 3, 1, 2, 3, 2, 3, }; - for (auto &dim : dims) + for (uint32_t index = 0; index < QueryDimCount; index++) { - uint32_t index = uint32_t(&dim - dims); - - for (auto &type : types) + for (uint32_t type_index = 0; type_index < QueryTypeCount; type_index++) { - statement(ret_types[index], " SPIRV_Cross_textureSize(", dim, "<", type, + uint32_t bit = 16 * type_index + index; + uint64_t mask = 1ull << bit; + + if ((required_textureSizeVariants & mask) == 0) + continue; + + statement(ret_types[index], " SPIRV_Cross_textureSize(", dims[index], "<", types[type_index], "> Tex, uint Level, out uint Param)"); begin_scope(); statement(ret_types[index], " ret;"); @@ -2398,11 +2403,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) auto result_type = ops[0]; auto id = ops[1]; - if (!requires_textureSize) - { - requires_textureSize = true; - force_recompile = true; - } + require_texture_query_variant(expression_type(ops[2])); auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter"); statement("uint ", dummy_samples_levels, ";"); @@ -2421,11 +2422,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) auto result_type = ops[0]; auto id = ops[1]; - if (!requires_textureSize) - { - requires_textureSize = true; - force_recompile = true; - } + require_texture_query_variant(expression_type(ops[2])); auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter"); statement("uint ", dummy_samples_levels, ";"); @@ -2443,11 +2440,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) auto result_type = ops[0]; auto id = ops[1]; - if (!requires_textureSize) - { - requires_textureSize = true; - force_recompile = true; - } + require_texture_query_variant(expression_type(ops[2])); // Keep it simple and do not emit special variants to make this look nicer ... // This stuff is barely, if ever, used. @@ -2468,6 +2461,64 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) } } +void CompilerHLSL::require_texture_query_variant(const SPIRType &type) +{ + uint32_t bit = 0; + switch (type.image.dim) + { + case Dim1D: + bit = type.image.arrayed ? Query1DArray : Query1D; + break; + + case Dim2D: + if (type.image.ms) + bit = type.image.arrayed ? Query2DMSArray : Query2DMS; + else + bit = type.image.arrayed ? Query2DArray : Query2D; + break; + + case Dim3D: + bit = Query3D; + break; + + case DimCube: + bit = type.image.arrayed ? QueryCubeArray : QueryCube; + break; + + case DimBuffer: + bit = QueryBuffer; + break; + + default: + SPIRV_CROSS_THROW("Unsupported query type."); + } + + switch (get(type.image.type).basetype) + { + case SPIRType::Float: + bit += QueryTypeFloat; + break; + + case SPIRType::Int: + bit += QueryTypeInt; + break; + + case SPIRType::UInt: + bit += QueryTypeUInt; + break; + + default: + SPIRV_CROSS_THROW("Unsupported query type."); + } + + uint64_t mask = 1ull << bit; + if ((required_textureSizeVariants & mask) == 0) + { + force_recompile = true; + required_textureSizeVariants |= mask; + } +} + string CompilerHLSL::compile() { // Do not deal with ES-isms like precision, older extensions and such. diff --git a/spirv_hlsl.hpp b/spirv_hlsl.hpp index 1317697..b259872 100644 --- a/spirv_hlsl.hpp +++ b/spirv_hlsl.hpp @@ -98,7 +98,31 @@ private: Options options; bool requires_op_fmod = false; bool requires_textureProj = false; - bool requires_textureSize = false; + uint64_t required_textureSizeVariants = 0; + void require_texture_query_variant(const SPIRType &type); + + enum TextureQueryVariantDim + { + Query1D = 0, + Query1DArray, + Query2D, + Query2DArray, + Query3D, + QueryBuffer, + QueryCube, + QueryCubeArray, + Query2DMS, + Query2DMSArray, + QueryDimCount + }; + + enum TextureQueryVariantType + { + QueryTypeFloat = 0, + QueryTypeInt = 16, + QueryTypeUInt = 32, + QueryTypeCount = 3 + }; void emit_builtin_variables(); bool require_output = false;