• 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 #if GR_TEST_UTILS
276     std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
277 #endif
278 
279 private:
280     enum VkVendor {
281         kAMD_VkVendor = 4098,
282         kARM_VkVendor = 5045,
283         kImagination_VkVendor = 4112,
284         kIntel_VkVendor = 32902,
285         kNvidia_VkVendor = 4318,
286         kQualcomm_VkVendor = 20803,
287     };
288 
289     void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
290               VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&,
291               uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected);
292     void initGrCaps(const GrVkInterface* vkInterface,
293                     VkPhysicalDevice physDev,
294                     const VkPhysicalDeviceProperties&,
295                     const VkPhysicalDeviceMemoryProperties&,
296                     const VkPhysicalDeviceFeatures2&,
297                     const GrVkExtensions&);
298     void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&);
299 
300     void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
301     void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
302 
303     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
304 
305     bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
306     bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
307                           const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
308     GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override;
309 
310     bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
311 
312     SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
313                                                  GrColorType) const override;
314 
315     GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
316 
317     GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const override;
318 
319     bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const override;
320 
321     // ColorTypeInfo for a specific format
322     struct ColorTypeInfo {
323         GrColorType fColorType = GrColorType::kUnknown;
324         GrColorType fTransferColorType = GrColorType::kUnknown;
325         enum {
326             kUploadData_Flag = 0x1,
327             // Does Ganesh itself support rendering to this colorType & format pair. Renderability
328             // still additionally depends on if the format itself is renderable.
329             kRenderable_Flag = 0x2,
330             // Indicates that this colorType is supported only if we are wrapping a texture with
331             // the given format and colorType. We do not allow creation with this pair.
332             kWrappedOnly_Flag = 0x4,
333         };
334         uint32_t fFlags = 0;
335 
336         GrSwizzle fReadSwizzle;
337         GrSwizzle fWriteSwizzle;
338     };
339 
340     struct FormatInfo {
colorTypeFlagsFormatInfo341         uint32_t colorTypeFlags(GrColorType colorType) const {
342             for (int i = 0; i < fColorTypeInfoCount; ++i) {
343                 if (fColorTypeInfos[i].fColorType == colorType) {
344                     return fColorTypeInfos[i].fFlags;
345                 }
346             }
347             return 0;
348         }
349 
350         void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
351                   VkFormat);
352         static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags);
353         void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
354                               const VkPhysicalDeviceProperties&, VkFormat);
355 
356         enum {
357             kTexturable_Flag = 0x1,
358             kRenderable_Flag = 0x2,
359             kBlitSrc_Flag    = 0x4,
360             kBlitDst_Flag    = 0x8,
361         };
362 
363         uint16_t fOptimalFlags = 0;
364         uint16_t fLinearFlags = 0;
365 
366         SkTDArray<int> fColorSampleCounts;
367 
368         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
369         int fColorTypeInfoCount = 0;
370     };
371     static const size_t kNumVkFormats = 22;
372     FormatInfo fFormatTable[kNumVkFormats];
373 
374     FormatInfo& getFormatInfo(VkFormat);
375     const FormatInfo& getFormatInfo(VkFormat) const;
376 
377     VkFormat fColorTypeToFormatTable[kGrColorTypeCnt];
378     void setColorType(GrColorType, std::initializer_list<VkFormat> formats);
379 
380     VkFormat fPreferredStencilFormat;
381 
382     SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos;
383 
384     bool fMustSyncCommandBuffersWithQueue = false;
385     bool fShouldAlwaysUseDedicatedImageMemory = false;
386 
387     bool fAvoidUpdateBuffers = false;
388 
389     bool fSupportsSwapchain = false;
390 
391     bool fSupportsPhysicalDeviceProperties2 = false;
392     bool fSupportsMemoryRequirements2 = false;
393     bool fSupportsBindMemory2 = false;
394     bool fSupportsMaintenance1 = false;
395     bool fSupportsMaintenance2 = false;
396     bool fSupportsMaintenance3 = false;
397 
398     bool fSupportsDedicatedAllocation = false;
399     bool fSupportsExternalMemory = false;
400     bool fSupportsAndroidHWBExternalMemory = false;
401 
402     bool fSupportsYcbcrConversion = false;
403 
404     bool fSupportsProtectedMemory = false;
405 
406     bool fSupportsDRMFormatModifiers = false;
407 
408     bool fPreferPrimaryOverSecondaryCommandBuffers = true;
409     bool fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = false;
410 
411     bool fMustUseCoherentHostVisibleMemory = false;
412     bool fGpuOnlyBuffersMorePerformant = false;
413     bool fShouldPersistentlyMapCpuToGpuBuffers = true;
414 
415     // We default this to 100 since we already cap the max render tasks at 100 before doing a
416     // submission in the GrDrawingManager, so we shouldn't be going over 100 secondary command
417     // buffers per primary anyways.
418     int fMaxPerPoolCachedSecondaryCommandBuffers = 100;
419 
420     uint32_t fMaxInputAttachmentDescriptors = 0;
421 
422     bool fPreferDiscardableMSAAAttachment = false;
423     bool fMustLoadFullImageWithDiscardableMSAA = false;
424     bool fSupportsDiscardableMSAAForDMSAA = true;
425     bool fSupportsMemorylessAttachments = false;
426 
427     uint32_t fMaxDrawIndirectDrawCount = 0;
428 
429     using INHERITED = GrCaps;
430 };
431 
432 #endif
433