Deprecate readonly storage textures

Bug: dawn:1025
Change-Id: Ie799507b534d983959d44b573436bb5421162150
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/59841
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
Corentin Wallez 2021-07-28 18:00:56 +00:00 committed by Dawn LUCI CQ
parent b550c143c0
commit 52201303f3
12 changed files with 326 additions and 104 deletions

View File

@ -159,6 +159,12 @@ namespace dawn_native {
if (storageTexture.access == wgpu::StorageTextureAccess::WriteOnly) {
allowedStages &= ~wgpu::ShaderStage::Vertex;
}
// TODO(crbug.com/dawn/1025): Remove after the deprecation period.
if (storageTexture.access == wgpu::StorageTextureAccess::ReadOnly) {
device->EmitDeprecationWarning(
"Readonly storage textures are deprecated and will be removed.");
}
}
const ExternalTextureBindingLayout* externalTextureBindingLayout = nullptr;

View File

@ -216,7 +216,9 @@ namespace dawn_native {
desc.entries = entryVec.data();
desc.entryCount = entryVec.size();
DAWN_TRY(ValidateBindGroupLayoutDescriptor(device, &desc));
if (device->IsValidationEnabled()) {
DAWN_TRY(ValidateBindGroupLayoutDescriptor(device, &desc));
}
return device->GetOrCreateBindGroupLayout(&desc);
};

View File

@ -578,7 +578,7 @@ class DawnTestBase {
#define DAWN_SUPPRESS_TEST_IF(condition) \
DAWN_SKIP_TEST_IF_BASE(!RunSuppressedTests() && condition, "suppressed", condition)
#define EXPECT_DEPRECATION_WARNING(statement) \
#define EXPECT_DEPRECATION_WARNINGS(statement, n) \
do { \
if (UsesWire()) { \
statement; \
@ -590,11 +590,12 @@ class DawnTestBase {
dawn_native::GetDeprecationWarningCountForTesting(device.Get()); \
EXPECT_EQ(mLastWarningCount, warningsBefore); \
if (!HasToggleEnabled("skip_validation")) { \
EXPECT_EQ(warningsAfter, warningsBefore + 1); \
EXPECT_EQ(warningsAfter, warningsBefore + n); \
} \
mLastWarningCount = warningsAfter; \
} \
} while (0)
#define EXPECT_DEPRECATION_WARNING(statement) EXPECT_DEPRECATION_WARNINGS(statement, 1)
template <typename Params = AdapterTestParam>
class DawnTestWithParams : public DawnTestBase, public ::testing::TestWithParam<Params> {

View File

@ -1237,7 +1237,9 @@ TEST_P(BindGroupTests, ReallyLargeBindGroup) {
wgpu::ComputePipelineDescriptor cpDesc;
cpDesc.compute.module = utils::CreateShaderModule(device, shader.c_str());
cpDesc.compute.entryPoint = "main";
wgpu::ComputePipeline cp = device.CreateComputePipeline(&cpDesc);
wgpu::ComputePipeline cp;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
EXPECT_DEPRECATION_WARNINGS(cp = device.CreateComputePipeline(&cpDesc), 4);
wgpu::BindGroupDescriptor bgDesc = {};
bgDesc.layout = cp.GetBindGroupLayout(0);
@ -1298,9 +1300,13 @@ TEST_P(BindGroupTests, CreateWithDestroyedResource) {
// Test a storage texture.
{
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly,
wgpu::TextureFormat::R32Uint}});
wgpu::BindGroupLayout bgl;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly,
wgpu::TextureFormat::R32Uint}}));
wgpu::TextureDescriptor textureDesc;
textureDesc.usage = wgpu::TextureUsage::Storage;

View File

@ -136,6 +136,19 @@ TEST_P(DeprecationTests, StoreOpClear) {
pass.EndPass();
}
// Test that readonly storage textures are deprecated
TEST_P(DeprecationTests, ReadOnlyStorageTextures) {
// Control case: WriteOnly storage textures are allowed.
utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly,
wgpu::TextureFormat::R32Float}});
// Error case: ReadOnly storage textures are not allowed.
EXPECT_DEPRECATION_WARNING(utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly,
wgpu::TextureFormat::R32Float}}));
}
DAWN_INSTANTIATE_TEST(DeprecationTests,
D3D12Backend(),
MetalBackend(),

View File

@ -264,7 +264,9 @@ TEST_P(GpuMemorySyncTests, SampledAndROStorageTextureInComputePass) {
output.storageOut = textureLoad(storageTex, vec2<i32>(0, 0)).x;
}
)");
wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDesc);
wgpu::ComputePipeline pipeline;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
EXPECT_DEPRECATION_WARNING(pipeline = device.CreateComputePipeline(&pipelineDesc));
// Run the compute pipeline and store the result in the buffer.
wgpu::BufferDescriptor outputDesc;

View File

@ -780,7 +780,10 @@ TEST_P(StorageTextureTests, ReadonlyStorageTextureInComputeShader) {
}
})";
CheckResultInStorageBuffer(readonlyStorageTexture, csStream.str());
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
CheckResultInStorageBuffer(readonlyStorageTexture, csStream.str()));
}
}
@ -824,7 +827,10 @@ struct VertexOut {
fn main([[location(0)]] color : vec4<f32>) -> [[location(0)]] vec4<f32> {
return color;
})";
CheckDrawsGreen(vsStream.str().c_str(), kFragmentShader, readonlyStorageTexture);
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
CheckDrawsGreen(vsStream.str().c_str(), kFragmentShader, readonlyStorageTexture));
}
}
@ -858,7 +864,10 @@ TEST_P(StorageTextureTests, ReadonlyStorageTextureInFragmentShader) {
}
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
})";
CheckDrawsGreen(kSimpleVertexShader, fsStream.str().c_str(), readonlyStorageTexture);
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
CheckDrawsGreen(kSimpleVertexShader, fsStream.str().c_str(), readonlyStorageTexture));
}
}
@ -927,8 +936,10 @@ TEST_P(StorageTextureTests, ReadWriteDifferentStorageTextureInOneDispatchInCompu
// Write the expected pixel values into the write-only storage texture.
const std::string computeShader = CommonReadWriteTestCode(format);
ReadWriteIntoStorageTextureInComputePass(readonlyStorageTexture, writeonlyStorageTexture,
computeShader.c_str());
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(ReadWriteIntoStorageTextureInComputePass(
readonlyStorageTexture, writeonlyStorageTexture, computeShader.c_str()));
// Verify the pixel data in the write-only storage texture is expected.
CheckOutputStorageTexture(writeonlyStorageTexture, format);
@ -1013,7 +1024,10 @@ TEST_P(StorageTextureTests, Readonly2DArrayOr3DStorageTexture) {
}
})";
CheckResultInStorageBuffer(readonlyStorageTexture, csStream.str(), dimension);
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
CheckResultInStorageBuffer(readonlyStorageTexture, csStream.str(), dimension));
}
}
@ -1075,10 +1089,14 @@ TEST_P(StorageTextureTests, ReadWrite2DArrayOr3DStorageTexture) {
// Read values from read-only storage texture and write into the write-only storage texture.
const std::string computeShader = CommonReadWriteTestCode(kTextureFormat, dimension);
ReadWriteIntoStorageTextureInComputePass(readonlyStorageTexture, writeonlyStorageTexture,
computeShader.c_str(), dimension);
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(ReadWriteIntoStorageTextureInComputePass(
readonlyStorageTexture, writeonlyStorageTexture, computeShader.c_str(), dimension));
// Verify the data in the write-only storage texture is expected.
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
CheckOutputStorageTexture(writeonlyStorageTexture, kTextureFormat, kSliceCount);
}
}
@ -1108,7 +1126,9 @@ TEST_P(StorageTextureTests, ReadonlyAndWriteonlyStorageTexturePingPong) {
wgpu::ComputePipelineDescriptor pipelineDesc = {};
pipelineDesc.compute.module = module;
pipelineDesc.compute.entryPoint = "main";
wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDesc);
wgpu::ComputePipeline pipeline;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
EXPECT_DEPRECATION_WARNING(pipeline = device.CreateComputePipeline(&pipelineDesc));
// In bindGroupA storageTexture1 is bound as read-only storage texture and storageTexture2 is
// bound as write-only storage texture.
@ -1302,7 +1322,9 @@ TEST_P(StorageTextureZeroInitTests, ReadonlyStorageTextureClearsToZeroInRenderPa
}
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
})";
CheckDrawsGreen(kVertexShader, kFragmentShader.c_str(), readonlyStorageTexture);
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
EXPECT_DEPRECATION_WARNING(
CheckDrawsGreen(kVertexShader, kFragmentShader.c_str(), readonlyStorageTexture));
}
// Verify that the texture is correctly cleared to 0 before its first usage as a read-only storage
@ -1329,7 +1351,8 @@ TEST_P(StorageTextureZeroInitTests, ReadonlyStorageTextureClearsToZeroInComputeP
}
})";
CheckResultInStorageBuffer(readonlyStorageTexture, kComputeShader);
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
EXPECT_DEPRECATION_WARNING(CheckResultInStorageBuffer(readonlyStorageTexture, kComputeShader));
}
// Verify that the texture is correctly cleared to 0 before its first usage as a write-only storage

View File

@ -406,7 +406,7 @@ TEST_F(BindGroupValidationTest, TextureUsage) {
// Check that a storage texture binding must have the correct usage
TEST_F(BindGroupValidationTest, StorageTextureUsage) {
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly,
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly,
wgpu::TextureFormat::RGBA8Uint}});
wgpu::TextureDescriptor descriptor;
@ -932,7 +932,7 @@ TEST_F(BindGroupLayoutValidationTest, PerStageLimits) {
wgpu::BindGroupLayoutEntry otherEntry;
};
std::array<TestInfo, 8> kTestInfos = {
std::array<TestInfo, 7> kTestInfos = {
TestInfo{kMaxSampledTexturesPerShaderStage, BGLEntryType(wgpu::TextureSampleType::Float),
BGLEntryType(wgpu::BufferBindingType::Uniform)},
TestInfo{kMaxSamplersPerShaderStage, BGLEntryType(wgpu::SamplerBindingType::Filtering),
@ -941,10 +941,6 @@ TEST_F(BindGroupLayoutValidationTest, PerStageLimits) {
BGLEntryType(wgpu::BufferBindingType::Uniform)},
TestInfo{kMaxStorageBuffersPerShaderStage, BGLEntryType(wgpu::BufferBindingType::Storage),
BGLEntryType(wgpu::BufferBindingType::Uniform)},
TestInfo{
kMaxStorageTexturesPerShaderStage,
BGLEntryType(wgpu::StorageTextureAccess::ReadOnly, wgpu::TextureFormat::RGBA8Unorm),
BGLEntryType(wgpu::BufferBindingType::Uniform)},
TestInfo{
kMaxStorageTexturesPerShaderStage,
BGLEntryType(wgpu::StorageTextureAccess::WriteOnly, wgpu::TextureFormat::RGBA8Unorm),
@ -1020,6 +1016,78 @@ TEST_F(BindGroupLayoutValidationTest, PerStageLimits) {
}
}
// This is the same test as PerStageLimits but for the deprecated ReadOnly storage textures.
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
TEST_F(BindGroupLayoutValidationTest, PerStageLimits_ReadOnlyStorageTexture) {
uint32_t maxCount = kMaxStorageTexturesPerShaderStage;
wgpu::BindGroupLayoutEntry entry =
BGLEntryType(wgpu::StorageTextureAccess::ReadOnly, wgpu::TextureFormat::RGBA8Unorm);
wgpu::BindGroupLayoutEntry otherEntry = BGLEntryType(wgpu::BufferBindingType::Uniform);
wgpu::BindGroupLayout bgl[2];
std::vector<utils::BindingLayoutEntryInitializationHelper> maxBindings;
for (uint32_t i = 0; i < maxCount; ++i) {
entry.binding = i;
maxBindings.push_back(entry);
}
// Creating with the maxes works.
EXPECT_DEPRECATION_WARNINGS(
bgl[0] = MakeBindGroupLayout(maxBindings.data(), maxBindings.size()), maxCount);
// Adding an extra binding of a different type works.
{
std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
wgpu::BindGroupLayoutEntry newEntry = otherEntry;
newEntry.binding = maxCount;
bindings.push_back(newEntry);
EXPECT_DEPRECATION_WARNINGS(MakeBindGroupLayout(bindings.data(), bindings.size()),
maxCount);
}
// Adding an extra binding of the maxed type in a different stage works
{
std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
wgpu::BindGroupLayoutEntry newEntry = entry;
newEntry.binding = maxCount;
newEntry.visibility = wgpu::ShaderStage::Fragment;
bindings.push_back(newEntry);
EXPECT_DEPRECATION_WARNINGS(MakeBindGroupLayout(bindings.data(), bindings.size()),
maxCount + 1);
}
// Adding an extra binding of the maxed type and stage exceeds the per stage limit.
{
std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
wgpu::BindGroupLayoutEntry newEntry = entry;
newEntry.binding = maxCount;
bindings.push_back(newEntry);
EXPECT_DEPRECATION_WARNINGS(
ASSERT_DEVICE_ERROR(MakeBindGroupLayout(bindings.data(), bindings.size())),
maxCount + 1);
}
// Creating a pipeline layout from the valid BGL works.
TestCreatePipelineLayout(bgl, 1, true);
// Adding an extra binding of a different type in a different BGL works
bgl[1] = utils::MakeBindGroupLayout(device, {otherEntry});
TestCreatePipelineLayout(bgl, 2, true);
{
// Adding an extra binding of the maxed type in a different stage works
wgpu::BindGroupLayoutEntry newEntry = entry;
newEntry.visibility = wgpu::ShaderStage::Fragment;
EXPECT_DEPRECATION_WARNING(bgl[1] = utils::MakeBindGroupLayout(device, {newEntry}));
TestCreatePipelineLayout(bgl, 2, true);
}
// Adding an extra binding of the maxed type in a different BGL exceeds the per stage limit.
EXPECT_DEPRECATION_WARNING(bgl[1] = utils::MakeBindGroupLayout(device, {entry}));
TestCreatePipelineLayout(bgl, 2, false);
}
// External textures require multiple binding slots (3 sampled texture, 1 uniform buffer, 1
// sampler), so ensure that these count towards the limit when combined non-external texture
// bindings.

View File

@ -822,11 +822,15 @@ namespace {
wgpu::TextureView view = texture.CreateView();
// Create a bind group to use the texture as sampled and readonly storage bindings
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
wgpu::TextureSampleType::Float},
{1, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout bgl;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
wgpu::TextureSampleType::Float},
{1, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
wgpu::StorageTextureAccess::ReadOnly, kFormat}}));
wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});
// Test render pass
@ -1100,9 +1104,13 @@ namespace {
wgpu::TextureView view = texture.CreateView();
// Create bind groups to use the texture as readonly and writeonly bindings
wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout readBGL;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
readBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly,
kFormat}}));
wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
@ -1133,9 +1141,13 @@ namespace {
wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout readBGL;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
readBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly,
kFormat}}));
wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});
wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, view}});
@ -1199,9 +1211,13 @@ namespace {
// Test compute pass
{
// Create bind groups to use the texture as readonly and writeonly storage bindings
wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout readBGL;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
readBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly,
kFormat}}));
wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
@ -1270,9 +1286,13 @@ namespace {
// Test compute pass
{
// Create the bind group to use the texture as readonly and writeonly storage bindings
wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout readBGL;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
readBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly,
kFormat}}));
wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
@ -1401,9 +1421,13 @@ namespace {
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout readBGL;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
readBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly,
kFormat}}));
wgpu::BindGroup writeBG0 = utils::MakeBindGroup(device, writeBGL, {{0, view0}});
wgpu::BindGroup readBG0 = utils::MakeBindGroup(device, readBGL, {{0, view0}});
@ -1455,10 +1479,15 @@ namespace {
// usage doesn't reside in render related stages at all
{
// Create a bind group whose bindings are not visible in render pass
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::None, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
wgpu::BindGroupLayout bgl;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
bgl = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::None, wgpu::StorageTextureAccess::WriteOnly,
kFormat}}));
wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});
// These two bindings are invisible in render pass. But we still track these bindings.
@ -1474,10 +1503,15 @@ namespace {
// usage doesn't reside in compute related stage at all
{
// Create a bind group whose bindings are not visible in compute pass
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::None, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
wgpu::BindGroupLayout bgl;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly,
kFormat},
{1, wgpu::ShaderStage::None, wgpu::StorageTextureAccess::WriteOnly,
kFormat}}));
wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});
// Create a no-op compute pipeline.
@ -1508,9 +1542,13 @@ namespace {
utils::ComboRenderPassDescriptor renderPass({view});
// Create a bind group which use the texture as readonly storage in compute stage
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout bgl;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly,
kFormat}}));
wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});
// Texture usage in compute stage in bind group conflicts with render target. And
@ -1526,10 +1564,15 @@ namespace {
// Test compute pass
{
// Create a bind group which contains both fragment and compute stages
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
wgpu::BindGroupLayout bgl;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly,
kFormat},
{1, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly,
kFormat}}));
wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});
// Create a no-op compute pipeline.
@ -1556,9 +1599,13 @@ namespace {
wgpu::TextureView view = texture.CreateView();
// Create bind groups.
wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
wgpu::StorageTextureAccess::ReadOnly, kFormat}});
wgpu::BindGroupLayout readBGL;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
EXPECT_DEPRECATION_WARNING(
readBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
wgpu::StorageTextureAccess::ReadOnly, kFormat}}));
wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
wgpu::StorageTextureAccess::WriteOnly, kFormat}});

View File

@ -111,13 +111,26 @@ class StorageTextureValidationTests : public ValidationTest {
wgpu::ShaderModule mDefaultFSModule;
const std::array<wgpu::StorageTextureAccess, 2> kSupportedStorageTextureAccess = {
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is
// passed.
wgpu::StorageTextureAccess::ReadOnly, wgpu::StorageTextureAccess::WriteOnly};
};
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
#define WARNING_IF_READONLY(statement, access) \
do { \
if (access == wgpu::StorageTextureAccess::ReadOnly) { \
EXPECT_DEPRECATION_WARNING(statement); \
} else { \
statement; \
} \
} while (0)
// Validate read-only storage textures can be declared in vertex and fragment shaders, while
// writeonly storage textures cannot be used in vertex shaders.
TEST_F(StorageTextureValidationTests, RenderPipeline) {
// Readonly storage texture can be declared in a vertex shader.
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
{
wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
[[group(0), binding(0)]] var image0 : texture_storage_2d<rgba8unorm, read>;
@ -131,10 +144,11 @@ TEST_F(StorageTextureValidationTests, RenderPipeline) {
descriptor.layout = nullptr;
descriptor.vertex.module = vsModule;
descriptor.cFragment.module = mDefaultFSModule;
device.CreateRenderPipeline(&descriptor);
EXPECT_DEPRECATION_WARNING(device.CreateRenderPipeline(&descriptor));
}
// Read-only storage textures can be declared in a fragment shader.
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
{
wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
[[group(0), binding(0)]] var image0 : texture_storage_2d<rgba8unorm, read>;
@ -148,7 +162,7 @@ TEST_F(StorageTextureValidationTests, RenderPipeline) {
descriptor.layout = nullptr;
descriptor.vertex.module = mDefaultVSModule;
descriptor.cFragment.module = fsModule;
device.CreateRenderPipeline(&descriptor);
EXPECT_DEPRECATION_WARNING(device.CreateRenderPipeline(&descriptor));
}
// Write-only storage textures cannot be declared in a vertex shader.
@ -187,6 +201,7 @@ TEST_F(StorageTextureValidationTests, RenderPipeline) {
// compute shaders.
TEST_F(StorageTextureValidationTests, ComputePipeline) {
// Read-only storage textures can be declared in a compute shader.
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
{
wgpu::ShaderModule csModule = utils::CreateShaderModule(device, R"(
[[group(0), binding(0)]] var image0 : texture_storage_2d<rgba8unorm, read>;
@ -205,7 +220,7 @@ TEST_F(StorageTextureValidationTests, ComputePipeline) {
descriptor.compute.module = csModule;
descriptor.compute.entryPoint = "main";
device.CreateComputePipeline(&descriptor);
EXPECT_DEPRECATION_WARNING(device.CreateComputePipeline(&descriptor));
}
// Write-only storage textures can be declared in a compute shader.
@ -281,9 +296,10 @@ TEST_F(StorageTextureValidationTests, BindGroupLayoutWithStorageTextureBindingTy
descriptor.entries = &entry;
if (testSpec.valid) {
device.CreateBindGroupLayout(&descriptor);
WARNING_IF_READONLY(device.CreateBindGroupLayout(&descriptor), testSpec.type);
} else {
ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor));
WARNING_IF_READONLY(ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor)),
testSpec.type);
}
}
}
@ -413,8 +429,10 @@ TEST_F(StorageTextureValidationTests, BindGroupLayoutEntryTypeMatchesShaderDecla
defaultComputePipelineDescriptor;
// Create bind group layout with different binding types.
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {bindingLayoutEntry});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(device, {bindingLayoutEntry}),
bindingLayoutEntry.storageTexture.access);
computePipelineDescriptor.layout =
utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
@ -456,7 +474,8 @@ TEST_F(StorageTextureValidationTests, StorageTextureFormatInBindGroupLayout) {
bindGroupLayoutBinding.storageTexture.access = bindingType;
bindGroupLayoutBinding.storageTexture.format = textureFormat;
if (utils::TextureFormatSupportsStorageTexture(textureFormat)) {
utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding});
WARNING_IF_READONLY(utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}),
bindingType);
} else {
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}));
}
@ -498,8 +517,10 @@ TEST_F(StorageTextureValidationTests, BindGroupLayoutStorageTextureFormatMatches
wgpu::BindGroupLayoutEntry bindGroupLayoutBinding = defaultBindGroupLayoutEntry;
bindGroupLayoutBinding.storageTexture.format =
storageTextureFormatInBindGroupLayout;
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}),
bindingType);
// Create the compute pipeline with the bind group layout.
wgpu::ComputePipelineDescriptor computePipelineDescriptor =
@ -547,8 +568,10 @@ TEST_F(StorageTextureValidationTests, BindGroupLayoutViewDimensionMatchesShaderD
// Create the bind group layout with the given texture view dimension.
wgpu::BindGroupLayoutEntry bindGroupLayoutBinding = defaultBindGroupLayoutEntry;
bindGroupLayoutBinding.storageTexture.viewDimension = dimensionInBindGroupLayout;
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}),
bindingType);
// Create the compute pipeline with the bind group layout.
wgpu::ComputePipelineDescriptor computePipelineDescriptor =
@ -579,8 +602,10 @@ TEST_F(StorageTextureValidationTests, StorageTextureBindingTypeInBindGroup) {
bindGroupLayoutBinding.visibility = wgpu::ShaderStage::Compute;
bindGroupLayoutBinding.storageTexture.access = storageBindingType;
bindGroupLayoutBinding.storageTexture.format = kStorageTextureFormat;
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}),
storageBindingType);
// Buffers are not allowed to be used as storage textures in a bind group.
{
@ -622,8 +647,10 @@ TEST_F(StorageTextureValidationTests, StorageTextureUsageInBindGroup) {
bindGroupLayoutBinding.visibility = wgpu::ShaderStage::Compute;
bindGroupLayoutBinding.storageTexture.access = storageBindingType;
bindGroupLayoutBinding.storageTexture.format = wgpu::TextureFormat::R32Float;
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}),
storageBindingType);
for (wgpu::TextureUsage usage : kTextureUsages) {
// Create texture views with different texture usages
@ -659,8 +686,10 @@ TEST_F(StorageTextureValidationTests, StorageTextureFormatInBindGroup) {
// Create a bind group layout with given storage texture format.
wgpu::BindGroupLayoutEntry bindGroupLayoutBinding = defaultBindGroupLayoutEntry;
bindGroupLayoutBinding.storageTexture.format = formatInBindGroupLayout;
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}),
storageBindingType);
for (wgpu::TextureFormat textureViewFormat : utils::kAllTextureFormats) {
if (!utils::TextureFormatSupportsStorageTexture(textureViewFormat)) {
@ -714,8 +743,10 @@ TEST_F(StorageTextureValidationTests, StorageTextureViewDimensionInBindGroup) {
// Create a bind group layout with given texture view dimension.
wgpu::BindGroupLayoutEntry bindGroupLayoutBinding = defaultBindGroupLayoutEntry;
bindGroupLayoutBinding.storageTexture.viewDimension = dimensionInBindGroupLayout;
wgpu::BindGroupLayout bindGroupLayout =
utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(device, {bindGroupLayoutBinding}),
storageBindingType);
for (wgpu::TextureViewDimension dimensionOfTextureView : kSupportedDimensions) {
// Create a texture view with given texture view dimension.
@ -760,8 +791,11 @@ TEST_F(StorageTextureValidationTests, StorageTextureInRenderPass) {
for (wgpu::StorageTextureAccess storageTextureType : kSupportedStorageTextureAccess) {
// Create a bind group that contains a storage texture.
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, storageTextureType, kFormat}});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, storageTextureType, kFormat}}),
storageTextureType);
wgpu::BindGroup bindGroupWithStorageTexture =
utils::MakeBindGroup(device, bindGroupLayout, {{0, storageTexture.CreateView()}});
@ -791,9 +825,12 @@ TEST_F(StorageTextureValidationTests, StorageTextureAndSampledTextureInOneRender
for (wgpu::StorageTextureAccess storageTextureType : kSupportedStorageTextureAccess) {
// Create a bind group that binds the same texture as both storage texture and sampled
// texture.
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, storageTextureType, kFormat},
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, storageTextureType, kFormat},
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}}),
storageTextureType);
wgpu::BindGroup bindGroup = utils::MakeBindGroup(
device, bindGroupLayout,
{{0, storageTexture.CreateView()}, {1, storageTexture.CreateView()}});
@ -829,8 +866,11 @@ TEST_F(StorageTextureValidationTests, StorageTextureAndRenderAttachmentInOneRend
for (wgpu::StorageTextureAccess storageTextureType : kSupportedStorageTextureAccess) {
// Create a bind group that contains a storage texture.
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, storageTextureType, kFormat}});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, storageTextureType, kFormat}}),
storageTextureType);
wgpu::BindGroup bindGroupWithStorageTexture =
utils::MakeBindGroup(device, bindGroupLayout, {{0, storageTexture.CreateView()}});
@ -852,9 +892,13 @@ TEST_F(StorageTextureValidationTests, ReadOnlyAndWriteOnlyStorageTextureInOneRen
// Create a bind group that uses the same texture as both read-only and write-only storage
// texture.
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
wgpu::BindGroupLayout bindGroupLayout;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
EXPECT_DEPRECATION_WARNING(
bindGroupLayout = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly, kFormat}}));
wgpu::BindGroup bindGroup =
utils::MakeBindGroup(device, bindGroupLayout,
{{0, storageTexture.CreateView()}, {1, storageTexture.CreateView()}});
@ -880,9 +924,12 @@ TEST_F(StorageTextureValidationTests, StorageTextureAndSampledTextureInOneComput
for (wgpu::StorageTextureAccess storageTextureType : kSupportedStorageTextureAccess) {
// Create a bind group that binds the same texture as both storage texture and sampled
// texture.
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, storageTextureType, kFormat},
{1, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}});
wgpu::BindGroupLayout bindGroupLayout;
WARNING_IF_READONLY(
bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, storageTextureType, kFormat},
{1, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}}),
storageTextureType);
wgpu::BindGroup bindGroup = utils::MakeBindGroup(
device, bindGroupLayout,
{{0, storageTexture.CreateView()}, {1, storageTexture.CreateView()}});
@ -905,9 +952,13 @@ TEST_F(StorageTextureValidationTests, ReadOnlyAndWriteOnlyStorageTextureInOneCom
// Create a bind group that uses the same texture as both read-only and write-only storage
// texture.
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
wgpu::BindGroupLayout bindGroupLayout;
// TODO(crbug.com/dawn/1025): Remove once ReadOnly storage texture deprecation period is passed.
EXPECT_DEPRECATION_WARNING(
bindGroupLayout = utils::MakeBindGroupLayout(
device,
{{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat},
{1, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}}));
wgpu::BindGroup bindGroup =
utils::MakeBindGroup(device, bindGroupLayout,
{{0, storageTexture.CreateView()}, {1, storageTexture.CreateView()}});

View File

@ -72,9 +72,11 @@ namespace {
{
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, samplerView}});
wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly,
kFormat}});
wgpu::BindGroupLayout bgl1;
EXPECT_DEPRECATION_WARNING(
bgl1 = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment,
wgpu::StorageTextureAccess::ReadOnly, kFormat}}));
wgpu::BindGroup bindGroup1 = utils::MakeBindGroup(device, bgl1, {{0, samplerView}});

View File

@ -42,7 +42,7 @@
} \
} while (0)
#define EXPECT_DEPRECATION_WARNING(statement) \
#define EXPECT_DEPRECATION_WARNINGS(statement, n) \
do { \
FlushWire(); \
size_t warningsBefore = dawn_native::GetDeprecationWarningCountForTesting(backendDevice); \
@ -50,9 +50,10 @@
statement; \
FlushWire(); \
size_t warningsAfter = dawn_native::GetDeprecationWarningCountForTesting(backendDevice); \
EXPECT_EQ(warningsAfter, warningsBefore + 1); \
EXPECT_EQ(warningsAfter, warningsBefore + n); \
mLastWarningCount = warningsAfter; \
} while (0)
#define EXPECT_DEPRECATION_WARNING(statement) EXPECT_DEPRECATION_WARNINGS(statement, 1)
namespace utils {
class WireHelper;