[tint][exe] Add --use-storage-input-output-16 flag
Add an E2E test that uses it, to show the polyfill working.
Bug: tint:2161
Change-Id: I445078579b5aefcbbc688af2a6c79e844549ead6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/173707
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index 85d8d3e..4d18bb9 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -178,6 +178,10 @@
tint::Vector<std::string, 4> transforms;
+#if TINT_BUILD_SPV_WRITER
+ bool use_storage_input_output_16 = true;
+#endif // TINT_BULD_SPV_WRITER
+
#if TINT_BUILD_HLSL_WRITER
std::string fxc_path;
std::string dxc_path;
@@ -345,6 +349,13 @@
});
#endif
+#if TINT_BUILD_SPV_WRITER
+ auto& use_storage_input_output_16 =
+ options.Add<BoolOption>("use-storage-input-output-16",
+ "Use the StorageInputOutput16 SPIR-V capability", Default{true});
+ TINT_DEFER(opts->use_storage_input_output_16 = *use_storage_input_output_16.value);
+#endif
+
auto& disable_wg_init = options.Add<BoolOption>(
"disable-workgroup-init", "Disable workgroup memory zero initialization", Default{false});
TINT_DEFER(opts->disable_workgroup_init = *disable_wg_init.value);
@@ -687,6 +698,7 @@
tint::spirv::writer::Options gen_options;
gen_options.disable_robustness = !options.enable_robustness;
gen_options.disable_workgroup_init = options.disable_workgroup_init;
+ gen_options.use_storage_input_output_16 = options.use_storage_input_output_16;
gen_options.bindings = tint::spirv::writer::GenerateBindings(program);
tint::Result<tint::spirv::writer::Output> result;
diff --git a/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl
new file mode 100644
index 0000000..c784e9b
--- /dev/null
+++ b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl
@@ -0,0 +1,13 @@
+// flags: --hlsl_shader_model 62 --use-storage-input-output-16=false
+enable f16;
+
+struct Outputs {
+ @location(1) a : f16,
+ @location(2) b : vec4<f16>,
+}
+
+@fragment
+fn frag_main(@location(1) loc1 : f16,
+ @location(2) loc2 : vec4<f16>) -> Outputs {
+ return Outputs(loc1 * 2, loc2 * 3);
+}
diff --git a/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.dxc.hlsl b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..510a946
--- /dev/null
+++ b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.dxc.hlsl
@@ -0,0 +1,25 @@
+struct Outputs {
+ float16_t a;
+ vector<float16_t, 4> b;
+};
+struct tint_symbol_1 {
+ float16_t loc1 : TEXCOORD1;
+ vector<float16_t, 4> loc2 : TEXCOORD2;
+};
+struct tint_symbol_2 {
+ float16_t a : SV_Target1;
+ vector<float16_t, 4> b : SV_Target2;
+};
+
+Outputs frag_main_inner(float16_t loc1, vector<float16_t, 4> loc2) {
+ Outputs tint_symbol_3 = {(loc1 * float16_t(2.0h)), (loc2 * float16_t(3.0h))};
+ return tint_symbol_3;
+}
+
+tint_symbol_2 frag_main(tint_symbol_1 tint_symbol) {
+ Outputs inner_result = frag_main_inner(tint_symbol.loc1, tint_symbol.loc2);
+ tint_symbol_2 wrapper_result = (tint_symbol_2)0;
+ wrapper_result.a = inner_result.a;
+ wrapper_result.b = inner_result.b;
+ return wrapper_result;
+}
diff --git a/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.fxc.hlsl b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..98230ce
--- /dev/null
+++ b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.fxc.hlsl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+struct Outputs {
+ float16_t a;
+ vector<float16_t, 4> b;
+};
+struct tint_symbol_1 {
+ float16_t loc1 : TEXCOORD1;
+ vector<float16_t, 4> loc2 : TEXCOORD2;
+};
+struct tint_symbol_2 {
+ float16_t a : SV_Target1;
+ vector<float16_t, 4> b : SV_Target2;
+};
+
+Outputs frag_main_inner(float16_t loc1, vector<float16_t, 4> loc2) {
+ Outputs tint_symbol_3 = {(loc1 * float16_t(2.0h)), (loc2 * float16_t(3.0h))};
+ return tint_symbol_3;
+}
+
+tint_symbol_2 frag_main(tint_symbol_1 tint_symbol) {
+ Outputs inner_result = frag_main_inner(tint_symbol.loc1, tint_symbol.loc2);
+ tint_symbol_2 wrapper_result = (tint_symbol_2)0;
+ wrapper_result.a = inner_result.a;
+ wrapper_result.b = inner_result.b;
+ return wrapper_result;
+}
diff --git a/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.glsl b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.glsl
new file mode 100644
index 0000000..598b9e9
--- /dev/null
+++ b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.glsl
@@ -0,0 +1,24 @@
+#version 310 es
+#extension GL_AMD_gpu_shader_half_float : require
+precision highp float;
+
+layout(location = 1) in float16_t loc1_1;
+layout(location = 2) in f16vec4 loc2_1;
+layout(location = 1) out float16_t a_1;
+layout(location = 2) out f16vec4 b_1;
+struct Outputs {
+ float16_t a;
+ f16vec4 b;
+};
+
+Outputs frag_main(float16_t loc1, f16vec4 loc2) {
+ Outputs tint_symbol = Outputs((loc1 * 2.0hf), (loc2 * 3.0hf));
+ return tint_symbol;
+}
+
+void main() {
+ Outputs inner_result = frag_main(loc1_1, loc2_1);
+ a_1 = inner_result.a;
+ b_1 = inner_result.b;
+ return;
+}
diff --git a/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.msl b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.msl
new file mode 100644
index 0000000..c07c23c
--- /dev/null
+++ b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.msl
@@ -0,0 +1,31 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct Outputs {
+ half a;
+ half4 b;
+};
+
+struct tint_symbol_1 {
+ half loc1 [[user(locn1)]];
+ half4 loc2 [[user(locn2)]];
+};
+
+struct tint_symbol_2 {
+ half a [[color(1)]];
+ half4 b [[color(2)]];
+};
+
+Outputs frag_main_inner(half loc1, half4 loc2) {
+ Outputs const tint_symbol_3 = {.a=(loc1 * 2.0h), .b=(loc2 * 3.0h)};
+ return tint_symbol_3;
+}
+
+fragment tint_symbol_2 frag_main(tint_symbol_1 tint_symbol [[stage_in]]) {
+ Outputs const inner_result = frag_main_inner(tint_symbol.loc1, tint_symbol.loc2);
+ tint_symbol_2 wrapper_result = {};
+ wrapper_result.a = inner_result.a;
+ wrapper_result.b = inner_result.b;
+ return wrapper_result;
+}
+
diff --git a/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.spvasm
new file mode 100644
index 0000000..baf6ffd
--- /dev/null
+++ b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.spvasm
@@ -0,0 +1,73 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 39
+; Schema: 0
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability UniformAndStorageBuffer16BitAccess
+ OpCapability StorageBuffer16BitAccess
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %frag_main "frag_main" %loc1_1 %loc2_1 %a_1 %b_1
+ OpExecutionMode %frag_main OriginUpperLeft
+ OpName %loc1_1 "loc1_1"
+ OpName %loc2_1 "loc2_1"
+ OpName %a_1 "a_1"
+ OpName %b_1 "b_1"
+ OpName %Outputs "Outputs"
+ OpMemberName %Outputs 0 "a"
+ OpMemberName %Outputs 1 "b"
+ OpName %frag_main_inner "frag_main_inner"
+ OpName %loc1 "loc1"
+ OpName %loc2 "loc2"
+ OpName %frag_main "frag_main"
+ OpDecorate %loc1_1 Location 1
+ OpDecorate %loc2_1 Location 2
+ OpDecorate %a_1 Location 1
+ OpDecorate %b_1 Location 2
+ OpMemberDecorate %Outputs 0 Offset 0
+ OpMemberDecorate %Outputs 1 Offset 8
+ %float = OpTypeFloat 32
+%_ptr_Input_float = OpTypePointer Input %float
+ %loc1_1 = OpVariable %_ptr_Input_float Input
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %loc2_1 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_float = OpTypePointer Output %float
+ %9 = OpConstantNull %float
+ %a_1 = OpVariable %_ptr_Output_float Output %9
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %12 = OpConstantNull %v4float
+ %b_1 = OpVariable %_ptr_Output_v4float Output %12
+ %half = OpTypeFloat 16
+ %v4half = OpTypeVector %half 4
+ %Outputs = OpTypeStruct %half %v4half
+ %13 = OpTypeFunction %Outputs %half %v4half
+%half_0x1p_1 = OpConstant %half 0x1p+1
+%half_0x1_8p_1 = OpConstant %half 0x1.8p+1
+ %void = OpTypeVoid
+ %26 = OpTypeFunction %void
+%frag_main_inner = OpFunction %Outputs None %13
+ %loc1 = OpFunctionParameter %half
+ %loc2 = OpFunctionParameter %v4half
+ %20 = OpLabel
+ %22 = OpFMul %half %loc1 %half_0x1p_1
+ %24 = OpVectorTimesScalar %v4half %loc2 %half_0x1_8p_1
+ %25 = OpCompositeConstruct %Outputs %22 %24
+ OpReturnValue %25
+ OpFunctionEnd
+ %frag_main = OpFunction %void None %26
+ %29 = OpLabel
+ %32 = OpLoad %float %loc1_1
+ %31 = OpFConvert %half %32
+ %34 = OpLoad %v4float %loc2_1
+ %33 = OpFConvert %v4half %34
+ %30 = OpFunctionCall %Outputs %frag_main_inner %31 %33
+ %36 = OpCompositeExtract %half %30 0
+ %35 = OpFConvert %float %36
+ OpStore %a_1 %35
+ %38 = OpCompositeExtract %v4half %30 1
+ %37 = OpFConvert %v4float %38
+ OpStore %b_1 %37
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.wgsl b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.wgsl
new file mode 100644
index 0000000..80eb8cd
--- /dev/null
+++ b/test/tint/types/functions/shader_io/fragment_f16_io_polyfill.wgsl.expected.wgsl
@@ -0,0 +1,13 @@
+enable f16;
+
+struct Outputs {
+ @location(1)
+ a : f16,
+ @location(2)
+ b : vec4<f16>,
+}
+
+@fragment
+fn frag_main(@location(1) loc1 : f16, @location(2) loc2 : vec4<f16>) -> Outputs {
+ return Outputs((loc1 * 2), (loc2 * 3));
+}