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