tint: Disallow write-only storage buffers
These have not been in the spec for a long time. The read_write access mode can be used instead. Fixed: tint:1342 Change-Id: I01ffc343d2d2f9df9d7028bba4548c749616c65c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/93500 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
3b800578b5
commit
5286ea9d16
|
@ -62,7 +62,7 @@ ResultOrError<ComputePipelineBase*> GetOrCreateIndirectDispatchValidationPipelin
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> uniformParams: UniformParams;
|
@group(0) @binding(0) var<uniform> uniformParams: UniformParams;
|
||||||
@group(0) @binding(1) var<storage, read_write> clientParams: IndirectParams;
|
@group(0) @binding(1) var<storage, read_write> clientParams: IndirectParams;
|
||||||
@group(0) @binding(2) var<storage, write> validatedParams: ValidatedParams;
|
@group(0) @binding(2) var<storage, read_write> validatedParams: ValidatedParams;
|
||||||
|
|
||||||
@compute @workgroup_size(1, 1, 1)
|
@compute @workgroup_size(1, 1, 1)
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -81,7 +81,7 @@ static const char sRenderValidationShaderSource[] = R"(
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, read> batch: BatchInfo;
|
@group(0) @binding(0) var<storage, read> batch: BatchInfo;
|
||||||
@group(0) @binding(1) var<storage, read_write> inputParams: IndirectParams;
|
@group(0) @binding(1) var<storage, read_write> inputParams: IndirectParams;
|
||||||
@group(0) @binding(2) var<storage, write> outputParams: IndirectParams;
|
@group(0) @binding(2) var<storage, read_write> outputParams: IndirectParams;
|
||||||
|
|
||||||
fn numIndirectParamsPerDrawCallInput() -> u32 {
|
fn numIndirectParamsPerDrawCallInput() -> u32 {
|
||||||
var numParams = kNumDrawIndirectParams;
|
var numParams = kNumDrawIndirectParams;
|
||||||
|
|
|
@ -78,7 +78,7 @@ TEST_P(ComputeSharedMemoryTests, Basic) {
|
||||||
x : u32
|
x : u32
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, write> dst : Dst;
|
@group(0) @binding(0) var<storage, read_write> dst : Dst;
|
||||||
var<workgroup> tmp : u32;
|
var<workgroup> tmp : u32;
|
||||||
|
|
||||||
@compute @workgroup_size(4,4,1)
|
@compute @workgroup_size(4,4,1)
|
||||||
|
@ -117,7 +117,7 @@ TEST_P(ComputeSharedMemoryTests, AssortedTypes) {
|
||||||
d_vector : vec4<f32>,
|
d_vector : vec4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, write> dst : Dst;
|
@group(0) @binding(0) var<storage, read_write> dst : Dst;
|
||||||
|
|
||||||
var<workgroup> wg_struct : StructValues;
|
var<workgroup> wg_struct : StructValues;
|
||||||
var<workgroup> wg_matrix : mat2x2<f32>;
|
var<workgroup> wg_matrix : mat2x2<f32>;
|
||||||
|
|
|
@ -663,7 +663,7 @@ TEST_P(DrawIndexedIndirectTest, ValidateReusedBundleWithChangingParams) {
|
||||||
firstIndex: u32,
|
firstIndex: u32,
|
||||||
}
|
}
|
||||||
@group(0) @binding(0) var<uniform> input: Input;
|
@group(0) @binding(0) var<uniform> input: Input;
|
||||||
@group(0) @binding(1) var<storage, write> params: Params;
|
@group(0) @binding(1) var<storage, read_write> params: Params;
|
||||||
@compute @workgroup_size(1) fn main() {
|
@compute @workgroup_size(1) fn main() {
|
||||||
params.indexCount = 3u;
|
params.indexCount = 3u;
|
||||||
params.instanceCount = 1u;
|
params.instanceCount = 1u;
|
||||||
|
|
|
@ -41,7 +41,7 @@ TEST_P(MaxLimitTests, MaxComputeWorkgroupStorageSize) {
|
||||||
value1 : u32,
|
value1 : u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, write> dst : Dst;
|
@group(0) @binding(0) var<storage, read_write> dst : Dst;
|
||||||
|
|
||||||
struct WGData {
|
struct WGData {
|
||||||
value0 : u32,
|
value0 : u32,
|
||||||
|
@ -142,7 +142,7 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, read> buf : Buf;
|
@group(0) @binding(0) var<storage, read> buf : Buf;
|
||||||
@group(0) @binding(1) var<storage, write> result : Result;
|
@group(0) @binding(1) var<storage, read_write> result : Result;
|
||||||
|
|
||||||
@compute @workgroup_size(1,1,1)
|
@compute @workgroup_size(1,1,1)
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -173,7 +173,7 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> buf : Buf;
|
@group(0) @binding(0) var<uniform> buf : Buf;
|
||||||
@group(0) @binding(1) var<storage, write> result : Result;
|
@group(0) @binding(1) var<storage, read_write> result : Result;
|
||||||
|
|
||||||
@compute @workgroup_size(1,1,1)
|
@compute @workgroup_size(1,1,1)
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ const std::string& kMatMulFloatHeader = R"(
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
||||||
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
||||||
@group(0) @binding(2) var<storage, write> resultMatrix : Matrix;
|
@group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
|
||||||
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
fn mm_readA(row : u32, col : u32) -> f32 {
|
fn mm_readA(row : u32, col : u32) -> f32 {
|
||||||
|
@ -200,7 +200,7 @@ const std::string& kMatMulVec4Header = R"(
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
||||||
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
||||||
@group(0) @binding(2) var<storage, write> resultMatrix : Matrix;
|
@group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
|
||||||
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
fn mm_readA(row : u32, col : u32) -> vec4<f32> {
|
fn mm_readA(row : u32, col : u32) -> vec4<f32> {
|
||||||
|
|
|
@ -52,7 +52,7 @@ var<private> g1 : f32 = 123.0;
|
||||||
@group(4) @binding(0) var g6 : texture_external;
|
@group(4) @binding(0) var g6 : texture_external;
|
||||||
|
|
||||||
var<private> g7 : vec3<f32>;
|
var<private> g7 : vec3<f32>;
|
||||||
@group(0) @binding(1) var<storage, write> g8 : S0;
|
@group(0) @binding(1) var<storage, read_write> g8 : S0;
|
||||||
@group(1) @binding(1) var<storage, read> g9 : S0;
|
@group(1) @binding(1) var<storage, read> g9 : S0;
|
||||||
@group(2) @binding(1) var<storage, read_write> g10 : S0;
|
@group(2) @binding(1) var<storage, read_write> g10 : S0;
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ struct S {
|
||||||
|
|
||||||
var<private> a: S;
|
var<private> a: S;
|
||||||
@group(1) @binding(1) var<uniform> b: S;
|
@group(1) @binding(1) var<uniform> b: S;
|
||||||
@group(1) @binding(2) var<storage, write> c: S;
|
@group(1) @binding(2) var<storage, read_write> c: S;
|
||||||
fn f() {
|
fn f() {
|
||||||
let ptr_b = &b;
|
let ptr_b = &b;
|
||||||
*&a = *ptr_b;
|
*&a = *ptr_b;
|
||||||
|
@ -422,7 +422,7 @@ struct S {
|
||||||
};
|
};
|
||||||
|
|
||||||
var<private> a: S;
|
var<private> a: S;
|
||||||
@group(0) @binding(0) var<storage, write> e: S;
|
@group(0) @binding(0) var<storage, read_write> e: S;
|
||||||
@group(1) @binding(1) var<uniform> b: S;
|
@group(1) @binding(1) var<uniform> b: S;
|
||||||
fn f() {
|
fn f() {
|
||||||
*&a = *&b;
|
*&a = *&b;
|
||||||
|
|
|
@ -180,6 +180,33 @@ TEST_F(ResolverStorageClassValidationTest, NotStorage_AccessMode) {
|
||||||
R"(56:78 error: only variables in <storage> storage class may declare an access mode)");
|
R"(56:78 error: only variables in <storage> storage class may declare an access mode)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverStorageClassValidationTest, Storage_ReadAccessMode) {
|
||||||
|
// @group(0) @binding(0) var<storage, read> a : i32;
|
||||||
|
GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
|
||||||
|
GroupAndBinding(0, 0));
|
||||||
|
|
||||||
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverStorageClassValidationTest, Storage_ReadWriteAccessMode) {
|
||||||
|
// @group(0) @binding(0) var<storage, read_write> a : i32;
|
||||||
|
GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kReadWrite,
|
||||||
|
GroupAndBinding(0, 0));
|
||||||
|
|
||||||
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverStorageClassValidationTest, Storage_WriteAccessMode) {
|
||||||
|
// @group(0) @binding(0) var<storage, read_write> a : i32;
|
||||||
|
GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kWrite,
|
||||||
|
GroupAndBinding(0, 0));
|
||||||
|
|
||||||
|
ASSERT_FALSE(r()->Resolve());
|
||||||
|
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
R"(56:78 error: access mode 'write' is not valid for the 'storage' address space)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) {
|
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) {
|
||||||
// struct S { x : i32 };
|
// struct S { x : i32 };
|
||||||
// var<storage, read> g : S;
|
// var<storage, read> g : S;
|
||||||
|
|
|
@ -554,11 +554,20 @@ bool Validator::GlobalVariable(
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration
|
// https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration
|
||||||
// The access mode always has a default, and except for variables in the
|
// The access mode always has a default, and except for variables in the
|
||||||
// storage storage class, must not be written.
|
// storage storage class, must not be written.
|
||||||
if (global->StorageClass() != ast::StorageClass::kStorage &&
|
if (var->declared_access != ast::Access::kUndefined) {
|
||||||
var->declared_access != ast::Access::kUndefined) {
|
if (global->StorageClass() == ast::StorageClass::kStorage) {
|
||||||
AddError("only variables in <storage> storage class may declare an access mode",
|
// The access mode for the storage address space can only be 'read' or
|
||||||
var->source);
|
// 'read_write'.
|
||||||
return false;
|
if (var->declared_access == ast::Access::kWrite) {
|
||||||
|
AddError("access mode 'write' is not valid for the 'storage' address space",
|
||||||
|
decl->source);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AddError("only variables in <storage> storage class may declare an access mode",
|
||||||
|
decl->source);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AtomicVariable(global, atomic_composite_info)) {
|
if (!AtomicVariable(global, atomic_composite_info)) {
|
||||||
|
|
|
@ -137,9 +137,9 @@ struct S {
|
||||||
a : f32,
|
a : f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(2) @binding(1) var<storage, read> a : S;
|
@group(2) @binding(1) var<storage, read_write> a : S;
|
||||||
|
|
||||||
@group(3) @binding(2) var<storage, write> b : S;
|
@group(3) @binding(2) var<storage, read_write> b : S;
|
||||||
|
|
||||||
@group(4) @binding(3) var<storage, read> c : S;
|
@group(4) @binding(3) var<storage, read> c : S;
|
||||||
|
|
||||||
|
@ -153,9 +153,9 @@ struct S {
|
||||||
a : f32,
|
a : f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(2) @binding(1) var<storage, write> a : S;
|
@group(2) @binding(1) var<storage, read_write> a : S;
|
||||||
|
|
||||||
@group(3) @binding(2) var<storage, write> b : S;
|
@group(3) @binding(2) var<storage, read_write> b : S;
|
||||||
|
|
||||||
@group(4) @binding(3) var<storage, read> c : S;
|
@group(4) @binding(3) var<storage, read> c : S;
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ fn f() {
|
||||||
data.Add<BindingRemapper::Remappings>(
|
data.Add<BindingRemapper::Remappings>(
|
||||||
BindingRemapper::BindingPoints{},
|
BindingRemapper::BindingPoints{},
|
||||||
BindingRemapper::AccessControls{
|
BindingRemapper::AccessControls{
|
||||||
{{2, 1}, ast::Access::kWrite}, // Modify access control
|
{{2, 1}, ast::Access::kReadWrite}, // Modify access control
|
||||||
// Keep @group(3) @binding(2) as is
|
// Keep @group(3) @binding(2) as is
|
||||||
{{4, 3}, ast::Access::kRead}, // Add access control
|
{{4, 3}, ast::Access::kRead}, // Add access control
|
||||||
});
|
});
|
||||||
|
@ -197,9 +197,9 @@ struct S {
|
||||||
a : f32,
|
a : f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(4) @binding(5) var<storage, write> a : S;
|
@group(4) @binding(5) var<storage, read_write> a : S;
|
||||||
|
|
||||||
@group(6) @binding(7) var<storage, write> b : S;
|
@group(6) @binding(7) var<storage, read_write> b : S;
|
||||||
|
|
||||||
@compute @workgroup_size(1)
|
@compute @workgroup_size(1)
|
||||||
fn f() {
|
fn f() {
|
||||||
|
@ -213,8 +213,8 @@ fn f() {
|
||||||
{{3, 2}, {6, 7}},
|
{{3, 2}, {6, 7}},
|
||||||
},
|
},
|
||||||
BindingRemapper::AccessControls{
|
BindingRemapper::AccessControls{
|
||||||
{{2, 1}, ast::Access::kWrite},
|
{{2, 1}, ast::Access::kReadWrite},
|
||||||
{{3, 2}, ast::Access::kWrite},
|
{{3, 2}, ast::Access::kReadWrite},
|
||||||
});
|
});
|
||||||
auto got = Run<BindingRemapper>(src, data);
|
auto got = Run<BindingRemapper>(src, data);
|
||||||
|
|
||||||
|
|
|
@ -568,7 +568,7 @@ struct S1 {
|
||||||
@group(3) @binding(0) var g5 : texture_depth_cube_array;
|
@group(3) @binding(0) var g5 : texture_depth_cube_array;
|
||||||
@group(4) @binding(0) var g6 : texture_external;
|
@group(4) @binding(0) var g6 : texture_external;
|
||||||
|
|
||||||
@group(0) @binding(1) var<storage, write> g8 : S0;
|
@group(0) @binding(1) var<storage, read_write> g8 : S0;
|
||||||
@group(1) @binding(3) var<storage, read> g9 : S0;
|
@group(1) @binding(3) var<storage, read> g9 : S0;
|
||||||
@group(3) @binding(2) var<storage, read_write> g10 : S0;
|
@group(3) @binding(2) var<storage, read_write> g10 : S0;
|
||||||
|
|
||||||
|
@ -634,7 +634,7 @@ struct S1 {
|
||||||
|
|
||||||
@group(4) @binding(0) var g6 : texture_external;
|
@group(4) @binding(0) var g6 : texture_external;
|
||||||
|
|
||||||
@group(0) @binding(1) var<storage, write> g8 : S0;
|
@group(0) @binding(1) var<storage, read_write> g8 : S0;
|
||||||
|
|
||||||
@group(1) @binding(3) var<storage, read> g9 : S0;
|
@group(1) @binding(3) var<storage, read> g9 : S0;
|
||||||
|
|
||||||
|
|
|
@ -549,7 +549,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_WO_Storage
|
||||||
Member("b", ty.f32()),
|
Member("b", ty.f32()),
|
||||||
});
|
});
|
||||||
|
|
||||||
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
|
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
|
||||||
ast::AttributeList{
|
ast::AttributeList{
|
||||||
create<ast::BindingAttribute>(0u),
|
create<ast::BindingAttribute>(0u),
|
||||||
create<ast::GroupAttribute>(1u),
|
create<ast::GroupAttribute>(1u),
|
||||||
|
|
|
@ -503,7 +503,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_WO_Storage
|
||||||
Member("b", ty.f32()),
|
Member("b", ty.f32()),
|
||||||
});
|
});
|
||||||
|
|
||||||
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
|
GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
|
||||||
ast::AttributeList{
|
ast::AttributeList{
|
||||||
create<ast::BindingAttribute>(0u),
|
create<ast::BindingAttribute>(0u),
|
||||||
create<ast::GroupAttribute>(1u),
|
create<ast::GroupAttribute>(1u),
|
||||||
|
|
|
@ -56,21 +56,6 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Access_Read) {
|
||||||
EXPECT_EQ(out.str(), R"(@binding(0) @group(0) var<storage, read> a : S;)");
|
EXPECT_EQ(out.str(), R"(@binding(0) @group(0) var<storage, read> a : S;)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_Write) {
|
|
||||||
auto* s = Structure("S", {Member("a", ty.i32())});
|
|
||||||
auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kWrite,
|
|
||||||
ast::AttributeList{
|
|
||||||
create<ast::BindingAttribute>(0u),
|
|
||||||
create<ast::GroupAttribute>(0u),
|
|
||||||
});
|
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
|
||||||
|
|
||||||
std::stringstream out;
|
|
||||||
ASSERT_TRUE(gen.EmitVariable(out, v)) << gen.error();
|
|
||||||
EXPECT_EQ(out.str(), R"(@binding(0) @group(0) var<storage, write> a : S;)");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_ReadWrite) {
|
TEST_F(WgslGeneratorImplTest, EmitVariable_Access_ReadWrite) {
|
||||||
auto* s = Structure("S", {Member("a", ty.i32())});
|
auto* s = Structure("S", {Member("a", ty.i32())});
|
||||||
auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
|
auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
|
||||||
|
|
|
@ -14,25 +14,25 @@ struct IsosurfaceVolume {
|
||||||
values : array<f32>,
|
values : array<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(1) var<storage, write> volume : IsosurfaceVolume;
|
@group(0) @binding(1) var<storage, read_write> volume : IsosurfaceVolume;
|
||||||
|
|
||||||
struct PositionBuffer {
|
struct PositionBuffer {
|
||||||
values : array<f32>,
|
values : array<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(2) var<storage, write> positionsOut : PositionBuffer;
|
@group(0) @binding(2) var<storage, read_write> positionsOut : PositionBuffer;
|
||||||
|
|
||||||
struct NormalBuffer {
|
struct NormalBuffer {
|
||||||
values : array<f32>,
|
values : array<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(3) var<storage, write> normalsOut : NormalBuffer;
|
@group(0) @binding(3) var<storage, read_write> normalsOut : NormalBuffer;
|
||||||
|
|
||||||
struct IndexBuffer {
|
struct IndexBuffer {
|
||||||
tris : array<u32>,
|
tris : array<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(4) var<storage, write> indicesOut : IndexBuffer;
|
@group(0) @binding(4) var<storage, read_write> indicesOut : IndexBuffer;
|
||||||
|
|
||||||
struct DrawIndirectArgs {
|
struct DrawIndirectArgs {
|
||||||
vc : u32,
|
vc : u32,
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct S {
|
||||||
j : array<Inner, 4>,
|
j : array<Inner, 4>,
|
||||||
};
|
};
|
||||||
|
|
||||||
@binding(0) @group(0) var<storage, write> s : S;
|
@binding(0) @group(0) var<storage, read_write> s : S;
|
||||||
|
|
||||||
@compute @workgroup_size(1)
|
@compute @workgroup_size(1)
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
OpMemberDecorate %Inner 0 Offset 0
|
OpMemberDecorate %Inner 0 Offset 0
|
||||||
OpMemberDecorate %S 9 Offset 108
|
OpMemberDecorate %S 9 Offset 108
|
||||||
OpDecorate %_arr_Inner_uint_4 ArrayStride 4
|
OpDecorate %_arr_Inner_uint_4 ArrayStride 4
|
||||||
OpDecorate %s NonReadable
|
|
||||||
OpDecorate %s Binding 0
|
OpDecorate %s Binding 0
|
||||||
OpDecorate %s DescriptorSet 0
|
OpDecorate %s DescriptorSet 0
|
||||||
%int = OpTypeInt 32 1
|
%int = OpTypeInt 32 1
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct S {
|
||||||
j : array<Inner, 4>,
|
j : array<Inner, 4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@binding(0) @group(0) var<storage, write> s : S;
|
@binding(0) @group(0) var<storage, read_write> s : S;
|
||||||
|
|
||||||
@compute @workgroup_size(1)
|
@compute @workgroup_size(1)
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
||||||
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
||||||
@group(0) @binding(2) var<storage, write> resultMatrix : Matrix;
|
@group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
|
||||||
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
@compute @workgroup_size(2,2,1)
|
@compute @workgroup_size(2,2,1)
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
OpDecorate %secondMatrix NonWritable
|
OpDecorate %secondMatrix NonWritable
|
||||||
OpDecorate %secondMatrix DescriptorSet 0
|
OpDecorate %secondMatrix DescriptorSet 0
|
||||||
OpDecorate %secondMatrix Binding 1
|
OpDecorate %secondMatrix Binding 1
|
||||||
OpDecorate %resultMatrix NonReadable
|
|
||||||
OpDecorate %resultMatrix DescriptorSet 0
|
OpDecorate %resultMatrix DescriptorSet 0
|
||||||
OpDecorate %resultMatrix Binding 2
|
OpDecorate %resultMatrix Binding 2
|
||||||
OpDecorate %Uniforms Block
|
OpDecorate %Uniforms Block
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Matrix {
|
||||||
|
|
||||||
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
||||||
|
|
||||||
@group(0) @binding(2) var<storage, write> resultMatrix : Matrix;
|
@group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
|
||||||
|
|
||||||
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
@group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
|
||||||
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
||||||
@group(0) @binding(2) var<storage, write> resultMatrix : Matrix;
|
@group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
|
||||||
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
fn mm_readA(row : u32, col : u32) -> f32 {
|
fn mm_readA(row : u32, col : u32) -> f32 {
|
||||||
|
|
|
@ -65,7 +65,6 @@
|
||||||
OpDecorate %secondMatrix NonWritable
|
OpDecorate %secondMatrix NonWritable
|
||||||
OpDecorate %secondMatrix DescriptorSet 0
|
OpDecorate %secondMatrix DescriptorSet 0
|
||||||
OpDecorate %secondMatrix Binding 1
|
OpDecorate %secondMatrix Binding 1
|
||||||
OpDecorate %resultMatrix NonReadable
|
|
||||||
OpDecorate %resultMatrix DescriptorSet 0
|
OpDecorate %resultMatrix DescriptorSet 0
|
||||||
OpDecorate %resultMatrix Binding 2
|
OpDecorate %resultMatrix Binding 2
|
||||||
OpDecorate %Uniforms Block
|
OpDecorate %Uniforms Block
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Matrix {
|
||||||
|
|
||||||
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
@group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
|
||||||
|
|
||||||
@group(0) @binding(2) var<storage, write> resultMatrix : Matrix;
|
@group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
|
||||||
|
|
||||||
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
@group(0) @binding(3) var<uniform> uniforms : Uniforms;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
struct Result {
|
struct Result {
|
||||||
value: u32,
|
value: u32,
|
||||||
};
|
};
|
||||||
@group(1) @binding(1) var<storage, write> result: Result;
|
@group(1) @binding(1) var<storage, read_write> result: Result;
|
||||||
|
|
||||||
struct TestData {
|
struct TestData {
|
||||||
data: array<atomic<i32>,3>,
|
data: array<atomic<i32>,3>,
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
OpDecorate %constants Binding 0
|
OpDecorate %constants Binding 0
|
||||||
OpDecorate %Result Block
|
OpDecorate %Result Block
|
||||||
OpMemberDecorate %Result 0 Offset 0
|
OpMemberDecorate %Result 0 Offset 0
|
||||||
OpDecorate %result NonReadable
|
|
||||||
OpDecorate %result DescriptorSet 1
|
OpDecorate %result DescriptorSet 1
|
||||||
OpDecorate %result Binding 1
|
OpDecorate %result Binding 1
|
||||||
OpDecorate %TestData Block
|
OpDecorate %TestData Block
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct Result {
|
||||||
value : u32,
|
value : u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(1) @binding(1) var<storage, write> result : Result;
|
@group(1) @binding(1) var<storage, read_write> result : Result;
|
||||||
|
|
||||||
struct TestData {
|
struct TestData {
|
||||||
data : array<atomic<i32>, 3>,
|
data : array<atomic<i32>, 3>,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
struct Result {
|
struct Result {
|
||||||
value: u32,
|
value: u32,
|
||||||
};
|
};
|
||||||
@group(1) @binding(1) var<storage, write> result: Result;
|
@group(1) @binding(1) var<storage, read_write> result: Result;
|
||||||
|
|
||||||
struct S {
|
struct S {
|
||||||
data: array<u32, 3>,
|
data: array<u32, 3>,
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
OpDecorate %constants Binding 0
|
OpDecorate %constants Binding 0
|
||||||
OpDecorate %Result Block
|
OpDecorate %Result Block
|
||||||
OpMemberDecorate %Result 0 Offset 0
|
OpMemberDecorate %Result 0 Offset 0
|
||||||
OpDecorate %result NonReadable
|
|
||||||
OpDecorate %result DescriptorSet 1
|
OpDecorate %result DescriptorSet 1
|
||||||
OpDecorate %result Binding 1
|
OpDecorate %result Binding 1
|
||||||
OpMemberDecorate %S 0 Offset 0
|
OpMemberDecorate %S 0 Offset 0
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct Result {
|
||||||
value : u32,
|
value : u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(1) @binding(1) var<storage, write> result : Result;
|
@group(1) @binding(1) var<storage, read_write> result : Result;
|
||||||
|
|
||||||
struct S {
|
struct S {
|
||||||
data : array<u32, 3>,
|
data : array<u32, 3>,
|
||||||
|
|
|
@ -5,7 +5,7 @@ struct S {
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0)
|
@group(0) @binding(0)
|
||||||
var<storage, write> output : S;
|
var<storage, read_write> output : S;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn frag_main(input : S) {
|
fn frag_main(input : S) {
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
OpMemberDecorate %S 0 Offset 0
|
OpMemberDecorate %S 0 Offset 0
|
||||||
OpMemberDecorate %S 1 Offset 4
|
OpMemberDecorate %S 1 Offset 4
|
||||||
OpMemberDecorate %S 2 Offset 128
|
OpMemberDecorate %S 2 Offset 128
|
||||||
OpDecorate %output NonReadable
|
|
||||||
OpDecorate %output DescriptorSet 0
|
OpDecorate %output DescriptorSet 0
|
||||||
OpDecorate %output Binding 0
|
OpDecorate %output Binding 0
|
||||||
%float = OpTypeFloat 32
|
%float = OpTypeFloat 32
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct S {
|
||||||
v : vec4<f32>,
|
v : vec4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<storage, write> output : S;
|
@group(0) @binding(0) var<storage, read_write> output : S;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn frag_main(input : S) {
|
fn frag_main(input : S) {
|
||||||
|
|
Loading…
Reference in New Issue