1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#ifndef GrVkCaps_DEFINED
9cb93a386Sopenharmony_ci#define GrVkCaps_DEFINED
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkTypes.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ciclass GrShaderCaps;
15cb93a386Sopenharmony_ciclass GrVkExtensions;
16cb93a386Sopenharmony_cistruct GrVkInterface;
17cb93a386Sopenharmony_ciclass GrVkRenderTarget;
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci/**
20cb93a386Sopenharmony_ci * Stores some capabilities of a Vk backend.
21cb93a386Sopenharmony_ci */
22cb93a386Sopenharmony_ciclass GrVkCaps : public GrCaps {
23cb93a386Sopenharmony_cipublic:
24cb93a386Sopenharmony_ci    /**
25cb93a386Sopenharmony_ci     * Creates a GrVkCaps that is set such that nothing is supported. The init function should
26cb93a386Sopenharmony_ci     * be called to fill out the caps.
27cb93a386Sopenharmony_ci     */
28cb93a386Sopenharmony_ci    GrVkCaps(const GrContextOptions& contextOptions,
29cb93a386Sopenharmony_ci             const GrVkInterface* vkInterface,
30cb93a386Sopenharmony_ci             VkPhysicalDevice device,
31cb93a386Sopenharmony_ci             const VkPhysicalDeviceFeatures2& features,
32cb93a386Sopenharmony_ci             uint32_t instanceVersion,
33cb93a386Sopenharmony_ci             uint32_t physicalDeviceVersion,
34cb93a386Sopenharmony_ci             const GrVkExtensions& extensions,
35cb93a386Sopenharmony_ci             GrProtected isProtected = GrProtected::kNo);
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ci    bool isFormatSRGB(const GrBackendFormat&) const override;
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ci    bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override;
40cb93a386Sopenharmony_ci    bool isVkFormatTexturable(VkFormat) const;
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ci    bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci    bool isFormatAsColorTypeRenderable(GrColorType ct,
45cb93a386Sopenharmony_ci                                       const GrBackendFormat& format,
46cb93a386Sopenharmony_ci                                       int sampleCount = 1) const override;
47cb93a386Sopenharmony_ci    bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override;
48cb93a386Sopenharmony_ci    bool isFormatRenderable(VkFormat, int sampleCount) const;
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci    int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override;
51cb93a386Sopenharmony_ci    int getRenderTargetSampleCount(int requestedCount, VkFormat) const;
52cb93a386Sopenharmony_ci
53cb93a386Sopenharmony_ci    int maxRenderTargetSampleCount(const GrBackendFormat&) const override;
54cb93a386Sopenharmony_ci    int maxRenderTargetSampleCount(VkFormat format) const;
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ci    SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
57cb93a386Sopenharmony_ci                                                 const GrBackendFormat& surfaceFormat,
58cb93a386Sopenharmony_ci                                                 GrColorType srcColorType) const override;
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ci    SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
61cb93a386Sopenharmony_ci
62cb93a386Sopenharmony_ci    bool isVkFormatTexturableLinearly(VkFormat format) const {
63cb93a386Sopenharmony_ci        return SkToBool(FormatInfo::kTexturable_Flag & this->getFormatInfo(format).fLinearFlags);
64cb93a386Sopenharmony_ci    }
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci    bool formatCanBeDstofBlit(VkFormat format, bool linearTiled) const {
67cb93a386Sopenharmony_ci        const FormatInfo& info = this->getFormatInfo(format);
68cb93a386Sopenharmony_ci        const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags;
69cb93a386Sopenharmony_ci        return SkToBool(FormatInfo::kBlitDst_Flag & flags);
70cb93a386Sopenharmony_ci    }
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci    bool formatCanBeSrcofBlit(VkFormat format, bool linearTiled) const {
73cb93a386Sopenharmony_ci        const FormatInfo& info = this->getFormatInfo(format);
74cb93a386Sopenharmony_ci        const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags;
75cb93a386Sopenharmony_ci        return SkToBool(FormatInfo::kBlitSrc_Flag & flags);
76cb93a386Sopenharmony_ci    }
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ci    // Gets the GrColorType that should be used to transfer data in/out of a transfer buffer to
79cb93a386Sopenharmony_ci    // write/read data when using a VkFormat with a specified color type.
80cb93a386Sopenharmony_ci    GrColorType transferColorType(VkFormat, GrColorType surfaceColorType) const;
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    // On some GPUs (Windows Nvidia and Imagination) calls to QueueWaitIdle return before actually
83cb93a386Sopenharmony_ci    // signalling the fences on the command buffers even though they have completed. This causes
84cb93a386Sopenharmony_ci    // issues when then deleting the command buffers. Therefore we additionally will call
85cb93a386Sopenharmony_ci    // vkWaitForFences on each outstanding command buffer to make sure the driver signals the fence.
86cb93a386Sopenharmony_ci    bool mustSyncCommandBuffersWithQueue() const { return fMustSyncCommandBuffersWithQueue; }
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ci    // Returns true if we should always make dedicated allocations for VkImages.
89cb93a386Sopenharmony_ci    bool shouldAlwaysUseDedicatedImageMemory() const {
90cb93a386Sopenharmony_ci        return fShouldAlwaysUseDedicatedImageMemory;
91cb93a386Sopenharmony_ci    }
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci    // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer.
94cb93a386Sopenharmony_ci    bool avoidUpdateBuffers() const { return fAvoidUpdateBuffers; }
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci    /**
97cb93a386Sopenharmony_ci     * Returns both a supported and most preferred stencil format to use in draws.
98cb93a386Sopenharmony_ci     */
99cb93a386Sopenharmony_ci    VkFormat preferredStencilFormat() const { return fPreferredStencilFormat; }
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ci    // Returns total number of bits used by stencil + depth + padding
102cb93a386Sopenharmony_ci    static int GetStencilFormatTotalBitCount(VkFormat format) {
103cb93a386Sopenharmony_ci        switch (format) {
104cb93a386Sopenharmony_ci            case VK_FORMAT_S8_UINT:
105cb93a386Sopenharmony_ci                return 8;
106cb93a386Sopenharmony_ci            case VK_FORMAT_D24_UNORM_S8_UINT:
107cb93a386Sopenharmony_ci                return 32;
108cb93a386Sopenharmony_ci            case VK_FORMAT_D32_SFLOAT_S8_UINT:
109cb93a386Sopenharmony_ci                // can optionally have 24 unused bits at the end so we assume the total bits is 64.
110cb93a386Sopenharmony_ci                return 64;
111cb93a386Sopenharmony_ci            default:
112cb93a386Sopenharmony_ci                SkASSERT(false);
113cb93a386Sopenharmony_ci                return 0;
114cb93a386Sopenharmony_ci        }
115cb93a386Sopenharmony_ci    }
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci    // Returns whether the device supports VK_KHR_Swapchain. Internally Skia never uses any of the
118cb93a386Sopenharmony_ci    // swapchain functions, but we may need to transition to and from the
119cb93a386Sopenharmony_ci    // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR image layout, so we must know whether that layout is
120cb93a386Sopenharmony_ci    // supported.
121cb93a386Sopenharmony_ci    bool supportsSwapchain() const { return fSupportsSwapchain; }
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ci    // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct.
124cb93a386Sopenharmony_ci    bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; }
125cb93a386Sopenharmony_ci    // Returns whether the device supports the ability to extend VkMemoryRequirements struct.
126cb93a386Sopenharmony_ci    bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; }
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ci    // Returns whether the device supports the ability to extend the vkBindMemory call.
129cb93a386Sopenharmony_ci    bool supportsBindMemory2() const { return fSupportsBindMemory2; }
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci    // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In
132cb93a386Sopenharmony_ci    // Vulkan 1.1 all these maintenance are part of the core spec.
133cb93a386Sopenharmony_ci    bool supportsMaintenance1() const { return fSupportsMaintenance1; }
134cb93a386Sopenharmony_ci    bool supportsMaintenance2() const { return fSupportsMaintenance2; }
135cb93a386Sopenharmony_ci    bool supportsMaintenance3() const { return fSupportsMaintenance3; }
136cb93a386Sopenharmony_ci
137cb93a386Sopenharmony_ci    // Returns true if the device supports passing in a flag to say we are using dedicated GPU when
138cb93a386Sopenharmony_ci    // allocating memory. For some devices this allows them to return more optimized memory knowning
139cb93a386Sopenharmony_ci    // they will never need to suballocate amonst multiple objects.
140cb93a386Sopenharmony_ci    bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; }
141cb93a386Sopenharmony_ci
142cb93a386Sopenharmony_ci    // Returns true if the device supports importing of external memory into Vulkan memory.
143cb93a386Sopenharmony_ci    bool supportsExternalMemory() const { return fSupportsExternalMemory; }
144cb93a386Sopenharmony_ci    // Returns true if the device supports importing Android hardware buffers into Vulkan memory.
145cb93a386Sopenharmony_ci    bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; }
146cb93a386Sopenharmony_ci
147cb93a386Sopenharmony_ci    // Returns true if it supports ycbcr conversion for samplers
148cb93a386Sopenharmony_ci    bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
149cb93a386Sopenharmony_ci
150cb93a386Sopenharmony_ci    // Returns the number of descriptor slots used by immutable ycbcr VkImages.
151cb93a386Sopenharmony_ci    //
152cb93a386Sopenharmony_ci    // TODO: We should update this to return a count for a specific format or external format. We
153cb93a386Sopenharmony_ci    // can use vkGetPhysicalDeviceImageFormatProperties2 with a
154cb93a386Sopenharmony_ci    // VkSamplerYcbcrConversionImageFormatProperties to query this. However, right now that call
155cb93a386Sopenharmony_ci    // does not support external android formats which is where the majority of ycbcr images are
156cb93a386Sopenharmony_ci    // coming from. So for now we stay safe and always return 3 here which is the max value that the
157cb93a386Sopenharmony_ci    // count could be for any format.
158cb93a386Sopenharmony_ci    uint32_t ycbcrCombinedImageSamplerDescriptorCount() const {
159cb93a386Sopenharmony_ci        return 3;
160cb93a386Sopenharmony_ci    }
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_ci    // Returns true if the device supports protected memory.
163cb93a386Sopenharmony_ci    bool supportsProtectedMemory() const { return fSupportsProtectedMemory; }
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_ci    // Returns true if the VK_EXT_image_drm_format_modifier is enabled.
166cb93a386Sopenharmony_ci    bool supportsDRMFormatModifiers() const { return fSupportsDRMFormatModifiers; }
167cb93a386Sopenharmony_ci
168cb93a386Sopenharmony_ci    // Returns whether we prefer to record draws directly into a primary command buffer.
169cb93a386Sopenharmony_ci    bool preferPrimaryOverSecondaryCommandBuffers() const {
170cb93a386Sopenharmony_ci        return fPreferPrimaryOverSecondaryCommandBuffers;
171cb93a386Sopenharmony_ci    }
172cb93a386Sopenharmony_ci
173cb93a386Sopenharmony_ci    int maxPerPoolCachedSecondaryCommandBuffers() const {
174cb93a386Sopenharmony_ci        return fMaxPerPoolCachedSecondaryCommandBuffers;
175cb93a386Sopenharmony_ci    }
176cb93a386Sopenharmony_ci
177cb93a386Sopenharmony_ci    uint32_t maxInputAttachmentDescriptors() const { return fMaxInputAttachmentDescriptors; }
178cb93a386Sopenharmony_ci
179cb93a386Sopenharmony_ci    bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const {
180cb93a386Sopenharmony_ci        return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments;
181cb93a386Sopenharmony_ci    }
182cb93a386Sopenharmony_ci
183cb93a386Sopenharmony_ci    // For host visible allocations, this returns true if we require that they are coherent. This
184cb93a386Sopenharmony_ci    // is used to work around bugs for devices that don't handle non-coherent memory correctly.
185cb93a386Sopenharmony_ci    bool mustUseCoherentHostVisibleMemory() const { return fMustUseCoherentHostVisibleMemory; }
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ci    // Returns whether a pure GPU accessible buffer is more performant to read than a buffer that is
188cb93a386Sopenharmony_ci    // also host visible. If so then in some cases we may prefer the cost of doing a copy to the
189cb93a386Sopenharmony_ci    // buffer. This typically would only be the case for buffers that are written once and read
190cb93a386Sopenharmony_ci    // many times on the gpu.
191cb93a386Sopenharmony_ci    bool gpuOnlyBuffersMorePerformant() const { return fGpuOnlyBuffersMorePerformant; }
192cb93a386Sopenharmony_ci
193cb93a386Sopenharmony_ci    // For our CPU write and GPU read buffers (vertex, uniform, etc.), should we keep these buffers
194cb93a386Sopenharmony_ci    // persistently mapped. In general the answer will be yes. The main case we don't do this is
195cb93a386Sopenharmony_ci    // when using special memory that is DEVICE_LOCAL and HOST_VISIBLE on discrete GPUs.
196cb93a386Sopenharmony_ci    bool shouldPersistentlyMapCpuToGpuBuffers() const {
197cb93a386Sopenharmony_ci        return fShouldPersistentlyMapCpuToGpuBuffers;
198cb93a386Sopenharmony_ci    }
199cb93a386Sopenharmony_ci
200cb93a386Sopenharmony_ci    // The max draw count that can be passed into indirect draw calls.
201cb93a386Sopenharmony_ci    uint32_t  maxDrawIndirectDrawCount() const { return fMaxDrawIndirectDrawCount; }
202cb93a386Sopenharmony_ci
203cb93a386Sopenharmony_ci    /**
204cb93a386Sopenharmony_ci     * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
205cb93a386Sopenharmony_ci     * the surface is not a render target, otherwise it is the number of samples in the render
206cb93a386Sopenharmony_ci     * target.
207cb93a386Sopenharmony_ci     */
208cb93a386Sopenharmony_ci    bool canCopyImage(VkFormat dstFormat,
209cb93a386Sopenharmony_ci                      int dstSampleCnt,
210cb93a386Sopenharmony_ci                      bool dstHasYcbcr,
211cb93a386Sopenharmony_ci                      VkFormat srcFormat,
212cb93a386Sopenharmony_ci                      int srcSamplecnt,
213cb93a386Sopenharmony_ci                      bool srcHasYcbcr) const;
214cb93a386Sopenharmony_ci
215cb93a386Sopenharmony_ci    bool canCopyAsBlit(VkFormat dstConfig,
216cb93a386Sopenharmony_ci                       int dstSampleCnt,
217cb93a386Sopenharmony_ci                       bool dstIsLinear,
218cb93a386Sopenharmony_ci                       bool dstHasYcbcr,
219cb93a386Sopenharmony_ci                       VkFormat srcConfig,
220cb93a386Sopenharmony_ci                       int srcSampleCnt,
221cb93a386Sopenharmony_ci                       bool srcIsLinear,
222cb93a386Sopenharmony_ci                       bool srcHasYcbcr) const;
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_ci    bool canCopyAsResolve(VkFormat dstConfig,
225cb93a386Sopenharmony_ci                          int dstSampleCnt,
226cb93a386Sopenharmony_ci                          bool dstHasYcbcr,
227cb93a386Sopenharmony_ci                          VkFormat srcConfig,
228cb93a386Sopenharmony_ci                          int srcSamplecnt,
229cb93a386Sopenharmony_ci                          bool srcHasYcbcr) const;
230cb93a386Sopenharmony_ci
231cb93a386Sopenharmony_ci    GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
232cb93a386Sopenharmony_ci
233cb93a386Sopenharmony_ci    VkFormat getFormatFromColorType(GrColorType colorType) const {
234cb93a386Sopenharmony_ci        int idx = static_cast<int>(colorType);
235cb93a386Sopenharmony_ci        return fColorTypeToFormatTable[idx];
236cb93a386Sopenharmony_ci    }
237cb93a386Sopenharmony_ci
238cb93a386Sopenharmony_ci    GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override;
239cb93a386Sopenharmony_ci
240cb93a386Sopenharmony_ci    uint64_t computeFormatKey(const GrBackendFormat&) const override;
241cb93a386Sopenharmony_ci
242cb93a386Sopenharmony_ci    int getFragmentUniformBinding() const;
243cb93a386Sopenharmony_ci    int getFragmentUniformSet() const;
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_ci    void addExtraSamplerKey(GrProcessorKeyBuilder*,
246cb93a386Sopenharmony_ci                            GrSamplerState,
247cb93a386Sopenharmony_ci                            const GrBackendFormat&) const override;
248cb93a386Sopenharmony_ci
249cb93a386Sopenharmony_ci    GrProgramDesc makeDesc(GrRenderTarget*,
250cb93a386Sopenharmony_ci                           const GrProgramInfo&,
251cb93a386Sopenharmony_ci                           ProgramDescOverrideFlags) const override;
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_ci    GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const override;
254cb93a386Sopenharmony_ci
255cb93a386Sopenharmony_ci    VkShaderStageFlags getPushConstantStageFlags() const;
256cb93a386Sopenharmony_ci
257cb93a386Sopenharmony_ci    // If true then when doing MSAA draws, we will prefer to discard the msaa attachment on load
258cb93a386Sopenharmony_ci    // and stores. The use of this feature for specific draws depends on the render target having a
259cb93a386Sopenharmony_ci    // resolve attachment, and if we need to load previous data the resolve attachment must be
260cb93a386Sopenharmony_ci    // usable as an input attachment. Otherwise we will just write out and store the msaa attachment
261cb93a386Sopenharmony_ci    // like normal.
262cb93a386Sopenharmony_ci    // This flag is similar to enabling gl render to texture for msaa rendering.
263cb93a386Sopenharmony_ci    bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; }
264cb93a386Sopenharmony_ci    bool mustLoadFullImageWithDiscardableMSAA() const {
265cb93a386Sopenharmony_ci        return fMustLoadFullImageWithDiscardableMSAA;
266cb93a386Sopenharmony_ci    }
267cb93a386Sopenharmony_ci    bool supportsDiscardableMSAAForDMSAA() const { return fSupportsDiscardableMSAAForDMSAA; }
268cb93a386Sopenharmony_ci    bool renderTargetSupportsDiscardableMSAA(const GrVkRenderTarget*) const;
269cb93a386Sopenharmony_ci    bool programInfoWillUseDiscardableMSAA(const GrProgramInfo&) const;
270cb93a386Sopenharmony_ci
271cb93a386Sopenharmony_ci    bool dmsaaResolveCanBeUsedAsTextureInSameRenderPass() const override { return false; }
272cb93a386Sopenharmony_ci
273cb93a386Sopenharmony_ci    bool supportsMemorylessAttachments() const { return fSupportsMemorylessAttachments; }
274cb93a386Sopenharmony_ci
275cb93a386Sopenharmony_ci    bool supportsHpsBlur(const GrSurfaceProxyView* proxyViewPtr) const override;
276cb93a386Sopenharmony_ci
277cb93a386Sopenharmony_ci#if GR_TEST_UTILS
278cb93a386Sopenharmony_ci    std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
279cb93a386Sopenharmony_ci#endif
280cb93a386Sopenharmony_ci
281cb93a386Sopenharmony_ciprivate:
282cb93a386Sopenharmony_ci    enum VkVendor {
283cb93a386Sopenharmony_ci        kAMD_VkVendor = 4098,
284cb93a386Sopenharmony_ci        kARM_VkVendor = 5045,
285cb93a386Sopenharmony_ci        kHisi_VkVendor = 6629,
286cb93a386Sopenharmony_ci        kImagination_VkVendor = 4112,
287cb93a386Sopenharmony_ci        kIntel_VkVendor = 32902,
288cb93a386Sopenharmony_ci        kNvidia_VkVendor = 4318,
289cb93a386Sopenharmony_ci        kQualcomm_VkVendor = 20803,
290cb93a386Sopenharmony_ci    };
291cb93a386Sopenharmony_ci
292cb93a386Sopenharmony_ci    void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
293cb93a386Sopenharmony_ci              VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&,
294cb93a386Sopenharmony_ci              uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected);
295cb93a386Sopenharmony_ci    void initGrCaps(const GrVkInterface* vkInterface,
296cb93a386Sopenharmony_ci                    VkPhysicalDevice physDev,
297cb93a386Sopenharmony_ci                    const VkPhysicalDeviceProperties&,
298cb93a386Sopenharmony_ci                    const VkPhysicalDeviceMemoryProperties&,
299cb93a386Sopenharmony_ci                    const VkPhysicalDeviceFeatures2&,
300cb93a386Sopenharmony_ci                    const GrVkExtensions&);
301cb93a386Sopenharmony_ci    void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&);
302cb93a386Sopenharmony_ci
303cb93a386Sopenharmony_ci    void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
304cb93a386Sopenharmony_ci    void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
305cb93a386Sopenharmony_ci
306cb93a386Sopenharmony_ci    void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
307cb93a386Sopenharmony_ci
308cb93a386Sopenharmony_ci    bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
309cb93a386Sopenharmony_ci    bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
310cb93a386Sopenharmony_ci                          const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
311cb93a386Sopenharmony_ci    GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override;
312cb93a386Sopenharmony_ci
313cb93a386Sopenharmony_ci    bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
314cb93a386Sopenharmony_ci
315cb93a386Sopenharmony_ci    SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
316cb93a386Sopenharmony_ci                                                 GrColorType) const override;
317cb93a386Sopenharmony_ci
318cb93a386Sopenharmony_ci    GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
319cb93a386Sopenharmony_ci
320cb93a386Sopenharmony_ci    GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const override;
321cb93a386Sopenharmony_ci
322cb93a386Sopenharmony_ci    bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const override;
323cb93a386Sopenharmony_ci
324cb93a386Sopenharmony_ci    // ColorTypeInfo for a specific format
325cb93a386Sopenharmony_ci    struct ColorTypeInfo {
326cb93a386Sopenharmony_ci        GrColorType fColorType = GrColorType::kUnknown;
327cb93a386Sopenharmony_ci        GrColorType fTransferColorType = GrColorType::kUnknown;
328cb93a386Sopenharmony_ci        enum {
329cb93a386Sopenharmony_ci            kUploadData_Flag = 0x1,
330cb93a386Sopenharmony_ci            // Does Ganesh itself support rendering to this colorType & format pair. Renderability
331cb93a386Sopenharmony_ci            // still additionally depends on if the format itself is renderable.
332cb93a386Sopenharmony_ci            kRenderable_Flag = 0x2,
333cb93a386Sopenharmony_ci            // Indicates that this colorType is supported only if we are wrapping a texture with
334cb93a386Sopenharmony_ci            // the given format and colorType. We do not allow creation with this pair.
335cb93a386Sopenharmony_ci            kWrappedOnly_Flag = 0x4,
336cb93a386Sopenharmony_ci        };
337cb93a386Sopenharmony_ci        uint32_t fFlags = 0;
338cb93a386Sopenharmony_ci
339cb93a386Sopenharmony_ci        GrSwizzle fReadSwizzle;
340cb93a386Sopenharmony_ci        GrSwizzle fWriteSwizzle;
341cb93a386Sopenharmony_ci    };
342cb93a386Sopenharmony_ci
343cb93a386Sopenharmony_ci    struct FormatInfo {
344cb93a386Sopenharmony_ci        uint32_t colorTypeFlags(GrColorType colorType) const {
345cb93a386Sopenharmony_ci            for (int i = 0; i < fColorTypeInfoCount; ++i) {
346cb93a386Sopenharmony_ci                if (fColorTypeInfos[i].fColorType == colorType) {
347cb93a386Sopenharmony_ci                    return fColorTypeInfos[i].fFlags;
348cb93a386Sopenharmony_ci                }
349cb93a386Sopenharmony_ci            }
350cb93a386Sopenharmony_ci            return 0;
351cb93a386Sopenharmony_ci        }
352cb93a386Sopenharmony_ci
353cb93a386Sopenharmony_ci        void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
354cb93a386Sopenharmony_ci                  VkFormat);
355cb93a386Sopenharmony_ci        static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags);
356cb93a386Sopenharmony_ci        void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
357cb93a386Sopenharmony_ci                              const VkPhysicalDeviceProperties&, VkFormat);
358cb93a386Sopenharmony_ci
359cb93a386Sopenharmony_ci        enum {
360cb93a386Sopenharmony_ci            kTexturable_Flag = 0x1,
361cb93a386Sopenharmony_ci            kRenderable_Flag = 0x2,
362cb93a386Sopenharmony_ci            kBlitSrc_Flag    = 0x4,
363cb93a386Sopenharmony_ci            kBlitDst_Flag    = 0x8,
364cb93a386Sopenharmony_ci        };
365cb93a386Sopenharmony_ci
366cb93a386Sopenharmony_ci        uint16_t fOptimalFlags = 0;
367cb93a386Sopenharmony_ci        uint16_t fLinearFlags = 0;
368cb93a386Sopenharmony_ci
369cb93a386Sopenharmony_ci        SkTDArray<int> fColorSampleCounts;
370cb93a386Sopenharmony_ci
371cb93a386Sopenharmony_ci        std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
372cb93a386Sopenharmony_ci        int fColorTypeInfoCount = 0;
373cb93a386Sopenharmony_ci    };
374cb93a386Sopenharmony_ci    static const size_t kNumVkFormats = 25;
375cb93a386Sopenharmony_ci    FormatInfo fFormatTable[kNumVkFormats];
376cb93a386Sopenharmony_ci
377cb93a386Sopenharmony_ci    FormatInfo& getFormatInfo(VkFormat);
378cb93a386Sopenharmony_ci    const FormatInfo& getFormatInfo(VkFormat) const;
379cb93a386Sopenharmony_ci
380cb93a386Sopenharmony_ci    VkFormat fColorTypeToFormatTable[kGrColorTypeCnt];
381cb93a386Sopenharmony_ci    void setColorType(GrColorType, std::initializer_list<VkFormat> formats);
382cb93a386Sopenharmony_ci
383cb93a386Sopenharmony_ci    VkFormat fPreferredStencilFormat;
384cb93a386Sopenharmony_ci
385cb93a386Sopenharmony_ci    SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos;
386cb93a386Sopenharmony_ci
387cb93a386Sopenharmony_ci    bool fMustSyncCommandBuffersWithQueue = false;
388cb93a386Sopenharmony_ci    bool fShouldAlwaysUseDedicatedImageMemory = false;
389cb93a386Sopenharmony_ci
390cb93a386Sopenharmony_ci    bool fAvoidUpdateBuffers = false;
391cb93a386Sopenharmony_ci
392cb93a386Sopenharmony_ci    bool fSupportsSwapchain = false;
393cb93a386Sopenharmony_ci
394cb93a386Sopenharmony_ci    bool fSupportsPhysicalDeviceProperties2 = false;
395cb93a386Sopenharmony_ci    bool fSupportsMemoryRequirements2 = false;
396cb93a386Sopenharmony_ci    bool fSupportsBindMemory2 = false;
397cb93a386Sopenharmony_ci    bool fSupportsMaintenance1 = false;
398cb93a386Sopenharmony_ci    bool fSupportsMaintenance2 = false;
399cb93a386Sopenharmony_ci    bool fSupportsMaintenance3 = false;
400cb93a386Sopenharmony_ci
401cb93a386Sopenharmony_ci    bool fSupportsDedicatedAllocation = false;
402cb93a386Sopenharmony_ci    bool fSupportsExternalMemory = false;
403cb93a386Sopenharmony_ci    bool fSupportsAndroidHWBExternalMemory = false;
404cb93a386Sopenharmony_ci
405cb93a386Sopenharmony_ci    bool fSupportsYcbcrConversion = false;
406cb93a386Sopenharmony_ci
407cb93a386Sopenharmony_ci    bool fSupportsProtectedMemory = false;
408cb93a386Sopenharmony_ci
409cb93a386Sopenharmony_ci    bool fSupportsDRMFormatModifiers = false;
410cb93a386Sopenharmony_ci
411cb93a386Sopenharmony_ci    bool fPreferPrimaryOverSecondaryCommandBuffers = true;
412cb93a386Sopenharmony_ci    bool fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = false;
413cb93a386Sopenharmony_ci
414cb93a386Sopenharmony_ci    bool fMustUseCoherentHostVisibleMemory = false;
415cb93a386Sopenharmony_ci    bool fGpuOnlyBuffersMorePerformant = false;
416cb93a386Sopenharmony_ci    bool fShouldPersistentlyMapCpuToGpuBuffers = true;
417cb93a386Sopenharmony_ci
418cb93a386Sopenharmony_ci    // We default this to 100 since we already cap the max render tasks at 100 before doing a
419cb93a386Sopenharmony_ci    // submission in the GrDrawingManager, so we shouldn't be going over 100 secondary command
420cb93a386Sopenharmony_ci    // buffers per primary anyways.
421cb93a386Sopenharmony_ci    int fMaxPerPoolCachedSecondaryCommandBuffers = 100;
422cb93a386Sopenharmony_ci
423cb93a386Sopenharmony_ci    uint32_t fMaxInputAttachmentDescriptors = 0;
424cb93a386Sopenharmony_ci
425cb93a386Sopenharmony_ci    bool fPreferDiscardableMSAAAttachment = false;
426cb93a386Sopenharmony_ci    bool fMustLoadFullImageWithDiscardableMSAA = false;
427cb93a386Sopenharmony_ci    bool fSupportsDiscardableMSAAForDMSAA = true;
428cb93a386Sopenharmony_ci    bool fSupportsMemorylessAttachments = false;
429cb93a386Sopenharmony_ci
430cb93a386Sopenharmony_ci    bool fSupportHpsBlur = false;
431cb93a386Sopenharmony_ci
432cb93a386Sopenharmony_ci    uint32_t fMaxDrawIndirectDrawCount = 0;
433cb93a386Sopenharmony_ci
434cb93a386Sopenharmony_ci    using INHERITED = GrCaps;
435cb93a386Sopenharmony_ci};
436cb93a386Sopenharmony_ci
437cb93a386Sopenharmony_ci#endif
438