From 0671b3c35bfb393da2c79e11f93ca3e561093f21 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Wed, 12 Jun 2019 11:36:52 +0200 Subject: [PATCH] MSL: Support OpImageQueryLod. Correctness is a bit unclear at the moment. The spec document for 2.2 is not updated for query-lod, but this is the best we can do anyways. --- .../frag/image-query-lod.msl22.frag | 70 +++++++++++++++++ .../frag/image-query-lod.msl22.frag | 77 +++++++++++++++++++ shaders-msl/frag/image-query-lod.msl22.frag | 33 ++++++++ spirv_msl.cpp | 27 ++++++- 4 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 reference/opt/shaders-msl/frag/image-query-lod.msl22.frag create mode 100644 reference/shaders-msl/frag/image-query-lod.msl22.frag create mode 100644 shaders-msl/frag/image-query-lod.msl22.frag diff --git a/reference/opt/shaders-msl/frag/image-query-lod.msl22.frag b/reference/opt/shaders-msl/frag/image-query-lod.msl22.frag new file mode 100644 index 00000000..03264de8 --- /dev/null +++ b/reference/opt/shaders-msl/frag/image-query-lod.msl22.frag @@ -0,0 +1,70 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float2 FragColor [[color(0)]]; +}; + +struct main0_in +{ + float3 vUV [[user(locn0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], texture2d uSampler2D [[texture(0)]], texture3d uSampler3D [[texture(1)]], texturecube uSamplerCube [[texture(2)]], texture2d uTexture2D [[texture(4)]], texture3d uTexture3D [[texture(5)]], texturecube uTextureCube [[texture(6)]], sampler uSampler2DSmplr [[sampler(0)]], sampler uSampler3DSmplr [[sampler(1)]], sampler uSamplerCubeSmplr [[sampler(2)]], sampler uSampler [[sampler(3)]]) +{ + main0_out out = {}; + out.FragColor = float2(0.0); + float2 _79; + _79.x = uSampler2D.calculate_clamped_lod(uSampler2DSmplr, in.vUV.xy); + _79.y = uSampler2D.calculate_unclamped_lod(uSampler2DSmplr, in.vUV.xy); + out.FragColor += _79; + float2 _84; + _84.x = uSampler3D.calculate_clamped_lod(uSampler3DSmplr, in.vUV); + _84.y = uSampler3D.calculate_unclamped_lod(uSampler3DSmplr, in.vUV); + out.FragColor += _84; + float2 _89; + _89.x = uSamplerCube.calculate_clamped_lod(uSamplerCubeSmplr, in.vUV); + _89.y = uSamplerCube.calculate_unclamped_lod(uSamplerCubeSmplr, in.vUV); + out.FragColor += _89; + float2 _97; + _97.x = uTexture2D.calculate_clamped_lod(uSampler, in.vUV.xy); + _97.y = uTexture2D.calculate_unclamped_lod(uSampler, in.vUV.xy); + out.FragColor += _97; + float2 _104; + _104.x = uTexture3D.calculate_clamped_lod(uSampler, in.vUV); + _104.y = uTexture3D.calculate_unclamped_lod(uSampler, in.vUV); + out.FragColor += _104; + float2 _111; + _111.x = uTextureCube.calculate_clamped_lod(uSampler, in.vUV); + _111.y = uTextureCube.calculate_unclamped_lod(uSampler, in.vUV); + out.FragColor += _111; + float2 _118; + _118.x = uSampler2D.calculate_clamped_lod(uSampler2DSmplr, in.vUV.xy); + _118.y = uSampler2D.calculate_unclamped_lod(uSampler2DSmplr, in.vUV.xy); + out.FragColor += _118; + float2 _123; + _123.x = uSampler3D.calculate_clamped_lod(uSampler3DSmplr, in.vUV); + _123.y = uSampler3D.calculate_unclamped_lod(uSampler3DSmplr, in.vUV); + out.FragColor += _123; + float2 _128; + _128.x = uSamplerCube.calculate_clamped_lod(uSamplerCubeSmplr, in.vUV); + _128.y = uSamplerCube.calculate_unclamped_lod(uSamplerCubeSmplr, in.vUV); + out.FragColor += _128; + float2 _136; + _136.x = uTexture2D.calculate_clamped_lod(uSampler, in.vUV.xy); + _136.y = uTexture2D.calculate_unclamped_lod(uSampler, in.vUV.xy); + out.FragColor += _136; + float2 _143; + _143.x = uTexture3D.calculate_clamped_lod(uSampler, in.vUV); + _143.y = uTexture3D.calculate_unclamped_lod(uSampler, in.vUV); + out.FragColor += _143; + float2 _150; + _150.x = uTextureCube.calculate_clamped_lod(uSampler, in.vUV); + _150.y = uTextureCube.calculate_unclamped_lod(uSampler, in.vUV); + out.FragColor += _150; + return out; +} + diff --git a/reference/shaders-msl/frag/image-query-lod.msl22.frag b/reference/shaders-msl/frag/image-query-lod.msl22.frag new file mode 100644 index 00000000..1eef53ad --- /dev/null +++ b/reference/shaders-msl/frag/image-query-lod.msl22.frag @@ -0,0 +1,77 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct main0_out +{ + float2 FragColor [[color(0)]]; +}; + +struct main0_in +{ + float3 vUV [[user(locn0)]]; +}; + +void from_function(thread float2& FragColor, thread texture2d uSampler2D, thread const sampler uSampler2DSmplr, thread float3& vUV, thread texture3d uSampler3D, thread const sampler uSampler3DSmplr, thread texturecube uSamplerCube, thread const sampler uSamplerCubeSmplr, thread texture2d uTexture2D, thread sampler uSampler, thread texture3d uTexture3D, thread texturecube uTextureCube) +{ + float2 _22; + _22.x = uSampler2D.calculate_clamped_lod(uSampler2DSmplr, vUV.xy); + _22.y = uSampler2D.calculate_unclamped_lod(uSampler2DSmplr, vUV.xy); + FragColor += _22; + float2 _31; + _31.x = uSampler3D.calculate_clamped_lod(uSampler3DSmplr, vUV); + _31.y = uSampler3D.calculate_unclamped_lod(uSampler3DSmplr, vUV); + FragColor += _31; + float2 _40; + _40.x = uSamplerCube.calculate_clamped_lod(uSamplerCubeSmplr, vUV); + _40.y = uSamplerCube.calculate_unclamped_lod(uSamplerCubeSmplr, vUV); + FragColor += _40; + float2 _53; + _53.x = uTexture2D.calculate_clamped_lod(uSampler, vUV.xy); + _53.y = uTexture2D.calculate_unclamped_lod(uSampler, vUV.xy); + FragColor += _53; + float2 _62; + _62.x = uTexture3D.calculate_clamped_lod(uSampler, vUV); + _62.y = uTexture3D.calculate_unclamped_lod(uSampler, vUV); + FragColor += _62; + float2 _71; + _71.x = uTextureCube.calculate_clamped_lod(uSampler, vUV); + _71.y = uTextureCube.calculate_unclamped_lod(uSampler, vUV); + FragColor += _71; +} + +fragment main0_out main0(main0_in in [[stage_in]], texture2d uSampler2D [[texture(0)]], texture3d uSampler3D [[texture(1)]], texturecube uSamplerCube [[texture(2)]], texture2d uTexture2D [[texture(4)]], texture3d uTexture3D [[texture(5)]], texturecube uTextureCube [[texture(6)]], sampler uSampler2DSmplr [[sampler(0)]], sampler uSampler3DSmplr [[sampler(1)]], sampler uSamplerCubeSmplr [[sampler(2)]], sampler uSampler [[sampler(3)]]) +{ + main0_out out = {}; + out.FragColor = float2(0.0); + float2 _79; + _79.x = uSampler2D.calculate_clamped_lod(uSampler2DSmplr, in.vUV.xy); + _79.y = uSampler2D.calculate_unclamped_lod(uSampler2DSmplr, in.vUV.xy); + out.FragColor += _79; + float2 _84; + _84.x = uSampler3D.calculate_clamped_lod(uSampler3DSmplr, in.vUV); + _84.y = uSampler3D.calculate_unclamped_lod(uSampler3DSmplr, in.vUV); + out.FragColor += _84; + float2 _89; + _89.x = uSamplerCube.calculate_clamped_lod(uSamplerCubeSmplr, in.vUV); + _89.y = uSamplerCube.calculate_unclamped_lod(uSamplerCubeSmplr, in.vUV); + out.FragColor += _89; + float2 _97; + _97.x = uTexture2D.calculate_clamped_lod(uSampler, in.vUV.xy); + _97.y = uTexture2D.calculate_unclamped_lod(uSampler, in.vUV.xy); + out.FragColor += _97; + float2 _104; + _104.x = uTexture3D.calculate_clamped_lod(uSampler, in.vUV); + _104.y = uTexture3D.calculate_unclamped_lod(uSampler, in.vUV); + out.FragColor += _104; + float2 _111; + _111.x = uTextureCube.calculate_clamped_lod(uSampler, in.vUV); + _111.y = uTextureCube.calculate_unclamped_lod(uSampler, in.vUV); + out.FragColor += _111; + from_function(out.FragColor, uSampler2D, uSampler2DSmplr, in.vUV, uSampler3D, uSampler3DSmplr, uSamplerCube, uSamplerCubeSmplr, uTexture2D, uSampler, uTexture3D, uTextureCube); + return out; +} + diff --git a/shaders-msl/frag/image-query-lod.msl22.frag b/shaders-msl/frag/image-query-lod.msl22.frag new file mode 100644 index 00000000..33d5630e --- /dev/null +++ b/shaders-msl/frag/image-query-lod.msl22.frag @@ -0,0 +1,33 @@ +#version 450 + +layout(location = 0) out vec2 FragColor; +layout(set = 0, binding = 0) uniform sampler2D uSampler2D; +layout(set = 0, binding = 1) uniform sampler3D uSampler3D; +layout(set = 0, binding = 2) uniform samplerCube uSamplerCube; +layout(set = 0, binding = 3) uniform sampler uSampler; +layout(set = 0, binding = 4) uniform texture2D uTexture2D; +layout(set = 0, binding = 5) uniform texture3D uTexture3D; +layout(set = 0, binding = 6) uniform textureCube uTextureCube; +layout(location = 0) in vec3 vUV; + +void from_function() +{ + FragColor += textureQueryLod(uSampler2D, vUV.xy); + FragColor += textureQueryLod(uSampler3D, vUV); + FragColor += textureQueryLod(uSamplerCube, vUV); + FragColor += textureQueryLod(sampler2D(uTexture2D, uSampler), vUV.xy); + FragColor += textureQueryLod(sampler3D(uTexture3D, uSampler), vUV); + FragColor += textureQueryLod(samplerCube(uTextureCube, uSampler), vUV); +} + +void main() +{ + FragColor = vec2(0.0); + FragColor += textureQueryLod(uSampler2D, vUV.xy); + FragColor += textureQueryLod(uSampler3D, vUV); + FragColor += textureQueryLod(uSamplerCube, vUV); + FragColor += textureQueryLod(sampler2D(uTexture2D, uSampler), vUV.xy); + FragColor += textureQueryLod(sampler3D(uTexture3D, uSampler), vUV); + FragColor += textureQueryLod(samplerCube(uTextureCube, uSampler), vUV); + from_function(); +} diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 3a827c65..765f6d7a 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -3904,7 +3904,32 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) } case OpImageQueryLod: - SPIRV_CROSS_THROW("MSL does not support textureQueryLod()."); + { + if (!msl_options.supports_msl_version(2, 2)) + SPIRV_CROSS_THROW("ImageQueryLod is only supported on MSL 2.2 and up."); + uint32_t result_type = ops[0]; + uint32_t id = ops[1]; + uint32_t image_id = ops[2]; + uint32_t coord_id = ops[3]; + emit_uninitialized_temporary_expression(result_type, id); + + auto sampler_expr = to_sampler_expression(image_id); + auto *combined = maybe_get(image_id); + auto image_expr = combined ? to_expression(combined->image) : to_expression(image_id); + + // TODO: It is unclear if calculcate_clamped_lod also conditionally rounds + // the reported LOD based on the sampler. NEAREST miplevel should + // round the LOD, but LINEAR miplevel should not round. + // Let's hope this does not become an issue ... + statement(to_expression(id), ".x = ", + image_expr, ".calculate_clamped_lod(", + sampler_expr, ", ", to_expression(coord_id), ");"); + statement(to_expression(id), ".y = ", + image_expr, ".calculate_unclamped_lod(", + sampler_expr, ", ", to_expression(coord_id), ");"); + register_control_dependent_expression(id); + break; + } #define MSL_ImgQry(qrytype) \ do \