Add internal Format structure for texture formats

Texture formats have plenty of properties we'd like to query on them
like their texel size, whether they are compressend or if they are depth
stencil. Instead of making switch statements for each of these
properties, we store them in a new `Format` structure. Textures compute
their format only onces and then pass a const reference to it on
GetFormat().

This is in preparation of adding all WebGPU texture formats.

BUG=dawn:128

Change-Id: Iad2831cf16f14e1a1bfce2c10b22527fc982d1aa
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8166
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Corentin Wallez 2019-06-21 10:16:15 +00:00 committed by Commit Bot service account
parent 4729b15365
commit a92f83b725
14 changed files with 297 additions and 323 deletions

View File

@ -52,10 +52,13 @@ namespace dawn_native {
// Compressed Textures will have paddings if their width or height is not a multiple of
// 4 at non-zero mipmap levels.
if (Is4x4CompressedFormat(texture->GetFormat())) {
const Format& textureFormat = texture->GetFormat();
if (textureFormat.isCompressed) {
// TODO(jiawei.shao@intel.com): check if there are any overflows.
widthAtLevel = (widthAtLevel + 3) / 4 * 4;
heightAtLevel = (heightAtLevel + 3) / 4 * 4;
uint32_t blockWidth = textureFormat.blockWidth;
uint32_t blockHeight = textureFormat.blockHeight;
widthAtLevel = (widthAtLevel + blockWidth - 1) / blockWidth * blockWidth;
heightAtLevel = (heightAtLevel + blockHeight - 1) / blockHeight * blockHeight;
}
if (uint64_t(textureCopy.origin.x) + uint64_t(copySize.width) >
@ -107,9 +110,8 @@ namespace dawn_native {
return {};
}
MaybeError ValidateTexelBufferOffset(TextureBase* texture, const BufferCopy& bufferCopy) {
uint32_t blockSize = TextureFormatTexelBlockSizeInBytes(texture->GetFormat());
if (bufferCopy.offset % blockSize != 0) {
MaybeError ValidateTexelBufferOffset(const BufferCopy& bufferCopy, const Format& format) {
if (bufferCopy.offset % format.blockByteSize != 0) {
return DAWN_VALIDATION_ERROR(
"Buffer offset must be a multiple of the texel or block size");
}
@ -187,10 +189,12 @@ namespace dawn_native {
DAWN_TRY(ValidateEntireSubresourceCopied(src, dst, copySize));
}
if (src.texture.Get()->GetFormat() != dst.texture.Get()->GetFormat()) {
if (src.texture.Get()->GetFormat().format != dst.texture.Get()->GetFormat().format) {
// Metal requires texture-to-texture copies be the same format
return DAWN_VALIDATION_ERROR("Source and destination texture formats must match.");
} else if (TextureFormatHasDepthOrStencil(src.texture.Get()->GetFormat())) {
}
if (src.texture.Get()->GetFormat().HasDepthOrStencil()) {
// D3D12 requires entire subresource to be copied when using CopyTextureRegion is
// used with depth/stencil.
DAWN_TRY(ValidateEntireSubresourceCopied(src, dst, copySize));
@ -199,43 +203,38 @@ namespace dawn_native {
return {};
}
MaybeError ComputeTextureCopyBufferSize(dawn::TextureFormat textureFormat,
MaybeError ComputeTextureCopyBufferSize(const Format& textureFormat,
const Extent3D& copySize,
uint32_t rowPitch,
uint32_t imageHeight,
uint32_t* bufferSize) {
DAWN_TRY(ValidateImageHeight(imageHeight, copySize.height));
uint32_t texelOrBlockSizeInBytes = TextureFormatTexelBlockSizeInBytes(textureFormat);
uint32_t blockWidthInTexels = TextureFormatBlockWidthInTexels(textureFormat);
uint32_t blockHeightInTexels = TextureFormatBlockWidthInTexels(textureFormat);
uint32_t blockByteSize = textureFormat.blockByteSize;
uint32_t blockWidth = textureFormat.blockWidth;
uint32_t blockHeight = textureFormat.blockHeight;
// TODO(cwallez@chromium.org): check for overflows
uint32_t slicePitch = rowPitch * imageHeight / blockWidthInTexels;
uint32_t sliceSize = rowPitch * (copySize.height / blockHeightInTexels - 1) +
(copySize.width / blockWidthInTexels) * texelOrBlockSizeInBytes;
uint32_t slicePitch = rowPitch * imageHeight / blockWidth;
uint32_t sliceSize = rowPitch * (copySize.height / blockHeight - 1) +
(copySize.width / blockWidth) * blockByteSize;
*bufferSize = (slicePitch * (copySize.depth - 1)) + sliceSize;
return {};
}
uint32_t ComputeDefaultRowPitch(TextureBase* texture, uint32_t width) {
const dawn::TextureFormat format = texture->GetFormat();
uint32_t texelOrBlockSizeInBytes = TextureFormatTexelBlockSizeInBytes(format);
uint32_t blockWidthInTexels = TextureFormatBlockWidthInTexels(format);
return width / blockWidthInTexels * texelOrBlockSizeInBytes;
uint32_t ComputeDefaultRowPitch(const Format& format, uint32_t width) {
return width / format.blockWidth * format.blockByteSize;
}
MaybeError ValidateRowPitch(dawn::TextureFormat format,
MaybeError ValidateRowPitch(const Format& format,
const Extent3D& copySize,
uint32_t rowPitch) {
if (rowPitch % kTextureRowPitchAlignment != 0) {
return DAWN_VALIDATION_ERROR("Row pitch must be a multiple of 256");
}
uint32_t texelOrBlockSizeInBytes = TextureFormatTexelBlockSizeInBytes(format);
uint32_t blockWidthInTexels = TextureFormatBlockWidthInTexels(format);
if (rowPitch < copySize.width / blockWidthInTexels * texelOrBlockSizeInBytes) {
if (rowPitch < copySize.width / format.blockWidth * format.blockByteSize) {
return DAWN_VALIDATION_ERROR(
"Row pitch must not be less than the number of bytes per row");
}
@ -243,8 +242,8 @@ namespace dawn_native {
return {};
}
MaybeError ValidateImageHeight(dawn::TextureFormat format, uint32_t imageHeight) {
if (imageHeight % TextureFormatBlockHeightInTexels(format) != 0) {
MaybeError ValidateImageHeight(const Format& format, uint32_t imageHeight) {
if (imageHeight % format.blockHeight != 0) {
return DAWN_VALIDATION_ERROR(
"Image height must be a multiple of compressed texture format block width");
}
@ -252,13 +251,13 @@ namespace dawn_native {
return {};
}
MaybeError ValidateImageOrigin(dawn::TextureFormat format, const Origin3D& offset) {
if (offset.x % TextureFormatBlockWidthInTexels(format) != 0) {
MaybeError ValidateImageOrigin(const Format& format, const Origin3D& offset) {
if (offset.x % format.blockWidth != 0) {
return DAWN_VALIDATION_ERROR(
"Offset.x must be a multiple of compressed texture format block width");
}
if (offset.y % TextureFormatBlockHeightInTexels(format) != 0) {
if (offset.y % format.blockHeight != 0) {
return DAWN_VALIDATION_ERROR(
"Offset.y must be a multiple of compressed texture format block height");
}
@ -266,13 +265,13 @@ namespace dawn_native {
return {};
}
MaybeError ValidateImageCopySize(dawn::TextureFormat format, const Extent3D& extent) {
if (extent.width % TextureFormatBlockWidthInTexels(format) != 0) {
MaybeError ValidateImageCopySize(const Format& format, const Extent3D& extent) {
if (extent.width % format.blockWidth != 0) {
return DAWN_VALIDATION_ERROR(
"Extent.width must be a multiple of compressed texture format block width");
}
if (extent.height % TextureFormatBlockHeightInTexels(format) != 0) {
if (extent.height % format.blockHeight != 0) {
return DAWN_VALIDATION_ERROR(
"Extent.height must be a multiple of compressed texture format block height");
}
@ -389,8 +388,9 @@ namespace dawn_native {
"The size of the resolve target must be the same as the color attachment");
}
dawn::TextureFormat resolveTargetFormat = colorAttachment->resolveTarget->GetFormat();
if (resolveTargetFormat != colorAttachment->attachment->GetFormat()) {
dawn::TextureFormat resolveTargetFormat =
colorAttachment->resolveTarget->GetFormat().format;
if (resolveTargetFormat != colorAttachment->attachment->GetFormat().format) {
return DAWN_VALIDATION_ERROR(
"The format of the resolve target must be the same as the color attachment");
}
@ -409,7 +409,7 @@ namespace dawn_native {
DAWN_TRY(device->ValidateObject(colorAttachment->attachment));
const TextureViewBase* attachment = colorAttachment->attachment;
if (!IsColorRenderableTextureFormat(attachment->GetFormat())) {
if (!attachment->GetFormat().IsColor() || !attachment->GetFormat().isRenderable) {
return DAWN_VALIDATION_ERROR(
"The format of the texture view used as color attachment is not color "
"renderable");
@ -436,7 +436,8 @@ namespace dawn_native {
DAWN_TRY(device->ValidateObject(depthStencilAttachment->attachment));
const TextureViewBase* attachment = depthStencilAttachment->attachment;
if (!TextureFormatHasDepthOrStencil(attachment->GetFormat())) {
if (!attachment->GetFormat().HasDepthOrStencil() ||
!attachment->GetFormat().isRenderable) {
return DAWN_VALIDATION_ERROR(
"The format of the texture view used as depth stencil attachment is not a "
"depth stencil format");
@ -783,7 +784,8 @@ namespace dawn_native {
copy->destination.level = destination->level;
copy->destination.slice = destination->slice;
if (source->rowPitch == 0) {
copy->source.rowPitch = ComputeDefaultRowPitch(destination->texture, copySize->width);
copy->source.rowPitch =
ComputeDefaultRowPitch(destination->texture->GetFormat(), copySize->width);
} else {
copy->source.rowPitch = source->rowPitch;
}
@ -819,7 +821,8 @@ namespace dawn_native {
copy->destination.buffer = destination->buffer;
copy->destination.offset = destination->offset;
if (destination->rowPitch == 0) {
copy->destination.rowPitch = ComputeDefaultRowPitch(source->texture, copySize->width);
copy->destination.rowPitch =
ComputeDefaultRowPitch(source->texture->GetFormat(), copySize->width);
} else {
copy->destination.rowPitch = destination->rowPitch;
}
@ -977,8 +980,8 @@ namespace dawn_native {
DAWN_TRY(ValidateCopySizeFitsInTexture(copy->destination, copy->copySize));
DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->source, bufferCopySize));
DAWN_TRY(
ValidateTexelBufferOffset(copy->destination.texture.Get(), copy->source));
DAWN_TRY(ValidateTexelBufferOffset(copy->source,
copy->destination.texture->GetFormat()));
DAWN_TRY(ValidateCanUseAs(copy->source.buffer.Get(),
dawn::BufferUsageBit::TransferSrc));
@ -1011,8 +1014,8 @@ namespace dawn_native {
DAWN_TRY(ValidateCopySizeFitsInTexture(copy->source, copy->copySize));
DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->destination, bufferCopySize));
DAWN_TRY(
ValidateTexelBufferOffset(copy->source.texture.Get(), copy->destination));
DAWN_TRY(ValidateTexelBufferOffset(copy->destination,
copy->source.texture->GetFormat()));
DAWN_TRY(ValidateCanUseAs(copy->source.texture.Get(),
dawn::TextureUsageBit::TransferSrc));

View File

@ -124,9 +124,9 @@ namespace dawn_native {
DAWN_TRY(ValidateBlendFactor(descriptor->colorBlend.dstFactor));
DAWN_TRY(ValidateColorWriteMask(descriptor->writeMask));
dawn::TextureFormat format = descriptor->format;
DAWN_TRY(ValidateTextureFormat(format));
if (!IsColorRenderableTextureFormat(format)) {
Format format;
DAWN_TRY_ASSIGN(format, ConvertFormat(descriptor->format));
if (!format.IsColor() || !format.isRenderable) {
return DAWN_VALIDATION_ERROR("Color format must be color renderable");
}
@ -148,9 +148,9 @@ namespace dawn_native {
DAWN_TRY(ValidateStencilOperation(descriptor->stencilBack.depthFailOp));
DAWN_TRY(ValidateStencilOperation(descriptor->stencilBack.passOp));
dawn::TextureFormat format = descriptor->format;
DAWN_TRY(ValidateTextureFormat(format));
if (!IsDepthStencilRenderableTextureFormat(format)) {
Format format;
DAWN_TRY_ASSIGN(format, ConvertFormat(descriptor->format));
if (!format.HasDepthOrStencil() || !format.isRenderable) {
return DAWN_VALIDATION_ERROR(
"Depth stencil format must be depth-stencil renderable");
}
@ -503,7 +503,8 @@ namespace dawn_native {
}
for (uint32_t i : IterateBitSet(mColorAttachmentsSet)) {
if (renderPass->colorAttachments[i].view->GetFormat() != mColorStates[i].format) {
if (renderPass->colorAttachments[i].view->GetFormat().format !=
mColorStates[i].format) {
return false;
}
}
@ -513,7 +514,8 @@ namespace dawn_native {
}
if (mHasDepthStencilAttachment &&
(renderPass->depthStencilAttachment.view->GetFormat() != mDepthStencilState.format)) {
(renderPass->depthStencilAttachment.view->GetFormat().format !=
mDepthStencilState.format)) {
return false;
}

View File

@ -27,7 +27,7 @@ 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() != descriptor->format) {
if (texture->GetFormat().format != descriptor->format) {
return DAWN_VALIDATION_ERROR(
"The format of texture view is not compatible to the original texture");
}
@ -86,38 +86,88 @@ namespace dawn_native {
}
}
bool IsBCFormat(dawn::TextureFormat format) {
// Returns a format with a blockByteSize of 0 for an invalid input format
Format ConvertFormatInternal(dawn::TextureFormat format) {
auto MakeColorFormat = [](dawn::TextureFormat format, bool renderable,
uint32_t byteSize) -> Format {
Format result;
result.format = format;
result.isRenderable = renderable;
result.isCompressed = false;
result.aspect = Format::Aspect::Color;
result.blockByteSize = byteSize;
result.blockWidth = 1;
result.blockHeight = 1;
return result;
};
auto MakeDepthStencilFormat = [](dawn::TextureFormat format, Format::Aspect aspect,
uint32_t byteSize) -> Format {
Format result;
result.format = format;
result.isRenderable = true;
result.isCompressed = false;
result.aspect = aspect;
result.blockByteSize = byteSize;
result.blockWidth = 1;
result.blockHeight = 1;
return result;
};
auto MakeCompressedFormat = [](dawn::TextureFormat format, uint32_t byteSize,
uint32_t width, uint32_t height) -> Format {
Format result;
result.format = format;
result.isRenderable = false;
result.isCompressed = true;
result.aspect = Format::Aspect::Color;
result.blockByteSize = byteSize;
result.blockWidth = width;
result.blockHeight = height;
return result;
};
switch (format) {
case dawn::TextureFormat::R8Unorm:
case dawn::TextureFormat::R8Uint:
return MakeColorFormat(format, true, 1);
case dawn::TextureFormat::RG8Unorm:
case dawn::TextureFormat::RG8Uint:
return MakeColorFormat(format, true, 2);
case dawn::TextureFormat::RGBA8Unorm:
case dawn::TextureFormat::RGBA8Uint:
case dawn::TextureFormat::BGRA8Unorm:
return MakeColorFormat(format, true, 4);
case dawn::TextureFormat::Depth24PlusStencil8:
// 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?
return MakeDepthStencilFormat(format, Format::Aspect::DepthStencil, 4);
case dawn::TextureFormat::BC1RGBAUnorm:
case dawn::TextureFormat::BC1RGBAUnormSrgb:
case dawn::TextureFormat::BC4RSnorm:
case dawn::TextureFormat::BC4RUnorm:
return MakeCompressedFormat(format, 8, 4, 4);
case dawn::TextureFormat::BC2RGBAUnorm:
case dawn::TextureFormat::BC2RGBAUnormSrgb:
case dawn::TextureFormat::BC3RGBAUnorm:
case dawn::TextureFormat::BC3RGBAUnormSrgb:
case dawn::TextureFormat::BC4RUnorm:
case dawn::TextureFormat::BC4RSnorm:
case dawn::TextureFormat::BC5RGUnorm:
case dawn::TextureFormat::BC5RGSnorm:
case dawn::TextureFormat::BC6HRGBUfloat:
case dawn::TextureFormat::BC5RGUnorm:
case dawn::TextureFormat::BC6HRGBSfloat:
case dawn::TextureFormat::BC6HRGBUfloat:
case dawn::TextureFormat::BC7RGBAUnorm:
case dawn::TextureFormat::BC7RGBAUnormSrgb:
return true;
return MakeCompressedFormat(format, 16, 4, 4);
default:
return false;
Format result = {};
result.blockByteSize = 0;
return result;
}
}
bool IsCompressedFormat(dawn::TextureFormat format) {
return IsBCFormat(format);
}
bool IsWritableFormat(dawn::TextureFormat format) {
return !IsBCFormat(format);
}
// TODO(jiawei.shao@intel.com): support more sample count.
MaybeError ValidateSampleCount(const TextureDescriptor* descriptor) {
MaybeError ValidateSampleCount(const TextureDescriptor* descriptor, const Format& format) {
if (!IsValidSampleCount(descriptor->sampleCount)) {
return DAWN_VALIDATION_ERROR("The sample count of the texture is not supported.");
}
@ -134,7 +184,7 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("Multisampled 2D array texture is not supported.");
}
if (IsCompressedFormat(descriptor->format)) {
if (format.isCompressed) {
return DAWN_VALIDATION_ERROR(
"The sample counts of the textures in BC formats must be 1.");
}
@ -171,7 +221,7 @@ namespace dawn_native {
TextureViewDescriptor MakeDefaultTextureViewDescriptor(const TextureBase* texture) {
TextureViewDescriptor descriptor;
descriptor.format = texture->GetFormat();
descriptor.format = texture->GetFormat().format;
descriptor.baseArrayLayer = 0;
descriptor.arrayLayerCount = texture->GetArrayLayers();
descriptor.baseMipLevel = 0;
@ -193,7 +243,7 @@ namespace dawn_native {
return descriptor;
}
MaybeError ValidateTextureSize(const TextureDescriptor* descriptor) {
MaybeError ValidateTextureSize(const TextureDescriptor* descriptor, const Format& format) {
ASSERT(descriptor->size.width != 0 && descriptor->size.height != 0);
if (Log2(std::max(descriptor->size.width, descriptor->size.height)) + 1 <
@ -201,63 +251,43 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("Texture has too many mip levels");
}
if (Is4x4CompressedFormat(descriptor->format)) {
if (descriptor->size.width % 4 != 0 || descriptor->size.height % 4 != 0) {
if (format.isCompressed && (descriptor->size.width % format.blockWidth != 0 ||
descriptor->size.height % format.blockHeight != 0)) {
return DAWN_VALIDATION_ERROR(
"The size of the texture is incompatible with the texture format");
}
}
return {};
}
} // anonymous namespace
bool Is4x4CompressedFormat(dawn::TextureFormat format) {
return IsBCFormat(format);
}
// We treat non-compressed texture formats as the block texture formats in 1x1 blocks.
uint32_t TextureFormatBlockWidthInTexels(dawn::TextureFormat format) {
if (Is4x4CompressedFormat(format)) {
return 4;
}
return 1;
}
// We treat non-compressed texture formats as the block texture formats in 1x1 blocks.
uint32_t TextureFormatBlockHeightInTexels(dawn::TextureFormat format) {
if (Is4x4CompressedFormat(format)) {
return 4;
}
return 1;
}
MaybeError ValidateTextureUsageBit(const TextureDescriptor* descriptor) {
MaybeError ValidateTextureUsage(const TextureDescriptor* descriptor, const Format& format) {
DAWN_TRY(ValidateTextureUsageBit(descriptor->usage));
if (!IsWritableFormat(descriptor->format)) {
if (format.isCompressed) {
constexpr dawn::TextureUsageBit kValidUsage = dawn::TextureUsageBit::Sampled |
dawn::TextureUsageBit::TransferSrc |
dawn::TextureUsageBit::TransferDst;
if (descriptor->usage & (~kValidUsage)) {
return DAWN_VALIDATION_ERROR(
"Texture format is incompatible with the texture usage");
"Compressed texture format is incompatible with the texture usage");
}
}
return {};
}
} // anonymous namespace
MaybeError ValidateTextureDescriptor(DeviceBase*, const TextureDescriptor* descriptor) {
if (descriptor->nextInChain != nullptr) {
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
}
DAWN_TRY(ValidateTextureUsageBit(descriptor));
Format format;
DAWN_TRY_ASSIGN(format, ConvertFormat(descriptor->format));
DAWN_TRY(ValidateTextureUsage(descriptor, format));
DAWN_TRY(ValidateTextureDimension(descriptor->dimension));
DAWN_TRY(ValidateTextureFormat(descriptor->format));
DAWN_TRY(ValidateSampleCount(descriptor));
DAWN_TRY(ValidateSampleCount(descriptor, format));
// TODO(jiawei.shao@intel.com): check stuff based on the dimension
if (descriptor->size.width == 0 || descriptor->size.height == 0 ||
@ -266,7 +296,7 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("Cannot create an empty texture");
}
DAWN_TRY(ValidateTextureSize(descriptor));
DAWN_TRY(ValidateTextureSize(descriptor, format));
return {};
}
@ -307,113 +337,6 @@ namespace dawn_native {
return {};
}
// We treat non-compressed texture formats as the block texture formats in 1x1 blocks.
uint32_t TextureFormatTexelBlockSizeInBytes(dawn::TextureFormat format) {
switch (format) {
// Non-compressed texture formats
case dawn::TextureFormat::R8Unorm:
case dawn::TextureFormat::R8Uint:
return 1;
case dawn::TextureFormat::RG8Unorm:
case dawn::TextureFormat::RG8Uint:
return 2;
case dawn::TextureFormat::RGBA8Unorm:
case dawn::TextureFormat::RGBA8Uint:
case dawn::TextureFormat::BGRA8Unorm:
return 4;
case dawn::TextureFormat::Depth24PlusStencil8:
return 8;
// BC formats
case dawn::TextureFormat::BC1RGBAUnorm:
case dawn::TextureFormat::BC1RGBAUnormSrgb:
case dawn::TextureFormat::BC4RSnorm:
case dawn::TextureFormat::BC4RUnorm:
return 8;
case dawn::TextureFormat::BC2RGBAUnorm:
case dawn::TextureFormat::BC2RGBAUnormSrgb:
case dawn::TextureFormat::BC3RGBAUnorm:
case dawn::TextureFormat::BC3RGBAUnormSrgb:
case dawn::TextureFormat::BC5RGSnorm:
case dawn::TextureFormat::BC5RGUnorm:
case dawn::TextureFormat::BC6HRGBSfloat:
case dawn::TextureFormat::BC6HRGBUfloat:
case dawn::TextureFormat::BC7RGBAUnorm:
case dawn::TextureFormat::BC7RGBAUnormSrgb:
return 16;
default:
UNREACHABLE();
}
}
bool TextureFormatHasDepth(dawn::TextureFormat format) {
switch (format) {
case dawn::TextureFormat::Depth24PlusStencil8:
return true;
default:
return false;
}
}
bool TextureFormatHasStencil(dawn::TextureFormat format) {
switch (format) {
case dawn::TextureFormat::Depth24PlusStencil8:
return true;
default:
return false;
}
}
bool TextureFormatHasDepthOrStencil(dawn::TextureFormat format) {
switch (format) {
case dawn::TextureFormat::Depth24PlusStencil8:
return true;
default:
return false;
}
}
bool IsColorRenderableTextureFormat(dawn::TextureFormat format) {
switch (format) {
case dawn::TextureFormat::BGRA8Unorm:
case dawn::TextureFormat::RGBA8Uint:
case dawn::TextureFormat::RGBA8Unorm:
case dawn::TextureFormat::RG8Uint:
case dawn::TextureFormat::RG8Unorm:
case dawn::TextureFormat::R8Uint:
case dawn::TextureFormat::R8Unorm:
return true;
case dawn::TextureFormat::Depth24PlusStencil8:
return false;
default:
UNREACHABLE();
return false;
}
}
bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format) {
switch (format) {
case dawn::TextureFormat::Depth24PlusStencil8:
return true;
case dawn::TextureFormat::BGRA8Unorm:
case dawn::TextureFormat::RGBA8Uint:
case dawn::TextureFormat::RGBA8Unorm:
case dawn::TextureFormat::RG8Uint:
case dawn::TextureFormat::RG8Unorm:
case dawn::TextureFormat::R8Uint:
case dawn::TextureFormat::R8Unorm:
return false;
default:
UNREACHABLE();
return false;
}
}
bool IsValidSampleCount(uint32_t sampleCount) {
switch (sampleCount) {
case 1:
@ -425,6 +348,36 @@ namespace dawn_native {
}
}
ResultOrError<Format> ConvertFormat(dawn::TextureFormat format) {
Format result = ConvertFormatInternal(format);
if (result.blockByteSize == 0) {
return DAWN_VALIDATION_ERROR("Invalid texture format");
}
return result;
}
Format ConvertValidFormat(dawn::TextureFormat format) {
Format result = ConvertFormatInternal(format);
ASSERT(result.blockByteSize != 0);
return result;
}
bool Format::IsColor() const {
return aspect == Aspect::Color;
}
bool Format::HasDepth() const {
return aspect == Depth || aspect == DepthStencil;
}
bool Format::HasStencil() const {
return aspect == Stencil || aspect == DepthStencil;
}
bool Format::HasDepthOrStencil() const {
return aspect != Color;
}
// TextureBase
TextureBase::TextureBase(DeviceBase* device,
@ -432,7 +385,7 @@ namespace dawn_native {
TextureState state)
: ObjectBase(device),
mDimension(descriptor->dimension),
mFormat(descriptor->format),
mFormat(ConvertValidFormat(descriptor->format)),
mSize(descriptor->size),
mArrayLayerCount(descriptor->arrayLayerCount),
mMipLevelCount(descriptor->mipLevelCount),
@ -459,7 +412,7 @@ namespace dawn_native {
}
// TODO(jiawei.shao@intel.com): return more information about texture format
dawn::TextureFormat TextureBase::GetFormat() const {
const Format& TextureBase::GetFormat() const {
ASSERT(!IsError());
return mFormat;
}
@ -586,7 +539,7 @@ namespace dawn_native {
TextureViewBase::TextureViewBase(TextureBase* texture, const TextureViewDescriptor* descriptor)
: ObjectBase(texture->GetDevice()),
mTexture(texture),
mFormat(descriptor->format),
mFormat(ConvertValidFormat(descriptor->format)),
mBaseMipLevel(descriptor->baseMipLevel),
mMipLevelCount(descriptor->mipLevelCount),
mBaseArrayLayer(descriptor->baseArrayLayer),
@ -612,7 +565,7 @@ namespace dawn_native {
return mTexture.Get();
}
dawn::TextureFormat TextureViewBase::GetFormat() const {
const Format& TextureViewBase::GetFormat() const {
ASSERT(!IsError());
return mFormat;
}

View File

@ -29,18 +29,8 @@ namespace dawn_native {
const TextureBase* texture,
const TextureViewDescriptor* descriptor);
uint32_t TextureFormatTexelBlockSizeInBytes(dawn::TextureFormat format);
bool TextureFormatHasDepth(dawn::TextureFormat format);
bool TextureFormatHasStencil(dawn::TextureFormat format);
bool TextureFormatHasDepthOrStencil(dawn::TextureFormat format);
bool IsColorRenderableTextureFormat(dawn::TextureFormat format);
bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format);
bool IsValidSampleCount(uint32_t sampleCount);
bool Is4x4CompressedFormat(dawn::TextureFormat format);
uint32_t TextureFormatBlockWidthInTexels(dawn::TextureFormat format);
uint32_t TextureFormatBlockHeightInTexels(dawn::TextureFormat format);
static constexpr dawn::TextureUsageBit kReadOnlyTextureUsages =
dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::Sampled |
dawn::TextureUsageBit::Present;
@ -49,6 +39,36 @@ namespace dawn_native {
dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Storage |
dawn::TextureUsageBit::OutputAttachment;
struct Format {
enum Aspect {
Color,
Depth,
Stencil,
DepthStencil,
};
dawn::TextureFormat format;
bool isRenderable;
bool isCompressed;
Aspect aspect;
uint32_t blockByteSize;
uint32_t blockWidth;
uint32_t blockHeight;
bool IsColor() const;
bool HasDepth() const;
bool HasStencil() const;
bool HasDepthOrStencil() const;
};
// Returns the Format corresponding to the dawn::TextureFormat or an error if the format
// isn't valid.
ResultOrError<Format> ConvertFormat(dawn::TextureFormat format);
// Returns the Format corresponding to the dawn::TextureFormat and assumes the format is valid.
Format ConvertValidFormat(dawn::TextureFormat format);
class TextureBase : public ObjectBase {
public:
enum class TextureState { OwnedInternal, OwnedExternal, Destroyed };
@ -58,7 +78,7 @@ namespace dawn_native {
static TextureBase* MakeError(DeviceBase* device);
dawn::TextureDimension GetDimension() const;
dawn::TextureFormat GetFormat() const;
const Format& GetFormat() const;
const Extent3D& GetSize() const;
uint32_t GetArrayLayers() const;
uint32_t GetNumMipLevels() const;
@ -93,7 +113,8 @@ namespace dawn_native {
MaybeError ValidateDestroy() const;
dawn::TextureDimension mDimension;
dawn::TextureFormat mFormat;
// TODO(cwallez@chromium.org): This should be deduplicated in the Device
Format mFormat;
Extent3D mSize;
uint32_t mArrayLayerCount;
uint32_t mMipLevelCount;
@ -114,7 +135,7 @@ namespace dawn_native {
const TextureBase* GetTexture() const;
TextureBase* GetTexture();
dawn::TextureFormat GetFormat() const;
const Format& GetFormat() const;
uint32_t GetBaseMipLevel() const;
uint32_t GetLevelCount() const;
uint32_t GetBaseArrayLayer() const;
@ -125,7 +146,8 @@ namespace dawn_native {
Ref<TextureBase> mTexture;
dawn::TextureFormat mFormat;
// TODO(cwallez@chromium.org): This should be deduplicated in the Device
Format mFormat;
uint32_t mBaseMipLevel;
uint32_t mMipLevelCount;
uint32_t mBaseArrayLayer;

View File

@ -505,9 +505,8 @@ namespace dawn_native { namespace d3d12 {
auto copySplit = ComputeTextureCopySplit(
copy->destination.origin, copy->copySize,
static_cast<uint32_t>(
TextureFormatTexelBlockSizeInBytes(texture->GetFormat())),
copy->source.offset, copy->source.rowPitch, copy->source.imageHeight);
texture->GetFormat().blockByteSize, copy->source.offset,
copy->source.rowPitch, copy->source.imageHeight);
D3D12_TEXTURE_COPY_LOCATION textureLocation =
CreateTextureCopyLocationForTexture(*texture, copy->destination.level,
@ -549,9 +548,7 @@ namespace dawn_native { namespace d3d12 {
buffer->TransitionUsageNow(commandList, dawn::BufferUsageBit::TransferDst);
auto copySplit = ComputeTextureCopySplit(
copy->source.origin, copy->copySize,
static_cast<uint32_t>(
TextureFormatTexelBlockSizeInBytes(texture->GetFormat())),
copy->source.origin, copy->copySize, texture->GetFormat().blockByteSize,
copy->destination.offset, copy->destination.rowPitch,
copy->destination.imageHeight);
@ -749,9 +746,9 @@ namespace dawn_native { namespace d3d12 {
Texture* texture = ToBackend(renderPass->depthStencilAttachment.view->GetTexture());
// Load op - depth/stencil
bool doDepthClear = TextureFormatHasDepth(texture->GetFormat()) &&
bool doDepthClear = texture->GetFormat().HasDepth() &&
(attachmentInfo.depthLoadOp == dawn::LoadOp::Clear);
bool doStencilClear = TextureFormatHasStencil(texture->GetFormat()) &&
bool doStencilClear = texture->GetFormat().HasStencil() &&
(attachmentInfo.stencilLoadOp == dawn::LoadOp::Clear);
D3D12_CLEAR_FLAGS clearFlags = {};

View File

@ -21,8 +21,7 @@
namespace dawn_native { namespace d3d12 {
namespace {
D3D12_RESOURCE_STATES D3D12TextureUsage(dawn::TextureUsageBit usage,
dawn::TextureFormat format) {
D3D12_RESOURCE_STATES D3D12TextureUsage(dawn::TextureUsageBit usage, const Format& format) {
D3D12_RESOURCE_STATES resourceState = D3D12_RESOURCE_STATE_COMMON;
// Present is an exclusive flag.
@ -44,7 +43,7 @@ namespace dawn_native { namespace d3d12 {
resourceState |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
}
if (usage & dawn::TextureUsageBit::OutputAttachment) {
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
if (format.HasDepthOrStencil()) {
resourceState |= D3D12_RESOURCE_STATE_DEPTH_WRITE;
} else {
resourceState |= D3D12_RESOURCE_STATE_RENDER_TARGET;
@ -55,7 +54,7 @@ namespace dawn_native { namespace d3d12 {
}
D3D12_RESOURCE_FLAGS D3D12ResourceFlags(dawn::TextureUsageBit usage,
dawn::TextureFormat format,
const Format& format,
bool isMultisampledTexture) {
D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE;
@ -68,7 +67,7 @@ namespace dawn_native { namespace d3d12 {
// https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_resource
// _desc
if ((usage & dawn::TextureUsageBit::OutputAttachment) || isMultisampledTexture) {
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
if (format.HasDepthOrStencil()) {
flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
} else {
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
@ -126,7 +125,7 @@ namespace dawn_native { namespace d3d12 {
resourceDescriptor.DepthOrArraySize = GetDepthOrArraySize();
resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
resourceDescriptor.Format = D3D12TextureFormat(GetFormat());
resourceDescriptor.Format = D3D12TextureFormat(GetFormat().format);
resourceDescriptor.SampleDesc.Count = descriptor->sampleCount;
// TODO(bryan.bernhart@intel.com): investigate how to specify standard MSAA sample pattern.
resourceDescriptor.SampleDesc.Quality = 0;
@ -225,7 +224,7 @@ namespace dawn_native { namespace d3d12 {
}
DXGI_FORMAT Texture::GetD3D12Format() const {
return D3D12TextureFormat(GetFormat());
return D3D12TextureFormat(GetFormat().format);
}
ID3D12Resource* Texture::GetD3D12Resource() const {
@ -329,7 +328,7 @@ namespace dawn_native { namespace d3d12 {
}
DXGI_FORMAT TextureView::GetD3D12Format() const {
return D3D12TextureFormat(GetFormat());
return D3D12TextureFormat(GetFormat().format);
}
const D3D12_SHADER_RESOURCE_VIEW_DESC& TextureView::GetSRVDescriptor() const {

View File

@ -89,9 +89,9 @@ namespace dawn_native { namespace metal {
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
id<MTLTexture> texture =
ToBackend(attachmentInfo.view->GetTexture())->GetMTLTexture();
dawn::TextureFormat format = attachmentInfo.view->GetTexture()->GetFormat();
const Format& format = attachmentInfo.view->GetTexture()->GetFormat();
if (TextureFormatHasDepth(format)) {
if (format.HasDepth()) {
descriptor.depthAttachment.texture = texture;
descriptor.depthAttachment.storeAction = MTLStoreActionStore;
@ -103,7 +103,7 @@ namespace dawn_native { namespace metal {
}
}
if (TextureFormatHasStencil(format)) {
if (format.HasStencil()) {
descriptor.stencilAttachment.texture = texture;
descriptor.stencilAttachment.storeAction = MTLStoreActionStore;
@ -453,8 +453,7 @@ namespace dawn_native { namespace metal {
// Doing the last row copy with the exact number of bytes in last row.
// Like copy to a 1D texture to workaround the issue.
uint32_t lastRowDataSize =
copySize.width * TextureFormatTexelBlockSizeInBytes(texture->GetFormat());
uint32_t lastRowDataSize = copySize.width * texture->GetFormat().blockByteSize;
[encoders.blit
copyFromBuffer:buffer->GetMTLBuffer()
@ -567,8 +566,7 @@ namespace dawn_native { namespace metal {
// Doing the last row copy with the exact number of bytes in last row.
// Like copy from a 1D texture to workaround the issue.
uint32_t lastRowDataSize =
copySize.width * TextureFormatTexelBlockSizeInBytes(texture->GetFormat());
uint32_t lastRowDataSize = copySize.width * texture->GetFormat().blockByteSize;
[encoders.blit
copyFromTexture:texture->GetMTLTexture()

View File

@ -82,7 +82,7 @@ namespace dawn_native { namespace metal {
bool RequiresCreatingNewTextureView(const TextureBase* texture,
const TextureViewDescriptor* textureViewDescriptor) {
if (texture->GetFormat() != textureViewDescriptor->format) {
if (texture->GetFormat().format != textureViewDescriptor->format) {
return true;
}

View File

@ -389,9 +389,8 @@ namespace dawn_native { namespace opengl {
gl.ActiveTexture(GL_TEXTURE0);
gl.BindTexture(target, texture->GetHandle());
gl.PixelStorei(
GL_UNPACK_ROW_LENGTH,
src.rowPitch / TextureFormatTexelBlockSizeInBytes(texture->GetFormat()));
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
src.rowPitch / texture->GetFormat().blockByteSize);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.imageHeight);
switch (texture->GetDimension()) {
case dawn::TextureDimension::e2D:
@ -452,9 +451,8 @@ namespace dawn_native { namespace opengl {
}
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
gl.PixelStorei(
GL_PACK_ROW_LENGTH,
dst.rowPitch / TextureFormatTexelBlockSizeInBytes(texture->GetFormat()));
gl.PixelStorei(GL_PACK_ROW_LENGTH,
dst.rowPitch / texture->GetFormat().blockByteSize);
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.imageHeight);
ASSERT(copySize.depth == 1 && src.origin.z == 0);
void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
@ -582,7 +580,7 @@ namespace dawn_native { namespace opengl {
// TODO(kainino@chromium.org): the color clears (later in
// this function) may be undefined for non-normalized integer formats.
dawn::TextureFormat format = textureView->GetTexture()->GetFormat();
dawn::TextureFormat format = textureView->GetTexture()->GetFormat().format;
ASSERT(format == dawn::TextureFormat::RGBA8Unorm ||
format == dawn::TextureFormat::RG8Unorm ||
format == dawn::TextureFormat::R8Unorm ||
@ -593,20 +591,25 @@ namespace dawn_native { namespace opengl {
if (renderPass->hasDepthStencilAttachment) {
TextureViewBase* textureView = renderPass->depthStencilAttachment.view.Get();
GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
dawn::TextureFormat format = textureView->GetTexture()->GetFormat();
const Format& format = textureView->GetTexture()->GetFormat();
// Attach depth/stencil buffer.
GLenum glAttachment = 0;
// TODO(kainino@chromium.org): it may be valid to just always use
// GL_DEPTH_STENCIL_ATTACHMENT here.
if (TextureFormatHasDepth(format)) {
if (TextureFormatHasStencil(format)) {
glAttachment = GL_DEPTH_STENCIL_ATTACHMENT;
} else {
switch (format.aspect) {
case Format::Aspect::Depth:
glAttachment = GL_DEPTH_ATTACHMENT;
}
} else {
break;
case Format::Aspect::Stencil:
glAttachment = GL_STENCIL_ATTACHMENT;
break;
case Format::Aspect::DepthStencil:
glAttachment = GL_DEPTH_STENCIL_ATTACHMENT;
break;
default:
UNREACHABLE();
break;
}
GLenum target = ToBackend(textureView->GetTexture())->GetGLTarget();
@ -614,7 +617,7 @@ namespace dawn_native { namespace opengl {
// TODO(kainino@chromium.org): the depth/stencil clears (later in
// this function) may be undefined for other texture formats.
ASSERT(format == dawn::TextureFormat::Depth24PlusStencil8);
ASSERT(format.format == dawn::TextureFormat::Depth24PlusStencil8);
}
}
@ -639,20 +642,19 @@ namespace dawn_native { namespace opengl {
if (renderPass->hasDepthStencilAttachment) {
const auto& attachmentInfo = renderPass->depthStencilAttachment;
dawn::TextureFormat attachmentFormat =
attachmentInfo.view->GetTexture()->GetFormat();
const Format& attachmentFormat = attachmentInfo.view->GetTexture()->GetFormat();
// Load op - depth/stencil
bool doDepthClear = TextureFormatHasDepth(attachmentFormat) &&
bool doDepthClear = attachmentFormat.HasDepth() &&
(attachmentInfo.depthLoadOp == dawn::LoadOp::Clear);
bool doStencilClear = TextureFormatHasStencil(attachmentFormat) &&
bool doStencilClear = attachmentFormat.HasStencil() &&
(attachmentInfo.stencilLoadOp == dawn::LoadOp::Clear);
if (doDepthClear) {
gl.DepthMask(GL_TRUE);
}
if (doStencilClear) {
gl.StencilMask(GetStencilMaskFromStencilFormat(attachmentFormat));
gl.StencilMask(GetStencilMaskFromStencilFormat(attachmentFormat.format));
}
if (doDepthClear && doStencilClear) {

View File

@ -102,7 +102,7 @@ namespace dawn_native { namespace opengl {
bool RequiresCreatingNewTextureView(const TextureBase* texture,
const TextureViewDescriptor* textureViewDescriptor) {
if (texture->GetFormat() != textureViewDescriptor->format) {
if (texture->GetFormat().format != textureViewDescriptor->format) {
return true;
}
@ -139,7 +139,7 @@ namespace dawn_native { namespace opengl {
uint32_t arrayLayers = GetArrayLayers();
uint32_t sampleCount = GetSampleCount();
auto formatInfo = GetGLFormatInfo(GetFormat());
auto formatInfo = GetGLFormatInfo(GetFormat().format);
gl.BindTexture(mTarget, mHandle);
@ -171,7 +171,7 @@ namespace dawn_native { namespace opengl {
if (GetDevice()->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
static constexpr uint32_t MAX_TEXEL_SIZE = 16;
ASSERT(TextureFormatTexelBlockSizeInBytes(GetFormat()) <= MAX_TEXEL_SIZE);
ASSERT(GetFormat().blockByteSize <= MAX_TEXEL_SIZE);
GLubyte clearColor[MAX_TEXEL_SIZE];
std::fill(clearColor, clearColor + MAX_TEXEL_SIZE, 255);
@ -208,7 +208,7 @@ namespace dawn_native { namespace opengl {
}
TextureFormatInfo Texture::GetGLFormat() const {
return GetGLFormatInfo(GetFormat());
return GetGLFormatInfo(GetFormat().format);
}
// TextureView

View File

@ -50,8 +50,7 @@ namespace dawn_native { namespace vulkan {
region.bufferOffset = bufferCopy.offset;
// In Vulkan the row length is in texels while it is in bytes for Dawn
region.bufferRowLength =
bufferCopy.rowPitch / TextureFormatTexelBlockSizeInBytes(texture->GetFormat());
region.bufferRowLength = bufferCopy.rowPitch / texture->GetFormat().blockByteSize;
region.bufferImageHeight = bufferCopy.imageHeight;
region.imageSubresource.aspectMask = texture->GetVkAspectMask();
@ -190,12 +189,13 @@ namespace dawn_native { namespace vulkan {
default: { UNREACHABLE(); } break;
}
query.SetColor(i, attachmentInfo.view->GetFormat(), loadOp, hasResolveTarget);
query.SetColor(i, attachmentInfo.view->GetFormat().format, loadOp,
hasResolveTarget);
}
if (renderPass->hasDepthStencilAttachment) {
auto& attachmentInfo = renderPass->depthStencilAttachment;
query.SetDepthStencil(attachmentInfo.view->GetTexture()->GetFormat(),
query.SetDepthStencil(attachmentInfo.view->GetTexture()->GetFormat().format,
attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp);
if (attachmentInfo.depthLoadOp == dawn::LoadOp::Load ||
attachmentInfo.stencilLoadOp == dawn::LoadOp::Load) {

View File

@ -92,8 +92,8 @@ namespace dawn_native { namespace vulkan {
createInfo.imageExtent.width = width;
createInfo.imageExtent.height = height;
createInfo.imageArrayLayers = 1;
createInfo.imageUsage =
VulkanImageUsage(static_cast<dawn::TextureUsageBit>(usage), mConfig.format);
createInfo.imageUsage = VulkanImageUsage(static_cast<dawn::TextureUsageBit>(usage),
ConvertValidFormat(mConfig.format));
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
createInfo.queueFamilyIndexCount = 0;
createInfo.pQueueFamilyIndices = nullptr;

View File

@ -51,7 +51,7 @@ namespace dawn_native { namespace vulkan {
}
// Computes which vulkan access type could be required for the given Dawn usage.
VkAccessFlags VulkanAccessFlags(dawn::TextureUsageBit usage, dawn::TextureFormat format) {
VkAccessFlags VulkanAccessFlags(dawn::TextureUsageBit usage, const Format& format) {
VkAccessFlags flags = 0;
if (usage & dawn::TextureUsageBit::TransferSrc) {
@ -67,7 +67,7 @@ namespace dawn_native { namespace vulkan {
flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
}
if (usage & dawn::TextureUsageBit::OutputAttachment) {
if (TextureFormatHasDepthOrStencil(format)) {
if (format.HasDepthOrStencil()) {
flags |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
} else {
@ -88,7 +88,7 @@ namespace dawn_native { namespace vulkan {
}
// Chooses which Vulkan image layout should be used for the given Dawn usage
VkImageLayout VulkanImageLayout(dawn::TextureUsageBit usage, dawn::TextureFormat format) {
VkImageLayout VulkanImageLayout(dawn::TextureUsageBit usage, const Format& format) {
if (usage == dawn::TextureUsageBit::None) {
return VK_IMAGE_LAYOUT_UNDEFINED;
}
@ -114,7 +114,7 @@ namespace dawn_native { namespace vulkan {
case dawn::TextureUsageBit::Storage:
return VK_IMAGE_LAYOUT_GENERAL;
case dawn::TextureUsageBit::OutputAttachment:
if (TextureFormatHasDepthOrStencil(format)) {
if (format.HasDepthOrStencil()) {
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
} else {
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@ -128,7 +128,7 @@ namespace dawn_native { namespace vulkan {
// Computes which Vulkan pipeline stage can access a texture in the given Dawn usage
VkPipelineStageFlags VulkanPipelineStage(dawn::TextureUsageBit usage,
dawn::TextureFormat format) {
const Format& format) {
VkPipelineStageFlags flags = 0;
if (usage == dawn::TextureUsageBit::None) {
@ -145,7 +145,7 @@ namespace dawn_native { namespace vulkan {
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
if (usage & dawn::TextureUsageBit::OutputAttachment) {
if (TextureFormatHasDepthOrStencil(format)) {
if (format.HasDepthOrStencil()) {
flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
// TODO(cwallez@chromium.org): This is missing the stage where the depth and
@ -170,22 +170,20 @@ namespace dawn_native { namespace vulkan {
}
// Computes which Vulkan texture aspects are relevant for the given Dawn format
VkImageAspectFlags VulkanAspectMask(dawn::TextureFormat format) {
bool isDepth = TextureFormatHasDepth(format);
bool isStencil = TextureFormatHasStencil(format);
VkImageAspectFlags flags = 0;
if (isDepth) {
flags |= VK_IMAGE_ASPECT_DEPTH_BIT;
}
if (isStencil) {
flags |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
if (flags != 0) {
return flags;
}
VkImageAspectFlags VulkanAspectMask(const Format& format) {
switch (format.aspect) {
case Format::Aspect::Color:
return VK_IMAGE_ASPECT_COLOR_BIT;
case Format::Aspect::Depth:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case Format::Aspect::Stencil:
return VK_IMAGE_ASPECT_STENCIL_BIT;
case Format::Aspect::DepthStencil:
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
default:
UNREACHABLE();
return 0;
}
}
VkExtent3D VulkanExtent3D(const Extent3D& extent) {
@ -236,7 +234,7 @@ namespace dawn_native { namespace vulkan {
// Converts the Dawn usage flags to Vulkan usage flags. Also needs the format to choose
// between color and depth attachment usages.
VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, dawn::TextureFormat format) {
VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, const Format& format) {
VkImageUsageFlags flags = 0;
if (usage & dawn::TextureUsageBit::TransferSrc) {
@ -252,7 +250,7 @@ namespace dawn_native { namespace vulkan {
flags |= VK_IMAGE_USAGE_STORAGE_BIT;
}
if (usage & dawn::TextureUsageBit::OutputAttachment) {
if (TextureFormatHasDepthOrStencil(format)) {
if (format.HasDepthOrStencil()) {
flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
} else {
flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
@ -283,7 +281,7 @@ namespace dawn_native { namespace vulkan {
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.imageType = VulkanImageType(GetDimension());
createInfo.format = VulkanImageFormat(GetFormat());
createInfo.format = VulkanImageFormat(GetFormat().format);
createInfo.extent = VulkanExtent3D(GetSize());
createInfo.mipLevels = GetNumMipLevels();
createInfo.arrayLayers = GetArrayLayers();
@ -334,7 +332,7 @@ namespace dawn_native { namespace vulkan {
TransitionUsageNow(ToBackend(GetDevice())->GetPendingCommandBuffer(),
dawn::TextureUsageBit::TransferDst);
if (TextureFormatHasDepthOrStencil(GetFormat())) {
if (GetFormat().HasDepthOrStencil()) {
VkClearDepthStencilValue clear_color[1];
clear_color[0].depth = 1.0f;
clear_color[0].stencil = 1u;
@ -396,7 +394,7 @@ namespace dawn_native { namespace vulkan {
return;
}
dawn::TextureFormat format = GetFormat();
const Format& format = GetFormat();
VkPipelineStageFlags srcStages = VulkanPipelineStage(mLastUsage, format);
VkPipelineStageFlags dstStages = VulkanPipelineStage(usage, format);
@ -439,7 +437,7 @@ namespace dawn_native { namespace vulkan {
range.layerCount = layerCount;
TransitionUsageNow(commands, dawn::TextureUsageBit::TransferDst);
if (TextureFormatHasDepthOrStencil(GetFormat())) {
if (GetFormat().HasDepthOrStencil()) {
VkClearDepthStencilValue clear_color[1];
clear_color[0].depth = 0.0f;
clear_color[0].stencil = 0u;
@ -490,7 +488,7 @@ namespace dawn_native { namespace vulkan {
createInfo.format = VulkanImageFormat(descriptor->format);
createInfo.components = VkComponentMapping{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
createInfo.subresourceRange.aspectMask = VulkanAspectMask(descriptor->format);
createInfo.subresourceRange.aspectMask = VulkanAspectMask(GetFormat());
createInfo.subresourceRange.baseMipLevel = descriptor->baseMipLevel;
createInfo.subresourceRange.levelCount = descriptor->mipLevelCount;
createInfo.subresourceRange.baseArrayLayer = descriptor->baseArrayLayer;

View File

@ -23,7 +23,7 @@
namespace dawn_native { namespace vulkan {
VkFormat VulkanImageFormat(dawn::TextureFormat format);
VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, dawn::TextureFormat format);
VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, const Format& format);
VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount);
class Texture : public TextureBase {