mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
tint: Add support for workgroupUniformLoad
Accept any type in the intrinsics definition, and then manually validate that there are no atomics in the type. Add manual E2E tests for composite types. Use the BuiltinPolyfill transform to implement it for all backends. Update the uniformity analysis with special-case tags for the builtin. Fixed: tint:1780 Change-Id: I95786dff4df70a0b16ed1c53b853b5d0ec6bc501 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114862 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: James Price <jrprice@google.com> Kokoro: James Price <jrprice@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
3b83e389fa
commit
128980f218
@@ -39,7 +39,14 @@ struct BuiltinPolyfill::State {
|
||||
/// Constructor
|
||||
/// @param c the CloneContext
|
||||
/// @param p the builtins to polyfill
|
||||
State(CloneContext& c, Builtins p) : ctx(c), polyfill(p) {}
|
||||
State(CloneContext& c, Builtins p) : ctx(c), polyfill(p) {
|
||||
has_full_ptr_params = false;
|
||||
for (auto* enable : c.src->AST().Enables()) {
|
||||
if (enable->extension == ast::Extension::kChromiumExperimentalFullPtrParameters) {
|
||||
has_full_ptr_params = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Function polyfills
|
||||
@@ -660,6 +667,29 @@ struct BuiltinPolyfill::State {
|
||||
return name;
|
||||
}
|
||||
|
||||
/// Builds the polyfill function for the `workgroupUniformLoad` builtin.
|
||||
/// @param type the type being loaded
|
||||
/// @return the polyfill function name
|
||||
Symbol workgroupUniformLoad(const type::Type* type) {
|
||||
if (!has_full_ptr_params) {
|
||||
b.Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
|
||||
has_full_ptr_params = true;
|
||||
}
|
||||
auto name = b.Symbols().New("tint_workgroupUniformLoad");
|
||||
b.Func(name,
|
||||
utils::Vector{
|
||||
b.Param("p", b.ty.pointer(T(type), ast::AddressSpace::kWorkgroup)),
|
||||
},
|
||||
T(type),
|
||||
utils::Vector{
|
||||
b.CallStmt(b.Call("workgroupBarrier")),
|
||||
b.Decl(b.Let("result", b.Deref("p"))),
|
||||
b.CallStmt(b.Call("workgroupBarrier")),
|
||||
b.Return("result"),
|
||||
});
|
||||
return name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Inline polyfills
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -756,6 +786,9 @@ struct BuiltinPolyfill::State {
|
||||
// Polyfill functions for binary operators.
|
||||
utils::Hashmap<BinaryOpSignature, Symbol, 8> binary_op_polyfills;
|
||||
|
||||
// Tracks whether the chromium_experimental_full_ptr_parameters extension has been enabled.
|
||||
bool has_full_ptr_params;
|
||||
|
||||
/// @returns the AST type for the given sem type
|
||||
const ast::Type* T(const type::Type* ty) const { return CreateASTTypeFor(ctx, ty); }
|
||||
|
||||
@@ -913,6 +946,13 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
|
||||
}
|
||||
break;
|
||||
|
||||
case sem::BuiltinType::kWorkgroupUniformLoad:
|
||||
if (polyfill.workgroup_uniform_load) {
|
||||
fn = builtin_polyfills.GetOrCreate(
|
||||
builtin, [&] { return s.workgroupUniformLoad(builtin->ReturnType()); });
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@ class BuiltinPolyfill final : public Castable<BuiltinPolyfill, Transform> {
|
||||
/// Should the vector form of `quantizeToF16()` be polyfilled with a scalar implementation?
|
||||
/// See crbug.com/tint/1741
|
||||
bool quantize_to_vec_f16 = false;
|
||||
/// Should `workgroupUniformLoad()` be polyfilled?
|
||||
bool workgroup_uniform_load = false;
|
||||
};
|
||||
|
||||
/// Config is consumed by the BuiltinPolyfill transform.
|
||||
|
||||
@@ -2942,6 +2942,169 @@ fn f() {
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// workgroupUniformLoad
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DataMap polyfillWorkgroupUniformLoad() {
|
||||
BuiltinPolyfill::Builtins builtins;
|
||||
builtins.workgroup_uniform_load = true;
|
||||
DataMap data;
|
||||
data.Add<BuiltinPolyfill::Config>(builtins);
|
||||
return data;
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, ShouldRunWorkgroupUniformLoad) {
|
||||
auto* src = R"(
|
||||
var<workgroup> v : i32;
|
||||
|
||||
fn f() {
|
||||
workgroupUniformLoad(&v);
|
||||
}
|
||||
)";
|
||||
|
||||
EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
|
||||
EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillWorkgroupUniformLoad()));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, WorkgroupUniformLoad_i32) {
|
||||
auto* src = R"(
|
||||
var<workgroup> v : i32;
|
||||
|
||||
fn f() {
|
||||
let r = workgroupUniformLoad(&v);
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
enable chromium_experimental_full_ptr_parameters;
|
||||
|
||||
fn tint_workgroupUniformLoad(p : ptr<workgroup, i32>) -> i32 {
|
||||
workgroupBarrier();
|
||||
let result = *(p);
|
||||
workgroupBarrier();
|
||||
return result;
|
||||
}
|
||||
|
||||
var<workgroup> v : i32;
|
||||
|
||||
fn f() {
|
||||
let r = tint_workgroupUniformLoad(&(v));
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillWorkgroupUniformLoad());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, WorkgroupUniformLoad_ComplexType) {
|
||||
auto* src = R"(
|
||||
struct Inner {
|
||||
b : bool,
|
||||
v : vec4<i32>,
|
||||
m : mat3x3<f32>,
|
||||
}
|
||||
|
||||
struct Outer {
|
||||
a : array<Inner, 4>,
|
||||
}
|
||||
|
||||
var<workgroup> v : Outer;
|
||||
|
||||
fn f() {
|
||||
let r = workgroupUniformLoad(&v);
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
enable chromium_experimental_full_ptr_parameters;
|
||||
|
||||
fn tint_workgroupUniformLoad(p : ptr<workgroup, Outer>) -> Outer {
|
||||
workgroupBarrier();
|
||||
let result = *(p);
|
||||
workgroupBarrier();
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
b : bool,
|
||||
v : vec4<i32>,
|
||||
m : mat3x3<f32>,
|
||||
}
|
||||
|
||||
struct Outer {
|
||||
a : array<Inner, 4>,
|
||||
}
|
||||
|
||||
var<workgroup> v : Outer;
|
||||
|
||||
fn f() {
|
||||
let r = tint_workgroupUniformLoad(&(v));
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillWorkgroupUniformLoad());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(BuiltinPolyfillTest, WorkgroupUniformLoad_AvoidDuplicateEnables) {
|
||||
auto* src = R"(
|
||||
enable chromium_experimental_full_ptr_parameters;
|
||||
|
||||
var<workgroup> a : i32;
|
||||
var<workgroup> b : u32;
|
||||
var<workgroup> c : f32;
|
||||
|
||||
fn f() {
|
||||
let ra = workgroupUniformLoad(&a);
|
||||
let rb = workgroupUniformLoad(&b);
|
||||
let rc = workgroupUniformLoad(&c);
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
enable chromium_experimental_full_ptr_parameters;
|
||||
|
||||
fn tint_workgroupUniformLoad(p : ptr<workgroup, i32>) -> i32 {
|
||||
workgroupBarrier();
|
||||
let result = *(p);
|
||||
workgroupBarrier();
|
||||
return result;
|
||||
}
|
||||
|
||||
fn tint_workgroupUniformLoad_1(p : ptr<workgroup, u32>) -> u32 {
|
||||
workgroupBarrier();
|
||||
let result = *(p);
|
||||
workgroupBarrier();
|
||||
return result;
|
||||
}
|
||||
|
||||
fn tint_workgroupUniformLoad_2(p : ptr<workgroup, f32>) -> f32 {
|
||||
workgroupBarrier();
|
||||
let result = *(p);
|
||||
workgroupBarrier();
|
||||
return result;
|
||||
}
|
||||
|
||||
var<workgroup> a : i32;
|
||||
|
||||
var<workgroup> b : u32;
|
||||
|
||||
var<workgroup> c : f32;
|
||||
|
||||
fn f() {
|
||||
let ra = tint_workgroupUniformLoad(&(a));
|
||||
let rb = tint_workgroupUniformLoad_1(&(b));
|
||||
let rc = tint_workgroupUniformLoad_2(&(c));
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<BuiltinPolyfill>(src, polyfillWorkgroupUniformLoad());
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// quantizeToF16
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user