Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 1 | // Copyright 2018 The SwiftShader Authors. All Rights Reserved. |
| 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 | #ifndef VK_IMAGE_HPP_ |
| 16 | #define VK_IMAGE_HPP_ |
| 17 | |
Antonio Maiorano | 42fd159 | 2020-04-27 11:30:40 -0400 | [diff] [blame] | 18 | #include "VkFormat.hpp" |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 19 | #include "VkObject.hpp" |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 20 | |
Alexis Hetu | 4f438a5 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 21 | #include "marl/mutex.h" |
| 22 | |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 23 | #ifdef __ANDROID__ |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 24 | # include <vulkan/vk_android_native_buffer.h> // For VkSwapchainImageUsageFlagsANDROID and buffer_handle_t |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 25 | #endif |
| 26 | |
Alexis Hetu | 4f438a5 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 27 | #include <unordered_set> |
| 28 | |
Nicolas Capens | 157ba26 | 2019-12-10 17:49:14 -0500 | [diff] [blame] | 29 | namespace vk { |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 30 | |
Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 31 | class Buffer; |
Alexis Hetu | 0da99f5 | 2019-02-27 12:54:52 -0500 | [diff] [blame] | 32 | class Device; |
Alexis Hetu | 0459596 | 2018-12-14 11:07:39 -0500 | [diff] [blame] | 33 | class DeviceMemory; |
| 34 | |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 35 | #ifdef __ANDROID__ |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 36 | struct BackingMemory |
| 37 | { |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 38 | int stride = 0; |
| 39 | bool externalMemory = false; |
| 40 | buffer_handle_t nativeHandle = nullptr; |
| 41 | VkSwapchainImageUsageFlagsANDROID androidUsage = 0; |
| 42 | }; |
| 43 | #endif |
| 44 | |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 45 | class Image : public Object<Image, VkImage> |
| 46 | { |
| 47 | public: |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 48 | Image(const VkImageCreateInfo *pCreateInfo, void *mem, Device *device); |
| 49 | void destroy(const VkAllocationCallbacks *pAllocator); |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 50 | |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 51 | #ifdef __ANDROID__ |
| 52 | VkResult prepareForExternalUseANDROID() const; |
| 53 | #endif |
| 54 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 55 | static size_t ComputeRequiredAllocationSize(const VkImageCreateInfo *pCreateInfo); |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 56 | |
Alexis Hetu | a233cea | 2018-12-07 11:53:19 -0500 | [diff] [blame] | 57 | const VkMemoryRequirements getMemoryRequirements() const; |
Alexis Hetu | 0774188 | 2020-04-01 16:49:03 -0400 | [diff] [blame] | 58 | size_t getSizeInBytes(const VkImageSubresourceRange &subresourceRange) const; |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 59 | void getSubresourceLayout(const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) const; |
| 60 | void bind(DeviceMemory *pDeviceMemory, VkDeviceSize pMemoryOffset); |
| 61 | void copyTo(Image *dstImage, const VkImageCopy &pRegion) const; |
| 62 | void copyTo(Buffer *dstBuffer, const VkBufferImageCopy ®ion); |
| 63 | void copyFrom(Buffer *srcBuffer, const VkBufferImageCopy ®ion); |
Alexis Hetu | a233cea | 2018-12-07 11:53:19 -0500 | [diff] [blame] | 64 | |
Nicolas Capens | 32f4be1 | 2020-06-10 13:14:07 -0400 | [diff] [blame] | 65 | void blitTo(Image *dstImage, const VkImageBlit ®ion, VkFilter filter) const; |
| 66 | void copyTo(uint8_t *dst, unsigned int dstPitch) const; |
| 67 | void resolveTo(Image *dstImage, const VkImageResolve ®ion) const; |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 68 | void clear(const VkClearValue &clearValue, const vk::Format &viewFormat, const VkRect2D &renderArea, const VkImageSubresourceRange &subresourceRange); |
| 69 | void clear(const VkClearColorValue &color, const VkImageSubresourceRange &subresourceRange); |
| 70 | void clear(const VkClearDepthStencilValue &color, const VkImageSubresourceRange &subresourceRange); |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 71 | |
Nicolas Capens | ad65826 | 2020-07-03 10:06:27 -0400 | [diff] [blame] | 72 | // Get the last layer and mipmap level, handling VK_REMAINING_ARRAY_LAYERS and |
| 73 | // VK_REMAINING_MIP_LEVELS, respectively. Note VkImageSubresourceLayers does not |
| 74 | // allow these symbolic values, so only VkImageSubresourceRange is accepted. |
| 75 | uint32_t getLastLayerIndex(const VkImageSubresourceRange &subresourceRange) const; |
| 76 | uint32_t getLastMipLevel(const VkImageSubresourceRange &subresourceRange) const; |
| 77 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 78 | VkImageType getImageType() const { return imageType; } |
| 79 | const Format &getFormat() const { return format; } |
| 80 | Format getFormat(VkImageAspectFlagBits aspect) const; |
| 81 | uint32_t getArrayLayers() const { return arrayLayers; } |
| 82 | uint32_t getMipLevels() const { return mipLevels; } |
| 83 | VkImageUsageFlags getUsage() const { return usage; } |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 84 | VkSampleCountFlagBits getSampleCountFlagBits() const { return samples; } |
| 85 | VkExtent3D getMipLevelExtent(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; |
| 86 | int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; |
| 87 | int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; |
Alexis Hetu | 4615971 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 88 | void *getTexelPointer(const VkOffset3D &offset, const VkImageSubresource &subresource) const; |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 89 | bool isCube() const; |
| 90 | bool is3DSlice() const; |
| 91 | uint8_t *end() const; |
| 92 | VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const; |
| 93 | VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; |
| 94 | bool canBindToMemory(DeviceMemory *pDeviceMemory) const; |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 95 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 96 | void prepareForSampling(const VkImageSubresourceRange &subresourceRange); |
Alexis Hetu | 4f438a5 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 97 | enum ContentsChangedContext |
| 98 | { |
| 99 | DIRECT_MEMORY_ACCESS = 0, |
| 100 | USING_STORAGE = 1 |
| 101 | }; |
| 102 | void contentsChanged(const VkImageSubresourceRange &subresourceRange, ContentsChangedContext contentsChangedContext = DIRECT_MEMORY_ACCESS); |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 103 | const Image *getSampledImage(const vk::Format &imageViewFormat) const; |
Alexis Hetu | ac87334 | 2019-04-17 15:59:03 -0400 | [diff] [blame] | 104 | |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 105 | #ifdef __ANDROID__ |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 106 | void setBackingMemory(BackingMemory &bm) |
| 107 | { |
| 108 | backingMemory = bm; |
| 109 | } |
| 110 | bool hasExternalMemory() const { return backingMemory.externalMemory; } |
| 111 | VkDeviceMemory getExternalMemory() const; |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 112 | #endif |
| 113 | |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 114 | private: |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 115 | void copy(Buffer *buffer, const VkBufferImageCopy ®ion, bool bufferIsSource); |
Chris Forbes | 2995dc2 | 2019-03-02 14:57:20 -0800 | [diff] [blame] | 116 | VkDeviceSize getStorageSize(VkImageAspectFlags flags) const; |
Alexis Hetu | 54ec759 | 2019-03-20 14:37:16 -0400 | [diff] [blame] | 117 | VkDeviceSize getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; |
Alexis Hetu | 32ac831 | 2019-04-15 17:20:29 -0400 | [diff] [blame] | 118 | VkDeviceSize getLayerOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; |
Chris Forbes | 2995dc2 | 2019-03-02 14:57:20 -0800 | [diff] [blame] | 119 | VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; |
| 120 | VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const; |
Alexis Hetu | 4615971 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 121 | VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D &offset, const VkImageSubresource &subresource) const; |
Chris Forbes | 2995dc2 | 2019-03-02 14:57:20 -0800 | [diff] [blame] | 122 | VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect) const; |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 123 | VkExtent3D imageExtentInBlocks(const VkExtent3D &extent, VkImageAspectFlagBits aspect) const; |
| 124 | VkOffset3D imageOffsetInBlocks(const VkOffset3D &offset, VkImageAspectFlagBits aspect) const; |
| 125 | VkExtent2D bufferExtentInBlocks(const VkExtent2D &extent, const VkBufferImageCopy ®ion) const; |
Alexis Hetu | eca9ca6 | 2019-01-16 14:21:33 -0500 | [diff] [blame] | 126 | VkFormat getClearFormat() const; |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 127 | void clear(void *pixelData, VkFormat pixelFormat, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D &renderArea); |
Nicolas Capens | ba87330 | 2019-05-16 11:25:27 -0400 | [diff] [blame] | 128 | int borderSize() const; |
Alexis Hetu | 4f438a5 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 129 | bool requiresPreprocessing() const; |
Alexis Hetu | 4615971 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 130 | void decompress(const VkImageSubresource &subresource); |
Alexis Hetu | 4f438a5 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 131 | bool updateCube(const VkImageSubresource &subresource); |
Alexis Hetu | 4615971 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 132 | void decodeETC2(const VkImageSubresource &subresource); |
| 133 | void decodeBC(const VkImageSubresource &subresource); |
| 134 | void decodeASTC(const VkImageSubresource &subresource); |
Alexis Hetu | a233cea | 2018-12-07 11:53:19 -0500 | [diff] [blame] | 135 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 136 | const Device *const device = nullptr; |
| 137 | DeviceMemory *deviceMemory = nullptr; |
| 138 | VkDeviceSize memoryOffset = 0; |
| 139 | VkImageCreateFlags flags = 0; |
| 140 | VkImageType imageType = VK_IMAGE_TYPE_2D; |
| 141 | Format format; |
| 142 | VkExtent3D extent = { 0, 0, 0 }; |
| 143 | uint32_t mipLevels = 0; |
| 144 | uint32_t arrayLayers = 0; |
| 145 | VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; |
| 146 | VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; |
| 147 | VkImageUsageFlags usage = (VkImageUsageFlags)0; |
| 148 | Image *decompressedImage = nullptr; |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 149 | #ifdef __ANDROID__ |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 150 | BackingMemory backingMemory = {}; |
Alexis Hetu | 5244595 | 2019-10-31 17:51:07 -0400 | [diff] [blame] | 151 | #endif |
David 'Digit' Turner | 359bc80 | 2019-08-14 17:46:07 +0200 | [diff] [blame] | 152 | |
| 153 | VkExternalMemoryHandleTypeFlags supportedExternalMemoryHandleTypes = (VkExternalMemoryHandleTypeFlags)0; |
Alexis Hetu | 4f438a5 | 2020-06-15 16:13:51 -0400 | [diff] [blame] | 154 | |
| 155 | // VkImageSubresource wrapper for use in unordered_set |
| 156 | class Subresource |
| 157 | { |
| 158 | public: |
| 159 | Subresource() |
| 160 | : subresource{ (VkImageAspectFlags)0, 0, 0 } |
| 161 | {} |
| 162 | Subresource(const VkImageSubresource &subres) |
| 163 | : subresource(subres) |
| 164 | {} |
| 165 | inline operator VkImageSubresource() const { return subresource; } |
| 166 | |
| 167 | bool operator==(const Subresource &other) const |
| 168 | { |
| 169 | return (subresource.aspectMask == other.subresource.aspectMask) && |
| 170 | (subresource.mipLevel == other.subresource.mipLevel) && |
| 171 | (subresource.arrayLayer == other.subresource.arrayLayer); |
| 172 | }; |
| 173 | |
| 174 | size_t operator()(const Subresource &other) const |
| 175 | { |
| 176 | return static_cast<size_t>(other.subresource.aspectMask) ^ |
| 177 | static_cast<size_t>(other.subresource.mipLevel) ^ |
| 178 | static_cast<size_t>(other.subresource.arrayLayer); |
| 179 | }; |
| 180 | |
| 181 | private: |
| 182 | VkImageSubresource subresource; |
| 183 | }; |
| 184 | |
| 185 | marl::mutex mutex; |
| 186 | std::unordered_set<Subresource, Subresource> dirtySubresources GUARDED_BY(mutex); |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 187 | }; |
| 188 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 189 | static inline Image *Cast(VkImage object) |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 190 | { |
Alexis Hetu | bd4cf81 | 2019-06-14 15:14:07 -0400 | [diff] [blame] | 191 | return Image::Cast(object); |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 192 | } |
| 193 | |
Nicolas Capens | 157ba26 | 2019-12-10 17:49:14 -0500 | [diff] [blame] | 194 | } // namespace vk |
Alexis Hetu | f62f375 | 2018-11-15 14:51:15 -0500 | [diff] [blame] | 195 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 196 | #endif // VK_IMAGE_HPP_ |