1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrVkCaps_DEFINED
9 #define GrVkCaps_DEFINED
10 
11 #include "include/gpu/vk/GrVkTypes.h"
12 #include "src/gpu/GrCaps.h"
13 #include "src/gpu/vk/GrVkStencilAttachment.h"
14 
15 class GrShaderCaps;
16 class GrVkExtensions;
17 struct GrVkInterface;
18 
19 /**
20  * Stores some capabilities of a Vk backend.
21  */
22 class GrVkCaps : public GrCaps {
23 public:
24     typedef GrVkStencilAttachment::Format StencilFormat;
25 
26     /**
27      * Creates a GrVkCaps that is set such that nothing is supported. The init function should
28      * be called to fill out the caps.
29      */
30     GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
31              VkPhysicalDevice device, const VkPhysicalDeviceFeatures2& features,
32              uint32_t instanceVersion, uint32_t physicalDeviceVersion,
33              const GrVkExtensions& extensions, GrProtected isProtected = GrProtected::kNo);
34 
35     bool isFormatSRGB(const GrBackendFormat&) const override;
36     bool isFormatCompressed(const GrBackendFormat&,
37                             SkImage::CompressionType* compressionType = nullptr) const override;
38 
39     bool isFormatTexturableAndUploadable(GrColorType, const GrBackendFormat&) const override;
40     bool isFormatTexturable(const GrBackendFormat&) const override;
41     bool isVkFormatTexturable(VkFormat) const;
42 
isFormatCopyable(const GrBackendFormat &)43     bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
44 
45     bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
46                                        int sampleCount = 1) const override;
47     bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override;
48     bool isFormatRenderable(VkFormat, int sampleCount) const;
49 
50     int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override;
51     int getRenderTargetSampleCount(int requestedCount, VkFormat) const;
52 
53     int maxRenderTargetSampleCount(const GrBackendFormat&) const override;
54     int maxRenderTargetSampleCount(VkFormat format) const;
55 
56     size_t bytesPerPixel(const GrBackendFormat&) const override;
57     size_t bytesPerPixel(VkFormat format) const;
58 
59     SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
60                                                  const GrBackendFormat& surfaceFormat,
61                                                  GrColorType srcColorType) const override;
62 
63     SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
64 
isVkFormatTexturableLinearly(VkFormat format)65     bool isVkFormatTexturableLinearly(VkFormat format) const {
66         return SkToBool(FormatInfo::kTexturable_Flag & this->getFormatInfo(format).fLinearFlags);
67     }
68 
formatCanBeDstofBlit(VkFormat format,bool linearTiled)69     bool formatCanBeDstofBlit(VkFormat format, bool linearTiled) const {
70         const FormatInfo& info = this->getFormatInfo(format);
71         const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags;
72         return SkToBool(FormatInfo::kBlitDst_Flag & flags);
73     }
74 
formatCanBeSrcofBlit(VkFormat format,bool linearTiled)75     bool formatCanBeSrcofBlit(VkFormat format, bool linearTiled) const {
76         const FormatInfo& info = this->getFormatInfo(format);
77         const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags;
78         return SkToBool(FormatInfo::kBlitSrc_Flag & flags);
79     }
80 
81     // On Adreno vulkan, they do not respect the imageOffset parameter at least in
82     // copyImageToBuffer. This flag says that we must do the copy starting from the origin always.
mustDoCopiesFromOrigin()83     bool mustDoCopiesFromOrigin() const {
84         return fMustDoCopiesFromOrigin;
85     }
86 
87     // Sometimes calls to QueueWaitIdle return before actually signalling the fences
88     // on the command buffers even though they have completed. This causes an assert to fire when
89     // destroying the command buffers. Therefore we add a sleep to make sure the fence signals.
mustSleepOnTearDown()90     bool mustSleepOnTearDown() const {
91         return fMustSleepOnTearDown;
92     }
93 
94     // Returns true if we should always make dedicated allocations for VkImages.
shouldAlwaysUseDedicatedImageMemory()95     bool shouldAlwaysUseDedicatedImageMemory() const {
96         return fShouldAlwaysUseDedicatedImageMemory;
97     }
98 
99     // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer.
avoidUpdateBuffers()100     bool avoidUpdateBuffers() const {
101         return fAvoidUpdateBuffers;
102     }
103 
104     /**
105      * Returns both a supported and most preferred stencil format to use in draws.
106      */
preferredStencilFormat()107     const StencilFormat& preferredStencilFormat() const {
108         return fPreferredStencilFormat;
109     }
110 
111     // Returns whether the device supports VK_KHR_Swapchain. Internally Skia never uses any of the
112     // swapchain functions, but we may need to transition to and from the
113     // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR image layout, so we must know whether that layout is
114     // supported.
supportsSwapchain()115     bool supportsSwapchain() const { return fSupportsSwapchain; }
116 
117     // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct.
supportsPhysicalDeviceProperties2()118     bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; }
119     // Returns whether the device supports the ability to extend VkMemoryRequirements struct.
supportsMemoryRequirements2()120     bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; }
121 
122     // Returns whether the device supports the ability to extend the vkBindMemory call.
supportsBindMemory2()123     bool supportsBindMemory2() const { return fSupportsBindMemory2; }
124 
125     // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In
126     // Vulkan 1.1 all these maintenance are part of the core spec.
supportsMaintenance1()127     bool supportsMaintenance1() const { return fSupportsMaintenance1; }
supportsMaintenance2()128     bool supportsMaintenance2() const { return fSupportsMaintenance2; }
supportsMaintenance3()129     bool supportsMaintenance3() const { return fSupportsMaintenance3; }
130 
131     // Returns true if the device supports passing in a flag to say we are using dedicated GPU when
132     // allocating memory. For some devices this allows them to return more optimized memory knowning
133     // they will never need to suballocate amonst multiple objects.
supportsDedicatedAllocation()134     bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; }
135 
136     // Returns true if the device supports importing of external memory into Vulkan memory.
supportsExternalMemory()137     bool supportsExternalMemory() const { return fSupportsExternalMemory; }
138     // Returns true if the device supports importing Android hardware buffers into Vulkan memory.
supportsAndroidHWBExternalMemory()139     bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; }
140 
141     // Returns true if it supports ycbcr conversion for samplers
supportsYcbcrConversion()142     bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
143 
144     // Returns true if the device supports protected memory.
supportsProtectedMemory()145     bool supportsProtectedMemory() const { return fSupportsProtectedMemory; }
146 
147     // Returns whether we prefer to record draws directly into a primary command buffer.
preferPrimaryOverSecondaryCommandBuffers()148     bool preferPrimaryOverSecondaryCommandBuffers() const {
149         return fPreferPrimaryOverSecondaryCommandBuffers;
150     }
151 
mustInvalidatePrimaryCmdBufferStateAfterClearAttachments()152     bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const {
153         return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments;
154     }
155 
156     /**
157      * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
158      * the surface is not a render target, otherwise it is the number of samples in the render
159      * target.
160      */
161     bool canCopyImage(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr,
162                       VkFormat srcFormat, int srcSamplecnt, bool srcHasYcbcr) const;
163 
164     bool canCopyAsBlit(VkFormat dstConfig, int dstSampleCnt, bool dstIsLinear, bool dstHasYcbcr,
165                        VkFormat srcConfig, int srcSampleCnt, bool srcIsLinear,
166                        bool srcHasYcbcr) const;
167 
168     bool canCopyAsResolve(VkFormat dstConfig, int dstSampleCnt, bool dstHasYcbcr,
169                           VkFormat srcConfig, int srcSamplecnt, bool srcHasYcbcr) const;
170 
171     GrColorType getYUVAColorTypeFromBackendFormat(const GrBackendFormat&,
172                                                   bool isAlphaChannel) const override;
173 
174     GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
175 
getFormatFromColorType(GrColorType colorType)176     VkFormat getFormatFromColorType(GrColorType colorType) const {
177         int idx = static_cast<int>(colorType);
178         return fColorTypeToFormatTable[idx];
179     }
180 
181     GrSwizzle getTextureSwizzle(const GrBackendFormat&, GrColorType) const override;
182     GrSwizzle getOutputSwizzle(const GrBackendFormat&, GrColorType) const override;
183 
184     int getFragmentUniformBinding() const;
185     int getFragmentUniformSet() const;
186 
187 #if GR_TEST_UTILS
188     std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
189 #endif
190 
191 private:
192     enum VkVendor {
193         kAMD_VkVendor = 4098,
194         kARM_VkVendor = 5045,
195         kImagination_VkVendor = 4112,
196         kIntel_VkVendor = 32902,
197         kNvidia_VkVendor = 4318,
198         kQualcomm_VkVendor = 20803,
199     };
200 
201     void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
202               VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&,
203               uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected);
204     void initGrCaps(const GrVkInterface* vkInterface,
205                     VkPhysicalDevice physDev,
206                     const VkPhysicalDeviceProperties&,
207                     const VkPhysicalDeviceMemoryProperties&,
208                     const VkPhysicalDeviceFeatures2&,
209                     const GrVkExtensions&);
210     void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&);
211 
212     void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
213     void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
214 
215     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
216 
217     bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
218     bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
219                           const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
220     GrBackendFormat onGetDefaultBackendFormat(GrColorType, GrRenderable) const override;
221 
222     GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat&, GrColorType) const override;
223     bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
224 
225     SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
226                                                  GrColorType) const override;
227 
228     // ColorTypeInfo for a specific format
229     struct ColorTypeInfo {
230         GrColorType fColorType = GrColorType::kUnknown;
231         enum {
232             kUploadData_Flag = 0x1,
233             // Does Ganesh itself support rendering to this colorType & format pair. Renderability
234             // still additionally depends on if the format itself is renderable.
235             kRenderable_Flag = 0x2,
236             // Indicates that this colorType is supported only if we are wrapping a texture with
237             // the given format and colorType. We do not allow creation with this pair.
238             kWrappedOnly_Flag = 0x4,
239         };
240         uint32_t fFlags = 0;
241 
242         GrSwizzle fTextureSwizzle;
243         GrSwizzle fOutputSwizzle;
244     };
245 
246     struct FormatInfo {
colorTypeFlagsFormatInfo247         uint32_t colorTypeFlags(GrColorType colorType) const {
248             for (int i = 0; i < fColorTypeInfoCount; ++i) {
249                 if (fColorTypeInfos[i].fColorType == colorType) {
250                     return fColorTypeInfos[i].fFlags;
251                 }
252             }
253             return 0;
254         }
255 
256         void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
257                   VkFormat);
258         static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags);
259         void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
260                               const VkPhysicalDeviceProperties&, VkFormat);
261 
262         enum {
263             kTexturable_Flag = 0x1,
264             kRenderable_Flag = 0x2,
265             kBlitSrc_Flag    = 0x4,
266             kBlitDst_Flag    = 0x8,
267         };
268 
269         uint16_t fOptimalFlags = 0;
270         uint16_t fLinearFlags = 0;
271 
272         SkTDArray<int> fColorSampleCounts;
273         // This value is only valid for regular formats. Compressed formats will be 0.
274         size_t fBytesPerPixel = 0;
275 
276         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
277         int fColorTypeInfoCount = 0;
278     };
279     static const size_t kNumVkFormats = 19;
280     FormatInfo fFormatTable[kNumVkFormats];
281 
282     FormatInfo& getFormatInfo(VkFormat);
283     const FormatInfo& getFormatInfo(VkFormat) const;
284 
285     VkFormat fColorTypeToFormatTable[kGrColorTypeCnt];
286     void setColorType(GrColorType, std::initializer_list<VkFormat> formats);
287 
288     StencilFormat fPreferredStencilFormat;
289 
290     SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos;
291 
292     bool fMustDoCopiesFromOrigin = false;
293     bool fMustSleepOnTearDown = false;
294     bool fShouldAlwaysUseDedicatedImageMemory = false;
295 
296     bool fAvoidUpdateBuffers = false;
297 
298     bool fSupportsSwapchain = false;
299 
300     bool fSupportsPhysicalDeviceProperties2 = false;
301     bool fSupportsMemoryRequirements2 = false;
302     bool fSupportsBindMemory2 = false;
303     bool fSupportsMaintenance1 = false;
304     bool fSupportsMaintenance2 = false;
305     bool fSupportsMaintenance3 = false;
306 
307     bool fSupportsDedicatedAllocation = false;
308     bool fSupportsExternalMemory = false;
309     bool fSupportsAndroidHWBExternalMemory = false;
310 
311     bool fSupportsYcbcrConversion = false;
312 
313     bool fSupportsProtectedMemory = false;
314 
315     bool fPreferPrimaryOverSecondaryCommandBuffers = true;
316     bool fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = false;
317 
318     typedef GrCaps INHERITED;
319 };
320 
321 #endif
322