Add Norm16 texture formats
This checks the availability of the formats on each backend to
properly enable the Feature::Norm16TextureFormats.
The new formats include:
R16Unorm
RG16Unorm
RGBA16Unorm
R16Snorm
RG16Snorm
RGBA16Snorm
Bug: dawn:1982
Change-Id: I09600911adea3335a6a691000ab74f08a8fba5e7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/147220
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
diff --git a/dawn.json b/dawn.json
index 94152e3..a40a306 100644
--- a/dawn.json
+++ b/dawn.json
@@ -1814,6 +1814,7 @@
{"value": 1016, "name": "chromium experimental read write storage texture", "tags": ["dawn"]},
{"value": 1017, "name": "pixel local storage coherent", "tags": ["dawn"]},
{"value": 1018, "name": "pixel local storage non coherent", "tags": ["dawn"]},
+ {"value": 1019, "name": "norm16 texture formats", "tags": ["dawn"]},
{"value": 1100, "name": "shared texture memory vk dedicated allocation", "tags": ["dawn", "native"]},
{"value": 1101, "name": "shared texture memory a hardware buffer", "tags": ["dawn", "native"]},
@@ -3292,7 +3293,14 @@
{"value": 93, "name": "ASTC 12x12 unorm", "jsrepr": "'astc-12x12-unorm'"},
{"value": 94, "name": "ASTC 12x12 unorm srgb", "jsrepr": "'astc-12x12-unorm-srgb'"},
- {"value": 95, "name": "R8 BG8 Biplanar 420 unorm", "tags": ["dawn"]}
+ {"value": 95, "name": "R16 unorm", "tags": ["dawn"]},
+ {"value": 96, "name": "RG16 unorm", "tags": ["dawn"]},
+ {"value": 97, "name": "RGBA16 unorm", "tags": ["dawn"]},
+ {"value": 98, "name": "R16 snorm", "tags": ["dawn"]},
+ {"value": 99, "name": "RG16 snorm", "tags": ["dawn"]},
+ {"value": 100, "name": "RGBA16 snorm", "tags": ["dawn"]},
+
+ {"value": 101, "name": "R8 BG8 Biplanar 420 unorm", "tags": ["dawn"]}
]
},
"texture usage": {
diff --git a/src/dawn/native/Features.cpp b/src/dawn/native/Features.cpp
index b5aa0c4..7c61f95 100644
--- a/src/dawn/native/Features.cpp
+++ b/src/dawn/native/Features.cpp
@@ -174,6 +174,9 @@
"overlapping fragments from the same draw cannot be made data race free).",
"https://bugs.chromium.org/p/dawn/issues/detail?id=1704",
FeatureInfo::FeatureState::Experimental}},
+ {Feature::Norm16TextureFormats,
+ {"norm16-texture-formats", "Supports R/RG/RGBA16 norm texture formats",
+ "https://bugs.chromium.org/p/dawn/issues/detail?id=1982", FeatureInfo::FeatureState::Stable}},
{Feature::SharedTextureMemoryVkDedicatedAllocation,
{"shared-texture-memory-vk-dedicated-allocation",
"Support specifying whether a Vulkan allocation for shared texture memory is a dedicated "
@@ -309,6 +312,8 @@
return Feature::PixelLocalStorageCoherent;
case wgpu::FeatureName::PixelLocalStorageNonCoherent:
return Feature::PixelLocalStorageNonCoherent;
+ case wgpu::FeatureName::Norm16TextureFormats:
+ return Feature::Norm16TextureFormats;
case wgpu::FeatureName::SharedTextureMemoryVkDedicatedAllocation:
return Feature::SharedTextureMemoryVkDedicatedAllocation;
case wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer:
@@ -371,6 +376,8 @@
return wgpu::FeatureName::DawnInternalUsages;
case Feature::MultiPlanarFormats:
return wgpu::FeatureName::DawnMultiPlanarFormats;
+ case Feature::Norm16TextureFormats:
+ return wgpu::FeatureName::Norm16TextureFormats;
case Feature::DawnNative:
return wgpu::FeatureName::DawnNative;
case Feature::ChromiumExperimentalDp4a:
diff --git a/src/dawn/native/Features.h b/src/dawn/native/Features.h
index a93cc50..9014738 100644
--- a/src/dawn/native/Features.h
+++ b/src/dawn/native/Features.h
@@ -58,6 +58,7 @@
ANGLETextureSharing,
PixelLocalStorageCoherent,
PixelLocalStorageNonCoherent,
+ Norm16TextureFormats,
SharedTextureMemoryVkDedicatedAllocation,
SharedTextureMemoryAHardwareBuffer,
diff --git a/src/dawn/native/Format.cpp b/src/dawn/native/Format.cpp
index 78f4d6e..e1ae867 100644
--- a/src/dawn/native/Format.cpp
+++ b/src/dawn/native/Format.cpp
@@ -456,6 +456,15 @@
AddColorFormat(wgpu::TextureFormat::RGBA32Sint, Cap::Renderable | Cap::StorageW, ByteSize(16), SampleTypeBit::Sint, ComponentCount(4), RenderTargetPixelByteCost(16), RenderTargetComponentAlignment(4));
AddColorFormat(wgpu::TextureFormat::RGBA32Float, Cap::Renderable | Cap::StorageW, ByteSize(16), sampleTypeFor32BitFloatFormats, ComponentCount(4), RenderTargetPixelByteCost(16), RenderTargetComponentAlignment(4));
+ // Norm16 color formats
+ auto norm16Capabilities = device->HasFeature(Feature::Norm16TextureFormats) ? Cap::Renderable | Cap::Multisample | Cap::Resolve : Cap::None;
+ AddColorFormat(wgpu::TextureFormat::R16Unorm, norm16Capabilities, ByteSize(2), kAnyFloat, ComponentCount(1), RenderTargetPixelByteCost(2), RenderTargetComponentAlignment(2));
+ AddColorFormat(wgpu::TextureFormat::RG16Unorm, norm16Capabilities, ByteSize(4), kAnyFloat, ComponentCount(2), RenderTargetPixelByteCost(4), RenderTargetComponentAlignment(2));
+ AddColorFormat(wgpu::TextureFormat::RGBA16Unorm, norm16Capabilities, ByteSize(8), kAnyFloat, ComponentCount(4), RenderTargetPixelByteCost(8), RenderTargetComponentAlignment(2));
+ AddColorFormat(wgpu::TextureFormat::R16Snorm, norm16Capabilities, ByteSize(2), kAnyFloat, ComponentCount(1), RenderTargetPixelByteCost(2), RenderTargetComponentAlignment(2));
+ AddColorFormat(wgpu::TextureFormat::RG16Snorm, norm16Capabilities, ByteSize(4), kAnyFloat, ComponentCount(2), RenderTargetPixelByteCost(4), RenderTargetComponentAlignment(2));
+ AddColorFormat(wgpu::TextureFormat::RGBA16Snorm, norm16Capabilities, ByteSize(8), kAnyFloat, ComponentCount(4), RenderTargetPixelByteCost(8), RenderTargetComponentAlignment(2));
+
// Depth-stencil formats
AddStencilFormat(wgpu::TextureFormat::Stencil8, Format::supported);
AddDepthFormat(wgpu::TextureFormat::Depth16Unorm, 2, Format::supported);
diff --git a/src/dawn/native/Format.h b/src/dawn/native/Format.h
index 8a82fa1..96ff348 100644
--- a/src/dawn/native/Format.h
+++ b/src/dawn/native/Format.h
@@ -93,7 +93,7 @@
// The number of formats Dawn knows about. Asserts in BuildFormatTable ensure that this is the
// exact number of known format.
-static constexpr uint32_t kKnownFormatCount = 95;
+static constexpr uint32_t kKnownFormatCount = 101;
using FormatIndex = TypedInteger<struct FormatIndexT, uint32_t>;
diff --git a/src/dawn/native/d3d/UtilsD3D.cpp b/src/dawn/native/d3d/UtilsD3D.cpp
index 4af1498..b8cb9d1 100644
--- a/src/dawn/native/d3d/UtilsD3D.cpp
+++ b/src/dawn/native/d3d/UtilsD3D.cpp
@@ -92,6 +92,8 @@
case wgpu::TextureFormat::R8Sint:
return DXGI_FORMAT_R8_TYPELESS;
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
case wgpu::TextureFormat::R16Uint:
case wgpu::TextureFormat::R16Sint:
case wgpu::TextureFormat::R16Float:
@@ -109,6 +111,8 @@
case wgpu::TextureFormat::R32Float:
return DXGI_FORMAT_R32_TYPELESS;
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RG16Snorm:
case wgpu::TextureFormat::RG16Uint:
case wgpu::TextureFormat::RG16Sint:
case wgpu::TextureFormat::RG16Float:
@@ -138,6 +142,8 @@
case wgpu::TextureFormat::RG32Float:
return DXGI_FORMAT_R32G32_TYPELESS;
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
case wgpu::TextureFormat::RGBA16Uint:
case wgpu::TextureFormat::RGBA16Sint:
case wgpu::TextureFormat::RGBA16Float:
@@ -245,6 +251,10 @@
case wgpu::TextureFormat::R8Sint:
return DXGI_FORMAT_R8_SINT;
+ case wgpu::TextureFormat::R16Unorm:
+ return DXGI_FORMAT_R16_UNORM;
+ case wgpu::TextureFormat::R16Snorm:
+ return DXGI_FORMAT_R16_SNORM;
case wgpu::TextureFormat::R16Uint:
return DXGI_FORMAT_R16_UINT;
case wgpu::TextureFormat::R16Sint:
@@ -266,6 +276,11 @@
return DXGI_FORMAT_R32_SINT;
case wgpu::TextureFormat::R32Float:
return DXGI_FORMAT_R32_FLOAT;
+
+ case wgpu::TextureFormat::RG16Unorm:
+ return DXGI_FORMAT_R16G16_UNORM;
+ case wgpu::TextureFormat::RG16Snorm:
+ return DXGI_FORMAT_R16G16_SNORM;
case wgpu::TextureFormat::RG16Uint:
return DXGI_FORMAT_R16G16_UINT;
case wgpu::TextureFormat::RG16Sint:
@@ -299,6 +314,10 @@
return DXGI_FORMAT_R32G32_SINT;
case wgpu::TextureFormat::RG32Float:
return DXGI_FORMAT_R32G32_FLOAT;
+ case wgpu::TextureFormat::RGBA16Unorm:
+ return DXGI_FORMAT_R16G16B16A16_UNORM;
+ case wgpu::TextureFormat::RGBA16Snorm:
+ return DXGI_FORMAT_R16G16B16A16_SNORM;
case wgpu::TextureFormat::RGBA16Uint:
return DXGI_FORMAT_R16G16B16A16_UINT;
case wgpu::TextureFormat::RGBA16Sint:
diff --git a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
index b453fb0..b1d9437 100644
--- a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
+++ b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
@@ -140,6 +140,7 @@
EnableFeature(Feature::D3D11MultithreadProtected);
EnableFeature(Feature::MSAARenderToSingleSampled);
EnableFeature(Feature::DualSourceBlending);
+ EnableFeature(Feature::Norm16TextureFormats);
// To import multi planar textures, we need to at least tier 2 support.
if (mDeviceInfo.supportsSharedResourceCapabilityTier2) {
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index e4c8244..dc916ba 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -126,6 +126,7 @@
EnableFeature(Feature::SurfaceCapabilities);
EnableFeature(Feature::Float32Filterable);
EnableFeature(Feature::DualSourceBlending);
+ EnableFeature(Feature::Norm16TextureFormats);
if (AreTimestampQueriesSupported()) {
EnableFeature(Feature::TimestampQuery);
diff --git a/src/dawn/native/metal/BackendMTL.mm b/src/dawn/native/metal/BackendMTL.mm
index e33914e..8adf17d 100644
--- a/src/dawn/native/metal/BackendMTL.mm
+++ b/src/dawn/native/metal/BackendMTL.mm
@@ -552,6 +552,8 @@
if (@available(macOS 10.14, iOS 12.0, *)) {
EnableFeature(Feature::SharedFenceMTLSharedEvent);
}
+
+ EnableFeature(Feature::Norm16TextureFormats);
}
void InitializeVendorArchitectureImpl() override {
diff --git a/src/dawn/native/metal/TextureMTL.mm b/src/dawn/native/metal/TextureMTL.mm
index 369fefa..f4e7d3f 100644
--- a/src/dawn/native/metal/TextureMTL.mm
+++ b/src/dawn/native/metal/TextureMTL.mm
@@ -254,6 +254,10 @@
case wgpu::TextureFormat::R8Sint:
return MTLPixelFormatR8Sint;
+ case wgpu::TextureFormat::R16Unorm:
+ return MTLPixelFormatR16Unorm;
+ case wgpu::TextureFormat::R16Snorm:
+ return MTLPixelFormatR16Snorm;
case wgpu::TextureFormat::R16Uint:
return MTLPixelFormatR16Uint;
case wgpu::TextureFormat::R16Sint:
@@ -275,6 +279,10 @@
return MTLPixelFormatR32Sint;
case wgpu::TextureFormat::R32Float:
return MTLPixelFormatR32Float;
+ case wgpu::TextureFormat::RG16Unorm:
+ return MTLPixelFormatRG16Unorm;
+ case wgpu::TextureFormat::RG16Snorm:
+ return MTLPixelFormatRG16Snorm;
case wgpu::TextureFormat::RG16Uint:
return MTLPixelFormatRG16Uint;
case wgpu::TextureFormat::RG16Sint:
@@ -308,6 +316,10 @@
return MTLPixelFormatRG32Sint;
case wgpu::TextureFormat::RG32Float:
return MTLPixelFormatRG32Float;
+ case wgpu::TextureFormat::RGBA16Unorm:
+ return MTLPixelFormatRGBA16Unorm;
+ case wgpu::TextureFormat::RGBA16Snorm:
+ return MTLPixelFormatRGBA16Snorm;
case wgpu::TextureFormat::RGBA16Uint:
return MTLPixelFormatRGBA16Uint;
case wgpu::TextureFormat::RGBA16Sint:
diff --git a/src/dawn/native/opengl/GLFormat.cpp b/src/dawn/native/opengl/GLFormat.cpp
index 529cc35..3c7edf6 100644
--- a/src/dawn/native/opengl/GLFormat.cpp
+++ b/src/dawn/native/opengl/GLFormat.cpp
@@ -50,6 +50,8 @@
AddFormat(wgpu::TextureFormat::R8Sint, GL_R8I, GL_RED_INTEGER, GL_BYTE, Type::Int);
// 2 bytes color formats
+ AddFormat(wgpu::TextureFormat::R16Unorm, GL_R16, GL_RED, GL_UNSIGNED_SHORT, Type::Float);
+ AddFormat(wgpu::TextureFormat::R16Snorm, GL_R16_SNORM, GL_RED, GL_SHORT, Type::Float);
AddFormat(wgpu::TextureFormat::R16Uint, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, Type::Uint);
AddFormat(wgpu::TextureFormat::R16Sint, GL_R16I, GL_RED_INTEGER, GL_SHORT, Type::Int);
AddFormat(wgpu::TextureFormat::R16Float, GL_R16F, GL_RED, GL_HALF_FLOAT, Type::Float);
@@ -62,6 +64,8 @@
AddFormat(wgpu::TextureFormat::R32Uint, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, Type::Uint);
AddFormat(wgpu::TextureFormat::R32Sint, GL_R32I, GL_RED_INTEGER, GL_INT, Type::Int);
AddFormat(wgpu::TextureFormat::R32Float, GL_R32F, GL_RED, GL_FLOAT, Type::Float);
+ AddFormat(wgpu::TextureFormat::RG16Unorm, GL_RG16, GL_RG, GL_UNSIGNED_SHORT, Type::Float);
+ AddFormat(wgpu::TextureFormat::RG16Snorm, GL_RG16_SNORM, GL_RG, GL_SHORT, Type::Float);
AddFormat(wgpu::TextureFormat::RG16Uint, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, Type::Uint);
AddFormat(wgpu::TextureFormat::RG16Sint, GL_RG16I, GL_RG_INTEGER, GL_SHORT, Type::Int);
AddFormat(wgpu::TextureFormat::RG16Float, GL_RG16F, GL_RG, GL_HALF_FLOAT, Type::Float);
@@ -80,6 +84,8 @@
AddFormat(wgpu::TextureFormat::RG32Uint, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, Type::Uint);
AddFormat(wgpu::TextureFormat::RG32Sint, GL_RG32I, GL_RG_INTEGER, GL_INT, Type::Int);
AddFormat(wgpu::TextureFormat::RG32Float, GL_RG32F, GL_RG, GL_FLOAT, Type::Float);
+ AddFormat(wgpu::TextureFormat::RGBA16Unorm, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, Type::Float);
+ AddFormat(wgpu::TextureFormat::RGBA16Snorm, GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, Type::Float);
AddFormat(wgpu::TextureFormat::RGBA16Uint, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, Type::Uint);
AddFormat(wgpu::TextureFormat::RGBA16Sint, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, Type::Int);
AddFormat(wgpu::TextureFormat::RGBA16Float, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, Type::Float);
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 5ef5e48..483d3a5 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -218,6 +218,11 @@
mFunctions.IsAtLeastGL(3, 3)) {
EnableFeature(Feature::DualSourceBlending);
}
+
+ // Norm16TextureFormats
+ if (mFunctions.IsGLExtensionSupported("GL_EXT_texture_norm16")) {
+ EnableFeature(Feature::Norm16TextureFormats);
+ }
}
namespace {
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 6e41986..651636e 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -260,6 +260,23 @@
EnableFeature(Feature::BGRA8UnormStorage);
}
+ bool norm16TextureFormatsSupported = true;
+ for (const auto& norm16Format :
+ {VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16B16A16_UNORM,
+ VK_FORMAT_R16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16B16A16_SNORM}) {
+ VkFormatProperties norm16Properties;
+ mVulkanInstance->GetFunctions().GetPhysicalDeviceFormatProperties(
+ mVkPhysicalDevice, norm16Format, &norm16Properties);
+ norm16TextureFormatsSupported &= IsSubset(
+ static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT),
+ norm16Properties.optimalTilingFeatures);
+ }
+ if (norm16TextureFormatsSupported) {
+ EnableFeature(Feature::Norm16TextureFormats);
+ }
+
// 32 bit float channel formats.
VkFormatProperties r32Properties;
VkFormatProperties rg32Properties;
diff --git a/src/dawn/native/vulkan/TextureVk.cpp b/src/dawn/native/vulkan/TextureVk.cpp
index 9af6681..f9a36b4 100644
--- a/src/dawn/native/vulkan/TextureVk.cpp
+++ b/src/dawn/native/vulkan/TextureVk.cpp
@@ -254,6 +254,10 @@
case wgpu::TextureFormat::R8Sint:
return VK_FORMAT_R8_SINT;
+ case wgpu::TextureFormat::R16Unorm:
+ return VK_FORMAT_R16_UNORM;
+ case wgpu::TextureFormat::R16Snorm:
+ return VK_FORMAT_R16_SNORM;
case wgpu::TextureFormat::R16Uint:
return VK_FORMAT_R16_UINT;
case wgpu::TextureFormat::R16Sint:
@@ -275,6 +279,10 @@
return VK_FORMAT_R32_SINT;
case wgpu::TextureFormat::R32Float:
return VK_FORMAT_R32_SFLOAT;
+ case wgpu::TextureFormat::RG16Unorm:
+ return VK_FORMAT_R16G16_UNORM;
+ case wgpu::TextureFormat::RG16Snorm:
+ return VK_FORMAT_R16G16_SNORM;
case wgpu::TextureFormat::RG16Uint:
return VK_FORMAT_R16G16_UINT;
case wgpu::TextureFormat::RG16Sint:
@@ -308,6 +316,10 @@
return VK_FORMAT_R32G32_SINT;
case wgpu::TextureFormat::RG32Float:
return VK_FORMAT_R32G32_SFLOAT;
+ case wgpu::TextureFormat::RGBA16Unorm:
+ return VK_FORMAT_R16G16B16A16_UNORM;
+ case wgpu::TextureFormat::RGBA16Snorm:
+ return VK_FORMAT_R16G16B16A16_SNORM;
case wgpu::TextureFormat::RGBA16Uint:
return VK_FORMAT_R16G16B16A16_UINT;
case wgpu::TextureFormat::RGBA16Sint:
diff --git a/src/dawn/tests/end2end/TextureFormatTests.cpp b/src/dawn/tests/end2end/TextureFormatTests.cpp
index 421ea3e..f247a15 100644
--- a/src/dawn/tests/end2end/TextureFormatTests.cpp
+++ b/src/dawn/tests/end2end/TextureFormatTests.cpp
@@ -440,6 +440,9 @@
ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize);
ASSERT(formatInfo.type == TextureComponentType::Float);
+ DAWN_TEST_UNSUPPORTED_IF((utils::IsNorm16TextureFormat(formatInfo.format)) &&
+ !IsNorm16TextureFormatsSupported());
+
T maxValue = std::numeric_limits<T>::max();
std::vector<T> textureData = {0, 1, maxValue, maxValue};
std::vector<float> uncompressedData = {0.0f, 1.0f / maxValue, 1.0f, 1.0f};
@@ -454,6 +457,9 @@
ASSERT(sizeof(T) * formatInfo.componentCount == formatInfo.texelByteSize);
ASSERT(formatInfo.type == TextureComponentType::Float);
+ DAWN_TEST_UNSUPPORTED_IF((utils::IsNorm16TextureFormat(formatInfo.format)) &&
+ !IsNorm16TextureFormatsSupported());
+
T maxValue = std::numeric_limits<T>::max();
T minValue = std::numeric_limits<T>::min();
std::vector<T> textureData = {0, 1, -1, maxValue, minValue, T(minValue + 1), 0, 0};
@@ -523,21 +529,25 @@
new ExpectFloat16(textureData));
}
- // For "rg11b10ufloat-renderable" feature test
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
+ std::vector<wgpu::FeatureName> requiredFeatures = {};
if (SupportsFeatures({wgpu::FeatureName::RG11B10UfloatRenderable})) {
mIsRG11B10UfloatRenderableSupported = true;
- return {wgpu::FeatureName::RG11B10UfloatRenderable};
- } else {
- mIsRG11B10UfloatRenderableSupported = false;
- return {};
+ requiredFeatures.push_back(wgpu::FeatureName::RG11B10UfloatRenderable);
}
+ if (SupportsFeatures({wgpu::FeatureName::Norm16TextureFormats})) {
+ mIsNorm16TextureFormatsSupported = true;
+ requiredFeatures.push_back(wgpu::FeatureName::Norm16TextureFormats);
+ }
+ return requiredFeatures;
}
bool IsRG11B10UfloatRenderableSupported() { return mIsRG11B10UfloatRenderableSupported; }
+ bool IsNorm16TextureFormatsSupported() { return mIsNorm16TextureFormatsSupported; }
private:
bool mIsRG11B10UfloatRenderableSupported = false;
+ bool mIsNorm16TextureFormatsSupported = false;
};
// Test the R8Unorm format
@@ -550,6 +560,21 @@
DoUnormTest<uint8_t>({wgpu::TextureFormat::RG8Unorm, 2, TextureComponentType::Float, 2});
}
+// Test the R16Unorm format
+TEST_P(TextureFormatTest, R16Unorm) {
+ DoUnormTest<uint16_t>({wgpu::TextureFormat::R16Unorm, 2, TextureComponentType::Float, 1});
+}
+
+// Test the RG16Unorm format
+TEST_P(TextureFormatTest, RG16Unorm) {
+ DoUnormTest<uint16_t>({wgpu::TextureFormat::RG16Unorm, 4, TextureComponentType::Float, 2});
+}
+
+// Test the RGBA16Unorm format
+TEST_P(TextureFormatTest, RGBA16Unorm) {
+ DoUnormTest<uint16_t>({wgpu::TextureFormat::RGBA16Unorm, 8, TextureComponentType::Float, 4});
+}
+
// Test the RGBA8Unorm format
TEST_P(TextureFormatTest, RGBA8Unorm) {
DoUnormTest<uint8_t>({wgpu::TextureFormat::RGBA8Unorm, 4, TextureComponentType::Float, 4});
@@ -585,6 +610,21 @@
DoSnormTest<int8_t>({wgpu::TextureFormat::RGBA8Snorm, 4, TextureComponentType::Float, 4});
}
+// Test the R16Snorm format
+TEST_P(TextureFormatTest, R16Snorm) {
+ DoSnormTest<int16_t>({wgpu::TextureFormat::R16Snorm, 2, TextureComponentType::Float, 1});
+}
+
+// Test the RG16Snorm format
+TEST_P(TextureFormatTest, RG16Snorm) {
+ DoSnormTest<int16_t>({wgpu::TextureFormat::RG16Snorm, 4, TextureComponentType::Float, 2});
+}
+
+// Test the RGBA16Snorm format
+TEST_P(TextureFormatTest, RGBA16Snorm) {
+ DoSnormTest<int16_t>({wgpu::TextureFormat::RGBA16Snorm, 8, TextureComponentType::Float, 4});
+}
+
// Test the R8Uint format
TEST_P(TextureFormatTest, R8Uint) {
DoUintTest<uint8_t>({wgpu::TextureFormat::R8Uint, 1, TextureComponentType::Uint, 1});
diff --git a/src/dawn/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp b/src/dawn/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
index e15373e..7b2979b 100644
--- a/src/dawn/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
@@ -993,7 +993,7 @@
// Tests the texture format of the resolve target must support being used as resolve target.
TEST_F(MultisampledRenderPassDescriptorValidationTest, ResolveTargetFormat) {
for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
- if (!utils::TextureFormatSupportsMultisampling(format) ||
+ if (!utils::TextureFormatSupportsMultisampling(device, format) ||
utils::IsDepthOrStencilFormat(format)) {
continue;
}
@@ -1006,7 +1006,7 @@
utils::ComboRenderPassDescriptor renderPass({colorTexture.CreateView()});
renderPass.cColorAttachments[0].resolveTarget = resolveTarget.CreateView();
- if (utils::TextureFormatSupportsResolveTarget(format)) {
+ if (utils::TextureFormatSupportsResolveTarget(device, format)) {
AssertBeginRenderPassSuccess(&renderPass);
} else {
AssertBeginRenderPassError(&renderPass);
diff --git a/src/dawn/tests/unittests/validation/TextureValidationTests.cpp b/src/dawn/tests/unittests/validation/TextureValidationTests.cpp
index 2cb0fc8..7d28eaf 100644
--- a/src/dawn/tests/unittests/validation/TextureValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/TextureValidationTests.cpp
@@ -147,7 +147,7 @@
for (wgpu::TextureFormat format : utils::kFormatsInCoreSpec) {
descriptor.format = format;
- if (utils::TextureFormatSupportsMultisampling(format)) {
+ if (utils::TextureFormatSupportsMultisampling(device, format)) {
device.CreateTexture(&descriptor);
} else {
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
@@ -921,6 +921,43 @@
device.CreateTexture(&descriptor);
}
+class Norm16TextureFormatsValidationTests : public TextureValidationTest {
+ protected:
+ WGPUDevice CreateTestDevice(native::Adapter dawnAdapter,
+ wgpu::DeviceDescriptor descriptor) override {
+ wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Norm16TextureFormats};
+ descriptor.requiredFeatures = requiredFeatures;
+ descriptor.requiredFeatureCount = 1;
+ return dawnAdapter.CreateDevice(&descriptor);
+ }
+};
+
+// Test that Norm16 formats are valid as renderable and sample-able texture if
+// 'norm16-texture-formats' is enabled.
+TEST_F(Norm16TextureFormatsValidationTests, RenderAndSample) {
+ wgpu::TextureDescriptor descriptor;
+ descriptor.size = {1, 1, 1};
+ descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
+
+ descriptor.format = wgpu::TextureFormat::R16Unorm;
+ device.CreateTexture(&descriptor);
+
+ descriptor.format = wgpu::TextureFormat::RG16Unorm;
+ device.CreateTexture(&descriptor);
+
+ descriptor.format = wgpu::TextureFormat::RGBA16Unorm;
+ device.CreateTexture(&descriptor);
+
+ descriptor.format = wgpu::TextureFormat::R16Snorm;
+ device.CreateTexture(&descriptor);
+
+ descriptor.format = wgpu::TextureFormat::RG16Snorm;
+ device.CreateTexture(&descriptor);
+
+ descriptor.format = wgpu::TextureFormat::RGBA16Snorm;
+ device.CreateTexture(&descriptor);
+}
+
static void CheckTextureMatchesDescriptor(const wgpu::Texture& tex,
const wgpu::TextureDescriptor& desc) {
EXPECT_EQ(desc.size.width, tex.GetWidth());
diff --git a/src/dawn/utils/TextureUtils.cpp b/src/dawn/utils/TextureUtils.cpp
index 8f84b9c..9023857 100644
--- a/src/dawn/utils/TextureUtils.cpp
+++ b/src/dawn/utils/TextureUtils.cpp
@@ -121,6 +121,20 @@
}
}
+bool IsNorm16TextureFormat(wgpu::TextureFormat textureFormat) {
+ switch (textureFormat) {
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
+ case wgpu::TextureFormat::RG16Snorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool IsDepthOnlyFormat(wgpu::TextureFormat textureFormat) {
switch (textureFormat) {
case wgpu::TextureFormat::Depth16Unorm:
@@ -155,12 +169,17 @@
}
}
-bool TextureFormatSupportsMultisampling(wgpu::TextureFormat textureFormat) {
+bool TextureFormatSupportsMultisampling(const wgpu::Device& device,
+ wgpu::TextureFormat textureFormat) {
if (IsBCTextureFormat(textureFormat) || IsETC2TextureFormat(textureFormat) ||
IsASTCTextureFormat(textureFormat)) {
return false;
}
+ if (IsNorm16TextureFormat(textureFormat)) {
+ return device.HasFeature(wgpu::FeatureName::Norm16TextureFormats);
+ }
+
switch (textureFormat) {
case wgpu::TextureFormat::R32Uint:
case wgpu::TextureFormat::R32Sint:
@@ -174,15 +193,18 @@
case wgpu::TextureFormat::R8Snorm:
case wgpu::TextureFormat::RG8Snorm:
case wgpu::TextureFormat::RGBA8Snorm:
- case wgpu::TextureFormat::RG11B10Ufloat:
return false;
+ case wgpu::TextureFormat::RG11B10Ufloat:
+ return device.HasFeature(wgpu::FeatureName::RG11B10UfloatRenderable);
+
default:
return true;
}
}
-bool TextureFormatSupportsResolveTarget(wgpu::TextureFormat textureFormat) {
+bool TextureFormatSupportsResolveTarget(const wgpu::Device& device,
+ wgpu::TextureFormat textureFormat) {
switch (textureFormat) {
case wgpu::TextureFormat::R8Unorm:
case wgpu::TextureFormat::RG8Unorm:
@@ -196,6 +218,14 @@
case wgpu::TextureFormat::RGB10A2Unorm:
return true;
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RG16Snorm:
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
+ return device.HasFeature(wgpu::FeatureName::Norm16TextureFormats);
+
default:
return false;
}
@@ -225,6 +255,8 @@
case wgpu::TextureFormat::Stencil8:
return 1u;
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
case wgpu::TextureFormat::R16Uint:
case wgpu::TextureFormat::R16Sint:
case wgpu::TextureFormat::R16Float:
@@ -237,6 +269,8 @@
case wgpu::TextureFormat::R32Float:
case wgpu::TextureFormat::R32Uint:
case wgpu::TextureFormat::R32Sint:
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RG16Snorm:
case wgpu::TextureFormat::RG16Uint:
case wgpu::TextureFormat::RG16Sint:
case wgpu::TextureFormat::RG16Float:
@@ -255,6 +289,8 @@
case wgpu::TextureFormat::RG32Float:
case wgpu::TextureFormat::RG32Uint:
case wgpu::TextureFormat::RG32Sint:
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
case wgpu::TextureFormat::RGBA16Uint:
case wgpu::TextureFormat::RGBA16Sint:
case wgpu::TextureFormat::RGBA16Float:
@@ -352,6 +388,8 @@
case wgpu::TextureFormat::R8Snorm:
case wgpu::TextureFormat::R8Uint:
case wgpu::TextureFormat::R8Sint:
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
case wgpu::TextureFormat::R16Uint:
case wgpu::TextureFormat::R16Sint:
case wgpu::TextureFormat::R16Float:
@@ -362,6 +400,8 @@
case wgpu::TextureFormat::R32Float:
case wgpu::TextureFormat::R32Uint:
case wgpu::TextureFormat::R32Sint:
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RG16Snorm:
case wgpu::TextureFormat::RG16Uint:
case wgpu::TextureFormat::RG16Sint:
case wgpu::TextureFormat::RG16Float:
@@ -378,6 +418,8 @@
case wgpu::TextureFormat::RG32Float:
case wgpu::TextureFormat::RG32Uint:
case wgpu::TextureFormat::RG32Sint:
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
case wgpu::TextureFormat::RGBA16Uint:
case wgpu::TextureFormat::RGBA16Sint:
case wgpu::TextureFormat::RGBA16Float:
@@ -468,6 +510,8 @@
case wgpu::TextureFormat::R8Snorm:
case wgpu::TextureFormat::R8Uint:
case wgpu::TextureFormat::R8Sint:
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
case wgpu::TextureFormat::R16Uint:
case wgpu::TextureFormat::R16Sint:
case wgpu::TextureFormat::R16Float:
@@ -478,6 +522,8 @@
case wgpu::TextureFormat::R32Float:
case wgpu::TextureFormat::R32Uint:
case wgpu::TextureFormat::R32Sint:
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RG16Snorm:
case wgpu::TextureFormat::RG16Uint:
case wgpu::TextureFormat::RG16Sint:
case wgpu::TextureFormat::RG16Float:
@@ -494,6 +540,8 @@
case wgpu::TextureFormat::RG32Float:
case wgpu::TextureFormat::RG32Uint:
case wgpu::TextureFormat::RG32Sint:
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
case wgpu::TextureFormat::RGBA16Uint:
case wgpu::TextureFormat::RGBA16Sint:
case wgpu::TextureFormat::RGBA16Float:
@@ -582,10 +630,14 @@
switch (textureFormat) {
case wgpu::TextureFormat::R8Unorm:
case wgpu::TextureFormat::R8Snorm:
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
case wgpu::TextureFormat::R16Float:
case wgpu::TextureFormat::RG8Unorm:
case wgpu::TextureFormat::RG8Snorm:
case wgpu::TextureFormat::R32Float:
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RG16Snorm:
case wgpu::TextureFormat::RG16Float:
case wgpu::TextureFormat::RGBA8Unorm:
case wgpu::TextureFormat::RGBA8Snorm:
@@ -593,6 +645,8 @@
case wgpu::TextureFormat::RG11B10Ufloat:
case wgpu::TextureFormat::RGB9E5Ufloat:
case wgpu::TextureFormat::RG32Float:
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
case wgpu::TextureFormat::RGBA16Float:
case wgpu::TextureFormat::RGBA32Float:
case wgpu::TextureFormat::BGRA8Unorm:
@@ -632,6 +686,8 @@
case wgpu::TextureFormat::R8Unorm:
case wgpu::TextureFormat::R8Uint:
case wgpu::TextureFormat::R8Sint:
+ case wgpu::TextureFormat::R16Unorm:
+ case wgpu::TextureFormat::R16Snorm:
case wgpu::TextureFormat::R16Uint:
case wgpu::TextureFormat::R16Sint:
case wgpu::TextureFormat::R16Float:
@@ -642,6 +698,8 @@
case wgpu::TextureFormat::RG8Unorm:
case wgpu::TextureFormat::RG8Uint:
case wgpu::TextureFormat::RG8Sint:
+ case wgpu::TextureFormat::RG16Unorm:
+ case wgpu::TextureFormat::RG16Snorm:
case wgpu::TextureFormat::RG16Uint:
case wgpu::TextureFormat::RG16Sint:
case wgpu::TextureFormat::RG16Float:
@@ -656,6 +714,8 @@
case wgpu::TextureFormat::BGRA8Unorm:
case wgpu::TextureFormat::BGRA8UnormSrgb:
case wgpu::TextureFormat::RGB10A2Unorm:
+ case wgpu::TextureFormat::RGBA16Unorm:
+ case wgpu::TextureFormat::RGBA16Snorm:
case wgpu::TextureFormat::RGBA16Uint:
case wgpu::TextureFormat::RGBA16Sint:
case wgpu::TextureFormat::RGBA16Float:
@@ -680,6 +740,10 @@
return "rgba8sint";
case wgpu::TextureFormat::BGRA8Unorm:
return "bgra8unorm";
+ case wgpu::TextureFormat::RGBA16Unorm:
+ return "rgba16unorm";
+ case wgpu::TextureFormat::RGBA16Snorm:
+ return "rgba16snorm";
case wgpu::TextureFormat::RGBA16Uint:
return "rgba16uint";
case wgpu::TextureFormat::RGBA16Sint:
@@ -715,6 +779,10 @@
return "r8uint";
case wgpu::TextureFormat::R8Sint:
return "r8sint";
+ case wgpu::TextureFormat::R16Unorm:
+ return "r16unorm";
+ case wgpu::TextureFormat::R16Snorm:
+ return "r16snorm";
case wgpu::TextureFormat::R16Uint:
return "r16uint";
case wgpu::TextureFormat::R16Sint:
@@ -729,6 +797,10 @@
return "rg8uint";
case wgpu::TextureFormat::RG8Sint:
return "rg8sint";
+ case wgpu::TextureFormat::RG16Unorm:
+ return "rg16unorm";
+ case wgpu::TextureFormat::RG16Snorm:
+ return "rg16snorm";
case wgpu::TextureFormat::RG16Uint:
return "rg16uint";
case wgpu::TextureFormat::RG16Sint:
diff --git a/src/dawn/utils/TextureUtils.h b/src/dawn/utils/TextureUtils.h
index be634a3..780152f 100644
--- a/src/dawn/utils/TextureUtils.h
+++ b/src/dawn/utils/TextureUtils.h
@@ -22,11 +22,13 @@
#include "dawn/common/Assert.h"
namespace dawn::utils {
-static constexpr std::array<wgpu::TextureFormat, 94> kAllTextureFormats = {
+static constexpr std::array<wgpu::TextureFormat, 100> kAllTextureFormats = {
wgpu::TextureFormat::R8Unorm,
wgpu::TextureFormat::R8Snorm,
wgpu::TextureFormat::R8Uint,
wgpu::TextureFormat::R8Sint,
+ wgpu::TextureFormat::R16Unorm,
+ wgpu::TextureFormat::R16Snorm,
wgpu::TextureFormat::R16Uint,
wgpu::TextureFormat::R16Sint,
wgpu::TextureFormat::R16Float,
@@ -37,6 +39,8 @@
wgpu::TextureFormat::R32Float,
wgpu::TextureFormat::R32Uint,
wgpu::TextureFormat::R32Sint,
+ wgpu::TextureFormat::RG16Unorm,
+ wgpu::TextureFormat::RG16Snorm,
wgpu::TextureFormat::RG16Uint,
wgpu::TextureFormat::RG16Sint,
wgpu::TextureFormat::RG16Float,
@@ -53,6 +57,8 @@
wgpu::TextureFormat::RG32Float,
wgpu::TextureFormat::RG32Uint,
wgpu::TextureFormat::RG32Sint,
+ wgpu::TextureFormat::RGBA16Unorm,
+ wgpu::TextureFormat::RGBA16Snorm,
wgpu::TextureFormat::RGBA16Uint,
wgpu::TextureFormat::RGBA16Sint,
wgpu::TextureFormat::RGBA16Float,
@@ -205,6 +211,11 @@
kBCFormats.size() + kETC2Formats.size() + kASTCFormats.size(),
"Number of compressed format must equal number of BC, ETC2, and ASTC formats.");
+static constexpr std::array<wgpu::TextureFormat, 6> kNorm16Formats = {
+ wgpu::TextureFormat::R16Unorm, wgpu::TextureFormat::RG16Unorm, wgpu::TextureFormat::RGBA16Unorm,
+ wgpu::TextureFormat::R16Snorm, wgpu::TextureFormat::RG16Snorm, wgpu::TextureFormat::RGBA16Snorm,
+};
+
static constexpr std::array<wgpu::TextureFormat, 5> kDepthFormats = {
wgpu::TextureFormat::Depth16Unorm, wgpu::TextureFormat::Depth32Float,
wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Depth24PlusStencil8,
@@ -226,6 +237,7 @@
bool IsBCTextureFormat(wgpu::TextureFormat textureFormat);
bool IsETC2TextureFormat(wgpu::TextureFormat textureFormat);
bool IsASTCTextureFormat(wgpu::TextureFormat textureFormat);
+bool IsNorm16TextureFormat(wgpu::TextureFormat textureFormat);
bool IsDepthOnlyFormat(wgpu::TextureFormat textureFormat);
bool IsStencilOnlyFormat(wgpu::TextureFormat textureFormat);
@@ -233,8 +245,10 @@
bool IsMultiPlanarFormat(wgpu::TextureFormat textureFormat);
-bool TextureFormatSupportsMultisampling(wgpu::TextureFormat textureFormat);
-bool TextureFormatSupportsResolveTarget(wgpu::TextureFormat textureFormat);
+bool TextureFormatSupportsMultisampling(const wgpu::Device& device,
+ wgpu::TextureFormat textureFormat);
+bool TextureFormatSupportsResolveTarget(const wgpu::Device& device,
+ wgpu::TextureFormat textureFormat);
uint32_t GetTexelBlockSizeInBytes(wgpu::TextureFormat textureFormat);
uint32_t GetTextureFormatBlockWidth(wgpu::TextureFormat textureFormat);
diff --git a/src/dawn/wire/SupportedFeatures.cpp b/src/dawn/wire/SupportedFeatures.cpp
index b82e806..f5fbeed 100644
--- a/src/dawn/wire/SupportedFeatures.cpp
+++ b/src/dawn/wire/SupportedFeatures.cpp
@@ -66,6 +66,7 @@
case WGPUFeatureName_ChromiumExperimentalReadWriteStorageTexture:
case WGPUFeatureName_PixelLocalStorageCoherent:
case WGPUFeatureName_PixelLocalStorageNonCoherent:
+ case WGPUFeatureName_Norm16TextureFormats:
return true;
}