tint/ast: Generate ast::TexelFormat from intrinsics.def

Emit unit tests for parsing and printing.
Emit benchmarks for parsing.
Uses intrinsics.def as a single-source-of-truth.
The generators provide a way to optimize the enum parsers.

Change-Id: I603c2a1bd238eb8d059f3d13238e5e48379de6af
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97202
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton
2022-07-27 22:30:10 +00:00
committed by Dawn LUCI CQ
parent fe8e6ee682
commit 08659d098d
22 changed files with 622 additions and 161 deletions

View File

@@ -238,7 +238,7 @@ struct TextureOverloadCase {
Access const access = Access::kReadWrite;
/// The image format for the storage texture
/// Used only when texture_kind is kStorage
ast::TexelFormat const texel_format = ast::TexelFormat::kNone;
ast::TexelFormat const texel_format = ast::TexelFormat::kInvalid;
/// The dimensions of the texture parameter
ast::TextureDimension const texture_dimension;
/// The data type of the texture parameter

View File

@@ -23,65 +23,6 @@ TINT_INSTANTIATE_TYPEINFO(tint::ast::StorageTexture);
namespace tint::ast {
// Note, these names match the names in the WGSL spec. This behaviour is used
// in the WGSL writer to emit the texture format names.
std::ostream& operator<<(std::ostream& out, TexelFormat format) {
switch (format) {
case TexelFormat::kNone:
out << "none";
break;
case TexelFormat::kR32Uint:
out << "r32uint";
break;
case TexelFormat::kR32Sint:
out << "r32sint";
break;
case TexelFormat::kR32Float:
out << "r32float";
break;
case TexelFormat::kRgba8Unorm:
out << "rgba8unorm";
break;
case TexelFormat::kRgba8Snorm:
out << "rgba8snorm";
break;
case TexelFormat::kRgba8Uint:
out << "rgba8uint";
break;
case TexelFormat::kRgba8Sint:
out << "rgba8sint";
break;
case TexelFormat::kRg32Uint:
out << "rg32uint";
break;
case TexelFormat::kRg32Sint:
out << "rg32sint";
break;
case TexelFormat::kRg32Float:
out << "rg32float";
break;
case TexelFormat::kRgba16Uint:
out << "rgba16uint";
break;
case TexelFormat::kRgba16Sint:
out << "rgba16sint";
break;
case TexelFormat::kRgba16Float:
out << "rgba16float";
break;
case TexelFormat::kRgba32Uint:
out << "rgba32uint";
break;
case TexelFormat::kRgba32Sint:
out << "rgba32sint";
break;
case TexelFormat::kRgba32Float:
out << "rgba32float";
break;
}
return out;
}
StorageTexture::StorageTexture(ProgramID pid,
NodeID nid,
const Source& src,
@@ -135,7 +76,7 @@ Type* StorageTexture::SubtypeFor(TexelFormat format, ProgramBuilder& builder) {
return builder.create<F32>();
}
case TexelFormat::kNone:
case TexelFormat::kInvalid:
break;
}

View File

@@ -18,36 +18,11 @@
#include <string>
#include "src/tint/ast/access.h"
#include "src/tint/ast/texel_format.h"
#include "src/tint/ast/texture.h"
namespace tint::ast {
/// The texel format in the storage texture
enum class TexelFormat {
kNone = -1,
kRgba8Unorm,
kRgba8Snorm,
kRgba8Uint,
kRgba8Sint,
kRgba16Uint,
kRgba16Sint,
kRgba16Float,
kR32Uint,
kR32Sint,
kR32Float,
kRg32Uint,
kRg32Sint,
kRg32Float,
kRgba32Uint,
kRgba32Sint,
kRgba32Float,
};
/// @param out the std::ostream to write to
/// @param format the TexelFormat
/// @return the std::ostream so calls can be chained
std::ostream& operator<<(std::ostream& out, TexelFormat format);
/// A storage texture type.
class StorageTexture final : public Castable<StorageTexture, Texture> {
public:

View File

@@ -0,0 +1,122 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/src/cmd/gen
// using the template:
// src/tint/ast/texel_format.cc.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#include "src/tint/ast/texel_format.h"
namespace tint::ast {
/// ParseTexelFormat parses a TexelFormat from a string.
/// @param str the string to parse
/// @returns the parsed enum, or TexelFormat::kInvalid if the string could not be parsed.
TexelFormat ParseTexelFormat(std::string_view str) {
if (str == "rgba8unorm") {
return TexelFormat::kRgba8Unorm;
}
if (str == "rgba8snorm") {
return TexelFormat::kRgba8Snorm;
}
if (str == "rgba8uint") {
return TexelFormat::kRgba8Uint;
}
if (str == "rgba8sint") {
return TexelFormat::kRgba8Sint;
}
if (str == "rgba16uint") {
return TexelFormat::kRgba16Uint;
}
if (str == "rgba16sint") {
return TexelFormat::kRgba16Sint;
}
if (str == "rgba16float") {
return TexelFormat::kRgba16Float;
}
if (str == "r32uint") {
return TexelFormat::kR32Uint;
}
if (str == "r32sint") {
return TexelFormat::kR32Sint;
}
if (str == "r32float") {
return TexelFormat::kR32Float;
}
if (str == "rg32uint") {
return TexelFormat::kRg32Uint;
}
if (str == "rg32sint") {
return TexelFormat::kRg32Sint;
}
if (str == "rg32float") {
return TexelFormat::kRg32Float;
}
if (str == "rgba32uint") {
return TexelFormat::kRgba32Uint;
}
if (str == "rgba32sint") {
return TexelFormat::kRgba32Sint;
}
if (str == "rgba32float") {
return TexelFormat::kRgba32Float;
}
return TexelFormat::kInvalid;
}
std::ostream& operator<<(std::ostream& out, TexelFormat value) {
switch (value) {
case TexelFormat::kInvalid:
return out << "invalid";
case TexelFormat::kRgba8Unorm:
return out << "rgba8unorm";
case TexelFormat::kRgba8Snorm:
return out << "rgba8snorm";
case TexelFormat::kRgba8Uint:
return out << "rgba8uint";
case TexelFormat::kRgba8Sint:
return out << "rgba8sint";
case TexelFormat::kRgba16Uint:
return out << "rgba16uint";
case TexelFormat::kRgba16Sint:
return out << "rgba16sint";
case TexelFormat::kRgba16Float:
return out << "rgba16float";
case TexelFormat::kR32Uint:
return out << "r32uint";
case TexelFormat::kR32Sint:
return out << "r32sint";
case TexelFormat::kR32Float:
return out << "r32float";
case TexelFormat::kRg32Uint:
return out << "rg32uint";
case TexelFormat::kRg32Sint:
return out << "rg32sint";
case TexelFormat::kRg32Float:
return out << "rg32float";
case TexelFormat::kRgba32Uint:
return out << "rgba32uint";
case TexelFormat::kRgba32Sint:
return out << "rgba32sint";
case TexelFormat::kRgba32Float:
return out << "rgba32float";
}
return out << "<unknown>";
}
} // namespace tint::ast

View File

@@ -0,0 +1,22 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate texel_format.cc
See:
* tools/src/cmd/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}
{{- Import "src/tint/templates/enums.tmpl.inc" -}}
{{- $enum := (Sem.Enum "texel_format") -}}
#include "src/tint/ast/texel_format.h"
namespace tint::ast {
{{ Eval "ParseEnum" $enum}}
{{ Eval "EnumOStream" $enum}}
} // namespace tint::ast

View File

@@ -0,0 +1,63 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/src/cmd/gen
// using the template:
// src/tint/ast/texel_format.h.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#ifndef SRC_TINT_AST_TEXEL_FORMAT_H_
#define SRC_TINT_AST_TEXEL_FORMAT_H_
#include <ostream>
namespace tint::ast {
/// Enumerator of texel formats
enum class TexelFormat {
kInvalid,
kRgba8Unorm,
kRgba8Snorm,
kRgba8Uint,
kRgba8Sint,
kRgba16Uint,
kRgba16Sint,
kRgba16Float,
kR32Uint,
kR32Sint,
kR32Float,
kRg32Uint,
kRg32Sint,
kRg32Float,
kRgba32Uint,
kRgba32Sint,
kRgba32Float,
};
/// @param out the std::ostream to write to
/// @param value the TexelFormat
/// @returns `out` so calls can be chained
std::ostream& operator<<(std::ostream& out, TexelFormat value);
/// ParseTexelFormat parses a TexelFormat from a string.
/// @param str the string to parse
/// @returns the parsed enum, or TexelFormat::kInvalid if the string could not be parsed.
TexelFormat ParseTexelFormat(std::string_view str);
} // namespace tint::ast
#endif // SRC_TINT_AST_TEXEL_FORMAT_H_

View File

@@ -0,0 +1,26 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate texel_format.h
See:
* tools/src/cmd/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}
{{- Import "src/tint/templates/enums.tmpl.inc" -}}
{{- $enum := (Sem.Enum "texel_format") -}}
#ifndef SRC_TINT_AST_TEXEL_FORMAT_H_
#define SRC_TINT_AST_TEXEL_FORMAT_H_
#include <ostream>
namespace tint::ast {
/// Enumerator of texel formats
{{ Eval "DeclareEnum" $enum}}
} // namespace tint::ast
#endif // SRC_TINT_AST_TEXEL_FORMAT_H_

View File

@@ -0,0 +1,158 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/src/cmd/gen
// using the template:
// src/tint/ast/texel_format_bench.cc.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#include "src/tint/ast/texel_format.h"
#include <array>
#include "benchmark/benchmark.h"
namespace tint::ast {
namespace {
void TexelFormatParser(::benchmark::State& state) {
std::array kStrings{
"rgbaunccrm",
"rlbanr3",
"rVba8unorm",
"rgba8unorm",
"rgba1unorm",
"rgbJqqnorm",
"rgb7ll8unorm",
"rgqqappnoHHm",
"rv8scor",
"rgbbGsnrm",
"rgba8snorm",
"rgba8vniirm",
"rg8a8snoWWm",
"Mgbaxxnorm",
"rXa8uggnt",
"rgbXVut",
"3gba8uint",
"rgba8uint",
"rgba8uiEt",
"rgTTPauint",
"ddgbauixxt",
"44gba8sint",
"VVgbaSSsint",
"rba8si2Rt",
"rgba8sint",
"r9bFsint",
"rgba8int",
"rgVROOsHnt",
"ryba1uint",
"r77ba1nnullrrt",
"rgb4006uint",
"rgba16uint",
"rb1uioot",
"rga1uzznt",
"r11b1uppiit",
"XXgba16sint",
"IIgb9916nni55t",
"rYbaSSrrsiHHat",
"rgba16sint",
"rbkk6Hit",
"jgba1sgRR",
"rgbab6si",
"rgba16fljat",
"rgba6float",
"rbq6float",
"rgba16float",
"rgba1NNloat",
"rgbvv6flot",
"rgbaQQ6foat",
"r3ffir",
"r32uijt",
"rNNwuin8",
"r32uint",
"r32int",
"rrr2uint",
"G32uint",
"r32sinFF",
"32st",
"r3rrint",
"r32sint",
"2sint",
"D3siJJt",
"r38n",
"r211lk",
"r32floa",
"r3flJat",
"r32float",
"r32fcoat",
"r32floOt",
"r32floKK_vtt",
"rxx32ui8",
"Fg3qq__n",
"rg32iqqt",
"rg32uint",
"rg333uin6",
"rtto62u9QQt",
"rg366uin",
"rOx2si6zz",
"rg3yysint",
"rHHsint",
"rg32sint",
"qWW432snt",
"rg3OOsnt",
"g32siYt",
"g32flo",
"rg32foaF",
"rg32fwat",
"rg32float",
"G3fKoaff",
"KKgq2float",
"rg32mmlo3t",
"rgba32uit",
"rqba3uint",
"rgbabb2uin",
"rgba32uint",
"rba32iint",
"qgba32uiOt",
"rgba32uiTTvv",
"rgFFa32sint",
"rg00Q2sPnt",
"rgbaP2sint",
"rgba32sint",
"rgb77s2sint",
"rgba32sbbRRC",
"rgbXX32sint",
"rOOOba3CCqoat",
"rgbu32fsLt",
"rgba3Xfloat",
"rgba32float",
"rba32float",
"qqb3float",
"rgba32fl22at",
};
for (auto _ : state) {
for (auto& str : kStrings) {
auto result = ParseTexelFormat(str);
benchmark::DoNotOptimize(result);
}
}
}
BENCHMARK(TexelFormatParser);
} // namespace
} // namespace tint::ast

View File

@@ -0,0 +1,26 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate texel_format_bench.cc
See:
* tools/src/cmd/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}
{{- Import "src/tint/templates/enums.tmpl.inc" -}}
{{- $enum := (Sem.Enum "texel_format") -}}
#include "src/tint/ast/texel_format.h"
#include <array>
#include "benchmark/benchmark.h"
namespace tint::ast {
namespace {
{{ Eval "BenchmarkParseEnum" $enum }}
} // namespace
} // namespace tint::ast

View File

@@ -0,0 +1,138 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/src/cmd/gen
// using the template:
// src/tint/ast/texel_format_test.cc.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
#include "src/tint/ast/texel_format.h"
#include <string>
#include "src/tint/ast/test_helper.h"
#include "src/tint/utils/string.h"
namespace tint::ast {
namespace {
namespace parse_print_tests {
struct Case {
const char* string;
TexelFormat value;
};
inline std::ostream& operator<<(std::ostream& out, Case c) {
return out << "'" << std::string(c.string) << "'";
}
static constexpr Case kValidCases[] = {
{"rgba8unorm", TexelFormat::kRgba8Unorm},
{"rgba8snorm", TexelFormat::kRgba8Snorm},
{"rgba8uint", TexelFormat::kRgba8Uint},
{"rgba8sint", TexelFormat::kRgba8Sint},
{"rgba16uint", TexelFormat::kRgba16Uint},
{"rgba16sint", TexelFormat::kRgba16Sint},
{"rgba16float", TexelFormat::kRgba16Float},
{"r32uint", TexelFormat::kR32Uint},
{"r32sint", TexelFormat::kR32Sint},
{"r32float", TexelFormat::kR32Float},
{"rg32uint", TexelFormat::kRg32Uint},
{"rg32sint", TexelFormat::kRg32Sint},
{"rg32float", TexelFormat::kRg32Float},
{"rgba32uint", TexelFormat::kRgba32Uint},
{"rgba32sint", TexelFormat::kRgba32Sint},
{"rgba32float", TexelFormat::kRgba32Float},
};
static constexpr Case kInvalidCases[] = {
{"rgbaunccrm", TexelFormat::kInvalid},
{"rlbanr3", TexelFormat::kInvalid},
{"rVba8unorm", TexelFormat::kInvalid},
{"rgba1snorm", TexelFormat::kInvalid},
{"rgbJqqnorm", TexelFormat::kInvalid},
{"rgb7ll8snorm", TexelFormat::kInvalid},
{"rgbauippqHH", TexelFormat::kInvalid},
{"rgbaun", TexelFormat::kInvalid},
{"rba8Gint", TexelFormat::kInvalid},
{"rgvia8sint", TexelFormat::kInvalid},
{"rgba8WWint", TexelFormat::kInvalid},
{"rgbasxxMt", TexelFormat::kInvalid},
{"rXba16ungg", TexelFormat::kInvalid},
{"rba1XuVt", TexelFormat::kInvalid},
{"rgba16uin3", TexelFormat::kInvalid},
{"rgba16sinE", TexelFormat::kInvalid},
{"TTgba16sPPn", TexelFormat::kInvalid},
{"rgbad6xxint", TexelFormat::kInvalid},
{"rgba446float", TexelFormat::kInvalid},
{"SSVVba16float", TexelFormat::kInvalid},
{"rgbRR6float", TexelFormat::kInvalid},
{"rFui9t", TexelFormat::kInvalid},
{"r32int", TexelFormat::kInvalid},
{"VOORRHnt", TexelFormat::kInvalid},
{"r3siyt", TexelFormat::kInvalid},
{"lln3rrs77nt", TexelFormat::kInvalid},
{"r32s4n00", TexelFormat::kInvalid},
{"32ooat", TexelFormat::kInvalid},
{"r32fzzt", TexelFormat::kInvalid},
{"r3iippl1a", TexelFormat::kInvalid},
{"XXg32uint", TexelFormat::kInvalid},
{"rII39955nnnt", TexelFormat::kInvalid},
{"aagHH2uinYSS", TexelFormat::kInvalid},
{"rkk3it", TexelFormat::kInvalid},
{"gj3sRRn", TexelFormat::kInvalid},
{"r3bsnt", TexelFormat::kInvalid},
{"rg32flojt", TexelFormat::kInvalid},
{"r32floa", TexelFormat::kInvalid},
{"rg32lot", TexelFormat::kInvalid},
{"rgb3uit", TexelFormat::kInvalid},
{"rgjj3uint", TexelFormat::kInvalid},
{"rgb2urnff", TexelFormat::kInvalid},
{"rgba32sijt", TexelFormat::kInvalid},
{"NNgba32ww2t", TexelFormat::kInvalid},
{"rgba32snt", TexelFormat::kInvalid},
{"rgba32rrloat", TexelFormat::kInvalid},
{"rgGa32float", TexelFormat::kInvalid},
{"FFgba32float", TexelFormat::kInvalid},
};
using TexelFormatParseTest = testing::TestWithParam<Case>;
TEST_P(TexelFormatParseTest, Parse) {
const char* string = GetParam().string;
TexelFormat expect = GetParam().value;
EXPECT_EQ(expect, ParseTexelFormat(string));
}
INSTANTIATE_TEST_SUITE_P(ValidCases, TexelFormatParseTest, testing::ValuesIn(kValidCases));
INSTANTIATE_TEST_SUITE_P(InvalidCases, TexelFormatParseTest, testing::ValuesIn(kInvalidCases));
using TexelFormatPrintTest = testing::TestWithParam<Case>;
TEST_P(TexelFormatPrintTest, Print) {
TexelFormat value = GetParam().value;
const char* expect = GetParam().string;
EXPECT_EQ(expect, utils::ToString(value));
}
INSTANTIATE_TEST_SUITE_P(ValidCases, TexelFormatPrintTest, testing::ValuesIn(kValidCases));
} // namespace parse_print_tests
} // namespace
} // namespace tint::ast

View File

@@ -0,0 +1,27 @@
{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate texel_format_test.cc
See:
* tools/src/cmd/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}
{{- Import "src/tint/templates/enums.tmpl.inc" -}}
{{- $enum := (Sem.Enum "texel_format") -}}
#include "src/tint/ast/texel_format.h"
#include <string>
#include "src/tint/ast/test_helper.h"
#include "src/tint/utils/string.h"
namespace tint::ast {
namespace {
{{ Eval "TestParsePrintEnum" $enum}}
} // namespace
} // namespace tint::ast