From e4d5c6183ab959a38fed570b8c39218535b82910 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Wed, 3 Apr 2019 10:50:32 +0200 Subject: [PATCH] GLSL: Fix OpImageFetch with uint coordinates and LOD. Also fix some minor issues with too many coordinate dimensions in HLSL and GLSL. --- .../asm/frag/image-fetch-uint-coord.asm.frag | 28 ++++++++++++ .../asm/frag/image-fetch-uint-coord.asm.frag | 22 ++++++++++ .../asm/frag/image-fetch-uint-coord.asm.frag | 12 +++++ .../asm/frag/image-fetch-uint-coord.asm.frag | 44 +++++++++++++++++++ .../asm/frag/image-fetch-uint-coord.asm.frag | 44 +++++++++++++++++++ .../asm/frag/image-fetch-uint-coord.asm.frag | 44 +++++++++++++++++++ spirv_glsl.cpp | 15 ++++++- spirv_hlsl.cpp | 12 +++-- 8 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 reference/shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag create mode 100644 reference/shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag create mode 100644 reference/shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag create mode 100644 shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag create mode 100644 shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag create mode 100644 shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag diff --git a/reference/shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag b/reference/shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag new file mode 100644 index 00000000..c5a76134 --- /dev/null +++ b/reference/shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag @@ -0,0 +1,28 @@ +Texture2D Tex : register(t0); + +static uint3 in_var_TEXCOORD0; +static float4 out_var_SV_Target0; + +struct SPIRV_Cross_Input +{ + nointerpolation uint3 in_var_TEXCOORD0 : TEXCOORD0; +}; + +struct SPIRV_Cross_Output +{ + float4 out_var_SV_Target0 : SV_Target0; +}; + +void frag_main() +{ + out_var_SV_Target0 = Tex.Load(int3(in_var_TEXCOORD0.xy, in_var_TEXCOORD0.z)); +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + in_var_TEXCOORD0 = stage_input.in_var_TEXCOORD0; + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.out_var_SV_Target0 = out_var_SV_Target0; + return stage_output; +} diff --git a/reference/shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag b/reference/shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag new file mode 100644 index 00000000..887200f7 --- /dev/null +++ b/reference/shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag @@ -0,0 +1,22 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_Target0 [[color(0)]]; +}; + +struct main0_in +{ + uint3 in_var_TEXCOORD0 [[user(locn0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], texture2d Tex [[texture(0)]]) +{ + main0_out out = {}; + out.out_var_SV_Target0 = Tex.read(uint2(in.in_var_TEXCOORD0.xy), in.in_var_TEXCOORD0.z); + return out; +} + diff --git a/reference/shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag b/reference/shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag new file mode 100644 index 00000000..8b8d0c85 --- /dev/null +++ b/reference/shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag @@ -0,0 +1,12 @@ +#version 450 + +uniform sampler2D SPIRV_Cross_CombinedTexSPIRV_Cross_DummySampler; + +layout(location = 0) flat in uvec3 in_var_TEXCOORD0; +layout(location = 0) out vec4 out_var_SV_Target0; + +void main() +{ + out_var_SV_Target0 = texelFetch(SPIRV_Cross_CombinedTexSPIRV_Cross_DummySampler, ivec2(in_var_TEXCOORD0.xy), int(in_var_TEXCOORD0.z)); +} + diff --git a/shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag b/shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag new file mode 100644 index 00000000..ca8022d4 --- /dev/null +++ b/shaders-hlsl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag @@ -0,0 +1,44 @@ +; SPIR-V +; Version: 1.0 +; Generator: Google spiregg; 0 +; Bound: 29 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %in_var_TEXCOORD0 %out_var_SV_Target0 + OpExecutionMode %main OriginUpperLeft + OpSource HLSL 600 + OpName %type_2d_image "type.2d.image" + OpName %Tex "Tex" + OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0" + OpName %out_var_SV_Target0 "out.var.SV_Target0" + OpName %main "main" + OpDecorate %in_var_TEXCOORD0 Flat + OpDecorate %in_var_TEXCOORD0 Location 0 + OpDecorate %out_var_SV_Target0 Location 0 + OpDecorate %Tex DescriptorSet 0 + OpDecorate %Tex Binding 0 + %int = OpTypeInt 32 1 + %int_2 = OpConstant %int 2 + %float = OpTypeFloat 32 +%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown +%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %void = OpTypeVoid + %16 = OpTypeFunction %void + %Tex = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant +%in_var_TEXCOORD0 = OpVariable %_ptr_Input_v3uint Input +%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %16 + %19 = OpLabel + %20 = OpLoad %v3uint %in_var_TEXCOORD0 + %21 = OpCompositeExtract %uint %20 2 + %27 = OpLoad %type_2d_image %Tex + %28 = OpImageFetch %v4float %27 %20 Lod %21 + OpStore %out_var_SV_Target0 %28 + OpReturn + OpFunctionEnd diff --git a/shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag b/shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag new file mode 100644 index 00000000..ca8022d4 --- /dev/null +++ b/shaders-msl-no-opt/asm/frag/image-fetch-uint-coord.asm.frag @@ -0,0 +1,44 @@ +; SPIR-V +; Version: 1.0 +; Generator: Google spiregg; 0 +; Bound: 29 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %in_var_TEXCOORD0 %out_var_SV_Target0 + OpExecutionMode %main OriginUpperLeft + OpSource HLSL 600 + OpName %type_2d_image "type.2d.image" + OpName %Tex "Tex" + OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0" + OpName %out_var_SV_Target0 "out.var.SV_Target0" + OpName %main "main" + OpDecorate %in_var_TEXCOORD0 Flat + OpDecorate %in_var_TEXCOORD0 Location 0 + OpDecorate %out_var_SV_Target0 Location 0 + OpDecorate %Tex DescriptorSet 0 + OpDecorate %Tex Binding 0 + %int = OpTypeInt 32 1 + %int_2 = OpConstant %int 2 + %float = OpTypeFloat 32 +%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown +%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %void = OpTypeVoid + %16 = OpTypeFunction %void + %Tex = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant +%in_var_TEXCOORD0 = OpVariable %_ptr_Input_v3uint Input +%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %16 + %19 = OpLabel + %20 = OpLoad %v3uint %in_var_TEXCOORD0 + %21 = OpCompositeExtract %uint %20 2 + %27 = OpLoad %type_2d_image %Tex + %28 = OpImageFetch %v4float %27 %20 Lod %21 + OpStore %out_var_SV_Target0 %28 + OpReturn + OpFunctionEnd diff --git a/shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag b/shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag new file mode 100644 index 00000000..ca8022d4 --- /dev/null +++ b/shaders-no-opt/asm/frag/image-fetch-uint-coord.asm.frag @@ -0,0 +1,44 @@ +; SPIR-V +; Version: 1.0 +; Generator: Google spiregg; 0 +; Bound: 29 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %in_var_TEXCOORD0 %out_var_SV_Target0 + OpExecutionMode %main OriginUpperLeft + OpSource HLSL 600 + OpName %type_2d_image "type.2d.image" + OpName %Tex "Tex" + OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0" + OpName %out_var_SV_Target0 "out.var.SV_Target0" + OpName %main "main" + OpDecorate %in_var_TEXCOORD0 Flat + OpDecorate %in_var_TEXCOORD0 Location 0 + OpDecorate %out_var_SV_Target0 Location 0 + OpDecorate %Tex DescriptorSet 0 + OpDecorate %Tex Binding 0 + %int = OpTypeInt 32 1 + %int_2 = OpConstant %int 2 + %float = OpTypeFloat 32 +%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown +%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %void = OpTypeVoid + %16 = OpTypeFunction %void + %Tex = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant +%in_var_TEXCOORD0 = OpVariable %_ptr_Input_v3uint Input +%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %16 + %19 = OpLabel + %20 = OpLoad %v3uint %in_var_TEXCOORD0 + %21 = OpCompositeExtract %uint %20 2 + %27 = OpLoad %type_2d_image %Tex + %28 = OpImageFetch %v4float %27 %20 Lod %21 + OpStore %out_var_SV_Target0 %28 + OpReturn + OpFunctionEnd diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index c8bf7e0e..151c668f 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -4590,6 +4590,7 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, boo if (coord_type.basetype == SPIRType::UInt) { auto expected_type = coord_type; + expected_type.vecsize = coord_components; expected_type.basetype = SPIRType::Int; coord_expr = bitcast_expression(expected_type, coord_type.basetype, coord_expr); } @@ -4690,7 +4691,19 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, boo { forward = forward && should_forward(lod); farg_str += ", "; - farg_str += to_expression(lod); + + auto &lod_expr_type = expression_type(lod); + + // Lod expression for TexelFetch in GLSL must be int, and only int. + if (is_fetch && imgtype.image.dim != DimBuffer && !imgtype.image.ms && + lod_expr_type.basetype != SPIRType::Int) + { + farg_str += join("int(", to_expression(lod), ")"); + } + else + { + farg_str += to_expression(lod); + } } } } diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 0cbf75b2..30d398e6 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -2716,7 +2716,8 @@ void CompilerHLSL::emit_texture_op(const Instruction &i) // The IR can give us more components than we need, so chop them off as needed. string coord_expr; - if (coord_components != expression_type(coord).vecsize) + auto &coord_type = expression_type(coord); + if (coord_components != coord_type.vecsize) coord_expr = to_enclosed_expression(coord) + swizzle(coord_components, expression_type(coord).vecsize); else coord_expr = to_expression(coord); @@ -2726,9 +2727,8 @@ void CompilerHLSL::emit_texture_op(const Instruction &i) if (hlsl_options.shader_model < 40 && lod) { - auto &coordtype = expression_type(coord); string coord_filler; - for (uint32_t size = coordtype.vecsize; size < 3; ++size) + for (uint32_t size = coord_components; size < 3; ++size) { coord_filler += ", 0.0"; } @@ -2737,9 +2737,8 @@ void CompilerHLSL::emit_texture_op(const Instruction &i) if (hlsl_options.shader_model < 40 && bias) { - auto &coordtype = expression_type(coord); string coord_filler; - for (uint32_t size = coordtype.vecsize; size < 3; ++size) + for (uint32_t size = coord_components; size < 3; ++size) { coord_filler += ", 0.0"; } @@ -2748,10 +2747,9 @@ void CompilerHLSL::emit_texture_op(const Instruction &i) if (op == OpImageFetch) { - auto &coordtype = expression_type(coord); if (imgtype.image.dim != DimBuffer && !imgtype.image.ms) coord_expr = - join("int", coordtype.vecsize + 1, "(", coord_expr, ", ", lod ? to_expression(lod) : string("0"), ")"); + join("int", coord_components + 1, "(", coord_expr, ", ", lod ? to_expression(lod) : string("0"), ")"); } else expr += ", ";