• 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(sk_sp<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 isRenderable(const TextureInfo&) const override;
63     bool isStorage(const TextureInfo&) const override;
64 
65     void buildKeyForTexture(SkISize dimensions,
66                             const TextureInfo&,
67                             ResourceType,
68                             Shareable,
69                             GraphiteResourceKey*) const override;
70 
shouldAlwaysUseDedicatedImageMemory()71     bool shouldAlwaysUseDedicatedImageMemory() const {
72         return fShouldAlwaysUseDedicatedImageMemory;
73     }
74 
75     // Returns whether a pure GPU accessible buffer is more performant to read than a buffer that is
76     // also host visible. If so then in some cases we may prefer the cost of doing a copy to the
77     // buffer. This typically would only be the case for buffers that are written once and read
78     // many times on the gpu.
gpuOnlyBuffersMorePerformant()79     bool gpuOnlyBuffersMorePerformant() const { return fGpuOnlyBuffersMorePerformant; }
80 
81     // For our CPU write and GPU read buffers (vertex, uniform, etc.), we should keep these buffers
82     // persistently mapped. In general, the answer will be yes. The main case where we don't do this
83     // is when using special memory that is DEVICE_LOCAL and HOST_VISIBLE on discrete GPUs.
shouldPersistentlyMapCpuToGpuBuffers()84     bool shouldPersistentlyMapCpuToGpuBuffers() const {
85         return fShouldPersistentlyMapCpuToGpuBuffers;
86     }
87 
supportsYcbcrConversion()88     bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
89 
supportsDeviceFaultInfo()90     bool supportsDeviceFaultInfo() const { return fSupportsDeviceFaultInfo; }
91 
maxVertexAttributes()92     uint32_t maxVertexAttributes() const {
93         return fMaxVertexAttributes;
94     }
maxUniformBufferRange()95     uint64_t maxUniformBufferRange() const { return fMaxUniformBufferRange; }
96 
physicalDeviceMemoryProperties2()97     const VkPhysicalDeviceMemoryProperties2& physicalDeviceMemoryProperties2() const {
98         return fPhysicalDeviceMemoryProperties2;
99     }
100 
101     bool isTransferSrc(const VulkanTextureInfo&) const;
102     bool isTransferDst(const VulkanTextureInfo&) const;
103 
104 private:
105     enum VkVendor {
106         kAMD_VkVendor             = 4098,
107         kARM_VkVendor             = 5045,
108         kImagination_VkVendor     = 4112,
109         kIntel_VkVendor           = 32902,
110         kNvidia_VkVendor          = 4318,
111         kQualcomm_VkVendor        = 20803,
112     };
113 
114     void init(const ContextOptions&,
115               const skgpu::VulkanInterface*,
116               VkPhysicalDevice,
117               uint32_t physicalDeviceVersion,
118               const VkPhysicalDeviceFeatures2*,
119               const skgpu::VulkanExtensions*,
120               Protected);
121 
122     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
123 
124     void initFormatTable(const skgpu::VulkanInterface*,
125                          VkPhysicalDevice,
126                          const VkPhysicalDeviceProperties&);
127 
128     void initDepthStencilFormatTable(const skgpu::VulkanInterface*,
129                                      VkPhysicalDevice,
130                                      const VkPhysicalDeviceProperties&);
131 
132     const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const override;
133 
134     bool onIsTexturable(const TextureInfo&) const override;
135 
136     bool supportsWritePixels(const TextureInfo&) const override;
137     bool supportsReadPixels(const TextureInfo&) const override;
138 
139     std::pair<SkColorType, bool /*isRGBFormat*/> supportedWritePixelsColorType(
140             SkColorType dstColorType,
141             const TextureInfo& dstTextureInfo,
142             SkColorType srcColorType) const override;
143     std::pair<SkColorType, bool /*isRGBFormat*/> supportedReadPixelsColorType(
144             SkColorType srcColorType,
145             const TextureInfo& srcTextureInfo,
146             SkColorType dstColorType) const override;
147 
148     // Struct that determines and stores which sample count quantities a VkFormat supports.
149     struct SupportedSampleCounts {
150         void initSampleCounts(const skgpu::VulkanInterface*,
151                               VkPhysicalDevice,
152                               const VkPhysicalDeviceProperties&,
153                               VkFormat,
154                               VkImageUsageFlags);
155 
156         bool isSampleCountSupported(int requestedCount) const;
157 
158         SkTDArray<int> fSampleCounts;
159     };
160 
161     // Struct that determines and stores useful information about VkFormats.
162     struct FormatInfo {
colorTypeFlagsFormatInfo163         uint32_t colorTypeFlags(SkColorType colorType) const {
164             for (int i = 0; i < fColorTypeInfoCount; ++i) {
165                 if (fColorTypeInfos[i].fColorType == colorType) {
166                     return fColorTypeInfos[i].fFlags;
167                 }
168             }
169             return 0;
170         }
171 
172         void init(const skgpu::VulkanInterface*,
173                   VkPhysicalDevice,
174                   const VkPhysicalDeviceProperties&,
175                   VkFormat);
176 
177         bool isTexturable(VkImageTiling) const;
178         bool isRenderable(VkImageTiling, uint32_t sampleCount) const;
179         bool isStorage(VkImageTiling) const;
180         bool isTransferSrc(VkImageTiling) const;
181         bool isTransferDst(VkImageTiling) const;
182 
183         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
184         int fColorTypeInfoCount = 0;
185 
186         VkFormatProperties fFormatProperties;
187         SupportedSampleCounts fSupportedSampleCounts;
188 
189         // Indicates that a format is only supported if we are wrapping a texture with it.
190         SkDEBUGCODE(bool fIsWrappedOnly = false;)
191     };
192 
193     // Map SkColorType to VkFormat.
194     VkFormat fColorTypeToFormatTable[kSkColorTypeCnt];
195     void setColorType(SkColorType, std::initializer_list<VkFormat> formats);
196     VkFormat getFormatFromColorType(SkColorType) const;
197 
198     // Map VkFormat to FormatInfo.
199     static const size_t kNumVkFormats = 22;
200     FormatInfo fFormatTable[kNumVkFormats];
201 
202     FormatInfo& getFormatInfo(VkFormat);
203     const FormatInfo& getFormatInfo(VkFormat) const;
204 
205     // A more lightweight equivalent to FormatInfo for depth/stencil VkFormats.
206     struct DepthStencilFormatInfo {
207         void init(const skgpu::VulkanInterface*,
208                   VkPhysicalDevice,
209                   const VkPhysicalDeviceProperties&,
210                   VkFormat);
211         bool isDepthStencilSupported(VkFormatFeatureFlags) const;
212 
213         VkFormatProperties fFormatProperties;
214         SupportedSampleCounts fSupportedSampleCounts;
215     };
216 
217     // Map DepthStencilFlags to VkFormat.
218     static const size_t kNumDepthStencilFlags = 4;
219     VkFormat fDepthStencilFlagsToFormatTable[kNumDepthStencilFlags];
220     VkFormat getFormatFromDepthStencilFlags(const SkEnumBitMask<DepthStencilFlags>& flags) const;
221 
222     // Map depth/stencil VkFormats to DepthStencilFormatInfo.
223     static const size_t kNumDepthStencilVkFormats = 5;
224     DepthStencilFormatInfo fDepthStencilFormatTable[kNumDepthStencilVkFormats];
225 
226     DepthStencilFormatInfo& getDepthStencilFormatInfo(VkFormat);
227     const DepthStencilFormatInfo& getDepthStencilFormatInfo(VkFormat) const;
228 
229     uint32_t fMaxVertexAttributes;
230     uint64_t fMaxUniformBufferRange;
231     VkPhysicalDeviceMemoryProperties2 fPhysicalDeviceMemoryProperties2;
232 
233     // ColorTypeInfo struct for use w/ external formats.
234     const ColorTypeInfo fExternalFormatColorTypeInfo = {SkColorType::kRGBA_8888_SkColorType,
235                                                         SkColorType::kRGBA_8888_SkColorType,
236                                                         /*flags=*/0,
237                                                         skgpu::Swizzle::RGBA(),
238                                                         skgpu::Swizzle::RGBA()};
239 
240     // Various bools to define whether certain Vulkan features are supported.
241     bool fSupportsMemorylessAttachments = false;
242     bool fSupportsYcbcrConversion = false;
243     bool fShouldAlwaysUseDedicatedImageMemory = false;
244     bool fGpuOnlyBuffersMorePerformant = false;
245     bool fShouldPersistentlyMapCpuToGpuBuffers = true;
246     bool fSupportsDeviceFaultInfo = false;
247 };
248 
249 } // namespace skgpu::graphite
250 
251 #endif // skgpu_graphite_VulkanCaps_DEFINED
252