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/GrVkDefines.h"
14 
15 struct GrVkInterface;
16 class GrShaderCaps;
17 
18 /**
19  * Stores some capabilities of a Vk backend.
20  */
21 class GrVkCaps : public GrCaps {
22 public:
23     typedef GrVkStencilAttachment::Format StencilFormat;
24 
25     /**
26      * Creates a GrVkCaps that is set such that nothing is supported. The init function should
27      * be called to fill out the caps.
28      */
29     GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
30              VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
31 
isConfigTexturable(GrPixelConfig config)32     bool isConfigTexturable(GrPixelConfig config) const override {
33         return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
34     }
35 
isConfigCopyable(GrPixelConfig config)36     bool isConfigCopyable(GrPixelConfig config) const override {
37         return true;
38     }
39 
40     int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override;
41     int maxRenderTargetSampleCount(GrPixelConfig config) const override;
42 
43     bool surfaceSupportsWritePixels(const GrSurface* surface) const override;
44 
isConfigTexturableLinearly(GrPixelConfig config)45     bool isConfigTexturableLinearly(GrPixelConfig config) const {
46         return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags);
47     }
48 
isConfigRenderableLinearly(GrPixelConfig config,bool withMSAA)49     bool isConfigRenderableLinearly(GrPixelConfig config, bool withMSAA) const {
50         return !withMSAA && SkToBool(ConfigInfo::kRenderable_Flag &
51                                      fConfigTable[config].fLinearFlags);
52     }
53 
configCanBeDstofBlit(GrPixelConfig config,bool linearTiled)54     bool configCanBeDstofBlit(GrPixelConfig config, bool linearTiled) const {
55         const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags :
56                                               fConfigTable[config].fOptimalFlags;
57         return SkToBool(ConfigInfo::kBlitDst_Flag & flags);
58     }
59 
configCanBeSrcofBlit(GrPixelConfig config,bool linearTiled)60     bool configCanBeSrcofBlit(GrPixelConfig config, bool linearTiled) const {
61         const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags :
62                                               fConfigTable[config].fOptimalFlags;
63         return SkToBool(ConfigInfo::kBlitSrc_Flag & flags);
64     }
65 
66     // Tells of if we can pass in straight GLSL string into vkCreateShaderModule
canUseGLSLForShaderModule()67     bool canUseGLSLForShaderModule() const {
68         return fCanUseGLSLForShaderModule;
69     }
70 
71     // On Adreno vulkan, they do not respect the imageOffset parameter at least in
72     // copyImageToBuffer. This flag says that we must do the copy starting from the origin always.
mustDoCopiesFromOrigin()73     bool mustDoCopiesFromOrigin() const {
74         return fMustDoCopiesFromOrigin;
75     }
76 
77     // Check whether we support using draws for copies.
supportsCopiesAsDraws()78     bool supportsCopiesAsDraws() const {
79         return fSupportsCopiesAsDraws;
80     }
81 
82     // On Nvidia there is a current bug where we must the current command buffer before copy
83     // operations or else the copy will not happen. This includes copies, blits, resolves, and copy
84     // as draws.
mustSubmitCommandsBeforeCopyOp()85     bool mustSubmitCommandsBeforeCopyOp() const {
86         return fMustSubmitCommandsBeforeCopyOp;
87     }
88 
89     // Sometimes calls to QueueWaitIdle return before actually signalling the fences
90     // on the command buffers even though they have completed. This causes an assert to fire when
91     // destroying the command buffers. Therefore we add a sleep to make sure the fence signals.
mustSleepOnTearDown()92     bool mustSleepOnTearDown() const {
93         return fMustSleepOnTearDown;
94     }
95 
96     // Returns true if while adding commands to command buffers, we must make a new command buffer
97     // everytime we want to bind a new VkPipeline. This is true for both primary and secondary
98     // command buffers. This is to work around a driver bug specifically on AMD.
newCBOnPipelineChange()99     bool newCBOnPipelineChange() const {
100         return fNewCBOnPipelineChange;
101     }
102 
103     // On certain Intel devices/drivers (IntelHD405) there is a bug if we try to flush non-coherent
104     // memory and pass in VK_WHOLE_SIZE. This returns whether or not it is safe to use VK_WHOLE_SIZE
105     // or not.
canUseWholeSizeOnFlushMappedMemory()106     bool canUseWholeSizeOnFlushMappedMemory() const {
107         return fCanUseWholeSizeOnFlushMappedMemory;
108     }
109 
110     /**
111      * Returns both a supported and most prefered stencil format to use in draws.
112      */
preferedStencilFormat()113     const StencilFormat& preferedStencilFormat() const {
114         return fPreferedStencilFormat;
115     }
116 
117     bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
118                             bool* rectsMustMatch, bool* disallowSubrect) const override;
119 
120     bool validateBackendTexture(const GrBackendTexture&, SkColorType,
121                                 GrPixelConfig*) const override;
122     bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType,
123                                      GrPixelConfig*) const override;
124 
125     bool getConfigFromBackendFormat(const GrBackendFormat&, SkColorType,
126                                     GrPixelConfig*) const override;
127 
128 private:
129     enum VkVendor {
130         kAMD_VkVendor = 4098,
131         kARM_VkVendor = 5045,
132         kImagination_VkVendor = 4112,
133         kIntel_VkVendor = 32902,
134         kNvidia_VkVendor = 4318,
135         kQualcomm_VkVendor = 20803,
136     };
137 
138     void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
139               VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
140     void initGrCaps(const VkPhysicalDeviceProperties&,
141                     const VkPhysicalDeviceMemoryProperties&,
142                     uint32_t featureFlags);
143     void initShaderCaps(const VkPhysicalDeviceProperties&, uint32_t featureFlags);
144 
145     void initConfigTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
146     void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
147 
148     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
149 
150     struct ConfigInfo {
ConfigInfoConfigInfo151         ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {}
152 
153         void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
154                   VkFormat);
155         static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags);
156         void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
157                               const VkPhysicalDeviceProperties&, VkFormat);
158 
159         enum {
160             kTextureable_Flag = 0x1,
161             kRenderable_Flag  = 0x2,
162             kBlitSrc_Flag     = 0x4,
163             kBlitDst_Flag     = 0x8,
164         };
165 
166         uint16_t fOptimalFlags;
167         uint16_t fLinearFlags;
168 
169         SkTDArray<int> fColorSampleCounts;
170     };
171     ConfigInfo fConfigTable[kGrPixelConfigCnt];
172 
173     StencilFormat fPreferedStencilFormat;
174 
175     bool fCanUseGLSLForShaderModule;
176 
177     bool fMustDoCopiesFromOrigin;
178 
179     bool fSupportsCopiesAsDraws;
180 
181     bool fMustSubmitCommandsBeforeCopyOp;
182 
183     bool fMustSleepOnTearDown;
184 
185     bool fNewCBOnPipelineChange;
186 
187     bool fCanUseWholeSizeOnFlushMappedMemory;
188 
189     typedef GrCaps INHERITED;
190 };
191 
192 #endif
193