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": 8, "name": "indirect first instance"},
|
||||
{"value": 9, "name": "shader f16"},
|
||||
{"value": 10, "name": "RG11B10 ufloat renderable"},
|
||||
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
||||
{"value": 1002, "name": "dawn internal usages", "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",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1510",
|
||||
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,
|
||||
{"dawn-internal-usages",
|
||||
"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;
|
||||
case wgpu::FeatureName::ShaderF16:
|
||||
return Feature::ShaderF16;
|
||||
case wgpu::FeatureName::RG11B10UfloatRenderable:
|
||||
return Feature::RG11B10UfloatRenderable;
|
||||
}
|
||||
return Feature::InvalidEnum;
|
||||
}
|
||||
|
@ -151,6 +158,8 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
|||
return wgpu::FeatureName::ChromiumExperimentalDp4a;
|
||||
case Feature::ShaderF16:
|
||||
return wgpu::FeatureName::ShaderF16;
|
||||
case Feature::RG11B10UfloatRenderable:
|
||||
return wgpu::FeatureName::RG11B10UfloatRenderable;
|
||||
|
||||
case Feature::EnumCount:
|
||||
break;
|
||||
|
|
|
@ -37,6 +37,7 @@ enum class Feature {
|
|||
ChromiumExperimentalDp4a,
|
||||
IndirectFirstInstance,
|
||||
ShaderF16,
|
||||
RG11B10UfloatRenderable,
|
||||
|
||||
// Dawn-specific
|
||||
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::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);
|
||||
|
||||
// 8 bytes color formats
|
||||
|
|
|
@ -137,6 +137,7 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
|||
mSupportedFeatures.EnableFeature(Feature::MultiPlanarFormats);
|
||||
mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8);
|
||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||
mSupportedFeatures.EnableFeature(Feature::RG11B10UfloatRenderable);
|
||||
|
||||
if (GetBackend()->GetFunctions()->IsDXCAvailable()) {
|
||||
uint64_t dxcVersion = 0;
|
||||
|
|
|
@ -370,8 +370,8 @@ class Adapter : public AdapterBase {
|
|||
}
|
||||
|
||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||
|
||||
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||
mSupportedFeatures.EnableFeature(Feature::RG11B10UfloatRenderable);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -181,6 +181,16 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
|||
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)
|
||||
// TODO(chromium:1258986): Precisely enable the feature by querying the device's format
|
||||
// features.
|
||||
|
|
|
@ -111,6 +111,83 @@ class ExpectFloat16 : public detail::Expectation {
|
|||
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 {
|
||||
protected:
|
||||
// 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,
|
||||
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
|
||||
|
@ -740,7 +833,20 @@ TEST_P(TextureFormatTest, RG11B10Ufloat) {
|
|||
DoFloatFormatSamplingTest(
|
||||
{wgpu::TextureFormat::RG11B10Ufloat, 4, wgpu::TextureComponentType::Float, 4}, textureData,
|
||||
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
|
||||
|
|
|
@ -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,
|
||||
const wgpu::TextureDescriptor& desc) {
|
||||
EXPECT_EQ(desc.size.width, tex.GetWidth());
|
||||
|
|
|
@ -37,6 +37,7 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
|||
case WGPUFeatureName_DawnMultiPlanarFormats:
|
||||
case WGPUFeatureName_ChromiumExperimentalDp4a:
|
||||
case WGPUFeatureName_ShaderF16:
|
||||
case WGPUFeatureName_RG11B10UfloatRenderable:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue