Support T2T copies between formats that have only difference on srgb-ness
In previous T2T copy, Dawn requires textures have the same formats. But Vulkan/Metal/D3D12 have ability to copy between "compatible" formats textures. Metal has the most restrict rules without setting interpreter flags when creating textures. It defines "compatible" texture formats to the formats that only have difference on srgb-ness. This CL follow Metal's rule and release the validations for T2T copies. It supports T2T copy between "compatible" texture format textures. Bug: dawn:1204 Change-Id: I50bf04ea15e8026530b3a5bdb5725f56aa192d85 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/74301 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
This commit is contained in:
parent
fa2fde1432
commit
cf0e4fceb3
|
@ -429,11 +429,13 @@ namespace dawn_native {
|
|||
MaybeError ValidateTextureToTextureCopyRestrictions(const ImageCopyTexture& src,
|
||||
const ImageCopyTexture& dst,
|
||||
const Extent3D& copySize) {
|
||||
// Metal requires texture-to-texture copies be the same format
|
||||
DAWN_INVALID_IF(src.texture->GetFormat().format != dst.texture->GetFormat().format,
|
||||
"Source %s format (%s) and destination %s format (%s) do not match.",
|
||||
src.texture, src.texture->GetFormat().format, dst.texture,
|
||||
dst.texture->GetFormat().format);
|
||||
// Metal requires texture-to-texture copies happens between texture formats that equal to
|
||||
// each other or only have diff on srgb-ness.
|
||||
DAWN_INVALID_IF(
|
||||
!src.texture->GetFormat().CopyCompatibleWith(dst.texture->GetFormat()),
|
||||
"Source %s format (%s) and destination %s format (%s) are not copy compatible.",
|
||||
src.texture, src.texture->GetFormat().format, dst.texture,
|
||||
dst.texture->GetFormat().format);
|
||||
|
||||
return ValidateTextureToTextureCopyCommonRestrictions(src, dst, copySize);
|
||||
}
|
||||
|
|
|
@ -104,6 +104,10 @@ namespace dawn_native {
|
|||
return (aspects & (Aspect::Plane0 | Aspect::Plane1)) != 0;
|
||||
}
|
||||
|
||||
bool Format::CopyCompatibleWith(const Format& format) const {
|
||||
return baseFormat == format.baseFormat;
|
||||
}
|
||||
|
||||
const AspectInfo& Format::GetAspectInfo(wgpu::TextureAspect aspect) const {
|
||||
return GetAspectInfo(SelectFormatAspects(*this, aspect));
|
||||
}
|
||||
|
@ -157,47 +161,57 @@ namespace dawn_native {
|
|||
formatsSet.set(index);
|
||||
};
|
||||
|
||||
auto AddColorFormat = [&AddFormat](wgpu::TextureFormat format, bool renderable,
|
||||
bool supportsStorageUsage, uint32_t byteSize,
|
||||
SampleTypeBit sampleTypes, uint8_t componentCount) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = renderable;
|
||||
internalFormat.isCompressed = false;
|
||||
internalFormat.isSupported = true;
|
||||
internalFormat.supportsStorageUsage = supportsStorageUsage;
|
||||
internalFormat.aspects = Aspect::Color;
|
||||
internalFormat.componentCount = componentCount;
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = 1;
|
||||
firstAspect->block.height = 1;
|
||||
if (HasOneBit(sampleTypes)) {
|
||||
switch (sampleTypes) {
|
||||
case SampleTypeBit::Float:
|
||||
case SampleTypeBit::UnfilterableFloat:
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
break;
|
||||
case SampleTypeBit::Sint:
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Sint;
|
||||
break;
|
||||
case SampleTypeBit::Uint:
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Uint;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
ASSERT((sampleTypes & SampleTypeBit::Float) != 0);
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
}
|
||||
firstAspect->supportedSampleTypes = sampleTypes;
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
auto AddColorFormat =
|
||||
[&AddFormat](wgpu::TextureFormat format, bool renderable, bool supportsStorageUsage,
|
||||
uint32_t byteSize, SampleTypeBit sampleTypes, uint8_t componentCount,
|
||||
wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = renderable;
|
||||
internalFormat.isCompressed = false;
|
||||
internalFormat.isSupported = true;
|
||||
internalFormat.supportsStorageUsage = supportsStorageUsage;
|
||||
internalFormat.aspects = Aspect::Color;
|
||||
internalFormat.componentCount = componentCount;
|
||||
|
||||
auto AddDepthFormat = [&AddFormat](wgpu::TextureFormat format, uint32_t byteSize,
|
||||
bool isSupported) {
|
||||
// Default baseFormat of each color formats should be themselves.
|
||||
if (baseFormat == wgpu::TextureFormat::Undefined) {
|
||||
internalFormat.baseFormat = format;
|
||||
} else {
|
||||
internalFormat.baseFormat = baseFormat;
|
||||
}
|
||||
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = 1;
|
||||
firstAspect->block.height = 1;
|
||||
if (HasOneBit(sampleTypes)) {
|
||||
switch (sampleTypes) {
|
||||
case SampleTypeBit::Float:
|
||||
case SampleTypeBit::UnfilterableFloat:
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
break;
|
||||
case SampleTypeBit::Sint:
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Sint;
|
||||
break;
|
||||
case SampleTypeBit::Uint:
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Uint;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
ASSERT((sampleTypes & SampleTypeBit::Float) != 0);
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
}
|
||||
firstAspect->supportedSampleTypes = sampleTypes;
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
auto AddDepthFormat = [&AddFormat](
|
||||
wgpu::TextureFormat format, uint32_t byteSize, bool isSupported,
|
||||
wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = true;
|
||||
|
@ -206,6 +220,14 @@ namespace dawn_native {
|
|||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = Aspect::Depth;
|
||||
internalFormat.componentCount = 1;
|
||||
|
||||
// Default baseFormat of each depth formats should be themselves.
|
||||
if (baseFormat == wgpu::TextureFormat::Undefined) {
|
||||
internalFormat.baseFormat = format;
|
||||
} else {
|
||||
internalFormat.baseFormat = baseFormat;
|
||||
}
|
||||
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = 1;
|
||||
|
@ -216,7 +238,9 @@ namespace dawn_native {
|
|||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
auto AddStencilFormat = [&AddFormat](wgpu::TextureFormat format, bool isSupported) {
|
||||
auto AddStencilFormat = [&AddFormat](wgpu::TextureFormat format, bool isSupported,
|
||||
wgpu::TextureFormat baseFormat =
|
||||
wgpu::TextureFormat::Undefined) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = true;
|
||||
|
@ -225,6 +249,15 @@ namespace dawn_native {
|
|||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = Aspect::Stencil;
|
||||
internalFormat.componentCount = 1;
|
||||
internalFormat.baseFormat = baseFormat;
|
||||
|
||||
// Default baseFormat of each stencil formats should be themselves.
|
||||
if (baseFormat == wgpu::TextureFormat::Undefined) {
|
||||
internalFormat.baseFormat = format;
|
||||
} else {
|
||||
internalFormat.baseFormat = baseFormat;
|
||||
}
|
||||
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = 1;
|
||||
firstAspect->block.width = 1;
|
||||
|
@ -235,31 +268,41 @@ namespace dawn_native {
|
|||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
auto AddCompressedFormat = [&AddFormat](wgpu::TextureFormat format, uint32_t byteSize,
|
||||
uint32_t width, uint32_t height, bool isSupported,
|
||||
uint8_t componentCount) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = false;
|
||||
internalFormat.isCompressed = true;
|
||||
internalFormat.isSupported = isSupported;
|
||||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = Aspect::Color;
|
||||
internalFormat.componentCount = componentCount;
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = width;
|
||||
firstAspect->block.height = height;
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
firstAspect->supportedSampleTypes = kAnyFloat;
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
auto AddCompressedFormat =
|
||||
[&AddFormat](wgpu::TextureFormat format, uint32_t byteSize, uint32_t width,
|
||||
uint32_t height, bool isSupported, uint8_t componentCount,
|
||||
wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = false;
|
||||
internalFormat.isCompressed = true;
|
||||
internalFormat.isSupported = isSupported;
|
||||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = Aspect::Color;
|
||||
internalFormat.componentCount = componentCount;
|
||||
|
||||
// Default baseFormat of each compressed formats should be themselves.
|
||||
if (baseFormat == wgpu::TextureFormat::Undefined) {
|
||||
internalFormat.baseFormat = format;
|
||||
} else {
|
||||
internalFormat.baseFormat = baseFormat;
|
||||
}
|
||||
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = byteSize;
|
||||
firstAspect->block.width = width;
|
||||
firstAspect->block.height = height;
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Float;
|
||||
firstAspect->supportedSampleTypes = kAnyFloat;
|
||||
firstAspect->format = format;
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
auto AddMultiAspectFormat =
|
||||
[&AddFormat, &table](wgpu::TextureFormat format, Aspect aspects,
|
||||
wgpu::TextureFormat firstFormat, wgpu::TextureFormat secondFormat,
|
||||
bool isRenderable, bool isSupported, uint8_t componentCount) {
|
||||
bool isRenderable, bool isSupported, uint8_t componentCount,
|
||||
wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
|
||||
Format internalFormat;
|
||||
internalFormat.format = format;
|
||||
internalFormat.isRenderable = isRenderable;
|
||||
|
@ -268,6 +311,14 @@ namespace dawn_native {
|
|||
internalFormat.supportsStorageUsage = false;
|
||||
internalFormat.aspects = aspects;
|
||||
internalFormat.componentCount = componentCount;
|
||||
|
||||
// Default baseFormat of each multi aspect formats should be themselves.
|
||||
if (baseFormat == wgpu::TextureFormat::Undefined) {
|
||||
internalFormat.baseFormat = format;
|
||||
} else {
|
||||
internalFormat.baseFormat = baseFormat;
|
||||
}
|
||||
|
||||
const size_t firstFormatIndex = ComputeFormatIndex(firstFormat);
|
||||
const size_t secondFormatIndex = ComputeFormatIndex(secondFormat);
|
||||
|
||||
|
@ -301,12 +352,12 @@ namespace dawn_native {
|
|||
AddColorFormat(wgpu::TextureFormat::RG16Sint, true, false, 4, SampleTypeBit::Sint, 2);
|
||||
AddColorFormat(wgpu::TextureFormat::RG16Float, true, false, 4, kAnyFloat, 2);
|
||||
AddColorFormat(wgpu::TextureFormat::RGBA8Unorm, true, true, 4, kAnyFloat, 4);
|
||||
AddColorFormat(wgpu::TextureFormat::RGBA8UnormSrgb, true, false, 4, kAnyFloat, 4);
|
||||
AddColorFormat(wgpu::TextureFormat::RGBA8UnormSrgb, true, false, 4, kAnyFloat, 4, wgpu::TextureFormat::RGBA8Unorm);
|
||||
AddColorFormat(wgpu::TextureFormat::RGBA8Snorm, false, true, 4, kAnyFloat, 4);
|
||||
AddColorFormat(wgpu::TextureFormat::RGBA8Uint, true, true, 4, SampleTypeBit::Uint, 4);
|
||||
AddColorFormat(wgpu::TextureFormat::RGBA8Sint, true, true, 4, SampleTypeBit::Sint, 4);
|
||||
AddColorFormat(wgpu::TextureFormat::BGRA8Unorm, true, false, 4, kAnyFloat, 4);
|
||||
AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, 4, kAnyFloat, 4);
|
||||
AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, 4, kAnyFloat, 4, wgpu::TextureFormat::BGRA8Unorm);
|
||||
AddColorFormat(wgpu::TextureFormat::RGB10A2Unorm, true, false, 4, kAnyFloat, 4);
|
||||
|
||||
AddColorFormat(wgpu::TextureFormat::RG11B10Ufloat, false, false, 4, kAnyFloat, 3);
|
||||
|
@ -346,28 +397,28 @@ namespace dawn_native {
|
|||
// BC compressed formats
|
||||
bool isBCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionBC);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnorm, 8, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, 8, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, 8, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC1RGBAUnorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC4RSnorm, 8, 4, 4, isBCFormatSupported, 1);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC4RUnorm, 8, 4, 4, isBCFormatSupported, 1);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC2RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC2RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC2RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC2RGBAUnorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC3RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC3RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC3RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC3RGBAUnorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC5RGSnorm, 16, 4, 4, isBCFormatSupported, 2);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC5RGUnorm, 16, 4, 4, isBCFormatSupported, 2);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC6HRGBFloat, 16, 4, 4, isBCFormatSupported, 3);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC6HRGBUfloat, 16, 4, 4, isBCFormatSupported, 3);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC7RGBAUnorm);
|
||||
|
||||
// ETC2/EAC compressed formats
|
||||
bool isETC2FormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionETC2);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8Unorm, 8, 4, 4, isETC2FormatSupported, 3);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, 8, 4, 4, isETC2FormatSupported, 3);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, 8, 4, 4, isETC2FormatSupported, 3, wgpu::TextureFormat::ETC2RGB8Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1Unorm, 8, 4, 4, isETC2FormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1UnormSrgb, 8, 4, 4, isETC2FormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1UnormSrgb, 8, 4, 4, isETC2FormatSupported, 4, wgpu::TextureFormat::ETC2RGB8A1Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGBA8Unorm, 16, 4, 4, isETC2FormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGBA8UnormSrgb, 16, 4, 4, isETC2FormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGBA8UnormSrgb, 16, 4, 4, isETC2FormatSupported, 4, wgpu::TextureFormat::ETC2RGBA8Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::EACR11Unorm, 8, 4, 4, isETC2FormatSupported, 1);
|
||||
AddCompressedFormat(wgpu::TextureFormat::EACR11Snorm, 8, 4, 4, isETC2FormatSupported, 1);
|
||||
AddCompressedFormat(wgpu::TextureFormat::EACRG11Unorm, 16, 4, 4, isETC2FormatSupported, 2);
|
||||
|
@ -376,33 +427,33 @@ namespace dawn_native {
|
|||
// ASTC compressed formats
|
||||
bool isASTCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionASTC);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC4x4Unorm, 16, 4, 4, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, 16, 4, 4, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, 16, 4, 4, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC4x4Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x4Unorm, 16, 5, 4, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x4UnormSrgb, 16, 5, 4, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x4UnormSrgb, 16, 5, 4, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC5x4Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x5Unorm, 16, 5, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x5UnormSrgb, 16, 5, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x5UnormSrgb, 16, 5, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC5x5Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC6x5Unorm, 16, 6, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC6x5UnormSrgb, 16, 6, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC6x5UnormSrgb, 16, 6, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC6x5Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC6x6Unorm, 16, 6, 6, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC6x6UnormSrgb, 16, 6, 6, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC6x6UnormSrgb, 16, 6, 6, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC6x6Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x5Unorm, 16, 8, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x5UnormSrgb, 16, 8, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x5UnormSrgb, 16, 8, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC8x5Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x6Unorm, 16, 8, 6, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x6UnormSrgb, 16, 8, 6, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x6UnormSrgb, 16, 8, 6, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC8x6Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x8Unorm, 16, 8, 8, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x8UnormSrgb, 16, 8, 8, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC8x8UnormSrgb, 16, 8, 8, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC8x8Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x5Unorm, 16, 10, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x5UnormSrgb, 16, 10, 5, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x5UnormSrgb, 16, 10, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x5Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x6Unorm, 16, 10, 6, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x6UnormSrgb, 16, 10, 6, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x6UnormSrgb, 16, 10, 6, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x6Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x8Unorm, 16, 10, 8, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x8UnormSrgb, 16, 10, 8, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x8UnormSrgb, 16, 10, 8, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x8Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x10Unorm, 16, 10, 10, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x10UnormSrgb, 16, 10, 10, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC10x10UnormSrgb, 16, 10, 10, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x10Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC12x10Unorm, 16, 12, 10, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC12x10UnormSrgb, 16, 12, 10, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC12x10UnormSrgb, 16, 12, 10, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC12x10Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC12x12Unorm, 16, 12, 12, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC12x12UnormSrgb, 16, 12, 12, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC12x12UnormSrgb, 16, 12, 12, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC12x12Unorm);
|
||||
|
||||
// multi-planar formats
|
||||
const bool isMultiPlanarFormatSupported = device->IsFeatureEnabled(Feature::MultiPlanarFormats);
|
||||
|
|
|
@ -85,6 +85,7 @@ namespace dawn_native {
|
|||
// A wgpu::TextureFormat along with all the information about it necessary for validation.
|
||||
struct Format {
|
||||
wgpu::TextureFormat format;
|
||||
|
||||
bool isRenderable;
|
||||
bool isCompressed;
|
||||
// A format can be known but not supported because it is part of a disabled extension.
|
||||
|
@ -110,6 +111,14 @@ namespace dawn_native {
|
|||
// in [0, kKnownFormatCount)
|
||||
size_t GetIndex() const;
|
||||
|
||||
// baseFormat represents the memory layout of the format.
|
||||
// If two formats has the same baseFormat, they could copy to each other.
|
||||
wgpu::TextureFormat baseFormat;
|
||||
|
||||
// CopyCompatibleWith() returns true if the input format has the same baseFormat
|
||||
// with current format.
|
||||
bool CopyCompatibleWith(const Format& format) const;
|
||||
|
||||
private:
|
||||
// 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
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
const Extent3D& copySize) {
|
||||
// Checked by validation
|
||||
ASSERT(src.texture->GetSampleCount() == dst.texture->GetSampleCount());
|
||||
ASSERT(src.texture->GetFormat().format == dst.texture->GetFormat().format);
|
||||
ASSERT(src.texture->GetFormat().CopyCompatibleWith(dst.texture->GetFormat()));
|
||||
ASSERT(src.aspect == dst.aspect);
|
||||
|
||||
const Extent3D& srcSize = src.texture->GetSize();
|
||||
|
@ -168,7 +168,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
Toggle::
|
||||
UseTempBufferInSmallFormatTextureToTextureCopyFromGreaterToLessMipLevel)) {
|
||||
bool copyToLesserLevel = srcCopy.mipLevel > dstCopy.mipLevel;
|
||||
ASSERT(srcCopy.texture->GetFormat().format == dstCopy.texture->GetFormat().format);
|
||||
ASSERT(
|
||||
srcCopy.texture->GetFormat().CopyCompatibleWith(dstCopy.texture->GetFormat()));
|
||||
|
||||
// GetAspectInfo(aspect) requires HasOneBit(aspect) == true, plus the texel block
|
||||
// sizes of depth stencil formats are always no less than 4 bytes.
|
||||
|
|
|
@ -897,6 +897,10 @@ namespace dawn_native { namespace metal {
|
|||
*sourceZPtr = copy->source.origin.z + z;
|
||||
*destinationZPtr = copy->destination.origin.z + z;
|
||||
|
||||
// Hold the ref until out of scope
|
||||
NSPRef<id<MTLTexture>> dstTextureView =
|
||||
dstTexture->CreateFormatView(srcTexture->GetFormat().format);
|
||||
|
||||
[commandContext->EnsureBlit()
|
||||
copyFromTexture:srcTexture->GetMTLTexture()
|
||||
sourceSlice:sourceLayer
|
||||
|
@ -904,7 +908,7 @@ namespace dawn_native { namespace metal {
|
|||
sourceOrigin:MTLOriginMake(copy->source.origin.x,
|
||||
copy->source.origin.y, sourceOriginZ)
|
||||
sourceSize:sizeOneSlice
|
||||
toTexture:dstTexture->GetMTLTexture()
|
||||
toTexture:dstTextureView.Get()
|
||||
destinationSlice:destinationLayer
|
||||
destinationLevel:copy->destination.mipLevel
|
||||
destinationOrigin:MTLOriginMake(copy->destination.origin.x,
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace dawn_native { namespace metal {
|
|||
NSPRef<id<MTLTexture>> wrapped);
|
||||
|
||||
id<MTLTexture> GetMTLTexture();
|
||||
NSPRef<id<MTLTexture>> CreateFormatView(wgpu::TextureFormat format);
|
||||
|
||||
void EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext,
|
||||
const SubresourceRange& range);
|
||||
|
|
|
@ -113,6 +113,49 @@ namespace dawn_native { namespace metal {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Metal only allows format reinterpretation to happen on swizzle pattern or conversion
|
||||
// between linear space and sRGB without setting MTLTextureUsagePixelFormatView flag. For
|
||||
// example, creating bgra8Unorm texture view on rgba8Unorm texture or creating
|
||||
// rgba8Unorm_srgb texture view on rgab8Unorm texture.
|
||||
bool AllowFormatReinterpretationWithoutFlag(MTLPixelFormat origin,
|
||||
MTLPixelFormat reinterpretation) {
|
||||
switch (origin) {
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
return reinterpretation == MTLPixelFormatBGRA8Unorm ||
|
||||
reinterpretation == MTLPixelFormatRGBA8Unorm_sRGB;
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
return reinterpretation == MTLPixelFormatRGBA8Unorm ||
|
||||
reinterpretation == MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
case MTLPixelFormatRGBA8Unorm_sRGB:
|
||||
return reinterpretation == MTLPixelFormatBGRA8Unorm_sRGB ||
|
||||
reinterpretation == MTLPixelFormatRGBA8Unorm;
|
||||
case MTLPixelFormatBGRA8Unorm_sRGB:
|
||||
return reinterpretation == MTLPixelFormatRGBA8Unorm_sRGB ||
|
||||
reinterpretation == MTLPixelFormatBGRA8Unorm;
|
||||
#if defined(DAWN_PLATFORM_MACOS)
|
||||
case MTLPixelFormatBC1_RGBA:
|
||||
return reinterpretation == MTLPixelFormatBC1_RGBA_sRGB;
|
||||
case MTLPixelFormatBC1_RGBA_sRGB:
|
||||
return reinterpretation == MTLPixelFormatBC1_RGBA;
|
||||
case MTLPixelFormatBC2_RGBA:
|
||||
return reinterpretation == MTLPixelFormatBC2_RGBA_sRGB;
|
||||
case MTLPixelFormatBC2_RGBA_sRGB:
|
||||
return reinterpretation == MTLPixelFormatBC2_RGBA;
|
||||
case MTLPixelFormatBC3_RGBA:
|
||||
return reinterpretation == MTLPixelFormatBC3_RGBA_sRGB;
|
||||
case MTLPixelFormatBC3_RGBA_sRGB:
|
||||
return reinterpretation == MTLPixelFormatBC3_RGBA;
|
||||
case MTLPixelFormatBC7_RGBAUnorm:
|
||||
return reinterpretation == MTLPixelFormatBC7_RGBAUnorm_sRGB;
|
||||
case MTLPixelFormatBC7_RGBAUnorm_sRGB:
|
||||
return reinterpretation == MTLPixelFormatBC7_RGBAUnorm;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ResultOrError<wgpu::TextureFormat> GetFormatEquivalentToIOSurfaceFormat(uint32_t format) {
|
||||
switch (format) {
|
||||
case kCVPixelFormatType_32RGBA:
|
||||
|
@ -382,7 +425,10 @@ namespace dawn_native { namespace metal {
|
|||
mtlDesc.width = GetWidth();
|
||||
mtlDesc.height = GetHeight();
|
||||
mtlDesc.sampleCount = GetSampleCount();
|
||||
// TODO: add MTLTextureUsagePixelFormatView when needed when we support format
|
||||
// Metal only allows format reinterpretation to happen on swizzle pattern or conversion
|
||||
// between linear space and sRGB. For example, creating bgra8Unorm texture view on
|
||||
// rgba8Unorm texture or creating rgba8Unorm_srgb texture view on rgab8Unorm texture.
|
||||
// TODO: add MTLTextureUsagePixelFormatView when needed when we support other format
|
||||
// reinterpretation.
|
||||
mtlDesc.usage = MetalTextureUsage(GetFormat(), GetInternalUsage(), GetSampleCount());
|
||||
mtlDesc.pixelFormat = MetalPixelFormat(GetFormat().format);
|
||||
|
@ -509,6 +555,17 @@ namespace dawn_native { namespace metal {
|
|||
return mMtlTexture.Get();
|
||||
}
|
||||
|
||||
NSPRef<id<MTLTexture>> Texture::CreateFormatView(wgpu::TextureFormat format) {
|
||||
if (GetFormat().format == format) {
|
||||
return mMtlTexture;
|
||||
}
|
||||
|
||||
ASSERT(AllowFormatReinterpretationWithoutFlag(MetalPixelFormat(GetFormat().format),
|
||||
MetalPixelFormat(format)));
|
||||
return AcquireNSPRef(
|
||||
[mMtlTexture.Get() newTextureViewWithPixelFormat:MetalPixelFormat(format)]);
|
||||
}
|
||||
|
||||
MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
|
||||
const SubresourceRange& range,
|
||||
TextureBase::ClearValue clearValue) {
|
||||
|
|
|
@ -327,35 +327,25 @@ namespace {
|
|||
// CopyTextureToTextureInternal.
|
||||
using UsageCopySrc = bool;
|
||||
DAWN_TEST_PARAM_STRUCT(CopyTestsParams, UsageCopySrc);
|
||||
|
||||
using SrcColorFormat = wgpu::TextureFormat;
|
||||
DAWN_TEST_PARAM_STRUCT(SrcColorFormatParams, SrcColorFormat);
|
||||
} // namespace
|
||||
|
||||
class CopyTests_T2T : public CopyTests, public DawnTestWithParams<CopyTestsParams> {
|
||||
template <typename Parent>
|
||||
class CopyTests_T2TBase : public CopyTests, public Parent {
|
||||
protected:
|
||||
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
|
||||
return {wgpu::FeatureName::DawnInternalUsages};
|
||||
}
|
||||
|
||||
void DoTest(const TextureSpec& srcSpec,
|
||||
const TextureSpec& dstSpec,
|
||||
const wgpu::Extent3D& copySize,
|
||||
bool copyWithinSameTexture = false,
|
||||
wgpu::TextureDimension dimension = wgpu::TextureDimension::e2D) {
|
||||
DoTest(srcSpec, dstSpec, copySize, dimension, dimension, copyWithinSameTexture);
|
||||
}
|
||||
|
||||
void DoTest(const TextureSpec& srcSpec,
|
||||
const TextureSpec& dstSpec,
|
||||
const wgpu::Extent3D& copySize,
|
||||
wgpu::TextureDimension srcDimension,
|
||||
wgpu::TextureDimension dstDimension,
|
||||
bool copyWithinSameTexture = false) {
|
||||
const bool usageCopySrc = GetParam().mUsageCopySrc;
|
||||
// If we do this test with a CopyWithinSameTexture, it will need to have usageCopySrc in the
|
||||
// public usage of the texture as it will later use a CopyTextureToBuffer, that needs the
|
||||
// public usage of it.
|
||||
DAWN_TEST_UNSUPPORTED_IF(!usageCopySrc && copyWithinSameTexture);
|
||||
|
||||
ASSERT_EQ(srcSpec.format, dstSpec.format);
|
||||
bool copyWithinSameTexture = false,
|
||||
bool usageCopySrc = false) {
|
||||
const wgpu::TextureFormat format = srcSpec.format;
|
||||
|
||||
wgpu::TextureDescriptor srcDescriptor;
|
||||
|
@ -375,7 +365,7 @@ class CopyTests_T2T : public CopyTests, public DawnTestWithParams<CopyTestsParam
|
|||
} else {
|
||||
internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
|
||||
}
|
||||
wgpu::Texture srcTexture = device.CreateTexture(&srcDescriptor);
|
||||
wgpu::Texture srcTexture = this->device.CreateTexture(&srcDescriptor);
|
||||
|
||||
wgpu::Texture dstTexture;
|
||||
if (copyWithinSameTexture) {
|
||||
|
@ -385,10 +375,10 @@ class CopyTests_T2T : public CopyTests, public DawnTestWithParams<CopyTestsParam
|
|||
dstDescriptor.dimension = dstDimension;
|
||||
dstDescriptor.size = dstSpec.textureSize;
|
||||
dstDescriptor.sampleCount = 1;
|
||||
dstDescriptor.format = format;
|
||||
dstDescriptor.format = dstSpec.format;
|
||||
dstDescriptor.mipLevelCount = dstSpec.levelCount;
|
||||
dstDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
|
||||
dstTexture = device.CreateTexture(&dstDescriptor);
|
||||
dstTexture = this->device.CreateTexture(&dstDescriptor);
|
||||
}
|
||||
|
||||
// Create an upload buffer and use it to completely populate the subresources of the src
|
||||
|
@ -409,12 +399,12 @@ class CopyTests_T2T : public CopyTests, public DawnTestWithParams<CopyTestsParam
|
|||
srcTexture, srcSpec.copyLevel, {0, 0, srcSpec.copyOrigin.z});
|
||||
wgpu::TextureDataLayout textureDataLayout = utils::CreateTextureDataLayout(
|
||||
0, srcDataCopyLayout.bytesPerRow, srcDataCopyLayout.rowsPerImage);
|
||||
queue.WriteTexture(&imageCopyTexture, srcTextureCopyData.data(),
|
||||
srcDataCopyLayout.byteLength, &textureDataLayout,
|
||||
&srcDataCopyLayout.mipSize);
|
||||
this->queue.WriteTexture(&imageCopyTexture, srcTextureCopyData.data(),
|
||||
srcDataCopyLayout.byteLength, &textureDataLayout,
|
||||
&srcDataCopyLayout.mipSize);
|
||||
}
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::CommandEncoder encoder = this->device.CreateCommandEncoder();
|
||||
|
||||
// Perform the texture to texture copy
|
||||
wgpu::ImageCopyTexture srcImageCopyTexture =
|
||||
|
@ -442,7 +432,7 @@ class CopyTests_T2T : public CopyTests, public DawnTestWithParams<CopyTestsParam
|
|||
wgpu::BufferDescriptor outputBufferDescriptor;
|
||||
outputBufferDescriptor.size = dstDataCopyLayout.byteLength;
|
||||
outputBufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
|
||||
wgpu::Buffer outputBuffer = device.CreateBuffer(&outputBufferDescriptor);
|
||||
wgpu::Buffer outputBuffer = this->device.CreateBuffer(&outputBufferDescriptor);
|
||||
const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(format);
|
||||
const uint32_t expectedDstDataOffset = dstSpec.copyOrigin.x * bytesPerTexel +
|
||||
dstSpec.copyOrigin.y * dstDataCopyLayout.bytesPerRow;
|
||||
|
@ -452,7 +442,7 @@ class CopyTests_T2T : public CopyTests, public DawnTestWithParams<CopyTestsParam
|
|||
encoder.CopyTextureToBuffer(&dstImageCopyTexture, &outputImageCopyBuffer, ©Size);
|
||||
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
this->queue.Submit(1, &commands);
|
||||
|
||||
// Validate if the data in outputBuffer is what we expected, including the untouched data
|
||||
// outside of the copy.
|
||||
|
@ -504,6 +494,67 @@ class CopyTests_T2T : public CopyTests, public DawnTestWithParams<CopyTestsParam
|
|||
}
|
||||
};
|
||||
|
||||
class CopyTests_T2T : public CopyTests_T2TBase<DawnTestWithParams<CopyTestsParams>> {
|
||||
protected:
|
||||
void DoTest(const TextureSpec& srcSpec,
|
||||
const TextureSpec& dstSpec,
|
||||
const wgpu::Extent3D& copySize,
|
||||
bool copyWithinSameTexture = false,
|
||||
wgpu::TextureDimension dimension = wgpu::TextureDimension::e2D) {
|
||||
DoTest(srcSpec, dstSpec, copySize, dimension, dimension, copyWithinSameTexture);
|
||||
}
|
||||
|
||||
void DoTest(const TextureSpec& srcSpec,
|
||||
const TextureSpec& dstSpec,
|
||||
const wgpu::Extent3D& copySize,
|
||||
wgpu::TextureDimension srcDimension,
|
||||
wgpu::TextureDimension dstDimension,
|
||||
bool copyWithinSameTexture = false) {
|
||||
const bool usageCopySrc = GetParam().mUsageCopySrc;
|
||||
// If we do this test with a CopyWithinSameTexture, it will need to have usageCopySrc in the
|
||||
// public usage of the texture as it will later use a CopyTextureToBuffer, that needs the
|
||||
// public usage of it.
|
||||
DAWN_TEST_UNSUPPORTED_IF(!usageCopySrc && copyWithinSameTexture);
|
||||
|
||||
ASSERT_EQ(srcSpec.format, dstSpec.format);
|
||||
|
||||
CopyTests_T2TBase<DawnTestWithParams<CopyTestsParams>>::DoTest(
|
||||
srcSpec, dstSpec, copySize, srcDimension, dstDimension, copyWithinSameTexture,
|
||||
usageCopySrc);
|
||||
}
|
||||
};
|
||||
|
||||
class CopyTests_Formats : public CopyTests_T2TBase<DawnTestWithParams<SrcColorFormatParams>> {
|
||||
protected:
|
||||
// Texture format is compatible and could be copied to each other if the only diff is srgb-ness.
|
||||
wgpu::TextureFormat GetCopyCompatibleFormat(wgpu::TextureFormat format) {
|
||||
switch (format) {
|
||||
case wgpu::TextureFormat::RGBA8Unorm:
|
||||
return wgpu::TextureFormat::RGBA8UnormSrgb;
|
||||
case wgpu::TextureFormat::RGBA8UnormSrgb:
|
||||
return wgpu::TextureFormat::RGBA8Unorm;
|
||||
case wgpu::TextureFormat::BGRA8Unorm:
|
||||
return wgpu::TextureFormat::BGRA8UnormSrgb;
|
||||
case wgpu::TextureFormat::BGRA8UnormSrgb:
|
||||
return wgpu::TextureFormat::BGRA8Unorm;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void DoTest(TextureSpec srcSpec,
|
||||
TextureSpec dstSpec,
|
||||
const wgpu::Extent3D& copySize,
|
||||
wgpu::TextureDimension srcDimension = wgpu::TextureDimension::e2D,
|
||||
wgpu::TextureDimension dstDimension = wgpu::TextureDimension::e2D) {
|
||||
srcSpec.format = GetParam().mSrcColorFormat;
|
||||
dstSpec.format = GetCopyCompatibleFormat(srcSpec.format);
|
||||
|
||||
CopyTests_T2TBase<DawnTestWithParams<SrcColorFormatParams>>::DoTest(
|
||||
srcSpec, dstSpec, copySize, srcDimension, dstDimension);
|
||||
}
|
||||
};
|
||||
|
||||
class CopyTests_B2B : public DawnTest {
|
||||
protected:
|
||||
// This is the same signature as CopyBufferToBuffer except that the buffers are replaced by
|
||||
|
@ -2409,6 +2460,27 @@ DAWN_INSTANTIATE_TEST_P(CopyTests_T2T,
|
|||
MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
|
||||
{true, false});
|
||||
|
||||
// Test copying between textures that have srgb compatible texture formats;
|
||||
TEST_P(CopyTests_Formats, SrgbCompatibility) {
|
||||
// Skip backends because which fails to support *-srgb formats
|
||||
// and bgra* formats.
|
||||
DAWN_SUPPRESS_TEST_IF(IsOpenGLES());
|
||||
DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());
|
||||
|
||||
constexpr uint32_t kWidth = 256;
|
||||
constexpr uint32_t kHeight = 128;
|
||||
|
||||
TextureSpec textureSpec;
|
||||
textureSpec.textureSize = {kWidth, kHeight, 1};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(CopyTests_Formats,
|
||||
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
|
||||
VulkanBackend()},
|
||||
{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8UnormSrgb,
|
||||
wgpu::TextureFormat::BGRA8Unorm, wgpu::TextureFormat::BGRA8UnormSrgb});
|
||||
|
||||
static constexpr uint64_t kSmallBufferSize = 4;
|
||||
static constexpr uint64_t kLargeBufferSize = 1 << 16;
|
||||
|
||||
|
|
|
@ -1646,6 +1646,21 @@ class CopyCommandTest_T2T : public CopyCommandTest {
|
|||
descriptor.requiredFeaturesCount = 2;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::TextureFormat GetCopyCompatibleFormat(wgpu::TextureFormat format) {
|
||||
switch (format) {
|
||||
case wgpu::TextureFormat::BGRA8Unorm:
|
||||
return wgpu::TextureFormat::BGRA8UnormSrgb;
|
||||
case wgpu::TextureFormat::BGRA8UnormSrgb:
|
||||
return wgpu::TextureFormat::BGRA8Unorm;
|
||||
case wgpu::TextureFormat::RGBA8Unorm:
|
||||
return wgpu::TextureFormat::RGBA8UnormSrgb;
|
||||
case wgpu::TextureFormat::RGBA8UnormSrgb:
|
||||
return wgpu::TextureFormat::RGBA8Unorm;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CopyCommandTest_T2T, Success) {
|
||||
|
@ -1892,6 +1907,23 @@ TEST_F(CopyCommandTest_T2T, FormatsMismatch) {
|
|||
{0, 0, 1});
|
||||
}
|
||||
|
||||
// Test copying between textures that have srgb compatible texture formats;
|
||||
TEST_F(CopyCommandTest_T2T, SrgbFormatsCompatibility) {
|
||||
for (wgpu::TextureFormat srcTextureFormat :
|
||||
{wgpu::TextureFormat::BGRA8Unorm, wgpu::TextureFormat::BGRA8UnormSrgb,
|
||||
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8UnormSrgb}) {
|
||||
wgpu::TextureFormat dstTextureFormat = GetCopyCompatibleFormat(srcTextureFormat);
|
||||
wgpu::Texture source =
|
||||
Create2DTexture(16, 16, 5, 2, srcTextureFormat, wgpu::TextureUsage::CopySrc);
|
||||
wgpu::Texture destination =
|
||||
Create2DTexture(16, 16, 5, 2, dstTextureFormat, wgpu::TextureUsage::CopyDst);
|
||||
|
||||
// Failure when formats don't match
|
||||
TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0},
|
||||
{0, 0, 1});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CopyCommandTest_T2T, MultisampledCopies) {
|
||||
wgpu::Texture sourceMultiSampled1x = Create2DTexture(
|
||||
16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::CopySrc, 1);
|
||||
|
@ -2112,6 +2144,97 @@ class CopyCommandTest_CompressedTextureFormats : public CopyCommandTest {
|
|||
uint32_t height = utils::GetTextureFormatBlockHeight(format) * 4;
|
||||
return Create2DTexture(format, 1, width, height);
|
||||
}
|
||||
|
||||
wgpu::TextureFormat GetCopyCompatibleFormat(wgpu::TextureFormat format) {
|
||||
switch (format) {
|
||||
case wgpu::TextureFormat::BC1RGBAUnorm:
|
||||
return wgpu::TextureFormat::BC1RGBAUnormSrgb;
|
||||
case wgpu::TextureFormat::BC1RGBAUnormSrgb:
|
||||
return wgpu::TextureFormat::BC1RGBAUnorm;
|
||||
case wgpu::TextureFormat::BC2RGBAUnorm:
|
||||
return wgpu::TextureFormat::BC2RGBAUnormSrgb;
|
||||
case wgpu::TextureFormat::BC2RGBAUnormSrgb:
|
||||
return wgpu::TextureFormat::BC2RGBAUnorm;
|
||||
case wgpu::TextureFormat::BC3RGBAUnorm:
|
||||
return wgpu::TextureFormat::BC3RGBAUnormSrgb;
|
||||
case wgpu::TextureFormat::BC3RGBAUnormSrgb:
|
||||
return wgpu::TextureFormat::BC3RGBAUnorm;
|
||||
case wgpu::TextureFormat::BC7RGBAUnorm:
|
||||
return wgpu::TextureFormat::BC7RGBAUnormSrgb;
|
||||
case wgpu::TextureFormat::BC7RGBAUnormSrgb:
|
||||
return wgpu::TextureFormat::BC7RGBAUnorm;
|
||||
case wgpu::TextureFormat::ETC2RGB8Unorm:
|
||||
return wgpu::TextureFormat::ETC2RGB8UnormSrgb;
|
||||
case wgpu::TextureFormat::ETC2RGB8UnormSrgb:
|
||||
return wgpu::TextureFormat::ETC2RGB8Unorm;
|
||||
case wgpu::TextureFormat::ETC2RGB8A1Unorm:
|
||||
return wgpu::TextureFormat::ETC2RGB8A1UnormSrgb;
|
||||
case wgpu::TextureFormat::ETC2RGB8A1UnormSrgb:
|
||||
return wgpu::TextureFormat::ETC2RGB8A1Unorm;
|
||||
case wgpu::TextureFormat::ETC2RGBA8Unorm:
|
||||
return wgpu::TextureFormat::ETC2RGBA8UnormSrgb;
|
||||
case wgpu::TextureFormat::ETC2RGBA8UnormSrgb:
|
||||
return wgpu::TextureFormat::ETC2RGBA8Unorm;
|
||||
case wgpu::TextureFormat::ASTC4x4Unorm:
|
||||
return wgpu::TextureFormat::ASTC4x4UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC4x4UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC4x4Unorm;
|
||||
case wgpu::TextureFormat::ASTC5x4Unorm:
|
||||
return wgpu::TextureFormat::ASTC5x4UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC5x4UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC5x4Unorm;
|
||||
case wgpu::TextureFormat::ASTC5x5Unorm:
|
||||
return wgpu::TextureFormat::ASTC5x5UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC5x5UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC5x5Unorm;
|
||||
case wgpu::TextureFormat::ASTC6x5Unorm:
|
||||
return wgpu::TextureFormat::ASTC6x5UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC6x5UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC6x5Unorm;
|
||||
case wgpu::TextureFormat::ASTC6x6Unorm:
|
||||
return wgpu::TextureFormat::ASTC6x6UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC6x6UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC6x6Unorm;
|
||||
case wgpu::TextureFormat::ASTC8x5Unorm:
|
||||
return wgpu::TextureFormat::ASTC8x5UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC8x5UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC8x5Unorm;
|
||||
case wgpu::TextureFormat::ASTC8x6Unorm:
|
||||
return wgpu::TextureFormat::ASTC8x6UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC8x6UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC8x6Unorm;
|
||||
case wgpu::TextureFormat::ASTC8x8Unorm:
|
||||
return wgpu::TextureFormat::ASTC8x8UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC8x8UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC8x8Unorm;
|
||||
case wgpu::TextureFormat::ASTC10x5Unorm:
|
||||
return wgpu::TextureFormat::ASTC10x5UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC10x5UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC10x5Unorm;
|
||||
case wgpu::TextureFormat::ASTC10x6Unorm:
|
||||
return wgpu::TextureFormat::ASTC10x6UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC10x6UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC10x6Unorm;
|
||||
case wgpu::TextureFormat::ASTC10x8Unorm:
|
||||
return wgpu::TextureFormat::ASTC10x8UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC10x8UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC10x8Unorm;
|
||||
case wgpu::TextureFormat::ASTC10x10Unorm:
|
||||
return wgpu::TextureFormat::ASTC10x10UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC10x10UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC10x10Unorm;
|
||||
case wgpu::TextureFormat::ASTC12x10Unorm:
|
||||
return wgpu::TextureFormat::ASTC12x10UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC12x10UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC12x10Unorm;
|
||||
case wgpu::TextureFormat::ASTC12x12Unorm:
|
||||
return wgpu::TextureFormat::ASTC12x12UnormSrgb;
|
||||
case wgpu::TextureFormat::ASTC12x12UnormSrgb:
|
||||
return wgpu::TextureFormat::ASTC12x12Unorm;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Tests to verify that bufferOffset must be a multiple of the compressed texture blocks in bytes
|
||||
|
@ -2358,6 +2481,48 @@ TEST_F(CopyCommandTest_CompressedTextureFormats, CopyToMultipleArrayLayers) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test copying between textures that have srgb compatible texture formats;
|
||||
TEST_F(CopyCommandTest_CompressedTextureFormats, SrgbFormatCompatibility) {
|
||||
constexpr std::array<wgpu::TextureFormat, 42> srcFormats = {
|
||||
wgpu::TextureFormat::BC1RGBAUnorm, wgpu::TextureFormat::BC1RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::BC2RGBAUnorm, wgpu::TextureFormat::BC2RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::BC3RGBAUnorm, wgpu::TextureFormat::BC3RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::BC7RGBAUnorm, wgpu::TextureFormat::BC7RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::ETC2RGB8Unorm, wgpu::TextureFormat::ETC2RGB8UnormSrgb,
|
||||
wgpu::TextureFormat::ETC2RGB8A1Unorm, wgpu::TextureFormat::ETC2RGB8A1UnormSrgb,
|
||||
wgpu::TextureFormat::ETC2RGBA8Unorm, wgpu::TextureFormat::ETC2RGBA8UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC4x4Unorm, wgpu::TextureFormat::ASTC4x4UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC5x4Unorm, wgpu::TextureFormat::ASTC5x4UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC5x5Unorm, wgpu::TextureFormat::ASTC5x5UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC6x5Unorm, wgpu::TextureFormat::ASTC6x5UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC6x6Unorm, wgpu::TextureFormat::ASTC6x6UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC8x5Unorm, wgpu::TextureFormat::ASTC8x5UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC8x6Unorm, wgpu::TextureFormat::ASTC8x6UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC8x8Unorm, wgpu::TextureFormat::ASTC8x8UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC10x5Unorm, wgpu::TextureFormat::ASTC10x5UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC10x6Unorm, wgpu::TextureFormat::ASTC10x6UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC10x8Unorm, wgpu::TextureFormat::ASTC10x8UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC10x10Unorm, wgpu::TextureFormat::ASTC10x10UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC12x10Unorm, wgpu::TextureFormat::ASTC12x10UnormSrgb,
|
||||
wgpu::TextureFormat::ASTC12x12Unorm, wgpu::TextureFormat::ASTC12x12UnormSrgb};
|
||||
|
||||
constexpr uint32_t kBlockPerDim = 2;
|
||||
constexpr uint32_t kMipmapLevels = 1;
|
||||
for (wgpu::TextureFormat srcFormat : srcFormats) {
|
||||
uint32_t blockWidth = utils::GetTextureFormatBlockWidth(srcFormat);
|
||||
uint32_t blockHeight = utils::GetTextureFormatBlockHeight(srcFormat);
|
||||
uint32_t testWidth = blockWidth * kBlockPerDim;
|
||||
uint32_t testHeight = blockHeight * kBlockPerDim;
|
||||
wgpu::Texture texture = Create2DTexture(srcFormat, kMipmapLevels, testWidth, testHeight);
|
||||
wgpu::Texture texture2 = Create2DTexture(GetCopyCompatibleFormat(srcFormat), kMipmapLevels,
|
||||
testWidth, testHeight);
|
||||
wgpu::Extent3D extent3D = {testWidth, testHeight, 1};
|
||||
|
||||
TestBothT2TCopies(utils::Expectation::Success, texture, 0, {0, 0, 0}, texture2, 0,
|
||||
{0, 0, 0}, extent3D);
|
||||
}
|
||||
}
|
||||
|
||||
class CopyCommandTest_ClearBuffer : public CopyCommandTest {};
|
||||
|
||||
TEST_F(CopyCommandTest_ClearBuffer, Success) {
|
||||
|
|
Loading…
Reference in New Issue