1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #ifndef VK_IMAGE_HPP_
16*03ce13f7SAndroid Build Coastguard Worker #define VK_IMAGE_HPP_
17*03ce13f7SAndroid Build Coastguard Worker
18*03ce13f7SAndroid Build Coastguard Worker #include "VkFormat.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "VkObject.hpp"
20*03ce13f7SAndroid Build Coastguard Worker
21*03ce13f7SAndroid Build Coastguard Worker #include "marl/mutex.h"
22*03ce13f7SAndroid Build Coastguard Worker
23*03ce13f7SAndroid Build Coastguard Worker #ifdef __ANDROID__
24*03ce13f7SAndroid Build Coastguard Worker # include <vulkan/vk_android_native_buffer.h> // For VkSwapchainImageUsageFlagsANDROID and buffer_handle_t
25*03ce13f7SAndroid Build Coastguard Worker #endif
26*03ce13f7SAndroid Build Coastguard Worker
27*03ce13f7SAndroid Build Coastguard Worker #include <unordered_set>
28*03ce13f7SAndroid Build Coastguard Worker
29*03ce13f7SAndroid Build Coastguard Worker namespace vk {
30*03ce13f7SAndroid Build Coastguard Worker
31*03ce13f7SAndroid Build Coastguard Worker class Buffer;
32*03ce13f7SAndroid Build Coastguard Worker class Device;
33*03ce13f7SAndroid Build Coastguard Worker class DeviceMemory;
34*03ce13f7SAndroid Build Coastguard Worker class ImageView;
35*03ce13f7SAndroid Build Coastguard Worker
36*03ce13f7SAndroid Build Coastguard Worker #ifdef __ANDROID__
37*03ce13f7SAndroid Build Coastguard Worker struct BackingMemory
38*03ce13f7SAndroid Build Coastguard Worker {
39*03ce13f7SAndroid Build Coastguard Worker bool externalMemory = false;
40*03ce13f7SAndroid Build Coastguard Worker VkSwapchainImageUsageFlagsANDROID androidUsage = 0;
41*03ce13f7SAndroid Build Coastguard Worker VkNativeBufferANDROID nativeBufferInfo = {};
42*03ce13f7SAndroid Build Coastguard Worker };
43*03ce13f7SAndroid Build Coastguard Worker #endif
44*03ce13f7SAndroid Build Coastguard Worker
45*03ce13f7SAndroid Build Coastguard Worker class Image : public Object<Image, VkImage>
46*03ce13f7SAndroid Build Coastguard Worker {
47*03ce13f7SAndroid Build Coastguard Worker public:
48*03ce13f7SAndroid Build Coastguard Worker Image(const VkImageCreateInfo *pCreateInfo, void *mem, Device *device);
49*03ce13f7SAndroid Build Coastguard Worker void destroy(const VkAllocationCallbacks *pAllocator);
50*03ce13f7SAndroid Build Coastguard Worker
51*03ce13f7SAndroid Build Coastguard Worker #ifdef __ANDROID__
52*03ce13f7SAndroid Build Coastguard Worker VkResult prepareForExternalUseANDROID() const;
53*03ce13f7SAndroid Build Coastguard Worker #endif
54*03ce13f7SAndroid Build Coastguard Worker
55*03ce13f7SAndroid Build Coastguard Worker static size_t ComputeRequiredAllocationSize(const VkImageCreateInfo *pCreateInfo);
56*03ce13f7SAndroid Build Coastguard Worker
57*03ce13f7SAndroid Build Coastguard Worker const VkMemoryRequirements getMemoryRequirements() const;
58*03ce13f7SAndroid Build Coastguard Worker void getMemoryRequirements(VkMemoryRequirements2 *pMemoryRequirements) const;
59*03ce13f7SAndroid Build Coastguard Worker size_t getSizeInBytes(const VkImageSubresourceRange &subresourceRange) const;
60*03ce13f7SAndroid Build Coastguard Worker void getSubresourceLayout(const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) const;
61*03ce13f7SAndroid Build Coastguard Worker void bind(DeviceMemory *pDeviceMemory, VkDeviceSize pMemoryOffset);
62*03ce13f7SAndroid Build Coastguard Worker void copyTo(Image *dstImage, const VkImageCopy2KHR ®ion) const;
63*03ce13f7SAndroid Build Coastguard Worker void copyTo(Buffer *dstBuffer, const VkBufferImageCopy2KHR ®ion);
64*03ce13f7SAndroid Build Coastguard Worker void copyFrom(Buffer *srcBuffer, const VkBufferImageCopy2KHR ®ion);
65*03ce13f7SAndroid Build Coastguard Worker
66*03ce13f7SAndroid Build Coastguard Worker // VK_EXT_host_image_copy variants of copy
67*03ce13f7SAndroid Build Coastguard Worker void copyToMemory(const VkImageToMemoryCopyEXT ®ion);
68*03ce13f7SAndroid Build Coastguard Worker void copyFromMemory(const VkMemoryToImageCopyEXT ®ion);
69*03ce13f7SAndroid Build Coastguard Worker
70*03ce13f7SAndroid Build Coastguard Worker void blitTo(Image *dstImage, const VkImageBlit2KHR ®ion, VkFilter filter) const;
71*03ce13f7SAndroid Build Coastguard Worker void copyTo(uint8_t *dst, unsigned int dstPitch) const;
72*03ce13f7SAndroid Build Coastguard Worker void resolveTo(Image *dstImage, const VkImageResolve2KHR ®ion) const;
73*03ce13f7SAndroid Build Coastguard Worker void resolveDepthStencilTo(const ImageView *src, ImageView *dst, VkResolveModeFlagBits depthResolveMode, VkResolveModeFlagBits stencilResolveMode) const;
74*03ce13f7SAndroid Build Coastguard Worker void clear(const VkClearValue &clearValue, const vk::Format &viewFormat, const VkRect2D &renderArea, const VkImageSubresourceRange &subresourceRange);
75*03ce13f7SAndroid Build Coastguard Worker void clear(const VkClearColorValue &color, const VkImageSubresourceRange &subresourceRange);
76*03ce13f7SAndroid Build Coastguard Worker void clear(const VkClearDepthStencilValue &color, const VkImageSubresourceRange &subresourceRange);
77*03ce13f7SAndroid Build Coastguard Worker
78*03ce13f7SAndroid Build Coastguard Worker // Get the last layer and mipmap level, handling VK_REMAINING_ARRAY_LAYERS and
79*03ce13f7SAndroid Build Coastguard Worker // VK_REMAINING_MIP_LEVELS, respectively. Note VkImageSubresourceLayers does not
80*03ce13f7SAndroid Build Coastguard Worker // allow these symbolic values, so only VkImageSubresourceRange is accepted.
81*03ce13f7SAndroid Build Coastguard Worker uint32_t getLastLayerIndex(const VkImageSubresourceRange &subresourceRange) const;
82*03ce13f7SAndroid Build Coastguard Worker uint32_t getLastMipLevel(const VkImageSubresourceRange &subresourceRange) const;
83*03ce13f7SAndroid Build Coastguard Worker
getImageType() const84*03ce13f7SAndroid Build Coastguard Worker VkImageType getImageType() const { return imageType; }
getFormat() const85*03ce13f7SAndroid Build Coastguard Worker const Format &getFormat() const { return format; }
86*03ce13f7SAndroid Build Coastguard Worker Format getFormat(VkImageAspectFlagBits aspect) const;
getArrayLayers() const87*03ce13f7SAndroid Build Coastguard Worker uint32_t getArrayLayers() const { return arrayLayers; }
getMipLevels() const88*03ce13f7SAndroid Build Coastguard Worker uint32_t getMipLevels() const { return mipLevels; }
getUsage() const89*03ce13f7SAndroid Build Coastguard Worker VkImageUsageFlags getUsage() const { return usage; }
getFlags() const90*03ce13f7SAndroid Build Coastguard Worker VkImageCreateFlags getFlags() const { return flags; }
getSampleCount() const91*03ce13f7SAndroid Build Coastguard Worker VkSampleCountFlagBits getSampleCount() const { return samples; }
getExtent() const92*03ce13f7SAndroid Build Coastguard Worker const VkExtent3D &getExtent() const { return extent; }
93*03ce13f7SAndroid Build Coastguard Worker VkExtent3D getMipLevelExtent(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
94*03ce13f7SAndroid Build Coastguard Worker size_t rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
95*03ce13f7SAndroid Build Coastguard Worker size_t slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
96*03ce13f7SAndroid Build Coastguard Worker void *getTexelPointer(const VkOffset3D &offset, const VkImageSubresource &subresource) const;
97*03ce13f7SAndroid Build Coastguard Worker bool isCubeCompatible() const;
98*03ce13f7SAndroid Build Coastguard Worker bool is3DSlice() const;
99*03ce13f7SAndroid Build Coastguard Worker uint8_t *end() const;
100*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const;
101*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
102*03ce13f7SAndroid Build Coastguard Worker bool canBindToMemory(DeviceMemory *pDeviceMemory) const;
103*03ce13f7SAndroid Build Coastguard Worker
104*03ce13f7SAndroid Build Coastguard Worker void prepareForSampling(const VkImageSubresourceRange &subresourceRange) const;
105*03ce13f7SAndroid Build Coastguard Worker enum ContentsChangedContext
106*03ce13f7SAndroid Build Coastguard Worker {
107*03ce13f7SAndroid Build Coastguard Worker DIRECT_MEMORY_ACCESS = 0,
108*03ce13f7SAndroid Build Coastguard Worker USING_STORAGE = 1
109*03ce13f7SAndroid Build Coastguard Worker };
110*03ce13f7SAndroid Build Coastguard Worker void contentsChanged(const VkImageSubresourceRange &subresourceRange, ContentsChangedContext contentsChangedContext = DIRECT_MEMORY_ACCESS);
111*03ce13f7SAndroid Build Coastguard Worker const Image *getSampledImage(const vk::Format &imageViewFormat) const;
112*03ce13f7SAndroid Build Coastguard Worker
113*03ce13f7SAndroid Build Coastguard Worker #ifdef __ANDROID__
setBackingMemory(BackingMemory & bm)114*03ce13f7SAndroid Build Coastguard Worker void setBackingMemory(BackingMemory &bm)
115*03ce13f7SAndroid Build Coastguard Worker {
116*03ce13f7SAndroid Build Coastguard Worker backingMemory = bm;
117*03ce13f7SAndroid Build Coastguard Worker }
hasExternalMemory() const118*03ce13f7SAndroid Build Coastguard Worker bool hasExternalMemory() const { return backingMemory.externalMemory; }
119*03ce13f7SAndroid Build Coastguard Worker VkDeviceMemory getExternalMemory() const;
getSupportedExternalMemoryHandleTypes() const120*03ce13f7SAndroid Build Coastguard Worker VkExternalMemoryHandleTypeFlags getSupportedExternalMemoryHandleTypes() const { return supportedExternalMemoryHandleTypes; }
121*03ce13f7SAndroid Build Coastguard Worker #endif
122*03ce13f7SAndroid Build Coastguard Worker
123*03ce13f7SAndroid Build Coastguard Worker DeviceMemory *deviceMemory = nullptr;
124*03ce13f7SAndroid Build Coastguard Worker
125*03ce13f7SAndroid Build Coastguard Worker private:
126*03ce13f7SAndroid Build Coastguard Worker void copy(const void *srcCopyMemory,
127*03ce13f7SAndroid Build Coastguard Worker void *dstCopyMemory,
128*03ce13f7SAndroid Build Coastguard Worker uint32_t rowLength,
129*03ce13f7SAndroid Build Coastguard Worker uint32_t imageHeight,
130*03ce13f7SAndroid Build Coastguard Worker const VkImageSubresourceLayers &imageSubresource,
131*03ce13f7SAndroid Build Coastguard Worker const VkOffset3D &imageCopyOffset,
132*03ce13f7SAndroid Build Coastguard Worker const VkExtent3D &imageCopyExtent);
133*03ce13f7SAndroid Build Coastguard Worker void copySingleAspectTo(Image *dstImage, const VkImageCopy2KHR ®ion) const;
134*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getStorageSize(VkImageAspectFlags flags) const;
135*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
136*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getLayerOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
137*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect) const;
138*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getAspectOffset(VkImageAspectFlagBits aspect) const;
139*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize getSubresourceOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const;
140*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D &offset, const VkImageSubresource &subresource) const;
141*03ce13f7SAndroid Build Coastguard Worker VkExtent3D imageExtentInBlocks(const VkExtent3D &extent, VkImageAspectFlagBits aspect) const;
142*03ce13f7SAndroid Build Coastguard Worker VkOffset3D imageOffsetInBlocks(const VkOffset3D &offset, VkImageAspectFlagBits aspect) const;
143*03ce13f7SAndroid Build Coastguard Worker VkExtent2D bufferExtentInBlocks(const VkExtent2D &extent, uint32_t rowLength, uint32_t imageHeight, const VkImageSubresourceLayers &imageSubresource, const VkOffset3D &imageOffset) const;
144*03ce13f7SAndroid Build Coastguard Worker void clear(const void *pixelData, VkFormat pixelFormat, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea);
145*03ce13f7SAndroid Build Coastguard Worker int borderSize() const;
146*03ce13f7SAndroid Build Coastguard Worker
147*03ce13f7SAndroid Build Coastguard Worker bool requiresPreprocessing() const;
148*03ce13f7SAndroid Build Coastguard Worker void decompress(const VkImageSubresource &subresource) const;
149*03ce13f7SAndroid Build Coastguard Worker void decodeETC2(const VkImageSubresource &subresource) const;
150*03ce13f7SAndroid Build Coastguard Worker void decodeBC(const VkImageSubresource &subresource) const;
151*03ce13f7SAndroid Build Coastguard Worker void decodeASTC(const VkImageSubresource &subresource) const;
152*03ce13f7SAndroid Build Coastguard Worker
153*03ce13f7SAndroid Build Coastguard Worker const Device *const device = nullptr;
154*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize memoryOffset = 0;
155*03ce13f7SAndroid Build Coastguard Worker VkImageCreateFlags flags = 0;
156*03ce13f7SAndroid Build Coastguard Worker VkImageType imageType = VK_IMAGE_TYPE_2D;
157*03ce13f7SAndroid Build Coastguard Worker Format format;
158*03ce13f7SAndroid Build Coastguard Worker VkExtent3D extent = { 0, 0, 0 };
159*03ce13f7SAndroid Build Coastguard Worker uint32_t mipLevels = 0;
160*03ce13f7SAndroid Build Coastguard Worker uint32_t arrayLayers = 0;
161*03ce13f7SAndroid Build Coastguard Worker VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
162*03ce13f7SAndroid Build Coastguard Worker VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
163*03ce13f7SAndroid Build Coastguard Worker VkImageUsageFlags usage = (VkImageUsageFlags)0;
164*03ce13f7SAndroid Build Coastguard Worker Image *decompressedImage = nullptr;
165*03ce13f7SAndroid Build Coastguard Worker #ifdef __ANDROID__
166*03ce13f7SAndroid Build Coastguard Worker BackingMemory backingMemory = {};
167*03ce13f7SAndroid Build Coastguard Worker #endif
168*03ce13f7SAndroid Build Coastguard Worker
169*03ce13f7SAndroid Build Coastguard Worker VkExternalMemoryHandleTypeFlags supportedExternalMemoryHandleTypes = (VkExternalMemoryHandleTypeFlags)0;
170*03ce13f7SAndroid Build Coastguard Worker
171*03ce13f7SAndroid Build Coastguard Worker // VkImageSubresource wrapper for use in unordered_set
172*03ce13f7SAndroid Build Coastguard Worker class Subresource
173*03ce13f7SAndroid Build Coastguard Worker {
174*03ce13f7SAndroid Build Coastguard Worker public:
Subresource()175*03ce13f7SAndroid Build Coastguard Worker Subresource()
176*03ce13f7SAndroid Build Coastguard Worker : subresource{ (VkImageAspectFlags)0, 0, 0 }
177*03ce13f7SAndroid Build Coastguard Worker {}
Subresource(const VkImageSubresource & subres)178*03ce13f7SAndroid Build Coastguard Worker Subresource(const VkImageSubresource &subres)
179*03ce13f7SAndroid Build Coastguard Worker : subresource(subres)
180*03ce13f7SAndroid Build Coastguard Worker {}
operator VkImageSubresource() const181*03ce13f7SAndroid Build Coastguard Worker inline operator VkImageSubresource() const { return subresource; }
182*03ce13f7SAndroid Build Coastguard Worker
operator ==(const Subresource & other) const183*03ce13f7SAndroid Build Coastguard Worker bool operator==(const Subresource &other) const
184*03ce13f7SAndroid Build Coastguard Worker {
185*03ce13f7SAndroid Build Coastguard Worker return (subresource.aspectMask == other.subresource.aspectMask) &&
186*03ce13f7SAndroid Build Coastguard Worker (subresource.mipLevel == other.subresource.mipLevel) &&
187*03ce13f7SAndroid Build Coastguard Worker (subresource.arrayLayer == other.subresource.arrayLayer);
188*03ce13f7SAndroid Build Coastguard Worker };
189*03ce13f7SAndroid Build Coastguard Worker
operator ()(const Subresource & other) const190*03ce13f7SAndroid Build Coastguard Worker size_t operator()(const Subresource &other) const
191*03ce13f7SAndroid Build Coastguard Worker {
192*03ce13f7SAndroid Build Coastguard Worker return static_cast<size_t>(other.subresource.aspectMask) ^
193*03ce13f7SAndroid Build Coastguard Worker static_cast<size_t>(other.subresource.mipLevel) ^
194*03ce13f7SAndroid Build Coastguard Worker static_cast<size_t>(other.subresource.arrayLayer);
195*03ce13f7SAndroid Build Coastguard Worker };
196*03ce13f7SAndroid Build Coastguard Worker
197*03ce13f7SAndroid Build Coastguard Worker private:
198*03ce13f7SAndroid Build Coastguard Worker VkImageSubresource subresource;
199*03ce13f7SAndroid Build Coastguard Worker };
200*03ce13f7SAndroid Build Coastguard Worker
201*03ce13f7SAndroid Build Coastguard Worker mutable marl::mutex mutex;
202*03ce13f7SAndroid Build Coastguard Worker mutable std::unordered_set<Subresource, Subresource> dirtySubresources GUARDED_BY(mutex);
203*03ce13f7SAndroid Build Coastguard Worker };
204*03ce13f7SAndroid Build Coastguard Worker
Cast(VkImage object)205*03ce13f7SAndroid Build Coastguard Worker static inline Image *Cast(VkImage object)
206*03ce13f7SAndroid Build Coastguard Worker {
207*03ce13f7SAndroid Build Coastguard Worker return Image::Cast(object);
208*03ce13f7SAndroid Build Coastguard Worker }
209*03ce13f7SAndroid Build Coastguard Worker
210*03ce13f7SAndroid Build Coastguard Worker } // namespace vk
211*03ce13f7SAndroid Build Coastguard Worker
operator ==(const VkExtent3D & lhs,const VkExtent3D & rhs)212*03ce13f7SAndroid Build Coastguard Worker inline bool operator==(const VkExtent3D &lhs, const VkExtent3D &rhs)
213*03ce13f7SAndroid Build Coastguard Worker {
214*03ce13f7SAndroid Build Coastguard Worker return lhs.width == rhs.width &&
215*03ce13f7SAndroid Build Coastguard Worker lhs.height == rhs.height &&
216*03ce13f7SAndroid Build Coastguard Worker lhs.depth == rhs.depth;
217*03ce13f7SAndroid Build Coastguard Worker }
218*03ce13f7SAndroid Build Coastguard Worker
operator !=(const VkExtent3D & lhs,const VkExtent3D & rhs)219*03ce13f7SAndroid Build Coastguard Worker inline bool operator!=(const VkExtent3D &lhs, const VkExtent3D &rhs)
220*03ce13f7SAndroid Build Coastguard Worker {
221*03ce13f7SAndroid Build Coastguard Worker return !(lhs == rhs);
222*03ce13f7SAndroid Build Coastguard Worker }
223*03ce13f7SAndroid Build Coastguard Worker
operator ==(const VkOffset3D & lhs,const VkOffset3D & rhs)224*03ce13f7SAndroid Build Coastguard Worker inline bool operator==(const VkOffset3D &lhs, const VkOffset3D &rhs)
225*03ce13f7SAndroid Build Coastguard Worker {
226*03ce13f7SAndroid Build Coastguard Worker return lhs.x == rhs.x &&
227*03ce13f7SAndroid Build Coastguard Worker lhs.y == rhs.y &&
228*03ce13f7SAndroid Build Coastguard Worker lhs.z == rhs.z;
229*03ce13f7SAndroid Build Coastguard Worker }
230*03ce13f7SAndroid Build Coastguard Worker
operator !=(const VkOffset3D & lhs,const VkOffset3D & rhs)231*03ce13f7SAndroid Build Coastguard Worker inline bool operator!=(const VkOffset3D &lhs, const VkOffset3D &rhs)
232*03ce13f7SAndroid Build Coastguard Worker {
233*03ce13f7SAndroid Build Coastguard Worker return !(lhs == rhs);
234*03ce13f7SAndroid Build Coastguard Worker }
235*03ce13f7SAndroid Build Coastguard Worker
236*03ce13f7SAndroid Build Coastguard Worker #endif // VK_IMAGE_HPP_
237