From fb91e3c8f378a4a5d709e45667f3b22d500b15eb Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 29 Jul 2021 18:05:19 +0000 Subject: [PATCH] transform: DMA: Don't load ignore() arguments ignore() might be passed a structure holding a runtime array. Fixed: tint:1046 Change-Id: I2beab91d8faabe69409308cf3e24b6403a84dd56 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60213 Kokoro: Kokoro Reviewed-by: David Neto Auto-Submit: Ben Clayton --- src/transform/decompose_memory_access.cc | 7 + test/bug/tint/1046.wgsl | 80 +++++++++ test/bug/tint/1046.wgsl.expected.hlsl | 61 +++++++ test/bug/tint/1046.wgsl.expected.msl | 70 ++++++++ test/bug/tint/1046.wgsl.expected.spvasm | 217 +++++++++++++++++++++++ test/bug/tint/1046.wgsl.expected.wgsl | 69 +++++++ 6 files changed, 504 insertions(+) create mode 100644 test/bug/tint/1046.wgsl create mode 100644 test/bug/tint/1046.wgsl.expected.hlsl create mode 100644 test/bug/tint/1046.wgsl.expected.msl create mode 100644 test/bug/tint/1046.wgsl.expected.spvasm create mode 100644 test/bug/tint/1046.wgsl.expected.wgsl diff --git a/src/transform/decompose_memory_access.cc b/src/transform/decompose_memory_access.cc index 8f94f18658..09aed03aa2 100644 --- a/src/transform/decompose_memory_access.cc +++ b/src/transform/decompose_memory_access.cc @@ -915,11 +915,18 @@ void DecomposeMemoryAccess::Run(CloneContext& ctx, const DataMap&, DataMap&) { if (auto* call_expr = node->As()) { auto* call = sem.Get(call_expr); if (auto* intrinsic = call->Target()->As()) { + if (intrinsic->Type() == sem::IntrinsicType::kIgnore) { + // ignore(X) + // Don't convert X into a load, this isn't actually used. + state.TakeAccess(call_expr->params()[0]); + continue; + } if (intrinsic->Type() == sem::IntrinsicType::kArrayLength) { // arrayLength(X) // Don't convert X into a load, this intrinsic actually requires the // real pointer. state.TakeAccess(call_expr->params()[0]); + continue; } if (intrinsic->IsAtomic()) { if (auto access = state.TakeAccess(call_expr->params()[0])) { diff --git a/test/bug/tint/1046.wgsl b/test/bug/tint/1046.wgsl new file mode 100644 index 0000000000..c288728636 --- /dev/null +++ b/test/bug/tint/1046.wgsl @@ -0,0 +1,80 @@ + +struct PointLight { + position : vec4; +}; + +[[block]] struct PointLights { + values : [[stride(16)]] array; +}; + +[[block]] struct Uniforms { + worldView : mat4x4; + proj : mat4x4; + numPointLights : u32; + color_source : u32; + color : vec4; +}; + +[[binding(0), group(0)]] var uniforms : Uniforms; +[[binding(1), group(0)]] var pointLights : PointLights; +[[binding(2), group(0)]] var mySampler: sampler; +[[binding(3), group(0)]] var myTexture: texture_2d; + +struct FragmentInput { + [[builtin(position)]] position : vec4; + [[location(0)]] view_position : vec4; + [[location(1)]] normal : vec4; + [[location(2)]] uv : vec2; + [[location(3)]] color : vec4; +}; + +struct FragmentOutput { + [[location(0)]] color : vec4; +}; + +fn getColor(fragment : FragmentInput) -> vec4{ + + var color : vec4; + + if(uniforms.color_source == 0u){ + // VERTEX COLOR + + color = fragment.color; + + }elseif(uniforms.color_source == 1u){ + // NORMALS + + // color = vec4(0.0, 0.0, 1.0, 1.0); + color = fragment.normal; + color.a = 1.0; + + }elseif(uniforms.color_source == 2u){ + // uniform color + + color = uniforms.color; + + }elseif(uniforms.color_source == 3u){ + // TEXTURE + + color = textureSample(myTexture, mySampler, fragment.uv); + + } + + return color; +}; + +[[stage(fragment)]] +fn main(fragment : FragmentInput) -> FragmentOutput { + + var output : FragmentOutput; + output.color = vec4(1.0, 0.0, 0.0, 1.0); + + ignore(uniforms); + ignore(mySampler); + ignore(myTexture); + + ignore(pointLights); + // output.color.x = output.color.x + pointLights.values[0].position.x; + + return output; +} diff --git a/test/bug/tint/1046.wgsl.expected.hlsl b/test/bug/tint/1046.wgsl.expected.hlsl new file mode 100644 index 0000000000..fd700b1950 --- /dev/null +++ b/test/bug/tint/1046.wgsl.expected.hlsl @@ -0,0 +1,61 @@ +cbuffer cbuffer_uniforms : register(b0, space0) { + uint4 uniforms[10]; +}; +ByteAddressBuffer pointLights : register(t1, space0); +SamplerState mySampler : register(s2, space0); +Texture2D myTexture : register(t3, space0); + +struct FragmentInput { + float4 position; + float4 view_position; + float4 normal; + float2 uv; + float4 color; +}; +struct FragmentOutput { + float4 color; +}; + +float4 getColor(FragmentInput fragment) { + float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f); + if ((uniforms[8].y == 0u)) { + color = fragment.color; + } else { + if ((uniforms[8].y == 1u)) { + color = fragment.normal; + color.a = 1.0f; + } else { + if ((uniforms[8].y == 2u)) { + color = asfloat(uniforms[9]); + } else { + if ((uniforms[8].y == 3u)) { + color = myTexture.Sample(mySampler, fragment.uv); + } + } + } + } + return color; +} + +struct tint_symbol_1 { + float4 view_position : TEXCOORD0; + float4 normal : TEXCOORD1; + float2 uv : TEXCOORD2; + float4 color : TEXCOORD3; + float4 position : SV_Position; +}; +struct tint_symbol_2 { + float4 color : SV_Target0; +}; + +tint_symbol_2 main(tint_symbol_1 tint_symbol) { + const FragmentInput fragment = {tint_symbol.position, tint_symbol.view_position, tint_symbol.normal, tint_symbol.uv, tint_symbol.color}; + FragmentOutput output = (FragmentOutput)0; + output.color = float4(1.0f, 0.0f, 0.0f, 1.0f); + uniforms; + mySampler; + myTexture; + pointLights; + const tint_symbol_2 tint_symbol_5 = {output.color}; + return tint_symbol_5; +} diff --git a/test/bug/tint/1046.wgsl.expected.msl b/test/bug/tint/1046.wgsl.expected.msl new file mode 100644 index 0000000000..0de4fdfc5c --- /dev/null +++ b/test/bug/tint/1046.wgsl.expected.msl @@ -0,0 +1,70 @@ +#include + +using namespace metal; +struct PointLight { + /* 0x0000 */ packed_float4 position; +}; +struct PointLights { + /* 0x0000 */ PointLight values[1]; +}; +struct Uniforms { + /* 0x0000 */ float4x4 worldView; + /* 0x0040 */ float4x4 proj; + /* 0x0080 */ uint numPointLights; + /* 0x0084 */ uint color_source; + /* 0x0088 */ int8_t tint_pad[8]; + /* 0x0090 */ packed_float4 color; +}; +struct FragmentInput { + float4 position; + float4 view_position; + float4 normal; + float2 uv; + float4 color; +}; +struct FragmentOutput { + float4 color; +}; +struct tint_symbol_4 { + float4 view_position [[user(locn0)]]; + float4 normal [[user(locn1)]]; + float2 uv [[user(locn2)]]; + float4 color [[user(locn3)]]; +}; +struct tint_symbol_5 { + float4 color [[color(0)]]; +}; + +float4 getColor(constant Uniforms& uniforms, FragmentInput tint_symbol, texture2d tint_symbol_7, sampler tint_symbol_8) { + float4 color = 0.0f; + if ((uniforms.color_source == 0u)) { + color = tint_symbol.color; + } else { + if ((uniforms.color_source == 1u)) { + color = tint_symbol.normal; + color.a = 1.0f; + } else { + if ((uniforms.color_source == 2u)) { + color = uniforms.color; + } else { + if ((uniforms.color_source == 3u)) { + color = tint_symbol_7.sample(tint_symbol_8, tint_symbol.uv); + } + } + } + } + return color; +} + +fragment tint_symbol_5 tint_symbol_1(sampler tint_symbol_9 [[sampler(2)]], texture2d tint_symbol_10 [[texture(3)]], float4 tint_symbol_3 [[position]], tint_symbol_4 tint_symbol_2 [[stage_in]], constant Uniforms& uniforms [[buffer(0)]], const device PointLights& pointLights [[buffer(1)]]) { + FragmentInput const tint_symbol = {.position=tint_symbol_3, .view_position=tint_symbol_2.view_position, .normal=tint_symbol_2.normal, .uv=tint_symbol_2.uv, .color=tint_symbol_2.color}; + FragmentOutput output = {}; + output.color = float4(1.0f, 0.0f, 0.0f, 1.0f); + (void) uniforms; + (void) tint_symbol_9; + (void) tint_symbol_10; + (void) pointLights; + tint_symbol_5 const tint_symbol_6 = {.color=output.color}; + return tint_symbol_6; +} + diff --git a/test/bug/tint/1046.wgsl.expected.spvasm b/test/bug/tint/1046.wgsl.expected.spvasm new file mode 100644 index 0000000000..9623706658 --- /dev/null +++ b/test/bug/tint/1046.wgsl.expected.spvasm @@ -0,0 +1,217 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 114 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %tint_symbol %tint_symbol_1 %tint_symbol_2 %tint_symbol_3 %tint_symbol_4 %tint_symbol_7 + OpExecutionMode %main OriginUpperLeft + OpName %Uniforms "Uniforms" + OpMemberName %Uniforms 0 "worldView" + OpMemberName %Uniforms 1 "proj" + OpMemberName %Uniforms 2 "numPointLights" + OpMemberName %Uniforms 3 "color_source" + OpMemberName %Uniforms 4 "color" + OpName %uniforms "uniforms" + OpName %PointLights "PointLights" + OpMemberName %PointLights 0 "values" + OpName %PointLight "PointLight" + OpMemberName %PointLight 0 "position" + OpName %pointLights "pointLights" + OpName %mySampler "mySampler" + OpName %myTexture "myTexture" + OpName %tint_symbol "tint_symbol" + OpName %tint_symbol_1 "tint_symbol_1" + OpName %tint_symbol_2 "tint_symbol_2" + OpName %tint_symbol_3 "tint_symbol_3" + OpName %tint_symbol_4 "tint_symbol_4" + OpName %tint_symbol_7 "tint_symbol_7" + OpName %FragmentInput "FragmentInput" + OpMemberName %FragmentInput 0 "position" + OpMemberName %FragmentInput 1 "view_position" + OpMemberName %FragmentInput 2 "normal" + OpMemberName %FragmentInput 3 "uv" + OpMemberName %FragmentInput 4 "color" + OpName %getColor "getColor" + OpName %fragment "fragment" + OpName %color "color" + OpName %FragmentOutput "FragmentOutput" + OpMemberName %FragmentOutput 0 "color" + OpName %tint_symbol_8 "tint_symbol_8" + OpName %tint_symbol_6 "tint_symbol_6" + OpName %main "main" + OpName %output "output" + OpDecorate %Uniforms Block + OpMemberDecorate %Uniforms 0 Offset 0 + OpMemberDecorate %Uniforms 0 ColMajor + OpMemberDecorate %Uniforms 0 MatrixStride 16 + OpMemberDecorate %Uniforms 1 Offset 64 + OpMemberDecorate %Uniforms 1 ColMajor + OpMemberDecorate %Uniforms 1 MatrixStride 16 + OpMemberDecorate %Uniforms 2 Offset 128 + OpMemberDecorate %Uniforms 3 Offset 132 + OpMemberDecorate %Uniforms 4 Offset 144 + OpDecorate %uniforms NonWritable + OpDecorate %uniforms Binding 0 + OpDecorate %uniforms DescriptorSet 0 + OpDecorate %PointLights Block + OpMemberDecorate %PointLights 0 Offset 0 + OpMemberDecorate %PointLight 0 Offset 0 + OpDecorate %_runtimearr_PointLight ArrayStride 16 + OpDecorate %pointLights NonWritable + OpDecorate %pointLights Binding 1 + OpDecorate %pointLights DescriptorSet 0 + OpDecorate %mySampler Binding 2 + OpDecorate %mySampler DescriptorSet 0 + OpDecorate %myTexture Binding 3 + OpDecorate %myTexture DescriptorSet 0 + OpDecorate %tint_symbol BuiltIn FragCoord + OpDecorate %tint_symbol_1 Location 0 + OpDecorate %tint_symbol_2 Location 1 + OpDecorate %tint_symbol_3 Location 2 + OpDecorate %tint_symbol_4 Location 3 + OpDecorate %tint_symbol_7 Location 0 + OpMemberDecorate %FragmentInput 0 Offset 0 + OpMemberDecorate %FragmentInput 1 Offset 16 + OpMemberDecorate %FragmentInput 2 Offset 32 + OpMemberDecorate %FragmentInput 3 Offset 48 + OpMemberDecorate %FragmentInput 4 Offset 64 + OpMemberDecorate %FragmentOutput 0 Offset 0 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%mat4v4float = OpTypeMatrix %v4float 4 + %uint = OpTypeInt 32 0 + %Uniforms = OpTypeStruct %mat4v4float %mat4v4float %uint %uint %v4float +%_ptr_Uniform_Uniforms = OpTypePointer Uniform %Uniforms + %uniforms = OpVariable %_ptr_Uniform_Uniforms Uniform + %PointLight = OpTypeStruct %v4float +%_runtimearr_PointLight = OpTypeRuntimeArray %PointLight +%PointLights = OpTypeStruct %_runtimearr_PointLight +%_ptr_StorageBuffer_PointLights = OpTypePointer StorageBuffer %PointLights +%pointLights = OpVariable %_ptr_StorageBuffer_PointLights StorageBuffer + %15 = OpTypeSampler +%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15 + %mySampler = OpVariable %_ptr_UniformConstant_15 UniformConstant + %18 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18 + %myTexture = OpVariable %_ptr_UniformConstant_18 UniformConstant +%_ptr_Input_v4float = OpTypePointer Input %v4float +%tint_symbol = OpVariable %_ptr_Input_v4float Input +%tint_symbol_1 = OpVariable %_ptr_Input_v4float Input +%tint_symbol_2 = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float +%tint_symbol_3 = OpVariable %_ptr_Input_v2float Input +%tint_symbol_4 = OpVariable %_ptr_Input_v4float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float + %29 = OpConstantNull %v4float +%tint_symbol_7 = OpVariable %_ptr_Output_v4float Output %29 +%FragmentInput = OpTypeStruct %v4float %v4float %v4float %v2float %v4float + %30 = OpTypeFunction %v4float %FragmentInput +%_ptr_Function_v4float = OpTypePointer Function %v4float + %uint_3 = OpConstant %uint 3 +%_ptr_Uniform_uint = OpTypePointer Uniform %uint + %uint_0 = OpConstant %uint 0 + %bool = OpTypeBool + %uint_1 = OpConstant %uint 1 +%_ptr_Function_float = OpTypePointer Function %float + %float_1 = OpConstant %float 1 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 +%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float + %78 = OpTypeSampledImage %18 + %void = OpTypeVoid +%FragmentOutput = OpTypeStruct %v4float + %82 = OpTypeFunction %void %FragmentOutput + %89 = OpTypeFunction %void +%_ptr_Function_FragmentOutput = OpTypePointer Function %FragmentOutput + %100 = OpConstantNull %FragmentOutput + %float_0 = OpConstant %float 0 + %103 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1 + %getColor = OpFunction %v4float None %30 + %fragment = OpFunctionParameter %FragmentInput + %34 = OpLabel + %color = OpVariable %_ptr_Function_v4float Function %29 + %39 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3 + %40 = OpLoad %uint %39 + %42 = OpIEqual %bool %40 %uint_0 + OpSelectionMerge %44 None + OpBranchConditional %42 %45 %46 + %45 = OpLabel + %47 = OpCompositeExtract %v4float %fragment 4 + OpStore %color %47 + OpBranch %44 + %46 = OpLabel + %48 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3 + %49 = OpLoad %uint %48 + %51 = OpIEqual %bool %49 %uint_1 + OpSelectionMerge %52 None + OpBranchConditional %51 %53 %54 + %53 = OpLabel + %55 = OpCompositeExtract %v4float %fragment 2 + OpStore %color %55 + %57 = OpAccessChain %_ptr_Function_float %color %uint_3 + OpStore %57 %float_1 + OpBranch %52 + %54 = OpLabel + %59 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3 + %60 = OpLoad %uint %59 + %62 = OpIEqual %bool %60 %uint_2 + OpSelectionMerge %63 None + OpBranchConditional %62 %64 %65 + %64 = OpLabel + %68 = OpAccessChain %_ptr_Uniform_v4float %uniforms %uint_4 + %69 = OpLoad %v4float %68 + OpStore %color %69 + OpBranch %63 + %65 = OpLabel + %70 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3 + %71 = OpLoad %uint %70 + %72 = OpIEqual %bool %71 %uint_3 + OpSelectionMerge %73 None + OpBranchConditional %72 %74 %73 + %74 = OpLabel + %76 = OpLoad %15 %mySampler + %77 = OpLoad %18 %myTexture + %79 = OpSampledImage %78 %77 %76 + %80 = OpCompositeExtract %v2float %fragment 3 + %75 = OpImageSampleImplicitLod %v4float %79 %80 + OpStore %color %75 + OpBranch %73 + %73 = OpLabel + OpBranch %63 + %63 = OpLabel + OpBranch %52 + %52 = OpLabel + OpBranch %44 + %44 = OpLabel + %81 = OpLoad %v4float %color + OpReturnValue %81 + OpFunctionEnd +%tint_symbol_8 = OpFunction %void None %82 +%tint_symbol_6 = OpFunctionParameter %FragmentOutput + %87 = OpLabel + %88 = OpCompositeExtract %v4float %tint_symbol_6 0 + OpStore %tint_symbol_7 %88 + OpReturn + OpFunctionEnd + %main = OpFunction %void None %89 + %91 = OpLabel + %output = OpVariable %_ptr_Function_FragmentOutput Function %100 + %92 = OpLoad %v4float %tint_symbol + %93 = OpLoad %v4float %tint_symbol_1 + %94 = OpLoad %v4float %tint_symbol_2 + %95 = OpLoad %v2float %tint_symbol_3 + %96 = OpLoad %v4float %tint_symbol_4 + %97 = OpCompositeConstruct %FragmentInput %92 %93 %94 %95 %96 + %101 = OpAccessChain %_ptr_Function_v4float %output %uint_0 + OpStore %101 %103 + %105 = OpLoad %Uniforms %uniforms + %107 = OpLoad %15 %mySampler + %109 = OpLoad %18 %myTexture + %111 = OpLoad %PointLights %pointLights + %113 = OpLoad %FragmentOutput %output + %112 = OpFunctionCall %void %tint_symbol_8 %113 + OpReturn + OpFunctionEnd diff --git a/test/bug/tint/1046.wgsl.expected.wgsl b/test/bug/tint/1046.wgsl.expected.wgsl new file mode 100644 index 0000000000..f041af84df --- /dev/null +++ b/test/bug/tint/1046.wgsl.expected.wgsl @@ -0,0 +1,69 @@ +struct PointLight { + position : vec4; +}; + +[[block]] +struct PointLights { + values : [[stride(16)]] array; +}; + +[[block]] +struct Uniforms { + worldView : mat4x4; + proj : mat4x4; + numPointLights : u32; + color_source : u32; + color : vec4; +}; + +[[binding(0), group(0)]] var uniforms : Uniforms; + +[[binding(1), group(0)]] var pointLights : PointLights; + +[[binding(2), group(0)]] var mySampler : sampler; + +[[binding(3), group(0)]] var myTexture : texture_2d; + +struct FragmentInput { + [[builtin(position)]] + position : vec4; + [[location(0)]] + view_position : vec4; + [[location(1)]] + normal : vec4; + [[location(2)]] + uv : vec2; + [[location(3)]] + color : vec4; +}; + +struct FragmentOutput { + [[location(0)]] + color : vec4; +}; + +fn getColor(fragment : FragmentInput) -> vec4 { + var color : vec4; + if ((uniforms.color_source == 0u)) { + color = fragment.color; + } elseif ((uniforms.color_source == 1u)) { + color = fragment.normal; + color.a = 1.0; + } elseif ((uniforms.color_source == 2u)) { + color = uniforms.color; + } elseif ((uniforms.color_source == 3u)) { + color = textureSample(myTexture, mySampler, fragment.uv); + } + return color; +} + +[[stage(fragment)]] +fn main(fragment : FragmentInput) -> FragmentOutput { + var output : FragmentOutput; + output.color = vec4(1.0, 0.0, 0.0, 1.0); + ignore(uniforms); + ignore(mySampler); + ignore(myTexture); + ignore(pointLights); + return output; +}