• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
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 skgpu_graphite_VulkanCaps_DEFINED
9 #define skgpu_graphite_VulkanCaps_DEFINED
10 
11 #include "include/private/base/SkTDArray.h"
12 #include "src/gpu/graphite/Caps.h"
13 #include "src/gpu/vk/VulkanInterface.h"
14 #include "src/gpu/vk/VulkanUtilsPriv.h"
15 
16 namespace skgpu::graphite {
17 struct ContextOptions;
18 struct VulkanTextureInfo;
19 
20 class VulkanCaps final : public Caps {
21 public:
22     VulkanCaps(const ContextOptions&,
23                const skgpu::VulkanInterface*,
24                VkPhysicalDevice,
25                uint32_t physicalDeviceVersion,
26                const VkPhysicalDeviceFeatures2*,
27                const skgpu::VulkanExtensions*,
28                Protected);
29     ~VulkanCaps() override;
30 
31     TextureInfo getDefaultSampledTextureInfo(SkColorType,
32                                              Mipmapped mipmapped,
33                                              Protected,
34                                              Renderable) const override;
35 
36     TextureInfo getTextureInfoForSampledCopy(const TextureInfo& textureInfo,
37                                              Mipmapped mipmapped) const override;
38 
39     TextureInfo getDefaultCompressedTextureInfo(SkTextureCompressionType,
40                                                 Mipmapped mipmapped,
41                                                 Protected) const override;
42 
43     TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo,
44                                           Discardable discardable) const override;
45 
46     TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags>,
47                                                   uint32_t sampleCount,
48                                                   Protected) const override;
49 
50     TextureInfo getDefaultStorageTextureInfo(SkColorType) const override;
51 
52     ImmutableSamplerInfo getImmutableSamplerInfo(const TextureProxy* proxy) const override;
53 
54     UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&,
55                                       const RenderPassDesc&) const override;
makeComputePipelineKey(const ComputePipelineDesc &)56     UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const override { return {}; }
57 
58     GraphiteResourceKey makeSamplerKey(const SamplerDesc&) const override;
59 
60     uint32_t channelMask(const TextureInfo&) const override;
61 
62     bool isTexturable(const VulkanTextureInfo&) const;
63 
64     bool isRenderable(const TextureInfo&) const override;
65     bool isRenderable(const VulkanTextureInfo&) const;
66     bool isStorage(const TextureInfo&) const override;
67 
68     void buildKeyForTexture(SkISize dimensions,
69                             const TextureInfo&,
70                             ResourceType,
71                             Shareable,
72                             GraphiteResourceKey*) const override;
73 
shouldAlwaysUseDedicatedImageMemory()74     bool shouldAlwaysUseDedicatedImageMemory() const {
75         return fShouldAlwaysUseDedicatedImageMemory;
76     }
77 
78     // Returns whether a pure GPU accessible buffer is more performant to read than a buffer that is
79     // also host visible. If so then in some cases we may prefer the cost of doing a copy to the
80     // buffer. This typically would only be the case for buffers that are written once and read
81     // many times on the gpu.
gpuOnlyBuffersMorePerformant()82     bool gpuOnlyBuffersMorePerformant() const { return fGpuOnlyBuffersMorePerformant; }
83 
84     // For our CPU write and GPU read buffers (vertex, uniform, etc.), we should keep these buffers
85     // persistently mapped. In general, the answer will be yes. The main case where we don't do this
86     // is when using special memory that is DEVICE_LOCAL and HOST_VISIBLE on discrete GPUs.
shouldPersistentlyMapCpuToGpuBuffers()87     bool shouldPersistentlyMapCpuToGpuBuffers() const {
88         return fShouldPersistentlyMapCpuToGpuBuffers;
89     }
90 
supportsYcbcrConversion()91     bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
supportsDeviceFaultInfo()92     bool supportsDeviceFaultInfo() const { return fSupportsDeviceFaultInfo; }
93 
maxVertexAttributes()94     uint32_t maxVertexAttributes()   const { return fMaxVertexAttributes;   }
maxUniformBufferRange()95     uint64_t maxUniformBufferRange() const { return fMaxUniformBufferRange; }
maxStorageBufferRange()96     uint64_t maxStorageBufferRange() const { return fMaxStorageBufferRange; }
97 
physicalDeviceMemoryProperties2()98     const VkPhysicalDeviceMemoryProperties2& physicalDeviceMemoryProperties2() const {
99         return fPhysicalDeviceMemoryProperties2;
100     }
101 
102     bool isTransferSrc(const VulkanTextureInfo&) const;
103     bool isTransferDst(const VulkanTextureInfo&) const;
104 
mustLoadFullImageForMSAA()105     bool mustLoadFullImageForMSAA() const { return fMustLoadFullImageForMSAA; }
106 
107 private:
108     enum VkVendor {
109         kAMD_VkVendor             = 4098,
110         kARM_VkVendor             = 5045,
111         kImagination_VkVendor     = 4112,
112         kIntel_VkVendor           = 32902,
113         kNvidia_VkVendor          = 4318,
114         kQualcomm_VkVendor        = 20803,
115     };
116 
117     void init(const ContextOptions&,
118               const skgpu::VulkanInterface*,
119               VkPhysicalDevice,
120               uint32_t physicalDeviceVersion,
121               const VkPhysicalDeviceFeatures2*,
122               const skgpu::VulkanExtensions*,
123               Protected);
124 
125     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
126 
127     void initFormatTable(const skgpu::VulkanInterface*,
128                          VkPhysicalDevice,
129                          const VkPhysicalDeviceProperties&);
130 
131     void initDepthStencilFormatTable(const skgpu::VulkanInterface*,
132                                      VkPhysicalDevice,
133                                      const VkPhysicalDeviceProperties&);
134 
135     const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const override;
136 
137     bool onIsTexturable(const TextureInfo&) const override;
138 
139     bool supportsWritePixels(const TextureInfo&) const override;
140     bool supportsReadPixels(const TextureInfo&) const override;
141 
142     std::pair<SkColorType, bool /*isRGBFormat*/> supportedWritePixelsColorType(
143             SkColorType dstColorType,
144             const TextureInfo& dstTextureInfo,
145             SkColorType srcColorType) const override;
146     std::pair<SkColorType, bool /*isRGBFormat*/> supportedReadPixelsColorType(
147             SkColorType srcColorType,
148             const TextureInfo& srcTextureInfo,
149             SkColorType dstColorType) const override;
150 
151     // Struct that determines and stores which sample count quantities a VkFormat supports.
152     struct SupportedSampleCounts {
153         void initSampleCounts(const skgpu::VulkanInterface*,
154                               VkPhysicalDevice,
155                               const VkPhysicalDeviceProperties&,
156                               VkFormat,
157                               VkImageUsageFlags);
158 
159         bool isSampleCountSupported(int requestedCount) const;
160 
161         SkTDArray<int> fSampleCounts;
162     };
163 
164     // Struct that determines and stores useful information about VkFormats.
165     struct FormatInfo {
colorTypeFlagsFormatInfo166         uint32_t colorTypeFlags(SkColorType colorType) const {
167             for (int i = 0; i < fColorTypeInfoCount; ++i) {
168                 if (fColorTypeInfos[i].fColorType == colorType) {
169                     return fColorTypeInfos[i].fFlags;
170                 }
171             }
172             return 0;
173         }
174 
175         void init(const skgpu::VulkanInterface*,
176                   VkPhysicalDevice,
177                   const VkPhysicalDeviceProperties&,
178                   VkFormat);
179 
180         bool isTexturable(VkImageTiling) const;
181         bool isRenderable(VkImageTiling, uint32_t sampleCount) const;
182         bool isStorage(VkImageTiling) const;
183         bool isTransferSrc(VkImageTiling) const;
184         bool isTransferDst(VkImageTiling) const;
185 
186         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
187         int fColorTypeInfoCount = 0;
188 
189         VkFormatProperties fFormatProperties;
190         SupportedSampleCounts fSupportedSampleCounts;
191 
192         // Indicates that a format is only supported if we are wrapping a texture with it.
193         SkDEBUGCODE(bool fIsWrappedOnly = false;)
194     };
195 
196     // Map SkColorType to VkFormat.
197     VkFormat fColorTypeToFormatTable[kSkColorTypeCnt];
198     void setColorType(SkColorType, std::initializer_list<VkFormat> formats);
199     VkFormat getFormatFromColorType(SkColorType) const;
200 
201     // Map VkFormat to FormatInfo.
202     static const size_t kNumVkFormats = 25;
203     FormatInfo fFormatTable[kNumVkFormats];
204 
205     FormatInfo& getFormatInfo(VkFormat);
206     const FormatInfo& getFormatInfo(VkFormat) const;
207 
208     // A more lightweight equivalent to FormatInfo for depth/stencil VkFormats.
209     struct DepthStencilFormatInfo {
210         void init(const skgpu::VulkanInterface*,
211                   VkPhysicalDevice,
212                   const VkPhysicalDeviceProperties&,
213                   VkFormat);
214         bool isDepthStencilSupported(VkFormatFeatureFlags) const;
215 
216         VkFormatProperties fFormatProperties;
217         SupportedSampleCounts fSupportedSampleCounts;
218     };
219 
220     // Map DepthStencilFlags to VkFormat.
221     static const size_t kNumDepthStencilFlags = 4;
222     VkFormat fDepthStencilFlagsToFormatTable[kNumDepthStencilFlags];
223     VkFormat getFormatFromDepthStencilFlags(const SkEnumBitMask<DepthStencilFlags>& flags) const;
224 
225     // Map depth/stencil VkFormats to DepthStencilFormatInfo.
226     static const size_t kNumDepthStencilVkFormats = 5;
227     DepthStencilFormatInfo fDepthStencilFormatTable[kNumDepthStencilVkFormats];
228 
229     DepthStencilFormatInfo& getDepthStencilFormatInfo(VkFormat);
230     const DepthStencilFormatInfo& getDepthStencilFormatInfo(VkFormat) const;
231 
232     uint32_t fMaxVertexAttributes;
233     uint64_t fMaxUniformBufferRange;
234     uint64_t fMaxStorageBufferRange;
235     VkPhysicalDeviceMemoryProperties2 fPhysicalDeviceMemoryProperties2;
236 
237     // ColorTypeInfo struct for use w/ external formats.
238     const ColorTypeInfo fExternalFormatColorTypeInfo = {SkColorType::kRGBA_8888_SkColorType,
239                                                         SkColorType::kRGBA_8888_SkColorType,
240                                                         /*flags=*/0,
241                                                         skgpu::Swizzle::RGBA(),
242                                                         skgpu::Swizzle::RGBA()};
243 
244     // Various bools to define whether certain Vulkan features are supported.
245     bool fSupportsMemorylessAttachments = false;
246     bool fSupportsYcbcrConversion = false;
247     bool fShouldAlwaysUseDedicatedImageMemory = false;
248     bool fGpuOnlyBuffersMorePerformant = false;
249     bool fShouldPersistentlyMapCpuToGpuBuffers = true;
250     bool fSupportsDeviceFaultInfo = false;
251 
252     // Flags to enable workarounds for driver bugs
253     bool fMustLoadFullImageForMSAA = false;
254 };
255 
256 } // namespace skgpu::graphite
257 
258 #endif // skgpu_graphite_VulkanCaps_DEFINED
259