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