blob: 15011ce5270b78bd8b2ad45306697881479e8d8f [file] [log] [blame]
Yan, Shaobo93158eb2019-01-04 04:56:08 +00001// Copyright 2019 The Dawn Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "dawn_native/vulkan/UtilsVulkan.h"
16
17#include "common/Assert.h"
Natasha Lee5f8a8aa2019-08-14 23:11:42 +000018#include "dawn_native/Format.h"
19#include "dawn_native/vulkan/Forward.h"
20#include "dawn_native/vulkan/TextureVk.h"
Yan, Shaobo93158eb2019-01-04 04:56:08 +000021
22namespace dawn_native { namespace vulkan {
23
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000024 VkCompareOp ToVulkanCompareOp(wgpu::CompareFunction op) {
Yan, Shaobo93158eb2019-01-04 04:56:08 +000025 switch (op) {
Austin Engd6a54312020-04-17 19:32:07 +000026 case wgpu::CompareFunction::Never:
27 return VK_COMPARE_OP_NEVER;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000028 case wgpu::CompareFunction::Less:
Yan, Shaobo93158eb2019-01-04 04:56:08 +000029 return VK_COMPARE_OP_LESS;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000030 case wgpu::CompareFunction::LessEqual:
Yan, Shaobo93158eb2019-01-04 04:56:08 +000031 return VK_COMPARE_OP_LESS_OR_EQUAL;
Austin Engd6a54312020-04-17 19:32:07 +000032 case wgpu::CompareFunction::Greater:
33 return VK_COMPARE_OP_GREATER;
34 case wgpu::CompareFunction::GreaterEqual:
35 return VK_COMPARE_OP_GREATER_OR_EQUAL;
36 case wgpu::CompareFunction::Equal:
37 return VK_COMPARE_OP_EQUAL;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000038 case wgpu::CompareFunction::NotEqual:
Yan, Shaobo93158eb2019-01-04 04:56:08 +000039 return VK_COMPARE_OP_NOT_EQUAL;
Austin Engd6a54312020-04-17 19:32:07 +000040 case wgpu::CompareFunction::Always:
41 return VK_COMPARE_OP_ALWAYS;
Yan, Shaobo93158eb2019-01-04 04:56:08 +000042 default:
43 UNREACHABLE();
44 }
45 }
46
Natasha Lee5f8a8aa2019-08-14 23:11:42 +000047 // Vulkan SPEC requires the source/destination region specified by each element of
48 // pRegions must be a region that is contained within srcImage/dstImage. Here the size of
49 // the image refers to the virtual size, while Dawn validates texture copy extent with the
50 // physical size, so we need to re-calculate the texture copy extent to ensure it should fit
51 // in the virtual size of the subresource.
52 Extent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy, const Extent3D& copySize) {
53 Extent3D validTextureCopyExtent = copySize;
54 const TextureBase* texture = textureCopy.texture.Get();
55 Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel);
56 if (textureCopy.origin.x + copySize.width > virtualSizeAtLevel.width) {
57 ASSERT(texture->GetFormat().isCompressed);
58 validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
59 }
60 if (textureCopy.origin.y + copySize.height > virtualSizeAtLevel.height) {
61 ASSERT(texture->GetFormat().isCompressed);
62 validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
63 }
64
65 return validTextureCopyExtent;
66 }
67
68 VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy,
69 const TextureCopy& textureCopy,
70 const Extent3D& copySize) {
Tomek Ponitkae28cc552020-07-16 09:08:41 +000071 TextureDataLayout passDataLayout;
72 passDataLayout.offset = bufferCopy.offset;
73 passDataLayout.rowsPerImage = bufferCopy.rowsPerImage;
74 passDataLayout.bytesPerRow = bufferCopy.bytesPerRow;
75 return ComputeBufferImageCopyRegion(passDataLayout, textureCopy, copySize);
76 }
77
78 VkBufferImageCopy ComputeBufferImageCopyRegion(const TextureDataLayout& dataLayout,
79 const TextureCopy& textureCopy,
80 const Extent3D& copySize) {
Natasha Lee5f8a8aa2019-08-14 23:11:42 +000081 const Texture* texture = ToBackend(textureCopy.texture.Get());
82
83 VkBufferImageCopy region;
84
Tomek Ponitkae28cc552020-07-16 09:08:41 +000085 region.bufferOffset = dataLayout.offset;
Natasha Lee5f8a8aa2019-08-14 23:11:42 +000086 // In Vulkan the row length is in texels while it is in bytes for Dawn
87 const Format& format = texture->GetFormat();
Tomek Ponitkae28cc552020-07-16 09:08:41 +000088 ASSERT(dataLayout.bytesPerRow % format.blockByteSize == 0);
89 region.bufferRowLength = dataLayout.bytesPerRow / format.blockByteSize * format.blockWidth;
90 region.bufferImageHeight = dataLayout.rowsPerImage;
Natasha Lee5f8a8aa2019-08-14 23:11:42 +000091
92 region.imageSubresource.aspectMask = texture->GetVkAspectMask();
93 region.imageSubresource.mipLevel = textureCopy.mipLevel;
Natasha Lee5f8a8aa2019-08-14 23:11:42 +000094
Corentin Wallezff905992020-06-26 11:07:00 +000095 switch (textureCopy.texture->GetDimension()) {
96 case wgpu::TextureDimension::e2D: {
97 region.imageOffset.x = textureCopy.origin.x;
98 region.imageOffset.y = textureCopy.origin.y;
99 region.imageOffset.z = 0;
Natasha Lee5f8a8aa2019-08-14 23:11:42 +0000100
Corentin Wallezff905992020-06-26 11:07:00 +0000101 region.imageSubresource.baseArrayLayer = textureCopy.origin.z;
102 region.imageSubresource.layerCount = copySize.depth;
Jiawei Shao92379bf2020-06-21 09:33:44 +0000103
Corentin Wallezff905992020-06-26 11:07:00 +0000104 Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
105 region.imageExtent.width = imageExtent.width;
106 region.imageExtent.height = imageExtent.height;
107 region.imageExtent.depth = 1;
108 break;
109 }
110
111 default:
112 UNREACHABLE();
113 break;
114 }
Natasha Lee5f8a8aa2019-08-14 23:11:42 +0000115
116 return region;
117 }
Tomek Ponitkae28cc552020-07-16 09:08:41 +0000118}} // namespace dawn_native::vulkan