Add testing and implementation for lazy init compressed textures
Bug: dawn:145 Change-Id: I176ac2fb4c7db708bb147e2ad0118538907b43d3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/33040 Commit-Queue: Natasha Lee <natlee@microsoft.com> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
8c813311f0
commit
c532048062
|
@ -851,11 +851,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
|
MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
|
||||||
const SubresourceRange& range,
|
const SubresourceRange& range,
|
||||||
TextureBase::ClearValue clearValue) {
|
TextureBase::ClearValue clearValue) {
|
||||||
// TODO(jiawei.shao@intel.com): initialize the textures in compressed formats with copies.
|
|
||||||
if (GetFormat().isCompressed) {
|
|
||||||
SetIsSubresourceContentInitialized(true, range);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();
|
ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();
|
||||||
|
|
||||||
|
@ -951,12 +946,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
uint32_t bytesPerRow = Align((GetWidth() / blockInfo.width) * blockInfo.byteSize,
|
uint32_t bytesPerRow = Align((GetWidth() / blockInfo.width) * blockInfo.byteSize,
|
||||||
kTextureBytesPerRowAlignment);
|
kTextureBytesPerRowAlignment);
|
||||||
uint64_t bufferSize64 = bytesPerRow * (GetHeight() / blockInfo.height);
|
uint64_t bufferSize = bytesPerRow * (GetHeight() / blockInfo.height);
|
||||||
if (bufferSize64 > std::numeric_limits<uint32_t>::max()) {
|
|
||||||
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate buffer.");
|
|
||||||
}
|
|
||||||
uint32_t bufferSize = static_cast<uint32_t>(bufferSize64);
|
|
||||||
|
|
||||||
DynamicUploader* uploader = device->GetDynamicUploader();
|
DynamicUploader* uploader = device->GetDynamicUploader();
|
||||||
UploadHandle uploadHandle;
|
UploadHandle uploadHandle;
|
||||||
DAWN_TRY_ASSIGN(uploadHandle,
|
DAWN_TRY_ASSIGN(uploadHandle,
|
||||||
|
@ -967,7 +957,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
for (uint32_t level = range.baseMipLevel;
|
for (uint32_t level = range.baseMipLevel;
|
||||||
level < range.baseMipLevel + range.levelCount; ++level) {
|
level < range.baseMipLevel + range.levelCount; ++level) {
|
||||||
// compute d3d12 texture copy locations for texture and buffer
|
// compute d3d12 texture copy locations for texture and buffer
|
||||||
Extent3D copySize = GetMipLevelVirtualSize(level);
|
Extent3D copySize = GetMipLevelPhysicalSize(level);
|
||||||
|
|
||||||
uint32_t rowsPerImage = GetHeight() / blockInfo.height;
|
uint32_t rowsPerImage = GetHeight() / blockInfo.height;
|
||||||
Texture2DCopySplit copySplit = ComputeTextureCopySplit(
|
Texture2DCopySplit copySplit = ComputeTextureCopySplit(
|
||||||
|
|
|
@ -1006,65 +1006,116 @@ namespace dawn_native { namespace vulkan {
|
||||||
imageRange.levelCount = 1;
|
imageRange.levelCount = 1;
|
||||||
imageRange.layerCount = 1;
|
imageRange.layerCount = 1;
|
||||||
|
|
||||||
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
|
if (GetFormat().isCompressed) {
|
||||||
++level) {
|
if (range.aspects == Aspect::None) {
|
||||||
imageRange.baseMipLevel = level;
|
return {};
|
||||||
for (uint32_t layer = range.baseArrayLayer;
|
}
|
||||||
layer < range.baseArrayLayer + range.layerCount; ++layer) {
|
// need to clear the texture with a copy from buffer
|
||||||
Aspect aspects = Aspect::None;
|
ASSERT(range.aspects == Aspect::Color);
|
||||||
for (Aspect aspect : IterateEnumMask(range.aspects)) {
|
const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
|
||||||
|
|
||||||
|
uint32_t bytesPerRow = Align((GetWidth() / blockInfo.width) * blockInfo.byteSize,
|
||||||
|
device->GetOptimalBytesPerRowAlignment());
|
||||||
|
uint64_t bufferSize = bytesPerRow * (GetHeight() / blockInfo.height);
|
||||||
|
DynamicUploader* uploader = device->GetDynamicUploader();
|
||||||
|
UploadHandle uploadHandle;
|
||||||
|
DAWN_TRY_ASSIGN(uploadHandle,
|
||||||
|
uploader->Allocate(bufferSize, device->GetPendingCommandSerial(),
|
||||||
|
blockInfo.byteSize));
|
||||||
|
memset(uploadHandle.mappedBuffer, uClearColor, bufferSize);
|
||||||
|
|
||||||
|
std::vector<VkBufferImageCopy> regions;
|
||||||
|
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
|
||||||
|
++level) {
|
||||||
|
imageRange.baseMipLevel = level;
|
||||||
|
for (uint32_t layer = range.baseArrayLayer;
|
||||||
|
layer < range.baseArrayLayer + range.layerCount; ++layer) {
|
||||||
if (clearValue == TextureBase::ClearValue::Zero &&
|
if (clearValue == TextureBase::ClearValue::Zero &&
|
||||||
IsSubresourceContentInitialized(
|
IsSubresourceContentInitialized(
|
||||||
SubresourceRange::SingleMipAndLayer(level, layer, aspect))) {
|
SubresourceRange::SingleMipAndLayer(level, layer, range.aspects))) {
|
||||||
// Skip lazy clears if already initialized.
|
// Skip lazy clears if already initialized.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
aspects |= aspect;
|
|
||||||
|
TextureDataLayout dataLayout;
|
||||||
|
dataLayout.offset = uploadHandle.startOffset;
|
||||||
|
dataLayout.rowsPerImage = GetHeight() / blockInfo.height;
|
||||||
|
dataLayout.bytesPerRow = bytesPerRow;
|
||||||
|
TextureCopy textureCopy;
|
||||||
|
textureCopy.aspect = range.aspects;
|
||||||
|
textureCopy.mipLevel = level;
|
||||||
|
textureCopy.origin = {0, 0, layer};
|
||||||
|
textureCopy.texture = this;
|
||||||
|
|
||||||
|
regions.push_back(ComputeBufferImageCopyRegion(dataLayout, textureCopy,
|
||||||
|
GetMipLevelPhysicalSize(level)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (aspects == Aspect::None) {
|
device->fn.CmdCopyBufferToImage(
|
||||||
continue;
|
recordingContext->commandBuffer,
|
||||||
}
|
ToBackend(uploadHandle.stagingBuffer)->GetBufferHandle(), GetHandle(),
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, regions.data());
|
||||||
imageRange.aspectMask = VulkanAspectMask(aspects);
|
} else {
|
||||||
imageRange.baseArrayLayer = layer;
|
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
|
||||||
|
++level) {
|
||||||
if (aspects & (Aspect::Depth | Aspect::Stencil)) {
|
imageRange.baseMipLevel = level;
|
||||||
VkClearDepthStencilValue clearDepthStencilValue[1];
|
for (uint32_t layer = range.baseArrayLayer;
|
||||||
clearDepthStencilValue[0].depth = fClearColor;
|
layer < range.baseArrayLayer + range.layerCount; ++layer) {
|
||||||
clearDepthStencilValue[0].stencil = uClearColor;
|
Aspect aspects = Aspect::None;
|
||||||
device->fn.CmdClearDepthStencilImage(recordingContext->commandBuffer,
|
for (Aspect aspect : IterateEnumMask(range.aspects)) {
|
||||||
GetHandle(),
|
if (clearValue == TextureBase::ClearValue::Zero &&
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
IsSubresourceContentInitialized(
|
||||||
clearDepthStencilValue, 1, &imageRange);
|
SubresourceRange::SingleMipAndLayer(level, layer, aspect))) {
|
||||||
} else {
|
// Skip lazy clears if already initialized.
|
||||||
ASSERT(aspects == Aspect::Color);
|
continue;
|
||||||
VkClearColorValue clearColorValue;
|
}
|
||||||
switch (GetFormat().GetAspectInfo(Aspect::Color).baseType) {
|
aspects |= aspect;
|
||||||
case wgpu::TextureComponentType::Float:
|
}
|
||||||
clearColorValue.float32[0] = fClearColor;
|
|
||||||
clearColorValue.float32[1] = fClearColor;
|
if (aspects == Aspect::None) {
|
||||||
clearColorValue.float32[2] = fClearColor;
|
continue;
|
||||||
clearColorValue.float32[3] = fClearColor;
|
}
|
||||||
break;
|
|
||||||
case wgpu::TextureComponentType::Sint:
|
imageRange.aspectMask = VulkanAspectMask(aspects);
|
||||||
clearColorValue.int32[0] = sClearColor;
|
imageRange.baseArrayLayer = layer;
|
||||||
clearColorValue.int32[1] = sClearColor;
|
|
||||||
clearColorValue.int32[2] = sClearColor;
|
if (aspects & (Aspect::Depth | Aspect::Stencil)) {
|
||||||
clearColorValue.int32[3] = sClearColor;
|
VkClearDepthStencilValue clearDepthStencilValue[1];
|
||||||
break;
|
clearDepthStencilValue[0].depth = fClearColor;
|
||||||
case wgpu::TextureComponentType::Uint:
|
clearDepthStencilValue[0].stencil = uClearColor;
|
||||||
clearColorValue.uint32[0] = uClearColor;
|
device->fn.CmdClearDepthStencilImage(
|
||||||
clearColorValue.uint32[1] = uClearColor;
|
recordingContext->commandBuffer, GetHandle(),
|
||||||
clearColorValue.uint32[2] = uClearColor;
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearDepthStencilValue, 1,
|
||||||
clearColorValue.uint32[3] = uClearColor;
|
&imageRange);
|
||||||
break;
|
} else {
|
||||||
case wgpu::TextureComponentType::DepthComparison:
|
ASSERT(aspects == Aspect::Color);
|
||||||
UNREACHABLE();
|
VkClearColorValue clearColorValue;
|
||||||
|
switch (GetFormat().GetAspectInfo(Aspect::Color).baseType) {
|
||||||
|
case wgpu::TextureComponentType::Float:
|
||||||
|
clearColorValue.float32[0] = fClearColor;
|
||||||
|
clearColorValue.float32[1] = fClearColor;
|
||||||
|
clearColorValue.float32[2] = fClearColor;
|
||||||
|
clearColorValue.float32[3] = fClearColor;
|
||||||
|
break;
|
||||||
|
case wgpu::TextureComponentType::Sint:
|
||||||
|
clearColorValue.int32[0] = sClearColor;
|
||||||
|
clearColorValue.int32[1] = sClearColor;
|
||||||
|
clearColorValue.int32[2] = sClearColor;
|
||||||
|
clearColorValue.int32[3] = sClearColor;
|
||||||
|
break;
|
||||||
|
case wgpu::TextureComponentType::Uint:
|
||||||
|
clearColorValue.uint32[0] = uClearColor;
|
||||||
|
clearColorValue.uint32[1] = uClearColor;
|
||||||
|
clearColorValue.uint32[2] = uClearColor;
|
||||||
|
clearColorValue.uint32[3] = uClearColor;
|
||||||
|
break;
|
||||||
|
case wgpu::TextureComponentType::DepthComparison:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
device->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(),
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
&clearColorValue, 1, &imageRange);
|
||||||
}
|
}
|
||||||
device->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(),
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
&clearColorValue, 1, &imageRange);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1082,12 +1133,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!IsSubresourceContentInitialized(range)) {
|
if (!IsSubresourceContentInitialized(range)) {
|
||||||
// TODO(jiawei.shao@intel.com): initialize textures in BC formats with Buffer-to-Texture
|
|
||||||
// copies.
|
|
||||||
if (GetFormat().isCompressed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If subresource has not been initialized, clear it to black as it could contain dirty
|
// If subresource has not been initialized, clear it to black as it could contain dirty
|
||||||
// bits from recycled memory
|
// bits from recycled memory
|
||||||
GetDevice()->ConsumedError(
|
GetDevice()->ConsumedError(
|
||||||
|
|
|
@ -419,16 +419,7 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
||||||
return sizeAtLevel;
|
return sizeAtLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::array<wgpu::TextureFormat, 14> kBCFormats = {
|
// The block width and height in texels are 4 for all BC formats.
|
||||||
wgpu::TextureFormat::BC1RGBAUnorm, wgpu::TextureFormat::BC1RGBAUnormSrgb,
|
|
||||||
wgpu::TextureFormat::BC2RGBAUnorm, wgpu::TextureFormat::BC2RGBAUnormSrgb,
|
|
||||||
wgpu::TextureFormat::BC3RGBAUnorm, wgpu::TextureFormat::BC3RGBAUnormSrgb,
|
|
||||||
wgpu::TextureFormat::BC4RSnorm, wgpu::TextureFormat::BC4RUnorm,
|
|
||||||
wgpu::TextureFormat::BC5RGSnorm, wgpu::TextureFormat::BC5RGUnorm,
|
|
||||||
wgpu::TextureFormat::BC6HRGBFloat, wgpu::TextureFormat::BC6HRGBUfloat,
|
|
||||||
wgpu::TextureFormat::BC7RGBAUnorm, wgpu::TextureFormat::BC7RGBAUnormSrgb};
|
|
||||||
|
|
||||||
// Tthe block width and height in texels are 4 for all BC formats.
|
|
||||||
static constexpr uint32_t kBCBlockWidthInTexels = 4;
|
static constexpr uint32_t kBCBlockWidthInTexels = 4;
|
||||||
static constexpr uint32_t kBCBlockHeightInTexels = 4;
|
static constexpr uint32_t kBCBlockHeightInTexels = 4;
|
||||||
|
|
||||||
|
@ -454,7 +445,7 @@ TEST_P(CompressedTextureBCFormatTest, Basic) {
|
||||||
config.textureDescriptor.size = {8, 8, 1};
|
config.textureDescriptor.size = {8, 8, 1};
|
||||||
config.copyExtent3D = config.textureDescriptor.size;
|
config.copyExtent3D = config.textureDescriptor.size;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -477,7 +468,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyIntoSubRegion) {
|
||||||
config.copyOrigin3D = kOrigin;
|
config.copyOrigin3D = kOrigin;
|
||||||
config.copyExtent3D = kExtent3D;
|
config.copyExtent3D = kExtent3D;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -503,7 +494,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyIntoNonZeroArrayLayer) {
|
||||||
config.textureDescriptor.size.depth = kArrayLayerCount;
|
config.textureDescriptor.size.depth = kArrayLayerCount;
|
||||||
config.copyOrigin3D.z = kArrayLayerCount - 1;
|
config.copyOrigin3D.z = kArrayLayerCount - 1;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -543,7 +534,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyBufferIntoNonZeroMipmapLevel) {
|
||||||
|
|
||||||
config.copyExtent3D = {kCopyWidthAtLevel, kCopyHeightAtLevel, 1};
|
config.copyExtent3D = {kCopyWidthAtLevel, kCopyHeightAtLevel, 1};
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -580,7 +571,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyWholeTextureSubResourceIntoNonZeroMipm
|
||||||
ASSERT_NE(0u, kVirtualSize.height % kBCBlockHeightInTexels);
|
ASSERT_NE(0u, kVirtualSize.height % kBCBlockHeightInTexels);
|
||||||
|
|
||||||
config.copyExtent3D = kPhysicalSize;
|
config.copyExtent3D = kPhysicalSize;
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
// Create bcTextureSrc as the source texture and initialize it with pre-prepared BC
|
// Create bcTextureSrc as the source texture and initialize it with pre-prepared BC
|
||||||
// compressed data.
|
// compressed data.
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
|
@ -643,7 +634,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyIntoSubresourceWithPhysicalSizeNotEqua
|
||||||
ASSERT_LT(srcConfig.copyOrigin3D.x + srcConfig.copyExtent3D.width, kSrcVirtualSize.width);
|
ASSERT_LT(srcConfig.copyOrigin3D.x + srcConfig.copyExtent3D.width, kSrcVirtualSize.width);
|
||||||
ASSERT_LT(srcConfig.copyOrigin3D.y + srcConfig.copyExtent3D.height, kSrcVirtualSize.height);
|
ASSERT_LT(srcConfig.copyOrigin3D.y + srcConfig.copyExtent3D.height, kSrcVirtualSize.height);
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
// Create bcTextureSrc as the source texture and initialize it with pre-prepared BC
|
// Create bcTextureSrc as the source texture and initialize it with pre-prepared BC
|
||||||
// compressed data.
|
// compressed data.
|
||||||
srcConfig.textureDescriptor.format = format;
|
srcConfig.textureDescriptor.format = format;
|
||||||
|
@ -705,7 +696,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyFromSubresourceWithPhysicalSizeNotEqua
|
||||||
ASSERT_GT(srcConfig.copyOrigin3D.x + srcConfig.copyExtent3D.width, kSrcVirtualSize.width);
|
ASSERT_GT(srcConfig.copyOrigin3D.x + srcConfig.copyExtent3D.width, kSrcVirtualSize.width);
|
||||||
ASSERT_GT(srcConfig.copyOrigin3D.y + srcConfig.copyExtent3D.height, kSrcVirtualSize.height);
|
ASSERT_GT(srcConfig.copyOrigin3D.y + srcConfig.copyExtent3D.height, kSrcVirtualSize.height);
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
srcConfig.textureDescriptor.format = dstConfig.textureDescriptor.format = format;
|
srcConfig.textureDescriptor.format = dstConfig.textureDescriptor.format = format;
|
||||||
srcConfig.textureDescriptor.usage =
|
srcConfig.textureDescriptor.usage =
|
||||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
|
||||||
|
@ -773,7 +764,7 @@ TEST_P(CompressedTextureBCFormatTest, MultipleCopiesWithPhysicalSizeNotEqualToVi
|
||||||
ASSERT_NE(0u, dstVirtualSizes[1].width % kBCBlockWidthInTexels);
|
ASSERT_NE(0u, dstVirtualSizes[1].width % kBCBlockWidthInTexels);
|
||||||
ASSERT_NE(0u, dstVirtualSizes[1].height % kBCBlockHeightInTexels);
|
ASSERT_NE(0u, dstVirtualSizes[1].height % kBCBlockHeightInTexels);
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
std::array<wgpu::Texture, kTotalCopyCount> bcSrcTextures;
|
std::array<wgpu::Texture, kTotalCopyCount> bcSrcTextures;
|
||||||
std::array<wgpu::Texture, kTotalCopyCount> bcDstTextures;
|
std::array<wgpu::Texture, kTotalCopyCount> bcDstTextures;
|
||||||
|
|
||||||
|
@ -832,7 +823,7 @@ TEST_P(CompressedTextureBCFormatTest, BufferOffsetAndExtentFitRowPitch) {
|
||||||
|
|
||||||
const uint32_t blockCountPerRow = config.textureDescriptor.size.width / kBCBlockWidthInTexels;
|
const uint32_t blockCountPerRow = config.textureDescriptor.size.width / kBCBlockWidthInTexels;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
|
|
||||||
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
||||||
|
@ -868,7 +859,7 @@ TEST_P(CompressedTextureBCFormatTest, BufferOffsetExceedsSlicePitch) {
|
||||||
const uint32_t slicePitchInBytes =
|
const uint32_t slicePitchInBytes =
|
||||||
config.bytesPerRowAlignment * (textureSizeLevel0.height / kBCBlockHeightInTexels);
|
config.bytesPerRowAlignment * (textureSizeLevel0.height / kBCBlockHeightInTexels);
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
|
|
||||||
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
||||||
|
@ -902,7 +893,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyWithBufferOffsetAndExtentExceedRowPitc
|
||||||
|
|
||||||
constexpr uint32_t kExceedRowBlockCount = 1;
|
constexpr uint32_t kExceedRowBlockCount = 1;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
|
|
||||||
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
||||||
|
@ -932,7 +923,7 @@ TEST_P(CompressedTextureBCFormatTest, RowPitchEqualToSlicePitch) {
|
||||||
const uint32_t blockCountPerRow = config.textureDescriptor.size.width / kBCBlockWidthInTexels;
|
const uint32_t blockCountPerRow = config.textureDescriptor.size.width / kBCBlockWidthInTexels;
|
||||||
const uint32_t slicePitchInBytes = config.bytesPerRowAlignment;
|
const uint32_t slicePitchInBytes = config.bytesPerRowAlignment;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
|
|
||||||
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
const uint32_t blockSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
|
||||||
|
@ -965,7 +956,7 @@ TEST_P(CompressedTextureBCFormatTest, LargeImageHeight) {
|
||||||
|
|
||||||
config.rowsPerImage = config.textureDescriptor.size.height * 2 / kBCBlockHeightInTexels;
|
config.rowsPerImage = config.textureDescriptor.size.height * 2 / kBCBlockHeightInTexels;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +999,7 @@ TEST_P(CompressedTextureBCFormatTest, LargeImageHeightAndClampedCopyExtent) {
|
||||||
|
|
||||||
config.rowsPerImage = kCopyHeightAtLevel * 2 / kBCBlockHeightInTexels;
|
config.rowsPerImage = kCopyHeightAtLevel * 2 / kBCBlockHeightInTexels;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -1036,7 +1027,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyWhole2DArrayTexture) {
|
||||||
config.copyExtent3D = config.textureDescriptor.size;
|
config.copyExtent3D = config.textureDescriptor.size;
|
||||||
config.copyExtent3D.depth = kArrayLayerCount;
|
config.copyExtent3D.depth = kArrayLayerCount;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1057,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyMultiple2DArrayLayers) {
|
||||||
config.copyExtent3D = config.textureDescriptor.size;
|
config.copyExtent3D = config.textureDescriptor.size;
|
||||||
config.copyExtent3D.depth = kCopyLayerCount;
|
config.copyExtent3D.depth = kCopyLayerCount;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestCopyRegionIntoBCFormatTextures(config);
|
TestCopyRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -1158,7 +1149,7 @@ TEST_P(CompressedTextureWriteTextureTest, Basic) {
|
||||||
config.bytesPerRowAlignment = 511;
|
config.bytesPerRowAlignment = 511;
|
||||||
config.rowsPerImage = 5;
|
config.rowsPerImage = 5;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestWriteRegionIntoBCFormatTextures(config);
|
TestWriteRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -1179,7 +1170,7 @@ TEST_P(CompressedTextureWriteTextureTest, WriteMultiple2DArrayLayers) {
|
||||||
config.bytesPerRowAlignment = 511;
|
config.bytesPerRowAlignment = 511;
|
||||||
config.rowsPerImage = 5;
|
config.rowsPerImage = 5;
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
config.textureDescriptor.format = format;
|
config.textureDescriptor.format = format;
|
||||||
TestWriteRegionIntoBCFormatTextures(config);
|
TestWriteRegionIntoBCFormatTextures(config);
|
||||||
}
|
}
|
||||||
|
@ -1199,7 +1190,7 @@ TEST_P(CompressedTextureWriteTextureTest,
|
||||||
// the texture physical size, but doesn't fit in the virtual size.
|
// the texture physical size, but doesn't fit in the virtual size.
|
||||||
for (unsigned int w : {12, 16}) {
|
for (unsigned int w : {12, 16}) {
|
||||||
for (unsigned int h : {12, 16}) {
|
for (unsigned int h : {12, 16}) {
|
||||||
for (wgpu::TextureFormat format : kBCFormats) {
|
for (wgpu::TextureFormat format : utils::kBCFormats) {
|
||||||
CopyConfig config;
|
CopyConfig config;
|
||||||
config.textureDescriptor.usage = kDefaultBCFormatTextureUsage;
|
config.textureDescriptor.usage = kDefaultBCFormatTextureUsage;
|
||||||
config.textureDescriptor.size = {60, 60, 1};
|
config.textureDescriptor.size = {60, 60, 1};
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// TODO(natlee@microsoft.com): test compressed textures are cleared
|
|
||||||
class TextureZeroInitTest : public DawnTest {
|
class TextureZeroInitTest : public DawnTest {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
|
@ -53,10 +52,12 @@ class TextureZeroInitTest : public DawnTest {
|
||||||
descriptor.usage = usage;
|
descriptor.usage = usage;
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
wgpu::TextureViewDescriptor CreateTextureViewDescriptor(uint32_t baseMipLevel,
|
wgpu::TextureViewDescriptor CreateTextureViewDescriptor(
|
||||||
uint32_t baseArrayLayer) {
|
uint32_t baseMipLevel,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
wgpu::TextureFormat format = kColorFormat) {
|
||||||
wgpu::TextureViewDescriptor descriptor;
|
wgpu::TextureViewDescriptor descriptor;
|
||||||
descriptor.format = kColorFormat;
|
descriptor.format = format;
|
||||||
descriptor.baseArrayLayer = baseArrayLayer;
|
descriptor.baseArrayLayer = baseArrayLayer;
|
||||||
descriptor.arrayLayerCount = 1;
|
descriptor.arrayLayerCount = 1;
|
||||||
descriptor.baseMipLevel = baseMipLevel;
|
descriptor.baseMipLevel = baseMipLevel;
|
||||||
|
@ -108,10 +109,11 @@ class TextureZeroInitTest : public DawnTest {
|
||||||
fragColor = texelFetch(sampler2D(texture0, sampler0), ivec2(gl_FragCoord), 0);
|
fragColor = texelFetch(sampler2D(texture0, sampler0), ivec2(gl_FragCoord), 0);
|
||||||
})");
|
})");
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr static uint32_t kSize = 128;
|
constexpr static uint32_t kSize = 128;
|
||||||
constexpr static uint32_t kUnalignedSize = 127;
|
constexpr static uint32_t kUnalignedSize = 127;
|
||||||
// All three texture formats used (RGBA8Unorm, Depth24PlusStencil8, and RGBA8Snorm) have the
|
// All texture formats used (RGBA8Unorm, Depth24PlusStencil8, and RGBA8Snorm, BC formats)
|
||||||
// same byte size of 4.
|
// have the same block byte size of 4.
|
||||||
constexpr static uint32_t kFormatBlockByteSize = 4;
|
constexpr static uint32_t kFormatBlockByteSize = 4;
|
||||||
constexpr static wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;
|
constexpr static wgpu::TextureFormat kColorFormat = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
constexpr static wgpu::TextureFormat kDepthStencilFormat =
|
constexpr static wgpu::TextureFormat kDepthStencilFormat =
|
||||||
|
@ -1644,3 +1646,342 @@ DAWN_INSTANTIATE_TEST(TextureZeroInitTest,
|
||||||
OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}),
|
OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}),
|
||||||
MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}),
|
MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}),
|
||||||
VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}));
|
VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}));
|
||||||
|
|
||||||
|
class CompressedTextureZeroInitTest : public TextureZeroInitTest {
|
||||||
|
protected:
|
||||||
|
void SetUp() override {
|
||||||
|
DawnTest::SetUp();
|
||||||
|
DAWN_SKIP_TEST_IF(UsesWire());
|
||||||
|
DAWN_SKIP_TEST_IF(!IsBCFormatSupported());
|
||||||
|
// TODO: find out why this test is flaky on Windows Intel Vulkan bots.
|
||||||
|
DAWN_SKIP_TEST_IF(IsIntel() && IsVulkan() && IsWindows());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const char*> GetRequiredExtensions() override {
|
||||||
|
mIsBCFormatSupported = SupportsExtensions({"texture_compression_bc"});
|
||||||
|
if (!mIsBCFormatSupported) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {"texture_compression_bc"};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsBCFormatSupported() const {
|
||||||
|
return mIsBCFormatSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the compressed texture data into the destination texture.
|
||||||
|
void InitializeDataInCompressedTextureAndExpectLazyClear(
|
||||||
|
wgpu::Texture bcCompressedTexture,
|
||||||
|
wgpu::TextureDescriptor textureDescriptor,
|
||||||
|
wgpu::Extent3D copyExtent3D,
|
||||||
|
uint32_t viewMipmapLevel,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
size_t lazyClearCount) {
|
||||||
|
uint32_t copyWidthInBlock = copyExtent3D.width / kFormatBlockByteSize;
|
||||||
|
uint32_t copyHeightInBlock = copyExtent3D.height / kFormatBlockByteSize;
|
||||||
|
uint32_t copyBytesPerRow =
|
||||||
|
Align(copyWidthInBlock * utils::GetTexelBlockSizeInBytes(textureDescriptor.format),
|
||||||
|
kTextureBytesPerRowAlignment);
|
||||||
|
|
||||||
|
std::vector<uint8_t> data(
|
||||||
|
utils::RequiredBytesInCopy(copyBytesPerRow, copyHeightInBlock, copyExtent3D,
|
||||||
|
textureDescriptor.format),
|
||||||
|
1);
|
||||||
|
|
||||||
|
// Copy texture data from a staging buffer to the destination texture.
|
||||||
|
wgpu::Buffer stagingBuffer = utils::CreateBufferFromData(device, data.data(), data.size(),
|
||||||
|
wgpu::BufferUsage::CopySrc);
|
||||||
|
wgpu::BufferCopyView bufferCopyView =
|
||||||
|
utils::CreateBufferCopyView(stagingBuffer, 0, copyBytesPerRow, copyHeightInBlock);
|
||||||
|
|
||||||
|
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||||
|
bcCompressedTexture, viewMipmapLevel, {0, 0, baseArrayLayer});
|
||||||
|
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Extent3D);
|
||||||
|
wgpu::CommandBuffer copy = encoder.Finish();
|
||||||
|
EXPECT_LAZY_CLEAR(lazyClearCount, queue.Submit(1, ©));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the tests that copies pre-prepared BC format data into a BC texture and verifies if we
|
||||||
|
// can render correctly with the pixel values sampled from the BC texture.
|
||||||
|
// Expect that the texture subresource is initialized
|
||||||
|
void TestCopyRegionIntoBCFormatTexturesAndCheckSubresourceIsInitialized(
|
||||||
|
wgpu::TextureDescriptor textureDescriptor,
|
||||||
|
wgpu::Extent3D copyExtent3D,
|
||||||
|
wgpu::Extent3D nonPaddedCopyExtent,
|
||||||
|
uint32_t viewMipmapLevel,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
size_t lazyClearCount,
|
||||||
|
bool halfCopyTest = false) {
|
||||||
|
wgpu::Texture bcTexture = device.CreateTexture(&textureDescriptor);
|
||||||
|
InitializeDataInCompressedTextureAndExpectLazyClear(bcTexture, textureDescriptor,
|
||||||
|
copyExtent3D, viewMipmapLevel,
|
||||||
|
baseArrayLayer, lazyClearCount);
|
||||||
|
|
||||||
|
SampleCompressedTextureAndVerifyColor(bcTexture, textureDescriptor, copyExtent3D,
|
||||||
|
nonPaddedCopyExtent, viewMipmapLevel, baseArrayLayer,
|
||||||
|
halfCopyTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleCompressedTextureAndVerifyColor(wgpu::Texture bcTexture,
|
||||||
|
wgpu::TextureDescriptor textureDescriptor,
|
||||||
|
wgpu::Extent3D copyExtent3D,
|
||||||
|
wgpu::Extent3D nonPaddedCopyExtent,
|
||||||
|
uint32_t viewMipmapLevel,
|
||||||
|
uint32_t baseArrayLayer,
|
||||||
|
bool halfCopyTest = false) {
|
||||||
|
// Sample the compressed texture and verify the texture colors in the render target
|
||||||
|
utils::BasicRenderPass renderPass =
|
||||||
|
utils::CreateBasicRenderPass(device, textureDescriptor.size.width >> viewMipmapLevel,
|
||||||
|
textureDescriptor.size.height >> viewMipmapLevel);
|
||||||
|
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
{
|
||||||
|
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
|
||||||
|
utils::ComboRenderPipelineDescriptor renderPipelineDescriptor(device);
|
||||||
|
renderPipelineDescriptor.cColorStates[0].format = kColorFormat;
|
||||||
|
renderPipelineDescriptor.vertexStage.module = CreateBasicVertexShaderForTest();
|
||||||
|
renderPipelineDescriptor.cFragmentStage.module =
|
||||||
|
CreateSampledTextureFragmentShaderForTest();
|
||||||
|
wgpu::RenderPipeline renderPipeline =
|
||||||
|
device.CreateRenderPipeline(&renderPipelineDescriptor);
|
||||||
|
pass.SetPipeline(renderPipeline);
|
||||||
|
|
||||||
|
wgpu::SamplerDescriptor samplerDesc = {};
|
||||||
|
wgpu::Sampler sampler = device.CreateSampler(&samplerDesc);
|
||||||
|
|
||||||
|
wgpu::TextureViewDescriptor textureViewDescriptor = CreateTextureViewDescriptor(
|
||||||
|
viewMipmapLevel, baseArrayLayer, textureDescriptor.format);
|
||||||
|
wgpu::BindGroup bindGroup = utils::MakeBindGroup(
|
||||||
|
device, renderPipeline.GetBindGroupLayout(0),
|
||||||
|
{{0, sampler}, {1, bcTexture.CreateView(&textureViewDescriptor)}});
|
||||||
|
pass.SetBindGroup(0, bindGroup);
|
||||||
|
pass.Draw(6);
|
||||||
|
pass.EndPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
|
||||||
|
std::vector<RGBA8> expected(nonPaddedCopyExtent.width * nonPaddedCopyExtent.height,
|
||||||
|
{0x00, 0x20, 0x08, 0xFF});
|
||||||
|
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, nonPaddedCopyExtent.width,
|
||||||
|
nonPaddedCopyExtent.height, 0, 0);
|
||||||
|
EXPECT_TRUE(dawn_native::IsTextureSubresourceInitialized(bcTexture.Get(), viewMipmapLevel,
|
||||||
|
1, baseArrayLayer, 1));
|
||||||
|
|
||||||
|
// If we only copied to half the texture, check the other half is initialized to black
|
||||||
|
if (halfCopyTest) {
|
||||||
|
std::vector<RGBA8> expectBlack(nonPaddedCopyExtent.width * nonPaddedCopyExtent.height,
|
||||||
|
{0x00, 0x00, 0x00, 0xFF});
|
||||||
|
EXPECT_TEXTURE_RGBA8_EQ(expectBlack.data(), renderPass.color, copyExtent3D.width, 0,
|
||||||
|
nonPaddedCopyExtent.width, nonPaddedCopyExtent.height, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mIsBCFormatSupported = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test that the clearing is skipped when we use a full mip copy (with the physical size different
|
||||||
|
// than the virtual mip size)
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, FullMipCopy) {
|
||||||
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
|
textureDescriptor.usage =
|
||||||
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
textureDescriptor.size = {60, 60, 1};
|
||||||
|
textureDescriptor.mipLevelCount = 1;
|
||||||
|
textureDescriptor.format = utils::kBCFormats[0];
|
||||||
|
|
||||||
|
TestCopyRegionIntoBCFormatTexturesAndCheckSubresourceIsInitialized(
|
||||||
|
textureDescriptor, textureDescriptor.size, textureDescriptor.size, 0, 0, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that 1 lazy clear count happens when we copy to half the texture
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyBufferToTexture) {
|
||||||
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
|
textureDescriptor.usage =
|
||||||
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
constexpr static uint32_t kSize = 16;
|
||||||
|
textureDescriptor.size = {kSize, kSize, 1};
|
||||||
|
textureDescriptor.mipLevelCount = 1;
|
||||||
|
textureDescriptor.format = utils::kBCFormats[0];
|
||||||
|
|
||||||
|
wgpu::Extent3D copyExtent3D = {kSize / 2, kSize, 1};
|
||||||
|
|
||||||
|
TestCopyRegionIntoBCFormatTexturesAndCheckSubresourceIsInitialized(
|
||||||
|
textureDescriptor, copyExtent3D, copyExtent3D, 0, 0, 1u, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that 0 lazy clear count happens when we copy buffer to texture to a nonzero mip level
|
||||||
|
// (with physical size different from the virtual mip size)
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroMipLevel) {
|
||||||
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
|
textureDescriptor.usage =
|
||||||
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
constexpr static uint32_t kSize = 60;
|
||||||
|
textureDescriptor.size = {kSize, kSize, 1};
|
||||||
|
textureDescriptor.mipLevelCount = 3;
|
||||||
|
textureDescriptor.format = utils::kBCFormats[0];
|
||||||
|
const uint32_t kViewMipLevel = 2;
|
||||||
|
const uint32_t kActualSizeAtLevel = kSize >> kViewMipLevel;
|
||||||
|
|
||||||
|
const uint32_t kCopySizeAtLevel = Align(kActualSizeAtLevel, kFormatBlockByteSize);
|
||||||
|
|
||||||
|
wgpu::Extent3D copyExtent3D = {kCopySizeAtLevel, kCopySizeAtLevel, 1};
|
||||||
|
|
||||||
|
TestCopyRegionIntoBCFormatTexturesAndCheckSubresourceIsInitialized(
|
||||||
|
textureDescriptor, copyExtent3D, {kActualSizeAtLevel, kActualSizeAtLevel, 1}, kViewMipLevel,
|
||||||
|
0, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that 1 lazy clear count happens when we copy buffer to half texture to a nonzero mip level
|
||||||
|
// (with physical size different from the virtual mip size)
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroMipLevel) {
|
||||||
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
|
textureDescriptor.usage =
|
||||||
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
constexpr static uint32_t kSize = 60;
|
||||||
|
textureDescriptor.size = {kSize, kSize, 1};
|
||||||
|
textureDescriptor.mipLevelCount = 3;
|
||||||
|
textureDescriptor.format = utils::kBCFormats[0];
|
||||||
|
const uint32_t kViewMipLevel = 2;
|
||||||
|
const uint32_t kActualSizeAtLevel = kSize >> kViewMipLevel;
|
||||||
|
|
||||||
|
const uint32_t kCopySizeAtLevel = Align(kActualSizeAtLevel, kFormatBlockByteSize);
|
||||||
|
|
||||||
|
wgpu::Extent3D copyExtent3D = {kCopySizeAtLevel / 2, kCopySizeAtLevel, 1};
|
||||||
|
|
||||||
|
TestCopyRegionIntoBCFormatTexturesAndCheckSubresourceIsInitialized(
|
||||||
|
textureDescriptor, copyExtent3D, {kActualSizeAtLevel / 2, kActualSizeAtLevel, 1},
|
||||||
|
kViewMipLevel, 0, 1u, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that 0 lazy clear count happens when we copy buffer to nonzero array layer
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroArrayLayer) {
|
||||||
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
|
textureDescriptor.usage =
|
||||||
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
constexpr static uint32_t kSize = 16;
|
||||||
|
constexpr static uint32_t kArrayLayers = 4;
|
||||||
|
textureDescriptor.size = {kSize, kSize, kArrayLayers};
|
||||||
|
textureDescriptor.mipLevelCount = 1;
|
||||||
|
textureDescriptor.format = utils::kBCFormats[0];
|
||||||
|
|
||||||
|
wgpu::Extent3D copyExtent3D = {kSize, kSize, 1};
|
||||||
|
|
||||||
|
TestCopyRegionIntoBCFormatTexturesAndCheckSubresourceIsInitialized(
|
||||||
|
textureDescriptor, copyExtent3D, copyExtent3D, 0, kArrayLayers - 2, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that 1 lazy clear count happens when we copy buffer to half texture to a nonzero array layer
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroArrayLayer) {
|
||||||
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
|
textureDescriptor.usage =
|
||||||
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
constexpr static uint32_t kSize = 16;
|
||||||
|
constexpr static uint32_t kArrayLayers = 4;
|
||||||
|
textureDescriptor.size = {kSize, kSize, kArrayLayers};
|
||||||
|
textureDescriptor.mipLevelCount = 3;
|
||||||
|
textureDescriptor.format = utils::kBCFormats[0];
|
||||||
|
|
||||||
|
wgpu::Extent3D copyExtent3D = {kSize / 2, kSize, 1};
|
||||||
|
|
||||||
|
TestCopyRegionIntoBCFormatTexturesAndCheckSubresourceIsInitialized(
|
||||||
|
textureDescriptor, copyExtent3D, copyExtent3D, 0, kArrayLayers - 2, 1u, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// full copy texture to texture, 0 lazy clears are needed
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, FullCopyTextureToTextureMipLevel) {
|
||||||
|
// create srcTexture and fill it with data
|
||||||
|
wgpu::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
|
||||||
|
3, 1,
|
||||||
|
wgpu::TextureUsage::Sampled | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst,
|
||||||
|
utils::kBCFormats[0]);
|
||||||
|
wgpu::Texture srcTexture = device.CreateTexture(&srcDescriptor);
|
||||||
|
|
||||||
|
const uint32_t kViewMipLevel = 2;
|
||||||
|
const uint32_t kActualSizeAtLevel = kSize >> kViewMipLevel;
|
||||||
|
|
||||||
|
const uint32_t kCopySizeAtLevel = Align(kActualSizeAtLevel, kFormatBlockByteSize);
|
||||||
|
|
||||||
|
wgpu::Extent3D copyExtent3D = {kCopySizeAtLevel, kCopySizeAtLevel, 1};
|
||||||
|
|
||||||
|
// fill srcTexture with data
|
||||||
|
InitializeDataInCompressedTextureAndExpectLazyClear(srcTexture, srcDescriptor, copyExtent3D,
|
||||||
|
kViewMipLevel, 0, 0u);
|
||||||
|
|
||||||
|
wgpu::TextureCopyView srcTextureCopyView =
|
||||||
|
utils::CreateTextureCopyView(srcTexture, kViewMipLevel, {0, 0, 0});
|
||||||
|
|
||||||
|
// create dstTexture that we will copy to
|
||||||
|
wgpu::TextureDescriptor dstDescriptor = CreateTextureDescriptor(
|
||||||
|
3, 1,
|
||||||
|
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::Sampled,
|
||||||
|
utils::kBCFormats[0]);
|
||||||
|
wgpu::Texture dstTexture = device.CreateTexture(&dstDescriptor);
|
||||||
|
|
||||||
|
wgpu::TextureCopyView dstTextureCopyView =
|
||||||
|
utils::CreateTextureCopyView(dstTexture, kViewMipLevel, {0, 0, 0});
|
||||||
|
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, ©Extent3D);
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
// the dstTexture does not need to be lazy cleared since it's fully copied to
|
||||||
|
EXPECT_LAZY_CLEAR(0u, queue.Submit(1, &commands));
|
||||||
|
|
||||||
|
SampleCompressedTextureAndVerifyColor(dstTexture, dstDescriptor, copyExtent3D,
|
||||||
|
{kActualSizeAtLevel, kActualSizeAtLevel, 1},
|
||||||
|
kViewMipLevel, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// half copy texture to texture, lazy clears are needed for noncopied half
|
||||||
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyTextureToTextureMipLevel) {
|
||||||
|
// create srcTexture with data
|
||||||
|
wgpu::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
|
||||||
|
3, 1,
|
||||||
|
wgpu::TextureUsage::Sampled | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst,
|
||||||
|
utils::kBCFormats[0]);
|
||||||
|
wgpu::Texture srcTexture = device.CreateTexture(&srcDescriptor);
|
||||||
|
|
||||||
|
const uint32_t kViewMipLevel = 2;
|
||||||
|
const uint32_t kActualSizeAtLevel = kSize >> kViewMipLevel;
|
||||||
|
|
||||||
|
const uint32_t kCopySizeAtLevel = Align(kActualSizeAtLevel, kFormatBlockByteSize);
|
||||||
|
|
||||||
|
wgpu::Extent3D copyExtent3D = {kCopySizeAtLevel / 2, kCopySizeAtLevel, 1};
|
||||||
|
|
||||||
|
// fill srcTexture with data
|
||||||
|
InitializeDataInCompressedTextureAndExpectLazyClear(srcTexture, srcDescriptor, copyExtent3D,
|
||||||
|
kViewMipLevel, 0, 1u);
|
||||||
|
|
||||||
|
wgpu::TextureCopyView srcTextureCopyView =
|
||||||
|
utils::CreateTextureCopyView(srcTexture, kViewMipLevel, {0, 0, 0});
|
||||||
|
|
||||||
|
// create dstTexture that we will copy to
|
||||||
|
wgpu::TextureDescriptor dstDescriptor = CreateTextureDescriptor(
|
||||||
|
3, 1,
|
||||||
|
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::Sampled,
|
||||||
|
utils::kBCFormats[0]);
|
||||||
|
wgpu::Texture dstTexture = device.CreateTexture(&dstDescriptor);
|
||||||
|
|
||||||
|
wgpu::TextureCopyView dstTextureCopyView =
|
||||||
|
utils::CreateTextureCopyView(dstTexture, kViewMipLevel, {0, 0, 0});
|
||||||
|
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, ©Extent3D);
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
// expect 1 lazy clear count since the dstTexture needs to be lazy cleared when we only copy to
|
||||||
|
// half texture
|
||||||
|
EXPECT_LAZY_CLEAR(1u, queue.Submit(1, &commands));
|
||||||
|
|
||||||
|
SampleCompressedTextureAndVerifyColor(dstTexture, dstDescriptor, copyExtent3D,
|
||||||
|
{kActualSizeAtLevel / 2, kActualSizeAtLevel, 1},
|
||||||
|
kViewMipLevel, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
DAWN_INSTANTIATE_TEST(CompressedTextureZeroInitTest,
|
||||||
|
D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}),
|
||||||
|
MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}),
|
||||||
|
VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}));
|
||||||
|
|
Loading…
Reference in New Issue