• 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 "GrCaps.h"
12 #include "GrVkStencilAttachment.h"
13 #include "vk/GrVkTypes.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);
34 
isConfigTexturable(GrPixelConfig config)35     bool isConfigTexturable(GrPixelConfig config) const override {
36         return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
37     }
38 
isConfigCopyable(GrPixelConfig config)39     bool isConfigCopyable(GrPixelConfig config) const override {
40         return true;
41     }
42 
43     int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override;
44     int maxRenderTargetSampleCount(GrPixelConfig config) const override;
45 
surfaceSupportsReadPixels(const GrSurface *)46     bool surfaceSupportsReadPixels(const GrSurface*) const override { return true; }
47 
isConfigTexturableLinearly(GrPixelConfig config)48     bool isConfigTexturableLinearly(GrPixelConfig config) const {
49         return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags);
50     }
51 
isConfigRenderableLinearly(GrPixelConfig config,bool withMSAA)52     bool isConfigRenderableLinearly(GrPixelConfig config, bool withMSAA) const {
53         return !withMSAA && SkToBool(ConfigInfo::kRenderable_Flag &
54                                      fConfigTable[config].fLinearFlags);
55     }
56 
configCanBeDstofBlit(GrPixelConfig config,bool linearTiled)57     bool configCanBeDstofBlit(GrPixelConfig config, bool linearTiled) const {
58         const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags :
59                                               fConfigTable[config].fOptimalFlags;
60         return SkToBool(ConfigInfo::kBlitDst_Flag & flags);
61     }
62 
configCanBeSrcofBlit(GrPixelConfig config,bool linearTiled)63     bool configCanBeSrcofBlit(GrPixelConfig config, bool linearTiled) const {
64         const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags :
65                                               fConfigTable[config].fOptimalFlags;
66         return SkToBool(ConfigInfo::kBlitSrc_Flag & flags);
67     }
68 
69     // On Adreno vulkan, they do not respect the imageOffset parameter at least in
70     // copyImageToBuffer. This flag says that we must do the copy starting from the origin always.
mustDoCopiesFromOrigin()71     bool mustDoCopiesFromOrigin() const {
72         return fMustDoCopiesFromOrigin;
73     }
74 
75     // Sometimes calls to QueueWaitIdle return before actually signalling the fences
76     // on the command buffers even though they have completed. This causes an assert to fire when
77     // destroying the command buffers. Therefore we add a sleep to make sure the fence signals.
mustSleepOnTearDown()78     bool mustSleepOnTearDown() const {
79         return fMustSleepOnTearDown;
80     }
81 
82     // Returns true if while adding commands to command buffers, we must make a new command buffer
83     // everytime we want to bind a new VkPipeline. This is true for both primary and secondary
84     // command buffers. This is to work around a driver bug specifically on AMD.
newCBOnPipelineChange()85     bool newCBOnPipelineChange() const {
86         return fNewCBOnPipelineChange;
87     }
88 
89     // Returns true if we should always make dedicated allocations for VkImages.
shouldAlwaysUseDedicatedImageMemory()90     bool shouldAlwaysUseDedicatedImageMemory() const {
91         return fShouldAlwaysUseDedicatedImageMemory;
92     }
93 
94     /**
95      * Returns both a supported and most preferred stencil format to use in draws.
96      */
preferredStencilFormat()97     const StencilFormat& preferredStencilFormat() const {
98         return fPreferredStencilFormat;
99     }
100 
101     // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct.
supportsPhysicalDeviceProperties2()102     bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; }
103     // Returns whether the device supports the ability to extend VkMemoryRequirements struct.
supportsMemoryRequirements2()104     bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; }
105 
106     // Returns whether the device supports the ability to extend the vkBindMemory call.
supportsBindMemory2()107     bool supportsBindMemory2() const { return fSupportsBindMemory2; }
108 
109     // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In
110     // Vulkan 1.1 all these maintenance are part of the core spec.
supportsMaintenance1()111     bool supportsMaintenance1() const { return fSupportsMaintenance1; }
supportsMaintenance2()112     bool supportsMaintenance2() const { return fSupportsMaintenance2; }
supportsMaintenance3()113     bool supportsMaintenance3() const { return fSupportsMaintenance3; }
114 
115     // Returns true if the device supports passing in a flag to say we are using dedicated GPU when
116     // allocating memory. For some devices this allows them to return more optimized memory knowning
117     // they will never need to suballocate amonst multiple objects.
supportsDedicatedAllocation()118     bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; }
119 
120     // Returns true if the device supports importing of external memory into Vulkan memory.
supportsExternalMemory()121     bool supportsExternalMemory() const { return fSupportsExternalMemory; }
122     // Returns true if the device supports importing Android hardware buffers into Vulkan memory.
supportsAndroidHWBExternalMemory()123     bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; }
124 
125     // Returns true if it supports ycbcr conversion for samplers
supportsYcbcrConversion()126     bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
127 
128     /**
129      * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
130      * the surface is not a render target, otherwise it is the number of samples in the render
131      * target.
132      */
133     bool canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin,
134                       GrPixelConfig srcConfig, int srcSamplecnt, GrSurfaceOrigin srcOrigin) const;
135 
136     bool canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt, bool dstIsLinear,
137                        GrPixelConfig srcConfig, int srcSampleCnt, bool srcIsLinear) const;
138 
139     bool canCopyAsResolve(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin,
140                           GrPixelConfig srcConfig, int srcSamplecnt,
141                           GrSurfaceOrigin srcOrigin) const;
142 
143     bool canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable,
144                        GrPixelConfig srcConfig, bool srcIsTextureable) const;
145 
146     bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
147                             bool* rectsMustMatch, bool* disallowSubrect) const override;
148 
149     GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&,
150                                               SkColorType) const override;
151 
152     GrPixelConfig getConfigFromBackendFormat(const GrBackendFormat&, SkColorType) const override;
153     GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat&) const override;
154 
155     GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
156                                                     GrSRGBEncoded srgbEncoded) const override;
157 
158 private:
159     enum VkVendor {
160         kAMD_VkVendor = 4098,
161         kARM_VkVendor = 5045,
162         kImagination_VkVendor = 4112,
163         kIntel_VkVendor = 32902,
164         kNvidia_VkVendor = 4318,
165         kQualcomm_VkVendor = 20803,
166     };
167 
168     void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
169               VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&,
170               uint32_t physicalDeviceVersion, const GrVkExtensions&);
171     void initGrCaps(const GrVkInterface* vkInterface,
172                     VkPhysicalDevice physDev,
173                     const VkPhysicalDeviceProperties&,
174                     const VkPhysicalDeviceMemoryProperties&,
175                     const VkPhysicalDeviceFeatures2&,
176                     const GrVkExtensions&);
177     void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&);
178 
179     void initConfigTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
180     void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
181 
182     uint8_t getYcbcrKeyFromYcbcrInfo(const GrVkYcbcrConversionInfo& info);
183 
184     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
185 
186     bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
187     bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
188                           const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
189 
190     struct ConfigInfo {
ConfigInfoConfigInfo191         ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {}
192 
193         void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
194                   VkFormat);
195         static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags);
196         void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
197                               const VkPhysicalDeviceProperties&, VkFormat);
198 
199         enum {
200             kTextureable_Flag = 0x1,
201             kRenderable_Flag  = 0x2,
202             kBlitSrc_Flag     = 0x4,
203             kBlitDst_Flag     = 0x8,
204         };
205 
206         uint16_t fOptimalFlags;
207         uint16_t fLinearFlags;
208 
209         SkTDArray<int> fColorSampleCounts;
210     };
211     ConfigInfo fConfigTable[kGrPixelConfigCnt];
212 
213     StencilFormat fPreferredStencilFormat;
214 
215     SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos;
216 
217     bool fMustDoCopiesFromOrigin = false;
218     bool fMustSleepOnTearDown = false;
219     bool fNewCBOnPipelineChange = false;
220     bool fShouldAlwaysUseDedicatedImageMemory = false;
221 
222     bool fSupportsPhysicalDeviceProperties2 = false;
223     bool fSupportsMemoryRequirements2 = false;
224     bool fSupportsBindMemory2 = false;
225     bool fSupportsMaintenance1 = false;
226     bool fSupportsMaintenance2 = false;
227     bool fSupportsMaintenance3 = false;
228 
229     bool fSupportsDedicatedAllocation = false;
230     bool fSupportsExternalMemory = false;
231     bool fSupportsAndroidHWBExternalMemory = false;
232 
233     bool fSupportsYcbcrConversion = false;
234 
235     typedef GrCaps INHERITED;
236 };
237 
238 #endif
239