• 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 
14 class GrShaderCaps;
15 class GrVkExtensions;
16 struct GrVkInterface;
17 class GrVkRenderTarget;
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&, GrTextureType) 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 true if the VK_EXT_image_drm_format_modifier is enabled.
supportsDRMFormatModifiers()166     bool supportsDRMFormatModifiers() const { return fSupportsDRMFormatModifiers; }
167 
168     // Returns whether we prefer to record draws directly into a primary command buffer.
preferPrimaryOverSecondaryCommandBuffers()169     bool preferPrimaryOverSecondaryCommandBuffers() const {
170         return fPreferPrimaryOverSecondaryCommandBuffers;
171     }
172 
maxPerPoolCachedSecondaryCommandBuffers()173     int maxPerPoolCachedSecondaryCommandBuffers() const {
174         return fMaxPerPoolCachedSecondaryCommandBuffers;
175     }
176 
maxInputAttachmentDescriptors()177     uint32_t maxInputAttachmentDescriptors() const { return fMaxInputAttachmentDescriptors; }
178 
mustInvalidatePrimaryCmdBufferStateAfterClearAttachments()179     bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const {
180         return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments;
181     }
182 
183     // For host visible allocations, this returns true if we require that they are coherent. This
184     // is used to work around bugs for devices that don't handle non-coherent memory correctly.
mustUseCoherentHostVisibleMemory()185     bool mustUseCoherentHostVisibleMemory() const { return fMustUseCoherentHostVisibleMemory; }
186 
187     // Returns whether a pure GPU accessible buffer is more performant to read than a buffer that is
188     // also host visible. If so then in some cases we may prefer the cost of doing a copy to the
189     // buffer. This typically would only be the case for buffers that are written once and read
190     // many times on the gpu.
gpuOnlyBuffersMorePerformant()191     bool gpuOnlyBuffersMorePerformant() const { return fGpuOnlyBuffersMorePerformant; }
192 
193     // For our CPU write and GPU read buffers (vertex, uniform, etc.), should we keep these buffers
194     // persistently mapped. In general the answer will be yes. The main case we don't do this is
195     // when using special memory that is DEVICE_LOCAL and HOST_VISIBLE on discrete GPUs.
shouldPersistentlyMapCpuToGpuBuffers()196     bool shouldPersistentlyMapCpuToGpuBuffers() const {
197         return fShouldPersistentlyMapCpuToGpuBuffers;
198     }
199 
200     // The max draw count that can be passed into indirect draw calls.
maxDrawIndirectDrawCount()201     uint32_t  maxDrawIndirectDrawCount() const { return fMaxDrawIndirectDrawCount; }
202 
203     /**
204      * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
205      * the surface is not a render target, otherwise it is the number of samples in the render
206      * target.
207      */
208     bool canCopyImage(VkFormat dstFormat,
209                       int dstSampleCnt,
210                       bool dstHasYcbcr,
211                       VkFormat srcFormat,
212                       int srcSamplecnt,
213                       bool srcHasYcbcr) const;
214 
215     bool canCopyAsBlit(VkFormat dstConfig,
216                        int dstSampleCnt,
217                        bool dstIsLinear,
218                        bool dstHasYcbcr,
219                        VkFormat srcConfig,
220                        int srcSampleCnt,
221                        bool srcIsLinear,
222                        bool srcHasYcbcr) const;
223 
224     bool canCopyAsResolve(VkFormat dstConfig,
225                           int dstSampleCnt,
226                           bool dstHasYcbcr,
227                           VkFormat srcConfig,
228                           int srcSamplecnt,
229                           bool srcHasYcbcr) const;
230 
231     GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
232 
getFormatFromColorType(GrColorType colorType)233     VkFormat getFormatFromColorType(GrColorType colorType) const {
234         int idx = static_cast<int>(colorType);
235         return fColorTypeToFormatTable[idx];
236     }
237 
238     GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override;
239 
240     uint64_t computeFormatKey(const GrBackendFormat&) const override;
241 
242     int getFragmentUniformBinding() const;
243     int getFragmentUniformSet() const;
244 
245     void addExtraSamplerKey(GrProcessorKeyBuilder*,
246                             GrSamplerState,
247                             const GrBackendFormat&) const override;
248 
249     GrProgramDesc makeDesc(GrRenderTarget*,
250                            const GrProgramInfo&,
251                            ProgramDescOverrideFlags) const override;
252 
253     GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const override;
254 
255     VkShaderStageFlags getPushConstantStageFlags() const;
256 
257     // If true then when doing MSAA draws, we will prefer to discard the msaa attachment on load
258     // and stores. The use of this feature for specific draws depends on the render target having a
259     // resolve attachment, and if we need to load previous data the resolve attachment must be
260     // usable as an input attachment. Otherwise we will just write out and store the msaa attachment
261     // like normal.
262     // This flag is similar to enabling gl render to texture for msaa rendering.
preferDiscardableMSAAAttachment()263     bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; }
mustLoadFullImageWithDiscardableMSAA()264     bool mustLoadFullImageWithDiscardableMSAA() const {
265         return fMustLoadFullImageWithDiscardableMSAA;
266     }
supportsDiscardableMSAAForDMSAA()267     bool supportsDiscardableMSAAForDMSAA() const { return fSupportsDiscardableMSAAForDMSAA; }
268     bool renderTargetSupportsDiscardableMSAA(const GrVkRenderTarget*) const;
269     bool programInfoWillUseDiscardableMSAA(const GrProgramInfo&) const;
270 
dmsaaResolveCanBeUsedAsTextureInSameRenderPass()271     bool dmsaaResolveCanBeUsedAsTextureInSameRenderPass() const override { return false; }
272 
supportsMemorylessAttachments()273     bool supportsMemorylessAttachments() const { return fSupportsMemorylessAttachments; }
274 
275     bool supportsHpsBlur(const GrSurfaceProxyView* proxyViewPtr) const override;
276 
277 #ifdef SUPPORT_OPAQUE_OPTIMIZATION
278     bool supportsOpaqueRegion() const override;
279 #endif
280 
281 #if GR_TEST_UTILS
282     std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
283 #endif
284 
285 private:
286     enum VkVendor {
287         kAMD_VkVendor = 4098,
288         kARM_VkVendor = 5045,
289         kHisi_VkVendor = 6629,
290         kImagination_VkVendor = 4112,
291         kIntel_VkVendor = 32902,
292         kNvidia_VkVendor = 4318,
293         kQualcomm_VkVendor = 20803,
294     };
295 
296     void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
297               VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&,
298               uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected);
299     void initGrCaps(const GrVkInterface* vkInterface,
300                     VkPhysicalDevice physDev,
301                     const VkPhysicalDeviceProperties&,
302                     const VkPhysicalDeviceMemoryProperties&,
303                     const VkPhysicalDeviceFeatures2&,
304                     const GrVkExtensions&);
305     void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&);
306 
307     void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
308     void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
309 
310     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
311 
312     bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
313     bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
314                           const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
315     GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override;
316 
317     bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
318 
319     SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
320                                                  GrColorType) const override;
321 
322     GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
323 
324     GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const override;
325 
326     bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const override;
327 
328     // ColorTypeInfo for a specific format
329     struct ColorTypeInfo {
330         GrColorType fColorType = GrColorType::kUnknown;
331         GrColorType fTransferColorType = GrColorType::kUnknown;
332         enum {
333             kUploadData_Flag = 0x1,
334             // Does Ganesh itself support rendering to this colorType & format pair. Renderability
335             // still additionally depends on if the format itself is renderable.
336             kRenderable_Flag = 0x2,
337             // Indicates that this colorType is supported only if we are wrapping a texture with
338             // the given format and colorType. We do not allow creation with this pair.
339             kWrappedOnly_Flag = 0x4,
340         };
341         uint32_t fFlags = 0;
342 
343         GrSwizzle fReadSwizzle;
344         GrSwizzle fWriteSwizzle;
345     };
346 
347     struct FormatInfo {
colorTypeFlagsFormatInfo348         uint32_t colorTypeFlags(GrColorType colorType) const {
349             for (int i = 0; i < fColorTypeInfoCount; ++i) {
350                 if (fColorTypeInfos[i].fColorType == colorType) {
351                     return fColorTypeInfos[i].fFlags;
352                 }
353             }
354             return 0;
355         }
356 
357         void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
358                   VkFormat);
359         static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags);
360         void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
361                               const VkPhysicalDeviceProperties&, VkFormat);
362 
363         enum {
364             kTexturable_Flag = 0x1,
365             kRenderable_Flag = 0x2,
366             kBlitSrc_Flag    = 0x4,
367             kBlitDst_Flag    = 0x8,
368         };
369 
370         uint16_t fOptimalFlags = 0;
371         uint16_t fLinearFlags = 0;
372 
373         SkTDArray<int> fColorSampleCounts;
374 
375         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
376         int fColorTypeInfoCount = 0;
377     };
378     static const size_t kNumVkFormats = 25;
379     FormatInfo fFormatTable[kNumVkFormats];
380 
381     FormatInfo& getFormatInfo(VkFormat);
382     const FormatInfo& getFormatInfo(VkFormat) const;
383 
384     VkFormat fColorTypeToFormatTable[kGrColorTypeCnt];
385     void setColorType(GrColorType, std::initializer_list<VkFormat> formats);
386 
387     VkFormat fPreferredStencilFormat;
388 
389     SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos;
390 
391     bool fMustSyncCommandBuffersWithQueue = false;
392     bool fShouldAlwaysUseDedicatedImageMemory = false;
393 
394     bool fAvoidUpdateBuffers = false;
395 
396     bool fSupportsSwapchain = false;
397 
398     bool fSupportsPhysicalDeviceProperties2 = false;
399     bool fSupportsMemoryRequirements2 = false;
400     bool fSupportsBindMemory2 = false;
401     bool fSupportsMaintenance1 = false;
402     bool fSupportsMaintenance2 = false;
403     bool fSupportsMaintenance3 = false;
404 
405     bool fSupportsDedicatedAllocation = false;
406     bool fSupportsExternalMemory = false;
407     bool fSupportsAndroidHWBExternalMemory = false;
408 
409     bool fSupportsYcbcrConversion = false;
410 
411     bool fSupportsProtectedMemory = false;
412 
413     bool fSupportsDRMFormatModifiers = false;
414 
415     bool fPreferPrimaryOverSecondaryCommandBuffers = true;
416     bool fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = false;
417 
418     bool fMustUseCoherentHostVisibleMemory = false;
419     bool fGpuOnlyBuffersMorePerformant = false;
420     bool fShouldPersistentlyMapCpuToGpuBuffers = true;
421 
422     // We default this to 100 since we already cap the max render tasks at 100 before doing a
423     // submission in the GrDrawingManager, so we shouldn't be going over 100 secondary command
424     // buffers per primary anyways.
425     int fMaxPerPoolCachedSecondaryCommandBuffers = 100;
426 
427     uint32_t fMaxInputAttachmentDescriptors = 0;
428 
429     bool fPreferDiscardableMSAAAttachment = false;
430     bool fMustLoadFullImageWithDiscardableMSAA = false;
431     bool fSupportsDiscardableMSAAForDMSAA = true;
432     bool fSupportsMemorylessAttachments = false;
433 
434     bool fSupportHpsBlur = false;
435 
436 #ifdef SUPPORT_OPAQUE_OPTIMIZATION
437     bool fSupportOpaqueRegion = false;
438 #endif
439 
440     uint32_t fMaxDrawIndirectDrawCount = 0;
441 
442     using INHERITED = GrCaps;
443 };
444 
445 #endif
446