1 
2 /*
3  * Copyright 2016 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #ifndef GrVkTypes_DEFINED
10 #define GrVkTypes_DEFINED
11 
12 #include "include/core/SkTypes.h"
13 #include "include/gpu/vk/GrVkVulkan.h"
14 
15 #ifndef VK_VERSION_1_1
16 #error Skia requires the use of Vulkan 1.1 headers
17 #endif
18 
19 #include <functional>
20 #include "include/gpu/GrTypes.h"
21 
22 typedef intptr_t GrVkBackendMemory;
23 
24 /**
25  * Types for interacting with Vulkan resources created externally to Skia. GrBackendObjects for
26  * Vulkan textures are really const GrVkImageInfo*
27  */
28 struct GrVkAlloc {
GrVkAllocGrVkAlloc29     GrVkAlloc()
30             : fMemory(VK_NULL_HANDLE)
31             , fOffset(0)
32             , fSize(0)
33             , fFlags(0)
34             , fBackendMemory(0)
35             , fUsesSystemHeap(false) {}
36 
GrVkAllocGrVkAlloc37     GrVkAlloc(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, uint32_t flags)
38             : fMemory(memory)
39             , fOffset(offset)
40             , fSize(size)
41             , fFlags(flags)
42             , fBackendMemory(0)
43             , fUsesSystemHeap(false) {}
44 
45     VkDeviceMemory    fMemory;  // can be VK_NULL_HANDLE iff is an RT and is borrowed
46     VkDeviceSize      fOffset;
47     VkDeviceSize      fSize;    // this can be indeterminate iff Tex uses borrow semantics
48     uint32_t          fFlags;
49     GrVkBackendMemory fBackendMemory; // handle to memory allocated via GrVkMemoryAllocator.
50 
51     enum Flag {
52         kNoncoherent_Flag = 0x1,   // memory must be flushed to device after mapping
53         kMappable_Flag    = 0x2,   // memory is able to be mapped.
54     };
55 
56     bool operator==(const GrVkAlloc& that) const {
57         return fMemory == that.fMemory && fOffset == that.fOffset && fSize == that.fSize &&
58                fFlags == that.fFlags && fUsesSystemHeap == that.fUsesSystemHeap;
59     }
60 
61 private:
62     friend class GrVkHeap; // For access to usesSystemHeap
63     bool fUsesSystemHeap;
64 };
65 
66 // This struct is used to pass in the necessary information to create a VkSamplerYcbcrConversion
67 // object for an VkExternalFormatANDROID.
68 struct GrVkYcbcrConversionInfo {
GrVkYcbcrConversionInfoGrVkYcbcrConversionInfo69     GrVkYcbcrConversionInfo()
70             : fFormat(VK_FORMAT_UNDEFINED)
71             , fExternalFormat(0)
72             , fYcbcrModel(VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
73             , fYcbcrRange(VK_SAMPLER_YCBCR_RANGE_ITU_FULL)
74             , fXChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN)
75             , fYChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN)
76             , fChromaFilter(VK_FILTER_NEAREST)
77             , fForceExplicitReconstruction(false) {}
78 
GrVkYcbcrConversionInfoGrVkYcbcrConversionInfo79     GrVkYcbcrConversionInfo(VkFormat format,
80                             int64_t externalFormat,
81                             VkSamplerYcbcrModelConversion ycbcrModel,
82                             VkSamplerYcbcrRange ycbcrRange,
83                             VkChromaLocation xChromaOffset,
84                             VkChromaLocation yChromaOffset,
85                             VkFilter chromaFilter,
86                             VkBool32 forceExplicitReconstruction,
87                             VkFormatFeatureFlags formatFeatures)
88             : fFormat(format)
89             , fExternalFormat(externalFormat)
90             , fYcbcrModel(ycbcrModel)
91             , fYcbcrRange(ycbcrRange)
92             , fXChromaOffset(xChromaOffset)
93             , fYChromaOffset(yChromaOffset)
94             , fChromaFilter(chromaFilter)
95             , fForceExplicitReconstruction(forceExplicitReconstruction)
96             , fFormatFeatures(formatFeatures) {
97         SkASSERT(fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY);
98         // Either format or externalFormat must be specified.
99         SkASSERT((fFormat != VK_FORMAT_UNDEFINED) ^ (externalFormat != 0));
100     }
101 
GrVkYcbcrConversionInfoGrVkYcbcrConversionInfo102     GrVkYcbcrConversionInfo(VkSamplerYcbcrModelConversion ycbcrModel,
103                             VkSamplerYcbcrRange ycbcrRange,
104                             VkChromaLocation xChromaOffset,
105                             VkChromaLocation yChromaOffset,
106                             VkFilter chromaFilter,
107                             VkBool32 forceExplicitReconstruction,
108                             uint64_t externalFormat,
109                             VkFormatFeatureFlags externalFormatFeatures)
110             : GrVkYcbcrConversionInfo(VK_FORMAT_UNDEFINED, externalFormat, ycbcrModel, ycbcrRange,
111                                       xChromaOffset, yChromaOffset, chromaFilter,
112                                       forceExplicitReconstruction, externalFormatFeatures) {}
113 
114     bool operator==(const GrVkYcbcrConversionInfo& that) const {
115         // Invalid objects are not required to have all other fields initialized or matching.
116         if (!this->isValid() && !that.isValid()) {
117             return true;
118         }
119         return this->fFormat == that.fFormat &&
120                this->fExternalFormat == that.fExternalFormat &&
121                this->fYcbcrModel == that.fYcbcrModel &&
122                this->fYcbcrRange == that.fYcbcrRange &&
123                this->fXChromaOffset == that.fXChromaOffset &&
124                this->fYChromaOffset == that.fYChromaOffset &&
125                this->fChromaFilter == that.fChromaFilter &&
126                this->fForceExplicitReconstruction == that.fForceExplicitReconstruction;
127     }
128     bool operator!=(const GrVkYcbcrConversionInfo& that) const { return !(*this == that); }
129 
isValidGrVkYcbcrConversionInfo130     bool isValid() const { return fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; }
131 
132     // Format of the source image. Must be set to VK_FORMAT_UNDEFINED for external images or
133     // a valid image format otherwise.
134     VkFormat                         fFormat;
135 
136     // The external format. Must be non-zero for external images, zero otherwise.
137     // Should be compatible to be used in a VkExternalFormatANDROID struct.
138     uint64_t                         fExternalFormat;
139 
140     VkSamplerYcbcrModelConversion    fYcbcrModel;
141     VkSamplerYcbcrRange              fYcbcrRange;
142     VkChromaLocation                 fXChromaOffset;
143     VkChromaLocation                 fYChromaOffset;
144     VkFilter                         fChromaFilter;
145     VkBool32                         fForceExplicitReconstruction;
146 
147     // For external images format features here should be those returned by a call to
148     // vkAndroidHardwareBufferFormatPropertiesANDROID
149     VkFormatFeatureFlags             fFormatFeatures;
150 };
151 
152 struct GrVkImageInfo {
153     VkImage                  fImage;
154     GrVkAlloc                fAlloc;
155     VkImageTiling            fImageTiling;
156     VkImageLayout            fImageLayout;
157     VkFormat                 fFormat;
158     uint32_t                 fLevelCount;
159     uint32_t                 fCurrentQueueFamily;
160     GrProtected              fProtected;
161     GrVkYcbcrConversionInfo  fYcbcrConversionInfo;
162 
GrVkImageInfoGrVkImageInfo163     GrVkImageInfo()
164             : fImage(VK_NULL_HANDLE)
165             , fAlloc()
166             , fImageTiling(VK_IMAGE_TILING_OPTIMAL)
167             , fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED)
168             , fFormat(VK_FORMAT_UNDEFINED)
169             , fLevelCount(0)
170             , fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED)
171             , fProtected(GrProtected::kNo)
172             , fYcbcrConversionInfo() {}
173 
174     GrVkImageInfo(VkImage image,
175                   GrVkAlloc alloc,
176                   VkImageTiling imageTiling,
177                   VkImageLayout layout,
178                   VkFormat format,
179                   uint32_t levelCount,
180                   uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED,
181                   GrProtected isProtected = GrProtected::kNo,
182                   GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo())
fImageGrVkImageInfo183             : fImage(image)
184             , fAlloc(alloc)
185             , fImageTiling(imageTiling)
186             , fImageLayout(layout)
187             , fFormat(format)
188             , fLevelCount(levelCount)
189             , fCurrentQueueFamily(currentQueueFamily)
190             , fProtected(isProtected)
191             , fYcbcrConversionInfo(ycbcrConversionInfo) {}
192 
GrVkImageInfoGrVkImageInfo193     GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout)
194             : fImage(info.fImage)
195             , fAlloc(info.fAlloc)
196             , fImageTiling(info.fImageTiling)
197             , fImageLayout(layout)
198             , fFormat(info.fFormat)
199             , fLevelCount(info.fLevelCount)
200             , fCurrentQueueFamily(info.fCurrentQueueFamily)
201             , fProtected(info.fProtected)
202             , fYcbcrConversionInfo(info.fYcbcrConversionInfo) {}
203 
204     // This gives a way for a client to update the layout of the Image if they change the layout
205     // while we're still holding onto the wrapped texture. They will first need to get a handle
206     // to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture.
updateImageLayoutGrVkImageInfo207     void updateImageLayout(VkImageLayout layout) { fImageLayout = layout; }
208 
209     bool operator==(const GrVkImageInfo& that) const {
210         return fImage == that.fImage && fAlloc == that.fAlloc &&
211                fImageTiling == that.fImageTiling && fImageLayout == that.fImageLayout &&
212                fFormat == that.fFormat && fLevelCount == that.fLevelCount &&
213                fCurrentQueueFamily == that.fCurrentQueueFamily && fProtected == that.fProtected &&
214                fYcbcrConversionInfo == that.fYcbcrConversionInfo;
215     }
216 };
217 
218 using GrVkGetProc = std::function<PFN_vkVoidFunction(
219         const char*, // function name
220         VkInstance,  // instance or VK_NULL_HANDLE
221         VkDevice     // device or VK_NULL_HANDLE
222         )>;
223 
224 /**
225  * This object is wrapped in a GrBackendDrawableInfo and passed in as an argument to
226  * drawBackendGpu() calls on an SkDrawable. The drawable will use this info to inject direct
227  * Vulkan calls into our stream of GPU draws.
228  *
229  * The SkDrawable is given a secondary VkCommandBuffer in which to record draws. The GPU backend
230  * will then execute that command buffer within a render pass it is using for its own draws. The
231  * drawable is also given the attachment of the color index, a compatible VkRenderPass, and the
232  * VkFormat of the color attachment so that it can make VkPipeline objects for the draws. The
233  * SkDrawable must not alter the state of the VkRenderpass or sub pass.
234  *
235  * Additionally, the SkDrawable may fill in the passed in fDrawBounds with the bounds of the draws
236  * that it submits to the command buffer. This will be used by the GPU backend for setting the
237  * bounds in vkCmdBeginRenderPass. If fDrawBounds is not updated, we will assume that the entire
238  * attachment may have been written to.
239  *
240  * The SkDrawable is always allowed to create its own command buffers and submit them to the queue
241  * to render offscreen textures which will be sampled in draws added to the passed in
242  * VkCommandBuffer. If this is done the SkDrawable is in charge of adding the required memory
243  * barriers to the queue for the sampled images since the Skia backend will not do this.
244  *
245  * The VkImage is informational only and should not be used or modified in any ways.
246  */
247 struct GrVkDrawableInfo {
248     VkCommandBuffer fSecondaryCommandBuffer;
249     uint32_t        fColorAttachmentIndex;
250     VkRenderPass    fCompatibleRenderPass;
251     VkFormat        fFormat;
252     VkRect2D*       fDrawBounds;
253     VkImage         fImage;
254 };
255 
256 #endif
257