From f463a20291420babb886157bf8f24f179804a893 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Wed, 21 Aug 2019 12:16:33 +0000 Subject: [PATCH] Add BGLBinding::textureComponentType This is a new compatibility constraint that the texture component type must match between what's declared in the shader and the bind group. - Format is updated to include the component type of the format. - Validation and state tracking is updated to reflect the new BGLBinding member. - TextureFormat tests are updated to pass with the added validation and to remove a redundant enum definition. - BGLBinding::multisampled validation is added because it was next to modified code for the BGLBinding::textureComponentType validation. - A redundant BGL caching test was removed. BUG=dawn:128 Change-Id: I9c4ae92062769c3ecf74caf46f27415344dfad77 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10281 Reviewed-by: Corentin Wallez Reviewed-by: Kai Ninomiya Reviewed-by: Austin Eng Commit-Queue: Corentin Wallez --- dawn.json | 13 +- src/dawn_native/BindGroup.cpp | 20 ++- src/dawn_native/BindGroupLayout.cpp | 8 +- src/dawn_native/BindGroupLayout.h | 1 + src/dawn_native/Format.cpp | 107 +++++++----- src/dawn_native/Format.h | 9 + src/tests/end2end/ObjectCachingTests.cpp | 19 +- src/tests/end2end/TextureFormatTests.cpp | 163 +++++++++--------- .../validation/BindGroupValidationTests.cpp | 42 +++-- .../unittests/wire/WireArgumentTests.cpp | 8 +- 10 files changed, 240 insertions(+), 150 deletions(-) diff --git a/dawn.json b/dawn.json index a2102b32ae..77ef423bc7 100644 --- a/dawn.json +++ b/dawn.json @@ -56,8 +56,9 @@ {"name": "binding", "type": "uint32_t"}, {"name": "visibility", "type": "shader stage bit"}, {"name": "type", "type": "binding type"}, - {"name": "dynamic", "type": "bool", "default": "false" }, - {"name": "multisampled", "type": "bool", "default": "false" } + {"name": "dynamic", "type": "bool", "default": "false"}, + {"name": "multisampled", "type": "bool", "default": "false"}, + {"name": "texture component type", "type": "texture component type", "default": "float"} ] }, "bind group layout descriptor": { @@ -1152,6 +1153,14 @@ {"value": 2, "name": "depth only"} ] }, + "texture component type": { + "category": "enum", + "values": [ + {"value": 0, "name": "float"}, + {"value": 1, "name": "sint"}, + {"value": 2, "name": "uint"} + ] + }, "texture copy view": { "category": "structure", "extensible": true, diff --git a/src/dawn_native/BindGroup.cpp b/src/dawn_native/BindGroup.cpp index da018e1230..c2b832b840 100644 --- a/src/dawn_native/BindGroup.cpp +++ b/src/dawn_native/BindGroup.cpp @@ -63,17 +63,29 @@ namespace dawn_native { MaybeError ValidateTextureBinding(const DeviceBase* device, const BindGroupBinding& binding, - dawn::TextureUsageBit requiredUsage) { + dawn::TextureUsageBit requiredUsage, + bool multisampledBinding, + dawn::TextureComponentType requiredComponentType) { if (binding.textureView == nullptr || binding.sampler != nullptr || binding.buffer != nullptr) { return DAWN_VALIDATION_ERROR("expected texture binding"); } DAWN_TRY(device->ValidateObject(binding.textureView)); - if (!(binding.textureView->GetTexture()->GetUsage() & requiredUsage)) { + TextureBase* texture = binding.textureView->GetTexture(); + + if (!(texture->GetUsage() & requiredUsage)) { return DAWN_VALIDATION_ERROR("texture binding usage mismatch"); } + if (texture->IsMultisampledTexture() != multisampledBinding) { + return DAWN_VALIDATION_ERROR("texture multisampling mismatch"); + } + + if (!texture->GetFormat().HasComponentType(requiredComponentType)) { + return DAWN_VALIDATION_ERROR("texture component type usage mismatch"); + } + return {}; } @@ -134,7 +146,9 @@ namespace dawn_native { break; case dawn::BindingType::SampledTexture: DAWN_TRY( - ValidateTextureBinding(device, binding, dawn::TextureUsageBit::Sampled)); + ValidateTextureBinding(device, binding, dawn::TextureUsageBit::Sampled, + layoutInfo.multisampled[bindingIndex], + layoutInfo.textureComponentTypes[bindingIndex])); break; case dawn::BindingType::Sampler: DAWN_TRY(ValidateSamplerBinding(device, binding)); diff --git a/src/dawn_native/BindGroupLayout.cpp b/src/dawn_native/BindGroupLayout.cpp index ff9acfa4a7..85e5391ce6 100644 --- a/src/dawn_native/BindGroupLayout.cpp +++ b/src/dawn_native/BindGroupLayout.cpp @@ -36,6 +36,7 @@ namespace dawn_native { const BindGroupLayoutBinding& binding = descriptor->bindings[i]; DAWN_TRY(ValidateShaderStageBit(binding.visibility)); DAWN_TRY(ValidateBindingType(binding.type)); + DAWN_TRY(ValidateTextureComponentType(binding.textureComponentType)); if (binding.binding >= kMaxBindingsPerGroup) { return DAWN_VALIDATION_ERROR("some binding index exceeds the maximum value"); @@ -98,7 +99,8 @@ namespace dawn_native { HashCombine(&hash, info.dynamic, info.multisampled); for (uint32_t binding : IterateBitSet(info.mask)) { - HashCombine(&hash, info.visibilities[binding], info.types[binding]); + HashCombine(&hash, info.visibilities[binding], info.types[binding], + info.textureComponentTypes[binding]); } return hash; @@ -112,7 +114,8 @@ namespace dawn_native { for (uint32_t binding : IterateBitSet(a.mask)) { if ((a.visibilities[binding] != b.visibilities[binding]) || - (a.types[binding] != b.types[binding])) { + (a.types[binding] != b.types[binding]) || + (a.textureComponentTypes[binding] != b.textureComponentTypes[binding])) { return false; } } @@ -133,6 +136,7 @@ namespace dawn_native { uint32_t index = binding.binding; mBindingInfo.visibilities[index] = binding.visibility; mBindingInfo.types[index] = binding.type; + mBindingInfo.textureComponentTypes[index] = binding.textureComponentType; if (binding.dynamic) { mBindingInfo.dynamic.set(index); diff --git a/src/dawn_native/BindGroupLayout.h b/src/dawn_native/BindGroupLayout.h index 98e912b2cc..b19bf825f9 100644 --- a/src/dawn_native/BindGroupLayout.h +++ b/src/dawn_native/BindGroupLayout.h @@ -42,6 +42,7 @@ namespace dawn_native { struct LayoutBindingInfo { std::array visibilities; std::array types; + std::array textureComponentTypes; std::bitset dynamic; std::bitset multisampled; std::bitset mask; diff --git a/src/dawn_native/Format.cpp b/src/dawn_native/Format.cpp index c18f57a3fd..0370c8923b 100644 --- a/src/dawn_native/Format.cpp +++ b/src/dawn_native/Format.cpp @@ -38,6 +38,25 @@ namespace dawn_native { return aspect != Color; } + bool Format::HasComponentType(dawn::TextureComponentType componentType) const { + // Depth stencil textures need to be special cased but we don't support sampling them yet. + if (aspect != Color) { + return false; + } + + // Check that Type is correctly mirrors TextureComponentType except for "Other". + static_assert(static_cast(Type::Float) == + dawn::TextureComponentType::Float, + ""); + static_assert( + static_cast(Type::Sint) == dawn::TextureComponentType::Sint, + ""); + static_assert( + static_cast(Type::Uint) == dawn::TextureComponentType::Uint, + ""); + return static_cast(type) == componentType; + } + size_t Format::GetIndex() const { return ComputeFormatIndex(format); } @@ -54,6 +73,9 @@ namespace dawn_native { FormatTable table; std::bitset formatsSet; + using Type = Format::Type; + using Aspect = Format::Aspect; + auto AddFormat = [&table, &formatsSet](Format format) { size_t index = ComputeFormatIndex(format.format); ASSERT(index < table.size()); @@ -67,13 +89,14 @@ namespace dawn_native { }; auto AddColorFormat = [&AddFormat](dawn::TextureFormat format, bool renderable, - uint32_t byteSize) { + uint32_t byteSize, Type type) { Format internalFormat; internalFormat.format = format; internalFormat.isRenderable = renderable; internalFormat.isCompressed = false; internalFormat.isSupported = true; - internalFormat.aspect = Format::Aspect::Color; + internalFormat.aspect = Aspect::Color; + internalFormat.type = type; internalFormat.blockByteSize = byteSize; internalFormat.blockWidth = 1; internalFormat.blockHeight = 1; @@ -88,6 +111,7 @@ namespace dawn_native { internalFormat.isCompressed = false; internalFormat.isSupported = true; internalFormat.aspect = aspect; + internalFormat.type = Type::Other; internalFormat.blockByteSize = byteSize; internalFormat.blockWidth = 1; internalFormat.blockHeight = 1; @@ -101,7 +125,8 @@ namespace dawn_native { internalFormat.isRenderable = false; internalFormat.isCompressed = true; internalFormat.isSupported = isSupported; - internalFormat.aspect = Format::Aspect::Color; + internalFormat.aspect = Aspect::Color; + internalFormat.type = Type::Float; internalFormat.blockByteSize = byteSize; internalFormat.blockWidth = width; internalFormat.blockHeight = height; @@ -111,57 +136,57 @@ namespace dawn_native { // clang-format off // 1 byte color formats - AddColorFormat(dawn::TextureFormat::R8Unorm, true, 1); - AddColorFormat(dawn::TextureFormat::R8Snorm, false, 1); - AddColorFormat(dawn::TextureFormat::R8Uint, true, 1); - AddColorFormat(dawn::TextureFormat::R8Sint, true, 1); + AddColorFormat(dawn::TextureFormat::R8Unorm, true, 1, Type::Float); + AddColorFormat(dawn::TextureFormat::R8Snorm, false, 1, Type::Float); + AddColorFormat(dawn::TextureFormat::R8Uint, true, 1, Type::Uint); + AddColorFormat(dawn::TextureFormat::R8Sint, true, 1, Type::Sint); // 2 bytes color formats - AddColorFormat(dawn::TextureFormat::R16Uint, true, 2); - AddColorFormat(dawn::TextureFormat::R16Sint, true, 2); - AddColorFormat(dawn::TextureFormat::R16Float, true, 2); - AddColorFormat(dawn::TextureFormat::RG8Unorm, true, 2); - AddColorFormat(dawn::TextureFormat::RG8Snorm, false, 2); - AddColorFormat(dawn::TextureFormat::RG8Uint, true, 2); - AddColorFormat(dawn::TextureFormat::RG8Sint, true, 2); + AddColorFormat(dawn::TextureFormat::R16Uint, true, 2, Type::Uint); + AddColorFormat(dawn::TextureFormat::R16Sint, true, 2, Type::Sint); + AddColorFormat(dawn::TextureFormat::R16Float, true, 2, Type::Float); + AddColorFormat(dawn::TextureFormat::RG8Unorm, true, 2, Type::Float); + AddColorFormat(dawn::TextureFormat::RG8Snorm, false, 2, Type::Float); + AddColorFormat(dawn::TextureFormat::RG8Uint, true, 2, Type::Uint); + AddColorFormat(dawn::TextureFormat::RG8Sint, true, 2, Type::Sint); // 4 bytes color formats - AddColorFormat(dawn::TextureFormat::R32Uint, true, 4); - AddColorFormat(dawn::TextureFormat::R32Sint, true, 4); - AddColorFormat(dawn::TextureFormat::R32Float, true, 4); - AddColorFormat(dawn::TextureFormat::RG16Uint, true, 4); - AddColorFormat(dawn::TextureFormat::RG16Sint, true, 4); - AddColorFormat(dawn::TextureFormat::RG16Float, true, 4); - AddColorFormat(dawn::TextureFormat::RGBA8Unorm, true, 4); - AddColorFormat(dawn::TextureFormat::RGBA8UnormSrgb, true, 4); - AddColorFormat(dawn::TextureFormat::RGBA8Snorm, false, 4); - AddColorFormat(dawn::TextureFormat::RGBA8Uint, true, 4); - AddColorFormat(dawn::TextureFormat::RGBA8Sint, true, 4); - AddColorFormat(dawn::TextureFormat::BGRA8Unorm, true, 4); - AddColorFormat(dawn::TextureFormat::BGRA8UnormSrgb, true, 4); - AddColorFormat(dawn::TextureFormat::RGB10A2Unorm, true, 4); + AddColorFormat(dawn::TextureFormat::R32Uint, true, 4, Type::Uint); + AddColorFormat(dawn::TextureFormat::R32Sint, true, 4, Type::Sint); + AddColorFormat(dawn::TextureFormat::R32Float, true, 4, Type::Float); + AddColorFormat(dawn::TextureFormat::RG16Uint, true, 4, Type::Uint); + AddColorFormat(dawn::TextureFormat::RG16Sint, true, 4, Type::Sint); + AddColorFormat(dawn::TextureFormat::RG16Float, true, 4, Type::Float); + AddColorFormat(dawn::TextureFormat::RGBA8Unorm, true, 4, Type::Float); + AddColorFormat(dawn::TextureFormat::RGBA8UnormSrgb, true, 4, Type::Float); + AddColorFormat(dawn::TextureFormat::RGBA8Snorm, false, 4, Type::Float); + AddColorFormat(dawn::TextureFormat::RGBA8Uint, true, 4, Type::Uint); + AddColorFormat(dawn::TextureFormat::RGBA8Sint, true, 4, Type::Sint); + AddColorFormat(dawn::TextureFormat::BGRA8Unorm, true, 4, Type::Float); + AddColorFormat(dawn::TextureFormat::BGRA8UnormSrgb, true, 4, Type::Float); + AddColorFormat(dawn::TextureFormat::RGB10A2Unorm, true, 4, Type::Float); - AddColorFormat(dawn::TextureFormat::RG11B10Float, false, 4); + AddColorFormat(dawn::TextureFormat::RG11B10Float, false, 4, Type::Float); // 8 bytes color formats - AddColorFormat(dawn::TextureFormat::RG32Uint, true, 8); - AddColorFormat(dawn::TextureFormat::RG32Sint, true, 8); - AddColorFormat(dawn::TextureFormat::RG32Float, true, 8); - AddColorFormat(dawn::TextureFormat::RGBA16Uint, true, 8); - AddColorFormat(dawn::TextureFormat::RGBA16Sint, true, 8); - AddColorFormat(dawn::TextureFormat::RGBA16Float, true, 8); + AddColorFormat(dawn::TextureFormat::RG32Uint, true, 8, Type::Uint); + AddColorFormat(dawn::TextureFormat::RG32Sint, true, 8, Type::Sint); + AddColorFormat(dawn::TextureFormat::RG32Float, true, 8, Type::Float); + AddColorFormat(dawn::TextureFormat::RGBA16Uint, true, 8, Type::Uint); + AddColorFormat(dawn::TextureFormat::RGBA16Sint, true, 8, Type::Sint); + AddColorFormat(dawn::TextureFormat::RGBA16Float, true, 8, Type::Float); // 16 bytes color formats - AddColorFormat(dawn::TextureFormat::RGBA32Uint, true, 16); - AddColorFormat(dawn::TextureFormat::RGBA32Sint, true, 16); - AddColorFormat(dawn::TextureFormat::RGBA32Float, true, 16); + AddColorFormat(dawn::TextureFormat::RGBA32Uint, true, 16, Type::Uint); + AddColorFormat(dawn::TextureFormat::RGBA32Sint, true, 16, Type::Sint); + AddColorFormat(dawn::TextureFormat::RGBA32Float, true, 16, Type::Float); // Depth stencil formats - AddDepthStencilFormat(dawn::TextureFormat::Depth32Float, Format::Aspect::Depth, 4); - AddDepthStencilFormat(dawn::TextureFormat::Depth24Plus, Format::Aspect::Depth, 4); + AddDepthStencilFormat(dawn::TextureFormat::Depth32Float, Aspect::Depth, 4); + AddDepthStencilFormat(dawn::TextureFormat::Depth24Plus, Aspect::Depth, 4); // TODO(cwallez@chromium.org): It isn't clear if this format should be copyable // because its size isn't well defined, is it 4, 5 or 8? - AddDepthStencilFormat(dawn::TextureFormat::Depth24PlusStencil8, Format::Aspect::DepthStencil, 4); + AddDepthStencilFormat(dawn::TextureFormat::Depth24PlusStencil8, Aspect::DepthStencil, 4); // BC compressed formats bool isBCFormatSupported = device->IsExtensionEnabled(Extension::TextureCompressionBC); diff --git a/src/dawn_native/Format.h b/src/dawn_native/Format.h index 39776d7c3e..4ec19b8b91 100644 --- a/src/dawn_native/Format.h +++ b/src/dawn_native/Format.h @@ -38,12 +38,20 @@ namespace dawn_native { DepthStencil, }; + enum Type { + Float, + Sint, + Uint, + Other, + }; + dawn::TextureFormat format; bool isRenderable; bool isCompressed; // A format can be known but not supported because it is part of a disabled extension. bool isSupported; Aspect aspect; + Type type; uint32_t blockByteSize; uint32_t blockWidth; @@ -53,6 +61,7 @@ namespace dawn_native { bool HasDepth() const; bool HasStencil() const; bool HasDepthOrStencil() const; + bool HasComponentType(dawn::TextureComponentType componentType) const; // The index of the format in the list of all known formats: a unique number for each format // in [0, kKnownFormatCount) diff --git a/src/tests/end2end/ObjectCachingTests.cpp b/src/tests/end2end/ObjectCachingTests.cpp index c96b3adfba..1d35fc9237 100644 --- a/src/tests/end2end/ObjectCachingTests.cpp +++ b/src/tests/end2end/ObjectCachingTests.cpp @@ -32,7 +32,7 @@ TEST_P(ObjectCachingTest, BindGroupLayoutDeduplication) { EXPECT_EQ(bgl.Get() == sameBgl.Get(), !UsesWire()); } -// Test that two similar bind group layouts won't refer to the same one. +// Test that two similar bind group layouts won't refer to the same one if they differ by dynamic. TEST_P(ObjectCachingTest, BindGroupLayoutDynamic) { dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout( device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer, true}}); @@ -45,6 +45,23 @@ TEST_P(ObjectCachingTest, BindGroupLayoutDynamic) { EXPECT_EQ(bgl.Get() == sameBgl.Get(), !UsesWire()); } +// Test that two similar bind group layouts won't refer to the same one if they differ by +// textureComponentType +TEST_P(ObjectCachingTest, BindGroupLayoutTextureComponentType) { + dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout( + device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture, false, + false, dawn::TextureComponentType::Float}}); + dawn::BindGroupLayout sameBgl = utils::MakeBindGroupLayout( + device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture, false, + false, dawn::TextureComponentType::Float}}); + dawn::BindGroupLayout otherBgl = utils::MakeBindGroupLayout( + device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture, false, + false, dawn::TextureComponentType::Uint}}); + + EXPECT_NE(bgl.Get(), otherBgl.Get()); + EXPECT_EQ(bgl.Get() == sameBgl.Get(), !UsesWire()); +} + // Test that an error object doesn't try to uncache itself TEST_P(ObjectCachingTest, ErrorObjectDoesntUncache) { ASSERT_DEVICE_ERROR( diff --git a/src/tests/end2end/TextureFormatTests.cpp b/src/tests/end2end/TextureFormatTests.cpp index 2567fde17e..b530c6969a 100644 --- a/src/tests/end2end/TextureFormatTests.cpp +++ b/src/tests/end2end/TextureFormatTests.cpp @@ -113,25 +113,13 @@ class TextureFormatTest : public DawnTest { protected: void SetUp() { DawnTest::SetUp(); - - mSampleBGL = utils::MakeBindGroupLayout( - device, {{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, - {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}}); } - // Describes what the "decompressed" data type for a texture format is. For example normalized - // formats are stored as integers but interpreted to produce floating point values. - enum ComponentType { - Uint, - Sint, - Float, - }; - // Structure containing all the information that tests need to know about the format. struct FormatTestInfo { dawn::TextureFormat format; uint32_t texelByteSize; - ComponentType type; + dawn::TextureComponentType type; uint32_t componentCount; }; @@ -161,13 +149,13 @@ class TextureFormatTest : public DawnTest { ASSERT(formatInfo.componentCount > 0 && formatInfo.componentCount <= 4); dawn::TextureFormat format; switch (formatInfo.type) { - case Float: + case dawn::TextureComponentType::Float: format = floatFormats[formatInfo.componentCount - 1]; break; - case Sint: + case dawn::TextureComponentType::Sint: format = sintFormats[formatInfo.componentCount - 1]; break; - case Uint: + case dawn::TextureComponentType::Uint: format = uintFormats[formatInfo.componentCount - 1]; break; default: @@ -181,7 +169,8 @@ class TextureFormatTest : public DawnTest { // Return a pipeline that can be used in a full-texture draw to sample from the texture in the // bindgroup and output its decompressed values to the render target. dawn::RenderPipeline CreateSamplePipeline(FormatTestInfo sampleFormatInfo, - FormatTestInfo renderFormatInfo) { + FormatTestInfo renderFormatInfo, + dawn::BindGroupLayout bgl) { utils::ComboRenderPipelineDescriptor desc(device); dawn::ShaderModule vsModule = @@ -199,13 +188,13 @@ class TextureFormatTest : public DawnTest { // Compute the prefix needed for GLSL types that handle our texture's data. const char* prefix = nullptr; switch (sampleFormatInfo.type) { - case Float: + case dawn::TextureComponentType::Float: prefix = ""; break; - case Sint: + case dawn::TextureComponentType::Sint: prefix = "i"; break; - case Uint: + case dawn::TextureComponentType::Uint: prefix = "u"; break; default: @@ -229,7 +218,7 @@ class TextureFormatTest : public DawnTest { desc.cVertexStage.module = vsModule; desc.cFragmentStage.module = fsModule; - desc.layout = utils::MakeBasicPipelineLayout(device, &mSampleBGL); + desc.layout = utils::MakeBasicPipelineLayout(device, &bgl); desc.cColorStates[0]->format = renderFormatInfo.format; return device.CreateRenderPipeline(&desc); @@ -281,12 +270,19 @@ class TextureFormatTest : public DawnTest { readbackBufferDesc.size = 4 * width * sampleFormatInfo.componentCount; dawn::Buffer readbackBuffer = device.CreateBuffer(&readbackBufferDesc); + // Create the bind group layout for sampling the texture + dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout( + device, {{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, + {1, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture, false, + false, sampleFormatInfo.type}}); + // Prepare objects needed to sample from texture in the renderpass - dawn::RenderPipeline pipeline = CreateSamplePipeline(sampleFormatInfo, renderFormatInfo); + dawn::RenderPipeline pipeline = + CreateSamplePipeline(sampleFormatInfo, renderFormatInfo, bgl); dawn::SamplerDescriptor samplerDesc = utils::GetDefaultSamplerDescriptor(); dawn::Sampler sampler = device.CreateSampler(&samplerDesc); dawn::BindGroup bindGroup = utils::MakeBindGroup( - device, mSampleBGL, {{0, sampler}, {1, sampleTexture.CreateDefaultView()}}); + device, bgl, {{0, sampler}, {1, sampleTexture.CreateDefaultView()}}); // Encode commands for the test that fill texture, sample it to render to renderTarget then // copy renderTarget in a buffer so we can read it easily. @@ -372,7 +368,7 @@ class TextureFormatTest : public DawnTest { void DoUnormTest(FormatTestInfo formatInfo) { static_assert(!std::is_signed::value && std::is_integral::value, ""); ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize); - ASSERT(formatInfo.type == Float); + ASSERT(formatInfo.type == dawn::TextureComponentType::Float); T maxValue = std::numeric_limits::max(); std::vector textureData = {0, 1, maxValue, maxValue}; @@ -386,7 +382,7 @@ class TextureFormatTest : public DawnTest { void DoSnormTest(FormatTestInfo formatInfo) { static_assert(std::is_signed::value && std::is_integral::value, ""); ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize); - ASSERT(formatInfo.type == Float); + ASSERT(formatInfo.type == dawn::TextureComponentType::Float); T maxValue = std::numeric_limits::max(); T minValue = std::numeric_limits::min(); @@ -401,7 +397,7 @@ class TextureFormatTest : public DawnTest { void DoUintTest(FormatTestInfo formatInfo) { static_assert(!std::is_signed::value && std::is_integral::value, ""); ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize); - ASSERT(formatInfo.type == Uint); + ASSERT(formatInfo.type == dawn::TextureComponentType::Uint); T maxValue = std::numeric_limits::max(); std::vector textureData = {0, 1, maxValue, maxValue}; @@ -415,7 +411,7 @@ class TextureFormatTest : public DawnTest { void DoSintTest(FormatTestInfo formatInfo) { static_assert(std::is_signed::value && std::is_integral::value, ""); ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize); - ASSERT(formatInfo.type == Sint); + ASSERT(formatInfo.type == dawn::TextureComponentType::Sint); T maxValue = std::numeric_limits::max(); T minValue = std::numeric_limits::min(); @@ -428,7 +424,7 @@ class TextureFormatTest : public DawnTest { void DoFloat32Test(FormatTestInfo formatInfo) { ASSERT(sizeof(float) * formatInfo.componentCount == formatInfo.texelByteSize); - ASSERT(formatInfo.type == Float); + ASSERT(formatInfo.type == dawn::TextureComponentType::Float); std::vector textureData = {+0.0f, -0.0f, 1.0f, 1.0e-29f, 1.0e29f, NAN, INFINITY, -INFINITY}; @@ -440,7 +436,7 @@ class TextureFormatTest : public DawnTest { void DoFloat16Test(FormatTestInfo formatInfo) { ASSERT(sizeof(int16_t) * formatInfo.componentCount == formatInfo.texelByteSize); - ASSERT(formatInfo.type == Float); + ASSERT(formatInfo.type == dawn::TextureComponentType::Float); std::vector uncompressedData = {+0.0f, -0.0f, 1.0f, 1.01e-4f, 1.0e4f, NAN, INFINITY, -INFINITY}; @@ -455,24 +451,22 @@ class TextureFormatTest : public DawnTest { DoFormatRenderingTest(formatInfo, uncompressedData, textureData, new ExpectFloat16(textureData)); } - - private: - dawn::BindGroupLayout mSampleBGL; }; // Test the R8Unorm format TEST_P(TextureFormatTest, R8Unorm) { - DoUnormTest({dawn::TextureFormat::R8Unorm, 1, Float, 1}); + DoUnormTest({dawn::TextureFormat::R8Unorm, 1, dawn::TextureComponentType::Float, 1}); } // Test the RG8Unorm format TEST_P(TextureFormatTest, RG8Unorm) { - DoUnormTest({dawn::TextureFormat::RG8Unorm, 2, Float, 2}); + DoUnormTest({dawn::TextureFormat::RG8Unorm, 2, dawn::TextureComponentType::Float, 2}); } // Test the RGBA8Unorm format TEST_P(TextureFormatTest, RGBA8Unorm) { - DoUnormTest({dawn::TextureFormat::RGBA8Unorm, 4, Float, 4}); + DoUnormTest( + {dawn::TextureFormat::RGBA8Unorm, 4, dawn::TextureComponentType::Float, 4}); } // Test the BGRA8Unorm format @@ -480,25 +474,26 @@ TEST_P(TextureFormatTest, BGRA8Unorm) { uint8_t maxValue = std::numeric_limits::max(); std::vector textureData = {maxValue, 1, 0, maxValue}; std::vector uncompressedData = {0.0f, 1.0f / maxValue, 1.0f, 1.0f}; - DoFormatSamplingTest({dawn::TextureFormat::BGRA8Unorm, 4, Float, 4}, textureData, - uncompressedData); - DoFormatRenderingTest({dawn::TextureFormat::BGRA8Unorm, 4, Float, 4}, uncompressedData, - textureData); + DoFormatSamplingTest({dawn::TextureFormat::BGRA8Unorm, 4, dawn::TextureComponentType::Float, 4}, + textureData, uncompressedData); + DoFormatRenderingTest( + {dawn::TextureFormat::BGRA8Unorm, 4, dawn::TextureComponentType::Float, 4}, + uncompressedData, textureData); } // Test the R8Snorm format TEST_P(TextureFormatTest, R8Snorm) { - DoSnormTest({dawn::TextureFormat::R8Snorm, 1, Float, 1}); + DoSnormTest({dawn::TextureFormat::R8Snorm, 1, dawn::TextureComponentType::Float, 1}); } // Test the RG8Snorm format TEST_P(TextureFormatTest, RG8Snorm) { - DoSnormTest({dawn::TextureFormat::RG8Snorm, 2, Float, 2}); + DoSnormTest({dawn::TextureFormat::RG8Snorm, 2, dawn::TextureComponentType::Float, 2}); } // Test the RGBA8Snorm format TEST_P(TextureFormatTest, RGBA8Snorm) { - DoSnormTest({dawn::TextureFormat::RGBA8Snorm, 4, Float, 4}); + DoSnormTest({dawn::TextureFormat::RGBA8Snorm, 4, dawn::TextureComponentType::Float, 4}); } // Test the R8Uint format @@ -506,7 +501,7 @@ TEST_P(TextureFormatTest, R8Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::R8Uint, 1, Uint, 1}); + DoUintTest({dawn::TextureFormat::R8Uint, 1, dawn::TextureComponentType::Uint, 1}); } // Test the RG8Uint format @@ -514,7 +509,7 @@ TEST_P(TextureFormatTest, RG8Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::RG8Uint, 2, Uint, 2}); + DoUintTest({dawn::TextureFormat::RG8Uint, 2, dawn::TextureComponentType::Uint, 2}); } // Test the RGBA8Uint format @@ -522,7 +517,7 @@ TEST_P(TextureFormatTest, RGBA8Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::RGBA8Uint, 4, Uint, 4}); + DoUintTest({dawn::TextureFormat::RGBA8Uint, 4, dawn::TextureComponentType::Uint, 4}); } // Test the R16Uint format @@ -530,7 +525,7 @@ TEST_P(TextureFormatTest, R16Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::R16Uint, 2, Uint, 1}); + DoUintTest({dawn::TextureFormat::R16Uint, 2, dawn::TextureComponentType::Uint, 1}); } // Test the RG16Uint format @@ -538,7 +533,7 @@ TEST_P(TextureFormatTest, RG16Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::RG16Uint, 4, Uint, 2}); + DoUintTest({dawn::TextureFormat::RG16Uint, 4, dawn::TextureComponentType::Uint, 2}); } // Test the RGBA16Uint format @@ -546,7 +541,7 @@ TEST_P(TextureFormatTest, RGBA16Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::RGBA16Uint, 8, Uint, 4}); + DoUintTest({dawn::TextureFormat::RGBA16Uint, 8, dawn::TextureComponentType::Uint, 4}); } // Test the R32Uint format @@ -554,7 +549,7 @@ TEST_P(TextureFormatTest, R32Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::R32Uint, 4, Uint, 1}); + DoUintTest({dawn::TextureFormat::R32Uint, 4, dawn::TextureComponentType::Uint, 1}); } // Test the RG32Uint format @@ -562,7 +557,7 @@ TEST_P(TextureFormatTest, RG32Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::RG32Uint, 8, Uint, 2}); + DoUintTest({dawn::TextureFormat::RG32Uint, 8, dawn::TextureComponentType::Uint, 2}); } // Test the RGBA32Uint format @@ -570,7 +565,8 @@ TEST_P(TextureFormatTest, RGBA32Uint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoUintTest({dawn::TextureFormat::RGBA32Uint, 16, Uint, 4}); + DoUintTest( + {dawn::TextureFormat::RGBA32Uint, 16, dawn::TextureComponentType::Uint, 4}); } // Test the R8Sint format @@ -578,7 +574,7 @@ TEST_P(TextureFormatTest, R8Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::R8Sint, 1, Sint, 1}); + DoSintTest({dawn::TextureFormat::R8Sint, 1, dawn::TextureComponentType::Sint, 1}); } // Test the RG8Sint format @@ -586,7 +582,7 @@ TEST_P(TextureFormatTest, RG8Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::RG8Sint, 2, Sint, 2}); + DoSintTest({dawn::TextureFormat::RG8Sint, 2, dawn::TextureComponentType::Sint, 2}); } // Test the RGBA8Sint format @@ -594,7 +590,7 @@ TEST_P(TextureFormatTest, RGBA8Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::RGBA8Sint, 4, Sint, 4}); + DoSintTest({dawn::TextureFormat::RGBA8Sint, 4, dawn::TextureComponentType::Sint, 4}); } // Test the R16Sint format @@ -602,7 +598,7 @@ TEST_P(TextureFormatTest, R16Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::R16Sint, 2, Sint, 1}); + DoSintTest({dawn::TextureFormat::R16Sint, 2, dawn::TextureComponentType::Sint, 1}); } // Test the RG16Sint format @@ -610,7 +606,7 @@ TEST_P(TextureFormatTest, RG16Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::RG16Sint, 4, Sint, 2}); + DoSintTest({dawn::TextureFormat::RG16Sint, 4, dawn::TextureComponentType::Sint, 2}); } // Test the RGBA16Sint format @@ -618,7 +614,7 @@ TEST_P(TextureFormatTest, RGBA16Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::RGBA16Sint, 8, Sint, 4}); + DoSintTest({dawn::TextureFormat::RGBA16Sint, 8, dawn::TextureComponentType::Sint, 4}); } // Test the R32Sint format @@ -626,7 +622,7 @@ TEST_P(TextureFormatTest, R32Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::R32Sint, 4, Sint, 1}); + DoSintTest({dawn::TextureFormat::R32Sint, 4, dawn::TextureComponentType::Sint, 1}); } // Test the RG32Sint format @@ -634,7 +630,7 @@ TEST_P(TextureFormatTest, RG32Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::RG32Sint, 8, Sint, 2}); + DoSintTest({dawn::TextureFormat::RG32Sint, 8, dawn::TextureComponentType::Sint, 2}); } // Test the RGBA32Sint format @@ -642,37 +638,37 @@ TEST_P(TextureFormatTest, RGBA32Sint) { // TODO(cwallez@chromium.org): This fails on the Intel GL driver, understand why. DAWN_SKIP_TEST_IF(IsOpenGL() && IsIntel()); - DoSintTest({dawn::TextureFormat::RGBA32Sint, 16, Sint, 4}); + DoSintTest({dawn::TextureFormat::RGBA32Sint, 16, dawn::TextureComponentType::Sint, 4}); } // Test the R32Float format TEST_P(TextureFormatTest, R32Float) { - DoFloat32Test({dawn::TextureFormat::R32Float, 4, Float, 1}); + DoFloat32Test({dawn::TextureFormat::R32Float, 4, dawn::TextureComponentType::Float, 1}); } // Test the RG32Float format TEST_P(TextureFormatTest, RG32Float) { - DoFloat32Test({dawn::TextureFormat::RG32Float, 8, Float, 2}); + DoFloat32Test({dawn::TextureFormat::RG32Float, 8, dawn::TextureComponentType::Float, 2}); } // Test the RGBA32Float format TEST_P(TextureFormatTest, RGBA32Float) { - DoFloat32Test({dawn::TextureFormat::RGBA32Float, 16, Float, 4}); + DoFloat32Test({dawn::TextureFormat::RGBA32Float, 16, dawn::TextureComponentType::Float, 4}); } // Test the R16Float format TEST_P(TextureFormatTest, R16Float) { - DoFloat16Test({dawn::TextureFormat::R16Float, 2, Float, 1}); + DoFloat16Test({dawn::TextureFormat::R16Float, 2, dawn::TextureComponentType::Float, 1}); } // Test the RG16Float format TEST_P(TextureFormatTest, RG16Float) { - DoFloat16Test({dawn::TextureFormat::RG16Float, 4, Float, 2}); + DoFloat16Test({dawn::TextureFormat::RG16Float, 4, dawn::TextureComponentType::Float, 2}); } // Test the RGBA16Float format TEST_P(TextureFormatTest, RGBA16Float) { - DoFloat16Test({dawn::TextureFormat::RGBA16Float, 8, Float, 4}); + DoFloat16Test({dawn::TextureFormat::RGBA16Float, 8, dawn::TextureComponentType::Float, 4}); } // Test the RGBA8Unorm format @@ -689,10 +685,12 @@ TEST_P(TextureFormatTest, RGBA8UnormSrgb) { uncompressedData.push_back(textureData[i + 3] / float(maxValue)); } - DoFloatFormatSamplingTest({dawn::TextureFormat::RGBA8UnormSrgb, 4, Float, 4}, textureData, - uncompressedData, 1.0e-3); - DoFormatRenderingTest({dawn::TextureFormat::RGBA8UnormSrgb, 4, Float, 4}, uncompressedData, - textureData); + DoFloatFormatSamplingTest( + {dawn::TextureFormat::RGBA8UnormSrgb, 4, dawn::TextureComponentType::Float, 4}, textureData, + uncompressedData, 1.0e-3); + DoFormatRenderingTest( + {dawn::TextureFormat::RGBA8UnormSrgb, 4, dawn::TextureComponentType::Float, 4}, + uncompressedData, textureData); } // Test the BGRA8UnormSrgb format @@ -714,10 +712,12 @@ TEST_P(TextureFormatTest, BGRA8UnormSrgb) { uncompressedData.push_back(textureData[i + 3] / float(maxValue)); } - DoFloatFormatSamplingTest({dawn::TextureFormat::BGRA8UnormSrgb, 4, Float, 4}, textureData, - uncompressedData, 1.0e-3); - DoFormatRenderingTest({dawn::TextureFormat::BGRA8UnormSrgb, 4, Float, 4}, uncompressedData, - textureData); + DoFloatFormatSamplingTest( + {dawn::TextureFormat::BGRA8UnormSrgb, 4, dawn::TextureComponentType::Float, 4}, textureData, + uncompressedData, 1.0e-3); + DoFormatRenderingTest( + {dawn::TextureFormat::BGRA8UnormSrgb, 4, dawn::TextureComponentType::Float, 4}, + uncompressedData, textureData); } // Test the RGB10A2Unorm format @@ -741,10 +741,12 @@ TEST_P(TextureFormatTest, RGB10A2Unorm) { }; // clang-format on - DoFloatFormatSamplingTest({dawn::TextureFormat::RGB10A2Unorm, 4, Float, 4}, textureData, - uncompressedData, 1.0e-5); - DoFormatRenderingTest({dawn::TextureFormat::RGB10A2Unorm, 4, Float, 4}, uncompressedData, - textureData); + DoFloatFormatSamplingTest( + {dawn::TextureFormat::RGB10A2Unorm, 4, dawn::TextureComponentType::Float, 4}, textureData, + uncompressedData, 1.0e-5); + DoFormatRenderingTest( + {dawn::TextureFormat::RGB10A2Unorm, 4, dawn::TextureComponentType::Float, 4}, + uncompressedData, textureData); } // Test the RG11B10Float format @@ -786,8 +788,9 @@ TEST_P(TextureFormatTest, RG11B10Float) { }; // clang-format on - DoFloatFormatSamplingTest({dawn::TextureFormat::RG11B10Float, 4, Float, 4}, textureData, - uncompressedData); + DoFloatFormatSamplingTest( + {dawn::TextureFormat::RG11B10Float, 4, dawn::TextureComponentType::Float, 4}, textureData, + uncompressedData); // This format is not renderable. } diff --git a/src/tests/unittests/validation/BindGroupValidationTests.cpp b/src/tests/unittests/validation/BindGroupValidationTests.cpp index 24d6c8f002..423dff18fa 100644 --- a/src/tests/unittests/validation/BindGroupValidationTests.cpp +++ b/src/tests/unittests/validation/BindGroupValidationTests.cpp @@ -306,6 +306,30 @@ TEST_F(BindGroupValidationTest, TextureUsage) { ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, outputTextureView}})); } +// Check that a texture must have the correct component type +TEST_F(BindGroupValidationTest, TextureComponentType) { + dawn::BindGroupLayout layout = utils::MakeBindGroupLayout( + device, {{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture, false, + false, dawn::TextureComponentType::Float}}); + + // Control case: setting a Float typed texture view works. + utils::MakeBindGroup(device, layout, {{0, mSampledTextureView}}); + + // Make an output attachment texture and try to set it for a SampledTexture binding + dawn::TextureDescriptor descriptor; + descriptor.dimension = dawn::TextureDimension::e2D; + descriptor.size = {16, 16, 1}; + descriptor.arrayLayerCount = 1; + descriptor.sampleCount = 1; + descriptor.format = dawn::TextureFormat::RGBA8Uint; + descriptor.mipLevelCount = 1; + descriptor.usage = dawn::TextureUsageBit::Sampled; + dawn::Texture uintTexture = device.CreateTexture(&descriptor); + dawn::TextureView uintTextureView = uintTexture.CreateDefaultView(); + + ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, uintTextureView}})); +} + // Check that a UBO must have the correct usage TEST_F(BindGroupValidationTest, BufferUsageUBO) { dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, { @@ -482,24 +506,6 @@ TEST_F(BindGroupLayoutValidationTest, DynamicAndTypeCompatibility) { })); } -// This test verifies that the BindGroupLayout cache is successfully caching/deduplicating objects. -// -// NOTE: This test only works currently because unittests are run without the wire - so the returned -// BindGroupLayout pointers are actually visibly equivalent. With the wire, this would not be true. -TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutCache) { - auto layout1 = utils::MakeBindGroupLayout( - device, { - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - auto layout2 = utils::MakeBindGroupLayout( - device, { - {0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}, - }); - - // Caching should cause these to be the same. - ASSERT_EQ(layout1.Get(), layout2.Get()); -} - // This test verifies that visibility of bindings in BindGroupLayout can't be none TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutVisibilityNone) { utils::MakeBindGroupLayout( diff --git a/src/tests/unittests/wire/WireArgumentTests.cpp b/src/tests/unittests/wire/WireArgumentTests.cpp index c0cce5c3df..e59fe24985 100644 --- a/src/tests/unittests/wire/WireArgumentTests.cpp +++ b/src/tests/unittests/wire/WireArgumentTests.cpp @@ -332,12 +332,14 @@ TEST_F(WireArgumentTests, StructureOfObjectArrayArgument) { TEST_F(WireArgumentTests, StructureOfStructureArrayArgument) { static constexpr int NUM_BINDINGS = 3; DawnBindGroupLayoutBinding bindings[NUM_BINDINGS]{ - {0, DAWN_SHADER_STAGE_BIT_VERTEX, DAWN_BINDING_TYPE_SAMPLER, false, false}, - {1, DAWN_SHADER_STAGE_BIT_VERTEX, DAWN_BINDING_TYPE_SAMPLED_TEXTURE, false, false}, + {0, DAWN_SHADER_STAGE_BIT_VERTEX, DAWN_BINDING_TYPE_SAMPLER, false, false, + DAWN_TEXTURE_COMPONENT_TYPE_FLOAT}, + {1, DAWN_SHADER_STAGE_BIT_VERTEX, DAWN_BINDING_TYPE_SAMPLED_TEXTURE, false, false, + DAWN_TEXTURE_COMPONENT_TYPE_FLOAT}, {2, static_cast(DAWN_SHADER_STAGE_BIT_VERTEX | DAWN_SHADER_STAGE_BIT_FRAGMENT), - DAWN_BINDING_TYPE_UNIFORM_BUFFER, false, false}, + DAWN_BINDING_TYPE_UNIFORM_BUFFER, false, false, DAWN_TEXTURE_COMPONENT_TYPE_FLOAT}, }; DawnBindGroupLayoutDescriptor bglDescriptor; bglDescriptor.bindingCount = NUM_BINDINGS;