[tint][cmd] Don't vary HLSL output based on validation mode

--hlsl_shader_model controls the features used by the HLSL writer. Don't also tweak things based on the validation flags.

To handle this, add support for format-filtered flags with the test runner.

Bug: tint:1497
Change-Id: I96c6af9287462a8f6007b42285a72cba65865146
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/170422
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index ff85ff7..474088e 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -145,6 +145,8 @@
 #if TINT_BUILD_HLSL_WRITER
 constexpr uint32_t kMinShaderModelForDXC = 60u;
 constexpr uint32_t kMaxSupportedShaderModelForDXC = 66u;
+constexpr uint32_t kMinShaderModelForDP4aInHLSL = 64u;
+constexpr uint32_t kMinShaderModelForPackUnpack4x8InHLSL = 66u;
 #endif  // TINT_BUILD_HLSL_WRITER
 
 struct Options {
@@ -917,17 +919,9 @@
         tint::cmd::GenerateExternalTextureBindings(program);
     gen_options.root_constant_binding_point = options.hlsl_root_constant_binding_point;
     gen_options.pixel_local_options = options.pixel_local_options;
-    if (must_validate_dxc) {
-        constexpr uint32_t kMinShaderModelForDP4aInHLSL = 64u;
-        constexpr uint32_t kMinShaderModelForPackUnPack4x8InHLSL = 66u;
-        gen_options.polyfill_dot_4x8_packed =
-            options.hlsl_shader_model < kMinShaderModelForDP4aInHLSL;
-        gen_options.polyfill_pack_unpack_4x8 =
-            options.hlsl_shader_model < kMinShaderModelForPackUnPack4x8InHLSL;
-    } else {
-        gen_options.polyfill_dot_4x8_packed = true;
-        gen_options.polyfill_pack_unpack_4x8 = true;
-    }
+    gen_options.polyfill_dot_4x8_packed = options.hlsl_shader_model < kMinShaderModelForDP4aInHLSL;
+    gen_options.polyfill_pack_unpack_4x8 =
+        options.hlsl_shader_model < kMinShaderModelForPackUnpack4x8InHLSL;
     auto result = tint::hlsl::writer::Generate(program, gen_options);
     if (result != tint::Success) {
         tint::cmd::PrintWGSL(std::cerr, program);
diff --git a/test/tint/bug/tint/2052.wgsl.expected.glsl b/test/tint/bug/tint/2052.wgsl.expected.glsl
index 4eb65ba..d9d2ddc 100644
--- a/test/tint/bug/tint/2052.wgsl.expected.glsl
+++ b/test/tint/bug/tint/2052.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
 #version 310 es
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -10,10 +8,3 @@
   discard;
 }
 
-error: Error parsing GLSL shader:
-ERROR: 0:8: 'discard' : not supported in this stage: compute
-ERROR: 0:8: '' : compilation terminated 
-ERROR: 2 compilation errors.  No code generated.
-
-
-
diff --git a/test/tint/builtins/gen/gen.wgsl.tmpl b/test/tint/builtins/gen/gen.wgsl.tmpl
index 7230c10..f27936c 100644
--- a/test/tint/builtins/gen/gen.wgsl.tmpl
+++ b/test/tint/builtins/gen/gen.wgsl.tmpl
@@ -203,10 +203,10 @@
 
 {{- /* Check and emit dot4I8Packed and dot4U8Packed */ -}}
 {{-   if or (eq "pack4xI8" $builtin_name) (eq "pack4xU8" $builtin_name) (eq "pack4xI8Clamp" $builtin_name) (eq "unpack4xI8" $builtin_name) (eq "unpack4xU8" $builtin_name)}}
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 
 {{-   else if or (eq "dot4I8Packed" $builtin_name) (eq "dot4U8Packed" $builtin_name)}}
-// flags: --hlsl_shader_model 64
+// [hlsl-dxc] flags: --hlsl_shader_model 64
 
 {{- /* Check and emit f16 */ -}}
 {{-   else if OverloadUsesF16 $overload}}
diff --git a/test/tint/builtins/gen/literal/dot4I8Packed/881e62.wgsl b/test/tint/builtins/gen/literal/dot4I8Packed/881e62.wgsl
index e4969f3..7931904 100644
--- a/test/tint/builtins/gen/literal/dot4I8Packed/881e62.wgsl
+++ b/test/tint/builtins/gen/literal/dot4I8Packed/881e62.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 64
+// [hlsl-dxc] flags: --hlsl_shader_model 64
 // fn dot4I8Packed(u32, u32) -> i32
 fn dot4I8Packed_881e62() {
   var res: i32 = dot4I8Packed(1u, 1u);
diff --git a/test/tint/builtins/gen/literal/dot4U8Packed/fbed7b.wgsl b/test/tint/builtins/gen/literal/dot4U8Packed/fbed7b.wgsl
index c3716ab..aa0db0f 100644
--- a/test/tint/builtins/gen/literal/dot4U8Packed/fbed7b.wgsl
+++ b/test/tint/builtins/gen/literal/dot4U8Packed/fbed7b.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 64
+// [hlsl-dxc] flags: --hlsl_shader_model 64
 // fn dot4U8Packed(u32, u32) -> u32
 fn dot4U8Packed_fbed7b() {
   var res: u32 = dot4U8Packed(1u, 1u);
diff --git a/test/tint/builtins/gen/literal/pack4xI8/bfce01.wgsl b/test/tint/builtins/gen/literal/pack4xI8/bfce01.wgsl
index 09fb395..942e495 100644
--- a/test/tint/builtins/gen/literal/pack4xI8/bfce01.wgsl
+++ b/test/tint/builtins/gen/literal/pack4xI8/bfce01.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn pack4xI8(vec4<i32>) -> u32
 fn pack4xI8_bfce01() {
   var res: u32 = pack4xI8(vec4<i32>(1i));
diff --git a/test/tint/builtins/gen/literal/pack4xI8Clamp/e42b2a.wgsl b/test/tint/builtins/gen/literal/pack4xI8Clamp/e42b2a.wgsl
index 3b7046f..b0ca006 100644
--- a/test/tint/builtins/gen/literal/pack4xI8Clamp/e42b2a.wgsl
+++ b/test/tint/builtins/gen/literal/pack4xI8Clamp/e42b2a.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn pack4xI8Clamp(vec4<i32>) -> u32
 fn pack4xI8Clamp_e42b2a() {
   var res: u32 = pack4xI8Clamp(vec4<i32>(1i));
diff --git a/test/tint/builtins/gen/literal/pack4xU8/b70b53.wgsl b/test/tint/builtins/gen/literal/pack4xU8/b70b53.wgsl
index 25c453b..22359a4 100644
--- a/test/tint/builtins/gen/literal/pack4xU8/b70b53.wgsl
+++ b/test/tint/builtins/gen/literal/pack4xU8/b70b53.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn pack4xU8(vec4<u32>) -> u32
 fn pack4xU8_b70b53() {
   var res: u32 = pack4xU8(vec4<u32>(1u));
diff --git a/test/tint/builtins/gen/literal/unpack4xI8/830900.wgsl b/test/tint/builtins/gen/literal/unpack4xI8/830900.wgsl
index 711a508..623542d 100644
--- a/test/tint/builtins/gen/literal/unpack4xI8/830900.wgsl
+++ b/test/tint/builtins/gen/literal/unpack4xI8/830900.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn unpack4xI8(u32) -> vec4<i32>
 fn unpack4xI8_830900() {
   var res: vec4<i32> = unpack4xI8(1u);
diff --git a/test/tint/builtins/gen/literal/unpack4xU8/a5ea55.wgsl b/test/tint/builtins/gen/literal/unpack4xU8/a5ea55.wgsl
index c5848e0..d21902b 100644
--- a/test/tint/builtins/gen/literal/unpack4xU8/a5ea55.wgsl
+++ b/test/tint/builtins/gen/literal/unpack4xU8/a5ea55.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn unpack4xU8(u32) -> vec4<u32>
 fn unpack4xU8_a5ea55() {
   var res: vec4<u32> = unpack4xU8(1u);
diff --git a/test/tint/builtins/gen/var/dot4I8Packed/881e62.wgsl b/test/tint/builtins/gen/var/dot4I8Packed/881e62.wgsl
index 932be22..7b5821a 100644
--- a/test/tint/builtins/gen/var/dot4I8Packed/881e62.wgsl
+++ b/test/tint/builtins/gen/var/dot4I8Packed/881e62.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 64
+// [hlsl-dxc] flags: --hlsl_shader_model 64
 // fn dot4I8Packed(u32, u32) -> i32
 fn dot4I8Packed_881e62() {
   var arg_0 = 1u;
diff --git a/test/tint/builtins/gen/var/dot4U8Packed/fbed7b.wgsl b/test/tint/builtins/gen/var/dot4U8Packed/fbed7b.wgsl
index 368e4d1..89a32d7 100644
--- a/test/tint/builtins/gen/var/dot4U8Packed/fbed7b.wgsl
+++ b/test/tint/builtins/gen/var/dot4U8Packed/fbed7b.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 64
+// [hlsl-dxc] flags: --hlsl_shader_model 64
 // fn dot4U8Packed(u32, u32) -> u32
 fn dot4U8Packed_fbed7b() {
   var arg_0 = 1u;
diff --git a/test/tint/builtins/gen/var/pack4xI8/bfce01.wgsl b/test/tint/builtins/gen/var/pack4xI8/bfce01.wgsl
index cea534b..9a42b70 100644
--- a/test/tint/builtins/gen/var/pack4xI8/bfce01.wgsl
+++ b/test/tint/builtins/gen/var/pack4xI8/bfce01.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn pack4xI8(vec4<i32>) -> u32
 fn pack4xI8_bfce01() {
   var arg_0 = vec4<i32>(1i);
diff --git a/test/tint/builtins/gen/var/pack4xI8Clamp/e42b2a.wgsl b/test/tint/builtins/gen/var/pack4xI8Clamp/e42b2a.wgsl
index ad981bc..d9ec3a8 100644
--- a/test/tint/builtins/gen/var/pack4xI8Clamp/e42b2a.wgsl
+++ b/test/tint/builtins/gen/var/pack4xI8Clamp/e42b2a.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn pack4xI8Clamp(vec4<i32>) -> u32
 fn pack4xI8Clamp_e42b2a() {
   var arg_0 = vec4<i32>(1i);
diff --git a/test/tint/builtins/gen/var/pack4xU8/b70b53.wgsl b/test/tint/builtins/gen/var/pack4xU8/b70b53.wgsl
index b9d10a9..c65c27a 100644
--- a/test/tint/builtins/gen/var/pack4xU8/b70b53.wgsl
+++ b/test/tint/builtins/gen/var/pack4xU8/b70b53.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn pack4xU8(vec4<u32>) -> u32
 fn pack4xU8_b70b53() {
   var arg_0 = vec4<u32>(1u);
diff --git a/test/tint/builtins/gen/var/unpack4xI8/830900.wgsl b/test/tint/builtins/gen/var/unpack4xI8/830900.wgsl
index 1f88592..31146cb 100644
--- a/test/tint/builtins/gen/var/unpack4xI8/830900.wgsl
+++ b/test/tint/builtins/gen/var/unpack4xI8/830900.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn unpack4xI8(u32) -> vec4<i32>
 fn unpack4xI8_830900() {
   var arg_0 = 1u;
diff --git a/test/tint/builtins/gen/var/unpack4xU8/a5ea55.wgsl b/test/tint/builtins/gen/var/unpack4xU8/a5ea55.wgsl
index f37cbf1..e39c3dd 100644
--- a/test/tint/builtins/gen/var/unpack4xU8/a5ea55.wgsl
+++ b/test/tint/builtins/gen/var/unpack4xU8/a5ea55.wgsl
@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 
-// flags: --hlsl_shader_model 66
+// [hlsl-dxc] flags: --hlsl_shader_model 66
 // fn unpack4xU8(u32) -> vec4<u32>
 fn unpack4xU8_a5ea55() {
   var arg_0 = 1u;
diff --git a/tools/src/cmd/tests/main.go b/tools/src/cmd/tests/main.go
index cda2f10..a2405cd 100644
--- a/tools/src/cmd/tests/main.go
+++ b/tools/src/cmd/tests/main.go
@@ -46,6 +46,7 @@
 	"time"
 	"unicode/utf8"
 
+	"dawn.googlesource.com/dawn/tools/src/container"
 	"dawn.googlesource.com/dawn/tools/src/fileutils"
 	"dawn.googlesource.com/dawn/tools/src/glob"
 	"dawn.googlesource.com/dawn/tools/src/match"
@@ -68,6 +69,9 @@
 	wgsl    = outputFormat("wgsl")
 )
 
+// allOutputFormats holds all the supported outputFormats
+var allOutputFormats = []outputFormat{wgsl, spvasm, msl, hlslDXC, hlslFXC, glsl}
+
 // The root directory of the dawn project
 var dawnRoot = fileutils.DawnRoot()
 
@@ -216,27 +220,14 @@
 	// Parse --format into a list of outputFormat
 	formats := []outputFormat{}
 	if formatList == "all" {
-		formats = []outputFormat{wgsl, spvasm, msl, hlslDXC, hlslFXC, glsl}
+		formats = allOutputFormats
 	} else {
 		for _, f := range strings.Split(formatList, ",") {
-			switch strings.TrimSpace(f) {
-			case "wgsl":
-				formats = append(formats, wgsl)
-			case "spvasm":
-				formats = append(formats, spvasm)
-			case "msl":
-				formats = append(formats, msl)
-			case "hlsl":
-				formats = append(formats, hlslDXC, hlslFXC)
-			case "hlsl-dxc":
-				formats = append(formats, hlslDXC)
-			case "hlsl-fxc":
-				formats = append(formats, hlslFXC)
-			case "glsl":
-				formats = append(formats, glsl)
-			default:
-				return fmt.Errorf("unknown format '%s'", f)
+			parsed, err := parseOutputFormats(strings.TrimSpace(f))
+			if err != nil {
+				return err
 			}
+			formats = append(formats, parsed...)
 		}
 	}
 
@@ -333,14 +324,23 @@
 	// Issue the jobs...
 	go func() {
 		for i, file := range absFiles { // For each test file...
-			flags := parseFlags(file)
+			flags, err := parseFlags(file)
+			if err != nil {
+				fmt.Println(file+" error:", err)
+				continue
+			}
 			for _, format := range formats { // For each output format...
-				pendingJobs <- job{
+				j := job{
 					file:   file,
-					flags:  flags,
 					format: format,
 					result: results[i][format],
 				}
+				for _, f := range flags {
+					if f.formats.Contains(format) {
+						j.flags = append(j.flags, f.flags...)
+					}
+				}
+				pendingJobs <- j
 			}
 		}
 		close(pendingJobs)
@@ -910,31 +910,71 @@
 	return true, str
 }
 
-var reFlags = regexp.MustCompile(`^ *(?:\/\/|;) *flags:(.*)`)
+var reFlags = regexp.MustCompile(`^\s*(?:\/\/|;)\s*(\[[\w-]+\])?\s*flags:(.*)`)
 
-// parseFlags looks for a `// flags:` header at the start of the file with the
-// given path, returning each of the space delimited tokens that follow for the
-// line
-func parseFlags(path string) []string {
+// cmdLineFlags are the flags that apply to the given formats, parsed by parseFlags
+type cmdLineFlags struct {
+	formats container.Set[outputFormat]
+	flags   []string
+}
+
+// parseFlags looks for a `// flags:` or `// [format] flags:` header at the start of the file with
+// the given path, returning each of the parsed flags
+func parseFlags(path string) ([]cmdLineFlags, error) {
 	inputFile, err := os.Open(path)
 	if err != nil {
-		return nil
+		return nil, err
 	}
 	defer inputFile.Close()
 
+	out := []cmdLineFlags{}
 	scanner := bufio.NewScanner(inputFile)
 	scanner.Split(bufio.ScanLines)
 	for scanner.Scan() {
 		content := scanner.Text()
 		m := reFlags.FindStringSubmatch(content)
-		if len(m) == 2 {
-			return strings.Split(m[1], " ")
+		if len(m) == 3 {
+			formats := allOutputFormats
+			if m[1] != "" {
+				fmts, err := parseOutputFormats(strings.Trim(m[1], "[]"))
+				if err != nil {
+					return nil, err
+				}
+				formats = fmts
+			}
+			out = append(out, cmdLineFlags{
+				formats: container.NewSet(formats...),
+				flags:   strings.Split(m[2], " "),
+			})
+			continue
 		}
 		if len(content) > 0 && !strings.HasPrefix(content, "//") {
 			break
 		}
 	}
-	return nil
+	return out, nil
+}
+
+// parseOutputFormats parses the outputFormat(s) from s.
+func parseOutputFormats(s string) ([]outputFormat, error) {
+	switch s {
+	case "wgsl":
+		return []outputFormat{wgsl}, nil
+	case "spvasm":
+		return []outputFormat{spvasm}, nil
+	case "msl":
+		return []outputFormat{msl}, nil
+	case "hlsl":
+		return []outputFormat{hlslDXC, hlslFXC}, nil
+	case "hlsl-dxc":
+		return []outputFormat{hlslDXC}, nil
+	case "hlsl-fxc":
+		return []outputFormat{hlslFXC}, nil
+	case "glsl":
+		return []outputFormat{glsl}, nil
+	default:
+		return nil, fmt.Errorf("unknown format '%s'", s)
+	}
 }
 
 func printDuration(d time.Duration) string {