Accept unfilterable-float sample type for depth format texture

Allow unfilterable-float sample type for depth format texture
and add unit tests and end2end tests to check it.

Bug: dawn:1508
Change-Id: I46fc22d66d0c2ad5e3923a18e4d13d174203964a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/99060
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Takahiro 2022-08-18 21:07:19 +00:00 committed by Dawn LUCI CQ
parent 539b0c2210
commit 6a314e49e1
3 changed files with 169 additions and 61 deletions

View File

@ -245,7 +245,7 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
firstAspect->block.width = 1; firstAspect->block.width = 1;
firstAspect->block.height = 1; firstAspect->block.height = 1;
firstAspect->baseType = wgpu::TextureComponentType::Float; firstAspect->baseType = wgpu::TextureComponentType::Float;
firstAspect->supportedSampleTypes = SampleTypeBit::Depth; firstAspect->supportedSampleTypes = SampleTypeBit::Depth | SampleTypeBit::UnfilterableFloat;
firstAspect->format = format; firstAspect->format = format;
AddFormat(internalFormat); AddFormat(internalFormat);
}; };

View File

@ -44,9 +44,10 @@ const std::vector<uint32_t> kStencilValues = {0, 1, 38, 255};
class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingTestParams> { class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingTestParams> {
protected: protected:
enum class TestAspect { enum class TestAspectAndSamplerType {
Depth, DepthAsDepth,
Stencil, DepthAsFloat,
StencilAsUint,
}; };
void SetUp() override { void SetUp() override {
@ -74,7 +75,7 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
} }
} }
void GenerateSamplingShader(const std::vector<TestAspect>& aspects, void GenerateSamplingShader(const std::vector<TestAspectAndSamplerType>& aspectAndSamplerTypes,
const std::vector<uint32_t> components, const std::vector<uint32_t> components,
std::ostringstream& shaderSource, std::ostringstream& shaderSource,
std::ostringstream& shaderBody) { std::ostringstream& shaderBody) {
@ -89,9 +90,9 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
shaderSource << "\n"; shaderSource << "\n";
uint32_t index = 0; uint32_t index = 0;
for (TestAspect aspect : aspects) { for (TestAspectAndSamplerType aspectAndSamplerType : aspectAndSamplerTypes) {
switch (aspect) { switch (aspectAndSamplerType) {
case TestAspect::Depth: case TestAspectAndSamplerType::DepthAsDepth:
shaderSource << "@group(0) @binding(" << 2 * index << ") var tex" << index shaderSource << "@group(0) @binding(" << 2 * index << ") var tex" << index
<< " : texture_depth_2d;\n"; << " : texture_depth_2d;\n";
@ -103,7 +104,19 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
shaderBody << "\nresult" << index << ".value = textureLoad(tex" << index shaderBody << "\nresult" << index << ".value = textureLoad(tex" << index
<< ", vec2<i32>(0, 0), 0);"; << ", vec2<i32>(0, 0), 0);";
break; break;
case TestAspect::Stencil: case TestAspectAndSamplerType::DepthAsFloat:
shaderSource << "@group(0) @binding(" << 2 * index << ") var tex" << index
<< " : texture_2d<f32>;\n";
shaderSource << "@group(0) @binding(" << 2 * index + 1
<< ") var<storage, read_write> result" << index
<< " : DepthResult;\n";
ASSERT(components.size() == 1 && components[0] == 0);
shaderBody << "\nresult" << index << ".value = textureLoad(tex" << index
<< ", vec2<i32>(0, 0), 0)[0];";
break;
case TestAspectAndSamplerType::StencilAsUint:
shaderSource << "@group(0) @binding(" << 2 * index << ") var tex" << index shaderSource << "@group(0) @binding(" << 2 * index << ") var tex" << index
<< " : texture_2d<u32>;\n"; << " : texture_2d<u32>;\n";
@ -125,8 +138,9 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
} }
} }
wgpu::RenderPipeline CreateSamplingRenderPipeline(std::vector<TestAspect> aspects, wgpu::RenderPipeline CreateSamplingRenderPipeline(
std::vector<uint32_t> components) { std::vector<TestAspectAndSamplerType> aspectAndSamplerTypes,
std::vector<uint32_t> components) {
wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"( wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
@vertex fn main() -> @builtin(position) vec4<f32> { @vertex fn main() -> @builtin(position) vec4<f32> {
return vec4<f32>(0.0, 0.0, 0.0, 1.0); return vec4<f32>(0.0, 0.0, 0.0, 1.0);
@ -138,7 +152,7 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
std::ostringstream shaderOutputStruct; std::ostringstream shaderOutputStruct;
std::ostringstream shaderBody; std::ostringstream shaderBody;
GenerateSamplingShader(aspects, components, shaderSource, shaderBody); GenerateSamplingShader(aspectAndSamplerTypes, components, shaderSource, shaderBody);
shaderSource << "@fragment fn main() -> @location(0) vec4<f32> {\n"; shaderSource << "@fragment fn main() -> @location(0) vec4<f32> {\n";
shaderSource << shaderBody.str() << "return vec4<f32>();\n }"; shaderSource << shaderBody.str() << "return vec4<f32>();\n }";
@ -152,11 +166,12 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
return device.CreateRenderPipeline(&pipelineDescriptor); return device.CreateRenderPipeline(&pipelineDescriptor);
} }
wgpu::ComputePipeline CreateSamplingComputePipeline(std::vector<TestAspect> aspects, wgpu::ComputePipeline CreateSamplingComputePipeline(
std::vector<uint32_t> components) { std::vector<TestAspectAndSamplerType> aspectAndSamplerTypes,
std::vector<uint32_t> components) {
std::ostringstream shaderSource; std::ostringstream shaderSource;
std::ostringstream shaderBody; std::ostringstream shaderBody;
GenerateSamplingShader(aspects, components, shaderSource, shaderBody); GenerateSamplingShader(aspectAndSamplerTypes, components, shaderSource, shaderBody);
shaderSource << "@compute @workgroup_size(1) fn main() { " << shaderBody.str() << "\n}"; shaderSource << "@compute @workgroup_size(1) fn main() { " << shaderBody.str() << "\n}";
@ -169,15 +184,17 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
return device.CreateComputePipeline(&pipelineDescriptor); return device.CreateComputePipeline(&pipelineDescriptor);
} }
wgpu::RenderPipeline CreateSamplingRenderPipeline(std::vector<TestAspect> aspects, wgpu::RenderPipeline CreateSamplingRenderPipeline(
uint32_t componentIndex) { std::vector<TestAspectAndSamplerType> aspectAndSamplerTypes,
return CreateSamplingRenderPipeline(std::move(aspects), uint32_t componentIndex) {
return CreateSamplingRenderPipeline(std::move(aspectAndSamplerTypes),
std::vector<uint32_t>{componentIndex}); std::vector<uint32_t>{componentIndex});
} }
wgpu::ComputePipeline CreateSamplingComputePipeline(std::vector<TestAspect> aspects, wgpu::ComputePipeline CreateSamplingComputePipeline(
uint32_t componentIndex) { std::vector<TestAspectAndSamplerType> aspectAndSamplerTypes,
return CreateSamplingComputePipeline(std::move(aspects), uint32_t componentIndex) {
return CreateSamplingComputePipeline(std::move(aspectAndSamplerTypes),
std::vector<uint32_t>{componentIndex}); std::vector<uint32_t>{componentIndex});
} }
@ -283,7 +300,7 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
} }
template <typename T, typename CheckBufferFn> template <typename T, typename CheckBufferFn>
void DoSamplingTestImpl(TestAspect aspect, void DoSamplingTestImpl(TestAspectAndSamplerType aspectAndSamplerType,
wgpu::RenderPipeline pipeline, wgpu::RenderPipeline pipeline,
wgpu::TextureFormat format, wgpu::TextureFormat format,
std::vector<T> textureValues, std::vector<T> textureValues,
@ -291,11 +308,12 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
CheckBufferFn CheckBuffer) { CheckBufferFn CheckBuffer) {
wgpu::Texture inputTexture = CreateInputTexture(format); wgpu::Texture inputTexture = CreateInputTexture(format);
wgpu::TextureViewDescriptor inputViewDesc = {}; wgpu::TextureViewDescriptor inputViewDesc = {};
switch (aspect) { switch (aspectAndSamplerType) {
case TestAspect::Depth: case TestAspectAndSamplerType::DepthAsDepth:
case TestAspectAndSamplerType::DepthAsFloat:
inputViewDesc.aspect = wgpu::TextureAspect::DepthOnly; inputViewDesc.aspect = wgpu::TextureAspect::DepthOnly;
break; break;
case TestAspect::Stencil: case TestAspectAndSamplerType::StencilAsUint:
inputViewDesc.aspect = wgpu::TextureAspect::StencilOnly; inputViewDesc.aspect = wgpu::TextureAspect::StencilOnly;
break; break;
} }
@ -309,11 +327,12 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
for (size_t i = 0; i < textureValues.size(); ++i) { for (size_t i = 0; i < textureValues.size(); ++i) {
// Set the input depth texture to the provided texture value // Set the input depth texture to the provided texture value
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
switch (aspect) { switch (aspectAndSamplerType) {
case TestAspect::Depth: case TestAspectAndSamplerType::DepthAsDepth:
case TestAspectAndSamplerType::DepthAsFloat:
UpdateInputDepth(commandEncoder, inputTexture, format, textureValues[i]); UpdateInputDepth(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
case TestAspect::Stencil: case TestAspectAndSamplerType::StencilAsUint:
UpdateInputStencil(commandEncoder, inputTexture, format, textureValues[i]); UpdateInputStencil(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
} }
@ -338,7 +357,7 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
} }
template <typename T, typename CheckBufferFn> template <typename T, typename CheckBufferFn>
void DoSamplingTestImpl(TestAspect aspect, void DoSamplingTestImpl(TestAspectAndSamplerType aspectAndSamplerType,
wgpu::ComputePipeline pipeline, wgpu::ComputePipeline pipeline,
wgpu::TextureFormat format, wgpu::TextureFormat format,
std::vector<T> textureValues, std::vector<T> textureValues,
@ -346,11 +365,12 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
CheckBufferFn CheckBuffer) { CheckBufferFn CheckBuffer) {
wgpu::Texture inputTexture = CreateInputTexture(format); wgpu::Texture inputTexture = CreateInputTexture(format);
wgpu::TextureViewDescriptor inputViewDesc = {}; wgpu::TextureViewDescriptor inputViewDesc = {};
switch (aspect) { switch (aspectAndSamplerType) {
case TestAspect::Depth: case TestAspectAndSamplerType::DepthAsDepth:
case TestAspectAndSamplerType::DepthAsFloat:
inputViewDesc.aspect = wgpu::TextureAspect::DepthOnly; inputViewDesc.aspect = wgpu::TextureAspect::DepthOnly;
break; break;
case TestAspect::Stencil: case TestAspectAndSamplerType::StencilAsUint:
inputViewDesc.aspect = wgpu::TextureAspect::StencilOnly; inputViewDesc.aspect = wgpu::TextureAspect::StencilOnly;
break; break;
} }
@ -364,11 +384,12 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
for (size_t i = 0; i < textureValues.size(); ++i) { for (size_t i = 0; i < textureValues.size(); ++i) {
// Set the input depth texture to the provided texture value // Set the input depth texture to the provided texture value
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
switch (aspect) { switch (aspectAndSamplerType) {
case TestAspect::Depth: case TestAspectAndSamplerType::DepthAsDepth:
case TestAspectAndSamplerType::DepthAsFloat:
UpdateInputDepth(commandEncoder, inputTexture, format, textureValues[i]); UpdateInputDepth(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
case TestAspect::Stencil: case TestAspectAndSamplerType::StencilAsUint:
UpdateInputStencil(commandEncoder, inputTexture, format, textureValues[i]); UpdateInputStencil(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
} }
@ -390,12 +411,12 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
} }
template <typename T> template <typename T>
void DoSamplingTest(TestAspect aspect, void DoSamplingTest(TestAspectAndSamplerType aspectAndSamplerType,
wgpu::RenderPipeline pipeline, wgpu::RenderPipeline pipeline,
wgpu::TextureFormat format, wgpu::TextureFormat format,
std::vector<T> textureValues, std::vector<T> textureValues,
T tolerance = {}) { T tolerance = {}) {
DoSamplingTestImpl(aspect, pipeline, format, textureValues, 1, DoSamplingTestImpl(aspectAndSamplerType, pipeline, format, textureValues, 1,
[this, tolerance](T expected, wgpu::Buffer buffer) { [this, tolerance](T expected, wgpu::Buffer buffer) {
EXPECT_BUFFER(buffer, 0, sizeof(T), EXPECT_BUFFER(buffer, 0, sizeof(T),
new ::detail::ExpectEq<T>(expected, tolerance)); new ::detail::ExpectEq<T>(expected, tolerance));
@ -403,12 +424,12 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
} }
template <typename T> template <typename T>
void DoSamplingTest(TestAspect aspect, void DoSamplingTest(TestAspectAndSamplerType aspectAndSamplerType,
wgpu::ComputePipeline pipeline, wgpu::ComputePipeline pipeline,
wgpu::TextureFormat format, wgpu::TextureFormat format,
std::vector<T> textureValues, std::vector<T> textureValues,
T tolerance = {}) { T tolerance = {}) {
DoSamplingTestImpl(aspect, pipeline, format, textureValues, 1, DoSamplingTestImpl(aspectAndSamplerType, pipeline, format, textureValues, 1,
[this, tolerance](T expected, wgpu::Buffer buffer) { [this, tolerance](T expected, wgpu::Buffer buffer) {
EXPECT_BUFFER(buffer, 0, sizeof(T), EXPECT_BUFFER(buffer, 0, sizeof(T),
new ::detail::ExpectEq<T>(expected, tolerance)); new ::detail::ExpectEq<T>(expected, tolerance));
@ -447,22 +468,24 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
uint32_t mExpected; uint32_t mExpected;
}; };
void DoSamplingExtraStencilComponentsRenderTest(TestAspect aspect, void DoSamplingExtraStencilComponentsRenderTest(TestAspectAndSamplerType aspectAndSamplerType,
wgpu::TextureFormat format, wgpu::TextureFormat format,
std::vector<uint8_t> textureValues) { std::vector<uint8_t> textureValues) {
DoSamplingTestImpl(aspect, DoSamplingTestImpl(aspectAndSamplerType,
CreateSamplingRenderPipeline({TestAspect::Stencil}, {0, 1, 2, 3}), CreateSamplingRenderPipeline({TestAspectAndSamplerType::StencilAsUint},
{0, 1, 2, 3}),
format, textureValues, 4, [&](uint32_t expected, wgpu::Buffer buffer) { format, textureValues, 4, [&](uint32_t expected, wgpu::Buffer buffer) {
EXPECT_BUFFER(buffer, 0, 4 * sizeof(uint32_t), EXPECT_BUFFER(buffer, 0, 4 * sizeof(uint32_t),
new ExtraStencilComponentsExpectation(expected)); new ExtraStencilComponentsExpectation(expected));
}); });
} }
void DoSamplingExtraStencilComponentsComputeTest(TestAspect aspect, void DoSamplingExtraStencilComponentsComputeTest(TestAspectAndSamplerType aspectAndSamplerType,
wgpu::TextureFormat format, wgpu::TextureFormat format,
std::vector<uint8_t> textureValues) { std::vector<uint8_t> textureValues) {
DoSamplingTestImpl(aspect, DoSamplingTestImpl(aspectAndSamplerType,
CreateSamplingComputePipeline({TestAspect::Stencil}, {0, 1, 2, 3}), CreateSamplingComputePipeline({TestAspectAndSamplerType::StencilAsUint},
{0, 1, 2, 3}),
format, textureValues, 4, [&](uint32_t expected, wgpu::Buffer buffer) { format, textureValues, 4, [&](uint32_t expected, wgpu::Buffer buffer) {
EXPECT_BUFFER(buffer, 0, 4 * sizeof(uint32_t), EXPECT_BUFFER(buffer, 0, 4 * sizeof(uint32_t),
new ExtraStencilComponentsExpectation(expected)); new ExtraStencilComponentsExpectation(expected));
@ -604,10 +627,10 @@ TEST_P(DepthStencilSamplingTest, SampleExtraComponents) {
wgpu::TextureFormat format = GetParam().mTextureFormat; wgpu::TextureFormat format = GetParam().mTextureFormat;
DoSamplingExtraStencilComponentsRenderTest(TestAspect::Stencil, format, DoSamplingExtraStencilComponentsRenderTest(TestAspectAndSamplerType::StencilAsUint, format,
{uint8_t(42), uint8_t(37)}); {uint8_t(42), uint8_t(37)});
DoSamplingExtraStencilComponentsComputeTest(TestAspect::Stencil, format, DoSamplingExtraStencilComponentsComputeTest(TestAspectAndSamplerType::StencilAsUint, format,
{uint8_t(42), uint8_t(37)}); {uint8_t(42), uint8_t(37)});
} }
@ -628,8 +651,8 @@ TEST_P(DepthStencilSamplingTest, SampleDepthAndStencilRender) {
// With render pipeline // With render pipeline
{ {
wgpu::RenderPipeline pipeline = wgpu::RenderPipeline pipeline = CreateSamplingRenderPipeline(
CreateSamplingRenderPipeline({TestAspect::Depth, TestAspect::Stencil}, 0); {TestAspectAndSamplerType::DepthAsDepth, TestAspectAndSamplerType::StencilAsUint}, 0);
wgpu::Buffer depthOutput = CreateOutputBuffer(); wgpu::Buffer depthOutput = CreateOutputBuffer();
wgpu::Buffer stencilOutput = CreateOutputBuffer(); wgpu::Buffer stencilOutput = CreateOutputBuffer();
@ -681,8 +704,8 @@ TEST_P(DepthStencilSamplingTest, SampleDepthAndStencilRender) {
// With compute pipeline // With compute pipeline
{ {
wgpu::ComputePipeline pipeline = wgpu::ComputePipeline pipeline = CreateSamplingComputePipeline(
CreateSamplingComputePipeline({TestAspect::Depth, TestAspect::Stencil}, 0); {TestAspectAndSamplerType::DepthAsDepth, TestAspectAndSamplerType::StencilAsUint}, 0);
wgpu::Buffer depthOutput = CreateOutputBuffer(); wgpu::Buffer depthOutput = CreateOutputBuffer();
wgpu::Buffer stencilOutput = CreateOutputBuffer(); wgpu::Buffer stencilOutput = CreateOutputBuffer();
@ -735,11 +758,19 @@ TEST_P(DepthSamplingTest, SampleDepthOnly) {
float tolerance = format == wgpu::TextureFormat::Depth16Unorm ? 0.001f : 0.0f; float tolerance = format == wgpu::TextureFormat::Depth16Unorm ? 0.001f : 0.0f;
// Test 0, between [0, 1], and 1. // Test 0, between [0, 1], and 1.
DoSamplingTest(TestAspect::Depth, CreateSamplingRenderPipeline({TestAspect::Depth}, 0), format, DoSamplingTest(TestAspectAndSamplerType::DepthAsDepth,
kNormalizedTextureValues, tolerance); CreateSamplingRenderPipeline({TestAspectAndSamplerType::DepthAsDepth}, 0),
format, kNormalizedTextureValues, tolerance);
DoSamplingTest(TestAspectAndSamplerType::DepthAsFloat,
CreateSamplingRenderPipeline({TestAspectAndSamplerType::DepthAsFloat}, 0),
format, kNormalizedTextureValues, tolerance);
DoSamplingTest(TestAspect::Depth, CreateSamplingComputePipeline({TestAspect::Depth}, 0), format, DoSamplingTest(TestAspectAndSamplerType::DepthAsDepth,
kNormalizedTextureValues, tolerance); CreateSamplingComputePipeline({TestAspectAndSamplerType::DepthAsDepth}, 0),
format, kNormalizedTextureValues, tolerance);
DoSamplingTest(TestAspectAndSamplerType::DepthAsFloat,
CreateSamplingComputePipeline({TestAspectAndSamplerType::DepthAsFloat}, 0),
format, kNormalizedTextureValues, tolerance);
} }
// Test that sampling in a render pipeline with all of the compare functions works. // Test that sampling in a render pipeline with all of the compare functions works.
@ -771,10 +802,12 @@ TEST_P(StencilSamplingTest, SampleStencilOnly) {
wgpu::TextureFormat format = GetParam().mTextureFormat; wgpu::TextureFormat format = GetParam().mTextureFormat;
DoSamplingTest(TestAspect::Stencil, CreateSamplingRenderPipeline({TestAspect::Stencil}, 0), DoSamplingTest(TestAspectAndSamplerType::StencilAsUint,
CreateSamplingRenderPipeline({TestAspectAndSamplerType::StencilAsUint}, 0),
format, kStencilValues); format, kStencilValues);
DoSamplingTest(TestAspect::Stencil, CreateSamplingComputePipeline({TestAspect::Stencil}, 0), DoSamplingTest(TestAspectAndSamplerType::StencilAsUint,
CreateSamplingComputePipeline({TestAspectAndSamplerType::StencilAsUint}, 0),
format, kStencilValues); format, kStencilValues);
} }

View File

@ -78,6 +78,14 @@ class BindGroupValidationTest : public ValidationTest {
return desc; return desc;
} }
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
return dawnAdapter.CreateDevice(&descriptor);
}
wgpu::Buffer mUBO; wgpu::Buffer mUBO;
wgpu::Buffer mSSBO; wgpu::Buffer mSSBO;
wgpu::Sampler mSampler; wgpu::Sampler mSampler;
@ -455,7 +463,8 @@ TEST_F(BindGroupValidationTest, StorageTextureUsage) {
// Check that a texture must have the correct sample type // Check that a texture must have the correct sample type
TEST_F(BindGroupValidationTest, TextureSampleType) { TEST_F(BindGroupValidationTest, TextureSampleType) {
auto DoTest = [this](bool success, wgpu::TextureFormat format, auto DoTest = [this](bool success, wgpu::TextureFormat format,
wgpu::TextureSampleType sampleType) { wgpu::TextureSampleType sampleType,
wgpu::TextureAspect aspect = wgpu::TextureAspect::All) {
wgpu::BindGroupLayout layout = wgpu::BindGroupLayout layout =
utils::MakeBindGroupLayout(device, {{0, wgpu::ShaderStage::Fragment, sampleType}}); utils::MakeBindGroupLayout(device, {{0, wgpu::ShaderStage::Fragment, sampleType}});
@ -464,7 +473,9 @@ TEST_F(BindGroupValidationTest, TextureSampleType) {
descriptor.usage = wgpu::TextureUsage::TextureBinding; descriptor.usage = wgpu::TextureUsage::TextureBinding;
descriptor.format = format; descriptor.format = format;
wgpu::TextureView view = device.CreateTexture(&descriptor).CreateView(); wgpu::TextureViewDescriptor viewDescriptor;
viewDescriptor.aspect = aspect;
wgpu::TextureView view = device.CreateTexture(&descriptor).CreateView(&viewDescriptor);
if (success) { if (success) {
utils::MakeBindGroup(device, layout, {{0, view}}); utils::MakeBindGroup(device, layout, {{0, view}});
@ -487,13 +498,77 @@ TEST_F(BindGroupValidationTest, TextureSampleType) {
DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Uint); DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Uint);
DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Sint); DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Sint);
// Test that Depth32Float is only compatible with depth. // Test that Depth16Unorm is only compatible with depth/unfilterable-float.
DoTest(false, wgpu::TextureFormat::Depth16Unorm, wgpu::TextureSampleType::Float);
DoTest(true, wgpu::TextureFormat::Depth16Unorm, wgpu::TextureSampleType::UnfilterableFloat);
DoTest(true, wgpu::TextureFormat::Depth16Unorm, wgpu::TextureSampleType::Depth);
DoTest(false, wgpu::TextureFormat::Depth16Unorm, wgpu::TextureSampleType::Uint);
DoTest(false, wgpu::TextureFormat::Depth16Unorm, wgpu::TextureSampleType::Sint);
// Test that Depth24Plus is only compatible with depth/unfilterable-float.
DoTest(false, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::Float);
DoTest(true, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::UnfilterableFloat);
DoTest(true, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::Depth);
DoTest(false, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::Uint);
DoTest(false, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::Sint);
// Test that Depth24PlusStencil8 with depth aspect is only compatible with
// depth/unfilterable-float.
DoTest(false, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Float,
wgpu::TextureAspect::DepthOnly);
DoTest(true, wgpu::TextureFormat::Depth24PlusStencil8,
wgpu::TextureSampleType::UnfilterableFloat, wgpu::TextureAspect::DepthOnly);
DoTest(true, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Depth,
wgpu::TextureAspect::DepthOnly);
DoTest(false, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Uint,
wgpu::TextureAspect::DepthOnly);
DoTest(false, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Sint,
wgpu::TextureAspect::DepthOnly);
// Test that Depth24PlusStencil8 with stencil aspect is only compatible with uint.
DoTest(false, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Float,
wgpu::TextureAspect::StencilOnly);
DoTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
wgpu::TextureSampleType::UnfilterableFloat, wgpu::TextureAspect::StencilOnly);
DoTest(false, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Depth,
wgpu::TextureAspect::StencilOnly);
DoTest(true, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Uint,
wgpu::TextureAspect::StencilOnly);
DoTest(false, wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureSampleType::Sint,
wgpu::TextureAspect::StencilOnly);
// Test that Depth32Float is only compatible with depth/unfilterable-float.
DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Float); DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Float);
DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::UnfilterableFloat); DoTest(true, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::UnfilterableFloat);
DoTest(true, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Depth); DoTest(true, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Depth);
DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Uint); DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Uint);
DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Sint); DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Sint);
// Test that Depth32FloatStencil8 with depth aspect is only compatible with
// depth/unfilterable-float.
DoTest(false, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Float,
wgpu::TextureAspect::DepthOnly);
DoTest(true, wgpu::TextureFormat::Depth32FloatStencil8,
wgpu::TextureSampleType::UnfilterableFloat, wgpu::TextureAspect::DepthOnly);
DoTest(true, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Depth,
wgpu::TextureAspect::DepthOnly);
DoTest(false, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Uint,
wgpu::TextureAspect::DepthOnly);
DoTest(false, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Sint,
wgpu::TextureAspect::DepthOnly);
// Test that Depth32FloatStencil8 with stencil aspect is only compatible with uint.
DoTest(false, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Float,
wgpu::TextureAspect::StencilOnly);
DoTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
wgpu::TextureSampleType::UnfilterableFloat, wgpu::TextureAspect::StencilOnly);
DoTest(false, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Depth,
wgpu::TextureAspect::StencilOnly);
DoTest(true, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Uint,
wgpu::TextureAspect::StencilOnly);
DoTest(false, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureSampleType::Sint,
wgpu::TextureAspect::StencilOnly);
// Test that RG8Uint is only compatible with uint // Test that RG8Uint is only compatible with uint
DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Float); DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Float);
DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::UnfilterableFloat); DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::UnfilterableFloat);