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:
James Price 2023-01-06 02:25:06 +00:00 committed by Dawn LUCI CQ
parent 3b83e389fa
commit 128980f218
148 changed files with 5314 additions and 1407 deletions

View File

@ -657,6 +657,7 @@ bool WgslMutator::ReplaceFunctionCallWithBuiltin(std::string& wgsl_code) {
"unpack2x16unorm", "unpack2x16unorm",
"unpack2x16float", "unpack2x16float",
"storageBarrier", "storageBarrier",
"workgroupUniformLoad",
"workgroupBarrier"}; "workgroupBarrier"};
wgsl_code.replace(left_bracket_pos + function_call_identifier.first, wgsl_code.replace(left_bracket_pos + function_call_identifier.first,
function_call_identifier.second, function_call_identifier.second,

View File

@ -275,6 +275,8 @@ match workgroup_or_storage
| address_space.storage | address_space.storage
match storage match storage
: address_space.storage : address_space.storage
match workgroup
: address_space.workgroup
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Builtin Functions // // Builtin Functions //
@ -594,6 +596,7 @@ fn dot4U8Packed(u32, u32) -> u32
@const fn unpack4x8snorm(u32) -> vec4<f32> @const fn unpack4x8snorm(u32) -> vec4<f32>
@const fn unpack4x8unorm(u32) -> vec4<f32> @const fn unpack4x8unorm(u32) -> vec4<f32>
@stage("compute") fn workgroupBarrier() @stage("compute") fn workgroupBarrier()
@stage("compute") fn workgroupUniformLoad<T>(ptr<workgroup, T, read_write>) -> T
fn textureDimensions<T: fiu32>(texture: texture_1d<T>) -> u32 fn textureDimensions<T: fiu32>(texture: texture_1d<T>) -> u32
fn textureDimensions<T: fiu32, L: iu32>(texture: texture_1d<T>, level: L) -> u32 fn textureDimensions<T: fiu32, L: iu32>(texture: texture_1d<T>, level: L) -> u32

View File

@ -647,5 +647,70 @@ TEST_F(ResolverDP4aExtensionValidationTest, Dot4U8PackedWithoutExtension) {
R"(12:34 error: cannot call built-in function 'dot4U8Packed' without extension chromium_experimental_dp4a)"); R"(12:34 error: cannot call built-in function 'dot4U8Packed' without extension chromium_experimental_dp4a)");
} }
TEST_F(ResolverBuiltinValidationTest, WorkgroupUniformLoad_WrongAddressSpace) {
// @group(0) @binding(0) var<storage, read_write> v : i32;
// fn foo() {
// workgroupUniformLoad(&v);
// }
GlobalVar("v", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
utils::Vector{Group(0_a), Binding(0_a)});
WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf(Source{{12, 34}}, "v"))));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(error: no matching call to workgroupUniformLoad(ptr<storage, i32, read_write>)
1 candidate function:
workgroupUniformLoad(ptr<workgroup, T, read_write>) -> T
)");
}
TEST_F(ResolverBuiltinValidationTest, WorkgroupUniformLoad_Atomic) {
// var<workgroup> v : atomic<i32>;
// fn foo() {
// workgroupUniformLoad(&v);
// }
GlobalVar("v", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf(Source{{12, 34}}, "v"))));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(12:34 error: workgroupUniformLoad must not be called with an argument that contains an atomic type)");
}
TEST_F(ResolverBuiltinValidationTest, WorkgroupUniformLoad_AtomicInArray) {
// var<workgroup> v : array<atomic<i32>, 4>;
// fn foo() {
// workgroupUniformLoad(&v);
// }
GlobalVar("v", ty.array(ty.atomic<i32>(), 4_a), ast::AddressSpace::kWorkgroup);
WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf(Source{{12, 34}}, "v"))));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(12:34 error: workgroupUniformLoad must not be called with an argument that contains an atomic type)");
}
TEST_F(ResolverBuiltinValidationTest, WorkgroupUniformLoad_AtomicInStruct) {
// struct Inner { a : array<atomic<i32, 4> }
// struct S { i : Inner }
// var<workgroup> v : array<S, 4>;
// fn foo() {
// workgroupUniformLoad(&v);
// }
Structure("Inner", utils::Vector{Member("a", ty.array(ty.atomic<i32>(), 4_a))});
Structure("S", utils::Vector{Member("i", ty.type_name("Inner"))});
GlobalVar(Source{{12, 34}}, "v", ty.array(ty.type_name("S"), 4_a),
ast::AddressSpace::kWorkgroup);
WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf("v"))));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(error: workgroupUniformLoad must not be called with an argument that contains an atomic type)");
}
} // namespace } // namespace
} // namespace tint::resolver } // namespace tint::resolver

File diff suppressed because it is too large Load Diff

View File

@ -2386,6 +2386,12 @@ sem::Call* Resolver::BuiltinCall(const ast::CallExpression* expr,
CollectTextureSamplerPairs(builtin.sem, call->Arguments()); CollectTextureSamplerPairs(builtin.sem, call->Arguments());
} }
if (builtin_type == sem::BuiltinType::kWorkgroupUniformLoad) {
if (!validator_.WorkgroupUniformLoad(call)) {
return nullptr;
}
}
if (!validator_.BuiltinCall(call)) { if (!validator_.BuiltinCall(call)) {
return nullptr; return nullptr;
} }

View File

@ -176,6 +176,7 @@ TEST_P(SideEffectsBuiltinTest, Test) {
GlobalVar("arr", ty.array<f32, 10>(), ast::AddressSpace::kPrivate); GlobalVar("arr", ty.array<f32, 10>(), ast::AddressSpace::kPrivate);
GlobalVar("storage_arr", ty.array<f32>(), ast::AddressSpace::kStorage, Group(0_a), GlobalVar("storage_arr", ty.array<f32>(), ast::AddressSpace::kStorage, Group(0_a),
Binding(AInt(next_binding++))); Binding(AInt(next_binding++)));
GlobalVar("workgroup_arr", ty.array<f32, 4>(), ast::AddressSpace::kWorkgroup);
GlobalVar("a", ty.atomic(ty.i32()), ast::AddressSpace::kStorage, ast::Access::kReadWrite, GlobalVar("a", ty.atomic(ty.i32()), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
Group(0_a), Binding(AInt(next_binding++))); Group(0_a), Binding(AInt(next_binding++)));
if (c.pipeline_stage != ast::PipelineStage::kCompute) { if (c.pipeline_stage != ast::PipelineStage::kCompute) {
@ -199,6 +200,9 @@ TEST_P(SideEffectsBuiltinTest, Test) {
utils::Vector<const ast::Statement*, 4> stmts; utils::Vector<const ast::Statement*, 4> stmts;
stmts.Push(Decl(Let("pstorage_arr", AddressOf("storage_arr")))); stmts.Push(Decl(Let("pstorage_arr", AddressOf("storage_arr"))));
if (c.pipeline_stage == ast::PipelineStage::kCompute) {
stmts.Push(Decl(Let("pworkgroup_arr", AddressOf("workgroup_arr"))));
}
stmts.Push(Decl(Let("pa", AddressOf("a")))); stmts.Push(Decl(Let("pa", AddressOf("a"))));
utils::Vector<const ast::Expression*, 5> args; utils::Vector<const ast::Expression*, 5> args;
@ -339,6 +343,10 @@ INSTANTIATE_TEST_SUITE_P(
C("atomicSub", utils::Vector{"pa", "i"}, true), // C("atomicSub", utils::Vector{"pa", "i"}, true), //
C("atomicXor", utils::Vector{"pa", "i"}, true), // C("atomicXor", utils::Vector{"pa", "i"}, true), //
C("textureStore", utils::Vector{"tstorage2d", "vi2", "vf4"}, true), // C("textureStore", utils::Vector{"tstorage2d", "vi2", "vf4"}, true), //
C("workgroupUniformLoad",
utils::Vector{"pworkgroup_arr"},
true,
ast::PipelineStage::kCompute), //
// Unimplemented builtins // Unimplemented builtins
// C("quantizeToF16", utils::Vector{"f"}, false), // // C("quantizeToF16", utils::Vector{"f"}, false), //

View File

@ -23,6 +23,7 @@
#include "src/tint/resolver/dependency_graph.h" #include "src/tint/resolver/dependency_graph.h"
#include "src/tint/scope_stack.h" #include "src/tint/scope_stack.h"
#include "src/tint/sem/block_statement.h" #include "src/tint/sem/block_statement.h"
#include "src/tint/sem/builtin.h"
#include "src/tint/sem/for_loop_statement.h" #include "src/tint/sem/for_loop_statement.h"
#include "src/tint/sem/function.h" #include "src/tint/sem/function.h"
#include "src/tint/sem/if_statement.h" #include "src/tint/sem/if_statement.h"
@ -1454,6 +1455,8 @@ class UniformityGraph {
// some texture sampling builtins, and atomics. // some texture sampling builtins, and atomics.
if (builtin->IsBarrier()) { if (builtin->IsBarrier()) {
callsite_tag = CallSiteRequiredToBeUniform; callsite_tag = CallSiteRequiredToBeUniform;
} else if (builtin->Type() == sem::BuiltinType::kWorkgroupUniformLoad) {
callsite_tag = CallSiteRequiredToBeUniform;
} else if (builtin->IsDerivative() || } else if (builtin->IsDerivative() ||
builtin->Type() == sem::BuiltinType::kTextureSample || builtin->Type() == sem::BuiltinType::kTextureSample ||
builtin->Type() == sem::BuiltinType::kTextureSampleBias || builtin->Type() == sem::BuiltinType::kTextureSampleBias ||
@ -1489,9 +1492,6 @@ class UniformityGraph {
TINT_ICE(Resolver, diagnostics_) << "unhandled function call target: " << name; TINT_ICE(Resolver, diagnostics_) << "unhandled function call target: " << name;
}); });
if (callsite_tag == CallSiteRequiredToBeUniform) {
current_function_->required_to_be_uniform->AddEdge(call_node);
}
cf_after->AddEdge(call_node); cf_after->AddEdge(call_node);
if (function_tag == ReturnValueMayBeNonUniform) { if (function_tag == ReturnValueMayBeNonUniform) {
@ -1562,12 +1562,25 @@ class UniformityGraph {
current_function_->variables.Set(root_ident, ptr_result); current_function_->variables.Set(root_ident, ptr_result);
} }
} else { } else {
// All builtin function parameters are RequiredToBeUniformForReturnValue, as are auto* builtin = sem->Target()->As<sem::Builtin>();
// parameters for type initializers and type conversions. if (builtin && builtin->Type() == sem::BuiltinType::kWorkgroupUniformLoad) {
result->AddEdge(args[i]); // The workgroupUniformLoad builtin requires its parameter to be uniform.
current_function_->required_to_be_uniform->AddEdge(args[i]);
} else {
// All other builtin function parameters are RequiredToBeUniformForReturnValue,
// as are parameters for type initializers and type conversions.
result->AddEdge(args[i]);
}
} }
} }
// Add the callsite requirement last.
// We traverse edges in reverse order, so this makes the callsite requirement take highest
// priority when reporting violations.
if (callsite_tag == CallSiteRequiredToBeUniform) {
current_function_->required_to_be_uniform->AddEdge(call_node);
}
return {cf_after, result}; return {cf_after, result};
} }
@ -1799,9 +1812,13 @@ class UniformityGraph {
if (cause->type == Node::kFunctionCallArgumentValue) { if (cause->type == Node::kFunctionCallArgumentValue) {
// The requirement was on a function parameter. // The requirement was on a function parameter.
auto param_name = NameFor(target->Parameters()[cause->arg_index]->Declaration()); auto* ast_param = target->Parameters()[cause->arg_index]->Declaration();
std::string param_name;
if (ast_param) {
param_name = " '" + NameFor(ast_param) + "'";
}
report(call->args[cause->arg_index]->source, report(call->args[cause->arg_index]->source,
"parameter '" + param_name + "' of '" + func_name + "' must be uniform"); "parameter" + param_name + " of '" + func_name + "' must be uniform");
// If this is a call to a user-defined function, add a note to show the reason that the // If this is a call to a user-defined function, add a note to show the reason that the
// parameter is required to be uniform. // parameter is required to be uniform.

View File

@ -116,6 +116,7 @@ class BasicTest : public UniformityAnalysisTestBase,
kUserRequiredToBeUniform, kUserRequiredToBeUniform,
kWorkgroupBarrier, kWorkgroupBarrier,
kStorageBarrier, kStorageBarrier,
kWorkgroupUniformLoad,
kTextureSample, kTextureSample,
kTextureSampleBias, kTextureSampleBias,
kTextureSampleCompare, kTextureSampleCompare,
@ -184,6 +185,8 @@ class BasicTest : public UniformityAnalysisTestBase,
return "workgroupBarrier()"; return "workgroupBarrier()";
case kStorageBarrier: case kStorageBarrier:
return "storageBarrier()"; return "storageBarrier()";
case kWorkgroupUniformLoad:
return "workgroupUniformLoad(&w)";
case kTextureSample: case kTextureSample:
return "textureSample(t, s, vec2(0.5, 0.5))"; return "textureSample(t, s, vec2(0.5, 0.5))";
case kTextureSampleBias: case kTextureSampleBias:
@ -257,6 +260,7 @@ class BasicTest : public UniformityAnalysisTestBase,
CASE(kUserRequiredToBeUniform); CASE(kUserRequiredToBeUniform);
CASE(kWorkgroupBarrier); CASE(kWorkgroupBarrier);
CASE(kStorageBarrier); CASE(kStorageBarrier);
CASE(kWorkgroupUniformLoad);
CASE(kTextureSample); CASE(kTextureSample);
CASE(kTextureSampleBias); CASE(kTextureSampleBias);
CASE(kTextureSampleCompare); CASE(kTextureSampleCompare);
@ -7591,6 +7595,106 @@ test:4:48 note: reading from read_write storage buffer 'arr' may result in a non
)"); )");
} }
TEST_F(UniformityAnalysisTest, WorkgroupUniformLoad) {
std::string src = R"(
const wgsize = 4;
var<workgroup> data : array<u32, wgsize>;
@compute @workgroup_size(wgsize)
fn main(@builtin(local_invocation_index) idx : u32) {
data[idx] = idx + 1;
if (workgroupUniformLoad(&data[0]) > 0) {
workgroupBarrier();
}
}
)";
RunTest(src, true);
}
TEST_F(UniformityAnalysisTest, WorkgroupUniformLoad_ViaPtrArg) {
std::string src = R"(
enable chromium_experimental_full_ptr_parameters;
const wgsize = 4;
var<workgroup> data : array<u32, wgsize>;
fn foo(p : ptr<workgroup, u32>) -> u32 {
return workgroupUniformLoad(p);
}
@compute @workgroup_size(wgsize)
fn main(@builtin(local_invocation_index) idx : u32) {
data[idx] = idx + 1;
if (foo(&data[0]) > 0) {
workgroupBarrier();
}
}
)";
RunTest(src, true);
}
TEST_F(UniformityAnalysisTest, WorkgroupUniformLoad_NonUniformPtr) {
std::string src = R"(
const wgsize = 4;
var<workgroup> data : array<u32, wgsize>;
@compute @workgroup_size(wgsize)
fn main(@builtin(local_invocation_index) idx : u32) {
data[idx] = idx + 1;
if (workgroupUniformLoad(&data[idx]) > 0) {
workgroupBarrier();
}
}
)";
RunTest(src, false);
EXPECT_EQ(error_, R"(test:8:28 warning: parameter of 'workgroupUniformLoad' must be uniform
if (workgroupUniformLoad(&data[idx]) > 0) {
^
test:8:34 note: reading from builtin 'idx' may result in a non-uniform value
if (workgroupUniformLoad(&data[idx]) > 0) {
^^^
)");
}
TEST_F(UniformityAnalysisTest, WorkgroupUniformLoad_NonUniformPtr_ViaPtrArg) {
std::string src = R"(
enable chromium_experimental_full_ptr_parameters;
const wgsize = 4;
var<workgroup> data : array<u32, wgsize>;
fn foo(p : ptr<workgroup, u32>) -> u32 {
return workgroupUniformLoad(p);
}
@compute @workgroup_size(wgsize)
fn main(@builtin(local_invocation_index) idx : u32) {
data[idx] = idx + 1;
if (foo(&data[idx]) > 0) {
workgroupBarrier();
}
}
)";
RunTest(src, false);
EXPECT_EQ(error_, R"(test:14:11 warning: parameter 'p' of 'foo' must be uniform
if (foo(&data[idx]) > 0) {
^
test:8:31 note: parameter of 'workgroupUniformLoad' must be uniform
return workgroupUniformLoad(p);
^
test:14:17 note: reading from builtin 'idx' may result in a non-uniform value
if (foo(&data[idx]) > 0) {
^^^
)");
}
TEST_F(UniformityAnalysisTest, WorkgroupAtomics) { TEST_F(UniformityAnalysisTest, WorkgroupAtomics) {
std::string src = R"( std::string src = R"(
var<workgroup> a : atomic<i32>; var<workgroup> a : atomic<i32>;
@ -7863,5 +7967,44 @@ test:17:7 note: return value of 'foo' may be non-uniform
)"); )");
} }
TEST_F(UniformityAnalysisTest, Error_CallsiteAndParameterRequireUniformity) {
// Test that we report a violation for the callsite of a function when it has multiple
// uniformity requirements.
std::string src = R"(
@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
fn foo(v : i32) {
if (v == 0) {
workgroupBarrier();
}
}
fn main() {
if (non_uniform == 42) {
foo(0);
}
}
)";
RunTest(src, false);
EXPECT_EQ(error_,
R"(test:12:5 warning: 'foo' must only be called from uniform control flow
foo(0);
^^^
test:6:5 note: 'foo' requires uniformity because it calls workgroupBarrier
workgroupBarrier();
^^^^^^^^^^^^^^^^
test:11:3 note: control flow depends on non-uniform value
if (non_uniform == 42) {
^^
test:11:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
if (non_uniform == 42) {
^^^^^^^^^^^
)");
}
} // namespace } // namespace
} // namespace tint::resolver } // namespace tint::resolver

View File

@ -1604,6 +1604,28 @@ bool Validator::TextureBuiltinFunction(const sem::Call* call) const {
check_arg_is_constexpr(sem::ParameterUsage::kComponent, 0, 3); check_arg_is_constexpr(sem::ParameterUsage::kComponent, 0, 3);
} }
bool Validator::WorkgroupUniformLoad(const sem::Call* call) const {
auto* builtin = call->Target()->As<sem::Builtin>();
if (!builtin) {
return false;
}
TINT_ASSERT(Resolver, call->Arguments().Length() > 0);
auto* arg = call->Arguments()[0];
auto* ptr = arg->Type()->As<type::Pointer>();
TINT_ASSERT(Resolver, ptr != nullptr);
auto* ty = ptr->StoreType();
if (ty->Is<type::Atomic>() || atomic_composite_info_.Contains(ty)) {
AddError(
"workgroupUniformLoad must not be called with an argument that contains an atomic type",
arg->Declaration()->source);
return false;
}
return true;
}
bool Validator::RequiredExtensionForBuiltinFunction(const sem::Call* call) const { bool Validator::RequiredExtensionForBuiltinFunction(const sem::Call* call) const {
const auto* builtin = call->Target()->As<sem::Builtin>(); const auto* builtin = call->Target()->As<sem::Builtin>();
if (!builtin) { if (!builtin) {

View File

@ -439,6 +439,11 @@ class Validator {
/// @returns true on success, false otherwise /// @returns true on success, false otherwise
bool TextureBuiltinFunction(const sem::Call* call) const; bool TextureBuiltinFunction(const sem::Call* call) const;
/// Validates a workgroupUniformLoad builtin function
/// @param call the builtin call to validate
/// @returns true on success, false otherwise
bool WorkgroupUniformLoad(const sem::Call* call) const;
/// Validates an optional builtin function and its required extension. /// Validates an optional builtin function and its required extension.
/// @param call the builtin call to validate /// @param call the builtin call to validate
/// @returns true on success, false otherwise /// @returns true on success, false otherwise

View File

@ -171,6 +171,7 @@ bool Builtin::HasSideEffects() const {
case sem::BuiltinType::kAtomicSub: case sem::BuiltinType::kAtomicSub:
case sem::BuiltinType::kAtomicXor: case sem::BuiltinType::kAtomicXor:
case sem::BuiltinType::kTextureStore: case sem::BuiltinType::kTextureStore:
case sem::BuiltinType::kWorkgroupUniformLoad:
return true; return true;
default: default:
break; break;

View File

@ -116,7 +116,8 @@ INSTANTIATE_TEST_SUITE_P(
BuiltinData{"unpack2x16unorm", BuiltinType::kUnpack2X16Unorm}, BuiltinData{"unpack2x16unorm", BuiltinType::kUnpack2X16Unorm},
BuiltinData{"unpack4x8snorm", BuiltinType::kUnpack4X8Snorm}, BuiltinData{"unpack4x8snorm", BuiltinType::kUnpack4X8Snorm},
BuiltinData{"unpack4x8unorm", BuiltinType::kUnpack4X8Unorm}, BuiltinData{"unpack4x8unorm", BuiltinType::kUnpack4X8Unorm},
BuiltinData{"workgroupBarrier", BuiltinType::kWorkgroupBarrier})); BuiltinData{"workgroupBarrier", BuiltinType::kWorkgroupBarrier},
BuiltinData{"workgroupUniformLoad", BuiltinType::kWorkgroupUniformLoad}));
TEST_F(BuiltinTypeTest, ParseNoMatch) { TEST_F(BuiltinTypeTest, ParseNoMatch) {
EXPECT_EQ(ParseBuiltinType("not_builtin"), BuiltinType::kNone); EXPECT_EQ(ParseBuiltinType("not_builtin"), BuiltinType::kNone);

View File

@ -285,6 +285,9 @@ BuiltinType ParseBuiltinType(const std::string& name) {
if (name == "workgroupBarrier") { if (name == "workgroupBarrier") {
return BuiltinType::kWorkgroupBarrier; return BuiltinType::kWorkgroupBarrier;
} }
if (name == "workgroupUniformLoad") {
return BuiltinType::kWorkgroupUniformLoad;
}
if (name == "textureDimensions") { if (name == "textureDimensions") {
return BuiltinType::kTextureDimensions; return BuiltinType::kTextureDimensions;
} }
@ -545,6 +548,8 @@ const char* str(BuiltinType i) {
return "unpack4x8unorm"; return "unpack4x8unorm";
case BuiltinType::kWorkgroupBarrier: case BuiltinType::kWorkgroupBarrier:
return "workgroupBarrier"; return "workgroupBarrier";
case BuiltinType::kWorkgroupUniformLoad:
return "workgroupUniformLoad";
case BuiltinType::kTextureDimensions: case BuiltinType::kTextureDimensions:
return "textureDimensions"; return "textureDimensions";
case BuiltinType::kTextureGather: case BuiltinType::kTextureGather:

View File

@ -117,6 +117,7 @@ enum class BuiltinType {
kUnpack4X8Snorm, kUnpack4X8Snorm,
kUnpack4X8Unorm, kUnpack4X8Unorm,
kWorkgroupBarrier, kWorkgroupBarrier,
kWorkgroupUniformLoad,
kTextureDimensions, kTextureDimensions,
kTextureGather, kTextureGather,
kTextureGatherCompare, kTextureGatherCompare,

View File

@ -39,7 +39,14 @@ struct BuiltinPolyfill::State {
/// Constructor /// Constructor
/// @param c the CloneContext /// @param c the CloneContext
/// @param p the builtins to polyfill /// @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 // Function polyfills
@ -660,6 +667,29 @@ struct BuiltinPolyfill::State {
return name; 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 // Inline polyfills
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -756,6 +786,9 @@ struct BuiltinPolyfill::State {
// Polyfill functions for binary operators. // Polyfill functions for binary operators.
utils::Hashmap<BinaryOpSignature, Symbol, 8> binary_op_polyfills; 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 /// @returns the AST type for the given sem type
const ast::Type* T(const type::Type* ty) const { return CreateASTTypeFor(ctx, ty); } 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; break;
case sem::BuiltinType::kWorkgroupUniformLoad:
if (polyfill.workgroup_uniform_load) {
fn = builtin_polyfills.GetOrCreate(
builtin, [&] { return s.workgroupUniformLoad(builtin->ReturnType()); });
}
break;
default: default:
break; break;
} }

View File

@ -75,6 +75,8 @@ class BuiltinPolyfill final : public Castable<BuiltinPolyfill, Transform> {
/// Should the vector form of `quantizeToF16()` be polyfilled with a scalar implementation? /// Should the vector form of `quantizeToF16()` be polyfilled with a scalar implementation?
/// See crbug.com/tint/1741 /// See crbug.com/tint/1741
bool quantize_to_vec_f16 = false; bool quantize_to_vec_f16 = false;
/// Should `workgroupUniformLoad()` be polyfilled?
bool workgroup_uniform_load = false;
}; };
/// Config is consumed by the BuiltinPolyfill transform. /// Config is consumed by the BuiltinPolyfill transform.

View File

@ -2942,6 +2942,169 @@ fn f() {
EXPECT_EQ(expect, str(got)); 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 // quantizeToF16
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -200,6 +200,7 @@ SanitizedResult Sanitize(const Program* in,
polyfills.int_div_mod = true; polyfills.int_div_mod = true;
polyfills.saturate = true; polyfills.saturate = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills); data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>(); manager.Add<transform::BuiltinPolyfill>();
} }

View File

@ -178,6 +178,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kFull; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kFull;
polyfills.int_div_mod = true; polyfills.int_div_mod = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills); data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>(); manager.Add<transform::BuiltinPolyfill>();
} }

View File

@ -183,6 +183,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
polyfills.int_div_mod = true; polyfills.int_div_mod = true;
polyfills.sign_int = true; polyfills.sign_int = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills); data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>(); manager.Add<transform::BuiltinPolyfill>();
} }

View File

@ -69,6 +69,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
polyfills.saturate = true; polyfills.saturate = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741 polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills); data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>(); manager.Add<transform::BuiltinPolyfill>();
} }

View File

@ -0,0 +1,33 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
var<workgroup> arg_0: u32;
// fn workgroupUniformLoad(ptr<workgroup, u32, read_write>) -> u32
fn workgroupUniformLoad_37307c() {
var res: u32 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_37307c();
}

View File

@ -0,0 +1,30 @@
groupshared uint arg_0;
uint tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const uint result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_37307c() {
uint res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0u;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_37307c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,30 @@
groupshared uint arg_0;
uint tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const uint result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_37307c() {
uint res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0u;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_37307c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,27 @@
#version 310 es
shared uint arg_0;
uint tint_workgroupUniformLoad_arg_0() {
barrier();
uint result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_37307c() {
uint res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0u;
}
barrier();
workgroupUniformLoad_37307c();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
uint tint_workgroupUniformLoad(threadgroup uint* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
uint const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_37307c(threadgroup uint* const tint_symbol) {
uint res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup uint* const tint_symbol_1) {
{
*(tint_symbol_1) = 0u;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_37307c(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup uint tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,59 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 32
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_37307c "workgroupUniformLoad_37307c"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
%arg_0 = OpVariable %_ptr_Workgroup_uint Workgroup
%6 = OpTypeFunction %uint
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%15 = OpTypeFunction %void
%_ptr_Function_uint = OpTypePointer Function %uint
%21 = OpConstantNull %uint
%22 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %uint None %6
%8 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%13 = OpLoad %uint %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %13
OpFunctionEnd
%workgroupUniformLoad_37307c = OpFunction %void None %15
%17 = OpLabel
%res = OpVariable %_ptr_Function_uint Function %21
%18 = OpFunctionCall %uint %tint_workgroupUniformLoad_arg_0
OpStore %res %18
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %22
%local_invocation_index = OpFunctionParameter %uint
%25 = OpLabel
OpStore %arg_0 %21
OpControlBarrier %uint_2 %uint_2 %uint_264
%27 = OpFunctionCall %void %workgroupUniformLoad_37307c
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %15
%29 = OpLabel
%31 = OpLoad %uint %local_invocation_index_1
%30 = OpFunctionCall %void %compute_main_inner %31
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,10 @@
var<workgroup> arg_0 : u32;
fn workgroupUniformLoad_37307c() {
var res : u32 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_37307c();
}

View File

@ -0,0 +1,33 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
var<workgroup> arg_0: f32;
// fn workgroupUniformLoad(ptr<workgroup, f32, read_write>) -> f32
fn workgroupUniformLoad_7a857c() {
var res: f32 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_7a857c();
}

View File

@ -0,0 +1,30 @@
groupshared float arg_0;
float tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_7a857c() {
float res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0.0f;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_7a857c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,30 @@
groupshared float arg_0;
float tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_7a857c() {
float res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0.0f;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_7a857c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,27 @@
#version 310 es
shared float arg_0;
float tint_workgroupUniformLoad_arg_0() {
barrier();
float result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_7a857c() {
float res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0.0f;
}
barrier();
workgroupUniformLoad_7a857c();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
float tint_workgroupUniformLoad(threadgroup float* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
float const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_7a857c(threadgroup float* const tint_symbol) {
float res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup float* const tint_symbol_1) {
{
*(tint_symbol_1) = 0.0f;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_7a857c(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup float tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,60 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 33
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_7a857c "workgroupUniformLoad_7a857c"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%float = OpTypeFloat 32
%_ptr_Workgroup_float = OpTypePointer Workgroup %float
%arg_0 = OpVariable %_ptr_Workgroup_float Workgroup
%7 = OpTypeFunction %float
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%16 = OpTypeFunction %void
%_ptr_Function_float = OpTypePointer Function %float
%22 = OpConstantNull %float
%23 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %float None %7
%9 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%14 = OpLoad %float %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %14
OpFunctionEnd
%workgroupUniformLoad_7a857c = OpFunction %void None %16
%18 = OpLabel
%res = OpVariable %_ptr_Function_float Function %22
%19 = OpFunctionCall %float %tint_workgroupUniformLoad_arg_0
OpStore %res %19
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %23
%local_invocation_index = OpFunctionParameter %uint
%26 = OpLabel
OpStore %arg_0 %22
OpControlBarrier %uint_2 %uint_2 %uint_264
%28 = OpFunctionCall %void %workgroupUniformLoad_7a857c
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %16
%30 = OpLabel
%32 = OpLoad %uint %local_invocation_index_1
%31 = OpFunctionCall %void %compute_main_inner %32
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,10 @@
var<workgroup> arg_0 : f32;
fn workgroupUniformLoad_7a857c() {
var res : f32 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_7a857c();
}

View File

@ -0,0 +1,33 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
var<workgroup> arg_0: i32;
// fn workgroupUniformLoad(ptr<workgroup, i32, read_write>) -> i32
fn workgroupUniformLoad_9d33de() {
var res: i32 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_9d33de();
}

View File

@ -0,0 +1,30 @@
groupshared int arg_0;
int tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const int result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_9d33de() {
int res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_9d33de();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,30 @@
groupshared int arg_0;
int tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const int result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_9d33de() {
int res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_9d33de();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,27 @@
#version 310 es
shared int arg_0;
int tint_workgroupUniformLoad_arg_0() {
barrier();
int result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_9d33de() {
int res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0;
}
barrier();
workgroupUniformLoad_9d33de();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
int tint_workgroupUniformLoad(threadgroup int* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
int const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_9d33de(threadgroup int* const tint_symbol) {
int res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup int* const tint_symbol_1) {
{
*(tint_symbol_1) = 0;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_9d33de(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup int tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,60 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 33
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_9d33de "workgroupUniformLoad_9d33de"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%int = OpTypeInt 32 1
%_ptr_Workgroup_int = OpTypePointer Workgroup %int
%arg_0 = OpVariable %_ptr_Workgroup_int Workgroup
%7 = OpTypeFunction %int
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%16 = OpTypeFunction %void
%_ptr_Function_int = OpTypePointer Function %int
%22 = OpConstantNull %int
%23 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %int None %7
%9 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%14 = OpLoad %int %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %14
OpFunctionEnd
%workgroupUniformLoad_9d33de = OpFunction %void None %16
%18 = OpLabel
%res = OpVariable %_ptr_Function_int Function %22
%19 = OpFunctionCall %int %tint_workgroupUniformLoad_arg_0
OpStore %res %19
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %23
%local_invocation_index = OpFunctionParameter %uint
%26 = OpLabel
OpStore %arg_0 %22
OpControlBarrier %uint_2 %uint_2 %uint_264
%28 = OpFunctionCall %void %workgroupUniformLoad_9d33de
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %16
%30 = OpLabel
%32 = OpLoad %uint %local_invocation_index_1
%31 = OpFunctionCall %void %compute_main_inner %32
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,10 @@
var<workgroup> arg_0 : i32;
fn workgroupUniformLoad_9d33de() {
var res : i32 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_9d33de();
}

View File

@ -0,0 +1,35 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
enable f16;
var<workgroup> arg_0: f16;
// fn workgroupUniformLoad(ptr<workgroup, f16, read_write>) -> f16
fn workgroupUniformLoad_e07d08() {
var res: f16 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_e07d08();
}

View File

@ -0,0 +1,30 @@
groupshared float16_t arg_0;
float16_t tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float16_t result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_e07d08() {
float16_t res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = float16_t(0.0h);
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_e07d08();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,35 @@
SKIP: FAILED
groupshared float16_t arg_0;
float16_t tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float16_t result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_e07d08() {
float16_t res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = float16_t(0.0h);
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_e07d08();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}
FXC validation failure:
T:\tmp\dawn-temp\dawn-src\test\tint\Shader@0x000001D7B7FE0DC0(1,13-21): error X3000: unrecognized identifier 'float16_t'

View File

@ -0,0 +1,28 @@
#version 310 es
#extension GL_AMD_gpu_shader_half_float : require
shared float16_t arg_0;
float16_t tint_workgroupUniformLoad_arg_0() {
barrier();
float16_t result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_e07d08() {
float16_t res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0.0hf;
}
barrier();
workgroupUniformLoad_e07d08();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
half tint_workgroupUniformLoad(threadgroup half* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
half const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_e07d08(threadgroup half* const tint_symbol) {
half res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup half* const tint_symbol_1) {
{
*(tint_symbol_1) = 0.0h;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_e07d08(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup half tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,64 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 33
; Schema: 0
OpCapability Shader
OpCapability Float16
OpCapability UniformAndStorageBuffer16BitAccess
OpCapability StorageBuffer16BitAccess
OpCapability StorageInputOutput16
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_e07d08 "workgroupUniformLoad_e07d08"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%half = OpTypeFloat 16
%_ptr_Workgroup_half = OpTypePointer Workgroup %half
%arg_0 = OpVariable %_ptr_Workgroup_half Workgroup
%7 = OpTypeFunction %half
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%16 = OpTypeFunction %void
%_ptr_Function_half = OpTypePointer Function %half
%22 = OpConstantNull %half
%23 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %half None %7
%9 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%14 = OpLoad %half %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %14
OpFunctionEnd
%workgroupUniformLoad_e07d08 = OpFunction %void None %16
%18 = OpLabel
%res = OpVariable %_ptr_Function_half Function %22
%19 = OpFunctionCall %half %tint_workgroupUniformLoad_arg_0
OpStore %res %19
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %23
%local_invocation_index = OpFunctionParameter %uint
%26 = OpLabel
OpStore %arg_0 %22
OpControlBarrier %uint_2 %uint_2 %uint_264
%28 = OpFunctionCall %void %workgroupUniformLoad_e07d08
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %16
%30 = OpLabel
%32 = OpLoad %uint %local_invocation_index_1
%31 = OpFunctionCall %void %compute_main_inner %32
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,12 @@
enable f16;
var<workgroup> arg_0 : f16;
fn workgroupUniformLoad_e07d08() {
var res : f16 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_e07d08();
}

View File

@ -0,0 +1,33 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
var<workgroup> arg_0: u32;
// fn workgroupUniformLoad(ptr<workgroup, u32, read_write>) -> u32
fn workgroupUniformLoad_37307c() {
var res: u32 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_37307c();
}

View File

@ -0,0 +1,30 @@
groupshared uint arg_0;
uint tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const uint result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_37307c() {
uint res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0u;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_37307c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,30 @@
groupshared uint arg_0;
uint tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const uint result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_37307c() {
uint res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0u;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_37307c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,27 @@
#version 310 es
shared uint arg_0;
uint tint_workgroupUniformLoad_arg_0() {
barrier();
uint result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_37307c() {
uint res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0u;
}
barrier();
workgroupUniformLoad_37307c();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
uint tint_workgroupUniformLoad(threadgroup uint* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
uint const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_37307c(threadgroup uint* const tint_symbol) {
uint res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup uint* const tint_symbol_1) {
{
*(tint_symbol_1) = 0u;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_37307c(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup uint tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,59 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 32
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_37307c "workgroupUniformLoad_37307c"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
%arg_0 = OpVariable %_ptr_Workgroup_uint Workgroup
%6 = OpTypeFunction %uint
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%15 = OpTypeFunction %void
%_ptr_Function_uint = OpTypePointer Function %uint
%21 = OpConstantNull %uint
%22 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %uint None %6
%8 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%13 = OpLoad %uint %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %13
OpFunctionEnd
%workgroupUniformLoad_37307c = OpFunction %void None %15
%17 = OpLabel
%res = OpVariable %_ptr_Function_uint Function %21
%18 = OpFunctionCall %uint %tint_workgroupUniformLoad_arg_0
OpStore %res %18
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %22
%local_invocation_index = OpFunctionParameter %uint
%25 = OpLabel
OpStore %arg_0 %21
OpControlBarrier %uint_2 %uint_2 %uint_264
%27 = OpFunctionCall %void %workgroupUniformLoad_37307c
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %15
%29 = OpLabel
%31 = OpLoad %uint %local_invocation_index_1
%30 = OpFunctionCall %void %compute_main_inner %31
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,10 @@
var<workgroup> arg_0 : u32;
fn workgroupUniformLoad_37307c() {
var res : u32 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_37307c();
}

View File

@ -0,0 +1,33 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
var<workgroup> arg_0: f32;
// fn workgroupUniformLoad(ptr<workgroup, f32, read_write>) -> f32
fn workgroupUniformLoad_7a857c() {
var res: f32 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_7a857c();
}

View File

@ -0,0 +1,30 @@
groupshared float arg_0;
float tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_7a857c() {
float res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0.0f;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_7a857c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,30 @@
groupshared float arg_0;
float tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_7a857c() {
float res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0.0f;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_7a857c();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,27 @@
#version 310 es
shared float arg_0;
float tint_workgroupUniformLoad_arg_0() {
barrier();
float result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_7a857c() {
float res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0.0f;
}
barrier();
workgroupUniformLoad_7a857c();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
float tint_workgroupUniformLoad(threadgroup float* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
float const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_7a857c(threadgroup float* const tint_symbol) {
float res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup float* const tint_symbol_1) {
{
*(tint_symbol_1) = 0.0f;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_7a857c(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup float tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,60 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 33
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_7a857c "workgroupUniformLoad_7a857c"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%float = OpTypeFloat 32
%_ptr_Workgroup_float = OpTypePointer Workgroup %float
%arg_0 = OpVariable %_ptr_Workgroup_float Workgroup
%7 = OpTypeFunction %float
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%16 = OpTypeFunction %void
%_ptr_Function_float = OpTypePointer Function %float
%22 = OpConstantNull %float
%23 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %float None %7
%9 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%14 = OpLoad %float %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %14
OpFunctionEnd
%workgroupUniformLoad_7a857c = OpFunction %void None %16
%18 = OpLabel
%res = OpVariable %_ptr_Function_float Function %22
%19 = OpFunctionCall %float %tint_workgroupUniformLoad_arg_0
OpStore %res %19
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %23
%local_invocation_index = OpFunctionParameter %uint
%26 = OpLabel
OpStore %arg_0 %22
OpControlBarrier %uint_2 %uint_2 %uint_264
%28 = OpFunctionCall %void %workgroupUniformLoad_7a857c
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %16
%30 = OpLabel
%32 = OpLoad %uint %local_invocation_index_1
%31 = OpFunctionCall %void %compute_main_inner %32
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,10 @@
var<workgroup> arg_0 : f32;
fn workgroupUniformLoad_7a857c() {
var res : f32 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_7a857c();
}

View File

@ -0,0 +1,33 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
var<workgroup> arg_0: i32;
// fn workgroupUniformLoad(ptr<workgroup, i32, read_write>) -> i32
fn workgroupUniformLoad_9d33de() {
var res: i32 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_9d33de();
}

View File

@ -0,0 +1,30 @@
groupshared int arg_0;
int tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const int result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_9d33de() {
int res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_9d33de();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,30 @@
groupshared int arg_0;
int tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const int result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_9d33de() {
int res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = 0;
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_9d33de();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,27 @@
#version 310 es
shared int arg_0;
int tint_workgroupUniformLoad_arg_0() {
barrier();
int result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_9d33de() {
int res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0;
}
barrier();
workgroupUniformLoad_9d33de();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
int tint_workgroupUniformLoad(threadgroup int* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
int const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_9d33de(threadgroup int* const tint_symbol) {
int res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup int* const tint_symbol_1) {
{
*(tint_symbol_1) = 0;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_9d33de(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup int tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,60 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 33
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_9d33de "workgroupUniformLoad_9d33de"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%int = OpTypeInt 32 1
%_ptr_Workgroup_int = OpTypePointer Workgroup %int
%arg_0 = OpVariable %_ptr_Workgroup_int Workgroup
%7 = OpTypeFunction %int
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%16 = OpTypeFunction %void
%_ptr_Function_int = OpTypePointer Function %int
%22 = OpConstantNull %int
%23 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %int None %7
%9 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%14 = OpLoad %int %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %14
OpFunctionEnd
%workgroupUniformLoad_9d33de = OpFunction %void None %16
%18 = OpLabel
%res = OpVariable %_ptr_Function_int Function %22
%19 = OpFunctionCall %int %tint_workgroupUniformLoad_arg_0
OpStore %res %19
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %23
%local_invocation_index = OpFunctionParameter %uint
%26 = OpLabel
OpStore %arg_0 %22
OpControlBarrier %uint_2 %uint_2 %uint_264
%28 = OpFunctionCall %void %workgroupUniformLoad_9d33de
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %16
%30 = OpLabel
%32 = OpLoad %uint %local_invocation_index_1
%31 = OpFunctionCall %void %compute_main_inner %32
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,10 @@
var<workgroup> arg_0 : i32;
fn workgroupUniformLoad_9d33de() {
var res : i32 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_9d33de();
}

View File

@ -0,0 +1,35 @@
// Copyright 2023 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:
// test/tint/builtins/gen/gen.wgsl.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
enable f16;
var<workgroup> arg_0: f16;
// fn workgroupUniformLoad(ptr<workgroup, f16, read_write>) -> f16
fn workgroupUniformLoad_e07d08() {
var res: f16 = workgroupUniformLoad(&arg_0);
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_e07d08();
}

View File

@ -0,0 +1,30 @@
groupshared float16_t arg_0;
float16_t tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float16_t result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_e07d08() {
float16_t res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = float16_t(0.0h);
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_e07d08();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}

View File

@ -0,0 +1,35 @@
SKIP: FAILED
groupshared float16_t arg_0;
float16_t tint_workgroupUniformLoad_arg_0() {
GroupMemoryBarrierWithGroupSync();
const float16_t result = arg_0;
GroupMemoryBarrierWithGroupSync();
return result;
}
void workgroupUniformLoad_e07d08() {
float16_t res = tint_workgroupUniformLoad_arg_0();
}
struct tint_symbol_1 {
uint local_invocation_index : SV_GroupIndex;
};
void compute_main_inner(uint local_invocation_index) {
{
arg_0 = float16_t(0.0h);
}
GroupMemoryBarrierWithGroupSync();
workgroupUniformLoad_e07d08();
}
[numthreads(1, 1, 1)]
void compute_main(tint_symbol_1 tint_symbol) {
compute_main_inner(tint_symbol.local_invocation_index);
return;
}
FXC validation failure:
T:\tmp\dawn-temp\dawn-src\test\tint\Shader@0x000001D6A00D1F90(1,13-21): error X3000: unrecognized identifier 'float16_t'

View File

@ -0,0 +1,28 @@
#version 310 es
#extension GL_AMD_gpu_shader_half_float : require
shared float16_t arg_0;
float16_t tint_workgroupUniformLoad_arg_0() {
barrier();
float16_t result = arg_0;
barrier();
return result;
}
void workgroupUniformLoad_e07d08() {
float16_t res = tint_workgroupUniformLoad_arg_0();
}
void compute_main(uint local_invocation_index) {
{
arg_0 = 0.0hf;
}
barrier();
workgroupUniformLoad_e07d08();
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
compute_main(gl_LocalInvocationIndex);
return;
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
half tint_workgroupUniformLoad(threadgroup half* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
half const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
void workgroupUniformLoad_e07d08(threadgroup half* const tint_symbol) {
half res = tint_workgroupUniformLoad(tint_symbol);
}
void compute_main_inner(uint local_invocation_index, threadgroup half* const tint_symbol_1) {
{
*(tint_symbol_1) = 0.0h;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
workgroupUniformLoad_e07d08(tint_symbol_1);
}
kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
threadgroup half tint_symbol_2;
compute_main_inner(local_invocation_index, &(tint_symbol_2));
return;
}

View File

@ -0,0 +1,64 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 33
; Schema: 0
OpCapability Shader
OpCapability Float16
OpCapability UniformAndStorageBuffer16BitAccess
OpCapability StorageBuffer16BitAccess
OpCapability StorageInputOutput16
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
OpExecutionMode %compute_main LocalSize 1 1 1
OpName %local_invocation_index_1 "local_invocation_index_1"
OpName %arg_0 "arg_0"
OpName %tint_workgroupUniformLoad_arg_0 "tint_workgroupUniformLoad_arg_0"
OpName %workgroupUniformLoad_e07d08 "workgroupUniformLoad_e07d08"
OpName %res "res"
OpName %compute_main_inner "compute_main_inner"
OpName %local_invocation_index "local_invocation_index"
OpName %compute_main "compute_main"
OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
%half = OpTypeFloat 16
%_ptr_Workgroup_half = OpTypePointer Workgroup %half
%arg_0 = OpVariable %_ptr_Workgroup_half Workgroup
%7 = OpTypeFunction %half
%void = OpTypeVoid
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%16 = OpTypeFunction %void
%_ptr_Function_half = OpTypePointer Function %half
%22 = OpConstantNull %half
%23 = OpTypeFunction %void %uint
%tint_workgroupUniformLoad_arg_0 = OpFunction %half None %7
%9 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%14 = OpLoad %half %arg_0
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %14
OpFunctionEnd
%workgroupUniformLoad_e07d08 = OpFunction %void None %16
%18 = OpLabel
%res = OpVariable %_ptr_Function_half Function %22
%19 = OpFunctionCall %half %tint_workgroupUniformLoad_arg_0
OpStore %res %19
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %23
%local_invocation_index = OpFunctionParameter %uint
%26 = OpLabel
OpStore %arg_0 %22
OpControlBarrier %uint_2 %uint_2 %uint_264
%28 = OpFunctionCall %void %workgroupUniformLoad_e07d08
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %16
%30 = OpLabel
%32 = OpLoad %uint %local_invocation_index_1
%31 = OpFunctionCall %void %compute_main_inner %32
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,12 @@
enable f16;
var<workgroup> arg_0 : f16;
fn workgroupUniformLoad_e07d08() {
var res : f16 = workgroupUniformLoad(&(arg_0));
}
@compute @workgroup_size(1)
fn compute_main() {
workgroupUniformLoad_e07d08();
}

View File

@ -0,0 +1,5 @@
var<workgroup> v : array<i32, 4>;
fn foo() -> array<i32, 4> {
return workgroupUniformLoad(&v);
}

View File

@ -0,0 +1,19 @@
[numthreads(1, 1, 1)]
void unused_entry_point() {
return;
}
groupshared int v[4];
typedef int tint_workgroupUniformLoad_v_ret[4];
tint_workgroupUniformLoad_v_ret tint_workgroupUniformLoad_v() {
GroupMemoryBarrierWithGroupSync();
const int result[4] = v;
GroupMemoryBarrierWithGroupSync();
return result;
}
typedef int foo_ret[4];
foo_ret foo() {
return tint_workgroupUniformLoad_v();
}

View File

@ -0,0 +1,19 @@
[numthreads(1, 1, 1)]
void unused_entry_point() {
return;
}
groupshared int v[4];
typedef int tint_workgroupUniformLoad_v_ret[4];
tint_workgroupUniformLoad_v_ret tint_workgroupUniformLoad_v() {
GroupMemoryBarrierWithGroupSync();
const int result[4] = v;
GroupMemoryBarrierWithGroupSync();
return result;
}
typedef int foo_ret[4];
foo_ret foo() {
return tint_workgroupUniformLoad_v();
}

View File

@ -0,0 +1,18 @@
#version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
shared int v[4];
int[4] tint_workgroupUniformLoad_v() {
barrier();
int result[4] = v;
barrier();
return result;
}
int[4] foo() {
return tint_workgroupUniformLoad_v();
}

View File

@ -0,0 +1,27 @@
#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
tint_array<int, 4> tint_workgroupUniformLoad(threadgroup tint_array<int, 4>* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
tint_array<int, 4> const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
tint_array<int, 4> foo(threadgroup tint_array<int, 4>* const tint_symbol) {
return tint_workgroupUniformLoad(tint_symbol);
}

View File

@ -0,0 +1,41 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 22
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
OpExecutionMode %unused_entry_point LocalSize 1 1 1
OpName %v "v"
OpName %unused_entry_point "unused_entry_point"
OpName %tint_workgroupUniformLoad_v "tint_workgroupUniformLoad_v"
OpName %foo "foo"
OpDecorate %_arr_int_uint_4 ArrayStride 4
%int = OpTypeInt 32 1
%uint = OpTypeInt 32 0
%uint_4 = OpConstant %uint 4
%_arr_int_uint_4 = OpTypeArray %int %uint_4
%_ptr_Workgroup__arr_int_uint_4 = OpTypePointer Workgroup %_arr_int_uint_4
%v = OpVariable %_ptr_Workgroup__arr_int_uint_4 Workgroup
%void = OpTypeVoid
%7 = OpTypeFunction %void
%11 = OpTypeFunction %_arr_int_uint_4
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%unused_entry_point = OpFunction %void None %7
%10 = OpLabel
OpReturn
OpFunctionEnd
%tint_workgroupUniformLoad_v = OpFunction %_arr_int_uint_4 None %11
%13 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%17 = OpLoad %_arr_int_uint_4 %v
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %17
OpFunctionEnd
%foo = OpFunction %_arr_int_uint_4 None %11
%20 = OpLabel
%21 = OpFunctionCall %_arr_int_uint_4 %tint_workgroupUniformLoad_v
OpReturnValue %21
OpFunctionEnd

View File

@ -0,0 +1,5 @@
var<workgroup> v : array<i32, 4>;
fn foo() -> array<i32, 4> {
return workgroupUniformLoad(&(v));
}

View File

@ -0,0 +1,7 @@
// flags: --overrides wgsize=64
override wgsize : i32;
var<workgroup> v : array<i32, wgsize * 2>;
fn foo() -> i32 {
return workgroupUniformLoad(&v)[0];
}

View File

@ -0,0 +1,19 @@
[numthreads(1, 1, 1)]
void unused_entry_point() {
return;
}
groupshared int v[128];
typedef int tint_workgroupUniformLoad_v_ret[128];
tint_workgroupUniformLoad_v_ret tint_workgroupUniformLoad_v() {
GroupMemoryBarrierWithGroupSync();
const int result[128] = v;
GroupMemoryBarrierWithGroupSync();
return result;
}
int foo() {
const int tint_symbol[128] = tint_workgroupUniformLoad_v();
return tint_symbol[0];
}

View File

@ -0,0 +1,19 @@
[numthreads(1, 1, 1)]
void unused_entry_point() {
return;
}
groupshared int v[128];
typedef int tint_workgroupUniformLoad_v_ret[128];
tint_workgroupUniformLoad_v_ret tint_workgroupUniformLoad_v() {
GroupMemoryBarrierWithGroupSync();
const int result[128] = v;
GroupMemoryBarrierWithGroupSync();
return result;
}
int foo() {
const int tint_symbol[128] = tint_workgroupUniformLoad_v();
return tint_symbol[0];
}

View File

@ -0,0 +1,19 @@
#version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
shared int v[128];
int[128] tint_workgroupUniformLoad_v() {
barrier();
int result[128] = v;
barrier();
return result;
}
int foo() {
int tint_symbol[128] = tint_workgroupUniformLoad_v();
return tint_symbol[0];
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
tint_array<int, 128> tint_workgroupUniformLoad(threadgroup tint_array<int, 128>* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
tint_array<int, 128> const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
int foo(threadgroup tint_array<int, 128>* const tint_symbol_1) {
tint_array<int, 128> const tint_symbol = tint_workgroupUniformLoad(tint_symbol_1);
return tint_symbol[0];
}

View File

@ -0,0 +1,44 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 25
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
OpExecutionMode %unused_entry_point LocalSize 1 1 1
OpName %v "v"
OpName %unused_entry_point "unused_entry_point"
OpName %tint_workgroupUniformLoad_v "tint_workgroupUniformLoad_v"
OpName %foo "foo"
OpDecorate %_arr_int_uint_128 ArrayStride 4
%int = OpTypeInt 32 1
%uint = OpTypeInt 32 0
%uint_128 = OpConstant %uint 128
%_arr_int_uint_128 = OpTypeArray %int %uint_128
%_ptr_Workgroup__arr_int_uint_128 = OpTypePointer Workgroup %_arr_int_uint_128
%v = OpVariable %_ptr_Workgroup__arr_int_uint_128 Workgroup
%void = OpTypeVoid
%7 = OpTypeFunction %void
%11 = OpTypeFunction %_arr_int_uint_128
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%19 = OpTypeFunction %int
%23 = OpConstantNull %int
%unused_entry_point = OpFunction %void None %7
%10 = OpLabel
OpReturn
OpFunctionEnd
%tint_workgroupUniformLoad_v = OpFunction %_arr_int_uint_128 None %11
%13 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%17 = OpLoad %_arr_int_uint_128 %v
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %17
OpFunctionEnd
%foo = OpFunction %int None %19
%21 = OpLabel
%22 = OpFunctionCall %_arr_int_uint_128 %tint_workgroupUniformLoad_v
%24 = OpCompositeExtract %int %22 0
OpReturnValue %24
OpFunctionEnd

View File

@ -0,0 +1,7 @@
const wgsize : i32 = 64i;
var<workgroup> v : array<i32, (wgsize * 2)>;
fn foo() -> i32 {
return workgroupUniformLoad(&(v))[0];
}

View File

@ -0,0 +1,8 @@
// flags: --overrides wgsize=64
override wgsize : i32;
type Array = array<i32, wgsize * 2>;
var<workgroup> v : Array;
fn foo() -> i32 {
return workgroupUniformLoad(&v)[0];
}

View File

@ -0,0 +1,19 @@
[numthreads(1, 1, 1)]
void unused_entry_point() {
return;
}
groupshared int v[128];
typedef int tint_workgroupUniformLoad_v_ret[128];
tint_workgroupUniformLoad_v_ret tint_workgroupUniformLoad_v() {
GroupMemoryBarrierWithGroupSync();
const int result[128] = v;
GroupMemoryBarrierWithGroupSync();
return result;
}
int foo() {
const int tint_symbol[128] = tint_workgroupUniformLoad_v();
return tint_symbol[0];
}

View File

@ -0,0 +1,19 @@
[numthreads(1, 1, 1)]
void unused_entry_point() {
return;
}
groupshared int v[128];
typedef int tint_workgroupUniformLoad_v_ret[128];
tint_workgroupUniformLoad_v_ret tint_workgroupUniformLoad_v() {
GroupMemoryBarrierWithGroupSync();
const int result[128] = v;
GroupMemoryBarrierWithGroupSync();
return result;
}
int foo() {
const int tint_symbol[128] = tint_workgroupUniformLoad_v();
return tint_symbol[0];
}

View File

@ -0,0 +1,19 @@
#version 310 es
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void unused_entry_point() {
return;
}
shared int v[128];
int[128] tint_workgroupUniformLoad_v() {
barrier();
int result[128] = v;
barrier();
return result;
}
int foo() {
int tint_symbol[128] = tint_workgroupUniformLoad_v();
return tint_symbol[0];
}

View File

@ -0,0 +1,28 @@
#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
tint_array<int, 128> tint_workgroupUniformLoad(threadgroup tint_array<int, 128>* const p) {
threadgroup_barrier(mem_flags::mem_threadgroup);
tint_array<int, 128> const result = *(p);
threadgroup_barrier(mem_flags::mem_threadgroup);
return result;
}
int foo(threadgroup tint_array<int, 128>* const tint_symbol_1) {
tint_array<int, 128> const tint_symbol = tint_workgroupUniformLoad(tint_symbol_1);
return tint_symbol[0];
}

View File

@ -0,0 +1,44 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 25
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
OpExecutionMode %unused_entry_point LocalSize 1 1 1
OpName %v "v"
OpName %unused_entry_point "unused_entry_point"
OpName %tint_workgroupUniformLoad_v "tint_workgroupUniformLoad_v"
OpName %foo "foo"
OpDecorate %_arr_int_uint_128 ArrayStride 4
%int = OpTypeInt 32 1
%uint = OpTypeInt 32 0
%uint_128 = OpConstant %uint 128
%_arr_int_uint_128 = OpTypeArray %int %uint_128
%_ptr_Workgroup__arr_int_uint_128 = OpTypePointer Workgroup %_arr_int_uint_128
%v = OpVariable %_ptr_Workgroup__arr_int_uint_128 Workgroup
%void = OpTypeVoid
%7 = OpTypeFunction %void
%11 = OpTypeFunction %_arr_int_uint_128
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%19 = OpTypeFunction %int
%23 = OpConstantNull %int
%unused_entry_point = OpFunction %void None %7
%10 = OpLabel
OpReturn
OpFunctionEnd
%tint_workgroupUniformLoad_v = OpFunction %_arr_int_uint_128 None %11
%13 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
%17 = OpLoad %_arr_int_uint_128 %v
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturnValue %17
OpFunctionEnd
%foo = OpFunction %int None %19
%21 = OpLabel
%22 = OpFunctionCall %_arr_int_uint_128 %tint_workgroupUniformLoad_v
%24 = OpCompositeExtract %int %22 0
OpReturnValue %24
OpFunctionEnd

View File

@ -0,0 +1,9 @@
const wgsize : i32 = 64i;
type Array = array<i32, (wgsize * 2)>;
var<workgroup> v : Array;
fn foo() -> i32 {
return workgroupUniformLoad(&(v))[0];
}

View File

@ -0,0 +1,5 @@
var<workgroup> v : bool;
fn foo() -> bool {
return workgroupUniformLoad(&v);
}

View File

@ -0,0 +1,17 @@
[numthreads(1, 1, 1)]
void unused_entry_point() {
return;
}
groupshared bool v;
bool tint_workgroupUniformLoad_v() {
GroupMemoryBarrierWithGroupSync();
const bool result = v;
GroupMemoryBarrierWithGroupSync();
return result;
}
bool foo() {
return tint_workgroupUniformLoad_v();
}

Some files were not shown because too many files have changed in this diff Show More