• 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 
19 class VulkanCaps final : public Caps {
20 public:
21     VulkanCaps(const skgpu::VulkanInterface*,
22                VkPhysicalDevice device,
23                uint32_t physicalDeviceVersion,
24                const skgpu::VulkanExtensions*,
25                const ContextOptions&);
26     ~VulkanCaps() override;
27 
28     TextureInfo getDefaultSampledTextureInfo(SkColorType,
29                                              Mipmapped mipmapped,
30                                              Protected,
31                                              Renderable) const override;
32 
33     TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo,
34                                           Discardable discardable) const override;
35 
36     TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags>,
37                                                   uint32_t sampleCount,
38                                                   Protected) const override;
39 
makeGraphicsPipelineKey(const GraphicsPipelineDesc &,const RenderPassDesc &)40     UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&,
41                                       const RenderPassDesc&) const override { return {}; }
makeComputePipelineKey(const ComputePipelineDesc &)42     UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const override { return {}; }
43 
isRenderable(const TextureInfo &)44     bool isRenderable(const TextureInfo&) const override { return false; }
45 
buildKeyForTexture(SkISize dimensions,const TextureInfo &,ResourceType,Shareable,GraphiteResourceKey *)46     void buildKeyForTexture(SkISize dimensions,
47                             const TextureInfo&,
48                             ResourceType,
49                             Shareable,
50                             GraphiteResourceKey*) const override {}
51 
shouldAlwaysUseDedicatedImageMemory()52     bool shouldAlwaysUseDedicatedImageMemory() const {
53         return fShouldAlwaysUseDedicatedImageMemory;
54     }
55 
56     // Returns whether a pure GPU accessible buffer is more performant to read than a buffer that is
57     // also host visible. If so then in some cases we may prefer the cost of doing a copy to the
58     // buffer. This typically would only be the case for buffers that are written once and read
59     // many times on the gpu.
gpuOnlyBuffersMorePerformant()60     bool gpuOnlyBuffersMorePerformant() const { return fGpuOnlyBuffersMorePerformant; }
61 
62     // For our CPU write and GPU read buffers (vertex, uniform, etc.), we should keep these buffers
63     // persistently mapped. In general, the answer will be yes. The main case where we don't do this
64     // is when using special memory that is DEVICE_LOCAL and HOST_VISIBLE on discrete GPUs.
shouldPersistentlyMapCpuToGpuBuffers()65     bool shouldPersistentlyMapCpuToGpuBuffers() const {
66         return fShouldPersistentlyMapCpuToGpuBuffers;
67     }
68 
69 private:
70     enum VkVendor {
71         kAMD_VkVendor             = 4098,
72         kARM_VkVendor             = 5045,
73         kImagination_VkVendor     = 4112,
74         kIntel_VkVendor           = 32902,
75         kNvidia_VkVendor          = 4318,
76         kQualcomm_VkVendor        = 20803,
77     };
78 
79     void init(const skgpu::VulkanInterface*,
80               VkPhysicalDevice,
81               uint32_t physicalDeviceVersion,
82               const skgpu::VulkanExtensions*,
83               const ContextOptions&);
84 
85     void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
86 
87     void initFormatTable(const skgpu::VulkanInterface*,
88                          VkPhysicalDevice,
89                          const VkPhysicalDeviceProperties&);
90 
91     void initDepthStencilFormatTable(const skgpu::VulkanInterface*,
92                                      VkPhysicalDevice,
93                                      const VkPhysicalDeviceProperties&);
94 
getColorTypeInfo(SkColorType,const TextureInfo &)95     const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const override {
96         return nullptr;
97     }
98 
onIsTexturable(const TextureInfo &)99     bool onIsTexturable(const TextureInfo&) const override { return false; }
100 
supportsWritePixels(const TextureInfo &)101     bool supportsWritePixels(const TextureInfo&) const override { return false; }
supportsReadPixels(const TextureInfo &)102     bool supportsReadPixels(const TextureInfo&) const override { return false; }
103 
supportedWritePixelsColorType(SkColorType dstColorType,const TextureInfo & dstTextureInfo,SkColorType srcColorType)104     SkColorType supportedWritePixelsColorType(SkColorType dstColorType,
105                                               const TextureInfo& dstTextureInfo,
106                                               SkColorType srcColorType) const override {
107         return kUnknown_SkColorType;
108     }
supportedReadPixelsColorType(SkColorType srcColorType,const TextureInfo & srcTextureInfo,SkColorType dstColorType)109     SkColorType supportedReadPixelsColorType(SkColorType srcColorType,
110                                              const TextureInfo& srcTextureInfo,
111                                              SkColorType dstColorType) const override {
112         return kUnknown_SkColorType;
113     }
114     // Struct that determines and stores which sample count quantities a VkFormat supports.
115     struct SupportedSampleCounts {
116         void initSampleCounts(const skgpu::VulkanInterface*,
117                               VkPhysicalDevice,
118                               const VkPhysicalDeviceProperties&,
119                               VkFormat,
120                               VkImageUsageFlags);
121 
122         bool isSampleCountSupported(int requestedCount) const;
123 
124         SkTDArray<int> fSampleCounts;
125     };
126 
127     // Struct that determines and stores useful information about VkFormats.
128     struct FormatInfo {
colorTypeFlagsFormatInfo129         uint32_t colorTypeFlags(SkColorType colorType) const {
130             for (int i = 0; i < fColorTypeInfoCount; ++i) {
131                 if (fColorTypeInfos[i].fColorType == colorType) {
132                     return fColorTypeInfos[i].fFlags;
133                 }
134             }
135             return 0;
136         }
137 
138         void init(const skgpu::VulkanInterface*,
139                   VkPhysicalDevice,
140                   const VkPhysicalDeviceProperties&,
141                   VkFormat);
142 
143 
144         bool isTexturable(VkImageTiling) const;
145         bool isRenderable(VkImageTiling, uint32_t sampleCount) const;
146 
147         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
148         int fColorTypeInfoCount = 0;
149 
150         VkFormatProperties fFormatProperties;
151         SupportedSampleCounts fSupportedSampleCounts;
152 
153         // Indicates that a format is only supported if we are wrapping a texture with it.
154         SkDEBUGCODE(bool fIsWrappedOnly;)
155 
156     private:
157         bool isTexturable(VkFormatFeatureFlags) const;
158         bool isRenderable(VkFormatFeatureFlags) const;
159     };
160 
161     // Map SkColorType to VkFormat.
162     VkFormat fColorTypeToFormatTable[kSkColorTypeCnt];
163     void setColorType(SkColorType, std::initializer_list<VkFormat> formats);
164     VkFormat getFormatFromColorType(SkColorType) const;
165 
166     // Map VkFormat to FormatInfo.
167     static const size_t kNumVkFormats = 22;
168     FormatInfo fFormatTable[kNumVkFormats];
169 
170     FormatInfo& getFormatInfo(VkFormat);
171     const FormatInfo& getFormatInfo(VkFormat) const;
172 
173     // A more lightweight equivalent to FormatInfo for depth/stencil VkFormats.
174     struct DepthStencilFormatInfo {
175         void init(const skgpu::VulkanInterface*,
176                   VkPhysicalDevice,
177                   const VkPhysicalDeviceProperties&,
178                   VkFormat);
179         bool isDepthStencilSupported(VkFormatFeatureFlags) const;
180 
181         VkFormatProperties fFormatProperties;
182         SupportedSampleCounts fSupportedSampleCounts;
183     };
184 
185     // Map DepthStencilFlags to VkFormat.
186     static const size_t kNumDepthStencilFlags = 4;
187     VkFormat fDepthStencilFlagsToFormatTable[kNumDepthStencilFlags];
188     VkFormat getFormatFromDepthStencilFlags(const SkEnumBitMask<DepthStencilFlags>& flags) const;
189 
190     // Map depth/stencil VkFormats to DepthStencilFormatInfo.
191     static const size_t kNumDepthStencilVkFormats = 3;
192     DepthStencilFormatInfo fDepthStencilFormatTable[kNumDepthStencilVkFormats];
193 
194     DepthStencilFormatInfo& getDepthStencilFormatInfo(VkFormat);
195     const DepthStencilFormatInfo& getDepthStencilFormatInfo(VkFormat) const;
196 
197     // Various bools to define whether certain Vulkan features are supported.
198     bool fSupportsMemorylessAttachments = false;
199     bool fSupportsYcbcrConversion = false; // TODO: Determine & assign real value.
200     bool fShouldAlwaysUseDedicatedImageMemory = false;
201     bool fGpuOnlyBuffersMorePerformant = false;
202     bool fShouldPersistentlyMapCpuToGpuBuffers = true;
203 };
204 
205 } // namespace skgpu::graphite
206 
207 #endif // skgpu_graphite_VulkanCaps_DEFINED
208