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 <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2019-08-21 12:16:33 +00:00 committed by Commit Bot service account
parent ae2b9f4720
commit f463a20291
10 changed files with 240 additions and 150 deletions

View File

@ -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,

View File

@ -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));

View File

@ -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);

View File

@ -42,6 +42,7 @@ namespace dawn_native {
struct LayoutBindingInfo {
std::array<dawn::ShaderStageBit, kMaxBindingsPerGroup> visibilities;
std::array<dawn::BindingType, kMaxBindingsPerGroup> types;
std::array<dawn::TextureComponentType, kMaxBindingsPerGroup> textureComponentTypes;
std::bitset<kMaxBindingsPerGroup> dynamic;
std::bitset<kMaxBindingsPerGroup> multisampled;
std::bitset<kMaxBindingsPerGroup> mask;

View File

@ -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<dawn::TextureComponentType>(Type::Float) ==
dawn::TextureComponentType::Float,
"");
static_assert(
static_cast<dawn::TextureComponentType>(Type::Sint) == dawn::TextureComponentType::Sint,
"");
static_assert(
static_cast<dawn::TextureComponentType>(Type::Uint) == dawn::TextureComponentType::Uint,
"");
return static_cast<dawn::TextureComponentType>(type) == componentType;
}
size_t Format::GetIndex() const {
return ComputeFormatIndex(format);
}
@ -54,6 +73,9 @@ namespace dawn_native {
FormatTable table;
std::bitset<kKnownFormatCount> 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);

View File

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

View File

@ -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(

View File

@ -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<T>::value && std::is_integral<T>::value, "");
ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize);
ASSERT(formatInfo.type == Float);
ASSERT(formatInfo.type == dawn::TextureComponentType::Float);
T maxValue = std::numeric_limits<T>::max();
std::vector<T> textureData = {0, 1, maxValue, maxValue};
@ -386,7 +382,7 @@ class TextureFormatTest : public DawnTest {
void DoSnormTest(FormatTestInfo formatInfo) {
static_assert(std::is_signed<T>::value && std::is_integral<T>::value, "");
ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize);
ASSERT(formatInfo.type == Float);
ASSERT(formatInfo.type == dawn::TextureComponentType::Float);
T maxValue = std::numeric_limits<T>::max();
T minValue = std::numeric_limits<T>::min();
@ -401,7 +397,7 @@ class TextureFormatTest : public DawnTest {
void DoUintTest(FormatTestInfo formatInfo) {
static_assert(!std::is_signed<T>::value && std::is_integral<T>::value, "");
ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize);
ASSERT(formatInfo.type == Uint);
ASSERT(formatInfo.type == dawn::TextureComponentType::Uint);
T maxValue = std::numeric_limits<T>::max();
std::vector<T> textureData = {0, 1, maxValue, maxValue};
@ -415,7 +411,7 @@ class TextureFormatTest : public DawnTest {
void DoSintTest(FormatTestInfo formatInfo) {
static_assert(std::is_signed<T>::value && std::is_integral<T>::value, "");
ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize);
ASSERT(formatInfo.type == Sint);
ASSERT(formatInfo.type == dawn::TextureComponentType::Sint);
T maxValue = std::numeric_limits<T>::max();
T minValue = std::numeric_limits<T>::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<float> 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<float> 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<uint8_t>({dawn::TextureFormat::R8Unorm, 1, Float, 1});
DoUnormTest<uint8_t>({dawn::TextureFormat::R8Unorm, 1, dawn::TextureComponentType::Float, 1});
}
// Test the RG8Unorm format
TEST_P(TextureFormatTest, RG8Unorm) {
DoUnormTest<uint8_t>({dawn::TextureFormat::RG8Unorm, 2, Float, 2});
DoUnormTest<uint8_t>({dawn::TextureFormat::RG8Unorm, 2, dawn::TextureComponentType::Float, 2});
}
// Test the RGBA8Unorm format
TEST_P(TextureFormatTest, RGBA8Unorm) {
DoUnormTest<uint8_t>({dawn::TextureFormat::RGBA8Unorm, 4, Float, 4});
DoUnormTest<uint8_t>(
{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<uint8_t>::max();
std::vector<uint8_t> textureData = {maxValue, 1, 0, maxValue};
std::vector<float> 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<int8_t>({dawn::TextureFormat::R8Snorm, 1, Float, 1});
DoSnormTest<int8_t>({dawn::TextureFormat::R8Snorm, 1, dawn::TextureComponentType::Float, 1});
}
// Test the RG8Snorm format
TEST_P(TextureFormatTest, RG8Snorm) {
DoSnormTest<int8_t>({dawn::TextureFormat::RG8Snorm, 2, Float, 2});
DoSnormTest<int8_t>({dawn::TextureFormat::RG8Snorm, 2, dawn::TextureComponentType::Float, 2});
}
// Test the RGBA8Snorm format
TEST_P(TextureFormatTest, RGBA8Snorm) {
DoSnormTest<int8_t>({dawn::TextureFormat::RGBA8Snorm, 4, Float, 4});
DoSnormTest<int8_t>({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<uint8_t>({dawn::TextureFormat::R8Uint, 1, Uint, 1});
DoUintTest<uint8_t>({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<uint8_t>({dawn::TextureFormat::RG8Uint, 2, Uint, 2});
DoUintTest<uint8_t>({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<uint8_t>({dawn::TextureFormat::RGBA8Uint, 4, Uint, 4});
DoUintTest<uint8_t>({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<uint16_t>({dawn::TextureFormat::R16Uint, 2, Uint, 1});
DoUintTest<uint16_t>({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<uint16_t>({dawn::TextureFormat::RG16Uint, 4, Uint, 2});
DoUintTest<uint16_t>({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<uint16_t>({dawn::TextureFormat::RGBA16Uint, 8, Uint, 4});
DoUintTest<uint16_t>({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<uint32_t>({dawn::TextureFormat::R32Uint, 4, Uint, 1});
DoUintTest<uint32_t>({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<uint32_t>({dawn::TextureFormat::RG32Uint, 8, Uint, 2});
DoUintTest<uint32_t>({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<uint32_t>({dawn::TextureFormat::RGBA32Uint, 16, Uint, 4});
DoUintTest<uint32_t>(
{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<int8_t>({dawn::TextureFormat::R8Sint, 1, Sint, 1});
DoSintTest<int8_t>({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<int8_t>({dawn::TextureFormat::RG8Sint, 2, Sint, 2});
DoSintTest<int8_t>({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<int8_t>({dawn::TextureFormat::RGBA8Sint, 4, Sint, 4});
DoSintTest<int8_t>({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<int16_t>({dawn::TextureFormat::R16Sint, 2, Sint, 1});
DoSintTest<int16_t>({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<int16_t>({dawn::TextureFormat::RG16Sint, 4, Sint, 2});
DoSintTest<int16_t>({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<int16_t>({dawn::TextureFormat::RGBA16Sint, 8, Sint, 4});
DoSintTest<int16_t>({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<int32_t>({dawn::TextureFormat::R32Sint, 4, Sint, 1});
DoSintTest<int32_t>({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<int32_t>({dawn::TextureFormat::RG32Sint, 8, Sint, 2});
DoSintTest<int32_t>({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<int32_t>({dawn::TextureFormat::RGBA32Sint, 16, Sint, 4});
DoSintTest<int32_t>({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.
}

View File

@ -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(

View File

@ -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<DawnShaderStageBit>(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;