mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-18 09:25:25 +00:00
Validate textures with filtering/non-filtering/comparison samplers
Renames dawn_native::ComponentTypeBit to SampleTypeBit and makes the bitmask match wgpu::TextureSampleType. wgpu::TextureComponentType should be removed in a follow-up CL. The Format table is augmented with float/unfilterable-float information so that textures can be validated against the BGLEntry's TextureSampleType. EntryPointMetadata::ShaderBindingInfo no longer inherits BindingInfo because the two types are diverging further. Most notably, this CL reflects from Tint the supported SampleTypeBits for texture bindings. This bitset is validated against the bind group layout. Adds an isFiltering getter to SamplerBase. A filtering sampler must not be used with a non-filtering sampler binding. Lastly, the CL reflects sampler/texture pairs from Tint and validates an entrypoint against the pipeline layout that a filtering sampler is not used with an unfilterable-float texture binding. Bug: dawn:367 Change-Id: If9f2c0d8fbad5641c2ecc30615a3c68a6ed6150a Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/56521 Reviewed-by: Jiawei Shao <jiawei.shao@intel.com> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
@@ -435,20 +435,61 @@ TEST_F(BindGroupValidationTest, StorageTextureUsage) {
|
||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
|
||||
}
|
||||
|
||||
// Check that a texture must have the correct component type
|
||||
TEST_F(BindGroupValidationTest, TextureComponentType) {
|
||||
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
|
||||
// Check that a texture must have the correct sample type
|
||||
TEST_F(BindGroupValidationTest, TextureSampleType) {
|
||||
auto DoTest = [this](bool success, wgpu::TextureFormat format,
|
||||
wgpu::TextureSampleType sampleType) {
|
||||
wgpu::BindGroupLayout layout =
|
||||
utils::MakeBindGroupLayout(device, {{0, wgpu::ShaderStage::Fragment, sampleType}});
|
||||
|
||||
// Control case: setting a Float typed texture view works.
|
||||
utils::MakeBindGroup(device, layout, {{0, mSampledTextureView}});
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.size = {4, 4, 1};
|
||||
descriptor.usage = wgpu::TextureUsage::Sampled;
|
||||
descriptor.format = format;
|
||||
|
||||
// Make a Uint component typed texture and try to set it to a Float component binding.
|
||||
wgpu::Texture uintTexture =
|
||||
CreateTexture(wgpu::TextureUsage::Sampled, wgpu::TextureFormat::RGBA8Uint, 1);
|
||||
wgpu::TextureView uintTextureView = uintTexture.CreateView();
|
||||
wgpu::TextureView view = device.CreateTexture(&descriptor).CreateView();
|
||||
|
||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, uintTextureView}}));
|
||||
if (success) {
|
||||
utils::MakeBindGroup(device, layout, {{0, view}});
|
||||
} else {
|
||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
|
||||
}
|
||||
};
|
||||
|
||||
// Test that RGBA8Unorm is only compatible with float/unfilterable-float
|
||||
DoTest(true, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Float);
|
||||
DoTest(true, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::UnfilterableFloat);
|
||||
DoTest(false, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Depth);
|
||||
DoTest(false, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Uint);
|
||||
DoTest(false, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Sint);
|
||||
|
||||
// Test that R32Float is only compatible with unfilterable-float
|
||||
DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Float);
|
||||
DoTest(true, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::UnfilterableFloat);
|
||||
DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Depth);
|
||||
DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Uint);
|
||||
DoTest(false, wgpu::TextureFormat::R32Float, wgpu::TextureSampleType::Sint);
|
||||
|
||||
// Test that Depth32Float is only compatible with float/unfilterable-float/depth
|
||||
DoTest(true, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Float);
|
||||
DoTest(true, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::UnfilterableFloat);
|
||||
DoTest(true, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Depth);
|
||||
DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Uint);
|
||||
DoTest(false, wgpu::TextureFormat::Depth32Float, wgpu::TextureSampleType::Sint);
|
||||
|
||||
// Test that RG8Uint is only compatible with uint
|
||||
DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Float);
|
||||
DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::UnfilterableFloat);
|
||||
DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Depth);
|
||||
DoTest(true, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Uint);
|
||||
DoTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Sint);
|
||||
|
||||
// Test that R16Sint is only compatible with sint
|
||||
DoTest(false, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Float);
|
||||
DoTest(false, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::UnfilterableFloat);
|
||||
DoTest(false, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Depth);
|
||||
DoTest(false, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Uint);
|
||||
DoTest(true, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Sint);
|
||||
}
|
||||
|
||||
// Test which depth-stencil formats are allowed to be sampled (all).
|
||||
@@ -493,36 +534,6 @@ TEST_F(BindGroupValidationTest, SamplingDepthStencilTexture) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check that a texture must have a correct format for DepthComparison
|
||||
TEST_F(BindGroupValidationTest, TextureComponentTypeDepthComparison) {
|
||||
wgpu::BindGroupLayout depthLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});
|
||||
|
||||
// Control case: setting a depth texture works.
|
||||
wgpu::Texture depthTexture =
|
||||
CreateTexture(wgpu::TextureUsage::Sampled, wgpu::TextureFormat::Depth32Float, 1);
|
||||
utils::MakeBindGroup(device, depthLayout, {{0, depthTexture.CreateView()}});
|
||||
|
||||
// Error case: setting a Float typed texture view fails.
|
||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, depthLayout, {{0, mSampledTextureView}}));
|
||||
}
|
||||
|
||||
// Check that a depth texture is allowed to be used for both TextureComponentType::Float and
|
||||
// ::DepthComparison
|
||||
TEST_F(BindGroupValidationTest, TextureComponentTypeForDepthTexture) {
|
||||
wgpu::BindGroupLayout depthLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});
|
||||
|
||||
wgpu::BindGroupLayout floatLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
|
||||
|
||||
wgpu::Texture depthTexture =
|
||||
CreateTexture(wgpu::TextureUsage::Sampled, wgpu::TextureFormat::Depth32Float, 1);
|
||||
|
||||
utils::MakeBindGroup(device, depthLayout, {{0, depthTexture.CreateView()}});
|
||||
utils::MakeBindGroup(device, floatLayout, {{0, depthTexture.CreateView()}});
|
||||
}
|
||||
|
||||
// Check that a texture must have the correct dimension
|
||||
TEST_F(BindGroupValidationTest, TextureDimension) {
|
||||
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
|
||||
@@ -2324,7 +2335,7 @@ TEST_F(BindingsValidationTest, BindGroupsWithLessBindingsThanPipelineLayout) {
|
||||
TestComputePassBindings(bg.data(), kBindingNum, computePipeline, false);
|
||||
}
|
||||
|
||||
class ComparisonSamplerBindingTest : public ValidationTest {
|
||||
class SamplerTypeBindingTest : public ValidationTest {
|
||||
protected:
|
||||
wgpu::RenderPipeline CreateFragmentPipeline(wgpu::BindGroupLayout* bindGroupLayout,
|
||||
const char* fragmentSource) {
|
||||
@@ -2345,10 +2356,13 @@ class ComparisonSamplerBindingTest : public ValidationTest {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(crbug.com/dawn/367): Disabled until we can perform shader analysis
|
||||
// of which samplers are comparison samplers.
|
||||
TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
|
||||
// Test that sampler binding works with normal sampler in the shader.
|
||||
// Test that the use of sampler and comparison_sampler in the shader must match the bind group
|
||||
// layout.
|
||||
TEST_F(SamplerTypeBindingTest, ShaderAndBGLMatches) {
|
||||
// Tint needed for proper shader reflection.
|
||||
DAWN_SKIP_TEST_IF(!HasToggleEnabled("use_tint_generator"));
|
||||
|
||||
// Test that a filtering sampler binding works with normal sampler in the shader.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});
|
||||
@@ -2356,11 +2370,23 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[stage(fragment)]] fn main() {
|
||||
let s : sampler = mySampler;
|
||||
ignore(mySampler);
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that comparison sampler binding works with shadow sampler in the shader.
|
||||
// Test that a non-filtering sampler binding works with normal sampler in the shader.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering}});
|
||||
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(mySampler);
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that comparison sampler binding works with comparison sampler in the shader.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Comparison}});
|
||||
@@ -2368,11 +2394,11 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler_comparison;
|
||||
[[stage(fragment)]] fn main() {
|
||||
let s : sampler_comparison = mySampler;
|
||||
ignore(mySampler);
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that sampler binding does not work with comparison sampler in the shader.
|
||||
// Test that filtering sampler binding does not work with comparison sampler in the shader.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});
|
||||
@@ -2380,7 +2406,19 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
|
||||
ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler_comparison;
|
||||
[[stage(fragment)]] fn main() {
|
||||
let s : sampler_comparison = mySampler;
|
||||
ignore(mySampler);
|
||||
})"));
|
||||
}
|
||||
|
||||
// Test that non-filtering sampler binding does not work with comparison sampler in the shader.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering}});
|
||||
|
||||
ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler_comparison;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(mySampler);
|
||||
})"));
|
||||
}
|
||||
|
||||
@@ -2392,12 +2430,110 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
|
||||
ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[stage(fragment)]] fn main() {
|
||||
let s : sampler = mySampler;
|
||||
ignore(mySampler);
|
||||
})"));
|
||||
}
|
||||
|
||||
// Test that a filtering sampler can be used to sample a float texture.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
|
||||
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
|
||||
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[group(0), binding(1)]] var myTexture: texture_2d<f32>;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSample(myTexture, mySampler, vec2<f32>(0.0, 0.0)));
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that a non-filtering sampler can be used to sample a float texture.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
|
||||
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
|
||||
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[group(0), binding(1)]] var myTexture: texture_2d<f32>;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSample(myTexture, mySampler, vec2<f32>(0.0, 0.0)));
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that a filtering sampler can be used to sample a depth texture.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
|
||||
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});
|
||||
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[group(0), binding(1)]] var myTexture: texture_depth_2d;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSample(myTexture, mySampler, vec2<f32>(0.0, 0.0)));
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that a non-filtering sampler can be used to sample a depth texture.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
|
||||
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});
|
||||
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[group(0), binding(1)]] var myTexture: texture_depth_2d;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSample(myTexture, mySampler, vec2<f32>(0.0, 0.0)));
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that a comparison sampler can be used to sample a depth texture.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Comparison},
|
||||
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});
|
||||
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler_comparison;
|
||||
[[group(0), binding(1)]] var myTexture: texture_depth_2d;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSampleCompare(myTexture, mySampler, vec2<f32>(0.0, 0.0), 0.0));
|
||||
})");
|
||||
}
|
||||
|
||||
// Test that a filtering sampler cannot be used to sample an unfilterable-float texture.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
|
||||
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::UnfilterableFloat}});
|
||||
|
||||
ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[group(0), binding(1)]] var myTexture: texture_2d<f32>;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSample(myTexture, mySampler, vec2<f32>(0.0, 0.0)));
|
||||
})"));
|
||||
}
|
||||
|
||||
// Test that a non-filtering sampler can be used to sample an unfilterable-float texture.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
|
||||
{1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::UnfilterableFloat}});
|
||||
|
||||
CreateFragmentPipeline(&bindGroupLayout, R"(
|
||||
[[group(0), binding(0)]] var mySampler: sampler;
|
||||
[[group(0), binding(1)]] var myTexture: texture_2d<f32>;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSample(myTexture, mySampler, vec2<f32>(0.0, 0.0)));
|
||||
})");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ComparisonSamplerBindingTest, SamplerAndBindGroupMatches) {
|
||||
TEST_F(SamplerTypeBindingTest, SamplerAndBindGroupMatches) {
|
||||
// Test that sampler binding works with normal sampler.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
@@ -2436,4 +2572,59 @@ TEST_F(ComparisonSamplerBindingTest, SamplerAndBindGroupMatches) {
|
||||
ASSERT_DEVICE_ERROR(
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
|
||||
}
|
||||
|
||||
// Test that filtering sampler binding works with a filtering or non-filtering sampler.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});
|
||||
|
||||
// Test each filter member
|
||||
{
|
||||
wgpu::SamplerDescriptor desc;
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}});
|
||||
}
|
||||
{
|
||||
wgpu::SamplerDescriptor desc;
|
||||
desc.magFilter = wgpu::FilterMode::Linear;
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}});
|
||||
}
|
||||
{
|
||||
wgpu::SamplerDescriptor desc;
|
||||
desc.mipmapFilter = wgpu::FilterMode::Linear;
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}});
|
||||
}
|
||||
|
||||
// Test non-filtering sampler
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler()}});
|
||||
}
|
||||
|
||||
// Test that non-filtering sampler binding does not work with a filtering sampler.
|
||||
{
|
||||
wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering}});
|
||||
|
||||
// Test each filter member
|
||||
{
|
||||
wgpu::SamplerDescriptor desc;
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
ASSERT_DEVICE_ERROR(
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
|
||||
}
|
||||
{
|
||||
wgpu::SamplerDescriptor desc;
|
||||
desc.magFilter = wgpu::FilterMode::Linear;
|
||||
ASSERT_DEVICE_ERROR(
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
|
||||
}
|
||||
{
|
||||
wgpu::SamplerDescriptor desc;
|
||||
desc.mipmapFilter = wgpu::FilterMode::Linear;
|
||||
ASSERT_DEVICE_ERROR(
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
|
||||
}
|
||||
|
||||
// Test non-filtering sampler
|
||||
utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler()}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +139,122 @@ TEST_F(GetBindGroupLayoutTests, DefaultShaderStageAndDynamicOffsets) {
|
||||
EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
}
|
||||
|
||||
TEST_F(GetBindGroupLayoutTests, DefaultTextureSampleType) {
|
||||
// This test works assuming Dawn Native's object deduplication.
|
||||
// Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
|
||||
// Native.
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
// Relies on Tint shader reflection.
|
||||
DAWN_SKIP_TEST_IF(!HasToggleEnabled("use_tint_generator"));
|
||||
|
||||
wgpu::BindGroupLayout filteringBGL = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
|
||||
wgpu::TextureSampleType::Float},
|
||||
{1, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
|
||||
wgpu::SamplerBindingType::Filtering}});
|
||||
|
||||
wgpu::BindGroupLayout nonFilteringBGL = utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
|
||||
wgpu::TextureSampleType::UnfilterableFloat},
|
||||
{1, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
|
||||
wgpu::SamplerBindingType::Filtering}});
|
||||
|
||||
wgpu::ShaderModule emptyVertexModule = utils::CreateShaderModule(device, R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
[[group(0), binding(1)]] var mySampler : sampler;
|
||||
[[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
ignore(myTexture);
|
||||
ignore(mySampler);
|
||||
return vec4<f32>();
|
||||
})");
|
||||
|
||||
wgpu::ShaderModule textureLoadVertexModule = utils::CreateShaderModule(device, R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
[[group(0), binding(1)]] var mySampler : sampler;
|
||||
[[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
ignore(textureLoad(myTexture, vec2<i32>(), 0));
|
||||
ignore(mySampler);
|
||||
return vec4<f32>();
|
||||
})");
|
||||
|
||||
wgpu::ShaderModule textureSampleVertexModule = utils::CreateShaderModule(device, R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
[[group(0), binding(1)]] var mySampler : sampler;
|
||||
[[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
ignore(textureSampleLevel(myTexture, mySampler, vec2<f32>(), 0.0));
|
||||
return vec4<f32>();
|
||||
})");
|
||||
|
||||
wgpu::ShaderModule unusedTextureFragmentModule = utils::CreateShaderModule(device, R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
[[group(0), binding(1)]] var mySampler : sampler;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(myTexture);
|
||||
ignore(mySampler);
|
||||
})");
|
||||
|
||||
wgpu::ShaderModule textureLoadFragmentModule = utils::CreateShaderModule(device, R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
[[group(0), binding(1)]] var mySampler : sampler;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureLoad(myTexture, vec2<i32>(), 0));
|
||||
ignore(mySampler);
|
||||
})");
|
||||
|
||||
wgpu::ShaderModule textureSampleFragmentModule = utils::CreateShaderModule(device, R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
[[group(0), binding(1)]] var mySampler : sampler;
|
||||
[[stage(fragment)]] fn main() {
|
||||
ignore(textureSample(myTexture, mySampler, vec2<f32>()));
|
||||
})");
|
||||
|
||||
auto BGLFromModules = [this](wgpu::ShaderModule vertexModule,
|
||||
wgpu::ShaderModule fragmentModule) {
|
||||
utils::ComboRenderPipelineDescriptor descriptor;
|
||||
descriptor.vertex.module = vertexModule;
|
||||
descriptor.cFragment.module = fragmentModule;
|
||||
return device.CreateRenderPipeline(&descriptor).GetBindGroupLayout(0);
|
||||
};
|
||||
|
||||
// Textures not used default to non-filtering
|
||||
EXPECT_EQ(BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(),
|
||||
nonFilteringBGL.Get());
|
||||
EXPECT_NE(BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(),
|
||||
filteringBGL.Get());
|
||||
|
||||
// Textures used with textureLoad default to non-filtering
|
||||
EXPECT_EQ(BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(),
|
||||
nonFilteringBGL.Get());
|
||||
EXPECT_NE(BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(),
|
||||
filteringBGL.Get());
|
||||
|
||||
// Textures used with textureLoad on both stages default to non-filtering
|
||||
EXPECT_EQ(BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(),
|
||||
nonFilteringBGL.Get());
|
||||
EXPECT_NE(BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(),
|
||||
filteringBGL.Get());
|
||||
|
||||
// Textures used with textureSample default to filtering
|
||||
EXPECT_NE(BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(),
|
||||
nonFilteringBGL.Get());
|
||||
EXPECT_EQ(BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(),
|
||||
filteringBGL.Get());
|
||||
EXPECT_NE(BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(),
|
||||
nonFilteringBGL.Get());
|
||||
EXPECT_EQ(BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(),
|
||||
filteringBGL.Get());
|
||||
|
||||
// Textures used with both textureLoad and textureSample default to filtering
|
||||
EXPECT_NE(BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(),
|
||||
nonFilteringBGL.Get());
|
||||
EXPECT_EQ(BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(),
|
||||
filteringBGL.Get());
|
||||
EXPECT_NE(BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(),
|
||||
nonFilteringBGL.Get());
|
||||
EXPECT_EQ(BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(),
|
||||
filteringBGL.Get());
|
||||
}
|
||||
|
||||
// Test GetBindGroupLayout works with a compute pipeline
|
||||
TEST_F(GetBindGroupLayoutTests, ComputePipeline) {
|
||||
// This test works assuming Dawn Native's object deduplication.
|
||||
@@ -240,7 +356,7 @@ TEST_F(GetBindGroupLayoutTests, BindingType) {
|
||||
binding.buffer.type = wgpu::BufferBindingType::Undefined;
|
||||
binding.buffer.minBindingSize = 0;
|
||||
{
|
||||
binding.texture.sampleType = wgpu::TextureSampleType::Float;
|
||||
binding.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
|
||||
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
|
||||
@@ -311,7 +427,7 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) {
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
binding.texture.sampleType = wgpu::TextureSampleType::Float;
|
||||
binding.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
|
||||
|
||||
wgpu::BindGroupLayoutDescriptor desc = {};
|
||||
desc.entryCount = 1;
|
||||
@@ -400,7 +516,7 @@ TEST_F(GetBindGroupLayoutTests, TextureComponentType) {
|
||||
desc.entries = &binding;
|
||||
|
||||
{
|
||||
binding.texture.sampleType = wgpu::TextureSampleType::Float;
|
||||
binding.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
|
||||
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
|
||||
[[group(0), binding(0)]] var myTexture : texture_2d<f32>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user