Support read-only and read-write storage textures as unsafe apis
This patch makes read-only and read-write storage textures a part of
WebGPU core feature behind toggle "allow-unsafe-apis" and makes the
original experimental extension a no-op one for compatibility.
Bug: dawn:1972
Change-Id: Ic7c0d27db4681f621793d10cced560f6d3ea7d64
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/157521
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index c263589..53940d9 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -83,13 +83,10 @@
switch (storageTextureBindingLayout.access) {
case wgpu::StorageTextureAccess::ReadOnly:
case wgpu::StorageTextureAccess::ReadWrite:
- if (!device->APIHasFeature(
- wgpu::FeatureName::ChromiumExperimentalReadWriteStorageTexture)) {
+ if (!device->IsToggleEnabled(Toggle::AllowUnsafeAPIs)) {
return DAWN_VALIDATION_ERROR(
- "storage texture access %s cannot be used without feature "
- "%s",
- storageTextureBindingLayout.access,
- wgpu::FeatureName::ChromiumExperimentalReadWriteStorageTexture);
+ "storage texture access %s is guarded by toggle allow_unsafe_apis",
+ storageTextureBindingLayout.access);
}
break;
diff --git a/src/dawn/native/Format.cpp b/src/dawn/native/Format.cpp
index a81327a..6da03b5 100644
--- a/src/dawn/native/Format.cpp
+++ b/src/dawn/native/Format.cpp
@@ -437,7 +437,7 @@
// 4 bytes color formats
SampleTypeBit sampleTypeFor32BitFloatFormats = device->HasFeature(Feature::Float32Filterable) ? kAnyFloat : SampleTypeBit::UnfilterableFloat;
- auto supportsReadWriteStorageUsage = device->HasFeature(Feature::ChromiumExperimentalReadWriteStorageTexture) ? Cap::StorageRW : Cap::None;
+ auto supportsReadWriteStorageUsage = device->IsToggleEnabled(Toggle::AllowUnsafeAPIs) ? Cap::StorageRW : Cap::None;
auto supportsPLS = device->HasFeature(Feature::PixelLocalStorageCoherent) || device->HasFeature(Feature::PixelLocalStorageNonCoherent) ? Cap::PLS : Cap::None;
AddColorFormat(wgpu::TextureFormat::R32Uint, Cap::Renderable | Cap::StorageW | supportsReadWriteStorageUsage | supportsPLS, ByteSize(4), SampleTypeBit::Uint, ComponentCount(1), RenderTargetPixelByteCost(4), RenderTargetComponentAlignment(4));
diff --git a/src/dawn/tests/end2end/StorageTextureTests.cpp b/src/dawn/tests/end2end/StorageTextureTests.cpp
index 7da7872..9de0161 100644
--- a/src/dawn/tests/end2end/StorageTextureTests.cpp
+++ b/src/dawn/tests/end2end/StorageTextureTests.cpp
@@ -1031,28 +1031,10 @@
MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}),
VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}));
-class ReadWriteStorageTextureTests : public StorageTextureTests {
- public:
- std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
- if (SupportsFeatures({wgpu::FeatureName::ChromiumExperimentalReadWriteStorageTexture})) {
- mIsReadWriteStorageTextureSupported = true;
- return {wgpu::FeatureName::ChromiumExperimentalReadWriteStorageTexture};
- } else {
- mIsReadWriteStorageTextureSupported = false;
- return {};
- }
- }
-
- bool IsReadWriteStorageTextureSupported() { return mIsReadWriteStorageTextureSupported; }
-
- private:
- bool mIsReadWriteStorageTextureSupported = false;
-};
+class ReadWriteStorageTextureTests : public StorageTextureTests {};
// Verify read-write storage texture can work correctly in compute shaders.
TEST_P(ReadWriteStorageTextureTests, ReadWriteStorageTextureInComputeShader) {
- DAWN_TEST_UNSUPPORTED_IF(!IsReadWriteStorageTextureSupported());
-
std::array<uint32_t, kWidth * kHeight> inputData;
std::array<uint32_t, kWidth * kHeight> expectedData;
for (size_t i = 0; i < inputData.size(); ++i) {
@@ -1066,7 +1048,6 @@
std::ostringstream sstream;
sstream << R"(
-enable chromium_experimental_read_write_storage_texture;
@group(0) @binding(0) var rwImage : texture_storage_2d<r32uint, read_write>;
@compute @workgroup_size()"
@@ -1098,8 +1079,6 @@
// Verify read-write storage texture can work correctly in fragment shaders.
TEST_P(ReadWriteStorageTextureTests, ReadWriteStorageTextureInFragmentShader) {
- DAWN_TEST_UNSUPPORTED_IF(!IsReadWriteStorageTextureSupported());
-
std::array<uint32_t, kWidth * kHeight> inputData;
std::array<uint32_t, kWidth * kHeight> expectedData;
for (size_t i = 0; i < inputData.size(); ++i) {
@@ -1130,7 +1109,6 @@
})");
wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
-enable chromium_experimental_read_write_storage_texture;
@group(0) @binding(0) var rwImage : texture_storage_2d<r32uint, read_write>;
@fragment fn main(@builtin(position) fragcoord: vec4f) -> @location(0) vec4f {
var data1 = textureLoad(rwImage, vec2i(fragcoord.xy));
@@ -1167,8 +1145,6 @@
// Verify read-only storage texture can work correctly in compute shaders.
TEST_P(ReadWriteStorageTextureTests, ReadOnlyStorageTextureInComputeShader) {
- DAWN_TEST_UNSUPPORTED_IF(!IsReadWriteStorageTextureSupported());
-
constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Uint;
const std::vector<uint8_t> kInitialTextureData = GetExpectedData(kStorageTextureFormat);
wgpu::Texture readonlyStorageTexture = CreateTextureWithTestData(
@@ -1176,7 +1152,6 @@
std::ostringstream sstream;
sstream << R"(
-enable chromium_experimental_read_write_storage_texture;
@group(0) @binding(0) var srcImage : texture_storage_2d<r32uint, read>;
@group(0) @binding(1) var<storage, read_write> output : u32;
@@ -1222,8 +1197,6 @@
// Verify read-only storage texture can work correctly in vertex shaders.
TEST_P(ReadWriteStorageTextureTests, ReadOnlyStorageTextureInVertexShader) {
- DAWN_TEST_UNSUPPORTED_IF(!IsReadWriteStorageTextureSupported());
-
// TODO(dawn:1972): Implement read-only storage texture as sampled texture in vertex shader.
DAWN_SUPPRESS_TEST_IF(IsOpenGLES());
@@ -1234,7 +1207,6 @@
std::ostringstream vsstream;
vsstream << R"(
-enable chromium_experimental_read_write_storage_texture;
@group(0) @binding(0) var srcImage : texture_storage_2d<r32uint, read>;
struct VertexOutput {
@@ -1274,8 +1246,6 @@
// Verify read-only storage texture can work correctly in fragment shaders.
TEST_P(ReadWriteStorageTextureTests, ReadOnlyStorageTextureInFragmentShader) {
- DAWN_TEST_UNSUPPORTED_IF(!IsReadWriteStorageTextureSupported());
-
constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Uint;
const std::vector<uint8_t> kInitialTextureData = GetExpectedData(kStorageTextureFormat);
wgpu::Texture readonlyStorageTexture = CreateTextureWithTestData(
@@ -1283,7 +1253,6 @@
std::ostringstream fsstream;
fsstream << R"(
-enable chromium_experimental_read_write_storage_texture;
@group(0) @binding(0) var srcImage : texture_storage_2d<r32uint, read>;
@fragment fn main() -> @location(0) vec4f {
@@ -1307,8 +1276,6 @@
// Verify using read-write storage texture access in pipeline layout is compatible with write-only
// storage texture access in shader.
TEST_P(ReadWriteStorageTextureTests, ReadWriteInPipelineLayoutAndWriteOnlyInShader) {
- DAWN_TEST_UNSUPPORTED_IF(!IsReadWriteStorageTextureSupported());
-
constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Uint;
std::array<uint32_t, kWidth * kHeight> expectedData;
for (size_t i = 0; i < expectedData.size(); ++i) {
@@ -1321,7 +1288,6 @@
std::ostringstream sstream;
sstream << R"(
-enable chromium_experimental_read_write_storage_texture;
@group(0) @binding(0) var rwImage : texture_storage_2d<r32uint, write>;
@compute @workgroup_size()"
diff --git a/src/dawn/tests/unittests/validation/StorageTextureValidationTests.cpp b/src/dawn/tests/unittests/validation/StorageTextureValidationTests.cpp
index 8771973..8e50d37 100644
--- a/src/dawn/tests/unittests/validation/StorageTextureValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/StorageTextureValidationTests.cpp
@@ -86,25 +86,17 @@
wgpu::StorageTextureAccess storageTextureBindingType,
wgpu::TextureFormat textureFormat,
const char* imageTypeDeclaration = "texture_storage_2d",
- bool disableReadWriteStorageTextureExtension = false,
wgpu::ShaderStage shaderStage = wgpu::ShaderStage::Compute) {
const char* access = "";
- const char* extension = "";
switch (storageTextureBindingType) {
case wgpu::StorageTextureAccess::WriteOnly:
access = "write";
break;
case wgpu::StorageTextureAccess::ReadOnly:
access = "read";
- if (!disableReadWriteStorageTextureExtension) {
- extension = "enable chromium_experimental_read_write_storage_texture;\n";
- }
break;
case wgpu::StorageTextureAccess::ReadWrite:
access = "read_write";
- if (!disableReadWriteStorageTextureExtension) {
- extension = "enable chromium_experimental_read_write_storage_texture;\n";
- }
break;
default:
DAWN_UNREACHABLE();
@@ -125,12 +117,19 @@
}
std::ostringstream ostream;
- ostream << extension << "@group(0) @binding(0) var image0 : " << imageTypeDeclaration << "<"
+ ostream << "@group(0) @binding(0) var image0 : " << imageTypeDeclaration << "<"
<< utils::GetWGSLImageFormatQualifier(textureFormat) << ", " << access << ">;\n"
- << shaderStageDeclaration
- << " fn main() {\n"
- " _ = textureDimensions(image0);\n"
- "}\n";
+ << shaderStageDeclaration << " fn main()";
+ if (shaderStage == wgpu::ShaderStage::Vertex) {
+ ostream << " -> @builtin(position) vec4f ";
+ }
+
+ ostream << "{\n"
+ " _ = textureDimensions(image0);\n";
+ if (shaderStage == wgpu::ShaderStage::Vertex) {
+ ostream << " return vec4f(0.0);";
+ }
+ ostream << "}\n";
return ostream.str();
}
@@ -218,15 +217,15 @@
}
}
-// Validate both read-only and write-only storage textures can be declared in
-// compute shaders.
+// Validate both read-only and write-only storage textures can be declared in compute shaders.
TEST_F(StorageTextureValidationTests, ComputePipeline) {
// Write-only storage textures can be declared in a compute shader.
{
wgpu::ShaderModule csModule = utils::CreateShaderModule(device, R"(
@group(0) @binding(0) var image0 : texture_storage_2d<rgba8unorm, write>;
- @compute @workgroup_size(1) fn main(@builtin(local_invocation_id) LocalInvocationID : vec3u) {
+ @compute @workgroup_size(1)
+ fn main(@builtin(local_invocation_id) LocalInvocationID : vec3u) {
textureStore(image0, vec2i(LocalInvocationID.xy), vec4f(0.0, 0.0, 0.0, 0.0));
})");
@@ -239,44 +238,22 @@
}
}
-// Validate read-only and read-write storage textures are not currently supported without enabling
-// chromium_experimental_read_write_storage_texture.
+// Validate read-only, write-only and read-write storage textures are supported in shader modules.
TEST_F(StorageTextureValidationTests, ReadWriteStorageTexture) {
constexpr std::array<wgpu::StorageTextureAccess, 2> kStorageTextureAccesses = {
{wgpu::StorageTextureAccess::ReadOnly, wgpu::StorageTextureAccess::ReadWrite}};
constexpr std::array<wgpu::ShaderStage, 3> kShaderStages = {
{wgpu::ShaderStage::Vertex, wgpu::ShaderStage::Fragment, wgpu::ShaderStage::Compute}};
- constexpr std::array<bool, 2> kDisableExtension = {{true, false}};
for (wgpu::StorageTextureAccess access : kStorageTextureAccesses) {
for (wgpu::ShaderStage shaderStage : kShaderStages) {
- for (bool disableExtension : kDisableExtension) {
- std::string shader = CreateShaderWithStorageTexture(
- access, wgpu::TextureFormat::R32Float, "texture_storage_2d", disableExtension,
- shaderStage);
- ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, shader.c_str()));
- }
+ std::string shader = CreateShaderWithStorageTexture(
+ access, wgpu::TextureFormat::R32Float, "texture_storage_2d", shaderStage);
+ utils::CreateShaderModule(device, shader.c_str());
}
}
}
-// Test that using write-only storage texture in BindGroupLayout is always valid, while using
-// read-only or read-write storage texture in BindGroupLayout is invalid without the optional
-// feature "chromium-experimental-read-write-storage-texture".
-TEST_F(StorageTextureValidationTests, BindGroupLayoutWithStorageTextureBindingType) {
- const std::vector<BindGroupLayoutTestSpec> kTestSpecs = {
- {{wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::WriteOnly, false},
- {wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::ReadOnly, false},
- {wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::ReadWrite, false},
- {wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly, true},
- {wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, false},
- {wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadWrite, false},
- {wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, true},
- {wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, false},
- {wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadWrite, false}}};
- DoBindGroupLayoutTest(kTestSpecs);
-}
-
// Validate it is an error to declare a read-only or write-only storage texture in shaders with any
// format that doesn't support TextureUsage::StorageBinding texture usages.
TEST_F(StorageTextureValidationTests, StorageTextureFormatInShaders) {
@@ -908,27 +885,20 @@
}
}
-class ReadWriteStorageTextureValidationTests : public StorageTextureValidationTests {
- protected:
- WGPUDevice CreateTestDevice(native::Adapter dawnAdapter,
- wgpu::DeviceDescriptor descriptor) override {
- wgpu::FeatureName requiredFeatures[1] = {
- wgpu::FeatureName::ChromiumExperimentalReadWriteStorageTexture};
- descriptor.requiredFeatures = requiredFeatures;
- descriptor.requiredFeatureCount = 1;
+class ReadWriteStorageTextureValidationTests : public StorageTextureValidationTests {};
- return dawnAdapter.CreateDevice(&descriptor);
- }
-};
-
-// Test that using read-only or read-write storage texture in BindGroupLayout is valid with the
-// optional feature "chromium-experimental-read-write-storage-texture".
-TEST_F(ReadWriteStorageTextureValidationTests, BindGroupLayoutWithStorageTextureBindingType) {
+// Test that using read-only storage texture is valid for all shader stages in BindGroupLayout,
+// while write-only and read-write storage textures are only valid for fragment and compute shader
+// stages.
+TEST_F(StorageTextureValidationTests, BindGroupLayoutWithStorageTextureBindingType) {
const std::vector<BindGroupLayoutTestSpec> kTestSpecs = {
- {{wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::ReadOnly, true},
+ {{wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::WriteOnly, false},
+ {wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::ReadOnly, true},
{wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::ReadWrite, false},
+ {wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly, true},
{wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, true},
{wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadWrite, true},
+ {wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, true},
{wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, true},
{wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadWrite, true}}};
DoBindGroupLayoutTest(kTestSpecs);
@@ -988,20 +958,6 @@
}
}
-// Test that using ReadOnly or ReadWrite storage texture access without declaring the optional
-// feature "chromium-experimental-read-write-storage-texture" is invalid.
-TEST_F(ReadWriteStorageTextureValidationTests, ReadWriteStorageTextureAccessWithoutExtension) {
- constexpr std::array<wgpu::StorageTextureAccess, 2> kStorageTextureAccesses = {
- {wgpu::StorageTextureAccess::ReadOnly, wgpu::StorageTextureAccess::ReadWrite}};
- constexpr bool kDisableExtension = true;
- constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::R32Uint;
- for (wgpu::StorageTextureAccess access : kStorageTextureAccesses) {
- std::string computeShader = CreateShaderWithStorageTexture(
- access, kFormat, "texture_storage_2d", kDisableExtension);
- ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, computeShader.c_str()));
- }
-}
-
// Test that storage texture access in shader must be compatible with the one in pipeline layout
// when we create a pipeline with storage texture. Note that read-write storage texture access in
// pipeline layout is compatible with write-only storage texture access in shader.
@@ -1196,5 +1152,81 @@
}
}
+class ReadWriteStorageTextureDisallowUnsafeAPITests
+ : public ReadWriteStorageTextureValidationTests {
+ protected:
+ // Create the device with the AllowUnsafeAPIs toggle explicitly disabled, which overrides the
+ // inheritance.
+ WGPUDevice CreateTestDevice(native::Adapter dawnAdapter,
+ wgpu::DeviceDescriptor descriptor) override {
+ wgpu::DawnTogglesDescriptor deviceTogglesDesc;
+ descriptor.nextInChain = &deviceTogglesDesc;
+ const char* toggle = "allow_unsafe_apis";
+ deviceTogglesDesc.disabledToggles = &toggle;
+ deviceTogglesDesc.disabledToggleCount = 1;
+ return dawnAdapter.CreateDevice(&descriptor);
+ }
+};
+
+// Check that both read-only and read-write storage texture accesses are validated as unsafe.
+TEST_F(ReadWriteStorageTextureDisallowUnsafeAPITests, StorageAccessInBindGroupLayout) {
+ const std::vector<BindGroupLayoutTestSpec> kTestSpecs = {
+ {{wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::ReadOnly, false},
+ {wgpu::ShaderStage::Vertex, wgpu::StorageTextureAccess::ReadWrite, false},
+ {wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, false},
+ {wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadWrite, false},
+ {wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, false},
+ {wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadWrite, false}}};
+ DoBindGroupLayoutTest(kTestSpecs);
+}
+
+// Check that both read-only and read-write storage textures are validated as unsafe in render and
+// compute pipelines.
+TEST_F(ReadWriteStorageTextureDisallowUnsafeAPITests, ReadWriteStorageTextureInPipeline) {
+ constexpr std::array<wgpu::StorageTextureAccess, 2> kStorageTextureAccesses = {
+ {wgpu::StorageTextureAccess::ReadOnly, wgpu::StorageTextureAccess::ReadWrite}};
+ constexpr std::array<wgpu::ShaderStage, 3> kShaderStages = {
+ {wgpu::ShaderStage::Vertex, wgpu::ShaderStage::Fragment, wgpu::ShaderStage::Compute}};
+
+ for (wgpu::StorageTextureAccess access : kStorageTextureAccesses) {
+ for (wgpu::ShaderStage shaderStage : kShaderStages) {
+ std::string shader = CreateShaderWithStorageTexture(
+ access, wgpu::TextureFormat::R32Float, "texture_storage_2d", shaderStage);
+ wgpu::ShaderModule shaderModule = utils::CreateShaderModule(device, shader.c_str());
+
+ switch (shaderStage) {
+ case wgpu::ShaderStage::Vertex: {
+ utils::ComboRenderPipelineDescriptor renderDescriptor;
+ renderDescriptor.vertex.module = shaderModule;
+ renderDescriptor.cFragment.module = mDefaultFSModule;
+ renderDescriptor.layout = nullptr;
+ ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&renderDescriptor));
+ break;
+ }
+ case wgpu::ShaderStage::Fragment: {
+ utils::ComboRenderPipelineDescriptor renderDescriptor;
+ renderDescriptor.vertex.module = mDefaultVSModule;
+ renderDescriptor.cFragment.module = shaderModule;
+ renderDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
+ renderDescriptor.layout = nullptr;
+ ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&renderDescriptor));
+ break;
+ }
+ case wgpu::ShaderStage::Compute: {
+ wgpu::ComputePipelineDescriptor computeDescriptor;
+ computeDescriptor.compute.module = shaderModule;
+ computeDescriptor.compute.entryPoint = "main";
+ ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&computeDescriptor));
+ break;
+ }
+ case wgpu::ShaderStage::None:
+ default: {
+ DAWN_UNREACHABLE();
+ }
+ }
+ }
+ }
+}
+
} // anonymous namespace
} // namespace dawn
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
index 2c7d268..0bf7f61 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
@@ -2583,9 +2583,6 @@
} else {
const auto access =
usage.IsStorageReadWriteTexture() ? core::Access::kReadWrite : core::Access::kWrite;
- if (access == core::Access::kReadWrite) {
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
- }
const auto format = enum_converter_.ToTexelFormat(image_type->format());
if (format == core::TexelFormat::kUndefined) {
return nullptr;
diff --git a/src/tint/lang/spirv/reader/ast_parser/function.cc b/src/tint/lang/spirv/reader/ast_parser/function.cc
index 99e728a..198f58f 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function.cc
@@ -5325,7 +5325,6 @@
if (memory != uint32_t(spv::Scope::Workgroup)) {
return Fail() << "textureBarrier requires workgroup memory scope";
}
- parser_impl_.Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
AddStatement(builder_.CallStmt(builder_.Call("textureBarrier")));
semantics &= ~static_cast<uint32_t>(spv::MemorySemanticsMask::ImageMemory);
}
diff --git a/src/tint/lang/spirv/reader/ast_parser/handle_test.cc b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
index 4d8caf4..154ccc2 100644
--- a/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
@@ -4233,9 +4233,8 @@
EXPECT_TRUE(p->error().empty()) << p->error();
const auto got = test::ToString(p->program());
- auto* expect = R"(enable chromium_experimental_read_write_storage_texture;
-
-@group(0) @binding(0) var RWTexture2D : texture_storage_2d<rgba32float, read_write>;
+ auto* expect =
+ R"(@group(0) @binding(0) var RWTexture2D : texture_storage_2d<rgba32float, read_write>;
const x_9 = vec2u(1u);
diff --git a/src/tint/lang/spirv/reader/ast_parser/parse.cc b/src/tint/lang/spirv/reader/ast_parser/parse.cc
index af503d2..94c4355 100644
--- a/src/tint/lang/spirv/reader/ast_parser/parse.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/parse.cc
@@ -71,7 +71,6 @@
case wgsl::Extension::kChromiumExperimentalFullPtrParameters:
case wgsl::Extension::kChromiumExperimentalPixelLocal:
case wgsl::Extension::kChromiumExperimentalPushConstant:
- case wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture:
case wgsl::Extension::kChromiumExperimentalSubgroups:
case wgsl::Extension::kChromiumInternalDualSourceBlending:
case wgsl::Extension::kChromiumInternalRelaxedUniformLayout: {
@@ -82,6 +81,7 @@
return Program(std::move(builder));
}
case wgsl::Extension::kF16:
+ case wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture:
break;
}
}
diff --git a/src/tint/lang/spirv/reader/ast_parser/parser_test.cc b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
index f7b2ded..7375186 100644
--- a/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
@@ -91,63 +91,6 @@
EXPECT_EQ(program.Diagnostics().count(), 0u) << errs;
}
-constexpr auto kShaderWithReadWriteStorageTexture = R"(
- OpCapability Shader
- OpCapability StorageImageExtendedFormats
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %100 "main"
- OpExecutionMode %100 LocalSize 8 8 1
- OpSource HLSL 600
- OpName %type_2d_image "type.2d.image"
- OpName %RWTexture2D "RWTexture2D"
- OpName %100 "main"
- OpDecorate %RWTexture2D DescriptorSet 0
- OpDecorate %RWTexture2D Binding 0
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %v4float = OpTypeVector %float 4
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %v2uint = OpTypeVector %uint 2
- %coord = OpConstantComposite %v2uint %uint_1 %uint_1
-%type_2d_image = OpTypeImage %float 2D 2 0 0 2 Rgba32f
-%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %void = OpTypeVoid
- %20 = OpTypeFunction %void
-%RWTexture2D = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %100 = OpFunction %void None %20
- %22 = OpLabel
- %30 = OpLoad %type_2d_image %RWTexture2D
- %31 = OpImageRead %v4float %30 %coord None
- %32 = OpFAdd %v4float %31 %31
- OpImageWrite %30 %coord %32 None
- OpReturn
- OpFunctionEnd
- )";
-
-TEST_F(ParserTest, AllowChromiumExtensions_False) {
- auto spv = test::Assemble(kShaderWithReadWriteStorageTexture);
- Options options;
- options.allow_chromium_extensions = false;
- auto program = Parse(spv, options);
- auto errs = program.Diagnostics().str();
- EXPECT_FALSE(program.IsValid()) << errs;
- EXPECT_THAT(errs,
- ::testing::HasSubstr(
- "error: module requires chromium_experimental_read_write_storage_texture, but "
- "'allow-chromium-extensions' was not passed"));
-}
-
-TEST_F(ParserTest, AllowChromiumExtensions_True) {
- auto spv = test::Assemble(kShaderWithReadWriteStorageTexture);
- Options options;
- options.allow_chromium_extensions = true;
- auto program = Parse(spv, options);
- auto errs = program.Diagnostics().str();
- EXPECT_TRUE(program.IsValid()) << errs;
- EXPECT_EQ(program.Diagnostics().count(), 0u) << errs;
-}
-
// TODO(dneto): uint32 vec, valid SPIR-V
// TODO(dneto): uint32 vec, invalid SPIR-V
diff --git a/src/tint/lang/wgsl/inspector/inspector_test.cc b/src/tint/lang/wgsl/inspector/inspector_test.cc
index 80435da..052c464 100644
--- a/src/tint/lang/wgsl/inspector/inspector_test.cc
+++ b/src/tint/lang/wgsl/inspector/inspector_test.cc
@@ -3126,11 +3126,9 @@
expectedResourceType = ResourceBinding::ResourceType::kWriteOnlyStorageTexture;
break;
case core::Access::kRead:
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
expectedResourceType = ResourceBinding::ResourceType::kReadOnlyStorageTexture;
break;
case core::Access::kReadWrite:
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
expectedResourceType = ResourceBinding::ResourceType::kReadWriteStorageTexture;
break;
case core::Access::kUndefined:
diff --git a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
index 4e4fe92..c317db4 100644
--- a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
@@ -809,29 +809,13 @@
R"(12:34 error: the sourceLaneIndex argument of subgroupBroadcast must be a const-expression)");
}
-TEST_F(ResolverBuiltinValidationTest, TextureBarrierWithoutExtension) {
+TEST_F(ResolverBuiltinValidationTest, TextureBarrier) {
// fn func { textureBarrier(); }
Func("func", tint::Empty, ty.void_(),
Vector{
CallStmt(Call(Source{Source::Location{12, 34}}, "textureBarrier")),
});
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(
- r()->error(),
- R"(12:34 error: cannot call built-in function 'textureBarrier' without extension chromium_experimental_read_write_storage_texture)");
-}
-
-TEST_F(ResolverBuiltinValidationTest, TextureBarrierWithExtension) {
- // enable chromium_experimental_read_write_storage_texture;
- // fn func { textureBarrier(); }
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
-
- Func("func", tint::Empty, ty.void_(),
- Vector{
- CallStmt(Call(Source{Source::Location{12, 34}}, "textureBarrier")),
- });
-
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
diff --git a/src/tint/lang/wgsl/resolver/type_validation_test.cc b/src/tint/lang/wgsl/resolver/type_validation_test.cc
index 710fdf4..bf9d840 100644
--- a/src/tint/lang/wgsl/resolver/type_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/type_validation_test.cc
@@ -1196,7 +1196,7 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(StorageTextureAccessTest, ReadOnlyAccess_WithoutExtension_Fail) {
+TEST_F(StorageTextureAccessTest, ReadOnlyAccess_Pass) {
// @group(0) @binding(0)
// var a : texture_storage_1d<r32uint, read>;
@@ -1205,27 +1205,10 @@
GlobalVar("a", st, Group(0_a), Binding(0_a));
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: read-only storage textures require the "
- "chromium_experimental_read_write_storage_texture extension to be enabled");
-}
-
-TEST_F(StorageTextureAccessTest, ReadOnlyAccess_WithExtension_Pass) {
- // enable chromium_experimental_read_write_storage_texture;
- // @group(0) @binding(0)
- // var a : texture_storage_1d<r32uint, read>;
-
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
- auto st = ty.storage_texture(Source{{12, 34}}, core::type::TextureDimension::k1d,
- core::TexelFormat::kR32Uint, core::Access::kRead);
-
- GlobalVar("a", st, Group(0_a), Binding(0_a));
-
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(StorageTextureAccessTest, RWAccess_WithoutExtension_Fail) {
+TEST_F(StorageTextureAccessTest, RWAccess_Pass) {
// @group(0) @binding(0)
// var a : texture_storage_1d<r32uint, read_write>;
@@ -1234,23 +1217,6 @@
GlobalVar("a", st, Group(0_a), Binding(0_a));
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: read-write storage textures require the "
- "chromium_experimental_read_write_storage_texture extension to be enabled");
-}
-
-TEST_F(StorageTextureAccessTest, RWAccess_WithExtension_Pass) {
- // enable chromium_experimental_read_write_storage_texture;
- // @group(0) @binding(0)
- // var a : texture_storage_1d<r32uint, read_write>;
-
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
- auto st = ty.storage_texture(Source{{12, 34}}, core::type::TextureDimension::k1d,
- core::TexelFormat::kR32Uint, core::Access::kReadWrite);
-
- GlobalVar("a", st, Group(0_a), Binding(0_a));
-
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index d3c0205..da7536d 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -333,25 +333,7 @@
bool Validator::StorageTexture(const core::type::StorageTexture* t, const Source& source) const {
switch (t->access()) {
case core::Access::kRead:
- if (!enabled_extensions_.Contains(
- wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture)) {
- AddError(
- "read-only storage textures require the "
- "chromium_experimental_read_write_storage_texture extension to be enabled",
- source);
- return false;
- }
- break;
case core::Access::kReadWrite:
- if (!enabled_extensions_.Contains(
- wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture)) {
- AddError(
- "read-write storage textures require the "
- "chromium_experimental_read_write_storage_texture extension to be enabled",
- source);
- return false;
- }
- break;
case core::Access::kWrite:
break;
case core::Access::kUndefined:
diff --git a/src/tint/lang/wgsl/sem/builtin_fn.cc b/src/tint/lang/wgsl/sem/builtin_fn.cc
index 968320f..ea49f47 100644
--- a/src/tint/lang/wgsl/sem/builtin_fn.cc
+++ b/src/tint/lang/wgsl/sem/builtin_fn.cc
@@ -112,9 +112,6 @@
if (IsSubgroup()) {
return wgsl::Extension::kChromiumExperimentalSubgroups;
}
- if (fn_ == wgsl::BuiltinFn::kTextureBarrier) {
- return wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture;
- }
return wgsl::Extension::kUndefined;
}
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
index 4a87f27..e3650e6 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
@@ -605,9 +605,6 @@
}
switch (c->Func()) {
- case wgsl::BuiltinFn::kTextureBarrier:
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
- break;
case wgsl::BuiltinFn::kSubgroupBallot:
case wgsl::BuiltinFn::kSubgroupBroadcast:
Enable(wgsl::Extension::kChromiumExperimentalSubgroups);
@@ -942,9 +939,6 @@
return b.ty.sampled_texture(t->dim(), el);
},
[&](const core::type::StorageTexture* t) {
- if (t->access() == core::Access::kRead || t->access() == core::Access::kReadWrite) {
- Enable(wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
- }
return b.ty.storage_texture(t->dim(), t->texel_format(), t->access());
},
[&](const core::type::Sampler* s) { return b.ty.sampler(s->kind()); },
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
index 86dbbca..53af431 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
@@ -3212,55 +3212,6 @@
}
////////////////////////////////////////////////////////////////////////////////
-// chromium_experimental_read_write_storage_texture
-////////////////////////////////////////////////////////////////////////////////
-TEST_F(IRToProgramTest, Enable_ChromiumExperimentalReadWriteStorageTexture_TextureBarrier) {
- auto* fn = b.Function("f", ty.void_());
- b.Append(fn->Block(), [&] {
- b.Append(mod.instructions.Create<wgsl::ir::BuiltinCall>(
- b.InstructionResult(ty.void_()), wgsl::BuiltinFn::kTextureBarrier, Empty));
- b.Return(fn);
- });
-
- EXPECT_WGSL(R"(
-enable chromium_experimental_read_write_storage_texture;
-
-fn f() {
- textureBarrier();
-}
-)");
-}
-
-TEST_F(IRToProgramTest, Enable_ChromiumExperimentalReadWriteStorageTexture_ReadOnlyStorageTexture) {
- auto* T = b.Var("T", ty.ptr<handle>(ty.Get<core::type::StorageTexture>(
- core::type::TextureDimension::k2d, core::TexelFormat::kR32Float,
- core::Access::kRead, ty.f32())));
- T->SetBindingPoint(0, 0);
- b.ir.root_block->Append(T);
-
- EXPECT_WGSL(R"(
-enable chromium_experimental_read_write_storage_texture;
-
-@group(0) @binding(0) var T : texture_storage_2d<r32float, read>;
-)");
-}
-
-TEST_F(IRToProgramTest,
- Enable_ChromiumExperimentalReadWriteStorageTexture_ReadWriteOnlyStorageTexture) {
- auto* T = b.Var("T", ty.ptr<handle>(ty.Get<core::type::StorageTexture>(
- core::type::TextureDimension::k2d, core::TexelFormat::kR32Float,
- core::Access::kReadWrite, ty.f32())));
- T->SetBindingPoint(0, 0);
- b.ir.root_block->Append(T);
-
- EXPECT_WGSL(R"(
-enable chromium_experimental_read_write_storage_texture;
-
-@group(0) @binding(0) var T : texture_storage_2d<r32float, read_write>;
-)");
-}
-
-////////////////////////////////////////////////////////////////////////////////
// chromium_experimental_subgroups
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramTest, Enable_ChromiumExperimentalSubgroups_SubgroupBallot) {