• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/GrVkAttachment.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     /**
25      * Creates a GrVkCaps that is set such that nothing is supported. The init function should
26      * be called to fill out the caps.
27      */
28     GrVkCaps(const GrContextOptions& contextOptions,
29              const GrVkInterface* vkInterface,
30              VkPhysicalDevice device,
31              const VkPhysicalDeviceFeatures2& features,
32              uint32_t instanceVersion,
33              uint32_t physicalDeviceVersion,
34              const GrVkExtensions& extensions,
35              GrProtected isProtected = GrProtected::kNo);
36 
37     bool isFormatSRGB(const GrBackendFormat&) const override;
38 
39     bool isFormatTexturable(const GrBackendFormat&) const override;
40     bool isVkFormatTexturable(VkFormat) const;
41 
isFormatCopyable(const GrBackendFormat &)42     bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
43 
44     bool isFormatAsColorTypeRenderable(GrColorType ct,
45                                        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     SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
57                                                  const GrBackendFormat& surfaceFormat,
58                                                  GrColorType srcColorType) const override;
59 
60     SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
61 
isVkFormatTexturableLinearly(VkFormat format)62     bool isVkFormatTexturableLinearly(VkFormat format) const {
63         return SkToBool(FormatInfo::kTexturable_Flag & this->getFormatInfo(format).fLinearFlags);
64     }
65 
formatCanBeDstofBlit(VkFormat format,bool linearTiled)66     bool formatCanBeDstofBlit(VkFormat format, bool linearTiled) const {
67         const FormatInfo& info = this->getFormatInfo(format);
68         const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags;
69         return SkToBool(FormatInfo::kBlitDst_Flag & flags);
70     }
71 
formatCanBeSrcofBlit(VkFormat format,bool linearTiled)72     bool formatCanBeSrcofBlit(VkFormat format, bool linearTiled) const {
73         const FormatInfo& info = this->getFormatInfo(format);
74         const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags;
75         return SkToBool(FormatInfo::kBlitSrc_Flag & flags);
76     }
77 
78     // Gets the GrColorType that should be used to transfer data in/out of a transfer buffer to
79     // write/read data when using a VkFormat with a specified color type.
80     GrColorType transferColorType(VkFormat, GrColorType surfaceColorType) const;
81 
82     // On some GPUs (Windows Nvidia and Imagination) calls to QueueWaitIdle return before actually
83     // signalling the fences on the command buffers even though they have completed. This causes
84     // issues when then deleting the command buffers. Therefore we additionally will call
85     // vkWaitForFences on each outstanding command buffer to make sure the driver signals the fence.
mustSyncCommandBuffersWithQueue()86     bool mustSyncCommandBuffersWithQueue() const { return fMustSyncCommandBuffersWithQueue; }
87 
88     // Returns true if we should always make dedicated allocations for VkImages.
shouldAlwaysUseDedicatedImageMemory()89     bool shouldAlwaysUseDedicatedImageMemory() const {
90         return fShouldAlwaysUseDedicatedImageMemory;
91     }
92 
93     // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer.
avoidUpdateBuffers()94     bool avoidUpdateBuffers() const { return fAvoidUpdateBuffers; }
95 
96     /**
97      * Returns both a supported and most preferred stencil format to use in draws.
98      */
preferredStencilFormat()99     VkFormat preferredStencilFormat() const { return fPreferredStencilFormat; }
100 
101     // Returns total number of bits used by stencil + depth + padding
GetStencilFormatTotalBitCount(VkFormat format)102     static int GetStencilFormatTotalBitCount(VkFormat format) {
103         switch (format) {
104             case VK_FORMAT_S8_UINT:
105                 return 8;
106             case VK_FORMAT_D24_UNORM_S8_UINT:
107                 return 32;
108             case VK_FORMAT_D32_SFLOAT_S8_UINT:
109                 // can optionally have 24 unused bits at the end so we assume the total bits is 64.
110                 return 64;
111             default:
112                 SkASSERT(false);
113                 return 0;
114         }
115     }
116 
117     // Returns whether the device supports VK_KHR_Swapchain. Internally Skia never uses any of the
118     // swapchain functions, but we may need to transition to and from the
119     // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR image layout, so we must know whether that layout is
120     // supported.
supportsSwapchain()121     bool supportsSwapchain() const { return fSupportsSwapchain; }
122 
123     // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct.
supportsPhysicalDeviceProperties2()124     bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; }
125     // Returns whether the device supports the ability to extend VkMemoryRequirements struct.
supportsMemoryRequirements2()126     bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; }
127 
128     // Returns whether the device supports the ability to extend the vkBindMemory call.
supportsBindMemory2()129     bool supportsBindMemory2() const { return fSupportsBindMemory2; }
130 
131     // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In
132     // Vulkan 1.1 all these maintenance are part of the core spec.
supportsMaintenance1()133     bool supportsMaintenance1() const { return fSupportsMaintenance1; }
supportsMaintenance2()134     bool supportsMaintenance2() const { return fSupportsMaintenance2; }
supportsMaintenance3()135     bool supportsMaintenance3() const { return fSupportsMaintenance3; }
136 
137     // Returns true if the device supports passing in a flag to say we are using dedicated GPU when
138     // allocating memory. For some devices this allows them to return more optimized memory knowning
139     // they will never need to suballocate amonst multiple objects.
supportsDedicatedAllocation()140     bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; }
141 
142     // Returns true if the device supports importing of external memory into Vulkan memory.
supportsExternalMemory()143     bool supportsExternalMemory() const { return fSupportsExternalMemory; }
144     // Returns true if the device supports importing Android hardware buffers into Vulkan memory.
supportsAndroidHWBExternalMemory()145     bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; }
146 
147     // Returns true if it supports ycbcr conversion for samplers
supportsYcbcrConversion()148     bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
149 
150     // Returns the number of descriptor slots used by immutable ycbcr VkImages.
151     //
152     // TODO: We should update this to return a count for a specific format or external format. We
153     // can use vkGetPhysicalDeviceImageFormatProperties2 with a
154     // VkSamplerYcbcrConversionImageFormatProperties to query this. However, right now that call
155     // does not support external android formats which is where the majority of ycbcr images are
156     // coming from. So for now we stay safe and always return 3 here which is the max value that the
157     // count could be for any format.
ycbcrCombinedImageSamplerDescriptorCount()158     uint32_t ycbcrCombinedImageSamplerDescriptorCount() const {
159         return 3;
160     }
161 
162     // Returns true if the device supports protected memory.
supportsProtectedMemory()163     bool supportsProtectedMemory() const { return fSupportsProtectedMemory; }
164 
165     // Returns whether we prefer to record draws directly into a primary command buffer.
preferPrimaryOverSecondaryCommandBuffers()166     bool preferPrimaryOverSecondaryCommandBuffers() const {
167         return fPreferPrimaryOverSecondaryCommandBuffers;
168     }
169 
maxPerPoolCachedSecondaryCommandBuffers()170     int maxPerPoolCachedSecondaryCommandBuffers() const {
171         return fMaxPerPoolCachedSecondaryCommandBuffers;
172     }
173 
maxInputAttachmentDescriptors()174     uint32_t maxInputAttachmentDescriptors() const { return fMaxInputAttachmentDescriptors; }
175 
mustInvalidatePrimaryCmdBufferStateAfterClearAttachments()176     bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const {
177         return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments;
178     }
179 
180     // For host visible allocations, this returns true if we require that they are coherent. This
181     // is used to work around bugs for devices that don't handle non-coherent memory correctly.
mustUseCoherentHostVisibleMemory()182     bool mustUseCoherentHostVisibleMemory() const { return fMustUseCoherentHostVisibleMemory; }
183 
184     // Returns whether a pure GPU accessible buffer is more performant to read than a buffer that is
185     // also host visible. If so then in some cases we may prefer the cost of doing a copy to the
186     // buffer. This typically would only be the case for buffers that are written once and read
187     // many times on the gpu.
gpuOnlyBuffersMorePerformant()188     bool gpuOnlyBuffersMorePerformant() const { return fGpuOnlyBuffersMorePerformant; }
189 
190     // For our CPU write and GPU read buffers (vertex, uniform, etc.), should we keep these buffers
191     // persistently mapped. In general the answer will be yes. The main case we don't do this is
192     // when using special memory that is DEVICE_LOCAL and HOST_VISIBLE on discrete GPUs.
shouldPersistentlyMapCpuToGpuBuffers()193     bool shouldPersistentlyMapCpuToGpuBuffers() const {
194         return fShouldPersistentlyMapCpuToGpuBuffers;
195     }
196 
197     // The max draw count that can be passed into indirect draw calls.
maxDrawIndirectDrawCount()198     uint32_t  maxDrawIndirectDrawCount() const { return fMaxDrawIndirectDrawCount; }
199 
200     /**
201      * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
202      * the surface is not a render target, otherwise it is the number of samples in the render
203      * target.
204      */
205     bool canCopyImage(VkFormat dstFormat,
206                       int dstSampleCnt,
207                       bool dstHasYcbcr,
208                       VkFormat srcFormat,
209                       int srcSamplecnt,
210                       bool srcHasYcbcr) const;
211 
212     bool canCopyAsBlit(VkFormat dstConfig,
213                        int dstSampleCnt,
214                        bool dstIsLinear,
215                        bool dstHasYcbcr,
216                        VkFormat srcConfig,
217                        int srcSampleCnt,
218                        bool srcIsLinear,
219                        bool srcHasYcbcr) const;
220 
221     bool canCopyAsResolve(VkFormat dstConfig,
222                           int dstSampleCnt,
223                           bool dstHasYcbcr,
224                           VkFormat srcConfig,
225                           int srcSamplecnt,
226                           bool srcHasYcbcr) const;
227 
228     GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
229 
getFormatFromColorType(GrColorType colorType)230     VkFormat getFormatFromColorType(GrColorType colorType) const {
231         int idx = static_cast<int>(colorType);
232         return fColorTypeToFormatTable[idx];
233     }
234 
235     GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override;
236 
237     uint64_t computeFormatKey(const GrBackendFormat&) const override;
238 
239     int getFragmentUniformBinding() const;
240     int getFragmentUniformSet() const;
241 
242     void addExtraSamplerKey(GrProcessorKeyBuilder*,
243                             GrSamplerState,
244                             const GrBackendFormat&) const override;
245 
246     GrProgramDesc makeDesc(GrRenderTarget*,
247                            const GrProgramInfo&,
248                            ProgramDescOverrideFlags) const override;
249 
250     GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const override;
251 
252     VkShaderStageFlags getPushConstantStageFlags() const;
253 
254     // If true then when doing MSAA draws, we will prefer to discard the msaa attachment on load
255     // and stores. The use of this feature for specific draws depends on the render target having a
256     // resolve attachment, and if we need to load previous data the resolve attachment must be
257     // usable as an input attachment. Otherwise we will just write out and store the msaa attachment
258     // like normal.
259     // This flag is similar to enabling gl render to texture for msaa rendering.
preferDiscardableMSAAAttachment()260     bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; }
261 
mustLoadFullImageWithDiscardableMSAA()262     bool mustLoadFullImageWithDiscardableMSAA() const {
263         return fMustLoadFullImageWithDiscardableMSAA;
264     }
265 
266 #if GR_TEST_UTILS
267     std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
268 #endif
269 
270 private:
271     enum VkVendor {
272         kAMD_VkVendor = 4098,
273         kARM_VkVendor = 5045,
274         kImagination_VkVendor = 4112,
275         kIntel_VkVendor = 32902,
276         kNvidia_VkVendor = 4318,
277         kQualcomm_VkVendor = 20803,
278     };
279 
280     void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
281               VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&,
282               uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected);
283     void initGrCaps(const GrVkInterface* vkInterface,
284                     VkPhysicalDevice physDev,
285                     const VkPhysicalDeviceProperties&,
286                     const VkPhysicalDeviceMemoryProperties&,
287                     const VkPhysicalDeviceFeatures2&,
288                     const GrVkExtensions&);
289     void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&);
290 
291     void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
292     void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
293 
294     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
295 
296     bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
297     bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
298                           const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
299     GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override;
300 
301     bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
302 
303     SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
304                                                  GrColorType) const override;
305 
306     GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
307 
308     GrDstSampleType onGetDstSampleTypeForProxy(const GrRenderTargetProxy*) const override;
309 
310     // ColorTypeInfo for a specific format
311     struct ColorTypeInfo {
312         GrColorType fColorType = GrColorType::kUnknown;
313         GrColorType fTransferColorType = GrColorType::kUnknown;
314         enum {
315             kUploadData_Flag = 0x1,
316             // Does Ganesh itself support rendering to this colorType & format pair. Renderability
317             // still additionally depends on if the format itself is renderable.
318             kRenderable_Flag = 0x2,
319             // Indicates that this colorType is supported only if we are wrapping a texture with
320             // the given format and colorType. We do not allow creation with this pair.
321             kWrappedOnly_Flag = 0x4,
322         };
323         uint32_t fFlags = 0;
324 
325         GrSwizzle fReadSwizzle;
326         GrSwizzle fWriteSwizzle;
327     };
328 
329     struct FormatInfo {
colorTypeFlagsFormatInfo330         uint32_t colorTypeFlags(GrColorType colorType) const {
331             for (int i = 0; i < fColorTypeInfoCount; ++i) {
332                 if (fColorTypeInfos[i].fColorType == colorType) {
333                     return fColorTypeInfos[i].fFlags;
334                 }
335             }
336             return 0;
337         }
338 
339         void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
340                   VkFormat);
341         static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags);
342         void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
343                               const VkPhysicalDeviceProperties&, VkFormat);
344 
345         enum {
346             kTexturable_Flag = 0x1,
347             kRenderable_Flag = 0x2,
348             kBlitSrc_Flag    = 0x4,
349             kBlitDst_Flag    = 0x8,
350         };
351 
352         uint16_t fOptimalFlags = 0;
353         uint16_t fLinearFlags = 0;
354 
355         SkTDArray<int> fColorSampleCounts;
356 
357         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
358         int fColorTypeInfoCount = 0;
359     };
360     static const size_t kNumVkFormats = 22;
361     FormatInfo fFormatTable[kNumVkFormats];
362 
363     FormatInfo& getFormatInfo(VkFormat);
364     const FormatInfo& getFormatInfo(VkFormat) const;
365 
366     VkFormat fColorTypeToFormatTable[kGrColorTypeCnt];
367     void setColorType(GrColorType, std::initializer_list<VkFormat> formats);
368 
369     VkFormat fPreferredStencilFormat;
370 
371     SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos;
372 
373     bool fMustSyncCommandBuffersWithQueue = false;
374     bool fShouldAlwaysUseDedicatedImageMemory = false;
375 
376     bool fAvoidUpdateBuffers = false;
377 
378     bool fSupportsSwapchain = false;
379 
380     bool fSupportsPhysicalDeviceProperties2 = false;
381     bool fSupportsMemoryRequirements2 = false;
382     bool fSupportsBindMemory2 = false;
383     bool fSupportsMaintenance1 = false;
384     bool fSupportsMaintenance2 = false;
385     bool fSupportsMaintenance3 = false;
386 
387     bool fSupportsDedicatedAllocation = false;
388     bool fSupportsExternalMemory = false;
389     bool fSupportsAndroidHWBExternalMemory = false;
390 
391     bool fSupportsYcbcrConversion = false;
392 
393     bool fSupportsProtectedMemory = false;
394 
395     bool fPreferPrimaryOverSecondaryCommandBuffers = true;
396     bool fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = false;
397 
398     bool fMustUseCoherentHostVisibleMemory = false;
399     bool fGpuOnlyBuffersMorePerformant = false;
400     bool fShouldPersistentlyMapCpuToGpuBuffers = true;
401 
402     // We default this to 100 since we already cap the max render tasks at 100 before doing a
403     // submission in the GrDrawingManager, so we shouldn't be going over 100 secondary command
404     // buffers per primary anyways.
405     int fMaxPerPoolCachedSecondaryCommandBuffers = 100;
406 
407     uint32_t fMaxInputAttachmentDescriptors = 0;
408 
409     bool fPreferDiscardableMSAAAttachment = false;
410     bool fMustLoadFullImageWithDiscardableMSAA = false;
411 
412     uint32_t fMaxDrawIndirectDrawCount = 0;
413 
414     using INHERITED = GrCaps;
415 };
416 
417 #endif
418