1 // 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"
18 #include "dawn_native/Format.h"
19 #include "dawn_native/vulkan/Forward.h"
20 #include "dawn_native/vulkan/TextureVk.h"
21 
22 namespace dawn_native { namespace vulkan {
23 
ToVulkanCompareOp(wgpu::CompareFunction op)24     VkCompareOp ToVulkanCompareOp(wgpu::CompareFunction op) {
25         switch (op) {
26             case wgpu::CompareFunction::Always:
27                 return VK_COMPARE_OP_ALWAYS;
28             case wgpu::CompareFunction::Equal:
29                 return VK_COMPARE_OP_EQUAL;
30             case wgpu::CompareFunction::Greater:
31                 return VK_COMPARE_OP_GREATER;
32             case wgpu::CompareFunction::GreaterEqual:
33                 return VK_COMPARE_OP_GREATER_OR_EQUAL;
34             case wgpu::CompareFunction::Less:
35                 return VK_COMPARE_OP_LESS;
36             case wgpu::CompareFunction::LessEqual:
37                 return VK_COMPARE_OP_LESS_OR_EQUAL;
38             case wgpu::CompareFunction::Never:
39                 return VK_COMPARE_OP_NEVER;
40             case wgpu::CompareFunction::NotEqual:
41                 return VK_COMPARE_OP_NOT_EQUAL;
42             default:
43                 UNREACHABLE();
44         }
45     }
46 
47     // 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.
ComputeTextureCopyExtent(const TextureCopy & textureCopy,const Extent3D & copySize)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 
ComputeBufferImageCopyRegion(const BufferCopy & bufferCopy,const TextureCopy & textureCopy,const Extent3D & copySize)68     VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy,
69                                                    const TextureCopy& textureCopy,
70                                                    const Extent3D& copySize) {
71         const Texture* texture = ToBackend(textureCopy.texture.Get());
72 
73         VkBufferImageCopy region;
74 
75         region.bufferOffset = bufferCopy.offset;
76         // In Vulkan the row length is in texels while it is in bytes for Dawn
77         const Format& format = texture->GetFormat();
78         ASSERT(bufferCopy.rowPitch % format.blockByteSize == 0);
79         region.bufferRowLength = bufferCopy.rowPitch / format.blockByteSize * format.blockWidth;
80         region.bufferImageHeight = bufferCopy.imageHeight;
81 
82         region.imageSubresource.aspectMask = texture->GetVkAspectMask();
83         region.imageSubresource.mipLevel = textureCopy.mipLevel;
84         region.imageSubresource.baseArrayLayer = textureCopy.arrayLayer;
85         region.imageSubresource.layerCount = 1;
86 
87         region.imageOffset.x = textureCopy.origin.x;
88         region.imageOffset.y = textureCopy.origin.y;
89         region.imageOffset.z = textureCopy.origin.z;
90 
91         Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
92         region.imageExtent.width = imageExtent.width;
93         region.imageExtent.height = imageExtent.height;
94         region.imageExtent.depth = copySize.depth;
95 
96         return region;
97     }
98 }}  // namespace dawn_native::vulkan
99