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) {