dawn-cmake/src/dawn_native/vulkan/UtilsVulkan.cpp
Corentin Wallez 6298d2b70c Format: Move the TexelBlockInfo inside an AspectInfo.
In follow up CLs additional will be added to the AspectInfo, like the
supported component types.

Also simplify the logic for GetTexelInfo since all aspects are the first
aspects, except stencil which is always stencil8.

Bug: dawn:517
Change-Id: Iebbcb8a7f8fa2c4b7b06f65d6e4e8917c0a85366
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/30100
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
2020-10-15 09:05:03 +00:00

143 lines
6.1 KiB
C++

// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn_native/vulkan/UtilsVulkan.h"
#include "common/Assert.h"
#include "dawn_native/EnumMaskIterator.h"
#include "dawn_native/Format.h"
#include "dawn_native/vulkan/Forward.h"
#include "dawn_native/vulkan/TextureVk.h"
namespace dawn_native { namespace vulkan {
VkCompareOp ToVulkanCompareOp(wgpu::CompareFunction op) {
switch (op) {
case wgpu::CompareFunction::Never:
return VK_COMPARE_OP_NEVER;
case wgpu::CompareFunction::Less:
return VK_COMPARE_OP_LESS;
case wgpu::CompareFunction::LessEqual:
return VK_COMPARE_OP_LESS_OR_EQUAL;
case wgpu::CompareFunction::Greater:
return VK_COMPARE_OP_GREATER;
case wgpu::CompareFunction::GreaterEqual:
return VK_COMPARE_OP_GREATER_OR_EQUAL;
case wgpu::CompareFunction::Equal:
return VK_COMPARE_OP_EQUAL;
case wgpu::CompareFunction::NotEqual:
return VK_COMPARE_OP_NOT_EQUAL;
case wgpu::CompareFunction::Always:
return VK_COMPARE_OP_ALWAYS;
case wgpu::CompareFunction::Undefined:
UNREACHABLE();
}
}
// Convert Dawn texture aspects to Vulkan texture aspect flags
VkImageAspectFlags VulkanAspectMask(const Aspect& aspects) {
VkImageAspectFlags flags = 0;
for (Aspect aspect : IterateEnumMask(aspects)) {
switch (aspect) {
case Aspect::Color:
flags |= VK_IMAGE_ASPECT_COLOR_BIT;
break;
case Aspect::Depth:
flags |= VK_IMAGE_ASPECT_DEPTH_BIT;
break;
case Aspect::Stencil:
flags |= VK_IMAGE_ASPECT_STENCIL_BIT;
break;
case Aspect::None:
UNREACHABLE();
}
}
return flags;
}
// Vulkan SPEC requires the source/destination region specified by each element of
// pRegions must be a region that is contained within srcImage/dstImage. Here the size of
// the image refers to the virtual size, while Dawn validates texture copy extent with the
// physical size, so we need to re-calculate the texture copy extent to ensure it should fit
// in the virtual size of the subresource.
Extent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy, const Extent3D& copySize) {
Extent3D validTextureCopyExtent = copySize;
const TextureBase* texture = textureCopy.texture.Get();
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel);
if (textureCopy.origin.x + copySize.width > virtualSizeAtLevel.width) {
ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
}
if (textureCopy.origin.y + copySize.height > virtualSizeAtLevel.height) {
ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
}
return validTextureCopyExtent;
}
VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy,
const TextureCopy& textureCopy,
const Extent3D& copySize) {
TextureDataLayout passDataLayout;
passDataLayout.offset = bufferCopy.offset;
passDataLayout.rowsPerImage = bufferCopy.rowsPerImage;
passDataLayout.bytesPerRow = bufferCopy.bytesPerRow;
return ComputeBufferImageCopyRegion(passDataLayout, textureCopy, copySize);
}
VkBufferImageCopy ComputeBufferImageCopyRegion(const TextureDataLayout& dataLayout,
const TextureCopy& textureCopy,
const Extent3D& copySize) {
const Texture* texture = ToBackend(textureCopy.texture.Get());
VkBufferImageCopy region;
region.bufferOffset = dataLayout.offset;
// In Vulkan the row length is in texels while it is in bytes for Dawn
const TexelBlockInfo& blockInfo =
texture->GetFormat().GetAspectInfo(textureCopy.aspect).block;
ASSERT(dataLayout.bytesPerRow % blockInfo.byteSize == 0);
region.bufferRowLength = dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width;
region.bufferImageHeight = dataLayout.rowsPerImage * blockInfo.height;
region.imageSubresource.aspectMask = VulkanAspectMask(textureCopy.aspect);
region.imageSubresource.mipLevel = textureCopy.mipLevel;
switch (textureCopy.texture->GetDimension()) {
case wgpu::TextureDimension::e2D: {
region.imageOffset.x = textureCopy.origin.x;
region.imageOffset.y = textureCopy.origin.y;
region.imageOffset.z = 0;
region.imageSubresource.baseArrayLayer = textureCopy.origin.z;
region.imageSubresource.layerCount = copySize.depth;
Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
region.imageExtent.width = imageExtent.width;
region.imageExtent.height = imageExtent.height;
region.imageExtent.depth = 1;
break;
}
case wgpu::TextureDimension::e1D:
case wgpu::TextureDimension::e3D:
UNREACHABLE();
}
return region;
}
}} // namespace dawn_native::vulkan