From 12ca9d1982538437c7d7c3c0409e6eb634834ebe Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Thu, 25 Jul 2019 11:07:14 +0200 Subject: [PATCH] Vulkan GLSL: Support disabling samplerless texture function EXT. Some platforms support Vulkan GLSL, but not this extension apparently ... --- main.cpp | 5 +- ...etch-no-sampler.no-samplerless.asm.vk.frag | 13 ++ ...h-no-sampler.no-samplerless.asm.vk.frag.vk | 14 ++ ...uery-no-sampler.no-samplerless.vk.asm.frag | 6 + ...y-no-sampler.no-samplerless.vk.asm.frag.vk | 6 + ...etch-no-sampler.no-samplerless.asm.vk.frag | 38 ++++ ...h-no-sampler.no-samplerless.asm.vk.frag.vk | 37 ++++ ...uery-no-sampler.no-samplerless.vk.asm.frag | 13 ++ ...y-no-sampler.no-samplerless.vk.asm.frag.vk | 14 ++ ...etch-no-sampler.no-samplerless.asm.vk.frag | 163 ++++++++++++++++++ ...uery-no-sampler.no-samplerless.vk.asm.frag | 57 ++++++ spirv_glsl.cpp | 22 ++- test_shaders.py | 2 + 13 files changed, 382 insertions(+), 8 deletions(-) create mode 100644 reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag create mode 100644 reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk create mode 100644 reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag create mode 100644 reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk create mode 100644 reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag create mode 100644 reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk create mode 100644 reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag create mode 100644 reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk create mode 100644 shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag create mode 100644 shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag diff --git a/main.cpp b/main.cpp index 6340e0e8..43e8cf79 100644 --- a/main.cpp +++ b/main.cpp @@ -519,6 +519,7 @@ struct CLIArguments bool msl_dispatch_base = false; bool glsl_emit_push_constant_as_ubo = false; bool glsl_emit_ubo_as_plain_uniforms = false; + bool vulkan_glsl_disable_ext_samplerless_texture_functions = false; bool emit_line_directives = false; SmallVector msl_discrete_descriptor_sets; SmallVector pls_in; @@ -585,6 +586,7 @@ static void print_help() "\t[--cpp-interface-name ]\n" "\t[--glsl-emit-push-constant-as-ubo]\n" "\t[--glsl-emit-ubo-as-plain-uniforms]\n" + "\t[--vulkan-glsl-disable-ext-samplerless-texture-functions]\n" "\t[--msl]\n" "\t[--msl-version ]\n" "\t[--msl-capture-output]\n" @@ -768,7 +770,7 @@ static string compile_iteration(const CLIArguments &args, std::vector else { combined_image_samplers = !args.vulkan_semantics; - if (!args.vulkan_semantics) + if (!args.vulkan_semantics || args.vulkan_glsl_disable_ext_samplerless_texture_functions) build_dummy_sampler = true; compiler.reset(new CompilerGLSL(move(spirv_parser.get_parsed_ir()))); } @@ -1061,6 +1063,7 @@ static int main_inner(int argc, char *argv[]) cbs.add("--metal", [&args](CLIParser &) { args.msl = true; }); // Legacy compatibility cbs.add("--glsl-emit-push-constant-as-ubo", [&args](CLIParser &) { args.glsl_emit_push_constant_as_ubo = true; }); cbs.add("--glsl-emit-ubo-as-plain-uniforms", [&args](CLIParser &) { args.glsl_emit_ubo_as_plain_uniforms = true; }); + cbs.add("--vulkan-glsl-disable-ext-samplerless-texture-functions", [&args](CLIParser &) { args.vulkan_glsl_disable_ext_samplerless_texture_functions = true; }); cbs.add("--msl", [&args](CLIParser &) { args.msl = true; }); cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; }); cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; }); diff --git a/reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag b/reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag new file mode 100644 index 00000000..452fd6fb --- /dev/null +++ b/reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag @@ -0,0 +1,13 @@ +#version 450 + +uniform sampler2D SPIRV_Cross_CombinedSampledImageSPIRV_Cross_DummySampler; +uniform sampler2D SPIRV_Cross_CombinedSampledImageSampler; + +layout(location = 0) out vec4 _entryPointOutput; + +void main() +{ + ivec2 _152 = ivec3(int(gl_FragCoord.x * 1280.0), int(gl_FragCoord.y * 720.0), 0).xy; + _entryPointOutput = ((texelFetch(SPIRV_Cross_CombinedSampledImageSPIRV_Cross_DummySampler, _152, 0) + texelFetch(SPIRV_Cross_CombinedSampledImageSPIRV_Cross_DummySampler, _152, 0)) + texture(SPIRV_Cross_CombinedSampledImageSampler, gl_FragCoord.xy)) + texture(SPIRV_Cross_CombinedSampledImageSampler, gl_FragCoord.xy); +} + diff --git a/reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk b/reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk new file mode 100644 index 00000000..23acab0b --- /dev/null +++ b/reference/opt/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk @@ -0,0 +1,14 @@ +#version 450 + +layout(set = 0, binding = 0) uniform sampler Sampler; +layout(set = 0, binding = 0) uniform texture2D SampledImage; +layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler; + +layout(location = 0) out vec4 _entryPointOutput; + +void main() +{ + ivec2 _152 = ivec3(int(gl_FragCoord.x * 1280.0), int(gl_FragCoord.y * 720.0), 0).xy; + _entryPointOutput = ((texelFetch(sampler2D(SampledImage, SPIRV_Cross_DummySampler), _152, 0) + texelFetch(sampler2D(SampledImage, SPIRV_Cross_DummySampler), _152, 0)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy)) + texture(sampler2D(SampledImage, Sampler), gl_FragCoord.xy); +} + diff --git a/reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag b/reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag new file mode 100644 index 00000000..05ce10ad --- /dev/null +++ b/reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag @@ -0,0 +1,6 @@ +#version 450 + +void main() +{ +} + diff --git a/reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk b/reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk new file mode 100644 index 00000000..05ce10ad --- /dev/null +++ b/reference/opt/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk @@ -0,0 +1,6 @@ +#version 450 + +void main() +{ +} + diff --git a/reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag b/reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag new file mode 100644 index 00000000..60bb78aa --- /dev/null +++ b/reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag @@ -0,0 +1,38 @@ +#version 450 + +uniform sampler2D SPIRV_Cross_CombinedparamSPIRV_Cross_DummySampler; +uniform sampler2D SPIRV_Cross_CombinedSampledImageSPIRV_Cross_DummySampler; +uniform sampler2D SPIRV_Cross_CombinedparamSampler; +uniform sampler2D SPIRV_Cross_CombinedSampledImageSampler; + +layout(location = 0) out vec4 _entryPointOutput; + +vec4 sample_fetch(ivec3 UV, sampler2D SPIRV_Cross_CombinedtexSPIRV_Cross_DummySampler) +{ + return texelFetch(SPIRV_Cross_CombinedtexSPIRV_Cross_DummySampler, UV.xy, UV.z); +} + +vec4 sample_sampler(vec2 UV, sampler2D SPIRV_Cross_CombinedtexSampler) +{ + return texture(SPIRV_Cross_CombinedtexSampler, UV); +} + +vec4 _main(vec4 xIn) +{ + ivec3 coord = ivec3(int(xIn.x * 1280.0), int(xIn.y * 720.0), 0); + ivec3 param = coord; + vec4 value = sample_fetch(param, SPIRV_Cross_CombinedparamSPIRV_Cross_DummySampler); + value += texelFetch(SPIRV_Cross_CombinedSampledImageSPIRV_Cross_DummySampler, coord.xy, coord.z); + vec2 param_1 = xIn.xy; + value += sample_sampler(param_1, SPIRV_Cross_CombinedparamSampler); + value += texture(SPIRV_Cross_CombinedSampledImageSampler, xIn.xy); + return value; +} + +void main() +{ + vec4 xIn = gl_FragCoord; + vec4 param = xIn; + _entryPointOutput = _main(param); +} + diff --git a/reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk b/reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk new file mode 100644 index 00000000..e4d9fc45 --- /dev/null +++ b/reference/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag.vk @@ -0,0 +1,37 @@ +#version 450 + +layout(set = 0, binding = 0) uniform sampler Sampler; +layout(set = 0, binding = 0) uniform texture2D SampledImage; +layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler; + +layout(location = 0) out vec4 _entryPointOutput; + +vec4 sample_fetch(texture2D tex, ivec3 UV) +{ + return texelFetch(sampler2D(tex, SPIRV_Cross_DummySampler), UV.xy, UV.z); +} + +vec4 sample_sampler(texture2D tex, vec2 UV) +{ + return texture(sampler2D(tex, Sampler), UV); +} + +vec4 _main(vec4 xIn) +{ + ivec3 coord = ivec3(int(xIn.x * 1280.0), int(xIn.y * 720.0), 0); + ivec3 param = coord; + vec4 value = sample_fetch(SampledImage, param); + value += texelFetch(sampler2D(SampledImage, SPIRV_Cross_DummySampler), coord.xy, coord.z); + vec2 param_1 = xIn.xy; + value += sample_sampler(SampledImage, param_1); + value += texture(sampler2D(SampledImage, Sampler), xIn.xy); + return value; +} + +void main() +{ + vec4 xIn = gl_FragCoord; + vec4 param = xIn; + _entryPointOutput = _main(param); +} + diff --git a/reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag b/reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag new file mode 100644 index 00000000..2040dd1a --- /dev/null +++ b/reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag @@ -0,0 +1,13 @@ +#version 450 + +uniform sampler2D SPIRV_Cross_CombineduSampler2DSPIRV_Cross_DummySampler; +uniform sampler2DMS SPIRV_Cross_CombineduSampler2DMSSPIRV_Cross_DummySampler; + +void main() +{ + ivec2 b = textureSize(SPIRV_Cross_CombineduSampler2DSPIRV_Cross_DummySampler, 0); + ivec2 c = textureSize(SPIRV_Cross_CombineduSampler2DMSSPIRV_Cross_DummySampler); + int l1 = textureQueryLevels(SPIRV_Cross_CombineduSampler2DSPIRV_Cross_DummySampler); + int s0 = textureSamples(SPIRV_Cross_CombineduSampler2DMSSPIRV_Cross_DummySampler); +} + diff --git a/reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk b/reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk new file mode 100644 index 00000000..828d2a87 --- /dev/null +++ b/reference/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag.vk @@ -0,0 +1,14 @@ +#version 450 + +layout(set = 0, binding = 0) uniform texture2D uSampler2D; +layout(set = 0, binding = 0) uniform texture2DMS uSampler2DMS; +layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler; + +void main() +{ + ivec2 b = textureSize(sampler2D(uSampler2D, SPIRV_Cross_DummySampler), 0); + ivec2 c = textureSize(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler)); + int l1 = textureQueryLevels(sampler2D(uSampler2D, SPIRV_Cross_DummySampler)); + int s0 = textureSamples(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler)); +} + diff --git a/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag b/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag new file mode 100644 index 00000000..a3d64c09 --- /dev/null +++ b/shaders/asm/frag/image-fetch-no-sampler.no-samplerless.asm.vk.frag @@ -0,0 +1,163 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 2 +; Bound: 113 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %xIn_1 %_entryPointOutput + OpExecutionMode %main OriginUpperLeft + OpSource HLSL 500 + OpName %main "main" + OpName %sample_fetch_t21_vi3_ "sample_fetch(t21;vi3;" + OpName %tex "tex" + OpName %UV "UV" + OpName %sample_sampler_t21_vf2_ "sample_sampler(t21;vf2;" + OpName %tex_0 "tex" + OpName %UV_0 "UV" + OpName %_main_vf4_ "@main(vf4;" + OpName %xIn "xIn" + OpName %Sampler "Sampler" + OpName %coord "coord" + OpName %value "value" + OpName %SampledImage "SampledImage" + OpName %param "param" + OpName %param_0 "param" + OpName %param_1 "param" + OpName %param_2 "param" + OpName %xIn_0 "xIn" + OpName %xIn_1 "xIn" + OpName %_entryPointOutput "@entryPointOutput" + OpName %param_3 "param" + OpDecorate %Sampler DescriptorSet 0 + OpDecorate %Sampler Binding 0 + OpDecorate %SampledImage DescriptorSet 0 + OpDecorate %SampledImage Binding 0 + OpDecorate %xIn_1 BuiltIn FragCoord + OpDecorate %_entryPointOutput Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %7 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_Function_7 = OpTypePointer Function %7 + %int = OpTypeInt 32 1 + %v3int = OpTypeVector %int 3 +%_ptr_Function_v3int = OpTypePointer Function %v3int + %v4float = OpTypeVector %float 4 + %13 = OpTypeFunction %v4float %_ptr_Function_7 %_ptr_Function_v3int + %v2float = OpTypeVector %float 2 +%_ptr_Function_v2float = OpTypePointer Function %v2float + %20 = OpTypeFunction %v4float %_ptr_Function_7 %_ptr_Function_v2float +%_ptr_Function_v4float = OpTypePointer Function %v4float + %26 = OpTypeFunction %v4float %_ptr_Function_v4float + %v2int = OpTypeVector %int 2 + %uint = OpTypeInt 32 0 + %uint_2 = OpConstant %uint 2 +%_ptr_Function_int = OpTypePointer Function %int + %43 = OpTypeSampler +%_ptr_UniformConstant_43 = OpTypePointer UniformConstant %43 + %Sampler = OpVariable %_ptr_UniformConstant_43 UniformConstant + %47 = OpTypeSampledImage %7 + %uint_0 = OpConstant %uint 0 +%_ptr_Function_float = OpTypePointer Function %float + %float_1280 = OpConstant %float 1280 + %uint_1 = OpConstant %uint 1 + %float_720 = OpConstant %float 720 + %int_0 = OpConstant %int 0 +%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7 +%SampledImage = OpVariable %_ptr_UniformConstant_7 UniformConstant +%_ptr_Input_v4float = OpTypePointer Input %v4float + %xIn_1 = OpVariable %_ptr_Input_v4float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float +%_entryPointOutput = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %3 + %5 = OpLabel + %xIn_0 = OpVariable %_ptr_Function_v4float Function + %param_3 = OpVariable %_ptr_Function_v4float Function + %107 = OpLoad %v4float %xIn_1 + OpStore %xIn_0 %107 + %111 = OpLoad %v4float %xIn_0 + OpStore %param_3 %111 + %112 = OpFunctionCall %v4float %_main_vf4_ %param_3 + OpStore %_entryPointOutput %112 + OpReturn + OpFunctionEnd +%sample_fetch_t21_vi3_ = OpFunction %v4float None %13 + %tex = OpFunctionParameter %_ptr_Function_7 + %UV = OpFunctionParameter %_ptr_Function_v3int + %17 = OpLabel + %30 = OpLoad %7 %tex + %32 = OpLoad %v3int %UV + %33 = OpVectorShuffle %v2int %32 %32 0 1 + %37 = OpAccessChain %_ptr_Function_int %UV %uint_2 + %38 = OpLoad %int %37 + %39 = OpImageFetch %v4float %30 %33 Lod %38 + OpReturnValue %39 + OpFunctionEnd +%sample_sampler_t21_vf2_ = OpFunction %v4float None %20 + %tex_0 = OpFunctionParameter %_ptr_Function_7 + %UV_0 = OpFunctionParameter %_ptr_Function_v2float + %24 = OpLabel + %42 = OpLoad %7 %tex_0 + %46 = OpLoad %43 %Sampler + %48 = OpSampledImage %47 %42 %46 + %49 = OpLoad %v2float %UV_0 + %50 = OpImageSampleImplicitLod %v4float %48 %49 + OpReturnValue %50 + OpFunctionEnd + %_main_vf4_ = OpFunction %v4float None %26 + %xIn = OpFunctionParameter %_ptr_Function_v4float + %29 = OpLabel + %coord = OpVariable %_ptr_Function_v3int Function + %value = OpVariable %_ptr_Function_v4float Function + %param = OpVariable %_ptr_Function_7 Function + %param_0 = OpVariable %_ptr_Function_v3int Function + %param_1 = OpVariable %_ptr_Function_7 Function + %param_2 = OpVariable %_ptr_Function_v2float Function + %56 = OpAccessChain %_ptr_Function_float %xIn %uint_0 + %57 = OpLoad %float %56 + %59 = OpFMul %float %57 %float_1280 + %60 = OpConvertFToS %int %59 + %62 = OpAccessChain %_ptr_Function_float %xIn %uint_1 + %63 = OpLoad %float %62 + %65 = OpFMul %float %63 %float_720 + %66 = OpConvertFToS %int %65 + %68 = OpCompositeConstruct %v3int %60 %66 %int_0 + OpStore %coord %68 + %73 = OpLoad %7 %SampledImage + OpStore %param %73 + %75 = OpLoad %v3int %coord + OpStore %param_0 %75 + %76 = OpFunctionCall %v4float %sample_fetch_t21_vi3_ %param %param_0 + OpStore %value %76 + %77 = OpLoad %7 %SampledImage + %78 = OpLoad %v3int %coord + %79 = OpVectorShuffle %v2int %78 %78 0 1 + %80 = OpAccessChain %_ptr_Function_int %coord %uint_2 + %81 = OpLoad %int %80 + %82 = OpImageFetch %v4float %77 %79 Lod %81 + %83 = OpLoad %v4float %value + %84 = OpFAdd %v4float %83 %82 + OpStore %value %84 + %86 = OpLoad %7 %SampledImage + OpStore %param_1 %86 + %88 = OpLoad %v4float %xIn + %89 = OpVectorShuffle %v2float %88 %88 0 1 + OpStore %param_2 %89 + %90 = OpFunctionCall %v4float %sample_sampler_t21_vf2_ %param_1 %param_2 + %91 = OpLoad %v4float %value + %92 = OpFAdd %v4float %91 %90 + OpStore %value %92 + %93 = OpLoad %7 %SampledImage + %94 = OpLoad %43 %Sampler + %95 = OpSampledImage %47 %93 %94 + %96 = OpLoad %v4float %xIn + %97 = OpVectorShuffle %v2float %96 %96 0 1 + %98 = OpImageSampleImplicitLod %v4float %95 %97 + %99 = OpLoad %v4float %value + %100 = OpFAdd %v4float %99 %98 + OpStore %value %100 + %101 = OpLoad %v4float %value + OpReturnValue %101 + OpFunctionEnd diff --git a/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag b/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag new file mode 100644 index 00000000..a232bd48 --- /dev/null +++ b/shaders/asm/frag/image-query-no-sampler.no-samplerless.vk.asm.frag @@ -0,0 +1,57 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 6 +; Bound: 36 +; Schema: 0 + OpCapability Shader + OpCapability ImageQuery + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %b "b" + OpName %uSampler2D "uSampler2D" + OpName %c "c" + OpName %uSampler2DMS "uSampler2DMS" + OpName %l1 "l1" + OpName %s0 "s0" + OpDecorate %uSampler2D DescriptorSet 0 + OpDecorate %uSampler2D Binding 0 + OpDecorate %uSampler2DMS DescriptorSet 0 + OpDecorate %uSampler2DMS Binding 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 +%_ptr_Function_v2int = OpTypePointer Function %v2int + %float = OpTypeFloat 32 + %11 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %11 + %uSampler2D = OpVariable %_ptr_UniformConstant_12 UniformConstant + %int_0 = OpConstant %int 0 + %20 = OpTypeImage %float 2D 0 0 1 1 Unknown +%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %20 +%uSampler2DMS = OpVariable %_ptr_UniformConstant_21 UniformConstant +%_ptr_Function_int = OpTypePointer Function %int + %main = OpFunction %void None %3 + %5 = OpLabel + %b = OpVariable %_ptr_Function_v2int Function + %c = OpVariable %_ptr_Function_v2int Function + %l1 = OpVariable %_ptr_Function_int Function + %s0 = OpVariable %_ptr_Function_int Function + %15 = OpLoad %11 %uSampler2D + %18 = OpImageQuerySizeLod %v2int %15 %int_0 + OpStore %b %18 + %24 = OpLoad %20 %uSampler2DMS + %26 = OpImageQuerySize %v2int %24 + OpStore %c %26 + %29 = OpLoad %11 %uSampler2D + %31 = OpImageQueryLevels %int %29 + OpStore %l1 %31 + %33 = OpLoad %20 %uSampler2DMS + %35 = OpImageQuerySamples %int %33 + OpStore %s0 %35 + OpReturn + OpFunctionEnd diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 4fe7d588..758be044 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -4654,16 +4654,16 @@ void CompilerGLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_i { emit_binary_func_op(result_type, result_id, image_id, samp_id, type_to_glsl(get(result_type), result_id).c_str()); - - // Make sure to suppress usage tracking and any expression invalidation. - // It is illegal to create temporaries of opaque types. - forwarded_temporaries.erase(result_id); } else { // Make sure to suppress usage tracking. It is illegal to create temporaries of opaque types. emit_op(result_type, result_id, to_combined_image_sampler(image_id, samp_id), true, true); } + + // Make sure to suppress usage tracking and any expression invalidation. + // It is illegal to create temporaries of opaque types. + forwarded_temporaries.erase(result_id); } static inline bool image_opcode_is_sample_no_dref(Op op) @@ -4976,10 +4976,18 @@ std::string CompilerGLSL::convert_separate_image_to_expression(uint32_t id) { if (options.vulkan_semantics) { - // Newer glslang supports this extension to deal with texture2D as argument to texture functions. if (dummy_sampler_id) - SPIRV_CROSS_THROW("Vulkan GLSL should not have a dummy sampler for combining."); - require_extension_internal("GL_EXT_samplerless_texture_functions"); + { + // Don't need to consider Shadow state since the dummy sampler is always non-shadow. + auto sampled_type = type; + sampled_type.basetype = SPIRType::SampledImage; + return join(type_to_glsl(sampled_type), "(", to_expression(id), ", ", to_expression(dummy_sampler_id), ")"); + } + else + { + // Newer glslang supports this extension to deal with texture2D as argument to texture functions. + require_extension_internal("GL_EXT_samplerless_texture_functions"); + } } else { diff --git a/test_shaders.py b/test_shaders.py index 73b72865..27466b39 100755 --- a/test_shaders.py +++ b/test_shaders.py @@ -385,6 +385,8 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl extra_args += ['--glsl-emit-push-constant-as-ubo'] if '.line.' in shader: extra_args += ['--emit-line-directives'] + if '.no-samplerless.' in shader: + extra_args += ['--vulkan-glsl-disable-ext-samplerless-texture-functions'] spirv_cross_path = paths.spirv_cross