Implement "rg11b10ufloat-renderable" feature
Implement "rg11b10ufloat-renderable" feature that allows the RENDER_ATTACHMENT usage on textures with format "rg11b10ufloat", and also allows textures of that format to be multisampled. Bug: dawn:1518 Change-Id: I4109dc0e9d90f4c0803219292edea554927a187a Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/102000 Commit-Queue: Takahiro <hogehoge@gachapin.jp> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
00093a35b7
commit
d4dd547bae
|
@ -1386,6 +1386,7 @@
|
||||||
{"value": 7, "name": "texture compression ASTC"},
|
{"value": 7, "name": "texture compression ASTC"},
|
||||||
{"value": 8, "name": "indirect first instance"},
|
{"value": 8, "name": "indirect first instance"},
|
||||||
{"value": 9, "name": "shader f16"},
|
{"value": 9, "name": "shader f16"},
|
||||||
|
{"value": 10, "name": "RG11B10 ufloat renderable"},
|
||||||
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
||||||
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
||||||
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
||||||
|
|
|
@ -68,6 +68,11 @@ static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {{
|
||||||
{"shader-f16", "Supports the \"enable f16;\" directive in WGSL",
|
{"shader-f16", "Supports the \"enable f16;\" directive in WGSL",
|
||||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1510",
|
"https://bugs.chromium.org/p/dawn/issues/detail?id=1510",
|
||||||
FeatureInfo::FeatureState::Experimental}},
|
FeatureInfo::FeatureState::Experimental}},
|
||||||
|
{Feature::RG11B10UfloatRenderable,
|
||||||
|
{"rg11b10ufloat-renderable",
|
||||||
|
"Allows the RENDER_ATTACHMENT usage on textures with format \"rg11b10ufloat\", and also "
|
||||||
|
"allows textures of that format to be multisampled.",
|
||||||
|
"https://bugs.chromium.org/p/dawn/issues/detail?id=1518", FeatureInfo::FeatureState::Stable}},
|
||||||
{Feature::DawnInternalUsages,
|
{Feature::DawnInternalUsages,
|
||||||
{"dawn-internal-usages",
|
{"dawn-internal-usages",
|
||||||
"Add internal usages to resources to affect how the texture is allocated, but not "
|
"Add internal usages to resources to affect how the texture is allocated, but not "
|
||||||
|
@ -119,6 +124,8 @@ Feature FromAPIFeature(wgpu::FeatureName feature) {
|
||||||
return Feature::ChromiumExperimentalDp4a;
|
return Feature::ChromiumExperimentalDp4a;
|
||||||
case wgpu::FeatureName::ShaderF16:
|
case wgpu::FeatureName::ShaderF16:
|
||||||
return Feature::ShaderF16;
|
return Feature::ShaderF16;
|
||||||
|
case wgpu::FeatureName::RG11B10UfloatRenderable:
|
||||||
|
return Feature::RG11B10UfloatRenderable;
|
||||||
}
|
}
|
||||||
return Feature::InvalidEnum;
|
return Feature::InvalidEnum;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +158,8 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
||||||
return wgpu::FeatureName::ChromiumExperimentalDp4a;
|
return wgpu::FeatureName::ChromiumExperimentalDp4a;
|
||||||
case Feature::ShaderF16:
|
case Feature::ShaderF16:
|
||||||
return wgpu::FeatureName::ShaderF16;
|
return wgpu::FeatureName::ShaderF16;
|
||||||
|
case Feature::RG11B10UfloatRenderable:
|
||||||
|
return wgpu::FeatureName::RG11B10UfloatRenderable;
|
||||||
|
|
||||||
case Feature::EnumCount:
|
case Feature::EnumCount:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -37,6 +37,7 @@ enum class Feature {
|
||||||
ChromiumExperimentalDp4a,
|
ChromiumExperimentalDp4a,
|
||||||
IndirectFirstInstance,
|
IndirectFirstInstance,
|
||||||
ShaderF16,
|
ShaderF16,
|
||||||
|
RG11B10UfloatRenderable,
|
||||||
|
|
||||||
// Dawn-specific
|
// Dawn-specific
|
||||||
DawnInternalUsages,
|
DawnInternalUsages,
|
||||||
|
|
|
@ -363,7 +363,8 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
||||||
AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, wgpu::TextureFormat::BGRA8Unorm);
|
AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, wgpu::TextureFormat::BGRA8Unorm);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGB10A2Unorm, true, false, true, true, 4, kAnyFloat, 4);
|
AddColorFormat(wgpu::TextureFormat::RGB10A2Unorm, true, false, true, true, 4, kAnyFloat, 4);
|
||||||
|
|
||||||
AddColorFormat(wgpu::TextureFormat::RG11B10Ufloat, false, false, false, false, 4, kAnyFloat, 3);
|
bool isRG11B10UfloatRenderable = device->HasFeature(Feature::RG11B10UfloatRenderable);
|
||||||
|
AddColorFormat(wgpu::TextureFormat::RG11B10Ufloat, isRG11B10UfloatRenderable, false, isRG11B10UfloatRenderable, false, 4, kAnyFloat, 3);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGB9E5Ufloat, false, false, false, false, 4, kAnyFloat, 3);
|
AddColorFormat(wgpu::TextureFormat::RGB9E5Ufloat, false, false, false, false, 4, kAnyFloat, 3);
|
||||||
|
|
||||||
// 8 bytes color formats
|
// 8 bytes color formats
|
||||||
|
|
|
@ -137,6 +137,7 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
mSupportedFeatures.EnableFeature(Feature::MultiPlanarFormats);
|
mSupportedFeatures.EnableFeature(Feature::MultiPlanarFormats);
|
||||||
mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8);
|
mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8);
|
||||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::RG11B10UfloatRenderable);
|
||||||
|
|
||||||
if (GetBackend()->GetFunctions()->IsDXCAvailable()) {
|
if (GetBackend()->GetFunctions()->IsDXCAvailable()) {
|
||||||
uint64_t dxcVersion = 0;
|
uint64_t dxcVersion = 0;
|
||||||
|
|
|
@ -370,8 +370,8 @@ class Adapter : public AdapterBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||||
|
|
||||||
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::RG11B10UfloatRenderable);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,6 +181,16 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
mSupportedFeatures.EnableFeature(Feature::DepthClipControl);
|
mSupportedFeatures.EnableFeature(Feature::DepthClipControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkFormatProperties properties;
|
||||||
|
mVulkanInstance->GetFunctions().GetPhysicalDeviceFormatProperties(
|
||||||
|
mPhysicalDevice, VK_FORMAT_B10G11R11_UFLOAT_PACK32, &properties);
|
||||||
|
|
||||||
|
if (IsSubset(static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
|
||||||
|
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT),
|
||||||
|
properties.optimalTilingFeatures)) {
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::RG11B10UfloatRenderable);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(DAWN_USE_SYNC_FDS)
|
#if defined(DAWN_USE_SYNC_FDS)
|
||||||
// TODO(chromium:1258986): Precisely enable the feature by querying the device's format
|
// TODO(chromium:1258986): Precisely enable the feature by querying the device's format
|
||||||
// features.
|
// features.
|
||||||
|
|
|
@ -111,6 +111,83 @@ class ExpectFloat16 : public detail::Expectation {
|
||||||
std::vector<uint16_t> mExpected;
|
std::vector<uint16_t> mExpected;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// An expectation for RG11B10Ufloat buffer content that can correctly compare different NaN values
|
||||||
|
class ExpectRG11B10Ufloat : public detail::Expectation {
|
||||||
|
public:
|
||||||
|
explicit ExpectRG11B10Ufloat(std::vector<uint32_t> expected) : mExpected(std::move(expected)) {}
|
||||||
|
|
||||||
|
testing::AssertionResult Check(const void* data, size_t size) override {
|
||||||
|
ASSERT(size == sizeof(uint32_t) * mExpected.size());
|
||||||
|
|
||||||
|
const uint32_t* actual = static_cast<const uint32_t*>(data);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mExpected.size(); ++i) {
|
||||||
|
uint32_t expectedValue = mExpected[i];
|
||||||
|
uint32_t actualValue = actual[i];
|
||||||
|
|
||||||
|
if (!RG11B10UfloatMatch(expectedValue, actualValue)) {
|
||||||
|
testing::AssertionResult result = testing::AssertionFailure()
|
||||||
|
<< "Expected data[" << i << "] to be "
|
||||||
|
<< expectedValue << ", actual " << actualValue
|
||||||
|
<< std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return testing::AssertionSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool RG11B10UfloatMatch(uint32_t expected, uint32_t actual) {
|
||||||
|
const uint32_t expectedR = expected & 0x7FF;
|
||||||
|
const uint32_t expectedG = (expected >> 11) & 0x7FF;
|
||||||
|
const uint32_t expectedB = (expected >> 22) & 0x3FF;
|
||||||
|
|
||||||
|
const uint32_t actualR = actual & 0x7FF;
|
||||||
|
const uint32_t actualG = (actual >> 11) & 0x7FF;
|
||||||
|
const uint32_t actualB = (actual >> 22) & 0x3FF;
|
||||||
|
|
||||||
|
return Float11Match(expectedR, actualR) && Float11Match(expectedG, actualG) &&
|
||||||
|
Float10Match(expectedB, actualB);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Float11Match(uint32_t expected, uint32_t actual) {
|
||||||
|
ASSERT((expected & ~0x7FF) == 0);
|
||||||
|
ASSERT((actual & ~0x7FF) == 0);
|
||||||
|
|
||||||
|
if (IsFloat11NaN(expected)) {
|
||||||
|
return IsFloat11NaN(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expected == actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Float10Match(uint32_t expected, uint32_t actual) {
|
||||||
|
ASSERT((expected & ~0x3FF) == 0);
|
||||||
|
ASSERT((actual & ~0x3FF) == 0);
|
||||||
|
|
||||||
|
if (IsFloat10NaN(expected)) {
|
||||||
|
return IsFloat10NaN(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expected == actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The number is NaN if exponent bits are all 1 and mantissa is non-zero
|
||||||
|
bool IsFloat11NaN(uint32_t value) {
|
||||||
|
ASSERT((value & ~0x7FF) == 0);
|
||||||
|
|
||||||
|
return ((value & 0x7C0) == 0x7C0) && ((value & 0x3F) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsFloat10NaN(uint32_t value) {
|
||||||
|
ASSERT((value & ~0x3FF) == 0);
|
||||||
|
|
||||||
|
return ((value & 0x3E0) == 0x3E0) && ((value & 0x1F) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> mExpected;
|
||||||
|
};
|
||||||
|
|
||||||
class TextureFormatTest : public DawnTest {
|
class TextureFormatTest : public DawnTest {
|
||||||
protected:
|
protected:
|
||||||
// Structure containing all the information that tests need to know about the format.
|
// Structure containing all the information that tests need to know about the format.
|
||||||
|
@ -436,6 +513,22 @@ class TextureFormatTest : public DawnTest {
|
||||||
DoFormatRenderingTest(formatInfo, uncompressedData, textureData,
|
DoFormatRenderingTest(formatInfo, uncompressedData, textureData,
|
||||||
new ExpectFloat16(textureData));
|
new ExpectFloat16(textureData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For "rg11b10ufloat-renderable" feature test
|
||||||
|
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
|
||||||
|
if (SupportsFeatures({wgpu::FeatureName::RG11B10UfloatRenderable})) {
|
||||||
|
mIsRG11B10UfloatRenderableSupported = true;
|
||||||
|
return {wgpu::FeatureName::RG11B10UfloatRenderable};
|
||||||
|
} else {
|
||||||
|
mIsRG11B10UfloatRenderableSupported = false;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRG11B10UfloatRenderableSupported() { return mIsRG11B10UfloatRenderableSupported; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mIsRG11B10UfloatRenderableSupported = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test the R8Unorm format
|
// Test the R8Unorm format
|
||||||
|
@ -740,7 +833,20 @@ TEST_P(TextureFormatTest, RG11B10Ufloat) {
|
||||||
DoFloatFormatSamplingTest(
|
DoFloatFormatSamplingTest(
|
||||||
{wgpu::TextureFormat::RG11B10Ufloat, 4, wgpu::TextureComponentType::Float, 4}, textureData,
|
{wgpu::TextureFormat::RG11B10Ufloat, 4, wgpu::TextureComponentType::Float, 4}, textureData,
|
||||||
uncompressedData);
|
uncompressedData);
|
||||||
// This format is not renderable.
|
|
||||||
|
// This format is renderable if "rg11b10ufloat-renderable" feature is enabled
|
||||||
|
if (IsRG11B10UfloatRenderableSupported()) {
|
||||||
|
// TODO(https://crbug.com/swiftshader/147) Rendering INFINITY and NaN isn't handled
|
||||||
|
// correctly by swiftshader
|
||||||
|
if ((IsVulkan() && IsSwiftshader()) || IsANGLE()) {
|
||||||
|
dawn::WarningLog() << "Skip Rendering test because Swiftshader doesn't render INFINITY "
|
||||||
|
"and NaN correctly for RG11B10Ufloat texture format.";
|
||||||
|
} else {
|
||||||
|
DoFormatRenderingTest(
|
||||||
|
{wgpu::TextureFormat::RG11B10Ufloat, 4, wgpu::TextureComponentType::Float, 4},
|
||||||
|
uncompressedData, textureData, new ExpectRG11B10Ufloat(textureData));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the RGB9E5Ufloat format
|
// Test the RGB9E5Ufloat format
|
||||||
|
|
|
@ -885,6 +885,29 @@ TEST_F(CompressedTextureFormatsValidationTests, TextureSize) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RG11B10UfloatTextureFormatsValidationTests : public TextureValidationTest {
|
||||||
|
protected:
|
||||||
|
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||||
|
wgpu::DeviceDescriptor descriptor;
|
||||||
|
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::RG11B10UfloatRenderable};
|
||||||
|
descriptor.requiredFeatures = requiredFeatures;
|
||||||
|
descriptor.requiredFeaturesCount = 1;
|
||||||
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test that RG11B10Ufloat format is valid as render attachment and also it allows
|
||||||
|
// multisampling if "rg11b10ufloat-renderable" feature is enabled
|
||||||
|
TEST_F(RG11B10UfloatTextureFormatsValidationTests, RenderableFeature) {
|
||||||
|
wgpu::TextureDescriptor descriptor;
|
||||||
|
descriptor.size = {1, 1, 1};
|
||||||
|
descriptor.usage = wgpu::TextureUsage::RenderAttachment;
|
||||||
|
|
||||||
|
descriptor.format = wgpu::TextureFormat::RG11B10Ufloat;
|
||||||
|
descriptor.sampleCount = 4;
|
||||||
|
device.CreateTexture(&descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
static void CheckTextureMatchesDescriptor(const wgpu::Texture& tex,
|
static void CheckTextureMatchesDescriptor(const wgpu::Texture& tex,
|
||||||
const wgpu::TextureDescriptor& desc) {
|
const wgpu::TextureDescriptor& desc) {
|
||||||
EXPECT_EQ(desc.size.width, tex.GetWidth());
|
EXPECT_EQ(desc.size.width, tex.GetWidth());
|
||||||
|
|
|
@ -37,6 +37,7 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
||||||
case WGPUFeatureName_DawnMultiPlanarFormats:
|
case WGPUFeatureName_DawnMultiPlanarFormats:
|
||||||
case WGPUFeatureName_ChromiumExperimentalDp4a:
|
case WGPUFeatureName_ChromiumExperimentalDp4a:
|
||||||
case WGPUFeatureName_ShaderF16:
|
case WGPUFeatureName_ShaderF16:
|
||||||
|
case WGPUFeatureName_RG11B10UfloatRenderable:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue