diff --git a/src/benchmark/benchmark.h b/src/benchmark/benchmark.h index 40de31d0d2..0d3c764bb5 100644 --- a/src/benchmark/benchmark.h +++ b/src/benchmark/benchmark.h @@ -57,12 +57,19 @@ std::variant LoadProgram(std::string name); /// Declares a set of benchmarks for the given function using a list of WGSL /// files in `/test/benchmark`. -#define TINT_BENCHMARK_WGSL_PROGRAMS(FUNC) \ - TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "empty.wgsl"); \ - TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "particles.wgsl"); \ - TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple_fragment.wgsl"); \ - TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple_vertex.wgsl"); \ - TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple_compute.wgsl"); +#define TINT_BENCHMARK_WGSL_PROGRAMS(FUNC) \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "animometer.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "bloom-vertical-blur.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "cluster-lights.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "empty.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "metaball-isosurface.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "particles.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "shadow-fragment.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple-compute.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple-fragment.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple-vertex.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "skinned-shadowed-pbr-fragment.wgsl"); \ + TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "skinned-shadowed-pbr-vertex.wgsl"); } // namespace tint::benchmark diff --git a/test/benchmark/animometer.wgsl b/test/benchmark/animometer.wgsl new file mode 100644 index 0000000000..b850d14602 --- /dev/null +++ b/test/benchmark/animometer.wgsl @@ -0,0 +1,48 @@ +struct Time { + value : f32; +} + +struct Uniforms { + scale : f32; + offsetX : f32; + offsetY : f32; + scalar : f32; + scalarOffset : f32; +} + +@binding(0) @group(0) var time : Time; + +@binding(1) @group(0) var uniforms : Uniforms; + +struct VertexOutput { + @builtin(position) + Position : vec4; + @location(0) + v_color : vec4; +} + +@stage(vertex) +fn vert_main(@location(0) position : vec4, @location(1) color : vec4) -> VertexOutput { + var fade : f32 = ((uniforms.scalarOffset + ((time.value * uniforms.scalar) / 10.0)) % 1.0); + if ((fade < 0.5)) { + fade = (fade * 2.0); + } else { + fade = ((1.0 - fade) * 2.0); + } + var xpos : f32 = (position.x * uniforms.scale); + var ypos : f32 = (position.y * uniforms.scale); + var angle : f32 = ((3.141590118 * 2.0) * fade); + var xrot : f32 = ((xpos * cos(angle)) - (ypos * sin(angle))); + var yrot : f32 = ((xpos * sin(angle)) + (ypos * cos(angle))); + xpos = (xrot + uniforms.offsetX); + ypos = (yrot + uniforms.offsetY); + var output : VertexOutput; + output.v_color = (vec4(fade, (1.0 - fade), 0.0, 1.0) + color); + output.Position = vec4(xpos, ypos, 0.0, 1.0); + return output; +} + +@stage(fragment) +fn frag_main(@location(0) v_color : vec4) -> @location(0) vec4 { + return v_color; +} diff --git a/test/benchmark/animometer.wgsl.expected.glsl b/test/benchmark/animometer.wgsl.expected.glsl new file mode 100644 index 0000000000..533937f5cc --- /dev/null +++ b/test/benchmark/animometer.wgsl.expected.glsl @@ -0,0 +1,149 @@ +SKIP: FAILED + +#version 310 es +precision mediump float; + +struct Time { + float value; +}; +struct Uniforms { + float scale; + float offsetX; + float offsetY; + float scalar; + float scalarOffset; +}; + +layout (binding = 0) uniform Time_1 { + float value; +} time; +layout (binding = 1) uniform Uniforms_1 { + float scale; + float offsetX; + float offsetY; + float scalar; + float scalarOffset; +} uniforms; + +struct VertexOutput { + vec4 Position; + vec4 v_color; +}; +struct tint_symbol_2 { + vec4 position; + vec4 color; +}; +struct tint_symbol_3 { + vec4 v_color; + vec4 Position; +}; + +VertexOutput vert_main_inner(vec4 position, vec4 color) { + float fade = ((uniforms.scalarOffset + ((time.value * uniforms.scalar) / 10.0f)) % 1.0f); + if ((fade < 0.5f)) { + fade = (fade * 2.0f); + } else { + fade = ((1.0f - fade) * 2.0f); + } + float xpos = (position.x * uniforms.scale); + float ypos = (position.y * uniforms.scale); + float angle = ((3.141590118f * 2.0f) * fade); + float xrot = ((xpos * cos(angle)) - (ypos * sin(angle))); + float yrot = ((xpos * sin(angle)) + (ypos * cos(angle))); + xpos = (xrot + uniforms.offsetX); + ypos = (yrot + uniforms.offsetY); + VertexOutput tint_symbol = VertexOutput(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f)); + tint_symbol.v_color = (vec4(fade, (1.0f - fade), 0.0f, 1.0f) + color); + tint_symbol.Position = vec4(xpos, ypos, 0.0f, 1.0f); + return tint_symbol; +} + +struct tint_symbol_5 { + vec4 v_color; +}; +struct tint_symbol_6 { + vec4 value; +}; + +tint_symbol_3 vert_main(tint_symbol_2 tint_symbol_1) { + VertexOutput inner_result = vert_main_inner(tint_symbol_1.position, tint_symbol_1.color); + tint_symbol_3 wrapper_result = tint_symbol_3(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.Position = inner_result.Position; + wrapper_result.v_color = inner_result.v_color; + return wrapper_result; +} +in vec4 position; +in vec4 color; +out vec4 v_color; +void main() { + tint_symbol_2 inputs; + inputs.position = position; + inputs.color = color; + tint_symbol_3 outputs; + outputs = vert_main(inputs); + v_color = outputs.v_color; + gl_Position = outputs.Position; + gl_Position.y = -gl_Position.y; +} + + +Error parsing GLSL shader: +ERROR: 0:40: '%' : wrong operand types: no operation '%' exists that takes a left-hand operand of type ' temp mediump float' and a right operand of type ' const float' (or there is no acceptable conversion) +ERROR: 0:40: '' : compilation terminated +ERROR: 2 compilation errors. No code generated. + + + +#version 310 es +precision mediump float; + +struct Time { + float value; +}; +struct Uniforms { + float scale; + float offsetX; + float offsetY; + float scalar; + float scalarOffset; +}; +struct VertexOutput { + vec4 Position; + vec4 v_color; +}; +struct tint_symbol_2 { + vec4 position; + vec4 color; +}; +struct tint_symbol_3 { + vec4 v_color; + vec4 Position; +}; +struct tint_symbol_5 { + vec4 v_color; +}; +struct tint_symbol_6 { + vec4 value; +}; + +vec4 frag_main_inner(vec4 v_color) { + return v_color; +} + +tint_symbol_6 frag_main(tint_symbol_5 tint_symbol_4) { + vec4 inner_result_1 = frag_main_inner(tint_symbol_4.v_color); + tint_symbol_6 wrapper_result_1 = tint_symbol_6(vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result_1.value = inner_result_1; + return wrapper_result_1; +} +in vec4 v_color; +out vec4 value; +void main() { + tint_symbol_5 inputs; + inputs.v_color = v_color; + tint_symbol_6 outputs; + outputs = frag_main(inputs); + value = outputs.value; +} + + diff --git a/test/benchmark/animometer.wgsl.expected.hlsl b/test/benchmark/animometer.wgsl.expected.hlsl new file mode 100644 index 0000000000..1e37c1e08d --- /dev/null +++ b/test/benchmark/animometer.wgsl.expected.hlsl @@ -0,0 +1,65 @@ +cbuffer cbuffer_time : register(b0, space0) { + uint4 time[1]; +}; +cbuffer cbuffer_uniforms : register(b1, space0) { + uint4 uniforms[2]; +}; + +struct VertexOutput { + float4 Position; + float4 v_color; +}; +struct tint_symbol_1 { + float4 position : TEXCOORD0; + float4 color : TEXCOORD1; +}; +struct tint_symbol_2 { + float4 v_color : TEXCOORD0; + float4 Position : SV_Position; +}; + +VertexOutput vert_main_inner(float4 position, float4 color) { + float fade = ((asfloat(uniforms[1].x) + ((asfloat(time[0].x) * asfloat(uniforms[0].w)) / 10.0f)) % 1.0f); + if ((fade < 0.5f)) { + fade = (fade * 2.0f); + } else { + fade = ((1.0f - fade) * 2.0f); + } + float xpos = (position.x * asfloat(uniforms[0].x)); + float ypos = (position.y * asfloat(uniforms[0].x)); + float angle = ((3.141590118f * 2.0f) * fade); + float xrot = ((xpos * cos(angle)) - (ypos * sin(angle))); + float yrot = ((xpos * sin(angle)) + (ypos * cos(angle))); + xpos = (xrot + asfloat(uniforms[0].y)); + ypos = (yrot + asfloat(uniforms[0].z)); + VertexOutput output = (VertexOutput)0; + output.v_color = (float4(fade, (1.0f - fade), 0.0f, 1.0f) + color); + output.Position = float4(xpos, ypos, 0.0f, 1.0f); + return output; +} + +tint_symbol_2 vert_main(tint_symbol_1 tint_symbol) { + const VertexOutput inner_result = vert_main_inner(tint_symbol.position, tint_symbol.color); + tint_symbol_2 wrapper_result = (tint_symbol_2)0; + wrapper_result.Position = inner_result.Position; + wrapper_result.v_color = inner_result.v_color; + return wrapper_result; +} + +struct tint_symbol_4 { + float4 v_color : TEXCOORD0; +}; +struct tint_symbol_5 { + float4 value : SV_Target0; +}; + +float4 frag_main_inner(float4 v_color) { + return v_color; +} + +tint_symbol_5 frag_main(tint_symbol_4 tint_symbol_3) { + const float4 inner_result_1 = frag_main_inner(tint_symbol_3.v_color); + tint_symbol_5 wrapper_result_1 = (tint_symbol_5)0; + wrapper_result_1.value = inner_result_1; + return wrapper_result_1; +} diff --git a/test/benchmark/animometer.wgsl.expected.msl b/test/benchmark/animometer.wgsl.expected.msl new file mode 100644 index 0000000000..f970428dd1 --- /dev/null +++ b/test/benchmark/animometer.wgsl.expected.msl @@ -0,0 +1,71 @@ +#include + +using namespace metal; +struct Time { + /* 0x0000 */ float value; +}; +struct Uniforms { + /* 0x0000 */ float scale; + /* 0x0004 */ float offsetX; + /* 0x0008 */ float offsetY; + /* 0x000c */ float scalar; + /* 0x0010 */ float scalarOffset; +}; +struct VertexOutput { + float4 Position; + float4 v_color; +}; +struct tint_symbol_1 { + float4 position [[attribute(0)]]; + float4 color [[attribute(1)]]; +}; +struct tint_symbol_2 { + float4 v_color [[user(locn0)]]; + float4 Position [[position]]; +}; +struct tint_symbol_4 { + float4 v_color [[user(locn0)]]; +}; +struct tint_symbol_5 { + float4 value [[color(0)]]; +}; + +VertexOutput vert_main_inner(float4 position, float4 color, const constant Uniforms* const tint_symbol_6, const constant Time* const tint_symbol_7) { + float fade = fmod(((*(tint_symbol_6)).scalarOffset + (((*(tint_symbol_7)).value * (*(tint_symbol_6)).scalar) / 10.0f)), 1.0f); + if ((fade < 0.5f)) { + fade = (fade * 2.0f); + } else { + fade = ((1.0f - fade) * 2.0f); + } + float xpos = (position[0] * (*(tint_symbol_6)).scale); + float ypos = (position[1] * (*(tint_symbol_6)).scale); + float angle = ((3.141590118f * 2.0f) * fade); + float xrot = ((xpos * cos(angle)) - (ypos * sin(angle))); + float yrot = ((xpos * sin(angle)) + (ypos * cos(angle))); + xpos = (xrot + (*(tint_symbol_6)).offsetX); + ypos = (yrot + (*(tint_symbol_6)).offsetY); + VertexOutput output = {}; + output.v_color = (float4(fade, (1.0f - fade), 0.0f, 1.0f) + color); + output.Position = float4(xpos, ypos, 0.0f, 1.0f); + return output; +} + +vertex tint_symbol_2 vert_main(const constant Uniforms* tint_symbol_8 [[buffer(0)]], const constant Time* tint_symbol_9 [[buffer(1)]], tint_symbol_1 tint_symbol [[stage_in]]) { + VertexOutput const inner_result = vert_main_inner(tint_symbol.position, tint_symbol.color, tint_symbol_8, tint_symbol_9); + tint_symbol_2 wrapper_result = {}; + wrapper_result.Position = inner_result.Position; + wrapper_result.v_color = inner_result.v_color; + return wrapper_result; +} + +float4 frag_main_inner(float4 v_color) { + return v_color; +} + +fragment tint_symbol_5 frag_main(tint_symbol_4 tint_symbol_3 [[stage_in]]) { + float4 const inner_result_1 = frag_main_inner(tint_symbol_3.v_color); + tint_symbol_5 wrapper_result_1 = {}; + wrapper_result_1.value = inner_result_1; + return wrapper_result_1; +} + diff --git a/test/benchmark/animometer.wgsl.expected.spvasm b/test/benchmark/animometer.wgsl.expected.spvasm new file mode 100644 index 0000000000..305ea643a3 --- /dev/null +++ b/test/benchmark/animometer.wgsl.expected.spvasm @@ -0,0 +1,232 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 138 +; Schema: 0 + OpCapability Shader + %76 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %vert_main "vert_main" %position_1 %color_1 %Position_1 %v_color_1 %vertex_point_size + OpEntryPoint Fragment %frag_main "frag_main" %v_color_2 %value_1 + OpExecutionMode %frag_main OriginUpperLeft + OpName %position_1 "position_1" + OpName %color_1 "color_1" + OpName %Position_1 "Position_1" + OpName %v_color_1 "v_color_1" + OpName %vertex_point_size "vertex_point_size" + OpName %v_color_2 "v_color_2" + OpName %value_1 "value_1" + OpName %Time "Time" + OpMemberName %Time 0 "value" + OpName %time "time" + OpName %Uniforms "Uniforms" + OpMemberName %Uniforms 0 "scale" + OpMemberName %Uniforms 1 "offsetX" + OpMemberName %Uniforms 2 "offsetY" + OpMemberName %Uniforms 3 "scalar" + OpMemberName %Uniforms 4 "scalarOffset" + OpName %uniforms "uniforms" + OpName %VertexOutput "VertexOutput" + OpMemberName %VertexOutput 0 "Position" + OpMemberName %VertexOutput 1 "v_color" + OpName %vert_main_inner "vert_main_inner" + OpName %position "position" + OpName %color "color" + OpName %fade "fade" + OpName %xpos "xpos" + OpName %ypos "ypos" + OpName %angle "angle" + OpName %xrot "xrot" + OpName %yrot "yrot" + OpName %output "output" + OpName %vert_main "vert_main" + OpName %frag_main_inner "frag_main_inner" + OpName %v_color "v_color" + OpName %frag_main "frag_main" + OpDecorate %position_1 Location 0 + OpDecorate %color_1 Location 1 + OpDecorate %Position_1 BuiltIn Position + OpDecorate %v_color_1 Location 0 + OpDecorate %vertex_point_size BuiltIn PointSize + OpDecorate %v_color_2 Location 0 + OpDecorate %value_1 Location 0 + OpDecorate %Time Block + OpMemberDecorate %Time 0 Offset 0 + OpDecorate %time NonWritable + OpDecorate %time Binding 0 + OpDecorate %time DescriptorSet 0 + OpDecorate %Uniforms Block + OpMemberDecorate %Uniforms 0 Offset 0 + OpMemberDecorate %Uniforms 1 Offset 4 + OpMemberDecorate %Uniforms 2 Offset 8 + OpMemberDecorate %Uniforms 3 Offset 12 + OpMemberDecorate %Uniforms 4 Offset 16 + OpDecorate %uniforms NonWritable + OpDecorate %uniforms Binding 1 + OpDecorate %uniforms DescriptorSet 0 + OpMemberDecorate %VertexOutput 0 Offset 0 + OpMemberDecorate %VertexOutput 1 Offset 16 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %position_1 = OpVariable %_ptr_Input_v4float Input + %color_1 = OpVariable %_ptr_Input_v4float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float + %8 = OpConstantNull %v4float + %Position_1 = OpVariable %_ptr_Output_v4float Output %8 + %v_color_1 = OpVariable %_ptr_Output_v4float Output %8 +%_ptr_Output_float = OpTypePointer Output %float + %12 = OpConstantNull %float +%vertex_point_size = OpVariable %_ptr_Output_float Output %12 + %v_color_2 = OpVariable %_ptr_Input_v4float Input + %value_1 = OpVariable %_ptr_Output_v4float Output %8 + %Time = OpTypeStruct %float +%_ptr_Uniform_Time = OpTypePointer Uniform %Time + %time = OpVariable %_ptr_Uniform_Time Uniform + %Uniforms = OpTypeStruct %float %float %float %float %float +%_ptr_Uniform_Uniforms = OpTypePointer Uniform %Uniforms + %uniforms = OpVariable %_ptr_Uniform_Uniforms Uniform +%VertexOutput = OpTypeStruct %v4float %v4float + %21 = OpTypeFunction %VertexOutput %v4float %v4float + %uint = OpTypeInt 32 0 + %uint_4 = OpConstant %uint 4 +%_ptr_Uniform_float = OpTypePointer Uniform %float + %uint_0 = OpConstant %uint 0 + %uint_3 = OpConstant %uint 3 + %float_10 = OpConstant %float 10 + %float_1 = OpConstant %float 1 +%_ptr_Function_float = OpTypePointer Function %float + %float_0_5 = OpConstant %float 0.5 + %bool = OpTypeBool + %float_2 = OpConstant %float 2 +%float_3_14159012 = OpConstant %float 3.14159012 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput + %107 = OpConstantNull %VertexOutput +%_ptr_Function_v4float = OpTypePointer Function %v4float + %float_0 = OpConstant %float 0 + %void = OpTypeVoid + %121 = OpTypeFunction %void + %130 = OpTypeFunction %v4float %v4float +%vert_main_inner = OpFunction %VertexOutput None %21 + %position = OpFunctionParameter %v4float + %color = OpFunctionParameter %v4float + %26 = OpLabel + %fade = OpVariable %_ptr_Function_float Function %12 + %xpos = OpVariable %_ptr_Function_float Function %12 + %ypos = OpVariable %_ptr_Function_float Function %12 + %angle = OpVariable %_ptr_Function_float Function %12 + %xrot = OpVariable %_ptr_Function_float Function %12 + %yrot = OpVariable %_ptr_Function_float Function %12 + %output = OpVariable %_ptr_Function_VertexOutput Function %107 + %30 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_4 + %31 = OpLoad %float %30 + %33 = OpAccessChain %_ptr_Uniform_float %time %uint_0 + %34 = OpLoad %float %33 + %36 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_3 + %37 = OpLoad %float %36 + %38 = OpFMul %float %34 %37 + %40 = OpFDiv %float %38 %float_10 + %41 = OpFAdd %float %31 %40 + %43 = OpFRem %float %41 %float_1 + OpStore %fade %43 + %46 = OpLoad %float %fade + %48 = OpFOrdLessThan %bool %46 %float_0_5 + OpSelectionMerge %50 None + OpBranchConditional %48 %51 %52 + %51 = OpLabel + %53 = OpLoad %float %fade + %55 = OpFMul %float %53 %float_2 + OpStore %fade %55 + OpBranch %50 + %52 = OpLabel + %56 = OpLoad %float %fade + %57 = OpFSub %float %float_1 %56 + %58 = OpFMul %float %57 %float_2 + OpStore %fade %58 + OpBranch %50 + %50 = OpLabel + %59 = OpCompositeExtract %float %position 0 + %60 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 + %61 = OpLoad %float %60 + %62 = OpFMul %float %59 %61 + OpStore %xpos %62 + %64 = OpCompositeExtract %float %position 1 + %65 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 + %66 = OpLoad %float %65 + %67 = OpFMul %float %64 %66 + OpStore %ypos %67 + %70 = OpFMul %float %float_3_14159012 %float_2 + %71 = OpLoad %float %fade + %72 = OpFMul %float %70 %71 + OpStore %angle %72 + %74 = OpLoad %float %xpos + %77 = OpLoad %float %angle + %75 = OpExtInst %float %76 Cos %77 + %78 = OpFMul %float %74 %75 + %79 = OpLoad %float %ypos + %81 = OpLoad %float %angle + %80 = OpExtInst %float %76 Sin %81 + %82 = OpFMul %float %79 %80 + %83 = OpFSub %float %78 %82 + OpStore %xrot %83 + %85 = OpLoad %float %xpos + %87 = OpLoad %float %angle + %86 = OpExtInst %float %76 Sin %87 + %88 = OpFMul %float %85 %86 + %89 = OpLoad %float %ypos + %91 = OpLoad %float %angle + %90 = OpExtInst %float %76 Cos %91 + %92 = OpFMul %float %89 %90 + %93 = OpFAdd %float %88 %92 + OpStore %yrot %93 + %95 = OpLoad %float %xrot + %97 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_1 + %98 = OpLoad %float %97 + %99 = OpFAdd %float %95 %98 + OpStore %xpos %99 + %100 = OpLoad %float %yrot + %102 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_2 + %103 = OpLoad %float %102 + %104 = OpFAdd %float %100 %103 + OpStore %ypos %104 + %109 = OpAccessChain %_ptr_Function_v4float %output %uint_1 + %110 = OpLoad %float %fade + %111 = OpLoad %float %fade + %112 = OpFSub %float %float_1 %111 + %114 = OpCompositeConstruct %v4float %110 %112 %float_0 %float_1 + %115 = OpFAdd %v4float %114 %color + OpStore %109 %115 + %116 = OpAccessChain %_ptr_Function_v4float %output %uint_0 + %117 = OpLoad %float %xpos + %118 = OpLoad %float %ypos + %119 = OpCompositeConstruct %v4float %117 %118 %float_0 %float_1 + OpStore %116 %119 + %120 = OpLoad %VertexOutput %output + OpReturnValue %120 + OpFunctionEnd + %vert_main = OpFunction %void None %121 + %124 = OpLabel + %126 = OpLoad %v4float %position_1 + %127 = OpLoad %v4float %color_1 + %125 = OpFunctionCall %VertexOutput %vert_main_inner %126 %127 + %128 = OpCompositeExtract %v4float %125 0 + OpStore %Position_1 %128 + %129 = OpCompositeExtract %v4float %125 1 + OpStore %v_color_1 %129 + OpStore %vertex_point_size %float_1 + OpReturn + OpFunctionEnd +%frag_main_inner = OpFunction %v4float None %130 + %v_color = OpFunctionParameter %v4float + %133 = OpLabel + OpReturnValue %v_color + OpFunctionEnd + %frag_main = OpFunction %void None %121 + %135 = OpLabel + %137 = OpLoad %v4float %v_color_2 + %136 = OpFunctionCall %v4float %frag_main_inner %137 + OpStore %value_1 %136 + OpReturn + OpFunctionEnd diff --git a/test/benchmark/animometer.wgsl.expected.wgsl b/test/benchmark/animometer.wgsl.expected.wgsl new file mode 100644 index 0000000000..b850d14602 --- /dev/null +++ b/test/benchmark/animometer.wgsl.expected.wgsl @@ -0,0 +1,48 @@ +struct Time { + value : f32; +} + +struct Uniforms { + scale : f32; + offsetX : f32; + offsetY : f32; + scalar : f32; + scalarOffset : f32; +} + +@binding(0) @group(0) var time : Time; + +@binding(1) @group(0) var uniforms : Uniforms; + +struct VertexOutput { + @builtin(position) + Position : vec4; + @location(0) + v_color : vec4; +} + +@stage(vertex) +fn vert_main(@location(0) position : vec4, @location(1) color : vec4) -> VertexOutput { + var fade : f32 = ((uniforms.scalarOffset + ((time.value * uniforms.scalar) / 10.0)) % 1.0); + if ((fade < 0.5)) { + fade = (fade * 2.0); + } else { + fade = ((1.0 - fade) * 2.0); + } + var xpos : f32 = (position.x * uniforms.scale); + var ypos : f32 = (position.y * uniforms.scale); + var angle : f32 = ((3.141590118 * 2.0) * fade); + var xrot : f32 = ((xpos * cos(angle)) - (ypos * sin(angle))); + var yrot : f32 = ((xpos * sin(angle)) + (ypos * cos(angle))); + xpos = (xrot + uniforms.offsetX); + ypos = (yrot + uniforms.offsetY); + var output : VertexOutput; + output.v_color = (vec4(fade, (1.0 - fade), 0.0, 1.0) + color); + output.Position = vec4(xpos, ypos, 0.0, 1.0); + return output; +} + +@stage(fragment) +fn frag_main(@location(0) v_color : vec4) -> @location(0) vec4 { + return v_color; +} diff --git a/test/benchmark/bloom-vertical-blur.wgsl b/test/benchmark/bloom-vertical-blur.wgsl new file mode 100644 index 0000000000..6425a83186 --- /dev/null +++ b/test/benchmark/bloom-vertical-blur.wgsl @@ -0,0 +1,42 @@ +let bloomDir = vec2(0.0, 1.0); + +var offsets : array = array(0.0, 1.384615421, 3.230769157); + +var weights : array = array(0.227027029, 0.31621623, 0.07027027); + +struct BloomUniforms { + radius : f32; + dim : f32; +} + +@group(0) @binding(0) var bloom : BloomUniforms; + +@group(0) @binding(1) var bloomTexture : texture_2d; + +@group(0) @binding(2) var bloomSampler : sampler; + +struct FragmentInput { + @location(0) + texCoord : vec2; +} + +fn getGaussianBlur(texCoord : vec2) -> vec4 { + let texelRadius = (vec2(bloom.radius) / vec2(textureDimensions(bloomTexture))); + let step = (bloomDir * texelRadius); + var sum = vec4(0.0); + sum = (sum + (textureSample(bloomTexture, bloomSampler, texCoord) * weights[0])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord + (step * 1.0))) * weights[1])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord - (step * 1.0))) * weights[1])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord + (step * 2.0))) * weights[2])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord - (step * 2.0))) * weights[2])); + return vec4(sum.rgb, 1.0); +} + +@group(0) @binding(3) var prevTexture : texture_2d; + +@stage(fragment) +fn fragmentMain(input : FragmentInput) -> @location(0) vec4 { + let blurColor = getGaussianBlur(input.texCoord); + let dimColor = (textureSample(prevTexture, bloomSampler, input.texCoord) * bloom.dim); + return (blurColor + dimColor); +} diff --git a/test/benchmark/bloom-vertical-blur.wgsl.expected.glsl b/test/benchmark/bloom-vertical-blur.wgsl.expected.glsl new file mode 100644 index 0000000000..0ed2c1bd7c --- /dev/null +++ b/test/benchmark/bloom-vertical-blur.wgsl.expected.glsl @@ -0,0 +1,67 @@ +#version 310 es +precision mediump float; + +const vec2 bloomDir = vec2(0.0f, 1.0f); +float weights[3] = float[3](0.227027029f, 0.31621623f, 0.07027027f); + +struct BloomUniforms { + float radius; + float dim; +}; + +layout (binding = 0) uniform BloomUniforms_1 { + float radius; + float dim; +} bloom; +uniform highp sampler2D bloomTexture; + + +struct FragmentInput { + vec2 texCoord; +}; + +vec4 getGaussianBlur(vec2 texCoord) { + vec2 texelRadius = (vec2(bloom.radius) / vec2(textureSize(bloomTexture, 0))); + vec2 tint_symbol = (bloomDir * texelRadius); + vec4 sum = vec4(0.0f); + sum = (sum + (texture(bloomTexture, texCoord) * weights[0])); + sum = (sum + (texture(bloomTexture, (texCoord + (tint_symbol * 1.0f))) * weights[1])); + sum = (sum + (texture(bloomTexture, (texCoord - (tint_symbol * 1.0f))) * weights[1])); + sum = (sum + (texture(bloomTexture, (texCoord + (tint_symbol * 2.0f))) * weights[2])); + sum = (sum + (texture(bloomTexture, (texCoord - (tint_symbol * 2.0f))) * weights[2])); + return vec4(sum.rgb, 1.0f); +} + +uniform highp sampler2D prevTexture; + +struct tint_symbol_3 { + vec2 texCoord; +}; +struct tint_symbol_4 { + vec4 value; +}; + +vec4 fragmentMain_inner(FragmentInput tint_symbol_1) { + vec4 blurColor = getGaussianBlur(tint_symbol_1.texCoord); + vec4 dimColor = (texture(prevTexture, tint_symbol_1.texCoord) * bloom.dim); + return (blurColor + dimColor); +} + +tint_symbol_4 fragmentMain(tint_symbol_3 tint_symbol_2) { + FragmentInput tint_symbol_5 = FragmentInput(tint_symbol_2.texCoord); + vec4 inner_result = fragmentMain_inner(tint_symbol_5); + tint_symbol_4 wrapper_result = tint_symbol_4(vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.value = inner_result; + return wrapper_result; +} +in vec2 texCoord; +out vec4 value; +void main() { + tint_symbol_3 inputs; + inputs.texCoord = texCoord; + tint_symbol_4 outputs; + outputs = fragmentMain(inputs); + value = outputs.value; +} + + diff --git a/test/benchmark/bloom-vertical-blur.wgsl.expected.hlsl b/test/benchmark/bloom-vertical-blur.wgsl.expected.hlsl new file mode 100644 index 0000000000..cde80727db --- /dev/null +++ b/test/benchmark/bloom-vertical-blur.wgsl.expected.hlsl @@ -0,0 +1,50 @@ +static const float2 bloomDir = float2(0.0f, 1.0f); +static float offsets[3] = {0.0f, 1.384615421f, 3.230769157f}; +static float weights[3] = {0.227027029f, 0.31621623f, 0.07027027f}; + +cbuffer cbuffer_bloom : register(b0, space0) { + uint4 bloom[1]; +}; +Texture2D bloomTexture : register(t1, space0); +SamplerState bloomSampler : register(s2, space0); + +struct FragmentInput { + float2 texCoord; +}; + +float4 getGaussianBlur(float2 texCoord) { + int2 tint_tmp; + bloomTexture.GetDimensions(tint_tmp.x, tint_tmp.y); + const float2 texelRadius = (float2((asfloat(bloom[0].x)).xx) / float2(tint_tmp)); + const float2 step = (bloomDir * texelRadius); + float4 sum = float4((0.0f).xxxx); + sum = (sum + (bloomTexture.Sample(bloomSampler, texCoord) * weights[0])); + sum = (sum + (bloomTexture.Sample(bloomSampler, (texCoord + (step * 1.0f))) * weights[1])); + sum = (sum + (bloomTexture.Sample(bloomSampler, (texCoord - (step * 1.0f))) * weights[1])); + sum = (sum + (bloomTexture.Sample(bloomSampler, (texCoord + (step * 2.0f))) * weights[2])); + sum = (sum + (bloomTexture.Sample(bloomSampler, (texCoord - (step * 2.0f))) * weights[2])); + return float4(sum.rgb, 1.0f); +} + +Texture2D prevTexture : register(t3, space0); + +struct tint_symbol_1 { + float2 texCoord : TEXCOORD0; +}; +struct tint_symbol_2 { + float4 value : SV_Target0; +}; + +float4 fragmentMain_inner(FragmentInput input) { + const float4 blurColor = getGaussianBlur(input.texCoord); + const float4 dimColor = (prevTexture.Sample(bloomSampler, input.texCoord) * asfloat(bloom[0].y)); + return (blurColor + dimColor); +} + +tint_symbol_2 fragmentMain(tint_symbol_1 tint_symbol) { + const FragmentInput tint_symbol_4 = {tint_symbol.texCoord}; + const float4 inner_result = fragmentMain_inner(tint_symbol_4); + tint_symbol_2 wrapper_result = (tint_symbol_2)0; + wrapper_result.value = inner_result; + return wrapper_result; +} diff --git a/test/benchmark/bloom-vertical-blur.wgsl.expected.msl b/test/benchmark/bloom-vertical-blur.wgsl.expected.msl new file mode 100644 index 0000000000..74f258c968 --- /dev/null +++ b/test/benchmark/bloom-vertical-blur.wgsl.expected.msl @@ -0,0 +1,48 @@ +#include + +using namespace metal; +struct tint_array_wrapper { + float arr[3]; +}; +struct BloomUniforms { + /* 0x0000 */ float radius; + /* 0x0004 */ float dim; +}; +struct FragmentInput { + float2 texCoord; +}; +struct tint_symbol_1 { + float2 texCoord [[user(locn0)]]; +}; +struct tint_symbol_2 { + float4 value [[color(0)]]; +}; + +constant float2 bloomDir = float2(0.0f, 1.0f); +float4 getGaussianBlur(float2 texCoord, const constant BloomUniforms* const tint_symbol_4, texture2d tint_symbol_5, sampler tint_symbol_6, thread tint_array_wrapper* const tint_symbol_7) { + float2 const texelRadius = (float2((*(tint_symbol_4)).radius) / float2(int2(tint_symbol_5.get_width(), tint_symbol_5.get_height()))); + float2 const step = (bloomDir * texelRadius); + float4 sum = float4(0.0f); + sum = (sum + (tint_symbol_5.sample(tint_symbol_6, texCoord) * (*(tint_symbol_7)).arr[0])); + sum = (sum + (tint_symbol_5.sample(tint_symbol_6, (texCoord + (step * 1.0f))) * (*(tint_symbol_7)).arr[1])); + sum = (sum + (tint_symbol_5.sample(tint_symbol_6, (texCoord - (step * 1.0f))) * (*(tint_symbol_7)).arr[1])); + sum = (sum + (tint_symbol_5.sample(tint_symbol_6, (texCoord + (step * 2.0f))) * (*(tint_symbol_7)).arr[2])); + sum = (sum + (tint_symbol_5.sample(tint_symbol_6, (texCoord - (step * 2.0f))) * (*(tint_symbol_7)).arr[2])); + return float4(float4(sum).rgb, 1.0f); +} + +float4 fragmentMain_inner(FragmentInput input, const constant BloomUniforms* const tint_symbol_8, texture2d tint_symbol_9, sampler tint_symbol_10, thread tint_array_wrapper* const tint_symbol_11, texture2d tint_symbol_12) { + float4 const blurColor = getGaussianBlur(input.texCoord, tint_symbol_8, tint_symbol_9, tint_symbol_10, tint_symbol_11); + float4 const dimColor = (tint_symbol_12.sample(tint_symbol_10, input.texCoord) * (*(tint_symbol_8)).dim); + return (blurColor + dimColor); +} + +fragment tint_symbol_2 fragmentMain(const constant BloomUniforms* tint_symbol_13 [[buffer(0)]], texture2d tint_symbol_14 [[texture(0)]], sampler tint_symbol_15 [[sampler(0)]], texture2d tint_symbol_17 [[texture(1)]], tint_symbol_1 tint_symbol [[stage_in]]) { + thread tint_array_wrapper tint_symbol_16 = {.arr={0.227027029f, 0.31621623f, 0.07027027f}}; + FragmentInput const tint_symbol_3 = {.texCoord=tint_symbol.texCoord}; + float4 const inner_result = fragmentMain_inner(tint_symbol_3, tint_symbol_13, tint_symbol_14, tint_symbol_15, &(tint_symbol_16), tint_symbol_17); + tint_symbol_2 wrapper_result = {}; + wrapper_result.value = inner_result; + return wrapper_result; +} + diff --git a/test/benchmark/bloom-vertical-blur.wgsl.expected.spvasm b/test/benchmark/bloom-vertical-blur.wgsl.expected.spvasm new file mode 100644 index 0000000000..41995a4394 --- /dev/null +++ b/test/benchmark/bloom-vertical-blur.wgsl.expected.spvasm @@ -0,0 +1,202 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 144 +; Schema: 0 + OpCapability Shader + OpCapability ImageQuery + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %fragmentMain "fragmentMain" %texCoord_1 %value + OpExecutionMode %fragmentMain OriginUpperLeft + OpName %texCoord_1 "texCoord_1" + OpName %value "value" + OpName %bloomDir "bloomDir" + OpName %offsets "offsets" + OpName %weights "weights" + OpName %BloomUniforms "BloomUniforms" + OpMemberName %BloomUniforms 0 "radius" + OpMemberName %BloomUniforms 1 "dim" + OpName %bloom "bloom" + OpName %bloomTexture "bloomTexture" + OpName %bloomSampler "bloomSampler" + OpName %prevTexture "prevTexture" + OpName %getGaussianBlur "getGaussianBlur" + OpName %texCoord "texCoord" + OpName %sum "sum" + OpName %FragmentInput "FragmentInput" + OpMemberName %FragmentInput 0 "texCoord" + OpName %fragmentMain_inner "fragmentMain_inner" + OpName %input "input" + OpName %fragmentMain "fragmentMain" + OpDecorate %texCoord_1 Location 0 + OpDecorate %value Location 0 + OpDecorate %_arr_float_uint_3 ArrayStride 4 + OpDecorate %BloomUniforms Block + OpMemberDecorate %BloomUniforms 0 Offset 0 + OpMemberDecorate %BloomUniforms 1 Offset 4 + OpDecorate %bloom NonWritable + OpDecorate %bloom DescriptorSet 0 + OpDecorate %bloom Binding 0 + OpDecorate %bloomTexture DescriptorSet 0 + OpDecorate %bloomTexture Binding 1 + OpDecorate %bloomSampler DescriptorSet 0 + OpDecorate %bloomSampler Binding 2 + OpDecorate %prevTexture DescriptorSet 0 + OpDecorate %prevTexture Binding 3 + OpMemberDecorate %FragmentInput 0 Offset 0 + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %texCoord_1 = OpVariable %_ptr_Input_v2float Input + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %8 = OpConstantNull %v4float + %value = OpVariable %_ptr_Output_v4float Output %8 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %bloomDir = OpConstantComposite %v2float %float_0 %float_1 + %uint = OpTypeInt 32 0 + %uint_3 = OpConstant %uint 3 +%_arr_float_uint_3 = OpTypeArray %float %uint_3 +%float_1_38461542 = OpConstant %float 1.38461542 +%float_3_23076916 = OpConstant %float 3.23076916 + %17 = OpConstantComposite %_arr_float_uint_3 %float_0 %float_1_38461542 %float_3_23076916 +%_ptr_Private__arr_float_uint_3 = OpTypePointer Private %_arr_float_uint_3 + %offsets = OpVariable %_ptr_Private__arr_float_uint_3 Private %17 +%float_0_227027029 = OpConstant %float 0.227027029 +%float_0_31621623 = OpConstant %float 0.31621623 +%float_0_0702702701 = OpConstant %float 0.0702702701 + %23 = OpConstantComposite %_arr_float_uint_3 %float_0_227027029 %float_0_31621623 %float_0_0702702701 + %weights = OpVariable %_ptr_Private__arr_float_uint_3 Private %23 +%BloomUniforms = OpTypeStruct %float %float +%_ptr_Uniform_BloomUniforms = OpTypePointer Uniform %BloomUniforms + %bloom = OpVariable %_ptr_Uniform_BloomUniforms Uniform + %30 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_30 = OpTypePointer UniformConstant %30 +%bloomTexture = OpVariable %_ptr_UniformConstant_30 UniformConstant + %33 = OpTypeSampler +%_ptr_UniformConstant_33 = OpTypePointer UniformConstant %33 +%bloomSampler = OpVariable %_ptr_UniformConstant_33 UniformConstant +%prevTexture = OpVariable %_ptr_UniformConstant_30 UniformConstant + %35 = OpTypeFunction %v4float %v2float + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_float = OpTypePointer Uniform %float + %int = OpTypeInt 32 1 + %v2int = OpTypeVector %int 2 + %int_0 = OpConstant %int 0 + %52 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 +%_ptr_Function_v4float = OpTypePointer Function %v4float + %59 = OpTypeSampledImage %30 +%_ptr_Private_float = OpTypePointer Private %float + %int_1 = OpConstant %int 1 + %float_2 = OpConstant %float 2 + %int_2 = OpConstant %int 2 + %v3float = OpTypeVector %float 3 +%FragmentInput = OpTypeStruct %v2float + %120 = OpTypeFunction %v4float %FragmentInput + %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %137 = OpTypeFunction %void +%getGaussianBlur = OpFunction %v4float None %35 + %texCoord = OpFunctionParameter %v2float + %38 = OpLabel + %sum = OpVariable %_ptr_Function_v4float Function %8 + %41 = OpAccessChain %_ptr_Uniform_float %bloom %uint_0 + %42 = OpLoad %float %41 + %43 = OpCompositeConstruct %v2float %42 %42 + %48 = OpLoad %30 %bloomTexture + %45 = OpImageQuerySizeLod %v2int %48 %int_0 + %44 = OpConvertSToF %v2float %45 + %50 = OpFDiv %v2float %43 %44 + %51 = OpFMul %v2float %bloomDir %50 + OpStore %sum %52 + %55 = OpLoad %v4float %sum + %57 = OpLoad %33 %bloomSampler + %58 = OpLoad %30 %bloomTexture + %60 = OpSampledImage %59 %58 %57 + %56 = OpImageSampleImplicitLod %v4float %60 %texCoord + %62 = OpAccessChain %_ptr_Private_float %weights %int_0 + %63 = OpLoad %float %62 + %64 = OpVectorTimesScalar %v4float %56 %63 + %65 = OpFAdd %v4float %55 %64 + OpStore %sum %65 + %66 = OpLoad %v4float %sum + %68 = OpLoad %33 %bloomSampler + %69 = OpLoad %30 %bloomTexture + %70 = OpSampledImage %59 %69 %68 + %71 = OpVectorTimesScalar %v2float %51 %float_1 + %72 = OpFAdd %v2float %texCoord %71 + %67 = OpImageSampleImplicitLod %v4float %70 %72 + %74 = OpAccessChain %_ptr_Private_float %weights %int_1 + %75 = OpLoad %float %74 + %76 = OpVectorTimesScalar %v4float %67 %75 + %77 = OpFAdd %v4float %66 %76 + OpStore %sum %77 + %78 = OpLoad %v4float %sum + %80 = OpLoad %33 %bloomSampler + %81 = OpLoad %30 %bloomTexture + %82 = OpSampledImage %59 %81 %80 + %83 = OpVectorTimesScalar %v2float %51 %float_1 + %84 = OpFSub %v2float %texCoord %83 + %79 = OpImageSampleImplicitLod %v4float %82 %84 + %85 = OpAccessChain %_ptr_Private_float %weights %int_1 + %86 = OpLoad %float %85 + %87 = OpVectorTimesScalar %v4float %79 %86 + %88 = OpFAdd %v4float %78 %87 + OpStore %sum %88 + %89 = OpLoad %v4float %sum + %91 = OpLoad %33 %bloomSampler + %92 = OpLoad %30 %bloomTexture + %93 = OpSampledImage %59 %92 %91 + %95 = OpVectorTimesScalar %v2float %51 %float_2 + %96 = OpFAdd %v2float %texCoord %95 + %90 = OpImageSampleImplicitLod %v4float %93 %96 + %98 = OpAccessChain %_ptr_Private_float %weights %int_2 + %99 = OpLoad %float %98 + %100 = OpVectorTimesScalar %v4float %90 %99 + %101 = OpFAdd %v4float %89 %100 + OpStore %sum %101 + %102 = OpLoad %v4float %sum + %104 = OpLoad %33 %bloomSampler + %105 = OpLoad %30 %bloomTexture + %106 = OpSampledImage %59 %105 %104 + %107 = OpVectorTimesScalar %v2float %51 %float_2 + %108 = OpFSub %v2float %texCoord %107 + %103 = OpImageSampleImplicitLod %v4float %106 %108 + %109 = OpAccessChain %_ptr_Private_float %weights %int_2 + %110 = OpLoad %float %109 + %111 = OpVectorTimesScalar %v4float %103 %110 + %112 = OpFAdd %v4float %102 %111 + OpStore %sum %112 + %114 = OpLoad %v4float %sum + %115 = OpVectorShuffle %v3float %114 %114 0 1 2 + %116 = OpCompositeExtract %float %115 0 + %117 = OpCompositeExtract %float %115 1 + %118 = OpCompositeExtract %float %115 2 + %119 = OpCompositeConstruct %v4float %116 %117 %118 %float_1 + OpReturnValue %119 + OpFunctionEnd +%fragmentMain_inner = OpFunction %v4float None %120 + %input = OpFunctionParameter %FragmentInput + %124 = OpLabel + %126 = OpCompositeExtract %v2float %input 0 + %125 = OpFunctionCall %v4float %getGaussianBlur %126 + %128 = OpLoad %33 %bloomSampler + %129 = OpLoad %30 %prevTexture + %130 = OpSampledImage %59 %129 %128 + %131 = OpCompositeExtract %v2float %input 0 + %127 = OpImageSampleImplicitLod %v4float %130 %131 + %133 = OpAccessChain %_ptr_Uniform_float %bloom %uint_1 + %134 = OpLoad %float %133 + %135 = OpVectorTimesScalar %v4float %127 %134 + %136 = OpFAdd %v4float %125 %135 + OpReturnValue %136 + OpFunctionEnd +%fragmentMain = OpFunction %void None %137 + %140 = OpLabel + %142 = OpLoad %v2float %texCoord_1 + %143 = OpCompositeConstruct %FragmentInput %142 + %141 = OpFunctionCall %v4float %fragmentMain_inner %143 + OpStore %value %141 + OpReturn + OpFunctionEnd diff --git a/test/benchmark/bloom-vertical-blur.wgsl.expected.wgsl b/test/benchmark/bloom-vertical-blur.wgsl.expected.wgsl new file mode 100644 index 0000000000..6425a83186 --- /dev/null +++ b/test/benchmark/bloom-vertical-blur.wgsl.expected.wgsl @@ -0,0 +1,42 @@ +let bloomDir = vec2(0.0, 1.0); + +var offsets : array = array(0.0, 1.384615421, 3.230769157); + +var weights : array = array(0.227027029, 0.31621623, 0.07027027); + +struct BloomUniforms { + radius : f32; + dim : f32; +} + +@group(0) @binding(0) var bloom : BloomUniforms; + +@group(0) @binding(1) var bloomTexture : texture_2d; + +@group(0) @binding(2) var bloomSampler : sampler; + +struct FragmentInput { + @location(0) + texCoord : vec2; +} + +fn getGaussianBlur(texCoord : vec2) -> vec4 { + let texelRadius = (vec2(bloom.radius) / vec2(textureDimensions(bloomTexture))); + let step = (bloomDir * texelRadius); + var sum = vec4(0.0); + sum = (sum + (textureSample(bloomTexture, bloomSampler, texCoord) * weights[0])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord + (step * 1.0))) * weights[1])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord - (step * 1.0))) * weights[1])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord + (step * 2.0))) * weights[2])); + sum = (sum + (textureSample(bloomTexture, bloomSampler, (texCoord - (step * 2.0))) * weights[2])); + return vec4(sum.rgb, 1.0); +} + +@group(0) @binding(3) var prevTexture : texture_2d; + +@stage(fragment) +fn fragmentMain(input : FragmentInput) -> @location(0) vec4 { + let blurColor = getGaussianBlur(input.texCoord); + let dimColor = (textureSample(prevTexture, bloomSampler, input.texCoord) * bloom.dim); + return (blurColor + dimColor); +} diff --git a/test/benchmark/cluster-lights.wgsl b/test/benchmark/cluster-lights.wgsl new file mode 100644 index 0000000000..00d4ee6b48 --- /dev/null +++ b/test/benchmark/cluster-lights.wgsl @@ -0,0 +1,119 @@ +struct Camera { + projection : mat4x4; + inverseProjection : mat4x4; + view : mat4x4; + position : vec3; + time : f32; + outputSize : vec2; + zNear : f32; + zFar : f32; +} + +@group(0) @binding(0) var camera : Camera; + +struct ClusterBounds { + minAABB : vec3; + maxAABB : vec3; +} + +struct Clusters { + bounds : array; +} + +@group(0) @binding(1) var clusters : Clusters; + +struct ClusterLights { + offset : u32; + count : u32; +} + +struct ClusterLightGroup { + offset : atomic; + lights : array; + indices : array; +} + +@group(0) @binding(2) var clusterLights : ClusterLightGroup; + +struct Light { + position : vec3; + range : f32; + color : vec3; + intensity : f32; +} + +struct GlobalLights { + ambient : vec3; + dirColor : vec3; + dirIntensity : f32; + dirDirection : vec3; + lightCount : u32; + lights : array; +} + +@group(0) @binding(3) var globalLights : GlobalLights; + +let tileCount = vec3(32u, 18u, 48u); + +fn linearDepth(depthSample : f32) -> f32 { + return ((camera.zFar * camera.zNear) / fma(depthSample, (camera.zNear - camera.zFar), camera.zFar)); +} + +fn getTile(fragCoord : vec4) -> vec3 { + let sliceScale = (f32(tileCount.z) / log2((camera.zFar / camera.zNear))); + let sliceBias = -(((f32(tileCount.z) * log2(camera.zNear)) / log2((camera.zFar / camera.zNear)))); + let zTile = u32(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0)); + return vec3(u32((fragCoord.x / (camera.outputSize.x / f32(tileCount.x)))), u32((fragCoord.y / (camera.outputSize.y / f32(tileCount.y)))), zTile); +} + +fn getClusterIndex(fragCoord : vec4) -> u32 { + let tile = getTile(fragCoord); + return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y)); +} + +fn sqDistPointAABB(point : vec3, minAABB : vec3, maxAABB : vec3) -> f32 { + var sqDist = 0.0; + for(var i : i32 = 0; (i < 3); i = (i + 1)) { + let v = point[i]; + if ((v < minAABB[i])) { + sqDist = (sqDist + ((minAABB[i] - v) * (minAABB[i] - v))); + } + if ((v > maxAABB[i])) { + sqDist = (sqDist + ((v - maxAABB[i]) * (v - maxAABB[i]))); + } + } + return sqDist; +} + +@stage(compute) @workgroup_size(4, 2, 4) +fn computeMain(@builtin(global_invocation_id) global_id : vec3) { + let tileIndex = ((global_id.x + (global_id.y * tileCount.x)) + ((global_id.z * tileCount.x) * tileCount.y)); + var clusterLightCount = 0u; + var cluserLightIndices : array; + for(var i = 0u; (i < globalLights.lightCount); i = (i + 1u)) { + let range = globalLights.lights[i].range; + var lightInCluster : bool = (range <= 0.0); + if (!(lightInCluster)) { + let lightViewPos = (camera.view * vec4(globalLights.lights[i].position, 1.0)); + let sqDist = sqDistPointAABB(lightViewPos.xyz, clusters.bounds[tileIndex].minAABB, clusters.bounds[tileIndex].maxAABB); + lightInCluster = (sqDist <= (range * range)); + } + if (lightInCluster) { + cluserLightIndices[clusterLightCount] = i; + clusterLightCount = (clusterLightCount + 1u); + } + if ((clusterLightCount == 256u)) { + break; + } + } + let lightCount = clusterLightCount; + var offset = atomicAdd(&(clusterLights.offset), lightCount); + if ((offset >= 1769472u)) { + return; + } + for(var i = 0u; (i < clusterLightCount); i = (i + 1u)) { + clusterLights.indices[(offset + i)] = cluserLightIndices[i]; + } + clusterLights.lights[tileIndex].offset = offset; + clusterLights.lights[tileIndex].count = clusterLightCount; +} diff --git a/test/benchmark/cluster-lights.wgsl.expected.glsl b/test/benchmark/cluster-lights.wgsl.expected.glsl new file mode 100644 index 0000000000..4669df3892 --- /dev/null +++ b/test/benchmark/cluster-lights.wgsl.expected.glsl @@ -0,0 +1,137 @@ +#version 310 es +precision mediump float; + +struct Camera { + mat4 projection; + mat4 inverseProjection; + mat4 view; + vec3 position; + float time; + vec2 outputSize; + float zNear; + float zFar; +}; + +layout (binding = 0) uniform Camera_1 { + mat4 projection; + mat4 inverseProjection; + mat4 view; + vec3 position; + float time; + vec2 outputSize; + float zNear; + float zFar; +} camera; + +struct ClusterBounds { + vec3 minAABB; + vec3 maxAABB; +}; +struct Clusters { + ClusterBounds bounds[27648]; +}; + +layout (binding = 1) buffer Clusters_1 { + ClusterBounds bounds[27648]; +} clusters; + +struct ClusterLights { + uint offset; + uint count; +}; +struct ClusterLightGroup { + uint offset; + ClusterLights lights[27648]; + uint indices[1769472]; +}; + +layout (binding = 2) buffer ClusterLightGroup_1 { + uint offset; + ClusterLights lights[27648]; + uint indices[1769472]; +} clusterLights; + +struct Light { + vec3 position; + float range; + vec3 color; + float intensity; +}; + +layout (binding = 3) buffer GlobalLights_1 { + vec3 ambient; + vec3 dirColor; + float dirIntensity; + vec3 dirDirection; + uint lightCount; + Light lights[]; +} globalLights; +const uvec3 tileCount = uvec3(32u, 18u, 48u); + +float sqDistPointAABB(vec3 point, vec3 minAABB, vec3 maxAABB) { + float sqDist = 0.0f; + { + for(int i = 0; (i < 3); i = (i + 1)) { + float v = point[i]; + if ((v < minAABB[i])) { + sqDist = (sqDist + ((minAABB[i] - v) * (minAABB[i] - v))); + } + if ((v > maxAABB[i])) { + sqDist = (sqDist + ((v - maxAABB[i]) * (v - maxAABB[i]))); + } + } + } + return sqDist; +} + +struct tint_symbol_1 { + uvec3 global_id; +}; + +void computeMain_inner(uvec3 global_id) { + uint tileIndex = ((global_id.x + (global_id.y * tileCount.x)) + ((global_id.z * tileCount.x) * tileCount.y)); + uint clusterLightCount = 0u; + uint cluserLightIndices[256] = uint[256](0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u); + { + for(uint i = 0u; (i < globalLights.lightCount); i = (i + 1u)) { + float range = globalLights.lights[i].range; + bool lightInCluster = (range <= 0.0f); + if (!(lightInCluster)) { + vec4 lightViewPos = (camera.view * vec4(globalLights.lights[i].position, 1.0f)); + float sqDist = sqDistPointAABB(lightViewPos.xyz, clusters.bounds[tileIndex].minAABB, clusters.bounds[tileIndex].maxAABB); + lightInCluster = (sqDist <= (range * range)); + } + if (lightInCluster) { + cluserLightIndices[clusterLightCount] = i; + clusterLightCount = (clusterLightCount + 1u); + } + if ((clusterLightCount == 256u)) { + break; + } + } + } + uint offset = atomicAdd(clusterLights.offset, clusterLightCount); + if ((offset >= 1769472u)) { + return; + } + { + for(uint i = 0u; (i < clusterLightCount); i = (i + 1u)) { + clusterLights.indices[(offset + i)] = cluserLightIndices[i]; + } + } + clusterLights.lights[tileIndex].offset = offset; + clusterLights.lights[tileIndex].count = clusterLightCount; +} + +layout(local_size_x = 4, local_size_y = 2, local_size_z = 4) in; +void computeMain(tint_symbol_1 tint_symbol) { + computeMain_inner(tint_symbol.global_id); + return; +} +void main() { + tint_symbol_1 inputs; + inputs.global_id = gl_GlobalInvocationID; + computeMain(inputs); +} + + diff --git a/test/benchmark/cluster-lights.wgsl.expected.hlsl b/test/benchmark/cluster-lights.wgsl.expected.hlsl new file mode 100644 index 0000000000..d8b6e017c4 --- /dev/null +++ b/test/benchmark/cluster-lights.wgsl.expected.hlsl @@ -0,0 +1,101 @@ +uint atomicAdd_1(RWByteAddressBuffer buffer, uint offset, uint value) { + uint original_value = 0; + buffer.InterlockedAdd(offset, value, original_value); + return original_value; +} + +cbuffer cbuffer_camera : register(b0, space0) { + uint4 camera[14]; +}; + +ByteAddressBuffer clusters : register(t1, space0); + +RWByteAddressBuffer clusterLights : register(u2, space0); + +ByteAddressBuffer globalLights : register(t3, space0); +static const uint3 tileCount = uint3(32u, 18u, 48u); + +float linearDepth(float depthSample) { + return ((asfloat(camera[13].w) * asfloat(camera[13].z)) / mad(depthSample, (asfloat(camera[13].z) - asfloat(camera[13].w)), asfloat(camera[13].w))); +} + +uint3 getTile(float4 fragCoord) { + const float sliceScale = (float(tileCount.z) / log2((asfloat(camera[13].w) / asfloat(camera[13].z)))); + const float sliceBias = -(((float(tileCount.z) * log2(asfloat(camera[13].z))) / log2((asfloat(camera[13].w) / asfloat(camera[13].z))))); + const uint zTile = uint(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0f)); + return uint3(uint((fragCoord.x / (asfloat(camera[13].x) / float(tileCount.x)))), uint((fragCoord.y / (asfloat(camera[13].y) / float(tileCount.y)))), zTile); +} + +uint getClusterIndex(float4 fragCoord) { + const uint3 tile = getTile(fragCoord); + return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y)); +} + +float sqDistPointAABB(float3 tint_symbol, float3 minAABB, float3 maxAABB) { + float sqDist = 0.0f; + { + [loop] for(int i = 0; (i < 3); i = (i + 1)) { + const float v = tint_symbol[i]; + if ((v < minAABB[i])) { + sqDist = (sqDist + ((minAABB[i] - v) * (minAABB[i] - v))); + } + if ((v > maxAABB[i])) { + sqDist = (sqDist + ((v - maxAABB[i]) * (v - maxAABB[i]))); + } + } + } + return sqDist; +} + +struct tint_symbol_2 { + uint3 global_id : SV_DispatchThreadID; +}; + +float4x4 tint_symbol_6(uint4 buffer[14], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + const uint scalar_offset_3 = ((offset + 48u)) / 4; + return float4x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4]), asfloat(buffer[scalar_offset_3 / 4])); +} + +void computeMain_inner(uint3 global_id) { + const uint tileIndex = ((global_id.x + (global_id.y * tileCount.x)) + ((global_id.z * tileCount.x) * tileCount.y)); + uint clusterLightCount = 0u; + uint cluserLightIndices[256] = (uint[256])0; + { + [loop] for(uint i = 0u; (i < globalLights.Load(44u)); i = (i + 1u)) { + const float range = asfloat(globalLights.Load(((48u + (32u * i)) + 12u))); + bool lightInCluster = (range <= 0.0f); + if (!(lightInCluster)) { + const float4 lightViewPos = mul(float4(asfloat(globalLights.Load3((48u + (32u * i)))), 1.0f), tint_symbol_6(camera, 128u)); + const float sqDist = sqDistPointAABB(lightViewPos.xyz, asfloat(clusters.Load3((32u * tileIndex))), asfloat(clusters.Load3(((32u * tileIndex) + 16u)))); + lightInCluster = (sqDist <= (range * range)); + } + if (lightInCluster) { + cluserLightIndices[clusterLightCount] = i; + clusterLightCount = (clusterLightCount + 1u); + } + if ((clusterLightCount == 256u)) { + break; + } + } + } + uint offset = atomicAdd_1(clusterLights, 0u, clusterLightCount); + if ((offset >= 1769472u)) { + return; + } + { + [loop] for(uint i = 0u; (i < clusterLightCount); i = (i + 1u)) { + clusterLights.Store((221188u + (4u * (offset + i))), asuint(cluserLightIndices[i])); + } + } + clusterLights.Store((4u + (8u * tileIndex)), asuint(offset)); + clusterLights.Store(((4u + (8u * tileIndex)) + 4u), asuint(clusterLightCount)); +} + +[numthreads(4, 2, 4)] +void computeMain(tint_symbol_2 tint_symbol_1) { + computeMain_inner(tint_symbol_1.global_id); + return; +} diff --git a/test/benchmark/cluster-lights.wgsl.expected.msl b/test/benchmark/cluster-lights.wgsl.expected.msl new file mode 100644 index 0000000000..93a76ead1c --- /dev/null +++ b/test/benchmark/cluster-lights.wgsl.expected.msl @@ -0,0 +1,138 @@ +#include + +using namespace metal; + +template +inline vec operator*(matrix lhs, packed_vec rhs) { + return lhs * vec(rhs); +} + +template +inline vec operator*(packed_vec lhs, matrix rhs) { + return vec(lhs) * rhs; +} + +struct Camera { + /* 0x0000 */ float4x4 projection; + /* 0x0040 */ float4x4 inverseProjection; + /* 0x0080 */ float4x4 view; + /* 0x00c0 */ packed_float3 position; + /* 0x00cc */ float time; + /* 0x00d0 */ float2 outputSize; + /* 0x00d8 */ float zNear; + /* 0x00dc */ float zFar; +}; +struct ClusterBounds { + /* 0x0000 */ packed_float3 minAABB; + /* 0x000c */ int8_t tint_pad[4]; + /* 0x0010 */ packed_float3 maxAABB; + /* 0x001c */ int8_t tint_pad_1[4]; +}; +struct tint_array_wrapper { + /* 0x0000 */ ClusterBounds arr[27648]; +}; +struct Clusters { + /* 0x0000 */ tint_array_wrapper bounds; +}; +struct ClusterLights { + /* 0x0000 */ uint offset; + /* 0x0004 */ uint count; +}; +struct tint_array_wrapper_1 { + /* 0x0000 */ ClusterLights arr[27648]; +}; +struct tint_array_wrapper_2 { + /* 0x0000 */ uint arr[1769472]; +}; +struct ClusterLightGroup { + /* 0x0000 */ atomic_uint offset; + /* 0x0004 */ tint_array_wrapper_1 lights; + /* 0x36004 */ tint_array_wrapper_2 indices; +}; +struct Light { + /* 0x0000 */ packed_float3 position; + /* 0x000c */ float range; + /* 0x0010 */ packed_float3 color; + /* 0x001c */ float intensity; +}; +struct GlobalLights { + /* 0x0000 */ packed_float3 ambient; + /* 0x000c */ int8_t tint_pad_2[4]; + /* 0x0010 */ packed_float3 dirColor; + /* 0x001c */ float dirIntensity; + /* 0x0020 */ packed_float3 dirDirection; + /* 0x002c */ uint lightCount; + /* 0x0030 */ Light lights[1]; +}; +struct tint_array_wrapper_3 { + uint arr[256]; +}; + +constant uint3 tileCount = uint3(32u, 18u, 48u); +float linearDepth(float depthSample, const constant Camera* const tint_symbol) { + return (((*(tint_symbol)).zFar * (*(tint_symbol)).zNear) / fma(depthSample, ((*(tint_symbol)).zNear - (*(tint_symbol)).zFar), (*(tint_symbol)).zFar)); +} + +uint3 getTile(float4 fragCoord, const constant Camera* const tint_symbol_1) { + float const sliceScale = (float(tileCount[2]) / log2(((*(tint_symbol_1)).zFar / (*(tint_symbol_1)).zNear))); + float const sliceBias = -(((float(tileCount[2]) * log2((*(tint_symbol_1)).zNear)) / log2(((*(tint_symbol_1)).zFar / (*(tint_symbol_1)).zNear)))); + uint const zTile = uint(fmax(((log2(linearDepth(fragCoord[2], tint_symbol_1)) * sliceScale) + sliceBias), 0.0f)); + return uint3(uint((fragCoord[0] / ((*(tint_symbol_1)).outputSize[0] / float(tileCount[0])))), uint((fragCoord[1] / ((*(tint_symbol_1)).outputSize[1] / float(tileCount[1])))), zTile); +} + +uint getClusterIndex(float4 fragCoord, const constant Camera* const tint_symbol_2) { + uint3 const tile = getTile(fragCoord, tint_symbol_2); + return ((tile[0] + (tile[1] * tileCount[0])) + ((tile[2] * tileCount[0]) * tileCount[1])); +} + +float sqDistPointAABB(float3 point, float3 minAABB, float3 maxAABB) { + float sqDist = 0.0f; + for(int i = 0; (i < 3); i = as_type((as_type(i) + as_type(1)))) { + float const v = point[i]; + if ((v < minAABB[i])) { + sqDist = (sqDist + ((minAABB[i] - v) * (minAABB[i] - v))); + } + if ((v > maxAABB[i])) { + sqDist = (sqDist + ((v - maxAABB[i]) * (v - maxAABB[i]))); + } + } + return sqDist; +} + +void computeMain_inner(uint3 global_id, const device GlobalLights* const tint_symbol_3, const constant Camera* const tint_symbol_4, const device Clusters* const tint_symbol_5, device ClusterLightGroup* const tint_symbol_6) { + uint const tileIndex = ((global_id[0] + (global_id[1] * tileCount[0])) + ((global_id[2] * tileCount[0]) * tileCount[1])); + uint clusterLightCount = 0u; + tint_array_wrapper_3 cluserLightIndices = {}; + for(uint i = 0u; (i < (*(tint_symbol_3)).lightCount); i = (i + 1u)) { + float const range = (*(tint_symbol_3)).lights[i].range; + bool lightInCluster = (range <= 0.0f); + if (!(lightInCluster)) { + float4 const lightViewPos = ((*(tint_symbol_4)).view * float4((*(tint_symbol_3)).lights[i].position, 1.0f)); + float const sqDist = sqDistPointAABB(float4(lightViewPos).xyz, (*(tint_symbol_5)).bounds.arr[tileIndex].minAABB, (*(tint_symbol_5)).bounds.arr[tileIndex].maxAABB); + lightInCluster = (sqDist <= (range * range)); + } + if (lightInCluster) { + cluserLightIndices.arr[clusterLightCount] = i; + clusterLightCount = (clusterLightCount + 1u); + } + if ((clusterLightCount == 256u)) { + break; + } + } + uint const lightCount = clusterLightCount; + uint offset = atomic_fetch_add_explicit(&((*(tint_symbol_6)).offset), lightCount, memory_order_relaxed); + if ((offset >= 1769472u)) { + return; + } + for(uint i = 0u; (i < clusterLightCount); i = (i + 1u)) { + (*(tint_symbol_6)).indices.arr[(offset + i)] = cluserLightIndices.arr[i]; + } + (*(tint_symbol_6)).lights.arr[tileIndex].offset = offset; + (*(tint_symbol_6)).lights.arr[tileIndex].count = clusterLightCount; +} + +kernel void computeMain(const device GlobalLights* tint_symbol_7 [[buffer(2)]], const constant Camera* tint_symbol_8 [[buffer(0)]], const device Clusters* tint_symbol_9 [[buffer(3)]], device ClusterLightGroup* tint_symbol_10 [[buffer(1)]], uint3 global_id [[thread_position_in_grid]]) { + computeMain_inner(global_id, tint_symbol_7, tint_symbol_8, tint_symbol_9, tint_symbol_10); + return; +} + diff --git a/test/benchmark/cluster-lights.wgsl.expected.spvasm b/test/benchmark/cluster-lights.wgsl.expected.spvasm new file mode 100644 index 0000000000..f2374b2751 --- /dev/null +++ b/test/benchmark/cluster-lights.wgsl.expected.spvasm @@ -0,0 +1,504 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 312 +; Schema: 0 + OpCapability Shader + %48 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %computeMain "computeMain" %global_id_1 + OpExecutionMode %computeMain LocalSize 4 2 4 + OpName %global_id_1 "global_id_1" + OpName %Camera "Camera" + OpMemberName %Camera 0 "projection" + OpMemberName %Camera 1 "inverseProjection" + OpMemberName %Camera 2 "view" + OpMemberName %Camera 3 "position" + OpMemberName %Camera 4 "time" + OpMemberName %Camera 5 "outputSize" + OpMemberName %Camera 6 "zNear" + OpMemberName %Camera 7 "zFar" + OpName %camera "camera" + OpName %Clusters "Clusters" + OpMemberName %Clusters 0 "bounds" + OpName %ClusterBounds "ClusterBounds" + OpMemberName %ClusterBounds 0 "minAABB" + OpMemberName %ClusterBounds 1 "maxAABB" + OpName %clusters "clusters" + OpName %ClusterLightGroup "ClusterLightGroup" + OpMemberName %ClusterLightGroup 0 "offset" + OpMemberName %ClusterLightGroup 1 "lights" + OpName %ClusterLights "ClusterLights" + OpMemberName %ClusterLights 0 "offset" + OpMemberName %ClusterLights 1 "count" + OpMemberName %ClusterLightGroup 2 "indices" + OpName %clusterLights "clusterLights" + OpName %GlobalLights "GlobalLights" + OpMemberName %GlobalLights 0 "ambient" + OpMemberName %GlobalLights 1 "dirColor" + OpMemberName %GlobalLights 2 "dirIntensity" + OpMemberName %GlobalLights 3 "dirDirection" + OpMemberName %GlobalLights 4 "lightCount" + OpMemberName %GlobalLights 5 "lights" + OpName %Light "Light" + OpMemberName %Light 0 "position" + OpMemberName %Light 1 "range" + OpMemberName %Light 2 "color" + OpMemberName %Light 3 "intensity" + OpName %globalLights "globalLights" + OpName %tileCount "tileCount" + OpName %linearDepth "linearDepth" + OpName %depthSample "depthSample" + OpName %getTile "getTile" + OpName %fragCoord "fragCoord" + OpName %getClusterIndex "getClusterIndex" + OpName %fragCoord_0 "fragCoord" + OpName %sqDistPointAABB "sqDistPointAABB" + OpName %point "point" + OpName %minAABB "minAABB" + OpName %maxAABB "maxAABB" + OpName %sqDist "sqDist" + OpName %i "i" + OpName %computeMain_inner "computeMain_inner" + OpName %global_id "global_id" + OpName %clusterLightCount "clusterLightCount" + OpName %cluserLightIndices "cluserLightIndices" + OpName %i_0 "i" + OpName %lightInCluster "lightInCluster" + OpName %offset "offset" + OpName %i_1 "i" + OpName %computeMain "computeMain" + OpDecorate %global_id_1 BuiltIn GlobalInvocationId + OpDecorate %Camera Block + OpMemberDecorate %Camera 0 Offset 0 + OpMemberDecorate %Camera 0 ColMajor + OpMemberDecorate %Camera 0 MatrixStride 16 + OpMemberDecorate %Camera 1 Offset 64 + OpMemberDecorate %Camera 1 ColMajor + OpMemberDecorate %Camera 1 MatrixStride 16 + OpMemberDecorate %Camera 2 Offset 128 + OpMemberDecorate %Camera 2 ColMajor + OpMemberDecorate %Camera 2 MatrixStride 16 + OpMemberDecorate %Camera 3 Offset 192 + OpMemberDecorate %Camera 4 Offset 204 + OpMemberDecorate %Camera 5 Offset 208 + OpMemberDecorate %Camera 6 Offset 216 + OpMemberDecorate %Camera 7 Offset 220 + OpDecorate %camera NonWritable + OpDecorate %camera DescriptorSet 0 + OpDecorate %camera Binding 0 + OpDecorate %Clusters Block + OpMemberDecorate %Clusters 0 Offset 0 + OpMemberDecorate %ClusterBounds 0 Offset 0 + OpMemberDecorate %ClusterBounds 1 Offset 16 + OpDecorate %_arr_ClusterBounds_uint_27648 ArrayStride 32 + OpDecorate %clusters NonWritable + OpDecorate %clusters DescriptorSet 0 + OpDecorate %clusters Binding 1 + OpDecorate %ClusterLightGroup Block + OpMemberDecorate %ClusterLightGroup 0 Offset 0 + OpMemberDecorate %ClusterLightGroup 1 Offset 4 + OpMemberDecorate %ClusterLights 0 Offset 0 + OpMemberDecorate %ClusterLights 1 Offset 4 + OpDecorate %_arr_ClusterLights_uint_27648 ArrayStride 8 + OpMemberDecorate %ClusterLightGroup 2 Offset 221188 + OpDecorate %_arr_uint_uint_1769472 ArrayStride 4 + OpDecorate %clusterLights DescriptorSet 0 + OpDecorate %clusterLights Binding 2 + OpDecorate %GlobalLights Block + OpMemberDecorate %GlobalLights 0 Offset 0 + OpMemberDecorate %GlobalLights 1 Offset 16 + OpMemberDecorate %GlobalLights 2 Offset 28 + OpMemberDecorate %GlobalLights 3 Offset 32 + OpMemberDecorate %GlobalLights 4 Offset 44 + OpMemberDecorate %GlobalLights 5 Offset 48 + OpMemberDecorate %Light 0 Offset 0 + OpMemberDecorate %Light 1 Offset 12 + OpMemberDecorate %Light 2 Offset 16 + OpMemberDecorate %Light 3 Offset 28 + OpDecorate %_runtimearr_Light ArrayStride 32 + OpDecorate %globalLights NonWritable + OpDecorate %globalLights DescriptorSet 0 + OpDecorate %globalLights Binding 3 + OpDecorate %_arr_uint_uint_256 ArrayStride 4 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%global_id_1 = OpVariable %_ptr_Input_v3uint Input + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%mat4v4float = OpTypeMatrix %v4float 4 + %v3float = OpTypeVector %float 3 + %v2float = OpTypeVector %float 2 + %Camera = OpTypeStruct %mat4v4float %mat4v4float %mat4v4float %v3float %float %v2float %float %float +%_ptr_Uniform_Camera = OpTypePointer Uniform %Camera + %camera = OpVariable %_ptr_Uniform_Camera Uniform +%ClusterBounds = OpTypeStruct %v3float %v3float + %uint_27648 = OpConstant %uint 27648 +%_arr_ClusterBounds_uint_27648 = OpTypeArray %ClusterBounds %uint_27648 + %Clusters = OpTypeStruct %_arr_ClusterBounds_uint_27648 +%_ptr_StorageBuffer_Clusters = OpTypePointer StorageBuffer %Clusters + %clusters = OpVariable %_ptr_StorageBuffer_Clusters StorageBuffer +%ClusterLights = OpTypeStruct %uint %uint +%_arr_ClusterLights_uint_27648 = OpTypeArray %ClusterLights %uint_27648 +%uint_1769472 = OpConstant %uint 1769472 +%_arr_uint_uint_1769472 = OpTypeArray %uint %uint_1769472 +%ClusterLightGroup = OpTypeStruct %uint %_arr_ClusterLights_uint_27648 %_arr_uint_uint_1769472 +%_ptr_StorageBuffer_ClusterLightGroup = OpTypePointer StorageBuffer %ClusterLightGroup +%clusterLights = OpVariable %_ptr_StorageBuffer_ClusterLightGroup StorageBuffer + %Light = OpTypeStruct %v3float %float %v3float %float +%_runtimearr_Light = OpTypeRuntimeArray %Light +%GlobalLights = OpTypeStruct %v3float %v3float %float %v3float %uint %_runtimearr_Light +%_ptr_StorageBuffer_GlobalLights = OpTypePointer StorageBuffer %GlobalLights +%globalLights = OpVariable %_ptr_StorageBuffer_GlobalLights StorageBuffer + %uint_32 = OpConstant %uint 32 + %uint_18 = OpConstant %uint 18 + %uint_48 = OpConstant %uint 48 + %tileCount = OpConstantComposite %v3uint %uint_32 %uint_18 %uint_48 + %35 = OpTypeFunction %float %float + %uint_7 = OpConstant %uint 7 +%_ptr_Uniform_float = OpTypePointer Uniform %float + %uint_6 = OpConstant %uint 6 + %57 = OpTypeFunction %v3uint %v4float + %float_0 = OpConstant %float 0 + %uint_5 = OpConstant %uint 5 + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %112 = OpTypeFunction %uint %v4float + %128 = OpTypeFunction %float %v3float %v3float %v3float +%_ptr_Function_float = OpTypePointer Function %float + %136 = OpConstantNull %float + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_Function_int = OpTypePointer Function %int + %141 = OpConstantNull %int + %int_3 = OpConstant %int 3 + %bool = OpTypeBool + %int_1 = OpConstant %int 1 + %void = OpTypeVoid + %187 = OpTypeFunction %void %v3uint +%_ptr_Function_uint = OpTypePointer Function %uint + %205 = OpConstantNull %uint + %uint_256 = OpConstant %uint 256 +%_arr_uint_uint_256 = OpTypeArray %uint %uint_256 +%_ptr_Function__arr_uint_uint_256 = OpTypePointer Function %_arr_uint_uint_256 + %210 = OpConstantNull %_arr_uint_uint_256 + %uint_4 = OpConstant %uint 4 +%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float +%_ptr_Function_bool = OpTypePointer Function %bool + %232 = OpConstantNull %bool + %uint_2 = OpConstant %uint 2 +%_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float +%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float + %float_1 = OpConstant %float 1 +%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint + %307 = OpTypeFunction %void +%linearDepth = OpFunction %float None %35 +%depthSample = OpFunctionParameter %float + %38 = OpLabel + %41 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %42 = OpLoad %float %41 + %44 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %45 = OpLoad %float %44 + %46 = OpFMul %float %42 %45 + %49 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %50 = OpLoad %float %49 + %51 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %52 = OpLoad %float %51 + %53 = OpFSub %float %50 %52 + %54 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %55 = OpLoad %float %54 + %47 = OpExtInst %float %48 Fma %depthSample %53 %55 + %56 = OpFDiv %float %46 %47 + OpReturnValue %56 + OpFunctionEnd + %getTile = OpFunction %v3uint None %57 + %fragCoord = OpFunctionParameter %v4float + %60 = OpLabel + %62 = OpCompositeExtract %uint %tileCount 2 + %61 = OpConvertUToF %float %62 + %64 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %65 = OpLoad %float %64 + %66 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %67 = OpLoad %float %66 + %68 = OpFDiv %float %65 %67 + %63 = OpExtInst %float %48 Log2 %68 + %69 = OpFDiv %float %61 %63 + %72 = OpCompositeExtract %uint %tileCount 2 + %71 = OpConvertUToF %float %72 + %74 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %75 = OpLoad %float %74 + %73 = OpExtInst %float %48 Log2 %75 + %76 = OpFMul %float %71 %73 + %78 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %79 = OpLoad %float %78 + %80 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %81 = OpLoad %float %80 + %82 = OpFDiv %float %79 %81 + %77 = OpExtInst %float %48 Log2 %82 + %83 = OpFDiv %float %76 %77 + %70 = OpFNegate %float %83 + %88 = OpCompositeExtract %float %fragCoord 2 + %87 = OpFunctionCall %float %linearDepth %88 + %86 = OpExtInst %float %48 Log2 %87 + %89 = OpFMul %float %86 %69 + %90 = OpFAdd %float %89 %70 + %85 = OpExtInst %float %48 NMax %90 %float_0 + %84 = OpConvertFToU %uint %85 + %93 = OpCompositeExtract %float %fragCoord 0 + %96 = OpAccessChain %_ptr_Uniform_float %camera %uint_5 %uint_0 + %97 = OpLoad %float %96 + %99 = OpCompositeExtract %uint %tileCount 0 + %98 = OpConvertUToF %float %99 + %100 = OpFDiv %float %97 %98 + %101 = OpFDiv %float %93 %100 + %92 = OpConvertFToU %uint %101 + %103 = OpCompositeExtract %float %fragCoord 1 + %105 = OpAccessChain %_ptr_Uniform_float %camera %uint_5 %uint_1 + %106 = OpLoad %float %105 + %108 = OpCompositeExtract %uint %tileCount 1 + %107 = OpConvertUToF %float %108 + %109 = OpFDiv %float %106 %107 + %110 = OpFDiv %float %103 %109 + %102 = OpConvertFToU %uint %110 + %111 = OpCompositeConstruct %v3uint %92 %102 %84 + OpReturnValue %111 + OpFunctionEnd +%getClusterIndex = OpFunction %uint None %112 +%fragCoord_0 = OpFunctionParameter %v4float + %115 = OpLabel + %116 = OpFunctionCall %v3uint %getTile %fragCoord_0 + %117 = OpCompositeExtract %uint %116 0 + %118 = OpCompositeExtract %uint %116 1 + %119 = OpCompositeExtract %uint %tileCount 0 + %120 = OpIMul %uint %118 %119 + %121 = OpIAdd %uint %117 %120 + %122 = OpCompositeExtract %uint %116 2 + %123 = OpCompositeExtract %uint %tileCount 0 + %124 = OpIMul %uint %122 %123 + %125 = OpCompositeExtract %uint %tileCount 1 + %126 = OpIMul %uint %124 %125 + %127 = OpIAdd %uint %121 %126 + OpReturnValue %127 + OpFunctionEnd +%sqDistPointAABB = OpFunction %float None %128 + %point = OpFunctionParameter %v3float + %minAABB = OpFunctionParameter %v3float + %maxAABB = OpFunctionParameter %v3float + %133 = OpLabel + %sqDist = OpVariable %_ptr_Function_float Function %136 + %i = OpVariable %_ptr_Function_int Function %141 + OpStore %sqDist %float_0 + OpStore %i %int_0 + OpBranch %142 + %142 = OpLabel + OpLoopMerge %143 %144 None + OpBranch %145 + %145 = OpLabel + %147 = OpLoad %int %i + %149 = OpSLessThan %bool %147 %int_3 + %146 = OpLogicalNot %bool %149 + OpSelectionMerge %151 None + OpBranchConditional %146 %152 %151 + %152 = OpLabel + OpBranch %143 + %151 = OpLabel + %153 = OpLoad %int %i + %154 = OpVectorExtractDynamic %float %point %153 + %155 = OpLoad %int %i + %156 = OpVectorExtractDynamic %float %minAABB %155 + %157 = OpFOrdLessThan %bool %154 %156 + OpSelectionMerge %158 None + OpBranchConditional %157 %159 %158 + %159 = OpLabel + %160 = OpLoad %float %sqDist + %161 = OpLoad %int %i + %162 = OpVectorExtractDynamic %float %minAABB %161 + %163 = OpFSub %float %162 %154 + %164 = OpLoad %int %i + %165 = OpVectorExtractDynamic %float %minAABB %164 + %166 = OpFSub %float %165 %154 + %167 = OpFMul %float %163 %166 + %168 = OpFAdd %float %160 %167 + OpStore %sqDist %168 + OpBranch %158 + %158 = OpLabel + %169 = OpLoad %int %i + %170 = OpVectorExtractDynamic %float %maxAABB %169 + %171 = OpFOrdGreaterThan %bool %154 %170 + OpSelectionMerge %172 None + OpBranchConditional %171 %173 %172 + %173 = OpLabel + %174 = OpLoad %float %sqDist + %175 = OpLoad %int %i + %176 = OpVectorExtractDynamic %float %maxAABB %175 + %177 = OpFSub %float %154 %176 + %178 = OpLoad %int %i + %179 = OpVectorExtractDynamic %float %maxAABB %178 + %180 = OpFSub %float %154 %179 + %181 = OpFMul %float %177 %180 + %182 = OpFAdd %float %174 %181 + OpStore %sqDist %182 + OpBranch %172 + %172 = OpLabel + OpBranch %144 + %144 = OpLabel + %183 = OpLoad %int %i + %185 = OpIAdd %int %183 %int_1 + OpStore %i %185 + OpBranch %142 + %143 = OpLabel + %186 = OpLoad %float %sqDist + OpReturnValue %186 + OpFunctionEnd +%computeMain_inner = OpFunction %void None %187 + %global_id = OpFunctionParameter %v3uint + %191 = OpLabel +%clusterLightCount = OpVariable %_ptr_Function_uint Function %205 +%cluserLightIndices = OpVariable %_ptr_Function__arr_uint_uint_256 Function %210 + %i_0 = OpVariable %_ptr_Function_uint Function %205 +%lightInCluster = OpVariable %_ptr_Function_bool Function %232 + %offset = OpVariable %_ptr_Function_uint Function %205 + %i_1 = OpVariable %_ptr_Function_uint Function %205 + %192 = OpCompositeExtract %uint %global_id 0 + %193 = OpCompositeExtract %uint %global_id 1 + %194 = OpCompositeExtract %uint %tileCount 0 + %195 = OpIMul %uint %193 %194 + %196 = OpIAdd %uint %192 %195 + %197 = OpCompositeExtract %uint %global_id 2 + %198 = OpCompositeExtract %uint %tileCount 0 + %199 = OpIMul %uint %197 %198 + %200 = OpCompositeExtract %uint %tileCount 1 + %201 = OpIMul %uint %199 %200 + %202 = OpIAdd %uint %196 %201 + OpStore %clusterLightCount %uint_0 + OpStore %i_0 %uint_0 + OpBranch %212 + %212 = OpLabel + OpLoopMerge %213 %214 None + OpBranch %215 + %215 = OpLabel + %217 = OpLoad %uint %i_0 + %220 = OpAccessChain %_ptr_StorageBuffer_uint %globalLights %uint_4 + %221 = OpLoad %uint %220 + %222 = OpULessThan %bool %217 %221 + %216 = OpLogicalNot %bool %222 + OpSelectionMerge %223 None + OpBranchConditional %216 %224 %223 + %224 = OpLabel + OpBranch %213 + %223 = OpLabel + %225 = OpLoad %uint %i_0 + %227 = OpAccessChain %_ptr_StorageBuffer_float %globalLights %uint_5 %225 %uint_1 + %228 = OpLoad %float %227 + %229 = OpFOrdLessThanEqual %bool %228 %float_0 + OpStore %lightInCluster %229 + %234 = OpLoad %bool %lightInCluster + %233 = OpLogicalNot %bool %234 + OpSelectionMerge %235 None + OpBranchConditional %233 %236 %235 + %236 = OpLabel + %239 = OpAccessChain %_ptr_Uniform_mat4v4float %camera %uint_2 + %240 = OpLoad %mat4v4float %239 + %241 = OpLoad %uint %i_0 + %243 = OpAccessChain %_ptr_StorageBuffer_v3float %globalLights %uint_5 %241 %uint_0 + %244 = OpLoad %v3float %243 + %245 = OpCompositeExtract %float %244 0 + %246 = OpCompositeExtract %float %244 1 + %247 = OpCompositeExtract %float %244 2 + %249 = OpCompositeConstruct %v4float %245 %246 %247 %float_1 + %250 = OpMatrixTimesVector %v4float %240 %249 + %252 = OpVectorShuffle %v3float %250 %250 0 1 2 + %253 = OpAccessChain %_ptr_StorageBuffer_v3float %clusters %uint_0 %202 %uint_0 + %254 = OpLoad %v3float %253 + %255 = OpAccessChain %_ptr_StorageBuffer_v3float %clusters %uint_0 %202 %uint_1 + %256 = OpLoad %v3float %255 + %251 = OpFunctionCall %float %sqDistPointAABB %252 %254 %256 + %257 = OpFMul %float %228 %228 + %258 = OpFOrdLessThanEqual %bool %251 %257 + OpStore %lightInCluster %258 + OpBranch %235 + %235 = OpLabel + %259 = OpLoad %bool %lightInCluster + OpSelectionMerge %260 None + OpBranchConditional %259 %261 %260 + %261 = OpLabel + %262 = OpLoad %uint %clusterLightCount + %263 = OpAccessChain %_ptr_Function_uint %cluserLightIndices %262 + %264 = OpLoad %uint %i_0 + OpStore %263 %264 + %265 = OpLoad %uint %clusterLightCount + %266 = OpIAdd %uint %265 %uint_1 + OpStore %clusterLightCount %266 + OpBranch %260 + %260 = OpLabel + %267 = OpLoad %uint %clusterLightCount + %268 = OpIEqual %bool %267 %uint_256 + OpSelectionMerge %269 None + OpBranchConditional %268 %270 %269 + %270 = OpLabel + OpBranch %213 + %269 = OpLabel + OpBranch %214 + %214 = OpLabel + %271 = OpLoad %uint %i_0 + %272 = OpIAdd %uint %271 %uint_1 + OpStore %i_0 %272 + OpBranch %212 + %213 = OpLabel + %273 = OpLoad %uint %clusterLightCount + %277 = OpAccessChain %_ptr_StorageBuffer_uint_0 %clusterLights %uint_0 + %274 = OpAtomicIAdd %uint %277 %uint_1 %uint_0 %273 + OpStore %offset %274 + %279 = OpLoad %uint %offset + %280 = OpUGreaterThanEqual %bool %279 %uint_1769472 + OpSelectionMerge %281 None + OpBranchConditional %280 %282 %281 + %282 = OpLabel + OpReturn + %281 = OpLabel + OpStore %i_1 %uint_0 + OpBranch %284 + %284 = OpLabel + OpLoopMerge %285 %286 None + OpBranch %287 + %287 = OpLabel + %289 = OpLoad %uint %i_1 + %290 = OpLoad %uint %clusterLightCount + %291 = OpULessThan %bool %289 %290 + %288 = OpLogicalNot %bool %291 + OpSelectionMerge %292 None + OpBranchConditional %288 %293 %292 + %293 = OpLabel + OpBranch %285 + %292 = OpLabel + %294 = OpLoad %uint %offset + %295 = OpLoad %uint %i_1 + %296 = OpIAdd %uint %294 %295 + %297 = OpAccessChain %_ptr_StorageBuffer_uint %clusterLights %uint_2 %296 + %298 = OpLoad %uint %i_1 + %299 = OpAccessChain %_ptr_Function_uint %cluserLightIndices %298 + %300 = OpLoad %uint %299 + OpStore %297 %300 + OpBranch %286 + %286 = OpLabel + %301 = OpLoad %uint %i_1 + %302 = OpIAdd %uint %301 %uint_1 + OpStore %i_1 %302 + OpBranch %284 + %285 = OpLabel + %303 = OpAccessChain %_ptr_StorageBuffer_uint %clusterLights %uint_1 %202 %uint_0 + %304 = OpLoad %uint %offset + OpStore %303 %304 + %305 = OpAccessChain %_ptr_StorageBuffer_uint %clusterLights %uint_1 %202 %uint_1 + %306 = OpLoad %uint %clusterLightCount + OpStore %305 %306 + OpReturn + OpFunctionEnd +%computeMain = OpFunction %void None %307 + %309 = OpLabel + %311 = OpLoad %v3uint %global_id_1 + %310 = OpFunctionCall %void %computeMain_inner %311 + OpReturn + OpFunctionEnd diff --git a/test/benchmark/cluster-lights.wgsl.expected.wgsl b/test/benchmark/cluster-lights.wgsl.expected.wgsl new file mode 100644 index 0000000000..00d4ee6b48 --- /dev/null +++ b/test/benchmark/cluster-lights.wgsl.expected.wgsl @@ -0,0 +1,119 @@ +struct Camera { + projection : mat4x4; + inverseProjection : mat4x4; + view : mat4x4; + position : vec3; + time : f32; + outputSize : vec2; + zNear : f32; + zFar : f32; +} + +@group(0) @binding(0) var camera : Camera; + +struct ClusterBounds { + minAABB : vec3; + maxAABB : vec3; +} + +struct Clusters { + bounds : array; +} + +@group(0) @binding(1) var clusters : Clusters; + +struct ClusterLights { + offset : u32; + count : u32; +} + +struct ClusterLightGroup { + offset : atomic; + lights : array; + indices : array; +} + +@group(0) @binding(2) var clusterLights : ClusterLightGroup; + +struct Light { + position : vec3; + range : f32; + color : vec3; + intensity : f32; +} + +struct GlobalLights { + ambient : vec3; + dirColor : vec3; + dirIntensity : f32; + dirDirection : vec3; + lightCount : u32; + lights : array; +} + +@group(0) @binding(3) var globalLights : GlobalLights; + +let tileCount = vec3(32u, 18u, 48u); + +fn linearDepth(depthSample : f32) -> f32 { + return ((camera.zFar * camera.zNear) / fma(depthSample, (camera.zNear - camera.zFar), camera.zFar)); +} + +fn getTile(fragCoord : vec4) -> vec3 { + let sliceScale = (f32(tileCount.z) / log2((camera.zFar / camera.zNear))); + let sliceBias = -(((f32(tileCount.z) * log2(camera.zNear)) / log2((camera.zFar / camera.zNear)))); + let zTile = u32(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0)); + return vec3(u32((fragCoord.x / (camera.outputSize.x / f32(tileCount.x)))), u32((fragCoord.y / (camera.outputSize.y / f32(tileCount.y)))), zTile); +} + +fn getClusterIndex(fragCoord : vec4) -> u32 { + let tile = getTile(fragCoord); + return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y)); +} + +fn sqDistPointAABB(point : vec3, minAABB : vec3, maxAABB : vec3) -> f32 { + var sqDist = 0.0; + for(var i : i32 = 0; (i < 3); i = (i + 1)) { + let v = point[i]; + if ((v < minAABB[i])) { + sqDist = (sqDist + ((minAABB[i] - v) * (minAABB[i] - v))); + } + if ((v > maxAABB[i])) { + sqDist = (sqDist + ((v - maxAABB[i]) * (v - maxAABB[i]))); + } + } + return sqDist; +} + +@stage(compute) @workgroup_size(4, 2, 4) +fn computeMain(@builtin(global_invocation_id) global_id : vec3) { + let tileIndex = ((global_id.x + (global_id.y * tileCount.x)) + ((global_id.z * tileCount.x) * tileCount.y)); + var clusterLightCount = 0u; + var cluserLightIndices : array; + for(var i = 0u; (i < globalLights.lightCount); i = (i + 1u)) { + let range = globalLights.lights[i].range; + var lightInCluster : bool = (range <= 0.0); + if (!(lightInCluster)) { + let lightViewPos = (camera.view * vec4(globalLights.lights[i].position, 1.0)); + let sqDist = sqDistPointAABB(lightViewPos.xyz, clusters.bounds[tileIndex].minAABB, clusters.bounds[tileIndex].maxAABB); + lightInCluster = (sqDist <= (range * range)); + } + if (lightInCluster) { + cluserLightIndices[clusterLightCount] = i; + clusterLightCount = (clusterLightCount + 1u); + } + if ((clusterLightCount == 256u)) { + break; + } + } + let lightCount = clusterLightCount; + var offset = atomicAdd(&(clusterLights.offset), lightCount); + if ((offset >= 1769472u)) { + return; + } + for(var i = 0u; (i < clusterLightCount); i = (i + 1u)) { + clusterLights.indices[(offset + i)] = cluserLightIndices[i]; + } + clusterLights.lights[tileIndex].offset = offset; + clusterLights.lights[tileIndex].count = clusterLightCount; +} diff --git a/test/benchmark/empty.wgsl.expected.glsl b/test/benchmark/empty.wgsl.expected.glsl new file mode 100644 index 0000000000..c15c45314e --- /dev/null +++ b/test/benchmark/empty.wgsl.expected.glsl @@ -0,0 +1,12 @@ +#version 310 es +precision mediump float; + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void unused_entry_point() { + return; +} +void main() { + unused_entry_point(); +} + + diff --git a/test/benchmark/metaball-isosurface.wgsl b/test/benchmark/metaball-isosurface.wgsl new file mode 100644 index 0000000000..40374f42fa --- /dev/null +++ b/test/benchmark/metaball-isosurface.wgsl @@ -0,0 +1,205 @@ +struct Tables { + edges : array; + tris : array; +} + +@group(0) @binding(0) var tables : Tables; + +struct IsosurfaceVolume { + min : vec3; + max : vec3; + step : vec3; + size : vec3; + threshold : f32; + values : array; +} + +@group(0) @binding(1) var volume : IsosurfaceVolume; + +struct PositionBuffer { + values : array; +} + +@group(0) @binding(2) var positionsOut : PositionBuffer; + +struct NormalBuffer { + values : array; +} + +@group(0) @binding(3) var normalsOut : NormalBuffer; + +struct IndexBuffer { + tris : array; +} + +@group(0) @binding(4) var indicesOut : IndexBuffer; + +struct DrawIndirectArgs { + vc : u32; + vertexCount : atomic; + firstVertex : u32; + firstInstance : u32; + indexCount : atomic; + indexedInstanceCount : u32; + indexedFirstIndex : u32; + indexedBaseVertex : u32; + indexedFirstInstance : u32; +} + +@group(0) @binding(5) var drawOut : DrawIndirectArgs; + +fn valueAt(index : vec3) -> f32 { + if (any((index >= volume.size))) { + return 0.0; + } + let valueIndex = ((index.x + (index.y * volume.size.x)) + ((index.z * volume.size.x) * volume.size.y)); + return volume.values[valueIndex]; +} + +fn positionAt(index : vec3) -> vec3 { + return (volume.min + (volume.step * vec3(index.xyz))); +} + +fn normalAt(index : vec3) -> vec3 { + return vec3((valueAt((index - vec3(1u, 0u, 0u))) - valueAt((index + vec3(1u, 0u, 0u)))), (valueAt((index - vec3(0u, 1u, 0u))) - valueAt((index + vec3(0u, 1u, 0u)))), (valueAt((index - vec3(0u, 0u, 1u))) - valueAt((index + vec3(0u, 0u, 1u))))); +} + +var positions : array, 12>; + +var normals : array, 12>; + +var indices : array; + +var cubeVerts : u32 = 0u; + +fn interpX(index : u32, i : vec3, va : f32, vb : f32) { + let mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3((volume.step.x * mu), 0.0, 0.0)); + let na = normalAt(i); + let nb = normalAt((i + vec3(1u, 0u, 0u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +fn interpY(index : u32, i : vec3, va : f32, vb : f32) { + let mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3(0.0, (volume.step.y * mu), 0.0)); + let na = normalAt(i); + let nb = normalAt((i + vec3(0u, 1u, 0u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +fn interpZ(index : u32, i : vec3, va : f32, vb : f32) { + let mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3(0.0, 0.0, (volume.step.z * mu))); + let na = normalAt(i); + let nb = normalAt((i + vec3(0u, 0u, 1u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +@stage(compute) @workgroup_size(4, 4, 4) +fn computeMain(@builtin(global_invocation_id) global_id : vec3) { + let i0 = global_id; + let i1 = (global_id + vec3(1u, 0u, 0u)); + let i2 = (global_id + vec3(1u, 1u, 0u)); + let i3 = (global_id + vec3(0u, 1u, 0u)); + let i4 = (global_id + vec3(0u, 0u, 1u)); + let i5 = (global_id + vec3(1u, 0u, 1u)); + let i6 = (global_id + vec3(1u, 1u, 1u)); + let i7 = (global_id + vec3(0u, 1u, 1u)); + let v0 = valueAt(i0); + let v1 = valueAt(i1); + let v2 = valueAt(i2); + let v3 = valueAt(i3); + let v4 = valueAt(i4); + let v5 = valueAt(i5); + let v6 = valueAt(i6); + let v7 = valueAt(i7); + var cubeIndex = 0u; + if ((v0 < volume.threshold)) { + cubeIndex = (cubeIndex | 1u); + } + if ((v1 < volume.threshold)) { + cubeIndex = (cubeIndex | 2u); + } + if ((v2 < volume.threshold)) { + cubeIndex = (cubeIndex | 4u); + } + if ((v3 < volume.threshold)) { + cubeIndex = (cubeIndex | 8u); + } + if ((v4 < volume.threshold)) { + cubeIndex = (cubeIndex | 16u); + } + if ((v5 < volume.threshold)) { + cubeIndex = (cubeIndex | 32u); + } + if ((v6 < volume.threshold)) { + cubeIndex = (cubeIndex | 64u); + } + if ((v7 < volume.threshold)) { + cubeIndex = (cubeIndex | 128u); + } + let edges = tables.edges[cubeIndex]; + if (((edges & 1u) != 0u)) { + interpX(0u, i0, v0, v1); + } + if (((edges & 2u) != 0u)) { + interpY(1u, i1, v1, v2); + } + if (((edges & 4u) != 0u)) { + interpX(2u, i3, v3, v2); + } + if (((edges & 8u) != 0u)) { + interpY(3u, i0, v0, v3); + } + if (((edges & 16u) != 0u)) { + interpX(4u, i4, v4, v5); + } + if (((edges & 32u) != 0u)) { + interpY(5u, i5, v5, v6); + } + if (((edges & 64u) != 0u)) { + interpX(6u, i7, v7, v6); + } + if (((edges & 128u) != 0u)) { + interpY(7u, i4, v4, v7); + } + if (((edges & 256u) != 0u)) { + interpZ(8u, i0, v0, v4); + } + if (((edges & 512u) != 0u)) { + interpZ(9u, i1, v1, v5); + } + if (((edges & 1024u) != 0u)) { + interpZ(10u, i2, v2, v6); + } + if (((edges & 2048u) != 0u)) { + interpZ(11u, i3, v3, v7); + } + let triTableOffset = ((cubeIndex << 4u) + 1u); + let indexCount = u32(tables.tris[(triTableOffset - 1u)]); + var firstVertex = atomicAdd(&(drawOut.vertexCount), cubeVerts); + let bufferOffset = ((global_id.x + (global_id.y * volume.size.x)) + ((global_id.z * volume.size.x) * volume.size.y)); + let firstIndex = (bufferOffset * 15u); + for(var i = 0u; (i < cubeVerts); i = (i + 1u)) { + positionsOut.values[((firstVertex * 3u) + (i * 3u))] = positions[i].x; + positionsOut.values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = positions[i].y; + positionsOut.values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = positions[i].z; + normalsOut.values[((firstVertex * 3u) + (i * 3u))] = normals[i].x; + normalsOut.values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = normals[i].y; + normalsOut.values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = normals[i].z; + } + for(var i = 0u; (i < indexCount); i = (i + 1u)) { + let index = tables.tris[(triTableOffset + i)]; + indicesOut.tris[(firstIndex + i)] = (firstVertex + indices[index]); + } + for(var i = indexCount; (i < 15u); i = (i + 1u)) { + indicesOut.tris[(firstIndex + i)] = firstVertex; + } +} diff --git a/test/benchmark/metaball-isosurface.wgsl.expected.glsl b/test/benchmark/metaball-isosurface.wgsl.expected.glsl new file mode 100644 index 0000000000..1e033af35c --- /dev/null +++ b/test/benchmark/metaball-isosurface.wgsl.expected.glsl @@ -0,0 +1,232 @@ +#version 310 es +precision mediump float; + +struct Tables { + uint edges[256]; + int tris[4096]; +}; + +layout (binding = 0) buffer Tables_1 { + uint edges[256]; + int tris[4096]; +} tables; + +layout (binding = 1) buffer IsosurfaceVolume_1 { + vec3 tint_symbol; + vec3 tint_symbol_1; + vec3 tint_symbol_2; + uvec3 size; + float threshold; + float values[]; +} volume; + +layout (binding = 2) buffer PositionBuffer_1 { + float values[]; +} positionsOut; + +layout (binding = 3) buffer NormalBuffer_1 { + float values[]; +} normalsOut; + +layout (binding = 4) buffer IndexBuffer_1 { + uint tris[]; +} indicesOut; + +struct DrawIndirectArgs { + uint vc; + uint vertexCount; + uint firstVertex; + uint firstInstance; + uint indexCount; + uint indexedInstanceCount; + uint indexedFirstIndex; + uint indexedBaseVertex; + uint indexedFirstInstance; +}; + +layout (binding = 5) buffer DrawIndirectArgs_1 { + uint vc; + uint vertexCount; + uint firstVertex; + uint firstInstance; + uint indexCount; + uint indexedInstanceCount; + uint indexedFirstIndex; + uint indexedBaseVertex; + uint indexedFirstInstance; +} drawOut; + +float valueAt(uvec3 index) { + if (any(greaterThanEqual(index, volume.size))) { + return 0.0f; + } + uint valueIndex = ((index.x + (index.y * volume.size.x)) + ((index.z * volume.size.x) * volume.size.y)); + return volume.values[valueIndex]; +} + +vec3 positionAt(uvec3 index) { + return (volume.tint_symbol + (volume.tint_symbol_2 * vec3(index.xyz))); +} + +vec3 normalAt(uvec3 index) { + return vec3((valueAt((index - uvec3(1u, 0u, 0u))) - valueAt((index + uvec3(1u, 0u, 0u)))), (valueAt((index - uvec3(0u, 1u, 0u))) - valueAt((index + uvec3(0u, 1u, 0u)))), (valueAt((index - uvec3(0u, 0u, 1u))) - valueAt((index + uvec3(0u, 0u, 1u))))); +} + +vec3 positions[12] = vec3[12](vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)); +vec3 normals[12] = vec3[12](vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)); +uint indices[12] = uint[12](0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u); +uint cubeVerts = 0u; + +void interpX(uint index, uvec3 i, float va, float vb) { + float mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3((volume.tint_symbol_2.x * mu), 0.0f, 0.0f)); + vec3 na = normalAt(i); + vec3 nb = normalAt((i + uvec3(1u, 0u, 0u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +void interpY(uint index, uvec3 i, float va, float vb) { + float mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3(0.0f, (volume.tint_symbol_2.y * mu), 0.0f)); + vec3 na = normalAt(i); + vec3 nb = normalAt((i + uvec3(0u, 1u, 0u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +void interpZ(uint index, uvec3 i, float va, float vb) { + float mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3(0.0f, 0.0f, (volume.tint_symbol_2.z * mu))); + vec3 na = normalAt(i); + vec3 nb = normalAt((i + uvec3(0u, 0u, 1u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +struct tint_symbol_4 { + uvec3 global_id; +}; + +void computeMain_inner(uvec3 global_id) { + uvec3 i0 = global_id; + uvec3 i1 = (global_id + uvec3(1u, 0u, 0u)); + uvec3 i2 = (global_id + uvec3(1u, 1u, 0u)); + uvec3 i3 = (global_id + uvec3(0u, 1u, 0u)); + uvec3 i4 = (global_id + uvec3(0u, 0u, 1u)); + uvec3 i5 = (global_id + uvec3(1u, 0u, 1u)); + uvec3 i6 = (global_id + uvec3(1u, 1u, 1u)); + uvec3 i7 = (global_id + uvec3(0u, 1u, 1u)); + float v0 = valueAt(i0); + float v1 = valueAt(i1); + float v2 = valueAt(i2); + float v3 = valueAt(i3); + float v4 = valueAt(i4); + float v5 = valueAt(i5); + float v6 = valueAt(i6); + float v7 = valueAt(i7); + uint cubeIndex = 0u; + if ((v0 < volume.threshold)) { + cubeIndex = (cubeIndex | 1u); + } + if ((v1 < volume.threshold)) { + cubeIndex = (cubeIndex | 2u); + } + if ((v2 < volume.threshold)) { + cubeIndex = (cubeIndex | 4u); + } + if ((v3 < volume.threshold)) { + cubeIndex = (cubeIndex | 8u); + } + if ((v4 < volume.threshold)) { + cubeIndex = (cubeIndex | 16u); + } + if ((v5 < volume.threshold)) { + cubeIndex = (cubeIndex | 32u); + } + if ((v6 < volume.threshold)) { + cubeIndex = (cubeIndex | 64u); + } + if ((v7 < volume.threshold)) { + cubeIndex = (cubeIndex | 128u); + } + uint edges = tables.edges[cubeIndex]; + if (((edges & 1u) != 0u)) { + interpX(0u, i0, v0, v1); + } + if (((edges & 2u) != 0u)) { + interpY(1u, i1, v1, v2); + } + if (((edges & 4u) != 0u)) { + interpX(2u, i3, v3, v2); + } + if (((edges & 8u) != 0u)) { + interpY(3u, i0, v0, v3); + } + if (((edges & 16u) != 0u)) { + interpX(4u, i4, v4, v5); + } + if (((edges & 32u) != 0u)) { + interpY(5u, i5, v5, v6); + } + if (((edges & 64u) != 0u)) { + interpX(6u, i7, v7, v6); + } + if (((edges & 128u) != 0u)) { + interpY(7u, i4, v4, v7); + } + if (((edges & 256u) != 0u)) { + interpZ(8u, i0, v0, v4); + } + if (((edges & 512u) != 0u)) { + interpZ(9u, i1, v1, v5); + } + if (((edges & 1024u) != 0u)) { + interpZ(10u, i2, v2, v6); + } + if (((edges & 2048u) != 0u)) { + interpZ(11u, i3, v3, v7); + } + uint triTableOffset = ((cubeIndex << 4u) + 1u); + uint indexCount = uint(tables.tris[(triTableOffset - 1u)]); + uint firstVertex = atomicAdd(drawOut.vertexCount, cubeVerts); + uint bufferOffset = ((global_id.x + (global_id.y * volume.size.x)) + ((global_id.z * volume.size.x) * volume.size.y)); + uint firstIndex = (bufferOffset * 15u); + { + for(uint i = 0u; (i < cubeVerts); i = (i + 1u)) { + positionsOut.values[((firstVertex * 3u) + (i * 3u))] = positions[i].x; + positionsOut.values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = positions[i].y; + positionsOut.values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = positions[i].z; + normalsOut.values[((firstVertex * 3u) + (i * 3u))] = normals[i].x; + normalsOut.values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = normals[i].y; + normalsOut.values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = normals[i].z; + } + } + { + for(uint i = 0u; (i < indexCount); i = (i + 1u)) { + int index = tables.tris[(triTableOffset + i)]; + indicesOut.tris[(firstIndex + i)] = (firstVertex + indices[index]); + } + } + { + for(uint i = indexCount; (i < 15u); i = (i + 1u)) { + indicesOut.tris[(firstIndex + i)] = firstVertex; + } + } +} + +layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; +void computeMain(tint_symbol_4 tint_symbol_3) { + computeMain_inner(tint_symbol_3.global_id); + return; +} +void main() { + tint_symbol_4 inputs; + inputs.global_id = gl_GlobalInvocationID; + computeMain(inputs); +} + + diff --git a/test/benchmark/metaball-isosurface.wgsl.expected.hlsl b/test/benchmark/metaball-isosurface.wgsl.expected.hlsl new file mode 100644 index 0000000000..b2602297fc --- /dev/null +++ b/test/benchmark/metaball-isosurface.wgsl.expected.hlsl @@ -0,0 +1,185 @@ +uint atomicAdd_1(RWByteAddressBuffer buffer, uint offset, uint value) { + uint original_value = 0; + buffer.InterlockedAdd(offset, value, original_value); + return original_value; +} + +ByteAddressBuffer tables : register(t0, space0); + +RWByteAddressBuffer volume : register(u1, space0); + +RWByteAddressBuffer positionsOut : register(u2, space0); + +RWByteAddressBuffer normalsOut : register(u3, space0); + +RWByteAddressBuffer indicesOut : register(u4, space0); + +RWByteAddressBuffer drawOut : register(u5, space0); + +float valueAt(uint3 index) { + if (any((index >= volume.Load3(48u)))) { + return 0.0f; + } + const uint valueIndex = ((index.x + (index.y * volume.Load(48u))) + ((index.z * volume.Load(48u)) * volume.Load(52u))); + return asfloat(volume.Load((64u + (4u * valueIndex)))); +} + +float3 positionAt(uint3 index) { + return (asfloat(volume.Load3(0u)) + (asfloat(volume.Load3(32u)) * float3(index.xyz))); +} + +float3 normalAt(uint3 index) { + return float3((valueAt((index - uint3(1u, 0u, 0u))) - valueAt((index + uint3(1u, 0u, 0u)))), (valueAt((index - uint3(0u, 1u, 0u))) - valueAt((index + uint3(0u, 1u, 0u)))), (valueAt((index - uint3(0u, 0u, 1u))) - valueAt((index + uint3(0u, 0u, 1u))))); +} + +static float3 positions[12] = (float3[12])0; +static float3 normals[12] = (float3[12])0; +static uint indices[12] = (uint[12])0; +static uint cubeVerts = 0u; + +void interpX(uint index, uint3 i, float va, float vb) { + const float mu = ((asfloat(volume.Load(60u)) - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + float3((asfloat(volume.Load(32u)) * mu), 0.0f, 0.0f)); + const float3 na = normalAt(i); + const float3 nb = normalAt((i + uint3(1u, 0u, 0u))); + normals[cubeVerts] = lerp(na, nb, float3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +void interpY(uint index, uint3 i, float va, float vb) { + const float mu = ((asfloat(volume.Load(60u)) - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + float3(0.0f, (asfloat(volume.Load(36u)) * mu), 0.0f)); + const float3 na = normalAt(i); + const float3 nb = normalAt((i + uint3(0u, 1u, 0u))); + normals[cubeVerts] = lerp(na, nb, float3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +void interpZ(uint index, uint3 i, float va, float vb) { + const float mu = ((asfloat(volume.Load(60u)) - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + float3(0.0f, 0.0f, (asfloat(volume.Load(40u)) * mu))); + const float3 na = normalAt(i); + const float3 nb = normalAt((i + uint3(0u, 0u, 1u))); + normals[cubeVerts] = lerp(na, nb, float3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +struct tint_symbol_1 { + uint3 global_id : SV_DispatchThreadID; +}; + +void computeMain_inner(uint3 global_id) { + const uint3 i0 = global_id; + const uint3 i1 = (global_id + uint3(1u, 0u, 0u)); + const uint3 i2 = (global_id + uint3(1u, 1u, 0u)); + const uint3 i3 = (global_id + uint3(0u, 1u, 0u)); + const uint3 i4 = (global_id + uint3(0u, 0u, 1u)); + const uint3 i5 = (global_id + uint3(1u, 0u, 1u)); + const uint3 i6 = (global_id + uint3(1u, 1u, 1u)); + const uint3 i7 = (global_id + uint3(0u, 1u, 1u)); + const float v0 = valueAt(i0); + const float v1 = valueAt(i1); + const float v2 = valueAt(i2); + const float v3 = valueAt(i3); + const float v4 = valueAt(i4); + const float v5 = valueAt(i5); + const float v6 = valueAt(i6); + const float v7 = valueAt(i7); + uint cubeIndex = 0u; + if ((v0 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 1u); + } + if ((v1 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 2u); + } + if ((v2 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 4u); + } + if ((v3 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 8u); + } + if ((v4 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 16u); + } + if ((v5 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 32u); + } + if ((v6 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 64u); + } + if ((v7 < asfloat(volume.Load(60u)))) { + cubeIndex = (cubeIndex | 128u); + } + const uint edges = tables.Load((4u * cubeIndex)); + if (((edges & 1u) != 0u)) { + interpX(0u, i0, v0, v1); + } + if (((edges & 2u) != 0u)) { + interpY(1u, i1, v1, v2); + } + if (((edges & 4u) != 0u)) { + interpX(2u, i3, v3, v2); + } + if (((edges & 8u) != 0u)) { + interpY(3u, i0, v0, v3); + } + if (((edges & 16u) != 0u)) { + interpX(4u, i4, v4, v5); + } + if (((edges & 32u) != 0u)) { + interpY(5u, i5, v5, v6); + } + if (((edges & 64u) != 0u)) { + interpX(6u, i7, v7, v6); + } + if (((edges & 128u) != 0u)) { + interpY(7u, i4, v4, v7); + } + if (((edges & 256u) != 0u)) { + interpZ(8u, i0, v0, v4); + } + if (((edges & 512u) != 0u)) { + interpZ(9u, i1, v1, v5); + } + if (((edges & 1024u) != 0u)) { + interpZ(10u, i2, v2, v6); + } + if (((edges & 2048u) != 0u)) { + interpZ(11u, i3, v3, v7); + } + const uint triTableOffset = ((cubeIndex << 4u) + 1u); + const uint indexCount = uint(asint(tables.Load((1024u + (4u * (triTableOffset - 1u)))))); + uint firstVertex = atomicAdd_1(drawOut, 4u, cubeVerts); + const uint bufferOffset = ((global_id.x + (global_id.y * volume.Load(48u))) + ((global_id.z * volume.Load(48u)) * volume.Load(52u))); + const uint firstIndex = (bufferOffset * 15u); + { + [loop] for(uint i = 0u; (i < cubeVerts); i = (i + 1u)) { + positionsOut.Store((4u * ((firstVertex * 3u) + (i * 3u))), asuint(positions[i].x)); + positionsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 1u)), asuint(positions[i].y)); + positionsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 2u)), asuint(positions[i].z)); + normalsOut.Store((4u * ((firstVertex * 3u) + (i * 3u))), asuint(normals[i].x)); + normalsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 1u)), asuint(normals[i].y)); + normalsOut.Store((4u * (((firstVertex * 3u) + (i * 3u)) + 2u)), asuint(normals[i].z)); + } + } + { + [loop] for(uint i = 0u; (i < indexCount); i = (i + 1u)) { + const int index = asint(tables.Load((1024u + (4u * (triTableOffset + i))))); + indicesOut.Store((4u * (firstIndex + i)), asuint((firstVertex + indices[index]))); + } + } + { + [loop] for(uint i = indexCount; (i < 15u); i = (i + 1u)) { + indicesOut.Store((4u * (firstIndex + i)), asuint(firstVertex)); + } + } +} + +[numthreads(4, 4, 4)] +void computeMain(tint_symbol_1 tint_symbol) { + computeMain_inner(tint_symbol.global_id); + return; +} diff --git a/test/benchmark/metaball-isosurface.wgsl.expected.msl b/test/benchmark/metaball-isosurface.wgsl.expected.msl new file mode 100644 index 0000000000..f4838bbd8e --- /dev/null +++ b/test/benchmark/metaball-isosurface.wgsl.expected.msl @@ -0,0 +1,219 @@ +#include + +using namespace metal; + +template +inline vec operator*(matrix lhs, packed_vec rhs) { + return lhs * vec(rhs); +} + +template +inline vec operator*(packed_vec lhs, matrix rhs) { + return vec(lhs) * rhs; +} + +struct tint_array_wrapper { + /* 0x0000 */ uint arr[256]; +}; +struct tint_array_wrapper_1 { + /* 0x0000 */ int arr[4096]; +}; +struct Tables { + /* 0x0000 */ tint_array_wrapper edges; + /* 0x0400 */ tint_array_wrapper_1 tris; +}; +struct IsosurfaceVolume { + /* 0x0000 */ packed_float3 min; + /* 0x000c */ int8_t tint_pad[4]; + /* 0x0010 */ packed_float3 max; + /* 0x001c */ int8_t tint_pad_1[4]; + /* 0x0020 */ packed_float3 step; + /* 0x002c */ int8_t tint_pad_2[4]; + /* 0x0030 */ packed_uint3 size; + /* 0x003c */ float threshold; + /* 0x0040 */ float values[1]; + /* 0x0044 */ int8_t tint_pad_3[12]; +}; +struct PositionBuffer { + /* 0x0000 */ float values[1]; +}; +struct NormalBuffer { + /* 0x0000 */ float values[1]; +}; +struct IndexBuffer { + /* 0x0000 */ uint tris[1]; +}; +struct DrawIndirectArgs { + /* 0x0000 */ uint vc; + /* 0x0004 */ atomic_uint vertexCount; + /* 0x0008 */ uint firstVertex; + /* 0x000c */ uint firstInstance; + /* 0x0010 */ atomic_uint indexCount; + /* 0x0014 */ uint indexedInstanceCount; + /* 0x0018 */ uint indexedFirstIndex; + /* 0x001c */ uint indexedBaseVertex; + /* 0x0020 */ uint indexedFirstInstance; +}; +struct tint_array_wrapper_2 { + float3 arr[12]; +}; +struct tint_array_wrapper_3 { + uint arr[12]; +}; + +float valueAt(uint3 index, device IsosurfaceVolume* const tint_symbol) { + if (any((index >= (*(tint_symbol)).size))) { + return 0.0f; + } + uint const valueIndex = ((index[0] + (index[1] * (*(tint_symbol)).size[0])) + ((index[2] * (*(tint_symbol)).size[0]) * (*(tint_symbol)).size[1])); + return (*(tint_symbol)).values[valueIndex]; +} + +float3 positionAt(uint3 index, device IsosurfaceVolume* const tint_symbol_1) { + return ((*(tint_symbol_1)).min + ((*(tint_symbol_1)).step * float3(uint3(index).xyz))); +} + +float3 normalAt(uint3 index, device IsosurfaceVolume* const tint_symbol_2) { + return float3((valueAt((index - uint3(1u, 0u, 0u)), tint_symbol_2) - valueAt((index + uint3(1u, 0u, 0u)), tint_symbol_2)), (valueAt((index - uint3(0u, 1u, 0u)), tint_symbol_2) - valueAt((index + uint3(0u, 1u, 0u)), tint_symbol_2)), (valueAt((index - uint3(0u, 0u, 1u)), tint_symbol_2) - valueAt((index + uint3(0u, 0u, 1u)), tint_symbol_2))); +} + +void interpX(uint index, uint3 i, float va, float vb, device IsosurfaceVolume* const tint_symbol_3, thread tint_array_wrapper_2* const tint_symbol_4, thread uint* const tint_symbol_5, thread tint_array_wrapper_2* const tint_symbol_6, thread tint_array_wrapper_3* const tint_symbol_7) { + float const mu = (((*(tint_symbol_3)).threshold - va) / (vb - va)); + (*(tint_symbol_4)).arr[*(tint_symbol_5)] = (positionAt(i, tint_symbol_3) + float3(((*(tint_symbol_3)).step[0] * mu), 0.0f, 0.0f)); + float3 const na = normalAt(i, tint_symbol_3); + float3 const nb = normalAt((i + uint3(1u, 0u, 0u)), tint_symbol_3); + (*(tint_symbol_6)).arr[*(tint_symbol_5)] = mix(na, nb, float3(mu, mu, mu)); + (*(tint_symbol_7)).arr[index] = *(tint_symbol_5); + *(tint_symbol_5) = (*(tint_symbol_5) + 1u); +} + +void interpY(uint index, uint3 i, float va, float vb, device IsosurfaceVolume* const tint_symbol_8, thread tint_array_wrapper_2* const tint_symbol_9, thread uint* const tint_symbol_10, thread tint_array_wrapper_2* const tint_symbol_11, thread tint_array_wrapper_3* const tint_symbol_12) { + float const mu = (((*(tint_symbol_8)).threshold - va) / (vb - va)); + (*(tint_symbol_9)).arr[*(tint_symbol_10)] = (positionAt(i, tint_symbol_8) + float3(0.0f, ((*(tint_symbol_8)).step[1] * mu), 0.0f)); + float3 const na = normalAt(i, tint_symbol_8); + float3 const nb = normalAt((i + uint3(0u, 1u, 0u)), tint_symbol_8); + (*(tint_symbol_11)).arr[*(tint_symbol_10)] = mix(na, nb, float3(mu, mu, mu)); + (*(tint_symbol_12)).arr[index] = *(tint_symbol_10); + *(tint_symbol_10) = (*(tint_symbol_10) + 1u); +} + +void interpZ(uint index, uint3 i, float va, float vb, device IsosurfaceVolume* const tint_symbol_13, thread tint_array_wrapper_2* const tint_symbol_14, thread uint* const tint_symbol_15, thread tint_array_wrapper_2* const tint_symbol_16, thread tint_array_wrapper_3* const tint_symbol_17) { + float const mu = (((*(tint_symbol_13)).threshold - va) / (vb - va)); + (*(tint_symbol_14)).arr[*(tint_symbol_15)] = (positionAt(i, tint_symbol_13) + float3(0.0f, 0.0f, ((*(tint_symbol_13)).step[2] * mu))); + float3 const na = normalAt(i, tint_symbol_13); + float3 const nb = normalAt((i + uint3(0u, 0u, 1u)), tint_symbol_13); + (*(tint_symbol_16)).arr[*(tint_symbol_15)] = mix(na, nb, float3(mu, mu, mu)); + (*(tint_symbol_17)).arr[index] = *(tint_symbol_15); + *(tint_symbol_15) = (*(tint_symbol_15) + 1u); +} + +void computeMain_inner(uint3 global_id, device IsosurfaceVolume* const tint_symbol_18, const device Tables* const tint_symbol_19, thread tint_array_wrapper_2* const tint_symbol_20, thread uint* const tint_symbol_21, thread tint_array_wrapper_2* const tint_symbol_22, thread tint_array_wrapper_3* const tint_symbol_23, device DrawIndirectArgs* const tint_symbol_24, device PositionBuffer* const tint_symbol_25, device NormalBuffer* const tint_symbol_26, device IndexBuffer* const tint_symbol_27) { + uint3 const i0 = global_id; + uint3 const i1 = (global_id + uint3(1u, 0u, 0u)); + uint3 const i2 = (global_id + uint3(1u, 1u, 0u)); + uint3 const i3 = (global_id + uint3(0u, 1u, 0u)); + uint3 const i4 = (global_id + uint3(0u, 0u, 1u)); + uint3 const i5 = (global_id + uint3(1u, 0u, 1u)); + uint3 const i6 = (global_id + uint3(1u, 1u, 1u)); + uint3 const i7 = (global_id + uint3(0u, 1u, 1u)); + float const v0 = valueAt(i0, tint_symbol_18); + float const v1 = valueAt(i1, tint_symbol_18); + float const v2 = valueAt(i2, tint_symbol_18); + float const v3 = valueAt(i3, tint_symbol_18); + float const v4 = valueAt(i4, tint_symbol_18); + float const v5 = valueAt(i5, tint_symbol_18); + float const v6 = valueAt(i6, tint_symbol_18); + float const v7 = valueAt(i7, tint_symbol_18); + uint cubeIndex = 0u; + if ((v0 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 1u); + } + if ((v1 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 2u); + } + if ((v2 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 4u); + } + if ((v3 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 8u); + } + if ((v4 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 16u); + } + if ((v5 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 32u); + } + if ((v6 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 64u); + } + if ((v7 < (*(tint_symbol_18)).threshold)) { + cubeIndex = (cubeIndex | 128u); + } + uint const edges = (*(tint_symbol_19)).edges.arr[cubeIndex]; + if (((edges & 1u) != 0u)) { + interpX(0u, i0, v0, v1, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 2u) != 0u)) { + interpY(1u, i1, v1, v2, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 4u) != 0u)) { + interpX(2u, i3, v3, v2, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 8u) != 0u)) { + interpY(3u, i0, v0, v3, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 16u) != 0u)) { + interpX(4u, i4, v4, v5, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 32u) != 0u)) { + interpY(5u, i5, v5, v6, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 64u) != 0u)) { + interpX(6u, i7, v7, v6, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 128u) != 0u)) { + interpY(7u, i4, v4, v7, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 256u) != 0u)) { + interpZ(8u, i0, v0, v4, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 512u) != 0u)) { + interpZ(9u, i1, v1, v5, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 1024u) != 0u)) { + interpZ(10u, i2, v2, v6, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + if (((edges & 2048u) != 0u)) { + interpZ(11u, i3, v3, v7, tint_symbol_18, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23); + } + uint const triTableOffset = ((cubeIndex << 4u) + 1u); + uint const indexCount = uint((*(tint_symbol_19)).tris.arr[(triTableOffset - 1u)]); + uint firstVertex = atomic_fetch_add_explicit(&((*(tint_symbol_24)).vertexCount), *(tint_symbol_21), memory_order_relaxed); + uint const bufferOffset = ((global_id[0] + (global_id[1] * (*(tint_symbol_18)).size[0])) + ((global_id[2] * (*(tint_symbol_18)).size[0]) * (*(tint_symbol_18)).size[1])); + uint const firstIndex = (bufferOffset * 15u); + for(uint i = 0u; (i < *(tint_symbol_21)); i = (i + 1u)) { + (*(tint_symbol_25)).values[((firstVertex * 3u) + (i * 3u))] = (*(tint_symbol_20)).arr[i][0]; + (*(tint_symbol_25)).values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = (*(tint_symbol_20)).arr[i][1]; + (*(tint_symbol_25)).values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = (*(tint_symbol_20)).arr[i][2]; + (*(tint_symbol_26)).values[((firstVertex * 3u) + (i * 3u))] = (*(tint_symbol_22)).arr[i][0]; + (*(tint_symbol_26)).values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = (*(tint_symbol_22)).arr[i][1]; + (*(tint_symbol_26)).values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = (*(tint_symbol_22)).arr[i][2]; + } + for(uint i = 0u; (i < indexCount); i = (i + 1u)) { + int const index = (*(tint_symbol_19)).tris.arr[(triTableOffset + i)]; + (*(tint_symbol_27)).tris[(firstIndex + i)] = (firstVertex + (*(tint_symbol_23)).arr[index]); + } + for(uint i = indexCount; (i < 15u); i = (i + 1u)) { + (*(tint_symbol_27)).tris[(firstIndex + i)] = firstVertex; + } +} + +kernel void computeMain(device IsosurfaceVolume* tint_symbol_28 [[buffer(0)]], const device Tables* tint_symbol_29 [[buffer(5)]], device DrawIndirectArgs* tint_symbol_34 [[buffer(1)]], device PositionBuffer* tint_symbol_35 [[buffer(2)]], device NormalBuffer* tint_symbol_36 [[buffer(3)]], device IndexBuffer* tint_symbol_37 [[buffer(4)]], uint3 global_id [[thread_position_in_grid]]) { + thread tint_array_wrapper_2 tint_symbol_30 = {}; + thread uint tint_symbol_31 = 0u; + thread tint_array_wrapper_2 tint_symbol_32 = {}; + thread tint_array_wrapper_3 tint_symbol_33 = {}; + computeMain_inner(global_id, tint_symbol_28, tint_symbol_29, &(tint_symbol_30), &(tint_symbol_31), &(tint_symbol_32), &(tint_symbol_33), tint_symbol_34, tint_symbol_35, tint_symbol_36, tint_symbol_37); + return; +} + diff --git a/test/benchmark/metaball-isosurface.wgsl.expected.spvasm b/test/benchmark/metaball-isosurface.wgsl.expected.spvasm new file mode 100644 index 0000000000..d27494ecc2 --- /dev/null +++ b/test/benchmark/metaball-isosurface.wgsl.expected.spvasm @@ -0,0 +1,777 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 515 +; Schema: 0 + OpCapability Shader + %145 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %computeMain "computeMain" %global_id_1 + OpExecutionMode %computeMain LocalSize 4 4 4 + OpName %global_id_1 "global_id_1" + OpName %Tables "Tables" + OpMemberName %Tables 0 "edges" + OpMemberName %Tables 1 "tris" + OpName %tables "tables" + OpName %IsosurfaceVolume "IsosurfaceVolume" + OpMemberName %IsosurfaceVolume 0 "min" + OpMemberName %IsosurfaceVolume 1 "max" + OpMemberName %IsosurfaceVolume 2 "step" + OpMemberName %IsosurfaceVolume 3 "size" + OpMemberName %IsosurfaceVolume 4 "threshold" + OpMemberName %IsosurfaceVolume 5 "values" + OpName %volume "volume" + OpName %PositionBuffer "PositionBuffer" + OpMemberName %PositionBuffer 0 "values" + OpName %positionsOut "positionsOut" + OpName %NormalBuffer "NormalBuffer" + OpMemberName %NormalBuffer 0 "values" + OpName %normalsOut "normalsOut" + OpName %IndexBuffer "IndexBuffer" + OpMemberName %IndexBuffer 0 "tris" + OpName %indicesOut "indicesOut" + OpName %DrawIndirectArgs "DrawIndirectArgs" + OpMemberName %DrawIndirectArgs 0 "vc" + OpMemberName %DrawIndirectArgs 1 "vertexCount" + OpMemberName %DrawIndirectArgs 2 "firstVertex" + OpMemberName %DrawIndirectArgs 3 "firstInstance" + OpMemberName %DrawIndirectArgs 4 "indexCount" + OpMemberName %DrawIndirectArgs 5 "indexedInstanceCount" + OpMemberName %DrawIndirectArgs 6 "indexedFirstIndex" + OpMemberName %DrawIndirectArgs 7 "indexedBaseVertex" + OpMemberName %DrawIndirectArgs 8 "indexedFirstInstance" + OpName %drawOut "drawOut" + OpName %positions "positions" + OpName %normals "normals" + OpName %indices "indices" + OpName %cubeVerts "cubeVerts" + OpName %valueAt "valueAt" + OpName %index "index" + OpName %positionAt "positionAt" + OpName %index_0 "index" + OpName %normalAt "normalAt" + OpName %index_1 "index" + OpName %interpX "interpX" + OpName %index_2 "index" + OpName %i "i" + OpName %va "va" + OpName %vb "vb" + OpName %interpY "interpY" + OpName %index_3 "index" + OpName %i_0 "i" + OpName %va_0 "va" + OpName %vb_0 "vb" + OpName %interpZ "interpZ" + OpName %index_4 "index" + OpName %i_1 "i" + OpName %va_1 "va" + OpName %vb_1 "vb" + OpName %computeMain_inner "computeMain_inner" + OpName %global_id "global_id" + OpName %cubeIndex "cubeIndex" + OpName %firstVertex "firstVertex" + OpName %i_2 "i" + OpName %i_3 "i" + OpName %i_4 "i" + OpName %computeMain "computeMain" + OpDecorate %global_id_1 BuiltIn GlobalInvocationId + OpDecorate %Tables Block + OpMemberDecorate %Tables 0 Offset 0 + OpDecorate %_arr_uint_uint_256 ArrayStride 4 + OpMemberDecorate %Tables 1 Offset 1024 + OpDecorate %_arr_int_uint_4096 ArrayStride 4 + OpDecorate %tables NonWritable + OpDecorate %tables DescriptorSet 0 + OpDecorate %tables Binding 0 + OpDecorate %IsosurfaceVolume Block + OpMemberDecorate %IsosurfaceVolume 0 Offset 0 + OpMemberDecorate %IsosurfaceVolume 1 Offset 16 + OpMemberDecorate %IsosurfaceVolume 2 Offset 32 + OpMemberDecorate %IsosurfaceVolume 3 Offset 48 + OpMemberDecorate %IsosurfaceVolume 4 Offset 60 + OpMemberDecorate %IsosurfaceVolume 5 Offset 64 + OpDecorate %_runtimearr_float ArrayStride 4 + OpDecorate %volume NonReadable + OpDecorate %volume DescriptorSet 0 + OpDecorate %volume Binding 1 + OpDecorate %PositionBuffer Block + OpMemberDecorate %PositionBuffer 0 Offset 0 + OpDecorate %positionsOut NonReadable + OpDecorate %positionsOut DescriptorSet 0 + OpDecorate %positionsOut Binding 2 + OpDecorate %NormalBuffer Block + OpMemberDecorate %NormalBuffer 0 Offset 0 + OpDecorate %normalsOut NonReadable + OpDecorate %normalsOut DescriptorSet 0 + OpDecorate %normalsOut Binding 3 + OpDecorate %IndexBuffer Block + OpMemberDecorate %IndexBuffer 0 Offset 0 + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %indicesOut NonReadable + OpDecorate %indicesOut DescriptorSet 0 + OpDecorate %indicesOut Binding 4 + OpDecorate %DrawIndirectArgs Block + OpMemberDecorate %DrawIndirectArgs 0 Offset 0 + OpMemberDecorate %DrawIndirectArgs 1 Offset 4 + OpMemberDecorate %DrawIndirectArgs 2 Offset 8 + OpMemberDecorate %DrawIndirectArgs 3 Offset 12 + OpMemberDecorate %DrawIndirectArgs 4 Offset 16 + OpMemberDecorate %DrawIndirectArgs 5 Offset 20 + OpMemberDecorate %DrawIndirectArgs 6 Offset 24 + OpMemberDecorate %DrawIndirectArgs 7 Offset 28 + OpMemberDecorate %DrawIndirectArgs 8 Offset 32 + OpDecorate %drawOut DescriptorSet 0 + OpDecorate %drawOut Binding 5 + OpDecorate %_arr_v3float_uint_12 ArrayStride 16 + OpDecorate %_arr_uint_uint_12 ArrayStride 4 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint +%global_id_1 = OpVariable %_ptr_Input_v3uint Input + %uint_256 = OpConstant %uint 256 +%_arr_uint_uint_256 = OpTypeArray %uint %uint_256 + %int = OpTypeInt 32 1 + %uint_4096 = OpConstant %uint 4096 +%_arr_int_uint_4096 = OpTypeArray %int %uint_4096 + %Tables = OpTypeStruct %_arr_uint_uint_256 %_arr_int_uint_4096 +%_ptr_StorageBuffer_Tables = OpTypePointer StorageBuffer %Tables + %tables = OpVariable %_ptr_StorageBuffer_Tables StorageBuffer + %float = OpTypeFloat 32 + %v3float = OpTypeVector %float 3 +%_runtimearr_float = OpTypeRuntimeArray %float +%IsosurfaceVolume = OpTypeStruct %v3float %v3float %v3float %v3uint %float %_runtimearr_float +%_ptr_StorageBuffer_IsosurfaceVolume = OpTypePointer StorageBuffer %IsosurfaceVolume + %volume = OpVariable %_ptr_StorageBuffer_IsosurfaceVolume StorageBuffer +%PositionBuffer = OpTypeStruct %_runtimearr_float +%_ptr_StorageBuffer_PositionBuffer = OpTypePointer StorageBuffer %PositionBuffer +%positionsOut = OpVariable %_ptr_StorageBuffer_PositionBuffer StorageBuffer +%NormalBuffer = OpTypeStruct %_runtimearr_float +%_ptr_StorageBuffer_NormalBuffer = OpTypePointer StorageBuffer %NormalBuffer + %normalsOut = OpVariable %_ptr_StorageBuffer_NormalBuffer StorageBuffer +%_runtimearr_uint = OpTypeRuntimeArray %uint +%IndexBuffer = OpTypeStruct %_runtimearr_uint +%_ptr_StorageBuffer_IndexBuffer = OpTypePointer StorageBuffer %IndexBuffer + %indicesOut = OpVariable %_ptr_StorageBuffer_IndexBuffer StorageBuffer +%DrawIndirectArgs = OpTypeStruct %uint %uint %uint %uint %uint %uint %uint %uint %uint +%_ptr_StorageBuffer_DrawIndirectArgs = OpTypePointer StorageBuffer %DrawIndirectArgs + %drawOut = OpVariable %_ptr_StorageBuffer_DrawIndirectArgs StorageBuffer + %uint_12 = OpConstant %uint 12 +%_arr_v3float_uint_12 = OpTypeArray %v3float %uint_12 +%_ptr_Private__arr_v3float_uint_12 = OpTypePointer Private %_arr_v3float_uint_12 + %36 = OpConstantNull %_arr_v3float_uint_12 + %positions = OpVariable %_ptr_Private__arr_v3float_uint_12 Private %36 + %normals = OpVariable %_ptr_Private__arr_v3float_uint_12 Private %36 +%_arr_uint_uint_12 = OpTypeArray %uint %uint_12 +%_ptr_Private__arr_uint_uint_12 = OpTypePointer Private %_arr_uint_uint_12 + %41 = OpConstantNull %_arr_uint_uint_12 + %indices = OpVariable %_ptr_Private__arr_uint_uint_12 Private %41 + %uint_0 = OpConstant %uint 0 +%_ptr_Private_uint = OpTypePointer Private %uint + %cubeVerts = OpVariable %_ptr_Private_uint Private %uint_0 + %45 = OpTypeFunction %float %v3uint + %bool = OpTypeBool + %uint_3 = OpConstant %uint 3 +%_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint + %v3bool = OpTypeVector %bool 3 + %float_0 = OpConstant %float 0 +%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint + %uint_1 = OpConstant %uint 1 + %uint_5 = OpConstant %uint 5 +%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float + %80 = OpTypeFunction %v3float %v3uint +%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float + %uint_2 = OpConstant %uint 2 + %98 = OpConstantComposite %v3uint %uint_1 %uint_0 %uint_0 + %104 = OpConstantComposite %v3uint %uint_0 %uint_1 %uint_0 + %110 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_1 + %void = OpTypeVoid + %116 = OpTypeFunction %void %uint %v3uint %float %float + %uint_4 = OpConstant %uint 4 +%_ptr_Private_v3float = OpTypePointer Private %v3float + %211 = OpTypeFunction %void %v3uint + %216 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_0 + %220 = OpConstantComposite %v3uint %uint_1 %uint_0 %uint_1 + %222 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %224 = OpConstantComposite %v3uint %uint_0 %uint_1 %uint_1 +%_ptr_Function_uint = OpTypePointer Function %uint + %236 = OpConstantNull %uint + %uint_8 = OpConstant %uint 8 + %uint_16 = OpConstant %uint 16 + %uint_32 = OpConstant %uint 32 + %uint_64 = OpConstant %uint 64 + %uint_128 = OpConstant %uint 128 + %uint_6 = OpConstant %uint 6 + %uint_7 = OpConstant %uint 7 + %uint_512 = OpConstant %uint 512 + %uint_9 = OpConstant %uint 9 + %uint_1024 = OpConstant %uint 1024 + %uint_10 = OpConstant %uint 10 + %uint_2048 = OpConstant %uint 2048 + %uint_11 = OpConstant %uint 11 +%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int +%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint + %uint_15 = OpConstant %uint 15 +%_ptr_Private_float = OpTypePointer Private %float + %510 = OpTypeFunction %void + %valueAt = OpFunction %float None %45 + %index = OpFunctionParameter %v3uint + %48 = OpLabel + %53 = OpAccessChain %_ptr_StorageBuffer_v3uint %volume %uint_3 + %54 = OpLoad %v3uint %53 + %55 = OpUGreaterThanEqual %v3bool %index %54 + %49 = OpAny %bool %55 + OpSelectionMerge %57 None + OpBranchConditional %49 %58 %57 + %58 = OpLabel + OpReturnValue %float_0 + %57 = OpLabel + %60 = OpCompositeExtract %uint %index 0 + %61 = OpCompositeExtract %uint %index 1 + %63 = OpAccessChain %_ptr_StorageBuffer_uint %volume %uint_3 %uint_0 + %64 = OpLoad %uint %63 + %65 = OpIMul %uint %61 %64 + %66 = OpIAdd %uint %60 %65 + %67 = OpCompositeExtract %uint %index 2 + %68 = OpAccessChain %_ptr_StorageBuffer_uint %volume %uint_3 %uint_0 + %69 = OpLoad %uint %68 + %70 = OpIMul %uint %67 %69 + %72 = OpAccessChain %_ptr_StorageBuffer_uint %volume %uint_3 %uint_1 + %73 = OpLoad %uint %72 + %74 = OpIMul %uint %70 %73 + %75 = OpIAdd %uint %66 %74 + %78 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_5 %75 + %79 = OpLoad %float %78 + OpReturnValue %79 + OpFunctionEnd + %positionAt = OpFunction %v3float None %80 + %index_0 = OpFunctionParameter %v3uint + %83 = OpLabel + %85 = OpAccessChain %_ptr_StorageBuffer_v3float %volume %uint_0 + %86 = OpLoad %v3float %85 + %88 = OpAccessChain %_ptr_StorageBuffer_v3float %volume %uint_2 + %89 = OpLoad %v3float %88 + %91 = OpVectorShuffle %v3uint %index_0 %index_0 0 1 2 + %90 = OpConvertUToF %v3float %91 + %92 = OpFMul %v3float %89 %90 + %93 = OpFAdd %v3float %86 %92 + OpReturnValue %93 + OpFunctionEnd + %normalAt = OpFunction %v3float None %80 + %index_1 = OpFunctionParameter %v3uint + %96 = OpLabel + %99 = OpISub %v3uint %index_1 %98 + %97 = OpFunctionCall %float %valueAt %99 + %101 = OpIAdd %v3uint %index_1 %98 + %100 = OpFunctionCall %float %valueAt %101 + %102 = OpFSub %float %97 %100 + %105 = OpISub %v3uint %index_1 %104 + %103 = OpFunctionCall %float %valueAt %105 + %107 = OpIAdd %v3uint %index_1 %104 + %106 = OpFunctionCall %float %valueAt %107 + %108 = OpFSub %float %103 %106 + %111 = OpISub %v3uint %index_1 %110 + %109 = OpFunctionCall %float %valueAt %111 + %113 = OpIAdd %v3uint %index_1 %110 + %112 = OpFunctionCall %float %valueAt %113 + %114 = OpFSub %float %109 %112 + %115 = OpCompositeConstruct %v3float %102 %108 %114 + OpReturnValue %115 + OpFunctionEnd + %interpX = OpFunction %void None %116 + %index_2 = OpFunctionParameter %uint + %i = OpFunctionParameter %v3uint + %va = OpFunctionParameter %float + %vb = OpFunctionParameter %float + %123 = OpLabel + %125 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %126 = OpLoad %float %125 + %127 = OpFSub %float %126 %va + %128 = OpFSub %float %vb %va + %129 = OpFDiv %float %127 %128 + %130 = OpLoad %uint %cubeVerts + %132 = OpAccessChain %_ptr_Private_v3float %positions %130 + %133 = OpFunctionCall %v3float %positionAt %i + %134 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_2 %uint_0 + %135 = OpLoad %float %134 + %136 = OpFMul %float %135 %129 + %137 = OpCompositeConstruct %v3float %136 %float_0 %float_0 + %138 = OpFAdd %v3float %133 %137 + OpStore %132 %138 + %139 = OpFunctionCall %v3float %normalAt %i + %141 = OpIAdd %v3uint %i %98 + %140 = OpFunctionCall %v3float %normalAt %141 + %142 = OpLoad %uint %cubeVerts + %143 = OpAccessChain %_ptr_Private_v3float %normals %142 + %146 = OpCompositeConstruct %v3float %129 %129 %129 + %144 = OpExtInst %v3float %145 FMix %139 %140 %146 + OpStore %143 %144 + %147 = OpAccessChain %_ptr_Private_uint %indices %index_2 + %148 = OpLoad %uint %cubeVerts + OpStore %147 %148 + %149 = OpLoad %uint %cubeVerts + %150 = OpIAdd %uint %149 %uint_1 + OpStore %cubeVerts %150 + OpReturn + OpFunctionEnd + %interpY = OpFunction %void None %116 + %index_3 = OpFunctionParameter %uint + %i_0 = OpFunctionParameter %v3uint + %va_0 = OpFunctionParameter %float + %vb_0 = OpFunctionParameter %float + %156 = OpLabel + %157 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %158 = OpLoad %float %157 + %159 = OpFSub %float %158 %va_0 + %160 = OpFSub %float %vb_0 %va_0 + %161 = OpFDiv %float %159 %160 + %162 = OpLoad %uint %cubeVerts + %163 = OpAccessChain %_ptr_Private_v3float %positions %162 + %164 = OpFunctionCall %v3float %positionAt %i_0 + %165 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_2 %uint_1 + %166 = OpLoad %float %165 + %167 = OpFMul %float %166 %161 + %168 = OpCompositeConstruct %v3float %float_0 %167 %float_0 + %169 = OpFAdd %v3float %164 %168 + OpStore %163 %169 + %170 = OpFunctionCall %v3float %normalAt %i_0 + %172 = OpIAdd %v3uint %i_0 %104 + %171 = OpFunctionCall %v3float %normalAt %172 + %173 = OpLoad %uint %cubeVerts + %174 = OpAccessChain %_ptr_Private_v3float %normals %173 + %176 = OpCompositeConstruct %v3float %161 %161 %161 + %175 = OpExtInst %v3float %145 FMix %170 %171 %176 + OpStore %174 %175 + %177 = OpAccessChain %_ptr_Private_uint %indices %index_3 + %178 = OpLoad %uint %cubeVerts + OpStore %177 %178 + %179 = OpLoad %uint %cubeVerts + %180 = OpIAdd %uint %179 %uint_1 + OpStore %cubeVerts %180 + OpReturn + OpFunctionEnd + %interpZ = OpFunction %void None %116 + %index_4 = OpFunctionParameter %uint + %i_1 = OpFunctionParameter %v3uint + %va_1 = OpFunctionParameter %float + %vb_1 = OpFunctionParameter %float + %186 = OpLabel + %187 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %188 = OpLoad %float %187 + %189 = OpFSub %float %188 %va_1 + %190 = OpFSub %float %vb_1 %va_1 + %191 = OpFDiv %float %189 %190 + %192 = OpLoad %uint %cubeVerts + %193 = OpAccessChain %_ptr_Private_v3float %positions %192 + %194 = OpFunctionCall %v3float %positionAt %i_1 + %195 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_2 %uint_2 + %196 = OpLoad %float %195 + %197 = OpFMul %float %196 %191 + %198 = OpCompositeConstruct %v3float %float_0 %float_0 %197 + %199 = OpFAdd %v3float %194 %198 + OpStore %193 %199 + %200 = OpFunctionCall %v3float %normalAt %i_1 + %202 = OpIAdd %v3uint %i_1 %110 + %201 = OpFunctionCall %v3float %normalAt %202 + %203 = OpLoad %uint %cubeVerts + %204 = OpAccessChain %_ptr_Private_v3float %normals %203 + %206 = OpCompositeConstruct %v3float %191 %191 %191 + %205 = OpExtInst %v3float %145 FMix %200 %201 %206 + OpStore %204 %205 + %207 = OpAccessChain %_ptr_Private_uint %indices %index_4 + %208 = OpLoad %uint %cubeVerts + OpStore %207 %208 + %209 = OpLoad %uint %cubeVerts + %210 = OpIAdd %uint %209 %uint_1 + OpStore %cubeVerts %210 + OpReturn + OpFunctionEnd +%computeMain_inner = OpFunction %void None %211 + %global_id = OpFunctionParameter %v3uint + %214 = OpLabel + %cubeIndex = OpVariable %_ptr_Function_uint Function %236 +%firstVertex = OpVariable %_ptr_Function_uint Function %236 + %i_2 = OpVariable %_ptr_Function_uint Function %236 + %i_3 = OpVariable %_ptr_Function_uint Function %236 + %i_4 = OpVariable %_ptr_Function_uint Function %236 + %215 = OpIAdd %v3uint %global_id %98 + %217 = OpIAdd %v3uint %global_id %216 + %218 = OpIAdd %v3uint %global_id %104 + %219 = OpIAdd %v3uint %global_id %110 + %221 = OpIAdd %v3uint %global_id %220 + %223 = OpIAdd %v3uint %global_id %222 + %225 = OpIAdd %v3uint %global_id %224 + %226 = OpFunctionCall %float %valueAt %global_id + %227 = OpFunctionCall %float %valueAt %215 + %228 = OpFunctionCall %float %valueAt %217 + %229 = OpFunctionCall %float %valueAt %218 + %230 = OpFunctionCall %float %valueAt %219 + %231 = OpFunctionCall %float %valueAt %221 + %232 = OpFunctionCall %float %valueAt %223 + %233 = OpFunctionCall %float %valueAt %225 + OpStore %cubeIndex %uint_0 + %237 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %238 = OpLoad %float %237 + %239 = OpFOrdLessThan %bool %226 %238 + OpSelectionMerge %240 None + OpBranchConditional %239 %241 %240 + %241 = OpLabel + %242 = OpLoad %uint %cubeIndex + %243 = OpBitwiseOr %uint %242 %uint_1 + OpStore %cubeIndex %243 + OpBranch %240 + %240 = OpLabel + %244 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %245 = OpLoad %float %244 + %246 = OpFOrdLessThan %bool %227 %245 + OpSelectionMerge %247 None + OpBranchConditional %246 %248 %247 + %248 = OpLabel + %249 = OpLoad %uint %cubeIndex + %250 = OpBitwiseOr %uint %249 %uint_2 + OpStore %cubeIndex %250 + OpBranch %247 + %247 = OpLabel + %251 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %252 = OpLoad %float %251 + %253 = OpFOrdLessThan %bool %228 %252 + OpSelectionMerge %254 None + OpBranchConditional %253 %255 %254 + %255 = OpLabel + %256 = OpLoad %uint %cubeIndex + %257 = OpBitwiseOr %uint %256 %uint_4 + OpStore %cubeIndex %257 + OpBranch %254 + %254 = OpLabel + %258 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %259 = OpLoad %float %258 + %260 = OpFOrdLessThan %bool %229 %259 + OpSelectionMerge %261 None + OpBranchConditional %260 %262 %261 + %262 = OpLabel + %263 = OpLoad %uint %cubeIndex + %265 = OpBitwiseOr %uint %263 %uint_8 + OpStore %cubeIndex %265 + OpBranch %261 + %261 = OpLabel + %266 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %267 = OpLoad %float %266 + %268 = OpFOrdLessThan %bool %230 %267 + OpSelectionMerge %269 None + OpBranchConditional %268 %270 %269 + %270 = OpLabel + %271 = OpLoad %uint %cubeIndex + %273 = OpBitwiseOr %uint %271 %uint_16 + OpStore %cubeIndex %273 + OpBranch %269 + %269 = OpLabel + %274 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %275 = OpLoad %float %274 + %276 = OpFOrdLessThan %bool %231 %275 + OpSelectionMerge %277 None + OpBranchConditional %276 %278 %277 + %278 = OpLabel + %279 = OpLoad %uint %cubeIndex + %281 = OpBitwiseOr %uint %279 %uint_32 + OpStore %cubeIndex %281 + OpBranch %277 + %277 = OpLabel + %282 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %283 = OpLoad %float %282 + %284 = OpFOrdLessThan %bool %232 %283 + OpSelectionMerge %285 None + OpBranchConditional %284 %286 %285 + %286 = OpLabel + %287 = OpLoad %uint %cubeIndex + %289 = OpBitwiseOr %uint %287 %uint_64 + OpStore %cubeIndex %289 + OpBranch %285 + %285 = OpLabel + %290 = OpAccessChain %_ptr_StorageBuffer_float %volume %uint_4 + %291 = OpLoad %float %290 + %292 = OpFOrdLessThan %bool %233 %291 + OpSelectionMerge %293 None + OpBranchConditional %292 %294 %293 + %294 = OpLabel + %295 = OpLoad %uint %cubeIndex + %297 = OpBitwiseOr %uint %295 %uint_128 + OpStore %cubeIndex %297 + OpBranch %293 + %293 = OpLabel + %298 = OpLoad %uint %cubeIndex + %299 = OpAccessChain %_ptr_StorageBuffer_uint %tables %uint_0 %298 + %300 = OpLoad %uint %299 + %301 = OpBitwiseAnd %uint %300 %uint_1 + %302 = OpINotEqual %bool %301 %uint_0 + OpSelectionMerge %303 None + OpBranchConditional %302 %304 %303 + %304 = OpLabel + %305 = OpFunctionCall %void %interpX %uint_0 %global_id %226 %227 + OpBranch %303 + %303 = OpLabel + %306 = OpBitwiseAnd %uint %300 %uint_2 + %307 = OpINotEqual %bool %306 %uint_0 + OpSelectionMerge %308 None + OpBranchConditional %307 %309 %308 + %309 = OpLabel + %310 = OpFunctionCall %void %interpY %uint_1 %215 %227 %228 + OpBranch %308 + %308 = OpLabel + %311 = OpBitwiseAnd %uint %300 %uint_4 + %312 = OpINotEqual %bool %311 %uint_0 + OpSelectionMerge %313 None + OpBranchConditional %312 %314 %313 + %314 = OpLabel + %315 = OpFunctionCall %void %interpX %uint_2 %218 %229 %228 + OpBranch %313 + %313 = OpLabel + %316 = OpBitwiseAnd %uint %300 %uint_8 + %317 = OpINotEqual %bool %316 %uint_0 + OpSelectionMerge %318 None + OpBranchConditional %317 %319 %318 + %319 = OpLabel + %320 = OpFunctionCall %void %interpY %uint_3 %global_id %226 %229 + OpBranch %318 + %318 = OpLabel + %321 = OpBitwiseAnd %uint %300 %uint_16 + %322 = OpINotEqual %bool %321 %uint_0 + OpSelectionMerge %323 None + OpBranchConditional %322 %324 %323 + %324 = OpLabel + %325 = OpFunctionCall %void %interpX %uint_4 %219 %230 %231 + OpBranch %323 + %323 = OpLabel + %326 = OpBitwiseAnd %uint %300 %uint_32 + %327 = OpINotEqual %bool %326 %uint_0 + OpSelectionMerge %328 None + OpBranchConditional %327 %329 %328 + %329 = OpLabel + %330 = OpFunctionCall %void %interpY %uint_5 %221 %231 %232 + OpBranch %328 + %328 = OpLabel + %331 = OpBitwiseAnd %uint %300 %uint_64 + %332 = OpINotEqual %bool %331 %uint_0 + OpSelectionMerge %333 None + OpBranchConditional %332 %334 %333 + %334 = OpLabel + %335 = OpFunctionCall %void %interpX %uint_6 %225 %233 %232 + OpBranch %333 + %333 = OpLabel + %337 = OpBitwiseAnd %uint %300 %uint_128 + %338 = OpINotEqual %bool %337 %uint_0 + OpSelectionMerge %339 None + OpBranchConditional %338 %340 %339 + %340 = OpLabel + %341 = OpFunctionCall %void %interpY %uint_7 %219 %230 %233 + OpBranch %339 + %339 = OpLabel + %343 = OpBitwiseAnd %uint %300 %uint_256 + %344 = OpINotEqual %bool %343 %uint_0 + OpSelectionMerge %345 None + OpBranchConditional %344 %346 %345 + %346 = OpLabel + %347 = OpFunctionCall %void %interpZ %uint_8 %global_id %226 %230 + OpBranch %345 + %345 = OpLabel + %349 = OpBitwiseAnd %uint %300 %uint_512 + %350 = OpINotEqual %bool %349 %uint_0 + OpSelectionMerge %351 None + OpBranchConditional %350 %352 %351 + %352 = OpLabel + %353 = OpFunctionCall %void %interpZ %uint_9 %215 %227 %231 + OpBranch %351 + %351 = OpLabel + %356 = OpBitwiseAnd %uint %300 %uint_1024 + %357 = OpINotEqual %bool %356 %uint_0 + OpSelectionMerge %358 None + OpBranchConditional %357 %359 %358 + %359 = OpLabel + %360 = OpFunctionCall %void %interpZ %uint_10 %217 %228 %232 + OpBranch %358 + %358 = OpLabel + %363 = OpBitwiseAnd %uint %300 %uint_2048 + %364 = OpINotEqual %bool %363 %uint_0 + OpSelectionMerge %365 None + OpBranchConditional %364 %366 %365 + %366 = OpLabel + %367 = OpFunctionCall %void %interpZ %uint_11 %218 %229 %233 + OpBranch %365 + %365 = OpLabel + %369 = OpLoad %uint %cubeIndex + %370 = OpShiftLeftLogical %uint %369 %uint_4 + %371 = OpIAdd %uint %370 %uint_1 + %373 = OpISub %uint %371 %uint_1 + %375 = OpAccessChain %_ptr_StorageBuffer_int %tables %uint_1 %373 + %376 = OpLoad %int %375 + %372 = OpBitcast %uint %376 + %380 = OpAccessChain %_ptr_StorageBuffer_uint_0 %drawOut %uint_1 + %381 = OpLoad %uint %cubeVerts + %377 = OpAtomicIAdd %uint %380 %uint_1 %uint_0 %381 + OpStore %firstVertex %377 + %383 = OpCompositeExtract %uint %global_id 0 + %384 = OpCompositeExtract %uint %global_id 1 + %385 = OpAccessChain %_ptr_StorageBuffer_uint %volume %uint_3 %uint_0 + %386 = OpLoad %uint %385 + %387 = OpIMul %uint %384 %386 + %388 = OpIAdd %uint %383 %387 + %389 = OpCompositeExtract %uint %global_id 2 + %390 = OpAccessChain %_ptr_StorageBuffer_uint %volume %uint_3 %uint_0 + %391 = OpLoad %uint %390 + %392 = OpIMul %uint %389 %391 + %393 = OpAccessChain %_ptr_StorageBuffer_uint %volume %uint_3 %uint_1 + %394 = OpLoad %uint %393 + %395 = OpIMul %uint %392 %394 + %396 = OpIAdd %uint %388 %395 + %398 = OpIMul %uint %396 %uint_15 + OpStore %i_2 %uint_0 + OpBranch %400 + %400 = OpLabel + OpLoopMerge %401 %402 None + OpBranch %403 + %403 = OpLabel + %405 = OpLoad %uint %i_2 + %406 = OpLoad %uint %cubeVerts + %407 = OpULessThan %bool %405 %406 + %404 = OpLogicalNot %bool %407 + OpSelectionMerge %408 None + OpBranchConditional %404 %409 %408 + %409 = OpLabel + OpBranch %401 + %408 = OpLabel + %410 = OpLoad %uint %firstVertex + %411 = OpIMul %uint %410 %uint_3 + %412 = OpLoad %uint %i_2 + %413 = OpIMul %uint %412 %uint_3 + %414 = OpIAdd %uint %411 %413 + %415 = OpAccessChain %_ptr_StorageBuffer_float %positionsOut %uint_0 %414 + %416 = OpLoad %uint %i_2 + %418 = OpAccessChain %_ptr_Private_float %positions %416 %uint_0 + %419 = OpLoad %float %418 + OpStore %415 %419 + %420 = OpLoad %uint %firstVertex + %421 = OpIMul %uint %420 %uint_3 + %422 = OpLoad %uint %i_2 + %423 = OpIMul %uint %422 %uint_3 + %424 = OpIAdd %uint %421 %423 + %425 = OpIAdd %uint %424 %uint_1 + %426 = OpAccessChain %_ptr_StorageBuffer_float %positionsOut %uint_0 %425 + %427 = OpLoad %uint %i_2 + %428 = OpAccessChain %_ptr_Private_float %positions %427 %uint_1 + %429 = OpLoad %float %428 + OpStore %426 %429 + %430 = OpLoad %uint %firstVertex + %431 = OpIMul %uint %430 %uint_3 + %432 = OpLoad %uint %i_2 + %433 = OpIMul %uint %432 %uint_3 + %434 = OpIAdd %uint %431 %433 + %435 = OpIAdd %uint %434 %uint_2 + %436 = OpAccessChain %_ptr_StorageBuffer_float %positionsOut %uint_0 %435 + %437 = OpLoad %uint %i_2 + %438 = OpAccessChain %_ptr_Private_float %positions %437 %uint_2 + %439 = OpLoad %float %438 + OpStore %436 %439 + %440 = OpLoad %uint %firstVertex + %441 = OpIMul %uint %440 %uint_3 + %442 = OpLoad %uint %i_2 + %443 = OpIMul %uint %442 %uint_3 + %444 = OpIAdd %uint %441 %443 + %445 = OpAccessChain %_ptr_StorageBuffer_float %normalsOut %uint_0 %444 + %446 = OpLoad %uint %i_2 + %447 = OpAccessChain %_ptr_Private_float %normals %446 %uint_0 + %448 = OpLoad %float %447 + OpStore %445 %448 + %449 = OpLoad %uint %firstVertex + %450 = OpIMul %uint %449 %uint_3 + %451 = OpLoad %uint %i_2 + %452 = OpIMul %uint %451 %uint_3 + %453 = OpIAdd %uint %450 %452 + %454 = OpIAdd %uint %453 %uint_1 + %455 = OpAccessChain %_ptr_StorageBuffer_float %normalsOut %uint_0 %454 + %456 = OpLoad %uint %i_2 + %457 = OpAccessChain %_ptr_Private_float %normals %456 %uint_1 + %458 = OpLoad %float %457 + OpStore %455 %458 + %459 = OpLoad %uint %firstVertex + %460 = OpIMul %uint %459 %uint_3 + %461 = OpLoad %uint %i_2 + %462 = OpIMul %uint %461 %uint_3 + %463 = OpIAdd %uint %460 %462 + %464 = OpIAdd %uint %463 %uint_2 + %465 = OpAccessChain %_ptr_StorageBuffer_float %normalsOut %uint_0 %464 + %466 = OpLoad %uint %i_2 + %467 = OpAccessChain %_ptr_Private_float %normals %466 %uint_2 + %468 = OpLoad %float %467 + OpStore %465 %468 + OpBranch %402 + %402 = OpLabel + %469 = OpLoad %uint %i_2 + %470 = OpIAdd %uint %469 %uint_1 + OpStore %i_2 %470 + OpBranch %400 + %401 = OpLabel + OpStore %i_3 %uint_0 + OpBranch %472 + %472 = OpLabel + OpLoopMerge %473 %474 None + OpBranch %475 + %475 = OpLabel + %477 = OpLoad %uint %i_3 + %478 = OpULessThan %bool %477 %372 + %476 = OpLogicalNot %bool %478 + OpSelectionMerge %479 None + OpBranchConditional %476 %480 %479 + %480 = OpLabel + OpBranch %473 + %479 = OpLabel + %481 = OpLoad %uint %i_3 + %482 = OpIAdd %uint %371 %481 + %483 = OpAccessChain %_ptr_StorageBuffer_int %tables %uint_1 %482 + %484 = OpLoad %int %483 + %485 = OpLoad %uint %i_3 + %486 = OpIAdd %uint %398 %485 + %487 = OpAccessChain %_ptr_StorageBuffer_uint %indicesOut %uint_0 %486 + %488 = OpLoad %uint %firstVertex + %489 = OpAccessChain %_ptr_Private_uint %indices %484 + %490 = OpLoad %uint %489 + %491 = OpIAdd %uint %488 %490 + OpStore %487 %491 + OpBranch %474 + %474 = OpLabel + %492 = OpLoad %uint %i_3 + %493 = OpIAdd %uint %492 %uint_1 + OpStore %i_3 %493 + OpBranch %472 + %473 = OpLabel + OpStore %i_4 %372 + OpBranch %495 + %495 = OpLabel + OpLoopMerge %496 %497 None + OpBranch %498 + %498 = OpLabel + %500 = OpLoad %uint %i_4 + %501 = OpULessThan %bool %500 %uint_15 + %499 = OpLogicalNot %bool %501 + OpSelectionMerge %502 None + OpBranchConditional %499 %503 %502 + %503 = OpLabel + OpBranch %496 + %502 = OpLabel + %504 = OpLoad %uint %i_4 + %505 = OpIAdd %uint %398 %504 + %506 = OpAccessChain %_ptr_StorageBuffer_uint %indicesOut %uint_0 %505 + %507 = OpLoad %uint %firstVertex + OpStore %506 %507 + OpBranch %497 + %497 = OpLabel + %508 = OpLoad %uint %i_4 + %509 = OpIAdd %uint %508 %uint_1 + OpStore %i_4 %509 + OpBranch %495 + %496 = OpLabel + OpReturn + OpFunctionEnd +%computeMain = OpFunction %void None %510 + %512 = OpLabel + %514 = OpLoad %v3uint %global_id_1 + %513 = OpFunctionCall %void %computeMain_inner %514 + OpReturn + OpFunctionEnd diff --git a/test/benchmark/metaball-isosurface.wgsl.expected.wgsl b/test/benchmark/metaball-isosurface.wgsl.expected.wgsl new file mode 100644 index 0000000000..40374f42fa --- /dev/null +++ b/test/benchmark/metaball-isosurface.wgsl.expected.wgsl @@ -0,0 +1,205 @@ +struct Tables { + edges : array; + tris : array; +} + +@group(0) @binding(0) var tables : Tables; + +struct IsosurfaceVolume { + min : vec3; + max : vec3; + step : vec3; + size : vec3; + threshold : f32; + values : array; +} + +@group(0) @binding(1) var volume : IsosurfaceVolume; + +struct PositionBuffer { + values : array; +} + +@group(0) @binding(2) var positionsOut : PositionBuffer; + +struct NormalBuffer { + values : array; +} + +@group(0) @binding(3) var normalsOut : NormalBuffer; + +struct IndexBuffer { + tris : array; +} + +@group(0) @binding(4) var indicesOut : IndexBuffer; + +struct DrawIndirectArgs { + vc : u32; + vertexCount : atomic; + firstVertex : u32; + firstInstance : u32; + indexCount : atomic; + indexedInstanceCount : u32; + indexedFirstIndex : u32; + indexedBaseVertex : u32; + indexedFirstInstance : u32; +} + +@group(0) @binding(5) var drawOut : DrawIndirectArgs; + +fn valueAt(index : vec3) -> f32 { + if (any((index >= volume.size))) { + return 0.0; + } + let valueIndex = ((index.x + (index.y * volume.size.x)) + ((index.z * volume.size.x) * volume.size.y)); + return volume.values[valueIndex]; +} + +fn positionAt(index : vec3) -> vec3 { + return (volume.min + (volume.step * vec3(index.xyz))); +} + +fn normalAt(index : vec3) -> vec3 { + return vec3((valueAt((index - vec3(1u, 0u, 0u))) - valueAt((index + vec3(1u, 0u, 0u)))), (valueAt((index - vec3(0u, 1u, 0u))) - valueAt((index + vec3(0u, 1u, 0u)))), (valueAt((index - vec3(0u, 0u, 1u))) - valueAt((index + vec3(0u, 0u, 1u))))); +} + +var positions : array, 12>; + +var normals : array, 12>; + +var indices : array; + +var cubeVerts : u32 = 0u; + +fn interpX(index : u32, i : vec3, va : f32, vb : f32) { + let mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3((volume.step.x * mu), 0.0, 0.0)); + let na = normalAt(i); + let nb = normalAt((i + vec3(1u, 0u, 0u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +fn interpY(index : u32, i : vec3, va : f32, vb : f32) { + let mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3(0.0, (volume.step.y * mu), 0.0)); + let na = normalAt(i); + let nb = normalAt((i + vec3(0u, 1u, 0u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +fn interpZ(index : u32, i : vec3, va : f32, vb : f32) { + let mu = ((volume.threshold - va) / (vb - va)); + positions[cubeVerts] = (positionAt(i) + vec3(0.0, 0.0, (volume.step.z * mu))); + let na = normalAt(i); + let nb = normalAt((i + vec3(0u, 0u, 1u))); + normals[cubeVerts] = mix(na, nb, vec3(mu, mu, mu)); + indices[index] = cubeVerts; + cubeVerts = (cubeVerts + 1u); +} + +@stage(compute) @workgroup_size(4, 4, 4) +fn computeMain(@builtin(global_invocation_id) global_id : vec3) { + let i0 = global_id; + let i1 = (global_id + vec3(1u, 0u, 0u)); + let i2 = (global_id + vec3(1u, 1u, 0u)); + let i3 = (global_id + vec3(0u, 1u, 0u)); + let i4 = (global_id + vec3(0u, 0u, 1u)); + let i5 = (global_id + vec3(1u, 0u, 1u)); + let i6 = (global_id + vec3(1u, 1u, 1u)); + let i7 = (global_id + vec3(0u, 1u, 1u)); + let v0 = valueAt(i0); + let v1 = valueAt(i1); + let v2 = valueAt(i2); + let v3 = valueAt(i3); + let v4 = valueAt(i4); + let v5 = valueAt(i5); + let v6 = valueAt(i6); + let v7 = valueAt(i7); + var cubeIndex = 0u; + if ((v0 < volume.threshold)) { + cubeIndex = (cubeIndex | 1u); + } + if ((v1 < volume.threshold)) { + cubeIndex = (cubeIndex | 2u); + } + if ((v2 < volume.threshold)) { + cubeIndex = (cubeIndex | 4u); + } + if ((v3 < volume.threshold)) { + cubeIndex = (cubeIndex | 8u); + } + if ((v4 < volume.threshold)) { + cubeIndex = (cubeIndex | 16u); + } + if ((v5 < volume.threshold)) { + cubeIndex = (cubeIndex | 32u); + } + if ((v6 < volume.threshold)) { + cubeIndex = (cubeIndex | 64u); + } + if ((v7 < volume.threshold)) { + cubeIndex = (cubeIndex | 128u); + } + let edges = tables.edges[cubeIndex]; + if (((edges & 1u) != 0u)) { + interpX(0u, i0, v0, v1); + } + if (((edges & 2u) != 0u)) { + interpY(1u, i1, v1, v2); + } + if (((edges & 4u) != 0u)) { + interpX(2u, i3, v3, v2); + } + if (((edges & 8u) != 0u)) { + interpY(3u, i0, v0, v3); + } + if (((edges & 16u) != 0u)) { + interpX(4u, i4, v4, v5); + } + if (((edges & 32u) != 0u)) { + interpY(5u, i5, v5, v6); + } + if (((edges & 64u) != 0u)) { + interpX(6u, i7, v7, v6); + } + if (((edges & 128u) != 0u)) { + interpY(7u, i4, v4, v7); + } + if (((edges & 256u) != 0u)) { + interpZ(8u, i0, v0, v4); + } + if (((edges & 512u) != 0u)) { + interpZ(9u, i1, v1, v5); + } + if (((edges & 1024u) != 0u)) { + interpZ(10u, i2, v2, v6); + } + if (((edges & 2048u) != 0u)) { + interpZ(11u, i3, v3, v7); + } + let triTableOffset = ((cubeIndex << 4u) + 1u); + let indexCount = u32(tables.tris[(triTableOffset - 1u)]); + var firstVertex = atomicAdd(&(drawOut.vertexCount), cubeVerts); + let bufferOffset = ((global_id.x + (global_id.y * volume.size.x)) + ((global_id.z * volume.size.x) * volume.size.y)); + let firstIndex = (bufferOffset * 15u); + for(var i = 0u; (i < cubeVerts); i = (i + 1u)) { + positionsOut.values[((firstVertex * 3u) + (i * 3u))] = positions[i].x; + positionsOut.values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = positions[i].y; + positionsOut.values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = positions[i].z; + normalsOut.values[((firstVertex * 3u) + (i * 3u))] = normals[i].x; + normalsOut.values[(((firstVertex * 3u) + (i * 3u)) + 1u)] = normals[i].y; + normalsOut.values[(((firstVertex * 3u) + (i * 3u)) + 2u)] = normals[i].z; + } + for(var i = 0u; (i < indexCount); i = (i + 1u)) { + let index = tables.tris[(triTableOffset + i)]; + indicesOut.tris[(firstIndex + i)] = (firstVertex + indices[index]); + } + for(var i = indexCount; (i < 15u); i = (i + 1u)) { + indicesOut.tris[(firstIndex + i)] = firstVertex; + } +} diff --git a/test/benchmark/particles.wgsl.expected.glsl b/test/benchmark/particles.wgsl.expected.glsl new file mode 100644 index 0000000000..7afb6e1c9b --- /dev/null +++ b/test/benchmark/particles.wgsl.expected.glsl @@ -0,0 +1,515 @@ +SKIP: FAILED + +#version 310 es +precision mediump float; + +struct RenderParams { + mat4 modelViewProjectionMatrix; + vec3 right; + vec3 up; +}; + +layout (binding = 0) uniform RenderParams_1 { + mat4 modelViewProjectionMatrix; + vec3 right; + vec3 up; +} render_params; + +struct VertexInput { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct VertexOutput { + vec4 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_4 { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_5 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; + +VertexOutput vs_main_inner(VertexInput tint_symbol) { + vec3 quad_pos = (mat2x3(render_params.right, render_params.up) * tint_symbol.quad_pos); + vec3 position = (tint_symbol.position + (quad_pos * 0.01f)); + VertexOutput tint_symbol_1 = VertexOutput(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec2(0.0f, 0.0f)); + tint_symbol_1.position = (render_params.modelViewProjectionMatrix * vec4(position, 1.0f)); + tint_symbol_1.color = tint_symbol.color; + tint_symbol_1.quad_pos = tint_symbol.quad_pos; + return tint_symbol_1; +} + +struct tint_symbol_7 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_8 { + vec4 value; +}; +struct SimulationParams { + float deltaTime; + vec4 seed; +}; +struct Particle { + vec3 position; + float lifetime; + vec4 color; + vec3 velocity; +}; +struct tint_symbol_10 { + uvec3 GlobalInvocationID; +}; +struct UBO { + uint width; +}; +struct tint_symbol_12 { + uvec3 coord; +}; +struct tint_symbol_14 { + uvec3 coord; +}; + +tint_symbol_5 vs_main(tint_symbol_4 tint_symbol_3) { + VertexInput tint_symbol_15 = VertexInput(tint_symbol_3.position, tint_symbol_3.color, tint_symbol_3.quad_pos); + VertexOutput inner_result = vs_main_inner(tint_symbol_15); + tint_symbol_5 wrapper_result = tint_symbol_5(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.position = inner_result.position; + wrapper_result.color = inner_result.color; + wrapper_result.quad_pos = inner_result.quad_pos; + return wrapper_result; +} +in vec3 position; +in vec4 color; +in vec2 quad_pos; +out vec4 color; +out vec2 quad_pos; +void main() { + tint_symbol_4 inputs; + inputs.position = position; + inputs.color = color; + inputs.quad_pos = quad_pos; + tint_symbol_5 outputs; + outputs = vs_main(inputs); + color = outputs.color; + quad_pos = outputs.quad_pos; + gl_Position = outputs.position; + gl_Position.y = -gl_Position.y; +} + + +Error parsing GLSL shader: +ERROR: 0:90: 'color' : redefinition +ERROR: 1 compilation errors. No code generated. + + + +#version 310 es +precision mediump float; + +struct RenderParams { + mat4 modelViewProjectionMatrix; + vec3 right; + vec3 up; +}; +struct VertexInput { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct VertexOutput { + vec4 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_4 { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_5 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_7 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_8 { + vec4 value; +}; + +vec4 fs_main_inner(VertexOutput tint_symbol) { + vec4 color = tint_symbol.color; + color.a = (color.a * max((1.0f - length(tint_symbol.quad_pos)), 0.0f)); + return color; +} + +struct SimulationParams { + float deltaTime; + vec4 seed; +}; +struct Particle { + vec3 position; + float lifetime; + vec4 color; + vec3 velocity; +}; +struct tint_symbol_10 { + uvec3 GlobalInvocationID; +}; +struct UBO { + uint width; +}; +struct tint_symbol_12 { + uvec3 coord; +}; +struct tint_symbol_14 { + uvec3 coord; +}; + +tint_symbol_8 fs_main(tint_symbol_7 tint_symbol_6) { + VertexOutput tint_symbol_15 = VertexOutput(tint_symbol_6.position, tint_symbol_6.color, tint_symbol_6.quad_pos); + vec4 inner_result_1 = fs_main_inner(tint_symbol_15); + tint_symbol_8 wrapper_result_1 = tint_symbol_8(vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result_1.value = inner_result_1; + return wrapper_result_1; +} +in vec4 color; +in vec2 quad_pos; +out vec4 value; +void main() { + tint_symbol_7 inputs; + inputs.color = color; + inputs.quad_pos = quad_pos; + inputs.position = gl_FragCoord; + tint_symbol_8 outputs; + outputs = fs_main(inputs); + value = outputs.value; +} + + +#version 310 es +precision mediump float; + +vec2 rand_seed = vec2(0.0f, 0.0f); + +float rand() { + rand_seed.x = frac((cos(dot(rand_seed, vec2(23.140779495f, 232.616897583f))) * 136.816802979f)); + rand_seed.y = frac((cos(dot(rand_seed, vec2(54.478565216f, 345.841522217f))) * 534.764526367f)); + return rand_seed.y; +} + +struct RenderParams { + mat4 modelViewProjectionMatrix; + vec3 right; + vec3 up; +}; +struct VertexInput { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct VertexOutput { + vec4 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_4 { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_5 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_7 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_8 { + vec4 value; +}; +struct SimulationParams { + float deltaTime; + vec4 seed; +}; +struct Particle { + vec3 position; + float lifetime; + vec4 color; + vec3 velocity; +}; + +layout (binding = 0) uniform SimulationParams_1 { + float deltaTime; + vec4 seed; +} sim_params; +layout (binding = 1) buffer Particles_1 { + Particle particles[]; +} data; +uniform highp sampler2D tint_symbol_2; + +struct tint_symbol_10 { + uvec3 GlobalInvocationID; +}; + +void simulate_inner(uvec3 GlobalInvocationID) { + rand_seed = ((sim_params.seed.xy + vec2(GlobalInvocationID.xy)) * sim_params.seed.zw); + uint idx = GlobalInvocationID.x; + Particle particle = data.particles[idx]; + particle.velocity.z = (particle.velocity.z - (sim_params.deltaTime * 0.5f)); + particle.position = (particle.position + (sim_params.deltaTime * particle.velocity)); + particle.lifetime = (particle.lifetime - sim_params.deltaTime); + particle.color.a = smoothstep(0.0f, 0.5f, particle.lifetime); + if ((particle.lifetime < 0.0f)) { + ivec2 coord = ivec2(0, 0); + { + for(int level = (textureQueryLevels(tint_symbol_2); - 1); (level > 0); level = (level - 1)) { + vec4 probabilites = texelFetch(tint_symbol_2, coord, level); + vec4 value = vec4(rand()); + bvec4 mask = (greaterThanEqual(value, vec4(0.0f, probabilites.xyz)) & lessThan(value, probabilites)); + coord = (coord * 2); + coord.x = (coord.x + (any(mask.yw) ? 1 : 0)); + coord.y = (coord.y + (any(mask.zw) ? 1 : 0)); + } + } + vec2 uv = (vec2(coord) / vec2(textureSize(tint_symbol_2, 0))); + particle.position = vec3((((uv - 0.5f) * 3.0f) * vec2(1.0f, -1.0f)), 0.0f); + particle.color = texelFetch(tint_symbol_2, coord, 0); + particle.velocity.x = ((rand() - 0.5f) * 0.100000001f); + particle.velocity.y = ((rand() - 0.5f) * 0.100000001f); + particle.velocity.z = (rand() * 0.300000012f); + particle.lifetime = (0.5f + (rand() * 2.0f)); + } + data.particles[idx] = particle; +} + +struct UBO { + uint width; +}; +struct tint_symbol_12 { + uvec3 coord; +}; +struct tint_symbol_14 { + uvec3 coord; +}; + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; +void simulate(tint_symbol_10 tint_symbol_9) { + simulate_inner(tint_symbol_9.GlobalInvocationID); + return; +} +void main() { + tint_symbol_10 inputs; + inputs.GlobalInvocationID = gl_GlobalInvocationID; + simulate(inputs); +} + + +Error parsing GLSL shader: +ERROR: 0:7: 'frac' : no matching overloaded function found +ERROR: 0:7: '' : compilation terminated +ERROR: 2 compilation errors. No code generated. + + + +#version 310 es +precision mediump float; + +struct RenderParams { + mat4 modelViewProjectionMatrix; + vec3 right; + vec3 up; +}; +struct VertexInput { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct VertexOutput { + vec4 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_4 { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_5 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_7 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_8 { + vec4 value; +}; +struct SimulationParams { + float deltaTime; + vec4 seed; +}; +struct Particle { + vec3 position; + float lifetime; + vec4 color; + vec3 velocity; +}; +struct tint_symbol_10 { + uvec3 GlobalInvocationID; +}; +struct UBO { + uint width; +}; + +layout (binding = 3) uniform UBO_1 { + uint width; +} ubo; +layout (binding = 4) buffer Buffer_1 { + float weights[]; +} buf_in; +layout (binding = 5) buffer Buffer_2 { + float weights[]; +} buf_out; +uniform highp sampler2D tex_in; + +struct tint_symbol_12 { + uvec3 coord; +}; + +void import_level_inner(uvec3 coord) { + uint offset = (coord.x + (coord.y * ubo.width)); + buf_out.weights[offset] = texelFetch(tex_in, ivec2(coord.xy), 0).w; +} + +struct tint_symbol_14 { + uvec3 coord; +}; + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; +void import_level(tint_symbol_12 tint_symbol_11) { + import_level_inner(tint_symbol_11.coord); + return; +} +void main() { + tint_symbol_12 inputs; + inputs.coord = gl_GlobalInvocationID; + import_level(inputs); +} + + +#version 310 es +precision mediump float; + +struct RenderParams { + mat4 modelViewProjectionMatrix; + vec3 right; + vec3 up; +}; +struct VertexInput { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct VertexOutput { + vec4 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_4 { + vec3 position; + vec4 color; + vec2 quad_pos; +}; +struct tint_symbol_5 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_7 { + vec4 color; + vec2 quad_pos; + vec4 position; +}; +struct tint_symbol_8 { + vec4 value; +}; +struct SimulationParams { + float deltaTime; + vec4 seed; +}; +struct Particle { + vec3 position; + float lifetime; + vec4 color; + vec3 velocity; +}; +struct tint_symbol_10 { + uvec3 GlobalInvocationID; +}; +struct UBO { + uint width; +}; + +layout (binding = 3) uniform UBO_1 { + uint width; +} ubo; +layout (binding = 4) buffer Buffer_1 { + float weights[]; +} buf_in; +layout (binding = 5) buffer Buffer_2 { + float weights[]; +} buf_out; +uniform highp writeonly image2D tex_out; + +struct tint_symbol_12 { + uvec3 coord; +}; +struct tint_symbol_14 { + uvec3 coord; +}; + +void export_level_inner(uvec3 coord) { + if (all(lessThan(coord.xy, uvec2(imageSize(tex_out))))) { + uint dst_offset = (coord.x + (coord.y * ubo.width)); + uint src_offset = ((coord.x * 2u) + ((coord.y * 2u) * ubo.width)); + float a_1 = buf_in.weights[(src_offset + 0u)]; + float b = buf_in.weights[(src_offset + 1u)]; + float c = buf_in.weights[((src_offset + 0u) + ubo.width)]; + float d = buf_in.weights[((src_offset + 1u) + ubo.width)]; + float sum = dot(vec4(a_1, b, c, d), vec4(1.0f)); + buf_out.weights[dst_offset] = (sum / 4.0f); + vec4 probabilities = (vec4(a_1, (a_1 + b), ((a_1 + b) + c), sum) / max(sum, 0.0001f)); + imageStore(tex_out, ivec2(coord.xy), probabilities); + } +} + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; +void export_level(tint_symbol_14 tint_symbol_13) { + export_level_inner(tint_symbol_13.coord); + return; +} +void main() { + tint_symbol_14 inputs; + inputs.coord = gl_GlobalInvocationID; + export_level(inputs); +} + + diff --git a/test/benchmark/shadow-fragment.wgsl b/test/benchmark/shadow-fragment.wgsl new file mode 100644 index 0000000000..e1a0b6ee6e --- /dev/null +++ b/test/benchmark/shadow-fragment.wgsl @@ -0,0 +1,42 @@ +let shadowDepthTextureSize : f32 = 1024.0; + +struct Scene { + lightViewProjMatrix : mat4x4; + cameraViewProjMatrix : mat4x4; + lightPos : vec3; +} + +@group(0) @binding(0) var scene : Scene; + +@group(0) @binding(1) var shadowMap : texture_depth_2d; + +@group(0) @binding(2) var shadowSampler : sampler_comparison; + +struct FragmentInput { + @location(0) + shadowPos : vec3; + @location(1) + fragPos : vec3; + @location(2) + fragNorm : vec3; +} + +let albedo : vec3 = vec3(0.899999976, 0.899999976, 0.899999976); + +let ambientFactor : f32 = 0.200000003; + +@stage(fragment) +fn main(input : FragmentInput) -> @location(0) vec4 { + var visibility : f32 = 0.0; + let oneOverShadowDepthTextureSize = (1.0 / shadowDepthTextureSize); + for(var y : i32 = -1; (y <= 1); y = (y + 1)) { + for(var x : i32 = -1; (x <= 1); x = (x + 1)) { + let offset : vec2 = vec2((f32(x) * oneOverShadowDepthTextureSize), (f32(y) * oneOverShadowDepthTextureSize)); + visibility = (visibility + textureSampleCompare(shadowMap, shadowSampler, (input.shadowPos.xy + offset), (input.shadowPos.z - 0.007))); + } + } + visibility = (visibility / 9.0); + let lambertFactor : f32 = max(dot(normalize((scene.lightPos - input.fragPos)), input.fragNorm), 0.0); + let lightingFactor : f32 = min((ambientFactor + (visibility * lambertFactor)), 1.0); + return vec4((lightingFactor * albedo), 1.0); +} diff --git a/test/benchmark/shadow-fragment.wgsl.expected.glsl b/test/benchmark/shadow-fragment.wgsl.expected.glsl new file mode 100644 index 0000000000..f2248c446b --- /dev/null +++ b/test/benchmark/shadow-fragment.wgsl.expected.glsl @@ -0,0 +1,87 @@ +SKIP: FAILED + +#version 310 es +precision mediump float; + +const float shadowDepthTextureSize = 1024.0f; + +struct Scene { + mat4 lightViewProjMatrix; + mat4 cameraViewProjMatrix; + vec3 lightPos; +}; + +layout (binding = 0) uniform Scene_1 { + mat4 lightViewProjMatrix; + mat4 cameraViewProjMatrix; + vec3 lightPos; +} scene; +uniform highp sampler2D shadowMap; + + +struct FragmentInput { + vec3 shadowPos; + vec3 fragPos; + vec3 fragNorm; +}; + +const vec3 albedo = vec3(0.899999976f, 0.899999976f, 0.899999976f); +const float ambientFactor = 0.200000003f; + +struct tint_symbol_3 { + vec3 shadowPos; + vec3 fragPos; + vec3 fragNorm; +}; +struct tint_symbol_4 { + vec4 value; +}; + +vec4 tint_symbol_inner(FragmentInput tint_symbol_1) { + float visibility = 0.0f; + float oneOverShadowDepthTextureSize = (1.0f / shadowDepthTextureSize); + { + for(int y = -1; (y <= 1); y = (y + 1)) { + { + for(int x = -1; (x <= 1); x = (x + 1)) { + vec2 offset = vec2((float(x) * oneOverShadowDepthTextureSize), (float(y) * oneOverShadowDepthTextureSize)); + visibility = (visibility + texture(shadowMap, (tint_symbol_1.shadowPos.xy + offset), (tint_symbol_1.shadowPos.z - 0.007f))); + } + } + } + } + visibility = (visibility / 9.0f); + float lambertFactor = max(dot(normalize((scene.lightPos - tint_symbol_1.fragPos)), tint_symbol_1.fragNorm), 0.0f); + float lightingFactor = min((ambientFactor + (visibility * lambertFactor)), 1.0f); + return vec4((lightingFactor * albedo), 1.0f); +} + +tint_symbol_4 tint_symbol(tint_symbol_3 tint_symbol_2) { + FragmentInput tint_symbol_5 = FragmentInput(tint_symbol_2.shadowPos, tint_symbol_2.fragPos, tint_symbol_2.fragNorm); + vec4 inner_result = tint_symbol_inner(tint_symbol_5); + tint_symbol_4 wrapper_result = tint_symbol_4(vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.value = inner_result; + return wrapper_result; +} +in vec3 shadowPos; +in vec3 fragPos; +in vec3 fragNorm; +out vec4 value; +void main() { + tint_symbol_3 inputs; + inputs.shadowPos = shadowPos; + inputs.fragPos = fragPos; + inputs.fragNorm = fragNorm; + tint_symbol_4 outputs; + outputs = tint_symbol(inputs); + value = outputs.value; +} + + +Error parsing GLSL shader: +ERROR: 0:46: 'assign' : cannot convert from ' temp highp 4-component vector of float' to ' temp mediump float' +ERROR: 0:46: '' : compilation terminated +ERROR: 2 compilation errors. No code generated. + + + diff --git a/test/benchmark/shadow-fragment.wgsl.expected.hlsl b/test/benchmark/shadow-fragment.wgsl.expected.hlsl new file mode 100644 index 0000000000..58baa9ea38 --- /dev/null +++ b/test/benchmark/shadow-fragment.wgsl.expected.hlsl @@ -0,0 +1,52 @@ +static const float shadowDepthTextureSize = 1024.0f; + +cbuffer cbuffer_scene : register(b0, space0) { + uint4 scene[9]; +}; +Texture2D shadowMap : register(t1, space0); +SamplerComparisonState shadowSampler : register(s2, space0); + +struct FragmentInput { + float3 shadowPos; + float3 fragPos; + float3 fragNorm; +}; + +static const float3 albedo = float3(0.899999976f, 0.899999976f, 0.899999976f); +static const float ambientFactor = 0.200000003f; + +struct tint_symbol_1 { + float3 shadowPos : TEXCOORD0; + float3 fragPos : TEXCOORD1; + float3 fragNorm : TEXCOORD2; +}; +struct tint_symbol_2 { + float4 value : SV_Target0; +}; + +float4 main_inner(FragmentInput input) { + float visibility = 0.0f; + const float oneOverShadowDepthTextureSize = (1.0f / shadowDepthTextureSize); + { + [loop] for(int y = -1; (y <= 1); y = (y + 1)) { + { + [loop] for(int x = -1; (x <= 1); x = (x + 1)) { + const float2 offset = float2((float(x) * oneOverShadowDepthTextureSize), (float(y) * oneOverShadowDepthTextureSize)); + visibility = (visibility + shadowMap.SampleCmp(shadowSampler, (input.shadowPos.xy + offset), (input.shadowPos.z - 0.007f))); + } + } + } + } + visibility = (visibility / 9.0f); + const float lambertFactor = max(dot(normalize((asfloat(scene[8].xyz) - input.fragPos)), input.fragNorm), 0.0f); + const float lightingFactor = min((ambientFactor + (visibility * lambertFactor)), 1.0f); + return float4((lightingFactor * albedo), 1.0f); +} + +tint_symbol_2 main(tint_symbol_1 tint_symbol) { + const FragmentInput tint_symbol_4 = {tint_symbol.shadowPos, tint_symbol.fragPos, tint_symbol.fragNorm}; + const float4 inner_result = main_inner(tint_symbol_4); + tint_symbol_2 wrapper_result = (tint_symbol_2)0; + wrapper_result.value = inner_result; + return wrapper_result; +} diff --git a/test/benchmark/shadow-fragment.wgsl.expected.msl b/test/benchmark/shadow-fragment.wgsl.expected.msl new file mode 100644 index 0000000000..409f8fd137 --- /dev/null +++ b/test/benchmark/shadow-fragment.wgsl.expected.msl @@ -0,0 +1,60 @@ +#include + +using namespace metal; + +template +inline vec operator*(matrix lhs, packed_vec rhs) { + return lhs * vec(rhs); +} + +template +inline vec operator*(packed_vec lhs, matrix rhs) { + return vec(lhs) * rhs; +} + +struct Scene { + /* 0x0000 */ float4x4 lightViewProjMatrix; + /* 0x0040 */ float4x4 cameraViewProjMatrix; + /* 0x0080 */ packed_float3 lightPos; + /* 0x008c */ int8_t tint_pad[4]; +}; +struct FragmentInput { + float3 shadowPos; + float3 fragPos; + float3 fragNorm; +}; +struct tint_symbol_2 { + float3 shadowPos [[user(locn0)]]; + float3 fragPos [[user(locn1)]]; + float3 fragNorm [[user(locn2)]]; +}; +struct tint_symbol_3 { + float4 value [[color(0)]]; +}; + +constant float shadowDepthTextureSize = 1024.0f; +constant float3 albedo = float3(0.899999976f, 0.899999976f, 0.899999976f); +constant float ambientFactor = 0.200000003f; +float4 tint_symbol_inner(FragmentInput input, depth2d tint_symbol_5, sampler tint_symbol_6, const constant Scene* const tint_symbol_7) { + float visibility = 0.0f; + float const oneOverShadowDepthTextureSize = (1.0f / shadowDepthTextureSize); + for(int y = -1; (y <= 1); y = as_type((as_type(y) + as_type(1)))) { + for(int x = -1; (x <= 1); x = as_type((as_type(x) + as_type(1)))) { + float2 const offset = float2((float(x) * oneOverShadowDepthTextureSize), (float(y) * oneOverShadowDepthTextureSize)); + visibility = (visibility + tint_symbol_5.sample_compare(tint_symbol_6, (float3(input.shadowPos).xy + offset), (input.shadowPos[2] - 0.007f))); + } + } + visibility = (visibility / 9.0f); + float const lambertFactor = fmax(dot(normalize(((*(tint_symbol_7)).lightPos - input.fragPos)), input.fragNorm), 0.0f); + float const lightingFactor = fmin((ambientFactor + (visibility * lambertFactor)), 1.0f); + return float4((lightingFactor * albedo), 1.0f); +} + +fragment tint_symbol_3 tint_symbol(depth2d tint_symbol_8 [[texture(0)]], sampler tint_symbol_9 [[sampler(0)]], const constant Scene* tint_symbol_10 [[buffer(0)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) { + FragmentInput const tint_symbol_4 = {.shadowPos=tint_symbol_1.shadowPos, .fragPos=tint_symbol_1.fragPos, .fragNorm=tint_symbol_1.fragNorm}; + float4 const inner_result = tint_symbol_inner(tint_symbol_4, tint_symbol_8, tint_symbol_9, tint_symbol_10); + tint_symbol_3 wrapper_result = {}; + wrapper_result.value = inner_result; + return wrapper_result; +} + diff --git a/test/benchmark/shadow-fragment.wgsl.expected.spvasm b/test/benchmark/shadow-fragment.wgsl.expected.spvasm new file mode 100644 index 0000000000..d6b1d1fea1 --- /dev/null +++ b/test/benchmark/shadow-fragment.wgsl.expected.spvasm @@ -0,0 +1,203 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 121 +; Schema: 0 + OpCapability Shader + %92 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %shadowPos_1 %fragPos_1 %fragNorm_1 %value + OpExecutionMode %main OriginUpperLeft + OpName %shadowPos_1 "shadowPos_1" + OpName %fragPos_1 "fragPos_1" + OpName %fragNorm_1 "fragNorm_1" + OpName %value "value" + OpName %shadowDepthTextureSize "shadowDepthTextureSize" + OpName %Scene "Scene" + OpMemberName %Scene 0 "lightViewProjMatrix" + OpMemberName %Scene 1 "cameraViewProjMatrix" + OpMemberName %Scene 2 "lightPos" + OpName %scene "scene" + OpName %shadowMap "shadowMap" + OpName %shadowSampler "shadowSampler" + OpName %albedo "albedo" + OpName %ambientFactor "ambientFactor" + OpName %FragmentInput "FragmentInput" + OpMemberName %FragmentInput 0 "shadowPos" + OpMemberName %FragmentInput 1 "fragPos" + OpMemberName %FragmentInput 2 "fragNorm" + OpName %main_inner "main_inner" + OpName %input "input" + OpName %visibility "visibility" + OpName %y "y" + OpName %x "x" + OpName %main "main" + OpDecorate %shadowPos_1 Location 0 + OpDecorate %fragPos_1 Location 1 + OpDecorate %fragNorm_1 Location 2 + OpDecorate %value Location 0 + OpDecorate %Scene Block + OpMemberDecorate %Scene 0 Offset 0 + OpMemberDecorate %Scene 0 ColMajor + OpMemberDecorate %Scene 0 MatrixStride 16 + OpMemberDecorate %Scene 1 Offset 64 + OpMemberDecorate %Scene 1 ColMajor + OpMemberDecorate %Scene 1 MatrixStride 16 + OpMemberDecorate %Scene 2 Offset 128 + OpDecorate %scene NonWritable + OpDecorate %scene DescriptorSet 0 + OpDecorate %scene Binding 0 + OpDecorate %shadowMap DescriptorSet 0 + OpDecorate %shadowMap Binding 1 + OpDecorate %shadowSampler DescriptorSet 0 + OpDecorate %shadowSampler Binding 2 + OpMemberDecorate %FragmentInput 0 Offset 0 + OpMemberDecorate %FragmentInput 1 Offset 16 + OpMemberDecorate %FragmentInput 2 Offset 32 + %float = OpTypeFloat 32 + %v3float = OpTypeVector %float 3 +%_ptr_Input_v3float = OpTypePointer Input %v3float +%shadowPos_1 = OpVariable %_ptr_Input_v3float Input + %fragPos_1 = OpVariable %_ptr_Input_v3float Input + %fragNorm_1 = OpVariable %_ptr_Input_v3float Input + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %10 = OpConstantNull %v4float + %value = OpVariable %_ptr_Output_v4float Output %10 +%shadowDepthTextureSize = OpConstant %float 1024 +%mat4v4float = OpTypeMatrix %v4float 4 + %Scene = OpTypeStruct %mat4v4float %mat4v4float %v3float +%_ptr_Uniform_Scene = OpTypePointer Uniform %Scene + %scene = OpVariable %_ptr_Uniform_Scene Uniform + %18 = OpTypeImage %float 2D 1 0 0 1 Unknown +%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18 + %shadowMap = OpVariable %_ptr_UniformConstant_18 UniformConstant + %21 = OpTypeSampler +%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 +%shadowSampler = OpVariable %_ptr_UniformConstant_21 UniformConstant +%float_0_899999976 = OpConstant %float 0.899999976 + %albedo = OpConstantComposite %v3float %float_0_899999976 %float_0_899999976 %float_0_899999976 +%ambientFactor = OpConstant %float 0.200000003 +%FragmentInput = OpTypeStruct %v3float %v3float %v3float + %25 = OpTypeFunction %v4float %FragmentInput + %float_0 = OpConstant %float 0 +%_ptr_Function_float = OpTypePointer Function %float + %33 = OpConstantNull %float + %float_1 = OpConstant %float 1 + %int = OpTypeInt 32 1 + %int_n1 = OpConstant %int -1 +%_ptr_Function_int = OpTypePointer Function %int + %40 = OpConstantNull %int + %int_1 = OpConstant %int 1 + %bool = OpTypeBool + %v2float = OpTypeVector %float 2 + %74 = OpTypeSampledImage %18 +%float_0_00700000022 = OpConstant %float 0.00700000022 + %float_9 = OpConstant %float 9 + %uint = OpTypeInt 32 0 + %uint_2 = OpConstant %uint 2 +%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float + %void = OpTypeVoid + %112 = OpTypeFunction %void + %main_inner = OpFunction %v4float None %25 + %input = OpFunctionParameter %FragmentInput + %29 = OpLabel + %visibility = OpVariable %_ptr_Function_float Function %33 + %y = OpVariable %_ptr_Function_int Function %40 + %x = OpVariable %_ptr_Function_int Function %40 + OpStore %visibility %float_0 + %35 = OpFDiv %float %float_1 %shadowDepthTextureSize + OpStore %y %int_n1 + OpBranch %41 + %41 = OpLabel + OpLoopMerge %42 %43 None + OpBranch %44 + %44 = OpLabel + %46 = OpLoad %int %y + %48 = OpSLessThanEqual %bool %46 %int_1 + %45 = OpLogicalNot %bool %48 + OpSelectionMerge %50 None + OpBranchConditional %45 %51 %50 + %51 = OpLabel + OpBranch %42 + %50 = OpLabel + OpStore %x %int_n1 + OpBranch %53 + %53 = OpLabel + OpLoopMerge %54 %55 None + OpBranch %56 + %56 = OpLabel + %58 = OpLoad %int %x + %59 = OpSLessThanEqual %bool %58 %int_1 + %57 = OpLogicalNot %bool %59 + OpSelectionMerge %60 None + OpBranchConditional %57 %61 %60 + %61 = OpLabel + OpBranch %54 + %60 = OpLabel + %64 = OpLoad %int %x + %63 = OpConvertSToF %float %64 + %65 = OpFMul %float %63 %35 + %67 = OpLoad %int %y + %66 = OpConvertSToF %float %67 + %68 = OpFMul %float %66 %35 + %69 = OpCompositeConstruct %v2float %65 %68 + %70 = OpLoad %float %visibility + %72 = OpLoad %21 %shadowSampler + %73 = OpLoad %18 %shadowMap + %75 = OpSampledImage %74 %73 %72 + %76 = OpCompositeExtract %v3float %input 0 + %77 = OpVectorShuffle %v2float %76 %76 0 1 + %78 = OpFAdd %v2float %77 %69 + %79 = OpCompositeExtract %v3float %input 0 + %80 = OpCompositeExtract %float %79 2 + %82 = OpFSub %float %80 %float_0_00700000022 + %71 = OpImageSampleDrefImplicitLod %float %75 %78 %82 + %83 = OpFAdd %float %70 %71 + OpStore %visibility %83 + OpBranch %55 + %55 = OpLabel + %84 = OpLoad %int %x + %85 = OpIAdd %int %84 %int_1 + OpStore %x %85 + OpBranch %53 + %54 = OpLabel + OpBranch %43 + %43 = OpLabel + %86 = OpLoad %int %y + %87 = OpIAdd %int %86 %int_1 + OpStore %y %87 + OpBranch %41 + %42 = OpLabel + %88 = OpLoad %float %visibility + %90 = OpFDiv %float %88 %float_9 + OpStore %visibility %90 + %98 = OpAccessChain %_ptr_Uniform_v3float %scene %uint_2 + %99 = OpLoad %v3float %98 + %100 = OpCompositeExtract %v3float %input 1 + %101 = OpFSub %v3float %99 %100 + %94 = OpExtInst %v3float %92 Normalize %101 + %102 = OpCompositeExtract %v3float %input 2 + %93 = OpDot %float %94 %102 + %91 = OpExtInst %float %92 NMax %93 %float_0 + %104 = OpLoad %float %visibility + %105 = OpFMul %float %104 %91 + %106 = OpFAdd %float %ambientFactor %105 + %103 = OpExtInst %float %92 NMin %106 %float_1 + %107 = OpVectorTimesScalar %v3float %albedo %103 + %108 = OpCompositeExtract %float %107 0 + %109 = OpCompositeExtract %float %107 1 + %110 = OpCompositeExtract %float %107 2 + %111 = OpCompositeConstruct %v4float %108 %109 %110 %float_1 + OpReturnValue %111 + OpFunctionEnd + %main = OpFunction %void None %112 + %115 = OpLabel + %117 = OpLoad %v3float %shadowPos_1 + %118 = OpLoad %v3float %fragPos_1 + %119 = OpLoad %v3float %fragNorm_1 + %120 = OpCompositeConstruct %FragmentInput %117 %118 %119 + %116 = OpFunctionCall %v4float %main_inner %120 + OpStore %value %116 + OpReturn + OpFunctionEnd diff --git a/test/benchmark/shadow-fragment.wgsl.expected.wgsl b/test/benchmark/shadow-fragment.wgsl.expected.wgsl new file mode 100644 index 0000000000..e1a0b6ee6e --- /dev/null +++ b/test/benchmark/shadow-fragment.wgsl.expected.wgsl @@ -0,0 +1,42 @@ +let shadowDepthTextureSize : f32 = 1024.0; + +struct Scene { + lightViewProjMatrix : mat4x4; + cameraViewProjMatrix : mat4x4; + lightPos : vec3; +} + +@group(0) @binding(0) var scene : Scene; + +@group(0) @binding(1) var shadowMap : texture_depth_2d; + +@group(0) @binding(2) var shadowSampler : sampler_comparison; + +struct FragmentInput { + @location(0) + shadowPos : vec3; + @location(1) + fragPos : vec3; + @location(2) + fragNorm : vec3; +} + +let albedo : vec3 = vec3(0.899999976, 0.899999976, 0.899999976); + +let ambientFactor : f32 = 0.200000003; + +@stage(fragment) +fn main(input : FragmentInput) -> @location(0) vec4 { + var visibility : f32 = 0.0; + let oneOverShadowDepthTextureSize = (1.0 / shadowDepthTextureSize); + for(var y : i32 = -1; (y <= 1); y = (y + 1)) { + for(var x : i32 = -1; (x <= 1); x = (x + 1)) { + let offset : vec2 = vec2((f32(x) * oneOverShadowDepthTextureSize), (f32(y) * oneOverShadowDepthTextureSize)); + visibility = (visibility + textureSampleCompare(shadowMap, shadowSampler, (input.shadowPos.xy + offset), (input.shadowPos.z - 0.007))); + } + } + visibility = (visibility / 9.0); + let lambertFactor : f32 = max(dot(normalize((scene.lightPos - input.fragPos)), input.fragNorm), 0.0); + let lightingFactor : f32 = min((ambientFactor + (visibility * lambertFactor)), 1.0); + return vec4((lightingFactor * albedo), 1.0); +} diff --git a/test/benchmark/simple_compute.wgsl b/test/benchmark/simple-compute.wgsl similarity index 100% rename from test/benchmark/simple_compute.wgsl rename to test/benchmark/simple-compute.wgsl diff --git a/test/benchmark/simple-compute.wgsl.expected.glsl b/test/benchmark/simple-compute.wgsl.expected.glsl new file mode 100644 index 0000000000..cd8d2ea3d2 --- /dev/null +++ b/test/benchmark/simple-compute.wgsl.expected.glsl @@ -0,0 +1,28 @@ +#version 310 es +precision mediump float; + + +layout (binding = 0) buffer SB_1 { + int data[]; +} tint_symbol; + +struct tint_symbol_3 { + uvec3 id; +}; + +void tint_symbol_1_inner(uvec3 id) { + tint_symbol.data[id.x] = (tint_symbol.data[id.x] + 1); +} + +layout(local_size_x = 1, local_size_y = 2, local_size_z = 3) in; +void tint_symbol_1(tint_symbol_3 tint_symbol_2) { + tint_symbol_1_inner(tint_symbol_2.id); + return; +} +void main() { + tint_symbol_3 inputs; + inputs.id = gl_GlobalInvocationID; + tint_symbol_1(inputs); +} + + diff --git a/test/benchmark/simple_compute.wgsl.expected.hlsl b/test/benchmark/simple-compute.wgsl.expected.hlsl similarity index 100% rename from test/benchmark/simple_compute.wgsl.expected.hlsl rename to test/benchmark/simple-compute.wgsl.expected.hlsl diff --git a/test/benchmark/simple_compute.wgsl.expected.msl b/test/benchmark/simple-compute.wgsl.expected.msl similarity index 100% rename from test/benchmark/simple_compute.wgsl.expected.msl rename to test/benchmark/simple-compute.wgsl.expected.msl diff --git a/test/benchmark/simple_compute.wgsl.expected.spvasm b/test/benchmark/simple-compute.wgsl.expected.spvasm similarity index 100% rename from test/benchmark/simple_compute.wgsl.expected.spvasm rename to test/benchmark/simple-compute.wgsl.expected.spvasm diff --git a/test/benchmark/simple_compute.wgsl.expected.wgsl b/test/benchmark/simple-compute.wgsl.expected.wgsl similarity index 100% rename from test/benchmark/simple_compute.wgsl.expected.wgsl rename to test/benchmark/simple-compute.wgsl.expected.wgsl diff --git a/test/benchmark/simple_fragment.wgsl b/test/benchmark/simple-fragment.wgsl similarity index 100% rename from test/benchmark/simple_fragment.wgsl rename to test/benchmark/simple-fragment.wgsl diff --git a/test/benchmark/simple-fragment.wgsl.expected.glsl b/test/benchmark/simple-fragment.wgsl.expected.glsl new file mode 100644 index 0000000000..af5753a03b --- /dev/null +++ b/test/benchmark/simple-fragment.wgsl.expected.glsl @@ -0,0 +1,47 @@ +SKIP: FAILED + +#version 310 es +precision mediump float; + +struct Input { + vec4 color; +}; +struct Output { + vec4 color; +}; +struct tint_symbol_3 { + vec4 color; +}; +struct tint_symbol_4 { + vec4 color; +}; + +Output tint_symbol_inner(Input tint_symbol_1) { + Output tint_symbol_5 = Output(tint_symbol_1.color); + return tint_symbol_5; +} + +tint_symbol_4 tint_symbol(tint_symbol_3 tint_symbol_2) { + Input tint_symbol_6 = Input(tint_symbol_2.color); + Output inner_result = tint_symbol_inner(tint_symbol_6); + tint_symbol_4 wrapper_result = tint_symbol_4(vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.color = inner_result.color; + return wrapper_result; +} +in vec4 color; +out vec4 color; +void main() { + tint_symbol_3 inputs; + inputs.color = color; + tint_symbol_4 outputs; + outputs = tint_symbol(inputs); + color = outputs.color; +} + + +Error parsing GLSL shader: +ERROR: 0:30: 'color' : redefinition +ERROR: 1 compilation errors. No code generated. + + + diff --git a/test/benchmark/simple_fragment.wgsl.expected.hlsl b/test/benchmark/simple-fragment.wgsl.expected.hlsl similarity index 100% rename from test/benchmark/simple_fragment.wgsl.expected.hlsl rename to test/benchmark/simple-fragment.wgsl.expected.hlsl diff --git a/test/benchmark/simple_fragment.wgsl.expected.msl b/test/benchmark/simple-fragment.wgsl.expected.msl similarity index 100% rename from test/benchmark/simple_fragment.wgsl.expected.msl rename to test/benchmark/simple-fragment.wgsl.expected.msl diff --git a/test/benchmark/simple_fragment.wgsl.expected.spvasm b/test/benchmark/simple-fragment.wgsl.expected.spvasm similarity index 100% rename from test/benchmark/simple_fragment.wgsl.expected.spvasm rename to test/benchmark/simple-fragment.wgsl.expected.spvasm diff --git a/test/benchmark/simple_fragment.wgsl.expected.wgsl b/test/benchmark/simple-fragment.wgsl.expected.wgsl similarity index 100% rename from test/benchmark/simple_fragment.wgsl.expected.wgsl rename to test/benchmark/simple-fragment.wgsl.expected.wgsl diff --git a/test/benchmark/simple_vertex.wgsl b/test/benchmark/simple-vertex.wgsl similarity index 100% rename from test/benchmark/simple_vertex.wgsl rename to test/benchmark/simple-vertex.wgsl diff --git a/test/benchmark/simple-vertex.wgsl.expected.glsl b/test/benchmark/simple-vertex.wgsl.expected.glsl new file mode 100644 index 0000000000..a870df43e1 --- /dev/null +++ b/test/benchmark/simple-vertex.wgsl.expected.glsl @@ -0,0 +1,39 @@ +#version 310 es +precision mediump float; + +struct Input { + vec4 position; +}; +struct Output { + vec4 position; +}; +struct tint_symbol_3 { + vec4 position; +}; +struct tint_symbol_4 { + vec4 position; +}; + +Output tint_symbol_inner(Input tint_symbol_1) { + Output tint_symbol_5 = Output(tint_symbol_1.position); + return tint_symbol_5; +} + +tint_symbol_4 tint_symbol(tint_symbol_3 tint_symbol_2) { + Input tint_symbol_6 = Input(tint_symbol_2.position); + Output inner_result = tint_symbol_inner(tint_symbol_6); + tint_symbol_4 wrapper_result = tint_symbol_4(vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.position = inner_result.position; + return wrapper_result; +} +in vec4 position; +void main() { + tint_symbol_3 inputs; + inputs.position = position; + tint_symbol_4 outputs; + outputs = tint_symbol(inputs); + gl_Position = outputs.position; + gl_Position.y = -gl_Position.y; +} + + diff --git a/test/benchmark/simple_vertex.wgsl.expected.hlsl b/test/benchmark/simple-vertex.wgsl.expected.hlsl similarity index 100% rename from test/benchmark/simple_vertex.wgsl.expected.hlsl rename to test/benchmark/simple-vertex.wgsl.expected.hlsl diff --git a/test/benchmark/simple_vertex.wgsl.expected.msl b/test/benchmark/simple-vertex.wgsl.expected.msl similarity index 100% rename from test/benchmark/simple_vertex.wgsl.expected.msl rename to test/benchmark/simple-vertex.wgsl.expected.msl diff --git a/test/benchmark/simple_vertex.wgsl.expected.spvasm b/test/benchmark/simple-vertex.wgsl.expected.spvasm similarity index 100% rename from test/benchmark/simple_vertex.wgsl.expected.spvasm rename to test/benchmark/simple-vertex.wgsl.expected.spvasm diff --git a/test/benchmark/simple_vertex.wgsl.expected.wgsl b/test/benchmark/simple-vertex.wgsl.expected.wgsl similarity index 100% rename from test/benchmark/simple_vertex.wgsl.expected.wgsl rename to test/benchmark/simple-vertex.wgsl.expected.wgsl diff --git a/test/benchmark/skinned-shadowed-pbr-fragment.wgsl b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl new file mode 100644 index 0000000000..4021327e26 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl @@ -0,0 +1,368 @@ +let GAMMA = 2.200000048; + +fn linearTosRGB(linear : vec3) -> vec3 { + let INV_GAMMA = (1.0 / GAMMA); + return pow(linear, vec3(INV_GAMMA)); +} + +fn sRGBToLinear(srgb : vec3) -> vec3 { + return pow(srgb, vec3(GAMMA)); +} + +struct Camera { + projection : mat4x4; + inverseProjection : mat4x4; + view : mat4x4; + position : vec3; + time : f32; + outputSize : vec2; + zNear : f32; + zFar : f32; +} + +@binding(0) @group(0) var camera : Camera; + +struct ClusterLights { + offset : u32; + count : u32; +} + +struct ClusterLightGroup { + offset : u32; + lights : array; + indices : array; +} + +@binding(1) @group(0) var clusterLights : ClusterLightGroup; + +struct Light { + position : vec3; + range : f32; + color : vec3; + intensity : f32; +} + +struct GlobalLights { + ambient : vec3; + dirColor : vec3; + dirIntensity : f32; + dirDirection : vec3; + lightCount : u32; + lights : @stride(32) array; +} + +@binding(2) @group(0) var globalLights : GlobalLights; + +let tileCount = vec3(32u, 18u, 48u); + +fn linearDepth(depthSample : f32) -> f32 { + return ((camera.zFar * camera.zNear) / fma(depthSample, (camera.zNear - camera.zFar), camera.zFar)); +} + +fn getTile(fragCoord : vec4) -> vec3 { + let sliceScale = (f32(tileCount.z) / log2((camera.zFar / camera.zNear))); + let sliceBias = -(((f32(tileCount.z) * log2(camera.zNear)) / log2((camera.zFar / camera.zNear)))); + let zTile = u32(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0)); + return vec3(u32((fragCoord.x / (camera.outputSize.x / f32(tileCount.x)))), u32((fragCoord.y / (camera.outputSize.y / f32(tileCount.y)))), zTile); +} + +fn getClusterIndex(fragCoord : vec4) -> u32 { + let tile = getTile(fragCoord); + return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y)); +} + +@binding(3) @group(0) var defaultSampler : sampler; + +@binding(4) @group(0) var shadowTexture : texture_depth_2d; + +@binding(5) @group(0) var shadowSampler : sampler_comparison; + +struct LightShadowTable { + light : array; +} + +@binding(6) @group(0) var lightShadowTable : LightShadowTable; + +var shadowSampleOffsets : array, 16> = array, 16>(vec2(-1.5, -1.5), vec2(-1.5, -0.5), vec2(-1.5, 0.5), vec2(-1.5, 1.5), vec2(-0.5, -1.5), vec2(-0.5, -0.5), vec2(-0.5, 0.5), vec2(-0.5, 1.5), vec2(0.5, -1.5), vec2(0.5, -0.5), vec2(0.5, 0.5), vec2(0.5, 1.5), vec2(1.5, -1.5), vec2(1.5, -0.5), vec2(1.5, 0.5), vec2(1.5, 1.5)); + +let shadowSampleCount = 16u; + +struct ShadowProperties { + viewport : vec4; + viewProj : mat4x4; +} + +struct LightShadows { + properties : array; +} + +@binding(7) @group(0) var shadow : LightShadows; + +fn dirLightVisibility(worldPos : vec3) -> f32 { + let shadowIndex = lightShadowTable.light[0u]; + if ((shadowIndex == -1)) { + return 1.0; + } + let viewport = shadow.properties[shadowIndex].viewport; + let lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0)); + let shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5, -0.5)) + vec2(0.5, 0.5)), (lightPos.z / lightPos.w)); + let viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw))); + let texelSize = (1.0 / vec2(textureDimensions(shadowTexture, 0))); + let clampRect = vec4((viewport.xy - texelSize), ((viewport.xy + viewport.zw) + texelSize)); + var visibility = 0.0; + for(var i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + textureSampleCompareLevel(shadowTexture, shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.003))); + } + return (visibility / f32(shadowSampleCount)); +} + +fn getCubeFace(v : vec3) -> i32 { + let vAbs = abs(v); + if (((vAbs.z >= vAbs.x) && (vAbs.z >= vAbs.y))) { + if ((v.z < 0.0)) { + return 5; + } + return 4; + } + if ((vAbs.y >= vAbs.x)) { + if ((v.y < 0.0)) { + return 3; + } + return 2; + } + if ((v.x < 0.0)) { + return 1; + } + return 0; +} + +fn pointLightVisibility(lightIndex : u32, worldPos : vec3, pointToLight : vec3) -> f32 { + var shadowIndex = lightShadowTable.light[(lightIndex + 1u)]; + if ((shadowIndex == -1)) { + return 1.0; + } + shadowIndex = (shadowIndex + getCubeFace((pointToLight * -1.0))); + let viewport = shadow.properties[shadowIndex].viewport; + let lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0)); + let shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5, -0.5)) + vec2(0.5, 0.5)), (lightPos.z / lightPos.w)); + let viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw))); + let texelSize = (1.0 / vec2(textureDimensions(shadowTexture, 0))); + let clampRect = vec4(viewport.xy, (viewport.xy + viewport.zw)); + var visibility = 0.0; + for(var i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + textureSampleCompareLevel(shadowTexture, shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.01))); + } + return (visibility / f32(shadowSampleCount)); +} + +struct VertexOutput { + @builtin(position) + position : vec4; + @location(0) + worldPos : vec3; + @location(1) + view : vec3; + @location(2) + texcoord : vec2; + @location(3) + texcoord2 : vec2; + @location(4) + color : vec4; + @location(5) + instanceColor : vec4; + @location(6) + normal : vec3; + @location(7) + tangent : vec3; + @location(8) + bitangent : vec3; +} + +struct Material { + baseColorFactor : vec4; + emissiveFactor : vec3; + occlusionStrength : f32; + metallicRoughnessFactor : vec2; + alphaCutoff : f32; +} + +@binding(8) @group(0) var material : Material; + +@binding(9) @group(0) var baseColorTexture : texture_2d; + +@binding(10) @group(0) var baseColorSampler : sampler; + +@binding(11) @group(0) var normalTexture : texture_2d; + +@binding(12) @group(0) var normalSampler : sampler; + +@binding(13) @group(0) var metallicRoughnessTexture : texture_2d; + +@binding(14) @group(0) var metallicRoughnessSampler : sampler; + +@binding(15) @group(0) var occlusionTexture : texture_2d; + +@binding(16) @group(0) var occlusionSampler : sampler; + +@binding(17) @group(0) var emissiveTexture : texture_2d; + +@binding(18) @group(0) var emissiveSampler : sampler; + +struct SurfaceInfo { + baseColor : vec4; + albedo : vec3; + metallic : f32; + roughness : f32; + normal : vec3; + f0 : vec3; + ao : f32; + emissive : vec3; + v : vec3; +} + +fn GetSurfaceInfo(input : VertexOutput) -> SurfaceInfo { + var surface : SurfaceInfo; + surface.v = normalize(input.view); + let tbn = mat3x3(input.tangent, input.bitangent, input.normal); + let normalMap = textureSample(normalTexture, normalSampler, input.texcoord).rgb; + surface.normal = normalize((tbn * ((2.0 * normalMap) - vec3(1.0)))); + let baseColorMap = textureSample(baseColorTexture, baseColorSampler, input.texcoord); + surface.baseColor = ((input.color * material.baseColorFactor) * baseColorMap); + if ((surface.baseColor.a < material.alphaCutoff)) { + discard; + } + surface.albedo = surface.baseColor.rgb; + let metallicRoughnessMap = textureSample(metallicRoughnessTexture, metallicRoughnessSampler, input.texcoord); + surface.metallic = (material.metallicRoughnessFactor.x * metallicRoughnessMap.b); + surface.roughness = (material.metallicRoughnessFactor.y * metallicRoughnessMap.g); + let dielectricSpec = vec3(0.039999999); + surface.f0 = mix(dielectricSpec, surface.albedo, vec3(surface.metallic)); + let occlusionMap = textureSample(occlusionTexture, occlusionSampler, input.texcoord); + surface.ao = (material.occlusionStrength * occlusionMap.r); + let emissiveMap = textureSample(emissiveTexture, emissiveSampler, input.texcoord); + surface.emissive = (material.emissiveFactor * emissiveMap.rgb); + if ((input.instanceColor.a == 0.0)) { + surface.albedo = (surface.albedo + input.instanceColor.rgb); + } else { + surface.albedo = (surface.albedo * input.instanceColor.rgb); + } + return surface; +} + +let PI = 3.141592741; + +let LightType_Point = 0u; + +let LightType_Spot = 1u; + +let LightType_Directional = 2u; + +struct PuctualLight { + lightType : u32; + pointToLight : vec3; + range : f32; + color : vec3; + intensity : f32; +} + +fn FresnelSchlick(cosTheta : f32, F0 : vec3) -> vec3 { + return (F0 + ((vec3(1.0) - F0) * pow((1.0 - cosTheta), 5.0))); +} + +fn DistributionGGX(N : vec3, H : vec3, roughness : f32) -> f32 { + let a = (roughness * roughness); + let a2 = (a * a); + let NdotH = max(dot(N, H), 0.0); + let NdotH2 = (NdotH * NdotH); + let num = a2; + let denom = ((NdotH2 * (a2 - 1.0)) + 1.0); + return (num / ((PI * denom) * denom)); +} + +fn GeometrySchlickGGX(NdotV : f32, roughness : f32) -> f32 { + let r = (roughness + 1.0); + let k = ((r * r) / 8.0); + let num = NdotV; + let denom = ((NdotV * (1.0 - k)) + k); + return (num / denom); +} + +fn GeometrySmith(N : vec3, V : vec3, L : vec3, roughness : f32) -> f32 { + let NdotV = max(dot(N, V), 0.0); + let NdotL = max(dot(N, L), 0.0); + let ggx2 = GeometrySchlickGGX(NdotV, roughness); + let ggx1 = GeometrySchlickGGX(NdotL, roughness); + return (ggx1 * ggx2); +} + +fn lightAttenuation(light : PuctualLight) -> f32 { + if ((light.lightType == LightType_Directional)) { + return 1.0; + } + let distance = length(light.pointToLight); + if ((light.range <= 0.0)) { + return (1.0 / pow(distance, 2.0)); + } + return (clamp((1.0 - pow((distance / light.range), 4.0)), 0.0, 1.0) / pow(distance, 2.0)); +} + +fn lightRadiance(light : PuctualLight, surface : SurfaceInfo) -> vec3 { + let L = normalize(light.pointToLight); + let H = normalize((surface.v + L)); + let NDF = DistributionGGX(surface.normal, H, surface.roughness); + let G = GeometrySmith(surface.normal, surface.v, L, surface.roughness); + let F = FresnelSchlick(max(dot(H, surface.v), 0.0), surface.f0); + let kD = ((vec3(1.0) - F) * (1.0 - surface.metallic)); + let NdotL = max(dot(surface.normal, L), 0.0); + let numerator = ((NDF * G) * F); + let denominator = max(((4.0 * max(dot(surface.normal, surface.v), 0.0)) * NdotL), 0.001); + let specular = (numerator / vec3(denominator)); + let radiance = ((light.color * light.intensity) * lightAttenuation(light)); + return (((((kD * surface.albedo) / vec3(PI)) + specular) * radiance) * NdotL); +} + +@binding(19) @group(0) var ssaoTexture : texture_2d; + +struct FragmentOutput { + @location(0) + color : vec4; + @location(1) + emissive : vec4; +} + +@stage(fragment) +fn fragmentMain(input : VertexOutput) -> FragmentOutput { + let surface = GetSurfaceInfo(input); + var Lo = vec3(0.0, 0.0, 0.0); + if ((globalLights.dirIntensity > 0.0)) { + var light : PuctualLight; + light.lightType = LightType_Directional; + light.pointToLight = globalLights.dirDirection; + light.color = globalLights.dirColor; + light.intensity = globalLights.dirIntensity; + let lightVis = dirLightVisibility(input.worldPos); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + let clusterIndex = getClusterIndex(input.position); + let lightOffset = clusterLights.lights[clusterIndex].offset; + let lightCount = clusterLights.lights[clusterIndex].count; + for(var lightIndex = 0u; (lightIndex < lightCount); lightIndex = (lightIndex + 1u)) { + let i = clusterLights.indices[(lightOffset + lightIndex)]; + var light : PuctualLight; + light.lightType = LightType_Point; + light.pointToLight = (globalLights.lights[i].position.xyz - input.worldPos); + light.range = globalLights.lights[i].range; + light.color = globalLights.lights[i].color; + light.intensity = globalLights.lights[i].intensity; + let lightVis = pointLightVisibility(i, input.worldPos, light.pointToLight); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + let ssaoCoord = (input.position.xy / vec2(textureDimensions(ssaoTexture).xy)); + let ssaoFactor = textureSample(ssaoTexture, defaultSampler, ssaoCoord).r; + let ambient = (((globalLights.ambient * surface.albedo) * surface.ao) * ssaoFactor); + let color = linearTosRGB(((Lo + ambient) + surface.emissive)); + var out : FragmentOutput; + out.color = vec4(color, surface.baseColor.a); + out.emissive = vec4(surface.emissive, surface.baseColor.a); + return out; +} diff --git a/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.glsl b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.glsl new file mode 100644 index 0000000000..fe680445d3 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.glsl @@ -0,0 +1,424 @@ +SKIP: FAILED + +benchmark/skinned-shadowed-pbr-fragment.wgsl:51:13 warning: use of deprecated language feature: the @stride attribute is deprecated; use a larger type if necessary + lights : @stride(32) array; + ^^^^^^ + +#version 310 es +precision mediump float; + +const float GAMMA = 2.200000048f; + +vec3 linearTosRGB(vec3 linear) { + float INV_GAMMA = (1.0f / GAMMA); + return pow(linear, vec3(INV_GAMMA)); +} + +struct Camera { + mat4 projection; + mat4 inverseProjection; + mat4 view; + vec3 position; + float time; + vec2 outputSize; + float zNear; + float zFar; +}; + +layout (binding = 0) uniform Camera_1 { + mat4 projection; + mat4 inverseProjection; + mat4 view; + vec3 position; + float time; + vec2 outputSize; + float zNear; + float zFar; +} camera; + +struct ClusterLights { + uint offset; + uint count; +}; +struct ClusterLightGroup { + uint offset; + ClusterLights lights[27648]; + uint indices[1769472]; +}; + +layout (binding = 1) buffer ClusterLightGroup_1 { + uint offset; + ClusterLights lights[27648]; + uint indices[1769472]; +} clusterLights; + +struct Light { + vec3 position; + float range; + vec3 color; + float intensity; +}; + +layout (binding = 2) buffer GlobalLights_1 { + vec3 ambient; + vec3 dirColor; + float dirIntensity; + vec3 dirDirection; + uint lightCount; + Light lights[]; +} globalLights; +const uvec3 tileCount = uvec3(32u, 18u, 48u); + +float linearDepth(float depthSample) { + return ((camera.zFar * camera.zNear) / mad(depthSample, (camera.zNear - camera.zFar), camera.zFar)); +} + +uvec3 getTile(vec4 fragCoord) { + float sliceScale = (float(tileCount.z) / log2((camera.zFar / camera.zNear))); + float sliceBias = -(((float(tileCount.z) * log2(camera.zNear)) / log2((camera.zFar / camera.zNear)))); + uint zTile = uint(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0f)); + return uvec3(uint((fragCoord.x / (camera.outputSize.x / float(tileCount.x)))), uint((fragCoord.y / (camera.outputSize.y / float(tileCount.y)))), zTile); +} + +uint getClusterIndex(vec4 fragCoord) { + uvec3 tile = getTile(fragCoord); + return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y)); +} + + +uniform highp sampler2D shadowTexture; + + +layout (binding = 6) buffer LightShadowTable_1 { + int light[]; +} lightShadowTable; +vec2 shadowSampleOffsets[16] = vec2[16](vec2(-1.5f, -1.5f), vec2(-1.5f, -0.5f), vec2(-1.5f, 0.5f), vec2(-1.5f, 1.5f), vec2(-0.5f, -1.5f), vec2(-0.5f, -0.5f), vec2(-0.5f, 0.5f), vec2(-0.5f, 1.5f), vec2(0.5f, -1.5f), vec2(0.5f, -0.5f), vec2(0.5f, 0.5f), vec2(0.5f, 1.5f), vec2(1.5f, -1.5f), vec2(1.5f, -0.5f), vec2(1.5f, 0.5f), vec2(1.5f, 1.5f)); +const uint shadowSampleCount = 16u; + +struct ShadowProperties { + vec4 viewport; + mat4 viewProj; +}; + +layout (binding = 7) buffer LightShadows_1 { + ShadowProperties properties[]; +} shadow; + +float dirLightVisibility(vec3 worldPos) { + int shadowIndex = lightShadowTable.light[0u]; + if ((shadowIndex == -1)) { + return 1.0f; + } + vec4 viewport = shadow.properties[shadowIndex].viewport; + vec4 lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0f)); + vec3 shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5f, -0.5f)) + vec2(0.5f, 0.5f)), (lightPos.z / lightPos.w)); + vec2 viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw))); + vec2 texelSize = (1.0f / vec2(textureSize(shadowTexture, 0))); + vec4 clampRect = vec4((viewport.xy - texelSize), ((viewport.xy + viewport.zw) + texelSize)); + float visibility = 0.0f; + { + for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + texture(shadowTexture, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.003f))); + } + } + return (visibility / float(shadowSampleCount)); +} + +int getCubeFace(vec3 v) { + vec3 vAbs = abs(v); + bool tint_tmp = (vAbs.z >= vAbs.x); + if (tint_tmp) { + tint_tmp = (vAbs.z >= vAbs.y); + } + if ((tint_tmp)) { + if ((v.z < 0.0f)) { + return 5; + } + return 4; + } + if ((vAbs.y >= vAbs.x)) { + if ((v.y < 0.0f)) { + return 3; + } + return 2; + } + if ((v.x < 0.0f)) { + return 1; + } + return 0; +} + +float pointLightVisibility(uint lightIndex, vec3 worldPos, vec3 pointToLight) { + int shadowIndex = lightShadowTable.light[(lightIndex + 1u)]; + if ((shadowIndex == -1)) { + return 1.0f; + } + shadowIndex = (shadowIndex + getCubeFace((pointToLight * -1.0f))); + vec4 viewport = shadow.properties[shadowIndex].viewport; + vec4 lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0f)); + vec3 shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5f, -0.5f)) + vec2(0.5f, 0.5f)), (lightPos.z / lightPos.w)); + vec2 viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw))); + vec2 texelSize = (1.0f / vec2(textureSize(shadowTexture, 0))); + vec4 clampRect = vec4(viewport.xy, (viewport.xy + viewport.zw)); + float visibility = 0.0f; + { + for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + texture(shadowTexture, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.01f))); + } + } + return (visibility / float(shadowSampleCount)); +} + +struct VertexOutput { + vec4 position; + vec3 worldPos; + vec3 view; + vec2 texcoord; + vec2 texcoord2; + vec4 color; + vec4 instanceColor; + vec3 normal; + vec3 tangent; + vec3 bitangent; +}; +struct Material { + vec4 baseColorFactor; + vec3 emissiveFactor; + float occlusionStrength; + vec2 metallicRoughnessFactor; + float alphaCutoff; +}; + +layout (binding = 8) uniform Material_1 { + vec4 baseColorFactor; + vec3 emissiveFactor; + float occlusionStrength; + vec2 metallicRoughnessFactor; + float alphaCutoff; +} material; +uniform highp sampler2D baseColorTexture; + +uniform highp sampler2D normalTexture; + +uniform highp sampler2D metallicRoughnessTexture; + +uniform highp sampler2D occlusionTexture; + +uniform highp sampler2D emissiveTexture; + + +struct SurfaceInfo { + vec4 baseColor; + vec3 albedo; + float metallic; + float roughness; + vec3 normal; + vec3 f0; + float ao; + vec3 emissive; + vec3 v; +}; + +SurfaceInfo GetSurfaceInfo(VertexOutput tint_symbol) { + SurfaceInfo surface = SurfaceInfo(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), 0.0f, 0.0f, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), 0.0f, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)); + surface.v = normalize(tint_symbol.view); + mat3 tbn = mat3(tint_symbol.tangent, tint_symbol.bitangent, tint_symbol.normal); + vec3 normalMap = texture(normalTexture, tint_symbol.texcoord).rgb; + surface.normal = normalize((tbn * ((2.0f * normalMap) - vec3(1.0f)))); + vec4 baseColorMap = texture(baseColorTexture, tint_symbol.texcoord); + surface.baseColor = ((tint_symbol.color * material.baseColorFactor) * baseColorMap); + if ((surface.baseColor.a < material.alphaCutoff)) { + discard; + } + surface.albedo = surface.baseColor.rgb; + vec4 metallicRoughnessMap = texture(metallicRoughnessTexture, tint_symbol.texcoord); + surface.metallic = (material.metallicRoughnessFactor.x * metallicRoughnessMap.b); + surface.roughness = (material.metallicRoughnessFactor.y * metallicRoughnessMap.g); + vec3 dielectricSpec = vec3(0.039999999f); + surface.f0 = mix(dielectricSpec, surface.albedo, vec3(surface.metallic)); + vec4 occlusionMap = texture(occlusionTexture, tint_symbol.texcoord); + surface.ao = (material.occlusionStrength * occlusionMap.r); + vec4 emissiveMap = texture(emissiveTexture, tint_symbol.texcoord); + surface.emissive = (material.emissiveFactor * emissiveMap.rgb); + if ((tint_symbol.instanceColor.a == 0.0f)) { + surface.albedo = (surface.albedo + tint_symbol.instanceColor.rgb); + } else { + surface.albedo = (surface.albedo * tint_symbol.instanceColor.rgb); + } + return surface; +} + +const float PI = 3.141592741f; +const uint LightType_Point = 0u; +const uint LightType_Directional = 2u; + +struct PuctualLight { + uint lightType; + vec3 pointToLight; + float range; + vec3 color; + float intensity; +}; + +vec3 FresnelSchlick(float cosTheta, vec3 F0) { + return (F0 + ((vec3(1.0f) - F0) * pow((1.0f - cosTheta), 5.0f))); +} + +float DistributionGGX(vec3 N, vec3 H, float roughness) { + float a_1 = (roughness * roughness); + float a2 = (a_1 * a_1); + float NdotH = max(dot(N, H), 0.0f); + float NdotH2 = (NdotH * NdotH); + float num = a2; + float denom = ((NdotH2 * (a2 - 1.0f)) + 1.0f); + return (num / ((PI * denom) * denom)); +} + +float GeometrySchlickGGX(float NdotV, float roughness) { + float r_1 = (roughness + 1.0f); + float k = ((r_1 * r_1) / 8.0f); + float num = NdotV; + float denom = ((NdotV * (1.0f - k)) + k); + return (num / denom); +} + +float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) { + float NdotV = max(dot(N, V), 0.0f); + float NdotL = max(dot(N, L), 0.0f); + float ggx2 = GeometrySchlickGGX(NdotV, roughness); + float ggx1 = GeometrySchlickGGX(NdotL, roughness); + return (ggx1 * ggx2); +} + +float lightAttenuation(PuctualLight light) { + if ((light.lightType == LightType_Directional)) { + return 1.0f; + } + float tint_symbol_1 = length(light.pointToLight); + if ((light.range <= 0.0f)) { + return (1.0f / pow(tint_symbol_1, 2.0f)); + } + return (clamp((1.0f - pow((tint_symbol_1 / light.range), 4.0f)), 0.0f, 1.0f) / pow(tint_symbol_1, 2.0f)); +} + +vec3 lightRadiance(PuctualLight light, SurfaceInfo surface) { + vec3 L = normalize(light.pointToLight); + vec3 H = normalize((surface.v + L)); + float NDF = DistributionGGX(surface.normal, H, surface.roughness); + float G = GeometrySmith(surface.normal, surface.v, L, surface.roughness); + vec3 F = FresnelSchlick(max(dot(H, surface.v), 0.0f), surface.f0); + vec3 kD = ((vec3(1.0f) - F) * (1.0f - surface.metallic)); + float NdotL = max(dot(surface.normal, L), 0.0f); + vec3 numerator = ((NDF * G) * F); + float denominator = max(((4.0f * max(dot(surface.normal, surface.v), 0.0f)) * NdotL), 0.001f); + vec3 specular = (numerator / vec3(denominator)); + vec3 radiance = ((light.color * light.intensity) * lightAttenuation(light)); + return (((((kD * surface.albedo) / vec3(PI)) + specular) * radiance) * NdotL); +} + +uniform highp sampler2D ssaoTexture; + +struct FragmentOutput { + vec4 color; + vec4 emissive; +}; +struct tint_symbol_4 { + vec3 worldPos; + vec3 view; + vec2 texcoord; + vec2 texcoord2; + vec4 color; + vec4 instanceColor; + vec3 normal; + vec3 tangent; + vec3 bitangent; + vec4 position; +}; +struct tint_symbol_5 { + vec4 color; + vec4 emissive; +}; + +FragmentOutput fragmentMain_inner(VertexOutput tint_symbol) { + SurfaceInfo surface = GetSurfaceInfo(tint_symbol); + vec3 Lo = vec3(0.0f, 0.0f, 0.0f); + if ((globalLights.dirIntensity > 0.0f)) { + PuctualLight light = PuctualLight(0u, vec3(0.0f, 0.0f, 0.0f), 0.0f, vec3(0.0f, 0.0f, 0.0f), 0.0f); + light.lightType = LightType_Directional; + light.pointToLight = globalLights.dirDirection; + light.color = globalLights.dirColor; + light.intensity = globalLights.dirIntensity; + float lightVis = dirLightVisibility(tint_symbol.worldPos); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + uint clusterIndex = getClusterIndex(tint_symbol.position); + uint lightOffset = clusterLights.lights[clusterIndex].offset; + uint lightCount = clusterLights.lights[clusterIndex].count; + { + for(uint lightIndex = 0u; (lightIndex < lightCount); lightIndex = (lightIndex + 1u)) { + uint i = clusterLights.indices[(lightOffset + lightIndex)]; + PuctualLight light = PuctualLight(0u, vec3(0.0f, 0.0f, 0.0f), 0.0f, vec3(0.0f, 0.0f, 0.0f), 0.0f); + light.lightType = LightType_Point; + light.pointToLight = (globalLights.lights[i].position.xyz - tint_symbol.worldPos); + light.range = globalLights.lights[i].range; + light.color = globalLights.lights[i].color; + light.intensity = globalLights.lights[i].intensity; + float lightVis = pointLightVisibility(i, tint_symbol.worldPos, light.pointToLight); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + } + vec2 ssaoCoord = (tint_symbol.position.xy / vec2(textureSize(ssaoTexture, 0).xy)); + float ssaoFactor = texture(ssaoTexture, ssaoCoord).r; + vec3 ambient = (((globalLights.ambient * surface.albedo) * surface.ao) * ssaoFactor); + vec3 color = linearTosRGB(((Lo + ambient) + surface.emissive)); + FragmentOutput tint_symbol_2 = FragmentOutput(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f)); + tint_symbol_2.color = vec4(color, surface.baseColor.a); + tint_symbol_2.emissive = vec4(surface.emissive, surface.baseColor.a); + return tint_symbol_2; +} + +tint_symbol_5 fragmentMain(tint_symbol_4 tint_symbol_3) { + VertexOutput tint_symbol_6 = VertexOutput(tint_symbol_3.position, tint_symbol_3.worldPos, tint_symbol_3.view, tint_symbol_3.texcoord, tint_symbol_3.texcoord2, tint_symbol_3.color, tint_symbol_3.instanceColor, tint_symbol_3.normal, tint_symbol_3.tangent, tint_symbol_3.bitangent); + FragmentOutput inner_result = fragmentMain_inner(tint_symbol_6); + tint_symbol_5 wrapper_result = tint_symbol_5(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.color = inner_result.color; + wrapper_result.emissive = inner_result.emissive; + return wrapper_result; +} +in vec3 worldPos; +in vec3 view; +in vec2 texcoord; +in vec2 texcoord2; +in vec4 color; +in vec4 instanceColor; +in vec3 normal; +in vec3 tangent; +in vec3 bitangent; +out vec4 color; +out vec4 emissive; +void main() { + tint_symbol_4 inputs; + inputs.worldPos = worldPos; + inputs.view = view; + inputs.texcoord = texcoord; + inputs.texcoord2 = texcoord2; + inputs.color = color; + inputs.instanceColor = instanceColor; + inputs.normal = normal; + inputs.tangent = tangent; + inputs.bitangent = bitangent; + inputs.position = gl_FragCoord; + tint_symbol_5 outputs; + outputs = fragmentMain(inputs); + color = outputs.color; + emissive = outputs.emissive; +} + + +Error parsing GLSL shader: +ERROR: 0:67: 'mad' : no matching overloaded function found +ERROR: 0:67: '' : compilation terminated +ERROR: 2 compilation errors. No code generated. + + + diff --git a/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.hlsl b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.hlsl new file mode 100644 index 0000000000..53858888f1 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.hlsl @@ -0,0 +1,335 @@ +benchmark/skinned-shadowed-pbr-fragment.wgsl:51:13 warning: use of deprecated language feature: the @stride attribute is deprecated; use a larger type if necessary + lights : @stride(32) array; + ^^^^^^ + +static const float GAMMA = 2.200000048f; + +float3 linearTosRGB(float3 tint_symbol) { + const float INV_GAMMA = (1.0f / GAMMA); + return pow(tint_symbol, float3((INV_GAMMA).xxx)); +} + +float3 sRGBToLinear(float3 srgb) { + return pow(srgb, float3((GAMMA).xxx)); +} + +cbuffer cbuffer_camera : register(b0, space0) { + uint4 camera[14]; +}; + +ByteAddressBuffer clusterLights : register(t1, space0); + +ByteAddressBuffer globalLights : register(t2, space0); +static const uint3 tileCount = uint3(32u, 18u, 48u); + +float linearDepth(float depthSample) { + return ((asfloat(camera[13].w) * asfloat(camera[13].z)) / mad(depthSample, (asfloat(camera[13].z) - asfloat(camera[13].w)), asfloat(camera[13].w))); +} + +uint3 getTile(float4 fragCoord) { + const float sliceScale = (float(tileCount.z) / log2((asfloat(camera[13].w) / asfloat(camera[13].z)))); + const float sliceBias = -(((float(tileCount.z) * log2(asfloat(camera[13].z))) / log2((asfloat(camera[13].w) / asfloat(camera[13].z))))); + const uint zTile = uint(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0f)); + return uint3(uint((fragCoord.x / (asfloat(camera[13].x) / float(tileCount.x)))), uint((fragCoord.y / (asfloat(camera[13].y) / float(tileCount.y)))), zTile); +} + +uint getClusterIndex(float4 fragCoord) { + const uint3 tile = getTile(fragCoord); + return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y)); +} + +SamplerState defaultSampler : register(s3, space0); +Texture2D shadowTexture : register(t4, space0); +SamplerComparisonState shadowSampler : register(s5, space0); + +ByteAddressBuffer lightShadowTable : register(t6, space0); +static float2 shadowSampleOffsets[16] = {float2(-1.5f, -1.5f), float2(-1.5f, -0.5f), float2(-1.5f, 0.5f), float2(-1.5f, 1.5f), float2(-0.5f, -1.5f), float2(-0.5f, -0.5f), float2(-0.5f, 0.5f), float2(-0.5f, 1.5f), float2(0.5f, -1.5f), float2(0.5f, -0.5f), float2(0.5f, 0.5f), float2(0.5f, 1.5f), float2(1.5f, -1.5f), float2(1.5f, -0.5f), float2(1.5f, 0.5f), float2(1.5f, 1.5f)}; +static const uint shadowSampleCount = 16u; + +ByteAddressBuffer shadow : register(t7, space0); + +float4x4 tint_symbol_8(ByteAddressBuffer buffer, uint offset) { + return float4x4(asfloat(buffer.Load4((offset + 0u))), asfloat(buffer.Load4((offset + 16u))), asfloat(buffer.Load4((offset + 32u))), asfloat(buffer.Load4((offset + 48u)))); +} + +float dirLightVisibility(float3 worldPos) { + const int shadowIndex = asint(lightShadowTable.Load(0u)); + if ((shadowIndex == -1)) { + return 1.0f; + } + const float4 viewport = asfloat(shadow.Load4((80u * uint(shadowIndex)))); + const float4 lightPos = mul(float4(worldPos, 1.0f), tint_symbol_8(shadow, ((80u * uint(shadowIndex)) + 16u))); + const float3 shadowPos = float3((((lightPos.xy / lightPos.w) * float2(0.5f, -0.5f)) + float2(0.5f, 0.5f)), (lightPos.z / lightPos.w)); + const float2 viewportPos = float2((viewport.xy + (shadowPos.xy * viewport.zw))); + int3 tint_tmp; + shadowTexture.GetDimensions(0, tint_tmp.x, tint_tmp.y, tint_tmp.z); + const float2 texelSize = (1.0f / float2(tint_tmp.xy)); + const float4 clampRect = float4((viewport.xy - texelSize), ((viewport.xy + viewport.zw) + texelSize)); + float visibility = 0.0f; + { + [loop] for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + shadowTexture.SampleCmpLevelZero(shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.003f))); + } + } + return (visibility / float(shadowSampleCount)); +} + +int getCubeFace(float3 v) { + const float3 vAbs = abs(v); + bool tint_tmp_1 = (vAbs.z >= vAbs.x); + if (tint_tmp_1) { + tint_tmp_1 = (vAbs.z >= vAbs.y); + } + if ((tint_tmp_1)) { + if ((v.z < 0.0f)) { + return 5; + } + return 4; + } + if ((vAbs.y >= vAbs.x)) { + if ((v.y < 0.0f)) { + return 3; + } + return 2; + } + if ((v.x < 0.0f)) { + return 1; + } + return 0; +} + +float pointLightVisibility(uint lightIndex, float3 worldPos, float3 pointToLight) { + int shadowIndex = asint(lightShadowTable.Load((4u * (lightIndex + 1u)))); + if ((shadowIndex == -1)) { + return 1.0f; + } + shadowIndex = (shadowIndex + getCubeFace((pointToLight * -1.0f))); + const float4 viewport = asfloat(shadow.Load4((80u * uint(shadowIndex)))); + const float4 lightPos = mul(float4(worldPos, 1.0f), tint_symbol_8(shadow, ((80u * uint(shadowIndex)) + 16u))); + const float3 shadowPos = float3((((lightPos.xy / lightPos.w) * float2(0.5f, -0.5f)) + float2(0.5f, 0.5f)), (lightPos.z / lightPos.w)); + const float2 viewportPos = float2((viewport.xy + (shadowPos.xy * viewport.zw))); + int3 tint_tmp_2; + shadowTexture.GetDimensions(0, tint_tmp_2.x, tint_tmp_2.y, tint_tmp_2.z); + const float2 texelSize = (1.0f / float2(tint_tmp_2.xy)); + const float4 clampRect = float4(viewport.xy, (viewport.xy + viewport.zw)); + float visibility = 0.0f; + { + [loop] for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + shadowTexture.SampleCmpLevelZero(shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.01f))); + } + } + return (visibility / float(shadowSampleCount)); +} + +struct VertexOutput { + float4 position; + float3 worldPos; + float3 view; + float2 texcoord; + float2 texcoord2; + float4 color; + float4 instanceColor; + float3 normal; + float3 tangent; + float3 bitangent; +}; + +cbuffer cbuffer_material : register(b8, space0) { + uint4 material[3]; +}; +Texture2D baseColorTexture : register(t9, space0); +SamplerState baseColorSampler : register(s10, space0); +Texture2D normalTexture : register(t11, space0); +SamplerState normalSampler : register(s12, space0); +Texture2D metallicRoughnessTexture : register(t13, space0); +SamplerState metallicRoughnessSampler : register(s14, space0); +Texture2D occlusionTexture : register(t15, space0); +SamplerState occlusionSampler : register(s16, space0); +Texture2D emissiveTexture : register(t17, space0); +SamplerState emissiveSampler : register(s18, space0); + +struct SurfaceInfo { + float4 baseColor; + float3 albedo; + float metallic; + float roughness; + float3 normal; + float3 f0; + float ao; + float3 emissive; + float3 v; +}; + +SurfaceInfo GetSurfaceInfo(VertexOutput input) { + if (true) { + SurfaceInfo surface = (SurfaceInfo)0; + surface.v = normalize(input.view); + const float3x3 tbn = float3x3(input.tangent, input.bitangent, input.normal); + const float3 normalMap = normalTexture.Sample(normalSampler, input.texcoord).rgb; + surface.normal = normalize(mul(((2.0f * normalMap) - float3((1.0f).xxx)), tbn)); + const float4 baseColorMap = baseColorTexture.Sample(baseColorSampler, input.texcoord); + surface.baseColor = ((input.color * asfloat(material[0])) * baseColorMap); + if ((surface.baseColor.a < asfloat(material[2].z))) { + discard; + } + surface.albedo = surface.baseColor.rgb; + const float4 metallicRoughnessMap = metallicRoughnessTexture.Sample(metallicRoughnessSampler, input.texcoord); + surface.metallic = (asfloat(material[2].x) * metallicRoughnessMap.b); + surface.roughness = (asfloat(material[2].y) * metallicRoughnessMap.g); + const float3 dielectricSpec = float3((0.039999999f).xxx); + surface.f0 = lerp(dielectricSpec, surface.albedo, float3((surface.metallic).xxx)); + const float4 occlusionMap = occlusionTexture.Sample(occlusionSampler, input.texcoord); + surface.ao = (asfloat(material[1].w) * occlusionMap.r); + const float4 emissiveMap = emissiveTexture.Sample(emissiveSampler, input.texcoord); + surface.emissive = (asfloat(material[1].xyz) * emissiveMap.rgb); + if ((input.instanceColor.a == 0.0f)) { + surface.albedo = (surface.albedo + input.instanceColor.rgb); + } else { + surface.albedo = (surface.albedo * input.instanceColor.rgb); + } + return surface; + } + SurfaceInfo unused; + return unused; +} + +static const float PI = 3.141592741f; +static const uint LightType_Point = 0u; +static const uint LightType_Spot = 1u; +static const uint LightType_Directional = 2u; + +struct PuctualLight { + uint lightType; + float3 pointToLight; + float range; + float3 color; + float intensity; +}; + +float3 FresnelSchlick(float cosTheta, float3 F0) { + return (F0 + ((float3((1.0f).xxx) - F0) * pow((1.0f - cosTheta), 5.0f))); +} + +float DistributionGGX(float3 N, float3 H, float roughness) { + const float a_1 = (roughness * roughness); + const float a2 = (a_1 * a_1); + const float NdotH = max(dot(N, H), 0.0f); + const float NdotH2 = (NdotH * NdotH); + const float num = a2; + const float denom = ((NdotH2 * (a2 - 1.0f)) + 1.0f); + return (num / ((PI * denom) * denom)); +} + +float GeometrySchlickGGX(float NdotV, float roughness) { + const float r_1 = (roughness + 1.0f); + const float k = ((r_1 * r_1) / 8.0f); + const float num = NdotV; + const float denom = ((NdotV * (1.0f - k)) + k); + return (num / denom); +} + +float GeometrySmith(float3 N, float3 V, float3 L, float roughness) { + const float NdotV = max(dot(N, V), 0.0f); + const float NdotL = max(dot(N, L), 0.0f); + const float ggx2 = GeometrySchlickGGX(NdotV, roughness); + const float ggx1 = GeometrySchlickGGX(NdotL, roughness); + return (ggx1 * ggx2); +} + +float lightAttenuation(PuctualLight light) { + if ((light.lightType == LightType_Directional)) { + return 1.0f; + } + const float distance = length(light.pointToLight); + if ((light.range <= 0.0f)) { + return (1.0f / pow(distance, 2.0f)); + } + return (clamp((1.0f - pow((distance / light.range), 4.0f)), 0.0f, 1.0f) / pow(distance, 2.0f)); +} + +float3 lightRadiance(PuctualLight light, SurfaceInfo surface) { + const float3 L = normalize(light.pointToLight); + const float3 H = normalize((surface.v + L)); + const float NDF = DistributionGGX(surface.normal, H, surface.roughness); + const float G = GeometrySmith(surface.normal, surface.v, L, surface.roughness); + const float3 F = FresnelSchlick(max(dot(H, surface.v), 0.0f), surface.f0); + const float3 kD = ((float3((1.0f).xxx) - F) * (1.0f - surface.metallic)); + const float NdotL = max(dot(surface.normal, L), 0.0f); + const float3 numerator = ((NDF * G) * F); + const float denominator = max(((4.0f * max(dot(surface.normal, surface.v), 0.0f)) * NdotL), 0.001f); + const float3 specular = (numerator / float3((denominator).xxx)); + const float3 radiance = ((light.color * light.intensity) * lightAttenuation(light)); + return (((((kD * surface.albedo) / float3((PI).xxx)) + specular) * radiance) * NdotL); +} + +Texture2D ssaoTexture : register(t19, space0); + +struct FragmentOutput { + float4 color; + float4 emissive; +}; +struct tint_symbol_3 { + float3 worldPos : TEXCOORD0; + float3 view : TEXCOORD1; + float2 texcoord : TEXCOORD2; + float2 texcoord2 : TEXCOORD3; + float4 color : TEXCOORD4; + float4 instanceColor : TEXCOORD5; + float3 normal : TEXCOORD6; + float3 tangent : TEXCOORD7; + float3 bitangent : TEXCOORD8; + float4 position : SV_Position; +}; +struct tint_symbol_4 { + float4 color : SV_Target0; + float4 emissive : SV_Target1; +}; + +FragmentOutput fragmentMain_inner(VertexOutput input) { + const SurfaceInfo surface = GetSurfaceInfo(input); + float3 Lo = float3(0.0f, 0.0f, 0.0f); + if ((asfloat(globalLights.Load(28u)) > 0.0f)) { + PuctualLight light = (PuctualLight)0; + light.lightType = LightType_Directional; + light.pointToLight = asfloat(globalLights.Load3(32u)); + light.color = asfloat(globalLights.Load3(16u)); + light.intensity = asfloat(globalLights.Load(28u)); + const float lightVis = dirLightVisibility(input.worldPos); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + const uint clusterIndex = getClusterIndex(input.position); + const uint lightOffset = clusterLights.Load((4u + (8u * clusterIndex))); + const uint lightCount = clusterLights.Load(((4u + (8u * clusterIndex)) + 4u)); + { + [loop] for(uint lightIndex = 0u; (lightIndex < lightCount); lightIndex = (lightIndex + 1u)) { + const uint i = clusterLights.Load((221188u + (4u * (lightOffset + lightIndex)))); + PuctualLight light = (PuctualLight)0; + light.lightType = LightType_Point; + light.pointToLight = (asfloat(globalLights.Load3((48u + (32u * i)))).xyz - input.worldPos); + light.range = asfloat(globalLights.Load(((48u + (32u * i)) + 12u))); + light.color = asfloat(globalLights.Load3(((48u + (32u * i)) + 16u))); + light.intensity = asfloat(globalLights.Load(((48u + (32u * i)) + 28u))); + const float lightVis = pointLightVisibility(i, input.worldPos, light.pointToLight); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + } + int2 tint_tmp_3; + ssaoTexture.GetDimensions(tint_tmp_3.x, tint_tmp_3.y); + const float2 ssaoCoord = (input.position.xy / float2(tint_tmp_3.xy)); + const float ssaoFactor = ssaoTexture.Sample(defaultSampler, ssaoCoord).r; + const float3 ambient = (((asfloat(globalLights.Load3(0u)) * surface.albedo) * surface.ao) * ssaoFactor); + const float3 color = linearTosRGB(((Lo + ambient) + surface.emissive)); + FragmentOutput tint_symbol_1 = (FragmentOutput)0; + tint_symbol_1.color = float4(color, surface.baseColor.a); + tint_symbol_1.emissive = float4(surface.emissive, surface.baseColor.a); + return tint_symbol_1; +} + +tint_symbol_4 fragmentMain(tint_symbol_3 tint_symbol_2) { + const VertexOutput tint_symbol_15 = {tint_symbol_2.position, tint_symbol_2.worldPos, tint_symbol_2.view, tint_symbol_2.texcoord, tint_symbol_2.texcoord2, tint_symbol_2.color, tint_symbol_2.instanceColor, tint_symbol_2.normal, tint_symbol_2.tangent, tint_symbol_2.bitangent}; + const FragmentOutput inner_result = fragmentMain_inner(tint_symbol_15); + tint_symbol_4 wrapper_result = (tint_symbol_4)0; + wrapper_result.color = inner_result.color; + wrapper_result.emissive = inner_result.emissive; + return wrapper_result; +} diff --git a/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.msl b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.msl new file mode 100644 index 0000000000..80f6efc7da --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.msl @@ -0,0 +1,349 @@ +benchmark/skinned-shadowed-pbr-fragment.wgsl:51:13 warning: use of deprecated language feature: the @stride attribute is deprecated; use a larger type if necessary + lights : @stride(32) array; + ^^^^^^ + +#include + +using namespace metal; + +template +inline vec operator*(matrix lhs, packed_vec rhs) { + return lhs * vec(rhs); +} + +template +inline vec operator*(packed_vec lhs, matrix rhs) { + return vec(lhs) * rhs; +} + +struct Camera { + /* 0x0000 */ float4x4 projection; + /* 0x0040 */ float4x4 inverseProjection; + /* 0x0080 */ float4x4 view; + /* 0x00c0 */ packed_float3 position; + /* 0x00cc */ float time; + /* 0x00d0 */ float2 outputSize; + /* 0x00d8 */ float zNear; + /* 0x00dc */ float zFar; +}; +struct ClusterLights { + /* 0x0000 */ uint offset; + /* 0x0004 */ uint count; +}; +struct tint_array_wrapper { + /* 0x0000 */ ClusterLights arr[27648]; +}; +struct tint_array_wrapper_1 { + /* 0x0000 */ uint arr[1769472]; +}; +struct ClusterLightGroup { + /* 0x0000 */ uint offset; + /* 0x0004 */ tint_array_wrapper lights; + /* 0x36004 */ tint_array_wrapper_1 indices; +}; +struct Light { + /* 0x0000 */ packed_float3 position; + /* 0x000c */ float range; + /* 0x0010 */ packed_float3 color; + /* 0x001c */ float intensity; +}; +struct GlobalLights { + /* 0x0000 */ packed_float3 ambient; + /* 0x000c */ int8_t tint_pad[4]; + /* 0x0010 */ packed_float3 dirColor; + /* 0x001c */ float dirIntensity; + /* 0x0020 */ packed_float3 dirDirection; + /* 0x002c */ uint lightCount; + /* 0x0030 */ Light lights[1]; +}; +struct LightShadowTable { + /* 0x0000 */ int light[1]; +}; +struct tint_array_wrapper_2 { + float2 arr[16]; +}; +struct ShadowProperties { + /* 0x0000 */ float4 viewport; + /* 0x0010 */ float4x4 viewProj; +}; +struct LightShadows { + /* 0x0000 */ ShadowProperties properties[1]; +}; +struct VertexOutput { + float4 position; + float3 worldPos; + float3 view; + float2 texcoord; + float2 texcoord2; + float4 color; + float4 instanceColor; + float3 normal; + float3 tangent; + float3 bitangent; +}; +struct Material { + /* 0x0000 */ float4 baseColorFactor; + /* 0x0010 */ packed_float3 emissiveFactor; + /* 0x001c */ float occlusionStrength; + /* 0x0020 */ float2 metallicRoughnessFactor; + /* 0x0028 */ float alphaCutoff; + /* 0x002c */ int8_t tint_pad_1[4]; +}; +struct SurfaceInfo { + float4 baseColor; + float3 albedo; + float metallic; + float roughness; + float3 normal; + float3 f0; + float ao; + float3 emissive; + float3 v; +}; +struct PuctualLight { + uint lightType; + float3 pointToLight; + float range; + float3 color; + float intensity; +}; +struct FragmentOutput { + float4 color; + float4 emissive; +}; +struct tint_symbol_1 { + float3 worldPos [[user(locn0)]]; + float3 view [[user(locn1)]]; + float2 texcoord [[user(locn2)]]; + float2 texcoord2 [[user(locn3)]]; + float4 color [[user(locn4)]]; + float4 instanceColor [[user(locn5)]]; + float3 normal [[user(locn6)]]; + float3 tangent [[user(locn7)]]; + float3 bitangent [[user(locn8)]]; +}; +struct tint_symbol_2 { + float4 color [[color(0)]]; + float4 emissive [[color(1)]]; +}; + +constant float GAMMA = 2.200000048f; +constant uint3 tileCount = uint3(32u, 18u, 48u); +constant uint shadowSampleCount = 16u; +constant float PI = 3.141592741f; +constant uint LightType_Point = 0u; +constant uint LightType_Spot = 1u; +constant uint LightType_Directional = 2u; +float3 linearTosRGB(float3 linear) { + float const INV_GAMMA = (1.0f / GAMMA); + return pow(linear, float3(INV_GAMMA)); +} + +float3 sRGBToLinear(float3 srgb) { + return pow(srgb, float3(GAMMA)); +} + +float linearDepth(float depthSample, const constant Camera* const tint_symbol_4) { + return (((*(tint_symbol_4)).zFar * (*(tint_symbol_4)).zNear) / fma(depthSample, ((*(tint_symbol_4)).zNear - (*(tint_symbol_4)).zFar), (*(tint_symbol_4)).zFar)); +} + +uint3 getTile(float4 fragCoord, const constant Camera* const tint_symbol_5) { + float const sliceScale = (float(tileCount[2]) / log2(((*(tint_symbol_5)).zFar / (*(tint_symbol_5)).zNear))); + float const sliceBias = -(((float(tileCount[2]) * log2((*(tint_symbol_5)).zNear)) / log2(((*(tint_symbol_5)).zFar / (*(tint_symbol_5)).zNear)))); + uint const zTile = uint(fmax(((log2(linearDepth(fragCoord[2], tint_symbol_5)) * sliceScale) + sliceBias), 0.0f)); + return uint3(uint((fragCoord[0] / ((*(tint_symbol_5)).outputSize[0] / float(tileCount[0])))), uint((fragCoord[1] / ((*(tint_symbol_5)).outputSize[1] / float(tileCount[1])))), zTile); +} + +uint getClusterIndex(float4 fragCoord, const constant Camera* const tint_symbol_6) { + uint3 const tile = getTile(fragCoord, tint_symbol_6); + return ((tile[0] + (tile[1] * tileCount[0])) + ((tile[2] * tileCount[0]) * tileCount[1])); +} + +float dirLightVisibility(float3 worldPos, const device LightShadowTable* const tint_symbol_7, const device LightShadows* const tint_symbol_8, depth2d tint_symbol_9, sampler tint_symbol_10, thread tint_array_wrapper_2* const tint_symbol_11) { + int const shadowIndex = (*(tint_symbol_7)).light[0u]; + if ((shadowIndex == -1)) { + return 1.0f; + } + float4 const viewport = (*(tint_symbol_8)).properties[shadowIndex].viewport; + float4 const lightPos = ((*(tint_symbol_8)).properties[shadowIndex].viewProj * float4(worldPos, 1.0f)); + float3 const shadowPos = float3((((float4(lightPos).xy / lightPos[3]) * float2(0.5f, -0.5f)) + float2(0.5f, 0.5f)), (lightPos[2] / lightPos[3])); + float2 const viewportPos = float2((float4(viewport).xy + (float3(shadowPos).xy * float4(viewport).zw))); + float2 const texelSize = (1.0f / float2(int2(tint_symbol_9.get_width(0), tint_symbol_9.get_height(0)))); + float4 const clampRect = float4((float4(viewport).xy - texelSize), ((float4(viewport).xy + float4(viewport).zw) + texelSize)); + float visibility = 0.0f; + for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + tint_symbol_9.sample_compare(tint_symbol_10, clamp((viewportPos + ((*(tint_symbol_11)).arr[i] * texelSize)), float4(clampRect).xy, float4(clampRect).zw), (shadowPos[2] - 0.003f), level(0))); + } + return (visibility / float(shadowSampleCount)); +} + +int getCubeFace(float3 v) { + float3 const vAbs = fabs(v); + if (((vAbs[2] >= vAbs[0]) && (vAbs[2] >= vAbs[1]))) { + if ((v[2] < 0.0f)) { + return 5; + } + return 4; + } + if ((vAbs[1] >= vAbs[0])) { + if ((v[1] < 0.0f)) { + return 3; + } + return 2; + } + if ((v[0] < 0.0f)) { + return 1; + } + return 0; +} + +float pointLightVisibility(uint lightIndex, float3 worldPos, float3 pointToLight, const device LightShadowTable* const tint_symbol_12, const device LightShadows* const tint_symbol_13, depth2d tint_symbol_14, sampler tint_symbol_15, thread tint_array_wrapper_2* const tint_symbol_16) { + int shadowIndex = (*(tint_symbol_12)).light[(lightIndex + 1u)]; + if ((shadowIndex == -1)) { + return 1.0f; + } + shadowIndex = as_type((as_type(shadowIndex) + as_type(getCubeFace((pointToLight * -1.0f))))); + float4 const viewport = (*(tint_symbol_13)).properties[shadowIndex].viewport; + float4 const lightPos = ((*(tint_symbol_13)).properties[shadowIndex].viewProj * float4(worldPos, 1.0f)); + float3 const shadowPos = float3((((float4(lightPos).xy / lightPos[3]) * float2(0.5f, -0.5f)) + float2(0.5f, 0.5f)), (lightPos[2] / lightPos[3])); + float2 const viewportPos = float2((float4(viewport).xy + (float3(shadowPos).xy * float4(viewport).zw))); + float2 const texelSize = (1.0f / float2(int2(tint_symbol_14.get_width(0), tint_symbol_14.get_height(0)))); + float4 const clampRect = float4(float4(viewport).xy, (float4(viewport).xy + float4(viewport).zw)); + float visibility = 0.0f; + for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + tint_symbol_14.sample_compare(tint_symbol_15, clamp((viewportPos + ((*(tint_symbol_16)).arr[i] * texelSize)), float4(clampRect).xy, float4(clampRect).zw), (shadowPos[2] - 0.01f), level(0))); + } + return (visibility / float(shadowSampleCount)); +} + +SurfaceInfo GetSurfaceInfo(VertexOutput input, texture2d tint_symbol_17, sampler tint_symbol_18, texture2d tint_symbol_19, sampler tint_symbol_20, const constant Material* const tint_symbol_21, texture2d tint_symbol_22, sampler tint_symbol_23, texture2d tint_symbol_24, sampler tint_symbol_25, texture2d tint_symbol_26, sampler tint_symbol_27) { + SurfaceInfo surface = {}; + surface.v = normalize(input.view); + float3x3 const tbn = float3x3(input.tangent, input.bitangent, input.normal); + float3 const normalMap = float4(tint_symbol_17.sample(tint_symbol_18, input.texcoord)).rgb; + surface.normal = normalize((tbn * ((2.0f * normalMap) - float3(1.0f)))); + float4 const baseColorMap = tint_symbol_19.sample(tint_symbol_20, input.texcoord); + surface.baseColor = ((input.color * (*(tint_symbol_21)).baseColorFactor) * baseColorMap); + if ((surface.baseColor[3] < (*(tint_symbol_21)).alphaCutoff)) { + discard_fragment(); + } + surface.albedo = float4(surface.baseColor).rgb; + float4 const metallicRoughnessMap = tint_symbol_22.sample(tint_symbol_23, input.texcoord); + surface.metallic = ((*(tint_symbol_21)).metallicRoughnessFactor[0] * metallicRoughnessMap[2]); + surface.roughness = ((*(tint_symbol_21)).metallicRoughnessFactor[1] * metallicRoughnessMap[1]); + float3 const dielectricSpec = float3(0.039999999f); + surface.f0 = mix(dielectricSpec, surface.albedo, float3(surface.metallic)); + float4 const occlusionMap = tint_symbol_24.sample(tint_symbol_25, input.texcoord); + surface.ao = ((*(tint_symbol_21)).occlusionStrength * occlusionMap[0]); + float4 const emissiveMap = tint_symbol_26.sample(tint_symbol_27, input.texcoord); + surface.emissive = ((*(tint_symbol_21)).emissiveFactor * float4(emissiveMap).rgb); + if ((input.instanceColor[3] == 0.0f)) { + surface.albedo = (surface.albedo + float4(input.instanceColor).rgb); + } else { + surface.albedo = (surface.albedo * float4(input.instanceColor).rgb); + } + return surface; +} + +float3 FresnelSchlick(float cosTheta, float3 F0) { + return (F0 + ((float3(1.0f) - F0) * pow((1.0f - cosTheta), 5.0f))); +} + +float DistributionGGX(float3 N, float3 H, float roughness) { + float const a_1 = (roughness * roughness); + float const a2 = (a_1 * a_1); + float const NdotH = fmax(dot(N, H), 0.0f); + float const NdotH2 = (NdotH * NdotH); + float const num = a2; + float const denom = ((NdotH2 * (a2 - 1.0f)) + 1.0f); + return (num / ((PI * denom) * denom)); +} + +float GeometrySchlickGGX(float NdotV, float roughness) { + float const r_1 = (roughness + 1.0f); + float const k = ((r_1 * r_1) / 8.0f); + float const num = NdotV; + float const denom = ((NdotV * (1.0f - k)) + k); + return (num / denom); +} + +float GeometrySmith(float3 N, float3 V, float3 L, float roughness) { + float const NdotV = fmax(dot(N, V), 0.0f); + float const NdotL = fmax(dot(N, L), 0.0f); + float const ggx2 = GeometrySchlickGGX(NdotV, roughness); + float const ggx1 = GeometrySchlickGGX(NdotL, roughness); + return (ggx1 * ggx2); +} + +float lightAttenuation(PuctualLight light) { + if ((light.lightType == LightType_Directional)) { + return 1.0f; + } + float const distance = length(light.pointToLight); + if ((light.range <= 0.0f)) { + return (1.0f / pow(distance, 2.0f)); + } + return (clamp((1.0f - pow((distance / light.range), 4.0f)), 0.0f, 1.0f) / pow(distance, 2.0f)); +} + +float3 lightRadiance(PuctualLight light, SurfaceInfo surface) { + float3 const L = normalize(light.pointToLight); + float3 const H = normalize((surface.v + L)); + float const NDF = DistributionGGX(surface.normal, H, surface.roughness); + float const G = GeometrySmith(surface.normal, surface.v, L, surface.roughness); + float3 const F = FresnelSchlick(fmax(dot(H, surface.v), 0.0f), surface.f0); + float3 const kD = ((float3(1.0f) - F) * (1.0f - surface.metallic)); + float const NdotL = fmax(dot(surface.normal, L), 0.0f); + float3 const numerator = ((NDF * G) * F); + float const denominator = fmax(((4.0f * fmax(dot(surface.normal, surface.v), 0.0f)) * NdotL), 0.001f); + float3 const specular = (numerator / float3(denominator)); + float3 const radiance = ((light.color * light.intensity) * lightAttenuation(light)); + return (((((kD * surface.albedo) / float3(PI)) + specular) * radiance) * NdotL); +} + +FragmentOutput fragmentMain_inner(VertexOutput input, texture2d tint_symbol_28, sampler tint_symbol_29, texture2d tint_symbol_30, sampler tint_symbol_31, const constant Material* const tint_symbol_32, texture2d tint_symbol_33, sampler tint_symbol_34, texture2d tint_symbol_35, sampler tint_symbol_36, texture2d tint_symbol_37, sampler tint_symbol_38, const device GlobalLights* const tint_symbol_39, const device LightShadowTable* const tint_symbol_40, const device LightShadows* const tint_symbol_41, depth2d tint_symbol_42, sampler tint_symbol_43, thread tint_array_wrapper_2* const tint_symbol_44, const constant Camera* const tint_symbol_45, const device ClusterLightGroup* const tint_symbol_46, texture2d tint_symbol_47, sampler tint_symbol_48) { + SurfaceInfo const surface = GetSurfaceInfo(input, tint_symbol_28, tint_symbol_29, tint_symbol_30, tint_symbol_31, tint_symbol_32, tint_symbol_33, tint_symbol_34, tint_symbol_35, tint_symbol_36, tint_symbol_37, tint_symbol_38); + float3 Lo = float3(0.0f, 0.0f, 0.0f); + if (((*(tint_symbol_39)).dirIntensity > 0.0f)) { + PuctualLight light = {}; + light.lightType = LightType_Directional; + light.pointToLight = (*(tint_symbol_39)).dirDirection; + light.color = (*(tint_symbol_39)).dirColor; + light.intensity = (*(tint_symbol_39)).dirIntensity; + float const lightVis = dirLightVisibility(input.worldPos, tint_symbol_40, tint_symbol_41, tint_symbol_42, tint_symbol_43, tint_symbol_44); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + uint const clusterIndex = getClusterIndex(input.position, tint_symbol_45); + uint const lightOffset = (*(tint_symbol_46)).lights.arr[clusterIndex].offset; + uint const lightCount = (*(tint_symbol_46)).lights.arr[clusterIndex].count; + for(uint lightIndex = 0u; (lightIndex < lightCount); lightIndex = (lightIndex + 1u)) { + uint const i = (*(tint_symbol_46)).indices.arr[(lightOffset + lightIndex)]; + PuctualLight light = {}; + light.lightType = LightType_Point; + light.pointToLight = (float3((*(tint_symbol_39)).lights[i].position).xyz - input.worldPos); + light.range = (*(tint_symbol_39)).lights[i].range; + light.color = (*(tint_symbol_39)).lights[i].color; + light.intensity = (*(tint_symbol_39)).lights[i].intensity; + float const lightVis = pointLightVisibility(i, input.worldPos, light.pointToLight, tint_symbol_40, tint_symbol_41, tint_symbol_42, tint_symbol_43, tint_symbol_44); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + float2 const ssaoCoord = (float4(input.position).xy / float2(int2(int2(tint_symbol_47.get_width(), tint_symbol_47.get_height())).xy)); + float const ssaoFactor = tint_symbol_47.sample(tint_symbol_48, ssaoCoord)[0]; + float3 const ambient = ((((*(tint_symbol_39)).ambient * surface.albedo) * surface.ao) * ssaoFactor); + float3 const color = linearTosRGB(((Lo + ambient) + surface.emissive)); + FragmentOutput out = {}; + out.color = float4(color, surface.baseColor[3]); + out.emissive = float4(surface.emissive, surface.baseColor[3]); + return out; +} + +fragment tint_symbol_2 fragmentMain(texture2d tint_symbol_49 [[texture(0)]], sampler tint_symbol_50 [[sampler(0)]], texture2d tint_symbol_51 [[texture(1)]], sampler tint_symbol_52 [[sampler(1)]], const constant Material* tint_symbol_53 [[buffer(0)]], texture2d tint_symbol_54 [[texture(2)]], sampler tint_symbol_55 [[sampler(2)]], texture2d tint_symbol_56 [[texture(3)]], sampler tint_symbol_57 [[sampler(3)]], texture2d tint_symbol_58 [[texture(4)]], sampler tint_symbol_59 [[sampler(4)]], const device GlobalLights* tint_symbol_60 [[buffer(2)]], const device LightShadowTable* tint_symbol_61 [[buffer(3)]], const device LightShadows* tint_symbol_62 [[buffer(4)]], depth2d tint_symbol_63 [[texture(6)]], sampler tint_symbol_64 [[sampler(6)]], const constant Camera* tint_symbol_66 [[buffer(1)]], const device ClusterLightGroup* tint_symbol_67 [[buffer(5)]], texture2d tint_symbol_68 [[texture(5)]], sampler tint_symbol_69 [[sampler(5)]], float4 position [[position]], tint_symbol_1 tint_symbol [[stage_in]]) { + thread tint_array_wrapper_2 tint_symbol_65 = {.arr={float2(-1.5f, -1.5f), float2(-1.5f, -0.5f), float2(-1.5f, 0.5f), float2(-1.5f, 1.5f), float2(-0.5f, -1.5f), float2(-0.5f, -0.5f), float2(-0.5f, 0.5f), float2(-0.5f, 1.5f), float2(0.5f, -1.5f), float2(0.5f, -0.5f), float2(0.5f, 0.5f), float2(0.5f, 1.5f), float2(1.5f, -1.5f), float2(1.5f, -0.5f), float2(1.5f, 0.5f), float2(1.5f, 1.5f)}}; + VertexOutput const tint_symbol_3 = {.position=position, .worldPos=tint_symbol.worldPos, .view=tint_symbol.view, .texcoord=tint_symbol.texcoord, .texcoord2=tint_symbol.texcoord2, .color=tint_symbol.color, .instanceColor=tint_symbol.instanceColor, .normal=tint_symbol.normal, .tangent=tint_symbol.tangent, .bitangent=tint_symbol.bitangent}; + FragmentOutput const inner_result = fragmentMain_inner(tint_symbol_3, tint_symbol_49, tint_symbol_50, tint_symbol_51, tint_symbol_52, tint_symbol_53, tint_symbol_54, tint_symbol_55, tint_symbol_56, tint_symbol_57, tint_symbol_58, tint_symbol_59, tint_symbol_60, tint_symbol_61, tint_symbol_62, tint_symbol_63, tint_symbol_64, &(tint_symbol_65), tint_symbol_66, tint_symbol_67, tint_symbol_68, tint_symbol_69); + tint_symbol_2 wrapper_result = {}; + wrapper_result.color = inner_result.color; + wrapper_result.emissive = inner_result.emissive; + return wrapper_result; +} + diff --git a/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.spvasm b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.spvasm new file mode 100644 index 0000000000..6a4dc79e13 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.spvasm @@ -0,0 +1,1302 @@ +benchmark/skinned-shadowed-pbr-fragment.wgsl:51:13 warning: use of deprecated language feature: the @stride attribute is deprecated; use a larger type if necessary + lights : @stride(32) array; + ^^^^^^ + +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 853 +; Schema: 0 + OpCapability Shader + OpCapability ImageQuery + %116 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %fragmentMain "fragmentMain" %position_1 %worldPos_1 %view_1 %texcoord_1 %texcoord2_1 %color_1 %instanceColor_1 %normal_1 %tangent_1 %bitangent_1 %color_2 %emissive_1 + OpExecutionMode %fragmentMain OriginUpperLeft + OpName %position_1 "position_1" + OpName %worldPos_1 "worldPos_1" + OpName %view_1 "view_1" + OpName %texcoord_1 "texcoord_1" + OpName %texcoord2_1 "texcoord2_1" + OpName %color_1 "color_1" + OpName %instanceColor_1 "instanceColor_1" + OpName %normal_1 "normal_1" + OpName %tangent_1 "tangent_1" + OpName %bitangent_1 "bitangent_1" + OpName %color_2 "color_2" + OpName %emissive_1 "emissive_1" + OpName %GAMMA "GAMMA" + OpName %Camera "Camera" + OpMemberName %Camera 0 "projection" + OpMemberName %Camera 1 "inverseProjection" + OpMemberName %Camera 2 "view" + OpMemberName %Camera 3 "position" + OpMemberName %Camera 4 "time" + OpMemberName %Camera 5 "outputSize" + OpMemberName %Camera 6 "zNear" + OpMemberName %Camera 7 "zFar" + OpName %camera "camera" + OpName %ClusterLightGroup "ClusterLightGroup" + OpMemberName %ClusterLightGroup 0 "offset" + OpMemberName %ClusterLightGroup 1 "lights" + OpName %ClusterLights "ClusterLights" + OpMemberName %ClusterLights 0 "offset" + OpMemberName %ClusterLights 1 "count" + OpMemberName %ClusterLightGroup 2 "indices" + OpName %clusterLights "clusterLights" + OpName %GlobalLights "GlobalLights" + OpMemberName %GlobalLights 0 "ambient" + OpMemberName %GlobalLights 1 "dirColor" + OpMemberName %GlobalLights 2 "dirIntensity" + OpMemberName %GlobalLights 3 "dirDirection" + OpMemberName %GlobalLights 4 "lightCount" + OpMemberName %GlobalLights 5 "lights" + OpName %Light "Light" + OpMemberName %Light 0 "position" + OpMemberName %Light 1 "range" + OpMemberName %Light 2 "color" + OpMemberName %Light 3 "intensity" + OpName %globalLights "globalLights" + OpName %tileCount "tileCount" + OpName %defaultSampler "defaultSampler" + OpName %shadowTexture "shadowTexture" + OpName %shadowSampler "shadowSampler" + OpName %LightShadowTable "LightShadowTable" + OpMemberName %LightShadowTable 0 "light" + OpName %lightShadowTable "lightShadowTable" + OpName %shadowSampleOffsets "shadowSampleOffsets" + OpName %shadowSampleCount "shadowSampleCount" + OpName %LightShadows "LightShadows" + OpMemberName %LightShadows 0 "properties" + OpName %ShadowProperties "ShadowProperties" + OpMemberName %ShadowProperties 0 "viewport" + OpMemberName %ShadowProperties 1 "viewProj" + OpName %shadow "shadow" + OpName %Material "Material" + OpMemberName %Material 0 "baseColorFactor" + OpMemberName %Material 1 "emissiveFactor" + OpMemberName %Material 2 "occlusionStrength" + OpMemberName %Material 3 "metallicRoughnessFactor" + OpMemberName %Material 4 "alphaCutoff" + OpName %material "material" + OpName %baseColorTexture "baseColorTexture" + OpName %baseColorSampler "baseColorSampler" + OpName %normalTexture "normalTexture" + OpName %normalSampler "normalSampler" + OpName %metallicRoughnessTexture "metallicRoughnessTexture" + OpName %metallicRoughnessSampler "metallicRoughnessSampler" + OpName %occlusionTexture "occlusionTexture" + OpName %occlusionSampler "occlusionSampler" + OpName %emissiveTexture "emissiveTexture" + OpName %emissiveSampler "emissiveSampler" + OpName %PI "PI" + OpName %LightType_Point "LightType_Point" + OpName %LightType_Spot "LightType_Spot" + OpName %LightType_Directional "LightType_Directional" + OpName %ssaoTexture "ssaoTexture" + OpName %linearTosRGB "linearTosRGB" + OpName %linear "linear" + OpName %sRGBToLinear "sRGBToLinear" + OpName %srgb "srgb" + OpName %linearDepth "linearDepth" + OpName %depthSample "depthSample" + OpName %getTile "getTile" + OpName %fragCoord "fragCoord" + OpName %getClusterIndex "getClusterIndex" + OpName %fragCoord_0 "fragCoord" + OpName %dirLightVisibility "dirLightVisibility" + OpName %worldPos "worldPos" + OpName %visibility "visibility" + OpName %i "i" + OpName %getCubeFace "getCubeFace" + OpName %v "v" + OpName %pointLightVisibility "pointLightVisibility" + OpName %lightIndex "lightIndex" + OpName %worldPos_0 "worldPos" + OpName %pointToLight "pointToLight" + OpName %shadowIndex "shadowIndex" + OpName %visibility_0 "visibility" + OpName %i_0 "i" + OpName %SurfaceInfo "SurfaceInfo" + OpMemberName %SurfaceInfo 0 "baseColor" + OpMemberName %SurfaceInfo 1 "albedo" + OpMemberName %SurfaceInfo 2 "metallic" + OpMemberName %SurfaceInfo 3 "roughness" + OpMemberName %SurfaceInfo 4 "normal" + OpMemberName %SurfaceInfo 5 "f0" + OpMemberName %SurfaceInfo 6 "ao" + OpMemberName %SurfaceInfo 7 "emissive" + OpMemberName %SurfaceInfo 8 "v" + OpName %VertexOutput "VertexOutput" + OpMemberName %VertexOutput 0 "position" + OpMemberName %VertexOutput 1 "worldPos" + OpMemberName %VertexOutput 2 "view" + OpMemberName %VertexOutput 3 "texcoord" + OpMemberName %VertexOutput 4 "texcoord2" + OpMemberName %VertexOutput 5 "color" + OpMemberName %VertexOutput 6 "instanceColor" + OpMemberName %VertexOutput 7 "normal" + OpMemberName %VertexOutput 8 "tangent" + OpMemberName %VertexOutput 9 "bitangent" + OpName %GetSurfaceInfo "GetSurfaceInfo" + OpName %input "input" + OpName %surface "surface" + OpName %FresnelSchlick "FresnelSchlick" + OpName %cosTheta "cosTheta" + OpName %F0 "F0" + OpName %DistributionGGX "DistributionGGX" + OpName %N "N" + OpName %H "H" + OpName %roughness "roughness" + OpName %GeometrySchlickGGX "GeometrySchlickGGX" + OpName %NdotV "NdotV" + OpName %roughness_0 "roughness" + OpName %GeometrySmith "GeometrySmith" + OpName %N_0 "N" + OpName %V "V" + OpName %L "L" + OpName %roughness_1 "roughness" + OpName %PuctualLight "PuctualLight" + OpMemberName %PuctualLight 0 "lightType" + OpMemberName %PuctualLight 1 "pointToLight" + OpMemberName %PuctualLight 2 "range" + OpMemberName %PuctualLight 3 "color" + OpMemberName %PuctualLight 4 "intensity" + OpName %lightAttenuation "lightAttenuation" + OpName %light "light" + OpName %lightRadiance "lightRadiance" + OpName %light_0 "light" + OpName %surface_0 "surface" + OpName %FragmentOutput "FragmentOutput" + OpMemberName %FragmentOutput 0 "color" + OpMemberName %FragmentOutput 1 "emissive" + OpName %fragmentMain_inner "fragmentMain_inner" + OpName %input_0 "input" + OpName %Lo "Lo" + OpName %light_1 "light" + OpName %lightIndex_0 "lightIndex" + OpName %light_2 "light" + OpName %out "out" + OpName %fragmentMain "fragmentMain" + OpDecorate %position_1 BuiltIn FragCoord + OpDecorate %worldPos_1 Location 0 + OpDecorate %view_1 Location 1 + OpDecorate %texcoord_1 Location 2 + OpDecorate %texcoord2_1 Location 3 + OpDecorate %color_1 Location 4 + OpDecorate %instanceColor_1 Location 5 + OpDecorate %normal_1 Location 6 + OpDecorate %tangent_1 Location 7 + OpDecorate %bitangent_1 Location 8 + OpDecorate %color_2 Location 0 + OpDecorate %emissive_1 Location 1 + OpDecorate %Camera Block + OpMemberDecorate %Camera 0 Offset 0 + OpMemberDecorate %Camera 0 ColMajor + OpMemberDecorate %Camera 0 MatrixStride 16 + OpMemberDecorate %Camera 1 Offset 64 + OpMemberDecorate %Camera 1 ColMajor + OpMemberDecorate %Camera 1 MatrixStride 16 + OpMemberDecorate %Camera 2 Offset 128 + OpMemberDecorate %Camera 2 ColMajor + OpMemberDecorate %Camera 2 MatrixStride 16 + OpMemberDecorate %Camera 3 Offset 192 + OpMemberDecorate %Camera 4 Offset 204 + OpMemberDecorate %Camera 5 Offset 208 + OpMemberDecorate %Camera 6 Offset 216 + OpMemberDecorate %Camera 7 Offset 220 + OpDecorate %camera NonWritable + OpDecorate %camera Binding 0 + OpDecorate %camera DescriptorSet 0 + OpDecorate %ClusterLightGroup Block + OpMemberDecorate %ClusterLightGroup 0 Offset 0 + OpMemberDecorate %ClusterLightGroup 1 Offset 4 + OpMemberDecorate %ClusterLights 0 Offset 0 + OpMemberDecorate %ClusterLights 1 Offset 4 + OpDecorate %_arr_ClusterLights_uint_27648 ArrayStride 8 + OpMemberDecorate %ClusterLightGroup 2 Offset 221188 + OpDecorate %_arr_uint_uint_1769472 ArrayStride 4 + OpDecorate %clusterLights NonWritable + OpDecorate %clusterLights Binding 1 + OpDecorate %clusterLights DescriptorSet 0 + OpDecorate %GlobalLights Block + OpMemberDecorate %GlobalLights 0 Offset 0 + OpMemberDecorate %GlobalLights 1 Offset 16 + OpMemberDecorate %GlobalLights 2 Offset 28 + OpMemberDecorate %GlobalLights 3 Offset 32 + OpMemberDecorate %GlobalLights 4 Offset 44 + OpMemberDecorate %GlobalLights 5 Offset 48 + OpMemberDecorate %Light 0 Offset 0 + OpMemberDecorate %Light 1 Offset 12 + OpMemberDecorate %Light 2 Offset 16 + OpMemberDecorate %Light 3 Offset 28 + OpDecorate %_runtimearr_Light ArrayStride 32 + OpDecorate %globalLights NonWritable + OpDecorate %globalLights Binding 2 + OpDecorate %globalLights DescriptorSet 0 + OpDecorate %defaultSampler Binding 3 + OpDecorate %defaultSampler DescriptorSet 0 + OpDecorate %shadowTexture Binding 4 + OpDecorate %shadowTexture DescriptorSet 0 + OpDecorate %shadowSampler Binding 5 + OpDecorate %shadowSampler DescriptorSet 0 + OpDecorate %LightShadowTable Block + OpMemberDecorate %LightShadowTable 0 Offset 0 + OpDecorate %_runtimearr_int ArrayStride 4 + OpDecorate %lightShadowTable NonWritable + OpDecorate %lightShadowTable Binding 6 + OpDecorate %lightShadowTable DescriptorSet 0 + OpDecorate %_arr_v2float_shadowSampleCount ArrayStride 8 + OpDecorate %LightShadows Block + OpMemberDecorate %LightShadows 0 Offset 0 + OpMemberDecorate %ShadowProperties 0 Offset 0 + OpMemberDecorate %ShadowProperties 1 Offset 16 + OpMemberDecorate %ShadowProperties 1 ColMajor + OpMemberDecorate %ShadowProperties 1 MatrixStride 16 + OpDecorate %_runtimearr_ShadowProperties ArrayStride 80 + OpDecorate %shadow NonWritable + OpDecorate %shadow Binding 7 + OpDecorate %shadow DescriptorSet 0 + OpDecorate %Material Block + OpMemberDecorate %Material 0 Offset 0 + OpMemberDecorate %Material 1 Offset 16 + OpMemberDecorate %Material 2 Offset 28 + OpMemberDecorate %Material 3 Offset 32 + OpMemberDecorate %Material 4 Offset 40 + OpDecorate %material NonWritable + OpDecorate %material Binding 8 + OpDecorate %material DescriptorSet 0 + OpDecorate %baseColorTexture Binding 9 + OpDecorate %baseColorTexture DescriptorSet 0 + OpDecorate %baseColorSampler Binding 10 + OpDecorate %baseColorSampler DescriptorSet 0 + OpDecorate %normalTexture Binding 11 + OpDecorate %normalTexture DescriptorSet 0 + OpDecorate %normalSampler Binding 12 + OpDecorate %normalSampler DescriptorSet 0 + OpDecorate %metallicRoughnessTexture Binding 13 + OpDecorate %metallicRoughnessTexture DescriptorSet 0 + OpDecorate %metallicRoughnessSampler Binding 14 + OpDecorate %metallicRoughnessSampler DescriptorSet 0 + OpDecorate %occlusionTexture Binding 15 + OpDecorate %occlusionTexture DescriptorSet 0 + OpDecorate %occlusionSampler Binding 16 + OpDecorate %occlusionSampler DescriptorSet 0 + OpDecorate %emissiveTexture Binding 17 + OpDecorate %emissiveTexture DescriptorSet 0 + OpDecorate %emissiveSampler Binding 18 + OpDecorate %emissiveSampler DescriptorSet 0 + OpDecorate %ssaoTexture Binding 19 + OpDecorate %ssaoTexture DescriptorSet 0 + OpMemberDecorate %SurfaceInfo 0 Offset 0 + OpMemberDecorate %SurfaceInfo 1 Offset 16 + OpMemberDecorate %SurfaceInfo 2 Offset 28 + OpMemberDecorate %SurfaceInfo 3 Offset 32 + OpMemberDecorate %SurfaceInfo 4 Offset 48 + OpMemberDecorate %SurfaceInfo 5 Offset 64 + OpMemberDecorate %SurfaceInfo 6 Offset 76 + OpMemberDecorate %SurfaceInfo 7 Offset 80 + OpMemberDecorate %SurfaceInfo 8 Offset 96 + OpMemberDecorate %VertexOutput 0 Offset 0 + OpMemberDecorate %VertexOutput 1 Offset 16 + OpMemberDecorate %VertexOutput 2 Offset 32 + OpMemberDecorate %VertexOutput 3 Offset 48 + OpMemberDecorate %VertexOutput 4 Offset 56 + OpMemberDecorate %VertexOutput 5 Offset 64 + OpMemberDecorate %VertexOutput 6 Offset 80 + OpMemberDecorate %VertexOutput 7 Offset 96 + OpMemberDecorate %VertexOutput 8 Offset 112 + OpMemberDecorate %VertexOutput 9 Offset 128 + OpMemberDecorate %PuctualLight 0 Offset 0 + OpMemberDecorate %PuctualLight 1 Offset 16 + OpMemberDecorate %PuctualLight 2 Offset 28 + OpMemberDecorate %PuctualLight 3 Offset 32 + OpMemberDecorate %PuctualLight 4 Offset 44 + OpMemberDecorate %FragmentOutput 0 Offset 0 + OpMemberDecorate %FragmentOutput 1 Offset 16 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %position_1 = OpVariable %_ptr_Input_v4float Input + %v3float = OpTypeVector %float 3 +%_ptr_Input_v3float = OpTypePointer Input %v3float + %worldPos_1 = OpVariable %_ptr_Input_v3float Input + %view_1 = OpVariable %_ptr_Input_v3float Input + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %texcoord_1 = OpVariable %_ptr_Input_v2float Input +%texcoord2_1 = OpVariable %_ptr_Input_v2float Input + %color_1 = OpVariable %_ptr_Input_v4float Input +%instanceColor_1 = OpVariable %_ptr_Input_v4float Input + %normal_1 = OpVariable %_ptr_Input_v3float Input + %tangent_1 = OpVariable %_ptr_Input_v3float Input +%bitangent_1 = OpVariable %_ptr_Input_v3float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float + %20 = OpConstantNull %v4float + %color_2 = OpVariable %_ptr_Output_v4float Output %20 + %emissive_1 = OpVariable %_ptr_Output_v4float Output %20 + %GAMMA = OpConstant %float 2.20000005 +%mat4v4float = OpTypeMatrix %v4float 4 + %Camera = OpTypeStruct %mat4v4float %mat4v4float %mat4v4float %v3float %float %v2float %float %float +%_ptr_Uniform_Camera = OpTypePointer Uniform %Camera + %camera = OpVariable %_ptr_Uniform_Camera Uniform + %uint = OpTypeInt 32 0 +%ClusterLights = OpTypeStruct %uint %uint + %uint_27648 = OpConstant %uint 27648 +%_arr_ClusterLights_uint_27648 = OpTypeArray %ClusterLights %uint_27648 +%uint_1769472 = OpConstant %uint 1769472 +%_arr_uint_uint_1769472 = OpTypeArray %uint %uint_1769472 +%ClusterLightGroup = OpTypeStruct %uint %_arr_ClusterLights_uint_27648 %_arr_uint_uint_1769472 +%_ptr_StorageBuffer_ClusterLightGroup = OpTypePointer StorageBuffer %ClusterLightGroup +%clusterLights = OpVariable %_ptr_StorageBuffer_ClusterLightGroup StorageBuffer + %Light = OpTypeStruct %v3float %float %v3float %float +%_runtimearr_Light = OpTypeRuntimeArray %Light +%GlobalLights = OpTypeStruct %v3float %v3float %float %v3float %uint %_runtimearr_Light +%_ptr_StorageBuffer_GlobalLights = OpTypePointer StorageBuffer %GlobalLights +%globalLights = OpVariable %_ptr_StorageBuffer_GlobalLights StorageBuffer + %v3uint = OpTypeVector %uint 3 + %uint_32 = OpConstant %uint 32 + %uint_18 = OpConstant %uint 18 + %uint_48 = OpConstant %uint 48 + %tileCount = OpConstantComposite %v3uint %uint_32 %uint_18 %uint_48 + %48 = OpTypeSampler +%_ptr_UniformConstant_48 = OpTypePointer UniformConstant %48 +%defaultSampler = OpVariable %_ptr_UniformConstant_48 UniformConstant + %51 = OpTypeImage %float 2D 1 0 0 1 Unknown +%_ptr_UniformConstant_51 = OpTypePointer UniformConstant %51 +%shadowTexture = OpVariable %_ptr_UniformConstant_51 UniformConstant +%_ptr_UniformConstant_48_0 = OpTypePointer UniformConstant %48 +%shadowSampler = OpVariable %_ptr_UniformConstant_48_0 UniformConstant + %int = OpTypeInt 32 1 +%_runtimearr_int = OpTypeRuntimeArray %int +%LightShadowTable = OpTypeStruct %_runtimearr_int +%_ptr_StorageBuffer_LightShadowTable = OpTypePointer StorageBuffer %LightShadowTable +%lightShadowTable = OpVariable %_ptr_StorageBuffer_LightShadowTable StorageBuffer +%shadowSampleCount = OpConstant %uint 16 +%_arr_v2float_shadowSampleCount = OpTypeArray %v2float %shadowSampleCount + %float_n1_5 = OpConstant %float -1.5 + %62 = OpConstantComposite %v2float %float_n1_5 %float_n1_5 + %float_n0_5 = OpConstant %float -0.5 + %64 = OpConstantComposite %v2float %float_n1_5 %float_n0_5 + %float_0_5 = OpConstant %float 0.5 + %66 = OpConstantComposite %v2float %float_n1_5 %float_0_5 + %float_1_5 = OpConstant %float 1.5 + %68 = OpConstantComposite %v2float %float_n1_5 %float_1_5 + %69 = OpConstantComposite %v2float %float_n0_5 %float_n1_5 + %70 = OpConstantComposite %v2float %float_n0_5 %float_n0_5 + %71 = OpConstantComposite %v2float %float_n0_5 %float_0_5 + %72 = OpConstantComposite %v2float %float_n0_5 %float_1_5 + %73 = OpConstantComposite %v2float %float_0_5 %float_n1_5 + %74 = OpConstantComposite %v2float %float_0_5 %float_n0_5 + %75 = OpConstantComposite %v2float %float_0_5 %float_0_5 + %76 = OpConstantComposite %v2float %float_0_5 %float_1_5 + %77 = OpConstantComposite %v2float %float_1_5 %float_n1_5 + %78 = OpConstantComposite %v2float %float_1_5 %float_n0_5 + %79 = OpConstantComposite %v2float %float_1_5 %float_0_5 + %80 = OpConstantComposite %v2float %float_1_5 %float_1_5 + %81 = OpConstantComposite %_arr_v2float_shadowSampleCount %62 %64 %66 %68 %69 %70 %71 %72 %73 %74 %75 %76 %77 %78 %79 %80 +%_ptr_Private__arr_v2float_shadowSampleCount = OpTypePointer Private %_arr_v2float_shadowSampleCount +%shadowSampleOffsets = OpVariable %_ptr_Private__arr_v2float_shadowSampleCount Private %81 +%ShadowProperties = OpTypeStruct %v4float %mat4v4float +%_runtimearr_ShadowProperties = OpTypeRuntimeArray %ShadowProperties +%LightShadows = OpTypeStruct %_runtimearr_ShadowProperties +%_ptr_StorageBuffer_LightShadows = OpTypePointer StorageBuffer %LightShadows + %shadow = OpVariable %_ptr_StorageBuffer_LightShadows StorageBuffer + %Material = OpTypeStruct %v4float %v3float %float %v2float %float +%_ptr_Uniform_Material = OpTypePointer Uniform %Material + %material = OpVariable %_ptr_Uniform_Material Uniform + %94 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_94 = OpTypePointer UniformConstant %94 +%baseColorTexture = OpVariable %_ptr_UniformConstant_94 UniformConstant +%baseColorSampler = OpVariable %_ptr_UniformConstant_48 UniformConstant +%normalTexture = OpVariable %_ptr_UniformConstant_94 UniformConstant +%normalSampler = OpVariable %_ptr_UniformConstant_48 UniformConstant +%metallicRoughnessTexture = OpVariable %_ptr_UniformConstant_94 UniformConstant +%metallicRoughnessSampler = OpVariable %_ptr_UniformConstant_48 UniformConstant +%occlusionTexture = OpVariable %_ptr_UniformConstant_94 UniformConstant +%occlusionSampler = OpVariable %_ptr_UniformConstant_48 UniformConstant +%emissiveTexture = OpVariable %_ptr_UniformConstant_94 UniformConstant +%emissiveSampler = OpVariable %_ptr_UniformConstant_48 UniformConstant + %PI = OpConstant %float 3.14159274 +%LightType_Point = OpConstant %uint 0 +%LightType_Spot = OpConstant %uint 1 +%LightType_Directional = OpConstant %uint 2 +%ssaoTexture = OpVariable %_ptr_UniformConstant_94 UniformConstant + %109 = OpTypeFunction %v3float %v3float + %float_1 = OpConstant %float 1 + %122 = OpConstantComposite %v3float %GAMMA %GAMMA %GAMMA + %123 = OpTypeFunction %float %float + %uint_7 = OpConstant %uint 7 +%_ptr_Uniform_float = OpTypePointer Uniform %float + %uint_6 = OpConstant %uint 6 + %144 = OpTypeFunction %v3uint %v4float + %float_0 = OpConstant %float 0 + %uint_5 = OpConstant %uint 5 + %197 = OpTypeFunction %uint %v4float + %213 = OpTypeFunction %float %v3float +%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int + %int_n1 = OpConstant %int -1 + %bool = OpTypeBool +%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float +%_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float +%_ptr_Function_v2float = OpTypePointer Function %v2float + %241 = OpConstantNull %v2float + %v2int = OpTypeVector %int 2 + %int_0 = OpConstant %int 0 +%_ptr_Function_float = OpTypePointer Function %float + %278 = OpConstantNull %float +%_ptr_Function_uint = OpTypePointer Function %uint + %281 = OpConstantNull %uint + %295 = OpTypeSampledImage %51 +%_ptr_Private_v2float = OpTypePointer Private %v2float +%float_0_00300000003 = OpConstant %float 0.00300000003 + %float_16 = OpConstant %float 16 + %315 = OpTypeFunction %int %v3float + %int_5 = OpConstant %int 5 + %int_4 = OpConstant %int 4 + %int_3 = OpConstant %int 3 + %int_2 = OpConstant %int 2 + %int_1 = OpConstant %int 1 + %353 = OpTypeFunction %float %uint %v3float %v3float +%_ptr_Function_int = OpTypePointer Function %int + %364 = OpConstantNull %int + %float_n1 = OpConstant %float -1 +%float_0_00999999978 = OpConstant %float 0.00999999978 +%SurfaceInfo = OpTypeStruct %v4float %v3float %float %float %v3float %v3float %float %v3float %v3float +%VertexOutput = OpTypeStruct %v4float %v3float %v3float %v2float %v2float %v4float %v4float %v3float %v3float %v3float + %451 = OpTypeFunction %SurfaceInfo %VertexOutput +%_ptr_Function_SurfaceInfo = OpTypePointer Function %SurfaceInfo + %459 = OpConstantNull %SurfaceInfo + %uint_8 = OpConstant %uint 8 +%_ptr_Function_v3float = OpTypePointer Function %v3float +%mat3v3float = OpTypeMatrix %v3float 3 + %473 = OpTypeSampledImage %94 + %uint_4 = OpConstant %uint 4 + %float_2 = OpConstant %float 2 + %482 = OpConstantComposite %v3float %float_1 %float_1 %float_1 +%_ptr_Function_v4float = OpTypePointer Function %v4float +%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float + %uint_3 = OpConstant %uint 3 +%float_0_0399999991 = OpConstant %float 0.0399999991 + %526 = OpConstantComposite %v3float %float_0_0399999991 %float_0_0399999991 %float_0_0399999991 +%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float + %574 = OpTypeFunction %v3float %float %v3float + %float_5 = OpConstant %float 5 + %585 = OpTypeFunction %float %v3float %v3float %float + %602 = OpTypeFunction %float %float %float + %float_8 = OpConstant %float 8 + %615 = OpTypeFunction %float %v3float %v3float %v3float %float +%PuctualLight = OpTypeStruct %uint %v3float %float %v3float %float + %629 = OpTypeFunction %float %PuctualLight + %float_4 = OpConstant %float 4 + %654 = OpTypeFunction %v3float %PuctualLight %SurfaceInfo +%float_0_00100000005 = OpConstant %float 0.00100000005 + %702 = OpConstantComposite %v3float %PI %PI %PI +%FragmentOutput = OpTypeStruct %v4float %v4float + %707 = OpTypeFunction %FragmentOutput %VertexOutput + %713 = OpConstantComposite %v3float %float_0 %float_0 %float_0 + %715 = OpConstantNull %v3float +%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float +%_ptr_Function_PuctualLight = OpTypePointer Function %PuctualLight + %724 = OpConstantNull %PuctualLight +%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float +%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +%_ptr_Function_FragmentOutput = OpTypePointer Function %FragmentOutput + %818 = OpConstantNull %FragmentOutput + %void = OpTypeVoid + %835 = OpTypeFunction %void +%linearTosRGB = OpFunction %v3float None %109 + %linear = OpFunctionParameter %v3float + %112 = OpLabel + %114 = OpFDiv %float %float_1 %GAMMA + %117 = OpCompositeConstruct %v3float %114 %114 %114 + %115 = OpExtInst %v3float %116 Pow %linear %117 + OpReturnValue %115 + OpFunctionEnd +%sRGBToLinear = OpFunction %v3float None %109 + %srgb = OpFunctionParameter %v3float + %120 = OpLabel + %121 = OpExtInst %v3float %116 Pow %srgb %122 + OpReturnValue %121 + OpFunctionEnd +%linearDepth = OpFunction %float None %123 +%depthSample = OpFunctionParameter %float + %126 = OpLabel + %129 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %130 = OpLoad %float %129 + %132 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %133 = OpLoad %float %132 + %134 = OpFMul %float %130 %133 + %136 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %137 = OpLoad %float %136 + %138 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %139 = OpLoad %float %138 + %140 = OpFSub %float %137 %139 + %141 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %142 = OpLoad %float %141 + %135 = OpExtInst %float %116 Fma %depthSample %140 %142 + %143 = OpFDiv %float %134 %135 + OpReturnValue %143 + OpFunctionEnd + %getTile = OpFunction %v3uint None %144 + %fragCoord = OpFunctionParameter %v4float + %147 = OpLabel + %149 = OpCompositeExtract %uint %tileCount 2 + %148 = OpConvertUToF %float %149 + %151 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %152 = OpLoad %float %151 + %153 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %154 = OpLoad %float %153 + %155 = OpFDiv %float %152 %154 + %150 = OpExtInst %float %116 Log2 %155 + %156 = OpFDiv %float %148 %150 + %159 = OpCompositeExtract %uint %tileCount 2 + %158 = OpConvertUToF %float %159 + %161 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %162 = OpLoad %float %161 + %160 = OpExtInst %float %116 Log2 %162 + %163 = OpFMul %float %158 %160 + %165 = OpAccessChain %_ptr_Uniform_float %camera %uint_7 + %166 = OpLoad %float %165 + %167 = OpAccessChain %_ptr_Uniform_float %camera %uint_6 + %168 = OpLoad %float %167 + %169 = OpFDiv %float %166 %168 + %164 = OpExtInst %float %116 Log2 %169 + %170 = OpFDiv %float %163 %164 + %157 = OpFNegate %float %170 + %175 = OpCompositeExtract %float %fragCoord 2 + %174 = OpFunctionCall %float %linearDepth %175 + %173 = OpExtInst %float %116 Log2 %174 + %176 = OpFMul %float %173 %156 + %177 = OpFAdd %float %176 %157 + %172 = OpExtInst %float %116 NMax %177 %float_0 + %171 = OpConvertFToU %uint %172 + %180 = OpCompositeExtract %float %fragCoord 0 + %182 = OpAccessChain %_ptr_Uniform_float %camera %uint_5 %LightType_Point + %183 = OpLoad %float %182 + %185 = OpCompositeExtract %uint %tileCount 0 + %184 = OpConvertUToF %float %185 + %186 = OpFDiv %float %183 %184 + %187 = OpFDiv %float %180 %186 + %179 = OpConvertFToU %uint %187 + %189 = OpCompositeExtract %float %fragCoord 1 + %190 = OpAccessChain %_ptr_Uniform_float %camera %uint_5 %LightType_Spot + %191 = OpLoad %float %190 + %193 = OpCompositeExtract %uint %tileCount 1 + %192 = OpConvertUToF %float %193 + %194 = OpFDiv %float %191 %192 + %195 = OpFDiv %float %189 %194 + %188 = OpConvertFToU %uint %195 + %196 = OpCompositeConstruct %v3uint %179 %188 %171 + OpReturnValue %196 + OpFunctionEnd +%getClusterIndex = OpFunction %uint None %197 +%fragCoord_0 = OpFunctionParameter %v4float + %200 = OpLabel + %201 = OpFunctionCall %v3uint %getTile %fragCoord_0 + %202 = OpCompositeExtract %uint %201 0 + %203 = OpCompositeExtract %uint %201 1 + %204 = OpCompositeExtract %uint %tileCount 0 + %205 = OpIMul %uint %203 %204 + %206 = OpIAdd %uint %202 %205 + %207 = OpCompositeExtract %uint %201 2 + %208 = OpCompositeExtract %uint %tileCount 0 + %209 = OpIMul %uint %207 %208 + %210 = OpCompositeExtract %uint %tileCount 1 + %211 = OpIMul %uint %209 %210 + %212 = OpIAdd %uint %206 %211 + OpReturnValue %212 + OpFunctionEnd +%dirLightVisibility = OpFunction %float None %213 + %worldPos = OpFunctionParameter %v3float + %216 = OpLabel + %239 = OpVariable %_ptr_Function_v2float Function %241 + %263 = OpVariable %_ptr_Function_v2float Function %241 + %visibility = OpVariable %_ptr_Function_float Function %278 + %i = OpVariable %_ptr_Function_uint Function %281 + %218 = OpAccessChain %_ptr_StorageBuffer_int %lightShadowTable %LightType_Point %LightType_Point + %219 = OpLoad %int %218 + %221 = OpIEqual %bool %219 %int_n1 + OpSelectionMerge %223 None + OpBranchConditional %221 %224 %223 + %224 = OpLabel + OpReturnValue %float_1 + %223 = OpLabel + %226 = OpAccessChain %_ptr_StorageBuffer_v4float %shadow %LightType_Point %219 %LightType_Point + %227 = OpLoad %v4float %226 + %229 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %shadow %LightType_Point %219 %LightType_Spot + %230 = OpLoad %mat4v4float %229 + %231 = OpCompositeExtract %float %worldPos 0 + %232 = OpCompositeExtract %float %worldPos 1 + %233 = OpCompositeExtract %float %worldPos 2 + %234 = OpCompositeConstruct %v4float %231 %232 %233 %float_1 + %235 = OpMatrixTimesVector %v4float %230 %234 + %236 = OpVectorShuffle %v2float %235 %235 0 1 + %237 = OpCompositeExtract %float %235 3 + %242 = OpCompositeConstruct %v2float %237 %237 + %238 = OpFDiv %v2float %236 %242 + %243 = OpFMul %v2float %238 %74 + %244 = OpFAdd %v2float %243 %75 + %245 = OpCompositeExtract %float %244 0 + %246 = OpCompositeExtract %float %244 1 + %247 = OpCompositeExtract %float %235 2 + %248 = OpCompositeExtract %float %235 3 + %249 = OpFDiv %float %247 %248 + %250 = OpCompositeConstruct %v3float %245 %246 %249 + %252 = OpVectorShuffle %v2float %227 %227 0 1 + %253 = OpVectorShuffle %v2float %250 %250 0 1 + %254 = OpVectorShuffle %v2float %227 %227 2 3 + %255 = OpFMul %v2float %253 %254 + %256 = OpFAdd %v2float %252 %255 + %260 = OpLoad %51 %shadowTexture + %258 = OpImageQuerySizeLod %v2int %260 %int_0 + %257 = OpConvertSToF %v2float %258 + %264 = OpCompositeConstruct %v2float %float_1 %float_1 + %262 = OpFDiv %v2float %264 %257 + %265 = OpVectorShuffle %v2float %227 %227 0 1 + %266 = OpFSub %v2float %265 %262 + %267 = OpCompositeExtract %float %266 0 + %268 = OpCompositeExtract %float %266 1 + %269 = OpVectorShuffle %v2float %227 %227 0 1 + %270 = OpVectorShuffle %v2float %227 %227 2 3 + %271 = OpFAdd %v2float %269 %270 + %272 = OpFAdd %v2float %271 %262 + %273 = OpCompositeExtract %float %272 0 + %274 = OpCompositeExtract %float %272 1 + %275 = OpCompositeConstruct %v4float %267 %268 %273 %274 + OpStore %visibility %float_0 + OpStore %i %LightType_Point + OpBranch %282 + %282 = OpLabel + OpLoopMerge %283 %284 None + OpBranch %285 + %285 = OpLabel + %287 = OpLoad %uint %i + %288 = OpULessThan %bool %287 %shadowSampleCount + %286 = OpLogicalNot %bool %288 + OpSelectionMerge %289 None + OpBranchConditional %286 %290 %289 + %290 = OpLabel + OpBranch %283 + %289 = OpLabel + %291 = OpLoad %float %visibility + %293 = OpLoad %48 %shadowSampler + %294 = OpLoad %51 %shadowTexture + %296 = OpSampledImage %295 %294 %293 + %298 = OpLoad %uint %i + %300 = OpAccessChain %_ptr_Private_v2float %shadowSampleOffsets %298 + %301 = OpLoad %v2float %300 + %302 = OpFMul %v2float %301 %262 + %303 = OpFAdd %v2float %256 %302 + %304 = OpVectorShuffle %v2float %275 %275 0 1 + %305 = OpVectorShuffle %v2float %275 %275 2 3 + %297 = OpExtInst %v2float %116 NClamp %303 %304 %305 + %306 = OpCompositeExtract %float %250 2 + %308 = OpFSub %float %306 %float_0_00300000003 + %292 = OpImageSampleDrefExplicitLod %float %296 %297 %308 Lod %float_0 + %309 = OpFAdd %float %291 %292 + OpStore %visibility %309 + OpBranch %284 + %284 = OpLabel + %310 = OpLoad %uint %i + %311 = OpIAdd %uint %310 %LightType_Spot + OpStore %i %311 + OpBranch %282 + %283 = OpLabel + %312 = OpLoad %float %visibility + %314 = OpFDiv %float %312 %float_16 + OpReturnValue %314 + OpFunctionEnd +%getCubeFace = OpFunction %int None %315 + %v = OpFunctionParameter %v3float + %318 = OpLabel + %319 = OpExtInst %v3float %116 FAbs %v + %320 = OpCompositeExtract %float %319 2 + %321 = OpCompositeExtract %float %319 0 + %322 = OpFOrdGreaterThanEqual %bool %320 %321 + OpSelectionMerge %323 None + OpBranchConditional %322 %324 %323 + %324 = OpLabel + %325 = OpCompositeExtract %float %319 2 + %326 = OpCompositeExtract %float %319 1 + %327 = OpFOrdGreaterThanEqual %bool %325 %326 + OpBranch %323 + %323 = OpLabel + %328 = OpPhi %bool %322 %318 %327 %324 + OpSelectionMerge %329 None + OpBranchConditional %328 %330 %329 + %330 = OpLabel + %331 = OpCompositeExtract %float %v 2 + %332 = OpFOrdLessThan %bool %331 %float_0 + OpSelectionMerge %333 None + OpBranchConditional %332 %334 %333 + %334 = OpLabel + OpReturnValue %int_5 + %333 = OpLabel + OpReturnValue %int_4 + %329 = OpLabel + %337 = OpCompositeExtract %float %319 1 + %338 = OpCompositeExtract %float %319 0 + %339 = OpFOrdGreaterThanEqual %bool %337 %338 + OpSelectionMerge %340 None + OpBranchConditional %339 %341 %340 + %341 = OpLabel + %342 = OpCompositeExtract %float %v 1 + %343 = OpFOrdLessThan %bool %342 %float_0 + OpSelectionMerge %344 None + OpBranchConditional %343 %345 %344 + %345 = OpLabel + OpReturnValue %int_3 + %344 = OpLabel + OpReturnValue %int_2 + %340 = OpLabel + %348 = OpCompositeExtract %float %v 0 + %349 = OpFOrdLessThan %bool %348 %float_0 + OpSelectionMerge %350 None + OpBranchConditional %349 %351 %350 + %351 = OpLabel + OpReturnValue %int_1 + %350 = OpLabel + OpReturnValue %int_0 + OpFunctionEnd +%pointLightVisibility = OpFunction %float None %353 + %lightIndex = OpFunctionParameter %uint + %worldPos_0 = OpFunctionParameter %v3float +%pointToLight = OpFunctionParameter %v3float + %358 = OpLabel +%shadowIndex = OpVariable %_ptr_Function_int Function %364 + %388 = OpVariable %_ptr_Function_v2float Function %241 + %408 = OpVariable %_ptr_Function_v2float Function %241 +%visibility_0 = OpVariable %_ptr_Function_float Function %278 + %i_0 = OpVariable %_ptr_Function_uint Function %281 + %359 = OpIAdd %uint %lightIndex %LightType_Spot + %360 = OpAccessChain %_ptr_StorageBuffer_int %lightShadowTable %LightType_Point %359 + %361 = OpLoad %int %360 + OpStore %shadowIndex %361 + %365 = OpLoad %int %shadowIndex + %366 = OpIEqual %bool %365 %int_n1 + OpSelectionMerge %367 None + OpBranchConditional %366 %368 %367 + %368 = OpLabel + OpReturnValue %float_1 + %367 = OpLabel + %369 = OpLoad %int %shadowIndex + %372 = OpVectorTimesScalar %v3float %pointToLight %float_n1 + %370 = OpFunctionCall %int %getCubeFace %372 + %373 = OpIAdd %int %369 %370 + OpStore %shadowIndex %373 + %374 = OpLoad %int %shadowIndex + %375 = OpAccessChain %_ptr_StorageBuffer_v4float %shadow %LightType_Point %374 %LightType_Point + %376 = OpLoad %v4float %375 + %377 = OpLoad %int %shadowIndex + %378 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %shadow %LightType_Point %377 %LightType_Spot + %379 = OpLoad %mat4v4float %378 + %380 = OpCompositeExtract %float %worldPos_0 0 + %381 = OpCompositeExtract %float %worldPos_0 1 + %382 = OpCompositeExtract %float %worldPos_0 2 + %383 = OpCompositeConstruct %v4float %380 %381 %382 %float_1 + %384 = OpMatrixTimesVector %v4float %379 %383 + %385 = OpVectorShuffle %v2float %384 %384 0 1 + %386 = OpCompositeExtract %float %384 3 + %389 = OpCompositeConstruct %v2float %386 %386 + %387 = OpFDiv %v2float %385 %389 + %390 = OpFMul %v2float %387 %74 + %391 = OpFAdd %v2float %390 %75 + %392 = OpCompositeExtract %float %391 0 + %393 = OpCompositeExtract %float %391 1 + %394 = OpCompositeExtract %float %384 2 + %395 = OpCompositeExtract %float %384 3 + %396 = OpFDiv %float %394 %395 + %397 = OpCompositeConstruct %v3float %392 %393 %396 + %399 = OpVectorShuffle %v2float %376 %376 0 1 + %400 = OpVectorShuffle %v2float %397 %397 0 1 + %401 = OpVectorShuffle %v2float %376 %376 2 3 + %402 = OpFMul %v2float %400 %401 + %403 = OpFAdd %v2float %399 %402 + %406 = OpLoad %51 %shadowTexture + %405 = OpImageQuerySizeLod %v2int %406 %int_0 + %404 = OpConvertSToF %v2float %405 + %409 = OpCompositeConstruct %v2float %float_1 %float_1 + %407 = OpFDiv %v2float %409 %404 + %410 = OpVectorShuffle %v2float %376 %376 0 1 + %411 = OpCompositeExtract %float %410 0 + %412 = OpCompositeExtract %float %410 1 + %413 = OpVectorShuffle %v2float %376 %376 0 1 + %414 = OpVectorShuffle %v2float %376 %376 2 3 + %415 = OpFAdd %v2float %413 %414 + %416 = OpCompositeExtract %float %415 0 + %417 = OpCompositeExtract %float %415 1 + %418 = OpCompositeConstruct %v4float %411 %412 %416 %417 + OpStore %visibility_0 %float_0 + OpStore %i_0 %LightType_Point + OpBranch %421 + %421 = OpLabel + OpLoopMerge %422 %423 None + OpBranch %424 + %424 = OpLabel + %426 = OpLoad %uint %i_0 + %427 = OpULessThan %bool %426 %shadowSampleCount + %425 = OpLogicalNot %bool %427 + OpSelectionMerge %428 None + OpBranchConditional %425 %429 %428 + %429 = OpLabel + OpBranch %422 + %428 = OpLabel + %430 = OpLoad %float %visibility_0 + %432 = OpLoad %48 %shadowSampler + %433 = OpLoad %51 %shadowTexture + %434 = OpSampledImage %295 %433 %432 + %436 = OpLoad %uint %i_0 + %437 = OpAccessChain %_ptr_Private_v2float %shadowSampleOffsets %436 + %438 = OpLoad %v2float %437 + %439 = OpFMul %v2float %438 %407 + %440 = OpFAdd %v2float %403 %439 + %441 = OpVectorShuffle %v2float %418 %418 0 1 + %442 = OpVectorShuffle %v2float %418 %418 2 3 + %435 = OpExtInst %v2float %116 NClamp %440 %441 %442 + %443 = OpCompositeExtract %float %397 2 + %445 = OpFSub %float %443 %float_0_00999999978 + %431 = OpImageSampleDrefExplicitLod %float %434 %435 %445 Lod %float_0 + %446 = OpFAdd %float %430 %431 + OpStore %visibility_0 %446 + OpBranch %423 + %423 = OpLabel + %447 = OpLoad %uint %i_0 + %448 = OpIAdd %uint %447 %LightType_Spot + OpStore %i_0 %448 + OpBranch %421 + %422 = OpLabel + %449 = OpLoad %float %visibility_0 + %450 = OpFDiv %float %449 %float_16 + OpReturnValue %450 + OpFunctionEnd +%GetSurfaceInfo = OpFunction %SurfaceInfo None %451 + %input = OpFunctionParameter %VertexOutput + %456 = OpLabel + %surface = OpVariable %_ptr_Function_SurfaceInfo Function %459 + %462 = OpAccessChain %_ptr_Function_v3float %surface %uint_8 + %464 = OpCompositeExtract %v3float %input 2 + %463 = OpExtInst %v3float %116 Normalize %464 + OpStore %462 %463 + %466 = OpCompositeExtract %v3float %input 8 + %467 = OpCompositeExtract %v3float %input 9 + %468 = OpCompositeExtract %v3float %input 7 + %469 = OpCompositeConstruct %mat3v3float %466 %467 %468 + %471 = OpLoad %48 %normalSampler + %472 = OpLoad %94 %normalTexture + %474 = OpSampledImage %473 %472 %471 + %475 = OpCompositeExtract %v2float %input 3 + %470 = OpImageSampleImplicitLod %v4float %474 %475 + %476 = OpVectorShuffle %v3float %470 %470 0 1 2 + %478 = OpAccessChain %_ptr_Function_v3float %surface %uint_4 + %481 = OpVectorTimesScalar %v3float %476 %float_2 + %483 = OpFSub %v3float %481 %482 + %484 = OpMatrixTimesVector %v3float %469 %483 + %479 = OpExtInst %v3float %116 Normalize %484 + OpStore %478 %479 + %486 = OpLoad %48 %baseColorSampler + %487 = OpLoad %94 %baseColorTexture + %488 = OpSampledImage %473 %487 %486 + %489 = OpCompositeExtract %v2float %input 3 + %485 = OpImageSampleImplicitLod %v4float %488 %489 + %491 = OpAccessChain %_ptr_Function_v4float %surface %LightType_Point + %492 = OpCompositeExtract %v4float %input 5 + %494 = OpAccessChain %_ptr_Uniform_v4float %material %LightType_Point + %495 = OpLoad %v4float %494 + %496 = OpFMul %v4float %492 %495 + %497 = OpFMul %v4float %496 %485 + OpStore %491 %497 + %499 = OpAccessChain %_ptr_Function_float %surface %LightType_Point %uint_3 + %500 = OpLoad %float %499 + %501 = OpAccessChain %_ptr_Uniform_float %material %uint_4 + %502 = OpLoad %float %501 + %503 = OpFOrdLessThan %bool %500 %502 + OpSelectionMerge %504 None + OpBranchConditional %503 %505 %504 + %505 = OpLabel + OpKill + %504 = OpLabel + %506 = OpAccessChain %_ptr_Function_v3float %surface %LightType_Spot + %507 = OpAccessChain %_ptr_Function_v4float %surface %LightType_Point + %508 = OpLoad %v4float %507 + %509 = OpVectorShuffle %v3float %508 %508 0 1 2 + OpStore %506 %509 + %511 = OpLoad %48 %metallicRoughnessSampler + %512 = OpLoad %94 %metallicRoughnessTexture + %513 = OpSampledImage %473 %512 %511 + %514 = OpCompositeExtract %v2float %input 3 + %510 = OpImageSampleImplicitLod %v4float %513 %514 + %515 = OpAccessChain %_ptr_Function_float %surface %LightType_Directional + %516 = OpAccessChain %_ptr_Uniform_float %material %uint_3 %LightType_Point + %517 = OpLoad %float %516 + %518 = OpCompositeExtract %float %510 2 + %519 = OpFMul %float %517 %518 + OpStore %515 %519 + %520 = OpAccessChain %_ptr_Function_float %surface %uint_3 + %521 = OpAccessChain %_ptr_Uniform_float %material %uint_3 %LightType_Spot + %522 = OpLoad %float %521 + %523 = OpCompositeExtract %float %510 1 + %524 = OpFMul %float %522 %523 + OpStore %520 %524 + %527 = OpAccessChain %_ptr_Function_v3float %surface %uint_5 + %529 = OpAccessChain %_ptr_Function_v3float %surface %LightType_Spot + %530 = OpLoad %v3float %529 + %531 = OpAccessChain %_ptr_Function_float %surface %LightType_Directional + %532 = OpLoad %float %531 + %533 = OpCompositeConstruct %v3float %532 %532 %532 + %528 = OpExtInst %v3float %116 FMix %526 %530 %533 + OpStore %527 %528 + %535 = OpLoad %48 %occlusionSampler + %536 = OpLoad %94 %occlusionTexture + %537 = OpSampledImage %473 %536 %535 + %538 = OpCompositeExtract %v2float %input 3 + %534 = OpImageSampleImplicitLod %v4float %537 %538 + %539 = OpAccessChain %_ptr_Function_float %surface %uint_6 + %540 = OpAccessChain %_ptr_Uniform_float %material %LightType_Directional + %541 = OpLoad %float %540 + %542 = OpCompositeExtract %float %534 0 + %543 = OpFMul %float %541 %542 + OpStore %539 %543 + %545 = OpLoad %48 %emissiveSampler + %546 = OpLoad %94 %emissiveTexture + %547 = OpSampledImage %473 %546 %545 + %548 = OpCompositeExtract %v2float %input 3 + %544 = OpImageSampleImplicitLod %v4float %547 %548 + %549 = OpAccessChain %_ptr_Function_v3float %surface %uint_7 + %551 = OpAccessChain %_ptr_Uniform_v3float %material %LightType_Spot + %552 = OpLoad %v3float %551 + %553 = OpVectorShuffle %v3float %544 %544 0 1 2 + %554 = OpFMul %v3float %552 %553 + OpStore %549 %554 + %555 = OpCompositeExtract %v4float %input 6 + %556 = OpCompositeExtract %float %555 3 + %557 = OpFOrdEqual %bool %556 %float_0 + OpSelectionMerge %558 None + OpBranchConditional %557 %559 %560 + %559 = OpLabel + %561 = OpAccessChain %_ptr_Function_v3float %surface %LightType_Spot + %562 = OpAccessChain %_ptr_Function_v3float %surface %LightType_Spot + %563 = OpLoad %v3float %562 + %564 = OpCompositeExtract %v4float %input 6 + %565 = OpVectorShuffle %v3float %564 %564 0 1 2 + %566 = OpFAdd %v3float %563 %565 + OpStore %561 %566 + OpBranch %558 + %560 = OpLabel + %567 = OpAccessChain %_ptr_Function_v3float %surface %LightType_Spot + %568 = OpAccessChain %_ptr_Function_v3float %surface %LightType_Spot + %569 = OpLoad %v3float %568 + %570 = OpCompositeExtract %v4float %input 6 + %571 = OpVectorShuffle %v3float %570 %570 0 1 2 + %572 = OpFMul %v3float %569 %571 + OpStore %567 %572 + OpBranch %558 + %558 = OpLabel + %573 = OpLoad %SurfaceInfo %surface + OpReturnValue %573 + OpFunctionEnd +%FresnelSchlick = OpFunction %v3float None %574 + %cosTheta = OpFunctionParameter %float + %F0 = OpFunctionParameter %v3float + %578 = OpLabel + %579 = OpFSub %v3float %482 %F0 + %581 = OpFSub %float %float_1 %cosTheta + %580 = OpExtInst %float %116 Pow %581 %float_5 + %583 = OpVectorTimesScalar %v3float %579 %580 + %584 = OpFAdd %v3float %F0 %583 + OpReturnValue %584 + OpFunctionEnd +%DistributionGGX = OpFunction %float None %585 + %N = OpFunctionParameter %v3float + %H = OpFunctionParameter %v3float + %roughness = OpFunctionParameter %float + %590 = OpLabel + %591 = OpFMul %float %roughness %roughness + %592 = OpFMul %float %591 %591 + %594 = OpDot %float %N %H + %593 = OpExtInst %float %116 NMax %594 %float_0 + %595 = OpFMul %float %593 %593 + %596 = OpFSub %float %592 %float_1 + %597 = OpFMul %float %595 %596 + %598 = OpFAdd %float %597 %float_1 + %599 = OpFMul %float %PI %598 + %600 = OpFMul %float %599 %598 + %601 = OpFDiv %float %592 %600 + OpReturnValue %601 + OpFunctionEnd +%GeometrySchlickGGX = OpFunction %float None %602 + %NdotV = OpFunctionParameter %float +%roughness_0 = OpFunctionParameter %float + %606 = OpLabel + %607 = OpFAdd %float %roughness_0 %float_1 + %608 = OpFMul %float %607 %607 + %610 = OpFDiv %float %608 %float_8 + %611 = OpFSub %float %float_1 %610 + %612 = OpFMul %float %NdotV %611 + %613 = OpFAdd %float %612 %610 + %614 = OpFDiv %float %NdotV %613 + OpReturnValue %614 + OpFunctionEnd +%GeometrySmith = OpFunction %float None %615 + %N_0 = OpFunctionParameter %v3float + %V = OpFunctionParameter %v3float + %L = OpFunctionParameter %v3float +%roughness_1 = OpFunctionParameter %float + %621 = OpLabel + %623 = OpDot %float %N_0 %V + %622 = OpExtInst %float %116 NMax %623 %float_0 + %625 = OpDot %float %N_0 %L + %624 = OpExtInst %float %116 NMax %625 %float_0 + %626 = OpFunctionCall %float %GeometrySchlickGGX %622 %roughness_1 + %627 = OpFunctionCall %float %GeometrySchlickGGX %624 %roughness_1 + %628 = OpFMul %float %627 %626 + OpReturnValue %628 + OpFunctionEnd +%lightAttenuation = OpFunction %float None %629 + %light = OpFunctionParameter %PuctualLight + %633 = OpLabel + %634 = OpCompositeExtract %uint %light 0 + %635 = OpIEqual %bool %634 %LightType_Directional + OpSelectionMerge %636 None + OpBranchConditional %635 %637 %636 + %637 = OpLabel + OpReturnValue %float_1 + %636 = OpLabel + %639 = OpCompositeExtract %v3float %light 1 + %638 = OpExtInst %float %116 Length %639 + %640 = OpCompositeExtract %float %light 2 + %641 = OpFOrdLessThanEqual %bool %640 %float_0 + OpSelectionMerge %642 None + OpBranchConditional %641 %643 %642 + %643 = OpLabel + %644 = OpExtInst %float %116 Pow %638 %float_2 + %645 = OpFDiv %float %float_1 %644 + OpReturnValue %645 + %642 = OpLabel + %648 = OpCompositeExtract %float %light 2 + %649 = OpFDiv %float %638 %648 + %647 = OpExtInst %float %116 Pow %649 %float_4 + %651 = OpFSub %float %float_1 %647 + %646 = OpExtInst %float %116 NClamp %651 %float_0 %float_1 + %652 = OpExtInst %float %116 Pow %638 %float_2 + %653 = OpFDiv %float %646 %652 + OpReturnValue %653 + OpFunctionEnd +%lightRadiance = OpFunction %v3float None %654 + %light_0 = OpFunctionParameter %PuctualLight + %surface_0 = OpFunctionParameter %SurfaceInfo + %658 = OpLabel + %660 = OpCompositeExtract %v3float %light_0 1 + %659 = OpExtInst %v3float %116 Normalize %660 + %662 = OpCompositeExtract %v3float %surface_0 8 + %663 = OpFAdd %v3float %662 %659 + %661 = OpExtInst %v3float %116 Normalize %663 + %665 = OpCompositeExtract %v3float %surface_0 4 + %666 = OpCompositeExtract %float %surface_0 3 + %664 = OpFunctionCall %float %DistributionGGX %665 %661 %666 + %668 = OpCompositeExtract %v3float %surface_0 4 + %669 = OpCompositeExtract %v3float %surface_0 8 + %670 = OpCompositeExtract %float %surface_0 3 + %667 = OpFunctionCall %float %GeometrySmith %668 %669 %659 %670 + %674 = OpCompositeExtract %v3float %surface_0 8 + %673 = OpDot %float %661 %674 + %672 = OpExtInst %float %116 NMax %673 %float_0 + %675 = OpCompositeExtract %v3float %surface_0 5 + %671 = OpFunctionCall %v3float %FresnelSchlick %672 %675 + %676 = OpFSub %v3float %482 %671 + %677 = OpCompositeExtract %float %surface_0 2 + %678 = OpFSub %float %float_1 %677 + %679 = OpVectorTimesScalar %v3float %676 %678 + %682 = OpCompositeExtract %v3float %surface_0 4 + %681 = OpDot %float %682 %659 + %680 = OpExtInst %float %116 NMax %681 %float_0 + %683 = OpFMul %float %664 %667 + %684 = OpVectorTimesScalar %v3float %671 %683 + %688 = OpCompositeExtract %v3float %surface_0 4 + %689 = OpCompositeExtract %v3float %surface_0 8 + %687 = OpDot %float %688 %689 + %686 = OpExtInst %float %116 NMax %687 %float_0 + %690 = OpFMul %float %float_4 %686 + %691 = OpFMul %float %690 %680 + %685 = OpExtInst %float %116 NMax %691 %float_0_00100000005 + %693 = OpCompositeConstruct %v3float %685 %685 %685 + %694 = OpFDiv %v3float %684 %693 + %695 = OpCompositeExtract %v3float %light_0 3 + %696 = OpCompositeExtract %float %light_0 4 + %697 = OpVectorTimesScalar %v3float %695 %696 + %698 = OpFunctionCall %float %lightAttenuation %light_0 + %699 = OpVectorTimesScalar %v3float %697 %698 + %700 = OpCompositeExtract %v3float %surface_0 1 + %701 = OpFMul %v3float %679 %700 + %703 = OpFDiv %v3float %701 %702 + %704 = OpFAdd %v3float %703 %694 + %705 = OpFMul %v3float %704 %699 + %706 = OpVectorTimesScalar %v3float %705 %680 + OpReturnValue %706 + OpFunctionEnd +%fragmentMain_inner = OpFunction %FragmentOutput None %707 + %input_0 = OpFunctionParameter %VertexOutput + %711 = OpLabel + %Lo = OpVariable %_ptr_Function_v3float Function %715 + %light_1 = OpVariable %_ptr_Function_PuctualLight Function %724 +%lightIndex_0 = OpVariable %_ptr_Function_uint Function %281 + %light_2 = OpVariable %_ptr_Function_PuctualLight Function %724 + %out = OpVariable %_ptr_Function_FragmentOutput Function %818 + %712 = OpFunctionCall %SurfaceInfo %GetSurfaceInfo %input_0 + OpStore %Lo %713 + %717 = OpAccessChain %_ptr_StorageBuffer_float %globalLights %LightType_Directional + %718 = OpLoad %float %717 + %719 = OpFOrdGreaterThan %bool %718 %float_0 + OpSelectionMerge %720 None + OpBranchConditional %719 %721 %720 + %721 = OpLabel + %725 = OpAccessChain %_ptr_Function_uint %light_1 %LightType_Point + OpStore %725 %LightType_Directional + %726 = OpAccessChain %_ptr_Function_v3float %light_1 %LightType_Spot + %728 = OpAccessChain %_ptr_StorageBuffer_v3float %globalLights %uint_3 + %729 = OpLoad %v3float %728 + OpStore %726 %729 + %730 = OpAccessChain %_ptr_Function_v3float %light_1 %uint_3 + %731 = OpAccessChain %_ptr_StorageBuffer_v3float %globalLights %LightType_Spot + %732 = OpLoad %v3float %731 + OpStore %730 %732 + %733 = OpAccessChain %_ptr_Function_float %light_1 %uint_4 + %734 = OpAccessChain %_ptr_StorageBuffer_float %globalLights %LightType_Directional + %735 = OpLoad %float %734 + OpStore %733 %735 + %737 = OpCompositeExtract %v3float %input_0 1 + %736 = OpFunctionCall %float %dirLightVisibility %737 + %738 = OpLoad %v3float %Lo + %740 = OpLoad %PuctualLight %light_1 + %739 = OpFunctionCall %v3float %lightRadiance %740 %712 + %741 = OpVectorTimesScalar %v3float %739 %736 + %742 = OpFAdd %v3float %738 %741 + OpStore %Lo %742 + OpBranch %720 + %720 = OpLabel + %744 = OpCompositeExtract %v4float %input_0 0 + %743 = OpFunctionCall %uint %getClusterIndex %744 + %746 = OpAccessChain %_ptr_StorageBuffer_uint %clusterLights %LightType_Spot %743 %LightType_Point + %747 = OpLoad %uint %746 + %748 = OpAccessChain %_ptr_StorageBuffer_uint %clusterLights %LightType_Spot %743 %LightType_Spot + %749 = OpLoad %uint %748 + OpStore %lightIndex_0 %LightType_Point + OpBranch %751 + %751 = OpLabel + OpLoopMerge %752 %753 None + OpBranch %754 + %754 = OpLabel + %756 = OpLoad %uint %lightIndex_0 + %757 = OpULessThan %bool %756 %749 + %755 = OpLogicalNot %bool %757 + OpSelectionMerge %758 None + OpBranchConditional %755 %759 %758 + %759 = OpLabel + OpBranch %752 + %758 = OpLabel + %760 = OpLoad %uint %lightIndex_0 + %761 = OpIAdd %uint %747 %760 + %762 = OpAccessChain %_ptr_StorageBuffer_uint %clusterLights %LightType_Directional %761 + %763 = OpLoad %uint %762 + %765 = OpAccessChain %_ptr_Function_uint %light_2 %LightType_Point + OpStore %765 %LightType_Point + %766 = OpAccessChain %_ptr_Function_v3float %light_2 %LightType_Spot + %767 = OpAccessChain %_ptr_StorageBuffer_v3float %globalLights %uint_5 %763 %LightType_Point + %768 = OpLoad %v3float %767 + %769 = OpVectorShuffle %v3float %768 %768 0 1 2 + %770 = OpCompositeExtract %v3float %input_0 1 + %771 = OpFSub %v3float %769 %770 + OpStore %766 %771 + %772 = OpAccessChain %_ptr_Function_float %light_2 %LightType_Directional + %773 = OpAccessChain %_ptr_StorageBuffer_float %globalLights %uint_5 %763 %LightType_Spot + %774 = OpLoad %float %773 + OpStore %772 %774 + %775 = OpAccessChain %_ptr_Function_v3float %light_2 %uint_3 + %776 = OpAccessChain %_ptr_StorageBuffer_v3float %globalLights %uint_5 %763 %LightType_Directional + %777 = OpLoad %v3float %776 + OpStore %775 %777 + %778 = OpAccessChain %_ptr_Function_float %light_2 %uint_4 + %779 = OpAccessChain %_ptr_StorageBuffer_float %globalLights %uint_5 %763 %uint_3 + %780 = OpLoad %float %779 + OpStore %778 %780 + %782 = OpCompositeExtract %v3float %input_0 1 + %783 = OpAccessChain %_ptr_Function_v3float %light_2 %LightType_Spot + %784 = OpLoad %v3float %783 + %781 = OpFunctionCall %float %pointLightVisibility %763 %782 %784 + %785 = OpLoad %v3float %Lo + %787 = OpLoad %PuctualLight %light_2 + %786 = OpFunctionCall %v3float %lightRadiance %787 %712 + %788 = OpVectorTimesScalar %v3float %786 %781 + %789 = OpFAdd %v3float %785 %788 + OpStore %Lo %789 + OpBranch %753 + %753 = OpLabel + %790 = OpLoad %uint %lightIndex_0 + %791 = OpIAdd %uint %790 %LightType_Spot + OpStore %lightIndex_0 %791 + OpBranch %751 + %752 = OpLabel + %792 = OpCompositeExtract %v4float %input_0 0 + %793 = OpVectorShuffle %v2float %792 %792 0 1 + %796 = OpLoad %94 %ssaoTexture + %795 = OpImageQuerySizeLod %v2int %796 %int_0 + %797 = OpVectorShuffle %v2int %795 %795 0 1 + %794 = OpConvertSToF %v2float %797 + %798 = OpFDiv %v2float %793 %794 + %800 = OpLoad %48 %defaultSampler + %801 = OpLoad %94 %ssaoTexture + %802 = OpSampledImage %473 %801 %800 + %799 = OpImageSampleImplicitLod %v4float %802 %798 + %803 = OpCompositeExtract %float %799 0 + %804 = OpAccessChain %_ptr_StorageBuffer_v3float %globalLights %LightType_Point + %805 = OpLoad %v3float %804 + %806 = OpCompositeExtract %v3float %712 1 + %807 = OpFMul %v3float %805 %806 + %808 = OpCompositeExtract %float %712 6 + %809 = OpVectorTimesScalar %v3float %807 %808 + %810 = OpVectorTimesScalar %v3float %809 %803 + %812 = OpLoad %v3float %Lo + %813 = OpFAdd %v3float %812 %810 + %814 = OpCompositeExtract %v3float %712 7 + %815 = OpFAdd %v3float %813 %814 + %811 = OpFunctionCall %v3float %linearTosRGB %815 + %819 = OpAccessChain %_ptr_Function_v4float %out %LightType_Point + %820 = OpCompositeExtract %float %811 0 + %821 = OpCompositeExtract %float %811 1 + %822 = OpCompositeExtract %float %811 2 + %823 = OpCompositeExtract %v4float %712 0 + %824 = OpCompositeExtract %float %823 3 + %825 = OpCompositeConstruct %v4float %820 %821 %822 %824 + OpStore %819 %825 + %826 = OpAccessChain %_ptr_Function_v4float %out %LightType_Spot + %827 = OpCompositeExtract %v3float %712 7 + %828 = OpCompositeExtract %float %827 0 + %829 = OpCompositeExtract %float %827 1 + %830 = OpCompositeExtract %float %827 2 + %831 = OpCompositeExtract %v4float %712 0 + %832 = OpCompositeExtract %float %831 3 + %833 = OpCompositeConstruct %v4float %828 %829 %830 %832 + OpStore %826 %833 + %834 = OpLoad %FragmentOutput %out + OpReturnValue %834 + OpFunctionEnd +%fragmentMain = OpFunction %void None %835 + %838 = OpLabel + %840 = OpLoad %v4float %position_1 + %841 = OpLoad %v3float %worldPos_1 + %842 = OpLoad %v3float %view_1 + %843 = OpLoad %v2float %texcoord_1 + %844 = OpLoad %v2float %texcoord2_1 + %845 = OpLoad %v4float %color_1 + %846 = OpLoad %v4float %instanceColor_1 + %847 = OpLoad %v3float %normal_1 + %848 = OpLoad %v3float %tangent_1 + %849 = OpLoad %v3float %bitangent_1 + %850 = OpCompositeConstruct %VertexOutput %840 %841 %842 %843 %844 %845 %846 %847 %848 %849 + %839 = OpFunctionCall %FragmentOutput %fragmentMain_inner %850 + %851 = OpCompositeExtract %v4float %839 0 + OpStore %color_2 %851 + %852 = OpCompositeExtract %v4float %839 1 + OpStore %emissive_1 %852 + OpReturn + OpFunctionEnd diff --git a/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.wgsl b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.wgsl new file mode 100644 index 0000000000..a38a624e02 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-fragment.wgsl.expected.wgsl @@ -0,0 +1,372 @@ +benchmark/skinned-shadowed-pbr-fragment.wgsl:51:13 warning: use of deprecated language feature: the @stride attribute is deprecated; use a larger type if necessary + lights : @stride(32) array; + ^^^^^^ + +let GAMMA = 2.200000048; + +fn linearTosRGB(linear : vec3) -> vec3 { + let INV_GAMMA = (1.0 / GAMMA); + return pow(linear, vec3(INV_GAMMA)); +} + +fn sRGBToLinear(srgb : vec3) -> vec3 { + return pow(srgb, vec3(GAMMA)); +} + +struct Camera { + projection : mat4x4; + inverseProjection : mat4x4; + view : mat4x4; + position : vec3; + time : f32; + outputSize : vec2; + zNear : f32; + zFar : f32; +} + +@binding(0) @group(0) var camera : Camera; + +struct ClusterLights { + offset : u32; + count : u32; +} + +struct ClusterLightGroup { + offset : u32; + lights : array; + indices : array; +} + +@binding(1) @group(0) var clusterLights : ClusterLightGroup; + +struct Light { + position : vec3; + range : f32; + color : vec3; + intensity : f32; +} + +struct GlobalLights { + ambient : vec3; + dirColor : vec3; + dirIntensity : f32; + dirDirection : vec3; + lightCount : u32; + lights : @stride(32) array; +} + +@binding(2) @group(0) var globalLights : GlobalLights; + +let tileCount = vec3(32u, 18u, 48u); + +fn linearDepth(depthSample : f32) -> f32 { + return ((camera.zFar * camera.zNear) / fma(depthSample, (camera.zNear - camera.zFar), camera.zFar)); +} + +fn getTile(fragCoord : vec4) -> vec3 { + let sliceScale = (f32(tileCount.z) / log2((camera.zFar / camera.zNear))); + let sliceBias = -(((f32(tileCount.z) * log2(camera.zNear)) / log2((camera.zFar / camera.zNear)))); + let zTile = u32(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0)); + return vec3(u32((fragCoord.x / (camera.outputSize.x / f32(tileCount.x)))), u32((fragCoord.y / (camera.outputSize.y / f32(tileCount.y)))), zTile); +} + +fn getClusterIndex(fragCoord : vec4) -> u32 { + let tile = getTile(fragCoord); + return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y)); +} + +@binding(3) @group(0) var defaultSampler : sampler; + +@binding(4) @group(0) var shadowTexture : texture_depth_2d; + +@binding(5) @group(0) var shadowSampler : sampler_comparison; + +struct LightShadowTable { + light : array; +} + +@binding(6) @group(0) var lightShadowTable : LightShadowTable; + +var shadowSampleOffsets : array, 16> = array, 16>(vec2(-1.5, -1.5), vec2(-1.5, -0.5), vec2(-1.5, 0.5), vec2(-1.5, 1.5), vec2(-0.5, -1.5), vec2(-0.5, -0.5), vec2(-0.5, 0.5), vec2(-0.5, 1.5), vec2(0.5, -1.5), vec2(0.5, -0.5), vec2(0.5, 0.5), vec2(0.5, 1.5), vec2(1.5, -1.5), vec2(1.5, -0.5), vec2(1.5, 0.5), vec2(1.5, 1.5)); + +let shadowSampleCount = 16u; + +struct ShadowProperties { + viewport : vec4; + viewProj : mat4x4; +} + +struct LightShadows { + properties : array; +} + +@binding(7) @group(0) var shadow : LightShadows; + +fn dirLightVisibility(worldPos : vec3) -> f32 { + let shadowIndex = lightShadowTable.light[0u]; + if ((shadowIndex == -1)) { + return 1.0; + } + let viewport = shadow.properties[shadowIndex].viewport; + let lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0)); + let shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5, -0.5)) + vec2(0.5, 0.5)), (lightPos.z / lightPos.w)); + let viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw))); + let texelSize = (1.0 / vec2(textureDimensions(shadowTexture, 0))); + let clampRect = vec4((viewport.xy - texelSize), ((viewport.xy + viewport.zw) + texelSize)); + var visibility = 0.0; + for(var i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + textureSampleCompareLevel(shadowTexture, shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.003))); + } + return (visibility / f32(shadowSampleCount)); +} + +fn getCubeFace(v : vec3) -> i32 { + let vAbs = abs(v); + if (((vAbs.z >= vAbs.x) && (vAbs.z >= vAbs.y))) { + if ((v.z < 0.0)) { + return 5; + } + return 4; + } + if ((vAbs.y >= vAbs.x)) { + if ((v.y < 0.0)) { + return 3; + } + return 2; + } + if ((v.x < 0.0)) { + return 1; + } + return 0; +} + +fn pointLightVisibility(lightIndex : u32, worldPos : vec3, pointToLight : vec3) -> f32 { + var shadowIndex = lightShadowTable.light[(lightIndex + 1u)]; + if ((shadowIndex == -1)) { + return 1.0; + } + shadowIndex = (shadowIndex + getCubeFace((pointToLight * -1.0))); + let viewport = shadow.properties[shadowIndex].viewport; + let lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0)); + let shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5, -0.5)) + vec2(0.5, 0.5)), (lightPos.z / lightPos.w)); + let viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw))); + let texelSize = (1.0 / vec2(textureDimensions(shadowTexture, 0))); + let clampRect = vec4(viewport.xy, (viewport.xy + viewport.zw)); + var visibility = 0.0; + for(var i = 0u; (i < shadowSampleCount); i = (i + 1u)) { + visibility = (visibility + textureSampleCompareLevel(shadowTexture, shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.01))); + } + return (visibility / f32(shadowSampleCount)); +} + +struct VertexOutput { + @builtin(position) + position : vec4; + @location(0) + worldPos : vec3; + @location(1) + view : vec3; + @location(2) + texcoord : vec2; + @location(3) + texcoord2 : vec2; + @location(4) + color : vec4; + @location(5) + instanceColor : vec4; + @location(6) + normal : vec3; + @location(7) + tangent : vec3; + @location(8) + bitangent : vec3; +} + +struct Material { + baseColorFactor : vec4; + emissiveFactor : vec3; + occlusionStrength : f32; + metallicRoughnessFactor : vec2; + alphaCutoff : f32; +} + +@binding(8) @group(0) var material : Material; + +@binding(9) @group(0) var baseColorTexture : texture_2d; + +@binding(10) @group(0) var baseColorSampler : sampler; + +@binding(11) @group(0) var normalTexture : texture_2d; + +@binding(12) @group(0) var normalSampler : sampler; + +@binding(13) @group(0) var metallicRoughnessTexture : texture_2d; + +@binding(14) @group(0) var metallicRoughnessSampler : sampler; + +@binding(15) @group(0) var occlusionTexture : texture_2d; + +@binding(16) @group(0) var occlusionSampler : sampler; + +@binding(17) @group(0) var emissiveTexture : texture_2d; + +@binding(18) @group(0) var emissiveSampler : sampler; + +struct SurfaceInfo { + baseColor : vec4; + albedo : vec3; + metallic : f32; + roughness : f32; + normal : vec3; + f0 : vec3; + ao : f32; + emissive : vec3; + v : vec3; +} + +fn GetSurfaceInfo(input : VertexOutput) -> SurfaceInfo { + var surface : SurfaceInfo; + surface.v = normalize(input.view); + let tbn = mat3x3(input.tangent, input.bitangent, input.normal); + let normalMap = textureSample(normalTexture, normalSampler, input.texcoord).rgb; + surface.normal = normalize((tbn * ((2.0 * normalMap) - vec3(1.0)))); + let baseColorMap = textureSample(baseColorTexture, baseColorSampler, input.texcoord); + surface.baseColor = ((input.color * material.baseColorFactor) * baseColorMap); + if ((surface.baseColor.a < material.alphaCutoff)) { + discard; + } + surface.albedo = surface.baseColor.rgb; + let metallicRoughnessMap = textureSample(metallicRoughnessTexture, metallicRoughnessSampler, input.texcoord); + surface.metallic = (material.metallicRoughnessFactor.x * metallicRoughnessMap.b); + surface.roughness = (material.metallicRoughnessFactor.y * metallicRoughnessMap.g); + let dielectricSpec = vec3(0.039999999); + surface.f0 = mix(dielectricSpec, surface.albedo, vec3(surface.metallic)); + let occlusionMap = textureSample(occlusionTexture, occlusionSampler, input.texcoord); + surface.ao = (material.occlusionStrength * occlusionMap.r); + let emissiveMap = textureSample(emissiveTexture, emissiveSampler, input.texcoord); + surface.emissive = (material.emissiveFactor * emissiveMap.rgb); + if ((input.instanceColor.a == 0.0)) { + surface.albedo = (surface.albedo + input.instanceColor.rgb); + } else { + surface.albedo = (surface.albedo * input.instanceColor.rgb); + } + return surface; +} + +let PI = 3.141592741; + +let LightType_Point = 0u; + +let LightType_Spot = 1u; + +let LightType_Directional = 2u; + +struct PuctualLight { + lightType : u32; + pointToLight : vec3; + range : f32; + color : vec3; + intensity : f32; +} + +fn FresnelSchlick(cosTheta : f32, F0 : vec3) -> vec3 { + return (F0 + ((vec3(1.0) - F0) * pow((1.0 - cosTheta), 5.0))); +} + +fn DistributionGGX(N : vec3, H : vec3, roughness : f32) -> f32 { + let a = (roughness * roughness); + let a2 = (a * a); + let NdotH = max(dot(N, H), 0.0); + let NdotH2 = (NdotH * NdotH); + let num = a2; + let denom = ((NdotH2 * (a2 - 1.0)) + 1.0); + return (num / ((PI * denom) * denom)); +} + +fn GeometrySchlickGGX(NdotV : f32, roughness : f32) -> f32 { + let r = (roughness + 1.0); + let k = ((r * r) / 8.0); + let num = NdotV; + let denom = ((NdotV * (1.0 - k)) + k); + return (num / denom); +} + +fn GeometrySmith(N : vec3, V : vec3, L : vec3, roughness : f32) -> f32 { + let NdotV = max(dot(N, V), 0.0); + let NdotL = max(dot(N, L), 0.0); + let ggx2 = GeometrySchlickGGX(NdotV, roughness); + let ggx1 = GeometrySchlickGGX(NdotL, roughness); + return (ggx1 * ggx2); +} + +fn lightAttenuation(light : PuctualLight) -> f32 { + if ((light.lightType == LightType_Directional)) { + return 1.0; + } + let distance = length(light.pointToLight); + if ((light.range <= 0.0)) { + return (1.0 / pow(distance, 2.0)); + } + return (clamp((1.0 - pow((distance / light.range), 4.0)), 0.0, 1.0) / pow(distance, 2.0)); +} + +fn lightRadiance(light : PuctualLight, surface : SurfaceInfo) -> vec3 { + let L = normalize(light.pointToLight); + let H = normalize((surface.v + L)); + let NDF = DistributionGGX(surface.normal, H, surface.roughness); + let G = GeometrySmith(surface.normal, surface.v, L, surface.roughness); + let F = FresnelSchlick(max(dot(H, surface.v), 0.0), surface.f0); + let kD = ((vec3(1.0) - F) * (1.0 - surface.metallic)); + let NdotL = max(dot(surface.normal, L), 0.0); + let numerator = ((NDF * G) * F); + let denominator = max(((4.0 * max(dot(surface.normal, surface.v), 0.0)) * NdotL), 0.001); + let specular = (numerator / vec3(denominator)); + let radiance = ((light.color * light.intensity) * lightAttenuation(light)); + return (((((kD * surface.albedo) / vec3(PI)) + specular) * radiance) * NdotL); +} + +@binding(19) @group(0) var ssaoTexture : texture_2d; + +struct FragmentOutput { + @location(0) + color : vec4; + @location(1) + emissive : vec4; +} + +@stage(fragment) +fn fragmentMain(input : VertexOutput) -> FragmentOutput { + let surface = GetSurfaceInfo(input); + var Lo = vec3(0.0, 0.0, 0.0); + if ((globalLights.dirIntensity > 0.0)) { + var light : PuctualLight; + light.lightType = LightType_Directional; + light.pointToLight = globalLights.dirDirection; + light.color = globalLights.dirColor; + light.intensity = globalLights.dirIntensity; + let lightVis = dirLightVisibility(input.worldPos); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + let clusterIndex = getClusterIndex(input.position); + let lightOffset = clusterLights.lights[clusterIndex].offset; + let lightCount = clusterLights.lights[clusterIndex].count; + for(var lightIndex = 0u; (lightIndex < lightCount); lightIndex = (lightIndex + 1u)) { + let i = clusterLights.indices[(lightOffset + lightIndex)]; + var light : PuctualLight; + light.lightType = LightType_Point; + light.pointToLight = (globalLights.lights[i].position.xyz - input.worldPos); + light.range = globalLights.lights[i].range; + light.color = globalLights.lights[i].color; + light.intensity = globalLights.lights[i].intensity; + let lightVis = pointLightVisibility(i, input.worldPos, light.pointToLight); + Lo = (Lo + (lightRadiance(light, surface) * lightVis)); + } + let ssaoCoord = (input.position.xy / vec2(textureDimensions(ssaoTexture).xy)); + let ssaoFactor = textureSample(ssaoTexture, defaultSampler, ssaoCoord).r; + let ambient = (((globalLights.ambient * surface.albedo) * surface.ao) * ssaoFactor); + let color = linearTosRGB(((Lo + ambient) + surface.emissive)); + var out : FragmentOutput; + out.color = vec4(color, surface.baseColor.a); + out.emissive = vec4(surface.emissive, surface.baseColor.a); + return out; +} diff --git a/test/benchmark/skinned-shadowed-pbr-vertex.wgsl b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl new file mode 100644 index 0000000000..52304590fd --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl @@ -0,0 +1,98 @@ +struct VertexInput { + @location(0) + position : vec4; + @location(1) + normal : vec3; + @location(2) + tangent : vec4; + @location(3) + texcoord : vec2; + @location(6) + joints : vec4; + @location(7) + weights : vec4; + @location(8) + instance0 : vec4; + @location(9) + instance1 : vec4; + @location(10) + instance2 : vec4; + @location(11) + instance3 : vec4; + @location(12) + instanceColor : vec4; +} + +struct VertexOutput { + @builtin(position) + position : vec4; + @location(0) + worldPos : vec3; + @location(1) + view : vec3; + @location(2) + texcoord : vec2; + @location(3) + texcoord2 : vec2; + @location(4) + color : vec4; + @location(5) + instanceColor : vec4; + @location(6) + normal : vec3; + @location(7) + tangent : vec3; + @location(8) + bitangent : vec3; +} + +struct Camera { + projection : mat4x4; + inverseProjection : mat4x4; + view : mat4x4; + position : vec3; + time : f32; + outputSize : vec2; + zNear : f32; + zFar : f32; +} + +@binding(0) @group(0) var camera : Camera; + +fn getInstanceMatrix(input : VertexInput) -> mat4x4 { + return mat4x4(input.instance0, input.instance1, input.instance2, input.instance3); +} + +struct Joints { + matrices : array>; +} + +@binding(1) @group(0) var joint : Joints; + +@binding(2) @group(0) var inverseBind : Joints; + +fn getSkinMatrix(input : VertexInput) -> mat4x4 { + let joint0 = (joint.matrices[input.joints.x] * inverseBind.matrices[input.joints.x]); + let joint1 = (joint.matrices[input.joints.y] * inverseBind.matrices[input.joints.y]); + let joint2 = (joint.matrices[input.joints.z] * inverseBind.matrices[input.joints.z]); + let joint3 = (joint.matrices[input.joints.w] * inverseBind.matrices[input.joints.w]); + let skinMatrix = ((((joint0 * input.weights.x) + (joint1 * input.weights.y)) + (joint2 * input.weights.z)) + (joint3 * input.weights.w)); + return skinMatrix; +} + +@stage(vertex) +fn vertexMain(input : VertexInput) -> VertexOutput { + var output : VertexOutput; + let modelMatrix = getSkinMatrix(input); + output.normal = normalize(((modelMatrix * vec4(input.normal, 0.0))).xyz); + output.tangent = normalize(((modelMatrix * vec4(input.tangent.xyz, 0.0))).xyz); + output.bitangent = (cross(output.normal, output.tangent) * input.tangent.w); + output.color = vec4(1.0); + output.texcoord = input.texcoord; + output.instanceColor = input.instanceColor; + let modelPos = (modelMatrix * input.position); + output.worldPos = modelPos.xyz; + output.view = (camera.position - modelPos.xyz); + output.position = ((camera.projection * camera.view) * modelPos); + return output; +} diff --git a/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.glsl b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.glsl new file mode 100644 index 0000000000..7c0e6d7a63 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.glsl @@ -0,0 +1,181 @@ +SKIP: FAILED + +#version 310 es +precision mediump float; + +struct VertexInput { + vec4 position; + vec3 normal; + vec4 tangent; + vec2 texcoord; + uvec4 joints; + vec4 weights; + vec4 instance0; + vec4 instance1; + vec4 instance2; + vec4 instance3; + vec4 instanceColor; +}; +struct VertexOutput { + vec4 position; + vec3 worldPos; + vec3 view; + vec2 texcoord; + vec2 texcoord2; + vec4 color; + vec4 instanceColor; + vec3 normal; + vec3 tangent; + vec3 bitangent; +}; +struct Camera { + mat4 projection; + mat4 inverseProjection; + mat4 view; + vec3 position; + float time; + vec2 outputSize; + float zNear; + float zFar; +}; + +layout (binding = 0) uniform Camera_1 { + mat4 projection; + mat4 inverseProjection; + mat4 view; + vec3 position; + float time; + vec2 outputSize; + float zNear; + float zFar; +} camera; + +layout (binding = 1) buffer Joints_1 { + mat4 matrices[]; +} joint; +layout (binding = 2) buffer Joints_2 { + mat4 matrices[]; +} inverseBind; + +mat4 getSkinMatrix(VertexInput tint_symbol) { + mat4 joint0 = (joint.matrices[tint_symbol.joints.x] * inverseBind.matrices[tint_symbol.joints.x]); + mat4 joint1 = (joint.matrices[tint_symbol.joints.y] * inverseBind.matrices[tint_symbol.joints.y]); + mat4 joint2 = (joint.matrices[tint_symbol.joints.z] * inverseBind.matrices[tint_symbol.joints.z]); + mat4 joint3 = (joint.matrices[tint_symbol.joints.w] * inverseBind.matrices[tint_symbol.joints.w]); + mat4 skinMatrix = ((((joint0 * tint_symbol.weights.x) + (joint1 * tint_symbol.weights.y)) + (joint2 * tint_symbol.weights.z)) + (joint3 * tint_symbol.weights.w)); + return skinMatrix; +} + +struct tint_symbol_3 { + vec4 position; + vec3 normal; + vec4 tangent; + vec2 texcoord; + uvec4 joints; + vec4 weights; + vec4 instance0; + vec4 instance1; + vec4 instance2; + vec4 instance3; + vec4 instanceColor; +}; +struct tint_symbol_4 { + vec3 worldPos; + vec3 view; + vec2 texcoord; + vec2 texcoord2; + vec4 color; + vec4 instanceColor; + vec3 normal; + vec3 tangent; + vec3 bitangent; + vec4 position; +}; + +VertexOutput vertexMain_inner(VertexInput tint_symbol) { + VertexOutput tint_symbol_1 = VertexOutput(vec4(0.0f, 0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec2(0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)); + mat4 modelMatrix = getSkinMatrix(tint_symbol); + tint_symbol_1.normal = normalize((modelMatrix * vec4(tint_symbol.normal, 0.0f)).xyz); + tint_symbol_1.tangent = normalize((modelMatrix * vec4(tint_symbol.tangent.xyz, 0.0f)).xyz); + tint_symbol_1.bitangent = (cross(tint_symbol_1.normal, tint_symbol_1.tangent) * tint_symbol.tangent.w); + tint_symbol_1.color = vec4(1.0f); + tint_symbol_1.texcoord = tint_symbol.texcoord; + tint_symbol_1.instanceColor = tint_symbol.instanceColor; + vec4 modelPos = (modelMatrix * tint_symbol.position); + tint_symbol_1.worldPos = modelPos.xyz; + tint_symbol_1.view = (camera.position - modelPos.xyz); + tint_symbol_1.position = ((camera.projection * camera.view) * modelPos); + return tint_symbol_1; +} + +tint_symbol_4 vertexMain(tint_symbol_3 tint_symbol_2) { + VertexInput tint_symbol_5 = VertexInput(tint_symbol_2.position, tint_symbol_2.normal, tint_symbol_2.tangent, tint_symbol_2.texcoord, tint_symbol_2.joints, tint_symbol_2.weights, tint_symbol_2.instance0, tint_symbol_2.instance1, tint_symbol_2.instance2, tint_symbol_2.instance3, tint_symbol_2.instanceColor); + VertexOutput inner_result = vertexMain_inner(tint_symbol_5); + tint_symbol_4 wrapper_result = tint_symbol_4(vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec2(0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f)); + wrapper_result.position = inner_result.position; + wrapper_result.worldPos = inner_result.worldPos; + wrapper_result.view = inner_result.view; + wrapper_result.texcoord = inner_result.texcoord; + wrapper_result.texcoord2 = inner_result.texcoord2; + wrapper_result.color = inner_result.color; + wrapper_result.instanceColor = inner_result.instanceColor; + wrapper_result.normal = inner_result.normal; + wrapper_result.tangent = inner_result.tangent; + wrapper_result.bitangent = inner_result.bitangent; + return wrapper_result; +} +in vec4 position; +in vec3 normal; +in vec4 tangent; +in vec2 texcoord; +in uvec4 joints; +in vec4 weights; +in vec4 instance0; +in vec4 instance1; +in vec4 instance2; +in vec4 instance3; +in vec4 instanceColor; +out vec3 worldPos; +out vec3 view; +out vec2 texcoord; +out vec2 texcoord2; +out vec4 color; +out vec4 instanceColor; +out vec3 normal; +out vec3 tangent; +out vec3 bitangent; +void main() { + tint_symbol_3 inputs; + inputs.position = position; + inputs.normal = normal; + inputs.tangent = tangent; + inputs.texcoord = texcoord; + inputs.joints = joints; + inputs.weights = weights; + inputs.instance0 = instance0; + inputs.instance1 = instance1; + inputs.instance2 = instance2; + inputs.instance3 = instance3; + inputs.instanceColor = instanceColor; + tint_symbol_4 outputs; + outputs = vertexMain(inputs); + worldPos = outputs.worldPos; + view = outputs.view; + texcoord = outputs.texcoord; + texcoord2 = outputs.texcoord2; + color = outputs.color; + instanceColor = outputs.instanceColor; + normal = outputs.normal; + tangent = outputs.tangent; + bitangent = outputs.bitangent; + gl_Position = outputs.position; + gl_Position.y = -gl_Position.y; +} + + +Error parsing GLSL shader: +ERROR: 0:138: 'texcoord' : redefinition +ERROR: 1 compilation errors. No code generated. + + + diff --git a/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.hlsl b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.hlsl new file mode 100644 index 0000000000..a1ce7697e9 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.hlsl @@ -0,0 +1,116 @@ +struct VertexInput { + float4 position; + float3 normal; + float4 tangent; + float2 texcoord; + uint4 joints; + float4 weights; + float4 instance0; + float4 instance1; + float4 instance2; + float4 instance3; + float4 instanceColor; +}; +struct VertexOutput { + float4 position; + float3 worldPos; + float3 view; + float2 texcoord; + float2 texcoord2; + float4 color; + float4 instanceColor; + float3 normal; + float3 tangent; + float3 bitangent; +}; + +cbuffer cbuffer_camera : register(b0, space0) { + uint4 camera[14]; +}; + +float4x4 getInstanceMatrix(VertexInput input) { + return float4x4(input.instance0, input.instance1, input.instance2, input.instance3); +} + +ByteAddressBuffer joint : register(t1, space0); +ByteAddressBuffer inverseBind : register(t2, space0); + +float4x4 tint_symbol_3(ByteAddressBuffer buffer, uint offset) { + return float4x4(asfloat(buffer.Load4((offset + 0u))), asfloat(buffer.Load4((offset + 16u))), asfloat(buffer.Load4((offset + 32u))), asfloat(buffer.Load4((offset + 48u)))); +} + +float4x4 getSkinMatrix(VertexInput input) { + const float4x4 joint0 = mul(tint_symbol_3(inverseBind, (64u * input.joints.x)), tint_symbol_3(joint, (64u * input.joints.x))); + const float4x4 joint1 = mul(tint_symbol_3(inverseBind, (64u * input.joints.y)), tint_symbol_3(joint, (64u * input.joints.y))); + const float4x4 joint2 = mul(tint_symbol_3(inverseBind, (64u * input.joints.z)), tint_symbol_3(joint, (64u * input.joints.z))); + const float4x4 joint3 = mul(tint_symbol_3(inverseBind, (64u * input.joints.w)), tint_symbol_3(joint, (64u * input.joints.w))); + const float4x4 skinMatrix = ((((joint0 * input.weights.x) + (joint1 * input.weights.y)) + (joint2 * input.weights.z)) + (joint3 * input.weights.w)); + return skinMatrix; +} + +struct tint_symbol_1 { + float4 position : TEXCOORD0; + float3 normal : TEXCOORD1; + float4 tangent : TEXCOORD2; + float2 texcoord : TEXCOORD3; + uint4 joints : TEXCOORD6; + float4 weights : TEXCOORD7; + float4 instance0 : TEXCOORD8; + float4 instance1 : TEXCOORD9; + float4 instance2 : TEXCOORD10; + float4 instance3 : TEXCOORD11; + float4 instanceColor : TEXCOORD12; +}; +struct tint_symbol_2 { + float3 worldPos : TEXCOORD0; + float3 view : TEXCOORD1; + float2 texcoord : TEXCOORD2; + float2 texcoord2 : TEXCOORD3; + float4 color : TEXCOORD4; + float4 instanceColor : TEXCOORD5; + float3 normal : TEXCOORD6; + float3 tangent : TEXCOORD7; + float3 bitangent : TEXCOORD8; + float4 position : SV_Position; +}; + +float4x4 tint_symbol_6(uint4 buffer[14], uint offset) { + const uint scalar_offset = ((offset + 0u)) / 4; + const uint scalar_offset_1 = ((offset + 16u)) / 4; + const uint scalar_offset_2 = ((offset + 32u)) / 4; + const uint scalar_offset_3 = ((offset + 48u)) / 4; + return float4x4(asfloat(buffer[scalar_offset / 4]), asfloat(buffer[scalar_offset_1 / 4]), asfloat(buffer[scalar_offset_2 / 4]), asfloat(buffer[scalar_offset_3 / 4])); +} + +VertexOutput vertexMain_inner(VertexInput input) { + VertexOutput output = (VertexOutput)0; + const float4x4 modelMatrix = getSkinMatrix(input); + output.normal = normalize(mul(float4(input.normal, 0.0f), modelMatrix).xyz); + output.tangent = normalize(mul(float4(input.tangent.xyz, 0.0f), modelMatrix).xyz); + output.bitangent = (cross(output.normal, output.tangent) * input.tangent.w); + output.color = float4((1.0f).xxxx); + output.texcoord = input.texcoord; + output.instanceColor = input.instanceColor; + const float4 modelPos = mul(input.position, modelMatrix); + output.worldPos = modelPos.xyz; + output.view = (asfloat(camera[12].xyz) - modelPos.xyz); + output.position = mul(modelPos, mul(tint_symbol_6(camera, 128u), tint_symbol_6(camera, 0u))); + return output; +} + +tint_symbol_2 vertexMain(tint_symbol_1 tint_symbol) { + const VertexInput tint_symbol_8 = {tint_symbol.position, tint_symbol.normal, tint_symbol.tangent, tint_symbol.texcoord, tint_symbol.joints, tint_symbol.weights, tint_symbol.instance0, tint_symbol.instance1, tint_symbol.instance2, tint_symbol.instance3, tint_symbol.instanceColor}; + const VertexOutput inner_result = vertexMain_inner(tint_symbol_8); + tint_symbol_2 wrapper_result = (tint_symbol_2)0; + wrapper_result.position = inner_result.position; + wrapper_result.worldPos = inner_result.worldPos; + wrapper_result.view = inner_result.view; + wrapper_result.texcoord = inner_result.texcoord; + wrapper_result.texcoord2 = inner_result.texcoord2; + wrapper_result.color = inner_result.color; + wrapper_result.instanceColor = inner_result.instanceColor; + wrapper_result.normal = inner_result.normal; + wrapper_result.tangent = inner_result.tangent; + wrapper_result.bitangent = inner_result.bitangent; + return wrapper_result; +} diff --git a/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.msl b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.msl new file mode 100644 index 0000000000..14e24805e8 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.msl @@ -0,0 +1,124 @@ +#include + +using namespace metal; + +template +inline vec operator*(matrix lhs, packed_vec rhs) { + return lhs * vec(rhs); +} + +template +inline vec operator*(packed_vec lhs, matrix rhs) { + return vec(lhs) * rhs; +} + +struct VertexInput { + float4 position; + float3 normal; + float4 tangent; + float2 texcoord; + uint4 joints; + float4 weights; + float4 instance0; + float4 instance1; + float4 instance2; + float4 instance3; + float4 instanceColor; +}; +struct VertexOutput { + float4 position; + float3 worldPos; + float3 view; + float2 texcoord; + float2 texcoord2; + float4 color; + float4 instanceColor; + float3 normal; + float3 tangent; + float3 bitangent; +}; +struct Camera { + /* 0x0000 */ float4x4 projection; + /* 0x0040 */ float4x4 inverseProjection; + /* 0x0080 */ float4x4 view; + /* 0x00c0 */ packed_float3 position; + /* 0x00cc */ float time; + /* 0x00d0 */ float2 outputSize; + /* 0x00d8 */ float zNear; + /* 0x00dc */ float zFar; +}; +struct Joints { + /* 0x0000 */ float4x4 matrices[1]; +}; +struct tint_symbol_1 { + float4 position [[attribute(0)]]; + float3 normal [[attribute(1)]]; + float4 tangent [[attribute(2)]]; + float2 texcoord [[attribute(3)]]; + uint4 joints [[attribute(6)]]; + float4 weights [[attribute(7)]]; + float4 instance0 [[attribute(8)]]; + float4 instance1 [[attribute(9)]]; + float4 instance2 [[attribute(10)]]; + float4 instance3 [[attribute(11)]]; + float4 instanceColor [[attribute(12)]]; +}; +struct tint_symbol_2 { + float3 worldPos [[user(locn0)]]; + float3 view [[user(locn1)]]; + float2 texcoord [[user(locn2)]]; + float2 texcoord2 [[user(locn3)]]; + float4 color [[user(locn4)]]; + float4 instanceColor [[user(locn5)]]; + float3 normal [[user(locn6)]]; + float3 tangent [[user(locn7)]]; + float3 bitangent [[user(locn8)]]; + float4 position [[position]]; +}; + +float4x4 getInstanceMatrix(VertexInput input) { + return float4x4(input.instance0, input.instance1, input.instance2, input.instance3); +} + +float4x4 getSkinMatrix(VertexInput input, const device Joints* const tint_symbol_4, const device Joints* const tint_symbol_5) { + float4x4 const joint0 = ((*(tint_symbol_4)).matrices[input.joints[0]] * (*(tint_symbol_5)).matrices[input.joints[0]]); + float4x4 const joint1 = ((*(tint_symbol_4)).matrices[input.joints[1]] * (*(tint_symbol_5)).matrices[input.joints[1]]); + float4x4 const joint2 = ((*(tint_symbol_4)).matrices[input.joints[2]] * (*(tint_symbol_5)).matrices[input.joints[2]]); + float4x4 const joint3 = ((*(tint_symbol_4)).matrices[input.joints[3]] * (*(tint_symbol_5)).matrices[input.joints[3]]); + float4x4 const skinMatrix = ((((joint0 * input.weights[0]) + (joint1 * input.weights[1])) + (joint2 * input.weights[2])) + (joint3 * input.weights[3])); + return skinMatrix; +} + +VertexOutput vertexMain_inner(VertexInput input, const device Joints* const tint_symbol_6, const device Joints* const tint_symbol_7, const constant Camera* const tint_symbol_8) { + VertexOutput output = {}; + float4x4 const modelMatrix = getSkinMatrix(input, tint_symbol_6, tint_symbol_7); + output.normal = normalize(float4(((modelMatrix * float4(input.normal, 0.0f)))).xyz); + output.tangent = normalize(float4(((modelMatrix * float4(float4(input.tangent).xyz, 0.0f)))).xyz); + output.bitangent = (cross(output.normal, output.tangent) * input.tangent[3]); + output.color = float4(1.0f); + output.texcoord = input.texcoord; + output.instanceColor = input.instanceColor; + float4 const modelPos = (modelMatrix * input.position); + output.worldPos = float4(modelPos).xyz; + output.view = ((*(tint_symbol_8)).position - float4(modelPos).xyz); + output.position = (((*(tint_symbol_8)).projection * (*(tint_symbol_8)).view) * modelPos); + return output; +} + +vertex tint_symbol_2 vertexMain(const device Joints* tint_symbol_9 [[buffer(1)]], const device Joints* tint_symbol_10 [[buffer(2)]], const constant Camera* tint_symbol_11 [[buffer(0)]], tint_symbol_1 tint_symbol [[stage_in]]) { + VertexInput const tint_symbol_3 = {.position=tint_symbol.position, .normal=tint_symbol.normal, .tangent=tint_symbol.tangent, .texcoord=tint_symbol.texcoord, .joints=tint_symbol.joints, .weights=tint_symbol.weights, .instance0=tint_symbol.instance0, .instance1=tint_symbol.instance1, .instance2=tint_symbol.instance2, .instance3=tint_symbol.instance3, .instanceColor=tint_symbol.instanceColor}; + VertexOutput const inner_result = vertexMain_inner(tint_symbol_3, tint_symbol_9, tint_symbol_10, tint_symbol_11); + tint_symbol_2 wrapper_result = {}; + wrapper_result.position = inner_result.position; + wrapper_result.worldPos = inner_result.worldPos; + wrapper_result.view = inner_result.view; + wrapper_result.texcoord = inner_result.texcoord; + wrapper_result.texcoord2 = inner_result.texcoord2; + wrapper_result.color = inner_result.color; + wrapper_result.instanceColor = inner_result.instanceColor; + wrapper_result.normal = inner_result.normal; + wrapper_result.tangent = inner_result.tangent; + wrapper_result.bitangent = inner_result.bitangent; + return wrapper_result; +} + diff --git a/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.spvasm b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.spvasm new file mode 100644 index 0000000000..243bda2ea8 --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.spvasm @@ -0,0 +1,429 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 258 +; Schema: 0 + OpCapability Shader + %168 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %vertexMain "vertexMain" %position_1 %normal_1 %tangent_1 %texcoord_1 %joints_1 %weights_1 %instance0_1 %instance1_1 %instance2_1 %instance3_1 %instanceColor_1 %position_2 %worldPos_1 %view_1 %texcoord_2 %texcoord2_1 %color_1 %instanceColor_2 %normal_2 %tangent_2 %bitangent_1 %vertex_point_size + OpName %position_1 "position_1" + OpName %normal_1 "normal_1" + OpName %tangent_1 "tangent_1" + OpName %texcoord_1 "texcoord_1" + OpName %joints_1 "joints_1" + OpName %weights_1 "weights_1" + OpName %instance0_1 "instance0_1" + OpName %instance1_1 "instance1_1" + OpName %instance2_1 "instance2_1" + OpName %instance3_1 "instance3_1" + OpName %instanceColor_1 "instanceColor_1" + OpName %position_2 "position_2" + OpName %worldPos_1 "worldPos_1" + OpName %view_1 "view_1" + OpName %texcoord_2 "texcoord_2" + OpName %texcoord2_1 "texcoord2_1" + OpName %color_1 "color_1" + OpName %instanceColor_2 "instanceColor_2" + OpName %normal_2 "normal_2" + OpName %tangent_2 "tangent_2" + OpName %bitangent_1 "bitangent_1" + OpName %vertex_point_size "vertex_point_size" + OpName %Camera "Camera" + OpMemberName %Camera 0 "projection" + OpMemberName %Camera 1 "inverseProjection" + OpMemberName %Camera 2 "view" + OpMemberName %Camera 3 "position" + OpMemberName %Camera 4 "time" + OpMemberName %Camera 5 "outputSize" + OpMemberName %Camera 6 "zNear" + OpMemberName %Camera 7 "zFar" + OpName %camera "camera" + OpName %Joints "Joints" + OpMemberName %Joints 0 "matrices" + OpName %joint "joint" + OpName %inverseBind "inverseBind" + OpName %VertexInput "VertexInput" + OpMemberName %VertexInput 0 "position" + OpMemberName %VertexInput 1 "normal" + OpMemberName %VertexInput 2 "tangent" + OpMemberName %VertexInput 3 "texcoord" + OpMemberName %VertexInput 4 "joints" + OpMemberName %VertexInput 5 "weights" + OpMemberName %VertexInput 6 "instance0" + OpMemberName %VertexInput 7 "instance1" + OpMemberName %VertexInput 8 "instance2" + OpMemberName %VertexInput 9 "instance3" + OpMemberName %VertexInput 10 "instanceColor" + OpName %getInstanceMatrix "getInstanceMatrix" + OpName %input "input" + OpName %getSkinMatrix "getSkinMatrix" + OpName %input_0 "input" + OpName %VertexOutput "VertexOutput" + OpMemberName %VertexOutput 0 "position" + OpMemberName %VertexOutput 1 "worldPos" + OpMemberName %VertexOutput 2 "view" + OpMemberName %VertexOutput 3 "texcoord" + OpMemberName %VertexOutput 4 "texcoord2" + OpMemberName %VertexOutput 5 "color" + OpMemberName %VertexOutput 6 "instanceColor" + OpMemberName %VertexOutput 7 "normal" + OpMemberName %VertexOutput 8 "tangent" + OpMemberName %VertexOutput 9 "bitangent" + OpName %vertexMain_inner "vertexMain_inner" + OpName %input_1 "input" + OpName %output "output" + OpName %vertexMain "vertexMain" + OpDecorate %position_1 Location 0 + OpDecorate %normal_1 Location 1 + OpDecorate %tangent_1 Location 2 + OpDecorate %texcoord_1 Location 3 + OpDecorate %joints_1 Location 6 + OpDecorate %weights_1 Location 7 + OpDecorate %instance0_1 Location 8 + OpDecorate %instance1_1 Location 9 + OpDecorate %instance2_1 Location 10 + OpDecorate %instance3_1 Location 11 + OpDecorate %instanceColor_1 Location 12 + OpDecorate %position_2 BuiltIn Position + OpDecorate %worldPos_1 Location 0 + OpDecorate %view_1 Location 1 + OpDecorate %texcoord_2 Location 2 + OpDecorate %texcoord2_1 Location 3 + OpDecorate %color_1 Location 4 + OpDecorate %instanceColor_2 Location 5 + OpDecorate %normal_2 Location 6 + OpDecorate %tangent_2 Location 7 + OpDecorate %bitangent_1 Location 8 + OpDecorate %vertex_point_size BuiltIn PointSize + OpDecorate %Camera Block + OpMemberDecorate %Camera 0 Offset 0 + OpMemberDecorate %Camera 0 ColMajor + OpMemberDecorate %Camera 0 MatrixStride 16 + OpMemberDecorate %Camera 1 Offset 64 + OpMemberDecorate %Camera 1 ColMajor + OpMemberDecorate %Camera 1 MatrixStride 16 + OpMemberDecorate %Camera 2 Offset 128 + OpMemberDecorate %Camera 2 ColMajor + OpMemberDecorate %Camera 2 MatrixStride 16 + OpMemberDecorate %Camera 3 Offset 192 + OpMemberDecorate %Camera 4 Offset 204 + OpMemberDecorate %Camera 5 Offset 208 + OpMemberDecorate %Camera 6 Offset 216 + OpMemberDecorate %Camera 7 Offset 220 + OpDecorate %camera NonWritable + OpDecorate %camera Binding 0 + OpDecorate %camera DescriptorSet 0 + OpDecorate %Joints Block + OpMemberDecorate %Joints 0 Offset 0 + OpMemberDecorate %Joints 0 ColMajor + OpMemberDecorate %Joints 0 MatrixStride 16 + OpDecorate %_runtimearr_mat4v4float ArrayStride 64 + OpDecorate %joint NonWritable + OpDecorate %joint Binding 1 + OpDecorate %joint DescriptorSet 0 + OpDecorate %inverseBind NonWritable + OpDecorate %inverseBind Binding 2 + OpDecorate %inverseBind DescriptorSet 0 + OpMemberDecorate %VertexInput 0 Offset 0 + OpMemberDecorate %VertexInput 1 Offset 16 + OpMemberDecorate %VertexInput 2 Offset 32 + OpMemberDecorate %VertexInput 3 Offset 48 + OpMemberDecorate %VertexInput 4 Offset 64 + OpMemberDecorate %VertexInput 5 Offset 80 + OpMemberDecorate %VertexInput 6 Offset 96 + OpMemberDecorate %VertexInput 7 Offset 112 + OpMemberDecorate %VertexInput 8 Offset 128 + OpMemberDecorate %VertexInput 9 Offset 144 + OpMemberDecorate %VertexInput 10 Offset 160 + OpMemberDecorate %VertexOutput 0 Offset 0 + OpMemberDecorate %VertexOutput 1 Offset 16 + OpMemberDecorate %VertexOutput 2 Offset 32 + OpMemberDecorate %VertexOutput 3 Offset 48 + OpMemberDecorate %VertexOutput 4 Offset 56 + OpMemberDecorate %VertexOutput 5 Offset 64 + OpMemberDecorate %VertexOutput 6 Offset 80 + OpMemberDecorate %VertexOutput 7 Offset 96 + OpMemberDecorate %VertexOutput 8 Offset 112 + OpMemberDecorate %VertexOutput 9 Offset 128 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %position_1 = OpVariable %_ptr_Input_v4float Input + %v3float = OpTypeVector %float 3 +%_ptr_Input_v3float = OpTypePointer Input %v3float + %normal_1 = OpVariable %_ptr_Input_v3float Input + %tangent_1 = OpVariable %_ptr_Input_v4float Input + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %texcoord_1 = OpVariable %_ptr_Input_v2float Input + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 +%_ptr_Input_v4uint = OpTypePointer Input %v4uint + %joints_1 = OpVariable %_ptr_Input_v4uint Input + %weights_1 = OpVariable %_ptr_Input_v4float Input +%instance0_1 = OpVariable %_ptr_Input_v4float Input +%instance1_1 = OpVariable %_ptr_Input_v4float Input +%instance2_1 = OpVariable %_ptr_Input_v4float Input +%instance3_1 = OpVariable %_ptr_Input_v4float Input +%instanceColor_1 = OpVariable %_ptr_Input_v4float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float + %24 = OpConstantNull %v4float + %position_2 = OpVariable %_ptr_Output_v4float Output %24 +%_ptr_Output_v3float = OpTypePointer Output %v3float + %27 = OpConstantNull %v3float + %worldPos_1 = OpVariable %_ptr_Output_v3float Output %27 + %view_1 = OpVariable %_ptr_Output_v3float Output %27 +%_ptr_Output_v2float = OpTypePointer Output %v2float + %31 = OpConstantNull %v2float + %texcoord_2 = OpVariable %_ptr_Output_v2float Output %31 +%texcoord2_1 = OpVariable %_ptr_Output_v2float Output %31 + %color_1 = OpVariable %_ptr_Output_v4float Output %24 +%instanceColor_2 = OpVariable %_ptr_Output_v4float Output %24 + %normal_2 = OpVariable %_ptr_Output_v3float Output %27 + %tangent_2 = OpVariable %_ptr_Output_v3float Output %27 +%bitangent_1 = OpVariable %_ptr_Output_v3float Output %27 +%_ptr_Output_float = OpTypePointer Output %float + %40 = OpConstantNull %float +%vertex_point_size = OpVariable %_ptr_Output_float Output %40 +%mat4v4float = OpTypeMatrix %v4float 4 + %Camera = OpTypeStruct %mat4v4float %mat4v4float %mat4v4float %v3float %float %v2float %float %float +%_ptr_Uniform_Camera = OpTypePointer Uniform %Camera + %camera = OpVariable %_ptr_Uniform_Camera Uniform +%_runtimearr_mat4v4float = OpTypeRuntimeArray %mat4v4float + %Joints = OpTypeStruct %_runtimearr_mat4v4float +%_ptr_StorageBuffer_Joints = OpTypePointer StorageBuffer %Joints + %joint = OpVariable %_ptr_StorageBuffer_Joints StorageBuffer +%inverseBind = OpVariable %_ptr_StorageBuffer_Joints StorageBuffer +%VertexInput = OpTypeStruct %v4float %v3float %v4float %v2float %v4uint %v4float %v4float %v4float %v4float %v4float %v4float + %50 = OpTypeFunction %mat4v4float %VertexInput + %uint_0 = OpConstant %uint 0 +%_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float +%VertexOutput = OpTypeStruct %v4float %v3float %v3float %v2float %v2float %v4float %v4float %v3float %v3float %v3float + %155 = OpTypeFunction %VertexOutput %VertexInput +%_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput + %162 = OpConstantNull %VertexOutput + %uint_7 = OpConstant %uint 7 +%_ptr_Function_v3float = OpTypePointer Function %v3float + %float_0 = OpConstant %float 0 + %uint_8 = OpConstant %uint 8 + %uint_9 = OpConstant %uint 9 + %uint_5 = OpConstant %uint 5 +%_ptr_Function_v4float = OpTypePointer Function %v4float + %float_1 = OpConstant %float 1 + %202 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %uint_3 = OpConstant %uint 3 +%_ptr_Function_v2float = OpTypePointer Function %v2float + %uint_6 = OpConstant %uint 6 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 +%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float +%_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float + %void = OpTypeVoid + %231 = OpTypeFunction %void +%getInstanceMatrix = OpFunction %mat4v4float None %50 + %input = OpFunctionParameter %VertexInput + %54 = OpLabel + %55 = OpCompositeExtract %v4float %input 6 + %56 = OpCompositeExtract %v4float %input 7 + %57 = OpCompositeExtract %v4float %input 8 + %58 = OpCompositeExtract %v4float %input 9 + %59 = OpCompositeConstruct %mat4v4float %55 %56 %57 %58 + OpReturnValue %59 + OpFunctionEnd +%getSkinMatrix = OpFunction %mat4v4float None %50 + %input_0 = OpFunctionParameter %VertexInput + %62 = OpLabel + %64 = OpCompositeExtract %v4uint %input_0 4 + %65 = OpCompositeExtract %uint %64 0 + %67 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %joint %uint_0 %65 + %68 = OpLoad %mat4v4float %67 + %69 = OpCompositeExtract %v4uint %input_0 4 + %70 = OpCompositeExtract %uint %69 0 + %71 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %inverseBind %uint_0 %70 + %72 = OpLoad %mat4v4float %71 + %73 = OpMatrixTimesMatrix %mat4v4float %68 %72 + %74 = OpCompositeExtract %v4uint %input_0 4 + %75 = OpCompositeExtract %uint %74 1 + %76 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %joint %uint_0 %75 + %77 = OpLoad %mat4v4float %76 + %78 = OpCompositeExtract %v4uint %input_0 4 + %79 = OpCompositeExtract %uint %78 1 + %80 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %inverseBind %uint_0 %79 + %81 = OpLoad %mat4v4float %80 + %82 = OpMatrixTimesMatrix %mat4v4float %77 %81 + %83 = OpCompositeExtract %v4uint %input_0 4 + %84 = OpCompositeExtract %uint %83 2 + %85 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %joint %uint_0 %84 + %86 = OpLoad %mat4v4float %85 + %87 = OpCompositeExtract %v4uint %input_0 4 + %88 = OpCompositeExtract %uint %87 2 + %89 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %inverseBind %uint_0 %88 + %90 = OpLoad %mat4v4float %89 + %91 = OpMatrixTimesMatrix %mat4v4float %86 %90 + %92 = OpCompositeExtract %v4uint %input_0 4 + %93 = OpCompositeExtract %uint %92 3 + %94 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %joint %uint_0 %93 + %95 = OpLoad %mat4v4float %94 + %96 = OpCompositeExtract %v4uint %input_0 4 + %97 = OpCompositeExtract %uint %96 3 + %98 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %inverseBind %uint_0 %97 + %99 = OpLoad %mat4v4float %98 + %100 = OpMatrixTimesMatrix %mat4v4float %95 %99 + %101 = OpCompositeExtract %v4float %input_0 5 + %102 = OpCompositeExtract %float %101 0 + %103 = OpMatrixTimesScalar %mat4v4float %73 %102 + %104 = OpCompositeExtract %v4float %input_0 5 + %105 = OpCompositeExtract %float %104 1 + %106 = OpMatrixTimesScalar %mat4v4float %82 %105 + %108 = OpCompositeExtract %v4float %103 0 + %109 = OpCompositeExtract %v4float %106 0 + %110 = OpFAdd %v4float %108 %109 + %111 = OpCompositeExtract %v4float %103 1 + %112 = OpCompositeExtract %v4float %106 1 + %113 = OpFAdd %v4float %111 %112 + %114 = OpCompositeExtract %v4float %103 2 + %115 = OpCompositeExtract %v4float %106 2 + %116 = OpFAdd %v4float %114 %115 + %117 = OpCompositeExtract %v4float %103 3 + %118 = OpCompositeExtract %v4float %106 3 + %119 = OpFAdd %v4float %117 %118 + %120 = OpCompositeConstruct %mat4v4float %110 %113 %116 %119 + %121 = OpCompositeExtract %v4float %input_0 5 + %122 = OpCompositeExtract %float %121 2 + %123 = OpMatrixTimesScalar %mat4v4float %91 %122 + %125 = OpCompositeExtract %v4float %120 0 + %126 = OpCompositeExtract %v4float %123 0 + %127 = OpFAdd %v4float %125 %126 + %128 = OpCompositeExtract %v4float %120 1 + %129 = OpCompositeExtract %v4float %123 1 + %130 = OpFAdd %v4float %128 %129 + %131 = OpCompositeExtract %v4float %120 2 + %132 = OpCompositeExtract %v4float %123 2 + %133 = OpFAdd %v4float %131 %132 + %134 = OpCompositeExtract %v4float %120 3 + %135 = OpCompositeExtract %v4float %123 3 + %136 = OpFAdd %v4float %134 %135 + %137 = OpCompositeConstruct %mat4v4float %127 %130 %133 %136 + %138 = OpCompositeExtract %v4float %input_0 5 + %139 = OpCompositeExtract %float %138 3 + %140 = OpMatrixTimesScalar %mat4v4float %100 %139 + %142 = OpCompositeExtract %v4float %137 0 + %143 = OpCompositeExtract %v4float %140 0 + %144 = OpFAdd %v4float %142 %143 + %145 = OpCompositeExtract %v4float %137 1 + %146 = OpCompositeExtract %v4float %140 1 + %147 = OpFAdd %v4float %145 %146 + %148 = OpCompositeExtract %v4float %137 2 + %149 = OpCompositeExtract %v4float %140 2 + %150 = OpFAdd %v4float %148 %149 + %151 = OpCompositeExtract %v4float %137 3 + %152 = OpCompositeExtract %v4float %140 3 + %153 = OpFAdd %v4float %151 %152 + %154 = OpCompositeConstruct %mat4v4float %144 %147 %150 %153 + OpReturnValue %154 + OpFunctionEnd +%vertexMain_inner = OpFunction %VertexOutput None %155 + %input_1 = OpFunctionParameter %VertexInput + %159 = OpLabel + %output = OpVariable %_ptr_Function_VertexOutput Function %162 + %163 = OpFunctionCall %mat4v4float %getSkinMatrix %input_1 + %166 = OpAccessChain %_ptr_Function_v3float %output %uint_7 + %169 = OpCompositeExtract %v3float %input_1 1 + %170 = OpCompositeExtract %float %169 0 + %171 = OpCompositeExtract %float %169 1 + %172 = OpCompositeExtract %float %169 2 + %174 = OpCompositeConstruct %v4float %170 %171 %172 %float_0 + %175 = OpMatrixTimesVector %v4float %163 %174 + %176 = OpVectorShuffle %v3float %175 %175 0 1 2 + %167 = OpExtInst %v3float %168 Normalize %176 + OpStore %166 %167 + %178 = OpAccessChain %_ptr_Function_v3float %output %uint_8 + %180 = OpCompositeExtract %v4float %input_1 2 + %181 = OpVectorShuffle %v3float %180 %180 0 1 2 + %182 = OpCompositeExtract %float %181 0 + %183 = OpCompositeExtract %float %181 1 + %184 = OpCompositeExtract %float %181 2 + %185 = OpCompositeConstruct %v4float %182 %183 %184 %float_0 + %186 = OpMatrixTimesVector %v4float %163 %185 + %187 = OpVectorShuffle %v3float %186 %186 0 1 2 + %179 = OpExtInst %v3float %168 Normalize %187 + OpStore %178 %179 + %189 = OpAccessChain %_ptr_Function_v3float %output %uint_9 + %191 = OpAccessChain %_ptr_Function_v3float %output %uint_7 + %192 = OpLoad %v3float %191 + %193 = OpAccessChain %_ptr_Function_v3float %output %uint_8 + %194 = OpLoad %v3float %193 + %190 = OpExtInst %v3float %168 Cross %192 %194 + %195 = OpCompositeExtract %v4float %input_1 2 + %196 = OpCompositeExtract %float %195 3 + %197 = OpVectorTimesScalar %v3float %190 %196 + OpStore %189 %197 + %200 = OpAccessChain %_ptr_Function_v4float %output %uint_5 + OpStore %200 %202 + %205 = OpAccessChain %_ptr_Function_v2float %output %uint_3 + %206 = OpCompositeExtract %v2float %input_1 3 + OpStore %205 %206 + %208 = OpAccessChain %_ptr_Function_v4float %output %uint_6 + %209 = OpCompositeExtract %v4float %input_1 10 + OpStore %208 %209 + %210 = OpCompositeExtract %v4float %input_1 0 + %211 = OpMatrixTimesVector %v4float %163 %210 + %213 = OpAccessChain %_ptr_Function_v3float %output %uint_1 + %214 = OpVectorShuffle %v3float %211 %211 0 1 2 + OpStore %213 %214 + %216 = OpAccessChain %_ptr_Function_v3float %output %uint_2 + %218 = OpAccessChain %_ptr_Uniform_v3float %camera %uint_3 + %219 = OpLoad %v3float %218 + %220 = OpVectorShuffle %v3float %211 %211 0 1 2 + %221 = OpFSub %v3float %219 %220 + OpStore %216 %221 + %222 = OpAccessChain %_ptr_Function_v4float %output %uint_0 + %224 = OpAccessChain %_ptr_Uniform_mat4v4float %camera %uint_0 + %225 = OpLoad %mat4v4float %224 + %226 = OpAccessChain %_ptr_Uniform_mat4v4float %camera %uint_2 + %227 = OpLoad %mat4v4float %226 + %228 = OpMatrixTimesMatrix %mat4v4float %225 %227 + %229 = OpMatrixTimesVector %v4float %228 %211 + OpStore %222 %229 + %230 = OpLoad %VertexOutput %output + OpReturnValue %230 + OpFunctionEnd + %vertexMain = OpFunction %void None %231 + %234 = OpLabel + %236 = OpLoad %v4float %position_1 + %237 = OpLoad %v3float %normal_1 + %238 = OpLoad %v4float %tangent_1 + %239 = OpLoad %v2float %texcoord_1 + %240 = OpLoad %v4uint %joints_1 + %241 = OpLoad %v4float %weights_1 + %242 = OpLoad %v4float %instance0_1 + %243 = OpLoad %v4float %instance1_1 + %244 = OpLoad %v4float %instance2_1 + %245 = OpLoad %v4float %instance3_1 + %246 = OpLoad %v4float %instanceColor_1 + %247 = OpCompositeConstruct %VertexInput %236 %237 %238 %239 %240 %241 %242 %243 %244 %245 %246 + %235 = OpFunctionCall %VertexOutput %vertexMain_inner %247 + %248 = OpCompositeExtract %v4float %235 0 + OpStore %position_2 %248 + %249 = OpCompositeExtract %v3float %235 1 + OpStore %worldPos_1 %249 + %250 = OpCompositeExtract %v3float %235 2 + OpStore %view_1 %250 + %251 = OpCompositeExtract %v2float %235 3 + OpStore %texcoord_2 %251 + %252 = OpCompositeExtract %v2float %235 4 + OpStore %texcoord2_1 %252 + %253 = OpCompositeExtract %v4float %235 5 + OpStore %color_1 %253 + %254 = OpCompositeExtract %v4float %235 6 + OpStore %instanceColor_2 %254 + %255 = OpCompositeExtract %v3float %235 7 + OpStore %normal_2 %255 + %256 = OpCompositeExtract %v3float %235 8 + OpStore %tangent_2 %256 + %257 = OpCompositeExtract %v3float %235 9 + OpStore %bitangent_1 %257 + OpStore %vertex_point_size %float_1 + OpReturn + OpFunctionEnd diff --git a/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.wgsl b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.wgsl new file mode 100644 index 0000000000..52304590fd --- /dev/null +++ b/test/benchmark/skinned-shadowed-pbr-vertex.wgsl.expected.wgsl @@ -0,0 +1,98 @@ +struct VertexInput { + @location(0) + position : vec4; + @location(1) + normal : vec3; + @location(2) + tangent : vec4; + @location(3) + texcoord : vec2; + @location(6) + joints : vec4; + @location(7) + weights : vec4; + @location(8) + instance0 : vec4; + @location(9) + instance1 : vec4; + @location(10) + instance2 : vec4; + @location(11) + instance3 : vec4; + @location(12) + instanceColor : vec4; +} + +struct VertexOutput { + @builtin(position) + position : vec4; + @location(0) + worldPos : vec3; + @location(1) + view : vec3; + @location(2) + texcoord : vec2; + @location(3) + texcoord2 : vec2; + @location(4) + color : vec4; + @location(5) + instanceColor : vec4; + @location(6) + normal : vec3; + @location(7) + tangent : vec3; + @location(8) + bitangent : vec3; +} + +struct Camera { + projection : mat4x4; + inverseProjection : mat4x4; + view : mat4x4; + position : vec3; + time : f32; + outputSize : vec2; + zNear : f32; + zFar : f32; +} + +@binding(0) @group(0) var camera : Camera; + +fn getInstanceMatrix(input : VertexInput) -> mat4x4 { + return mat4x4(input.instance0, input.instance1, input.instance2, input.instance3); +} + +struct Joints { + matrices : array>; +} + +@binding(1) @group(0) var joint : Joints; + +@binding(2) @group(0) var inverseBind : Joints; + +fn getSkinMatrix(input : VertexInput) -> mat4x4 { + let joint0 = (joint.matrices[input.joints.x] * inverseBind.matrices[input.joints.x]); + let joint1 = (joint.matrices[input.joints.y] * inverseBind.matrices[input.joints.y]); + let joint2 = (joint.matrices[input.joints.z] * inverseBind.matrices[input.joints.z]); + let joint3 = (joint.matrices[input.joints.w] * inverseBind.matrices[input.joints.w]); + let skinMatrix = ((((joint0 * input.weights.x) + (joint1 * input.weights.y)) + (joint2 * input.weights.z)) + (joint3 * input.weights.w)); + return skinMatrix; +} + +@stage(vertex) +fn vertexMain(input : VertexInput) -> VertexOutput { + var output : VertexOutput; + let modelMatrix = getSkinMatrix(input); + output.normal = normalize(((modelMatrix * vec4(input.normal, 0.0))).xyz); + output.tangent = normalize(((modelMatrix * vec4(input.tangent.xyz, 0.0))).xyz); + output.bitangent = (cross(output.normal, output.tangent) * input.tangent.w); + output.color = vec4(1.0); + output.texcoord = input.texcoord; + output.instanceColor = input.instanceColor; + let modelPos = (modelMatrix * input.position); + output.worldPos = modelPos.xyz; + output.view = (camera.position - modelPos.xyz); + output.position = ((camera.projection * camera.view) * modelPos); + return output; +}