2019-01-04 04:56:08 +00:00
|
|
|
// 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"
|
2020-08-06 17:00:29 +00:00
|
|
|
#include "dawn_native/EnumMaskIterator.h"
|
2019-08-14 23:11:42 +00:00
|
|
|
#include "dawn_native/Format.h"
|
|
|
|
#include "dawn_native/vulkan/Forward.h"
|
|
|
|
#include "dawn_native/vulkan/TextureVk.h"
|
2019-01-04 04:56:08 +00:00
|
|
|
|
|
|
|
namespace dawn_native { namespace vulkan {
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkCompareOp ToVulkanCompareOp(wgpu::CompareFunction op) {
|
2019-01-04 04:56:08 +00:00
|
|
|
switch (op) {
|
2020-04-17 19:32:07 +00:00
|
|
|
case wgpu::CompareFunction::Never:
|
|
|
|
return VK_COMPARE_OP_NEVER;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::CompareFunction::Less:
|
2019-01-04 04:56:08 +00:00
|
|
|
return VK_COMPARE_OP_LESS;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::CompareFunction::LessEqual:
|
2019-01-04 04:56:08 +00:00
|
|
|
return VK_COMPARE_OP_LESS_OR_EQUAL;
|
2020-04-17 19:32:07 +00:00
|
|
|
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;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::CompareFunction::NotEqual:
|
2019-01-04 04:56:08 +00:00
|
|
|
return VK_COMPARE_OP_NOT_EQUAL;
|
2020-04-17 19:32:07 +00:00
|
|
|
case wgpu::CompareFunction::Always:
|
|
|
|
return VK_COMPARE_OP_ALWAYS;
|
2020-09-24 14:56:50 +00:00
|
|
|
|
|
|
|
case wgpu::CompareFunction::Undefined:
|
2019-01-04 04:56:08 +00:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-06 17:00:29 +00:00
|
|
|
// 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;
|
2020-09-24 14:56:50 +00:00
|
|
|
case Aspect::None:
|
2020-08-06 17:00:29 +00:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2019-08-14 23:11:42 +00:00
|
|
|
// 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) {
|
2020-07-16 09:08:41 +00:00
|
|
|
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) {
|
2019-08-14 23:11:42 +00:00
|
|
|
const Texture* texture = ToBackend(textureCopy.texture.Get());
|
|
|
|
|
|
|
|
VkBufferImageCopy region;
|
|
|
|
|
2020-07-16 09:08:41 +00:00
|
|
|
region.bufferOffset = dataLayout.offset;
|
2019-08-14 23:11:42 +00:00
|
|
|
// In Vulkan the row length is in texels while it is in bytes for Dawn
|
2020-08-04 19:46:37 +00:00
|
|
|
const TexelBlockInfo& blockInfo =
|
2020-10-15 09:05:03 +00:00
|
|
|
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;
|
2019-08-14 23:11:42 +00:00
|
|
|
|
2020-08-06 17:00:29 +00:00
|
|
|
region.imageSubresource.aspectMask = VulkanAspectMask(textureCopy.aspect);
|
2019-08-14 23:11:42 +00:00
|
|
|
region.imageSubresource.mipLevel = textureCopy.mipLevel;
|
|
|
|
|
2020-06-26 11:07:00 +00:00
|
|
|
switch (textureCopy.texture->GetDimension()) {
|
|
|
|
case wgpu::TextureDimension::e2D: {
|
|
|
|
region.imageOffset.x = textureCopy.origin.x;
|
|
|
|
region.imageOffset.y = textureCopy.origin.y;
|
|
|
|
region.imageOffset.z = 0;
|
2019-08-14 23:11:42 +00:00
|
|
|
|
2020-06-26 11:07:00 +00:00
|
|
|
region.imageSubresource.baseArrayLayer = textureCopy.origin.z;
|
|
|
|
region.imageSubresource.layerCount = copySize.depth;
|
2020-06-21 09:33:44 +00:00
|
|
|
|
2020-06-26 11:07:00 +00:00
|
|
|
Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
|
|
|
|
region.imageExtent.width = imageExtent.width;
|
|
|
|
region.imageExtent.height = imageExtent.height;
|
|
|
|
region.imageExtent.depth = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-09-24 14:56:50 +00:00
|
|
|
case wgpu::TextureDimension::e1D:
|
|
|
|
case wgpu::TextureDimension::e3D:
|
2020-06-26 11:07:00 +00:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
2019-08-14 23:11:42 +00:00
|
|
|
|
|
|
|
return region;
|
|
|
|
}
|
2020-08-04 19:46:37 +00:00
|
|
|
}} // namespace dawn_native::vulkan
|