diff --git a/test/bug/dawn/947.wgsl b/test/bug/dawn/947.wgsl new file mode 100644 index 0000000000..5cee0a4f5a --- /dev/null +++ b/test/bug/dawn/947.wgsl @@ -0,0 +1,63 @@ +[[block]] struct Uniforms { + u_scale : vec2; + u_offset : vec2; +}; +[[binding(0), group(0)]] var uniforms : Uniforms; + +struct VertexOutputs { + [[location(0)]] texcoords : vec2; + [[builtin(position)]] position : vec4; +}; + +[[stage(vertex)]] fn vs_main( + [[builtin(vertex_index)]] VertexIndex : u32 +) -> VertexOutputs { + var texcoord = array, 3>( + vec2(-0.5, 0.0), + vec2( 1.5, 0.0), + vec2( 0.5, 2.0)); + + var output : VertexOutputs; + output.position = vec4((texcoord[VertexIndex] * 2.0 - vec2(1.0, 1.0)), 0.0, 1.0); + + // Y component of scale is calculated by the copySizeHeight / textureHeight. Only + // flipY case can get negative number. + var flipY = uniforms.u_scale.y < 0.0; + + // Texture coordinate takes top-left as origin point. We need to map the + // texture to triangle carefully. + if (flipY) { + // We need to get the mirror positions(mirrored based on y = 0.5) on flip cases. + // Adopt transform to src texture and then mapping it to triangle coord which + // do a +1 shift on Y dimension will help us got that mirror position perfectly. + output.texcoords = (texcoord[VertexIndex] * uniforms.u_scale + uniforms.u_offset) * + vec2(1.0, -1.0) + vec2(0.0, 1.0); + } else { + // For the normal case, we need to get the exact position. + // So mapping texture to triangle firstly then adopt the transform. + output.texcoords = (texcoord[VertexIndex] * + vec2(1.0, -1.0) + vec2(0.0, 1.0)) * + uniforms.u_scale + uniforms.u_offset; + } + + return output; +} + +[[binding(1), group(0)]] var mySampler: sampler; +[[binding(2), group(0)]] var myTexture: texture_2d; + +[[stage(fragment)]] fn fs_main( + [[location(0)]] texcoord : vec2 +) -> [[location(0)]] vec4 { + // Clamp the texcoord and discard the out-of-bound pixels. + var clampedTexcoord = + clamp(texcoord, vec2(0.0, 0.0), vec2(1.0, 1.0)); + if (!all(clampedTexcoord == texcoord)) { + discard; + } + + var srcColor = textureSample(myTexture, mySampler, texcoord); + // Swizzling of texture formats when sampling / rendering is handled by the + // hardware so we don't need special logic in this shader. This is covered by tests. + return srcColor; +} diff --git a/test/bug/dawn/947.wgsl.expected.hlsl b/test/bug/dawn/947.wgsl.expected.hlsl new file mode 100644 index 0000000000..8e0ad9c0ea --- /dev/null +++ b/test/bug/dawn/947.wgsl.expected.hlsl @@ -0,0 +1,63 @@ +cbuffer cbuffer_uniforms : register(b0, space0) { + uint4 uniforms[1]; +}; + +struct VertexOutputs { + float2 texcoords; + float4 position; +}; +struct tint_symbol_1 { + uint VertexIndex : SV_VertexID; +}; +struct tint_symbol_2 { + float2 texcoords : TEXCOORD0; + float4 position : SV_Position; +}; +struct tint_array_wrapper { + float2 arr[3]; +}; + +tint_symbol_2 vs_main(tint_symbol_1 tint_symbol) { + const uint VertexIndex = tint_symbol.VertexIndex; + tint_array_wrapper texcoord = {{float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)}}; + VertexOutputs output = {float2(0.0f, 0.0f), float4(0.0f, 0.0f, 0.0f, 0.0f)}; + output.position = float4(((texcoord.arr[VertexIndex] * 2.0f) - float2(1.0f, 1.0f)), 0.0f, 1.0f); + const int scalar_offset = (4u) / 4; + bool flipY = (asfloat(uniforms[scalar_offset / 4][scalar_offset % 4]) < 0.0f); + if (flipY) { + const int scalar_offset_1 = (0u) / 4; + uint4 ubo_load = uniforms[scalar_offset_1 / 4]; + const int scalar_offset_2 = (8u) / 4; + uint4 ubo_load_1 = uniforms[scalar_offset_2 / 4]; + output.texcoords = ((((texcoord.arr[VertexIndex] * asfloat(((scalar_offset_1 & 2) ? ubo_load.zw : ubo_load.xy))) + asfloat(((scalar_offset_2 & 2) ? ubo_load_1.zw : ubo_load_1.xy))) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)); + } else { + const int scalar_offset_3 = (0u) / 4; + uint4 ubo_load_2 = uniforms[scalar_offset_3 / 4]; + const int scalar_offset_4 = (8u) / 4; + uint4 ubo_load_3 = uniforms[scalar_offset_4 / 4]; + output.texcoords = ((((texcoord.arr[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(((scalar_offset_3 & 2) ? ubo_load_2.zw : ubo_load_2.xy))) + asfloat(((scalar_offset_4 & 2) ? ubo_load_3.zw : ubo_load_3.xy))); + } + const tint_symbol_2 tint_symbol_8 = {output.texcoords, output.position}; + return tint_symbol_8; +} + +SamplerState mySampler : register(s1, space0); +Texture2D myTexture : register(t2, space0); + +struct tint_symbol_4 { + float2 texcoord : TEXCOORD0; +}; +struct tint_symbol_5 { + float4 value : SV_Target0; +}; + +tint_symbol_5 fs_main(tint_symbol_4 tint_symbol_3) { + const float2 texcoord = tint_symbol_3.texcoord; + float2 clampedTexcoord = clamp(texcoord, float2(0.0f, 0.0f), float2(1.0f, 1.0f)); + if (!(all((clampedTexcoord == texcoord)))) { + discard; + } + float4 srcColor = myTexture.Sample(mySampler, texcoord); + const tint_symbol_5 tint_symbol_9 = {srcColor}; + return tint_symbol_9; +} diff --git a/test/bug/dawn/947.wgsl.expected.msl b/test/bug/dawn/947.wgsl.expected.msl new file mode 100644 index 0000000000..b33557aba7 --- /dev/null +++ b/test/bug/dawn/947.wgsl.expected.msl @@ -0,0 +1,50 @@ +#include + +using namespace metal; +struct Uniforms { + /* 0x0000 */ packed_float2 u_scale; + /* 0x0008 */ packed_float2 u_offset; +}; +struct VertexOutputs { + float2 texcoords; + float4 position; +}; +struct tint_symbol_1 { + float2 texcoords [[user(locn0)]]; + float4 position [[position]]; +}; +struct tint_array_wrapper { + float2 arr[3]; +}; +struct tint_symbol_3 { + float2 texcoord [[user(locn0)]]; +}; +struct tint_symbol_4 { + float4 value [[color(0)]]; +}; + +vertex tint_symbol_1 vs_main(uint VertexIndex [[vertex_id]], constant Uniforms& uniforms [[buffer(0)]]) { + tint_array_wrapper texcoord = {.arr={float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)}}; + VertexOutputs output = {}; + output.position = float4(((texcoord.arr[VertexIndex] * 2.0f) - float2(1.0f, 1.0f)), 0.0f, 1.0f); + bool flipY = (uniforms.u_scale.y < 0.0f); + if (flipY) { + output.texcoords = ((((texcoord.arr[VertexIndex] * uniforms.u_scale) + uniforms.u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)); + } else { + output.texcoords = ((((texcoord.arr[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * uniforms.u_scale) + uniforms.u_offset); + } + tint_symbol_1 const tint_symbol_5 = {.texcoords=output.texcoords, .position=output.position}; + return tint_symbol_5; +} + +fragment tint_symbol_4 fs_main(texture2d tint_symbol_7 [[texture(2)]], sampler tint_symbol_8 [[sampler(1)]], tint_symbol_3 tint_symbol_2 [[stage_in]]) { + float2 const texcoord = tint_symbol_2.texcoord; + float2 clampedTexcoord = clamp(texcoord, float2(0.0f, 0.0f), float2(1.0f, 1.0f)); + if (!( all((clampedTexcoord == texcoord)))) { + discard_fragment(); + } + float4 srcColor = tint_symbol_7.sample(tint_symbol_8, texcoord); + tint_symbol_4 const tint_symbol_6 = {.value=srcColor}; + return tint_symbol_6; +} + diff --git a/test/bug/dawn/947.wgsl.expected.spvasm b/test/bug/dawn/947.wgsl.expected.spvasm new file mode 100644 index 0000000000..2f6571e9cc --- /dev/null +++ b/test/bug/dawn/947.wgsl.expected.spvasm @@ -0,0 +1,221 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 141 +; Schema: 0 + OpCapability Shader + %120 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %vs_main "vs_main" %tint_pointsize %tint_symbol %tint_symbol_2 %tint_symbol_3 + OpEntryPoint Fragment %fs_main "fs_main" %tint_symbol_5 %tint_symbol_7 + OpExecutionMode %fs_main OriginUpperLeft + OpName %tint_pointsize "tint_pointsize" + OpName %Uniforms "Uniforms" + OpMemberName %Uniforms 0 "u_scale" + OpMemberName %Uniforms 1 "u_offset" + OpName %uniforms "uniforms" + OpName %tint_symbol "tint_symbol" + OpName %tint_symbol_2 "tint_symbol_2" + OpName %tint_symbol_3 "tint_symbol_3" + OpName %mySampler "mySampler" + OpName %myTexture "myTexture" + OpName %tint_symbol_5 "tint_symbol_5" + OpName %tint_symbol_7 "tint_symbol_7" + OpName %VertexOutputs "VertexOutputs" + OpMemberName %VertexOutputs 0 "texcoords" + OpMemberName %VertexOutputs 1 "position" + OpName %tint_symbol_4 "tint_symbol_4" + OpName %tint_symbol_1 "tint_symbol_1" + OpName %vs_main "vs_main" + OpName %texcoord "texcoord" + OpName %output "output" + OpName %flipY "flipY" + OpName %tint_symbol_8 "tint_symbol_8" + OpName %tint_symbol_6 "tint_symbol_6" + OpName %fs_main "fs_main" + OpName %clampedTexcoord "clampedTexcoord" + OpName %srcColor "srcColor" + OpDecorate %tint_pointsize BuiltIn PointSize + OpDecorate %Uniforms Block + OpMemberDecorate %Uniforms 0 Offset 0 + OpMemberDecorate %Uniforms 1 Offset 8 + OpDecorate %uniforms NonWritable + OpDecorate %uniforms Binding 0 + OpDecorate %uniforms DescriptorSet 0 + OpDecorate %tint_symbol BuiltIn VertexIndex + OpDecorate %tint_symbol_2 Location 0 + OpDecorate %tint_symbol_3 BuiltIn Position + OpDecorate %mySampler Binding 1 + OpDecorate %mySampler DescriptorSet 0 + OpDecorate %myTexture Binding 2 + OpDecorate %myTexture DescriptorSet 0 + OpDecorate %tint_symbol_5 Location 0 + OpDecorate %tint_symbol_7 Location 0 + OpMemberDecorate %VertexOutputs 0 Offset 0 + OpMemberDecorate %VertexOutputs 1 Offset 16 + OpDecorate %_arr_v2float_uint_3 ArrayStride 8 + %float = OpTypeFloat 32 +%_ptr_Output_float = OpTypePointer Output %float + %4 = OpConstantNull %float +%tint_pointsize = OpVariable %_ptr_Output_float Output %4 + %v2float = OpTypeVector %float 2 + %Uniforms = OpTypeStruct %v2float %v2float +%_ptr_Uniform_Uniforms = OpTypePointer Uniform %Uniforms + %uniforms = OpVariable %_ptr_Uniform_Uniforms Uniform + %uint = OpTypeInt 32 0 +%_ptr_Input_uint = OpTypePointer Input %uint +%tint_symbol = OpVariable %_ptr_Input_uint Input +%_ptr_Output_v2float = OpTypePointer Output %v2float + %14 = OpConstantNull %v2float +%tint_symbol_2 = OpVariable %_ptr_Output_v2float Output %14 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %18 = OpConstantNull %v4float +%tint_symbol_3 = OpVariable %_ptr_Output_v4float Output %18 + %21 = OpTypeSampler +%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 + %mySampler = OpVariable %_ptr_UniformConstant_21 UniformConstant + %24 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_24 = OpTypePointer UniformConstant %24 + %myTexture = OpVariable %_ptr_UniformConstant_24 UniformConstant +%_ptr_Input_v2float = OpTypePointer Input %v2float +%tint_symbol_5 = OpVariable %_ptr_Input_v2float Input +%tint_symbol_7 = OpVariable %_ptr_Output_v4float Output %18 + %void = OpTypeVoid +%VertexOutputs = OpTypeStruct %v2float %v4float + %28 = OpTypeFunction %void %VertexOutputs + %36 = OpTypeFunction %void + %float_1 = OpConstant %float 1 + %uint_3 = OpConstant %uint 3 +%_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3 + %float_n0_5 = OpConstant %float -0.5 + %float_0 = OpConstant %float 0 + %44 = OpConstantComposite %v2float %float_n0_5 %float_0 + %float_1_5 = OpConstant %float 1.5 + %46 = OpConstantComposite %v2float %float_1_5 %float_0 + %float_0_5 = OpConstant %float 0.5 + %float_2 = OpConstant %float 2 + %49 = OpConstantComposite %v2float %float_0_5 %float_2 + %50 = OpConstantComposite %_arr_v2float_uint_3 %44 %46 %49 +%_ptr_Function__arr_v2float_uint_3 = OpTypePointer Function %_arr_v2float_uint_3 + %53 = OpConstantNull %_arr_v2float_uint_3 +%_ptr_Function_VertexOutputs = OpTypePointer Function %VertexOutputs + %56 = OpConstantNull %VertexOutputs + %uint_1 = OpConstant %uint 1 +%_ptr_Function_v4float = OpTypePointer Function %v4float +%_ptr_Function_v2float = OpTypePointer Function %v2float + %65 = OpConstantComposite %v2float %float_1 %float_1 + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_float = OpTypePointer Uniform %float + %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %78 = OpConstantNull %bool +%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float + %float_n1 = OpConstant %float -1 + %95 = OpConstantComposite %v2float %float_1 %float_n1 + %97 = OpConstantComposite %v2float %float_0 %float_1 + %113 = OpTypeFunction %void %v4float + %122 = OpConstantComposite %v2float %float_0 %float_0 + %v2bool = OpTypeVector %bool 2 + %135 = OpTypeSampledImage %24 +%tint_symbol_4 = OpFunction %void None %28 +%tint_symbol_1 = OpFunctionParameter %VertexOutputs + %33 = OpLabel + %34 = OpCompositeExtract %v2float %tint_symbol_1 0 + OpStore %tint_symbol_2 %34 + %35 = OpCompositeExtract %v4float %tint_symbol_1 1 + OpStore %tint_symbol_3 %35 + OpReturn + OpFunctionEnd + %vs_main = OpFunction %void None %36 + %38 = OpLabel + %texcoord = OpVariable %_ptr_Function__arr_v2float_uint_3 Function %53 + %output = OpVariable %_ptr_Function_VertexOutputs Function %56 + %flipY = OpVariable %_ptr_Function_bool Function %78 + OpStore %tint_pointsize %float_1 + OpStore %texcoord %50 + %59 = OpAccessChain %_ptr_Function_v4float %output %uint_1 + %60 = OpLoad %uint %tint_symbol + %62 = OpAccessChain %_ptr_Function_v2float %texcoord %60 + %63 = OpLoad %v2float %62 + %64 = OpVectorTimesScalar %v2float %63 %float_2 + %66 = OpFSub %v2float %64 %65 + %67 = OpCompositeExtract %float %66 0 + %68 = OpCompositeExtract %float %66 1 + %69 = OpCompositeConstruct %v4float %67 %68 %float_0 %float_1 + OpStore %59 %69 + %72 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_1 + %73 = OpLoad %float %72 + %74 = OpFOrdLessThan %bool %73 %float_0 + OpStore %flipY %74 + %79 = OpLoad %bool %flipY + OpSelectionMerge %80 None + OpBranchConditional %79 %81 %82 + %81 = OpLabel + %83 = OpAccessChain %_ptr_Function_v2float %output %uint_0 + %84 = OpLoad %uint %tint_symbol + %85 = OpAccessChain %_ptr_Function_v2float %texcoord %84 + %86 = OpLoad %v2float %85 + %88 = OpAccessChain %_ptr_Uniform_v2float %uniforms %uint_0 + %89 = OpLoad %v2float %88 + %90 = OpFMul %v2float %86 %89 + %91 = OpAccessChain %_ptr_Uniform_v2float %uniforms %uint_1 + %92 = OpLoad %v2float %91 + %93 = OpFAdd %v2float %90 %92 + %96 = OpFMul %v2float %93 %95 + %98 = OpFAdd %v2float %96 %97 + OpStore %83 %98 + OpBranch %80 + %82 = OpLabel + %99 = OpAccessChain %_ptr_Function_v2float %output %uint_0 + %100 = OpLoad %uint %tint_symbol + %101 = OpAccessChain %_ptr_Function_v2float %texcoord %100 + %102 = OpLoad %v2float %101 + %103 = OpFMul %v2float %102 %95 + %104 = OpFAdd %v2float %103 %97 + %105 = OpAccessChain %_ptr_Uniform_v2float %uniforms %uint_0 + %106 = OpLoad %v2float %105 + %107 = OpFMul %v2float %104 %106 + %108 = OpAccessChain %_ptr_Uniform_v2float %uniforms %uint_1 + %109 = OpLoad %v2float %108 + %110 = OpFAdd %v2float %107 %109 + OpStore %99 %110 + OpBranch %80 + %80 = OpLabel + %112 = OpLoad %VertexOutputs %output + %111 = OpFunctionCall %void %tint_symbol_4 %112 + OpReturn + OpFunctionEnd +%tint_symbol_8 = OpFunction %void None %113 +%tint_symbol_6 = OpFunctionParameter %v4float + %116 = OpLabel + OpStore %tint_symbol_7 %tint_symbol_6 + OpReturn + OpFunctionEnd + %fs_main = OpFunction %void None %36 + %118 = OpLabel +%clampedTexcoord = OpVariable %_ptr_Function_v2float Function %14 + %srcColor = OpVariable %_ptr_Function_v4float Function %18 + %121 = OpLoad %v2float %tint_symbol_5 + %119 = OpExtInst %v2float %120 NClamp %121 %122 %65 + OpStore %clampedTexcoord %119 + %126 = OpLoad %v2float %clampedTexcoord + %127 = OpLoad %v2float %tint_symbol_5 + %128 = OpFOrdEqual %v2bool %126 %127 + %125 = OpAll %bool %128 + %124 = OpLogicalNot %bool %125 + OpSelectionMerge %130 None + OpBranchConditional %124 %131 %130 + %131 = OpLabel + OpKill + %130 = OpLabel + %133 = OpLoad %21 %mySampler + %134 = OpLoad %24 %myTexture + %136 = OpSampledImage %135 %134 %133 + %137 = OpLoad %v2float %tint_symbol_5 + %132 = OpImageSampleImplicitLod %v4float %136 %137 + OpStore %srcColor %132 + %140 = OpLoad %v4float %srcColor + %139 = OpFunctionCall %void %tint_symbol_8 %140 + OpReturn + OpFunctionEnd diff --git a/test/bug/dawn/947.wgsl.expected.wgsl b/test/bug/dawn/947.wgsl.expected.wgsl new file mode 100644 index 0000000000..618cc7282d --- /dev/null +++ b/test/bug/dawn/947.wgsl.expected.wgsl @@ -0,0 +1,42 @@ +[[block]] +struct Uniforms { + u_scale : vec2; + u_offset : vec2; +}; + +[[binding(0), group(0)]] var uniforms : Uniforms; + +struct VertexOutputs { + [[location(0)]] + texcoords : vec2; + [[builtin(position)]] + position : vec4; +}; + +[[stage(vertex)]] +fn vs_main([[builtin(vertex_index)]] VertexIndex : u32) -> VertexOutputs { + var texcoord = array, 3>(vec2(-0.5, 0.0), vec2(1.5, 0.0), vec2(0.5, 2.0)); + var output : VertexOutputs; + output.position = vec4(((texcoord[VertexIndex] * 2.0) - vec2(1.0, 1.0)), 0.0, 1.0); + var flipY = (uniforms.u_scale.y < 0.0); + if (flipY) { + output.texcoords = ((((texcoord[VertexIndex] * uniforms.u_scale) + uniforms.u_offset) * vec2(1.0, -1.0)) + vec2(0.0, 1.0)); + } else { + output.texcoords = ((((texcoord[VertexIndex] * vec2(1.0, -1.0)) + vec2(0.0, 1.0)) * uniforms.u_scale) + uniforms.u_offset); + } + return output; +} + +[[binding(1), group(0)]] var mySampler : sampler; + +[[binding(2), group(0)]] var myTexture : texture_2d; + +[[stage(fragment)]] +fn fs_main([[location(0)]] texcoord : vec2) -> [[location(0)]] vec4 { + var clampedTexcoord = clamp(texcoord, vec2(0.0, 0.0), vec2(1.0, 1.0)); + if (!(all((clampedTexcoord == texcoord)))) { + discard; + } + var srcColor = textureSample(myTexture, mySampler, texcoord); + return srcColor; +}