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 { |
29 | GrVkAlloc() |
30 | : fMemory(VK_NULL_HANDLE) |
31 | , fOffset(0) |
32 | , fSize(0) |
33 | , fFlags(0) |
34 | , fBackendMemory(0) |
35 | , fUsesSystemHeap(false) {} |
36 | |
37 | 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 { |
69 | 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 | |
79 | GrVkYcbcrConversionInfo(VkFormat format, |
80 | uint64_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 | |
102 | 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 | |
130 | 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 | /* |
153 | * When wrapping a GrBackendTexture or GrBackendRendenderTarget, the fCurrentQueueFamily should |
154 | * either be VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL, or VK_QUEUE_FAMILY_FOREIGN_EXT. If |
155 | * fSharingMode is VK_SHARING_MODE_EXCLUSIVE then fCurrentQueueFamily can also be the graphics |
156 | * queue index passed into Skia. |
157 | */ |
158 | struct GrVkImageInfo { |
159 | VkImage fImage; |
160 | GrVkAlloc fAlloc; |
161 | VkImageTiling fImageTiling; |
162 | VkImageLayout fImageLayout; |
163 | VkFormat fFormat; |
164 | uint32_t fLevelCount; |
165 | uint32_t fCurrentQueueFamily; |
166 | GrProtected fProtected; |
167 | GrVkYcbcrConversionInfo fYcbcrConversionInfo; |
168 | VkSharingMode fSharingMode; |
169 | |
170 | GrVkImageInfo() |
171 | : fImage(VK_NULL_HANDLE) |
172 | , fAlloc() |
173 | , fImageTiling(VK_IMAGE_TILING_OPTIMAL) |
174 | , fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED) |
175 | , fFormat(VK_FORMAT_UNDEFINED) |
176 | , fLevelCount(0) |
177 | , fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED) |
178 | , fProtected(GrProtected::kNo) |
179 | , fYcbcrConversionInfo() |
180 | , fSharingMode(VK_SHARING_MODE_EXCLUSIVE) {} |
181 | |
182 | GrVkImageInfo(VkImage image, |
183 | GrVkAlloc alloc, |
184 | VkImageTiling imageTiling, |
185 | VkImageLayout layout, |
186 | VkFormat format, |
187 | uint32_t levelCount, |
188 | uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED, |
189 | GrProtected isProtected = GrProtected::kNo, |
190 | GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo(), |
191 | VkSharingMode sharingMode = VK_SHARING_MODE_EXCLUSIVE) |
192 | : fImage(image) |
193 | , fAlloc(alloc) |
194 | , fImageTiling(imageTiling) |
195 | , fImageLayout(layout) |
196 | , fFormat(format) |
197 | , fLevelCount(levelCount) |
198 | , fCurrentQueueFamily(currentQueueFamily) |
199 | , fProtected(isProtected) |
200 | , fYcbcrConversionInfo(ycbcrConversionInfo) |
201 | , fSharingMode(sharingMode) {} |
202 | |
203 | GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout, uint32_t familyQueueIndex) |
204 | : fImage(info.fImage) |
205 | , fAlloc(info.fAlloc) |
206 | , fImageTiling(info.fImageTiling) |
207 | , fImageLayout(layout) |
208 | , fFormat(info.fFormat) |
209 | , fLevelCount(info.fLevelCount) |
210 | , fCurrentQueueFamily(familyQueueIndex) |
211 | , fProtected(info.fProtected) |
212 | , fYcbcrConversionInfo(info.fYcbcrConversionInfo) |
213 | , fSharingMode(info.fSharingMode) {} |
214 | |
215 | #if GR_TEST_UTILS |
216 | bool operator==(const GrVkImageInfo& that) const { |
217 | return fImage == that.fImage && fAlloc == that.fAlloc && |
218 | fImageTiling == that.fImageTiling && fImageLayout == that.fImageLayout && |
219 | fFormat == that.fFormat && fLevelCount == that.fLevelCount && |
220 | fCurrentQueueFamily == that.fCurrentQueueFamily && fProtected == that.fProtected && |
221 | fYcbcrConversionInfo == that.fYcbcrConversionInfo && |
222 | fSharingMode == that.fSharingMode; |
223 | } |
224 | #endif |
225 | }; |
226 | |
227 | using GrVkGetProc = std::function<PFN_vkVoidFunction( |
228 | const char*, // function name |
229 | VkInstance, // instance or VK_NULL_HANDLE |
230 | VkDevice // device or VK_NULL_HANDLE |
231 | )>; |
232 | |
233 | /** |
234 | * This object is wrapped in a GrBackendDrawableInfo and passed in as an argument to |
235 | * drawBackendGpu() calls on an SkDrawable. The drawable will use this info to inject direct |
236 | * Vulkan calls into our stream of GPU draws. |
237 | * |
238 | * The SkDrawable is given a secondary VkCommandBuffer in which to record draws. The GPU backend |
239 | * will then execute that command buffer within a render pass it is using for its own draws. The |
240 | * drawable is also given the attachment of the color index, a compatible VkRenderPass, and the |
241 | * VkFormat of the color attachment so that it can make VkPipeline objects for the draws. The |
242 | * SkDrawable must not alter the state of the VkRenderpass or sub pass. |
243 | * |
244 | * Additionally, the SkDrawable may fill in the passed in fDrawBounds with the bounds of the draws |
245 | * that it submits to the command buffer. This will be used by the GPU backend for setting the |
246 | * bounds in vkCmdBeginRenderPass. If fDrawBounds is not updated, we will assume that the entire |
247 | * attachment may have been written to. |
248 | * |
249 | * The SkDrawable is always allowed to create its own command buffers and submit them to the queue |
250 | * to render offscreen textures which will be sampled in draws added to the passed in |
251 | * VkCommandBuffer. If this is done the SkDrawable is in charge of adding the required memory |
252 | * barriers to the queue for the sampled images since the Skia backend will not do this. |
253 | * |
254 | * The VkImage is informational only and should not be used or modified in any ways. |
255 | */ |
256 | struct GrVkDrawableInfo { |
257 | VkCommandBuffer fSecondaryCommandBuffer; |
258 | uint32_t fColorAttachmentIndex; |
259 | VkRenderPass fCompatibleRenderPass; |
260 | VkFormat fFormat; |
261 | VkRect2D* fDrawBounds; |
262 | VkImage fImage; |
263 | }; |
264 | |
265 | #endif |
266 | |