Generalize multi-aspect formats
Removes special casing depth-stencil or multi-planar formats. Like depth-stencil, NV12 views can be created but not sampled. BUG=dawn:551 Change-Id: I3cd43d079253f4ee45660d0efd2723e1650f88d3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/41342 Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com> Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Bryan Bernhart <bryan.bernhart@intel.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
6dd34f7e34
commit
536c7aea7d
33
dawn.json
33
dawn.json
|
@ -1819,23 +1819,24 @@
|
|||
|
||||
{"value": 37, "name": "depth32 float"},
|
||||
{"value": 38, "name": "depth24 plus"},
|
||||
{"value": 39, "name": "depth24 plus stencil8"},
|
||||
{"value": 39, "name": "stencil8"},
|
||||
{"value": 40, "name": "depth24 plus stencil8"},
|
||||
|
||||
{"value": 40, "name": "BC1 RGBA unorm"},
|
||||
{"value": 41, "name": "BC1 RGBA unorm srgb"},
|
||||
{"value": 42, "name": "BC2 RGBA unorm"},
|
||||
{"value": 43, "name": "BC2 RGBA unorm srgb"},
|
||||
{"value": 44, "name": "BC3 RGBA unorm"},
|
||||
{"value": 45, "name": "BC3 RGBA unorm srgb"},
|
||||
{"value": 46, "name": "BC4 R unorm"},
|
||||
{"value": 47, "name": "BC4 R snorm"},
|
||||
{"value": 48, "name": "BC5 RG unorm"},
|
||||
{"value": 49, "name": "BC5 RG snorm"},
|
||||
{"value": 50, "name": "BC6H RGB ufloat"},
|
||||
{"value": 51, "name": "BC6H RGB float"},
|
||||
{"value": 52, "name": "BC7 RGBA unorm"},
|
||||
{"value": 53, "name": "BC7 RGBA unorm srgb"},
|
||||
{"value": 54, "name": "R8 BG8 Biplanar 420 unorm"}
|
||||
{"value": 41, "name": "BC1 RGBA unorm"},
|
||||
{"value": 42, "name": "BC1 RGBA unorm srgb"},
|
||||
{"value": 43, "name": "BC2 RGBA unorm"},
|
||||
{"value": 44, "name": "BC2 RGBA unorm srgb"},
|
||||
{"value": 45, "name": "BC3 RGBA unorm"},
|
||||
{"value": 46, "name": "BC3 RGBA unorm srgb"},
|
||||
{"value": 47, "name": "BC4 R unorm"},
|
||||
{"value": 48, "name": "BC4 R snorm"},
|
||||
{"value": 49, "name": "BC5 RG unorm"},
|
||||
{"value": 50, "name": "BC5 RG snorm"},
|
||||
{"value": 51, "name": "BC6H RGB ufloat"},
|
||||
{"value": 52, "name": "BC6H RGB float"},
|
||||
{"value": 53, "name": "BC7 RGBA unorm"},
|
||||
{"value": 54, "name": "BC7 RGBA unorm srgb"},
|
||||
{"value": 55, "name": "R8 BG8 Biplanar 420 unorm"}
|
||||
]
|
||||
},
|
||||
"texture usage": {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "dawn_native/Format.h"
|
||||
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/EnumMaskIterator.h"
|
||||
#include "dawn_native/Extensions.h"
|
||||
#include "dawn_native/Texture.h"
|
||||
|
||||
|
@ -22,22 +23,6 @@
|
|||
|
||||
namespace dawn_native {
|
||||
|
||||
namespace {
|
||||
|
||||
static const AspectInfo kStencil8AspectInfo = {{1, 1, 1},
|
||||
wgpu::TextureComponentType::Uint,
|
||||
ComponentTypeBit::Uint};
|
||||
|
||||
// R8BG8Biplanar420Unorm must be specialized since it represents planar data and cannot be
|
||||
// used without a per plane format. In particular, the component type is float since
|
||||
// Dawn does not allow texture format reinterpretion (ex. using R8BG82plane420 with Uint or
|
||||
// Unorm). Block size is always zero since the format is not renderable or copyable.
|
||||
static const AspectInfo kR8BG8Biplanar420UnormAspectInfo = {
|
||||
{0, 0, 0},
|
||||
wgpu::TextureComponentType::Float,
|
||||
ComponentTypeBit::Float};
|
||||
}
|
||||
|
||||
// Format
|
||||
|
||||
// TODO(dawn:527): Remove when unused.
|
||||
|
@ -113,50 +98,21 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
const AspectInfo& Format::GetAspectInfo(wgpu::TextureAspect aspect) const {
|
||||
return GetAspectInfo(ConvertAspect(*this, aspect));
|
||||
return GetAspectInfo(SelectFormatAspects(*this, aspect));
|
||||
}
|
||||
|
||||
const AspectInfo& Format::GetAspectInfo(Aspect aspect) const {
|
||||
ASSERT(HasOneBit(aspect));
|
||||
ASSERT(aspects & aspect);
|
||||
|
||||
// The stencil aspect is the only aspect that's not the first aspect. Since it is always the
|
||||
// same aspect information, special case it to return a constant AspectInfo.
|
||||
if (aspect == Aspect::Stencil) {
|
||||
return kStencil8AspectInfo;
|
||||
// multi-planar formats are specified per plane aspect. Since it does not support
|
||||
// non-planar access, it can always be the same aspect information, special cased to
|
||||
// return a constant AspectInfo.
|
||||
// TODO(dawn:551): Refactor and remove GetAspectFormat.
|
||||
} else if (format == wgpu::TextureFormat::R8BG8Biplanar420Unorm) {
|
||||
return kR8BG8Biplanar420UnormAspectInfo;
|
||||
} else {
|
||||
return firstAspect;
|
||||
}
|
||||
const size_t aspectIndex = GetAspectIndex(aspect);
|
||||
ASSERT(aspectIndex < GetAspectCount(aspects));
|
||||
return aspectInfo[aspectIndex];
|
||||
}
|
||||
|
||||
size_t Format::GetIndex() const {
|
||||
return ComputeFormatIndex(format);
|
||||
}
|
||||
|
||||
wgpu::TextureFormat Format::GetAspectFormat(wgpu::TextureAspect aspect) const {
|
||||
switch (format) {
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
switch (aspect) {
|
||||
case wgpu::TextureAspect::Plane0Only:
|
||||
return wgpu::TextureFormat::R8Unorm;
|
||||
case wgpu::TextureAspect::Plane1Only:
|
||||
return wgpu::TextureFormat::RG8Unorm;
|
||||
default:
|
||||
return wgpu::TextureFormat::Undefined;
|
||||
}
|
||||
break;
|
||||
// TODO(dawn:551): Consider using for depth-stencil formats.
|
||||
default:
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation details of the format table of the DeviceBase
|
||||
|
||||
// For the enum for formats are packed but this might change when we have a broader extension
|
||||
|
@ -185,9 +141,9 @@ namespace dawn_native {
|
|||
|
||||
// Vulkan describes bytesPerRow in units of texels. If there's any format for which this
|
||||
// ASSERT isn't true, then additional validation on bytesPerRow must be added.
|
||||
// Multi-planar formats are not copyable and have no first aspect.
|
||||
ASSERT(format.IsMultiPlanar() ||
|
||||
(kTextureBytesPerRowAlignment % format.firstAspect.block.byteSize) == 0);
|
||||
const bool hasMultipleAspects = !HasOneBit(format.aspects);
|
||||
ASSERT(hasMultipleAspects ||
|
||||
(kTextureBytesPerRowAlignment % format.aspectInfo[0].block.byteSize) == 0);
|
||||
|
||||
table[index] = format;
|
||||
formatsSet.set(index);
|
||||
|
@ -203,29 +159,50 @@ namespace dawn_native {
|
|||
internalFormat.isSupported = true;
|
||||
internalFormat.supportsStorageUsage = supportsStorageUsage;
|
||||
internalFormat.aspects = Aspect::Color;
|
||||
internalFormat.firstAspect.block.byteSize = byteSize;
|
||||
internalFormat.firstAspect.block.width = 1;
|
||||
internalFormat.firstAspect.block.height = 1;
|
||||
internalFormat.firstAspect.baseType = type;
|
||||
internalFormat.firstAspect.supportedComponentTypes = ToComponentTypeBit(type);
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = 1;
|
||||
firstAspect->block.height = 1;
|
||||
firstAspect->baseType = type;
|
||||
firstAspect->supportedComponentTypes = ToComponentTypeBit(type);
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
auto AddDepthStencilFormat = [&AddFormat](wgpu::TextureFormat format, Aspect aspects,
|
||||
uint32_t byteSize) {
|
||||
auto AddDepthFormat = [&AddFormat](wgpu::TextureFormat format, uint32_t byteSize) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = true;
|
||||
internalFormat.isCompressed = false;
|
||||
internalFormat.isSupported = true;
|
||||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = aspects;
|
||||
internalFormat.firstAspect.block.byteSize = byteSize;
|
||||
internalFormat.firstAspect.block.width = 1;
|
||||
internalFormat.firstAspect.block.height = 1;
|
||||
internalFormat.firstAspect.baseType = wgpu::TextureComponentType::Float;
|
||||
internalFormat.firstAspect.supportedComponentTypes =
|
||||
internalFormat.aspects = Aspect::Depth;
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = 1;
|
||||
firstAspect->block.height = 1;
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
firstAspect->supportedComponentTypes =
|
||||
ComponentTypeBit::Float | ComponentTypeBit::DepthComparison;
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
auto AddStencilFormat = [&AddFormat](wgpu::TextureFormat format) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = true;
|
||||
internalFormat.isCompressed = false;
|
||||
internalFormat.isSupported = false;
|
||||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = Aspect::Stencil;
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = 1;
|
||||
firstAspect->block.width = 1;
|
||||
firstAspect->block.height = 1;
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Uint;
|
||||
firstAspect->supportedComponentTypes = ComponentTypeBit::Uint;
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
|
@ -238,23 +215,34 @@ namespace dawn_native {
|
|||
internalFormat.isSupported = isSupported;
|
||||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = Aspect::Color;
|
||||
internalFormat.firstAspect.block.byteSize = byteSize;
|
||||
internalFormat.firstAspect.block.width = width;
|
||||
internalFormat.firstAspect.block.height = height;
|
||||
internalFormat.firstAspect.baseType = wgpu::TextureComponentType::Float;
|
||||
internalFormat.firstAspect.supportedComponentTypes = ComponentTypeBit::Float;
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = width;
|
||||
firstAspect->block.height = height;
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
firstAspect->supportedComponentTypes = ComponentTypeBit::Float;
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
auto AddMultiPlanarFormat = [&AddFormat](wgpu::TextureFormat format, Aspect aspects,
|
||||
bool isSupported) {
|
||||
auto AddMultiAspectFormat = [&AddFormat, &table](wgpu::TextureFormat format, Aspect aspects,
|
||||
wgpu::TextureFormat firstFormat,
|
||||
wgpu::TextureFormat secondFormat,
|
||||
bool isRenderable, bool isSupported) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = false;
|
||||
internalFormat.isRenderable = isRenderable;
|
||||
internalFormat.isCompressed = false;
|
||||
internalFormat.isSupported = isSupported;
|
||||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = aspects;
|
||||
|
||||
const size_t firstFormatIndex = ComputeFormatIndex(firstFormat);
|
||||
const size_t secondFormatIndex = ComputeFormatIndex(secondFormat);
|
||||
|
||||
internalFormat.aspectInfo[0] = table[firstFormatIndex].aspectInfo[0];
|
||||
internalFormat.aspectInfo[1] = table[secondFormatIndex].aspectInfo[0];
|
||||
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
|
@ -308,12 +296,14 @@ namespace dawn_native {
|
|||
AddColorFormat(wgpu::TextureFormat::RGBA32Float, true, true, 16, Type::Float);
|
||||
|
||||
// Depth-stencil formats
|
||||
AddDepthStencilFormat(wgpu::TextureFormat::Depth32Float, Aspect::Depth, 4);
|
||||
AddDepthStencilFormat(wgpu::TextureFormat::Depth24Plus, Aspect::Depth, 4);
|
||||
AddDepthFormat(wgpu::TextureFormat::Depth32Float, 4);
|
||||
AddDepthFormat(wgpu::TextureFormat::Depth24Plus, 4);
|
||||
// TODO(dawn:666): Implement the stencil8 format
|
||||
AddStencilFormat(wgpu::TextureFormat::Stencil8);
|
||||
// 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(wgpu::TextureFormat::Depth24PlusStencil8,
|
||||
Aspect::Depth | Aspect::Stencil, 4);
|
||||
AddMultiAspectFormat(wgpu::TextureFormat::Depth24PlusStencil8,
|
||||
Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, true);
|
||||
|
||||
// BC compressed formats
|
||||
bool isBCFormatSupported = device->IsExtensionEnabled(Extension::TextureCompressionBC);
|
||||
|
@ -334,7 +324,8 @@ namespace dawn_native {
|
|||
|
||||
// multi-planar formats
|
||||
const bool isMultiPlanarFormatSupported = device->IsExtensionEnabled(Extension::MultiPlanarFormats);
|
||||
AddMultiPlanarFormat(wgpu::TextureFormat::R8BG8Biplanar420Unorm, Aspect::Plane0 | Aspect::Plane1, isMultiPlanarFormatSupported);
|
||||
AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar420Unorm, Aspect::Plane0 | Aspect::Plane1,
|
||||
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, false, isMultiPlanarFormatSupported);
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -68,11 +68,16 @@ namespace dawn_native {
|
|||
TexelBlockInfo block;
|
||||
wgpu::TextureComponentType baseType;
|
||||
ComponentTypeBit supportedComponentTypes;
|
||||
wgpu::TextureFormat format;
|
||||
};
|
||||
|
||||
// The number of formats Dawn knows about. Asserts in BuildFormatTable ensure that this is the
|
||||
// exact number of known format.
|
||||
static constexpr size_t kKnownFormatCount = 54;
|
||||
static constexpr size_t kKnownFormatCount = 55;
|
||||
|
||||
// The maximum number of planes per format Dawn knows about. Asserts in BuildFormatTable that
|
||||
// the per plane index does not exceed the known maximum plane count
|
||||
static constexpr uint32_t kMaxPlanesPerFormat = 2;
|
||||
|
||||
struct Format;
|
||||
using FormatTable = std::array<Format, kKnownFormatCount>;
|
||||
|
@ -103,14 +108,12 @@ namespace dawn_native {
|
|||
// in [0, kKnownFormatCount)
|
||||
size_t GetIndex() const;
|
||||
|
||||
// Used to lookup the compatible view format using an aspect which corresponds to the
|
||||
// plane index. Returns Undefined if the wrong plane aspect is requested.
|
||||
wgpu::TextureFormat GetAspectFormat(wgpu::TextureAspect aspect) const;
|
||||
|
||||
private:
|
||||
// The most common aspect: the color aspect for color texture, the depth aspect for
|
||||
// depth[-stencil] textures.
|
||||
AspectInfo firstAspect;
|
||||
// Used to store the aspectInfo for one or more planes. For single plane "color" formats,
|
||||
// only the first aspect info or aspectInfo[0] is valid. For depth-stencil, the first aspect
|
||||
// info is depth and the second aspect info is stencil. For multi-planar formats,
|
||||
// aspectInfo[i] is the ith plane.
|
||||
std::array<AspectInfo, kMaxPlanesPerFormat> aspectInfo;
|
||||
|
||||
friend FormatTable BuildFormatTable(const DeviceBase* device);
|
||||
};
|
||||
|
|
|
@ -29,7 +29,13 @@ namespace dawn_native {
|
|||
// TODO(jiawei.shao@intel.com): implement texture view format compatibility rule
|
||||
MaybeError ValidateTextureViewFormatCompatibility(const TextureBase* texture,
|
||||
const TextureViewDescriptor* descriptor) {
|
||||
if (texture->GetFormat().GetAspectFormat(descriptor->aspect) != descriptor->format) {
|
||||
if (texture->GetFormat().format != descriptor->format) {
|
||||
if (descriptor->aspect != wgpu::TextureAspect::All &&
|
||||
texture->GetFormat().GetAspectInfo(descriptor->aspect).format ==
|
||||
descriptor->format) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"The format of texture view is not compatible to the original texture");
|
||||
}
|
||||
|
@ -357,7 +363,8 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
if (desc.format == wgpu::TextureFormat::Undefined) {
|
||||
desc.format = texture->GetFormat().GetAspectFormat(desc.aspect);
|
||||
// TODO(dawn:682): Use GetAspectInfo(aspect).
|
||||
desc.format = texture->GetFormat().format;
|
||||
}
|
||||
if (desc.arrayLayerCount == 0) {
|
||||
desc.arrayLayerCount = texture->GetArrayLayers() - desc.baseArrayLayer;
|
||||
|
|
|
@ -203,6 +203,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
return DXGI_FORMAT_BC7_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -328,6 +329,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
return DXGI_FORMAT_NV12;
|
||||
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1098,7 +1100,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
// Per plane view formats must have the plane slice number be the index of the plane in the
|
||||
// array of textures.
|
||||
if (texture->GetFormat().IsMultiPlanar()) {
|
||||
planeSlice = GetAspectIndex(ConvertViewAspect(GetFormat(), descriptor->aspect));
|
||||
const Aspect planeAspect = ConvertViewAspect(GetFormat(), descriptor->aspect);
|
||||
planeSlice = GetAspectIndex(planeAspect);
|
||||
mSrvDesc.Format = D3D12TextureFormat(GetFormat().GetAspectInfo(planeAspect).format);
|
||||
}
|
||||
|
||||
// Currently we always use D3D12_TEX2D_ARRAY_SRV because we cannot specify base array layer
|
||||
|
|
|
@ -339,6 +339,7 @@ namespace dawn_native { namespace vulkan {
|
|||
case wgpu::TextureFormat::BC7RGBAUnormSrgb:
|
||||
return VK_FORMAT_BC7_SRGB_BLOCK;
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -43,9 +43,6 @@ namespace {
|
|||
wgpu::Texture videoTexture = CreateVideoTextureForTest(
|
||||
wgpu::TextureFormat::R8BG8Biplanar420Unorm, wgpu::TextureUsage::None);
|
||||
|
||||
// Create a default view with no plane selected.
|
||||
ASSERT_DEVICE_ERROR(videoTexture.CreateView());
|
||||
|
||||
wgpu::TextureViewDescriptor viewDesc = {};
|
||||
|
||||
// Correct plane index but incompatible view format.
|
||||
|
|
|
@ -113,6 +113,7 @@ namespace utils {
|
|||
// Block size of a multi-planar format depends on aspect.
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -180,6 +181,7 @@ namespace utils {
|
|||
// Block size of a multi-planar format depends on aspect.
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -247,6 +249,7 @@ namespace utils {
|
|||
// Block size of a multi-planar format depends on aspect.
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue