1cb93a386Sopenharmony_ci
2cb93a386Sopenharmony_ci/*
3cb93a386Sopenharmony_ci * Copyright 2020 Google LLC
4cb93a386Sopenharmony_ci *
5cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
6cb93a386Sopenharmony_ci * found in the LICENSE file.
7cb93a386Sopenharmony_ci */
8cb93a386Sopenharmony_ci
9cb93a386Sopenharmony_ci#ifndef GrD3DCaps_DEFINED
10cb93a386Sopenharmony_ci#define GrD3DCaps_DEFINED
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ci#include "include/gpu/d3d/GrD3DTypes.h"
15cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DAttachment.h"
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_ciclass GrShaderCaps;
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci/**
20cb93a386Sopenharmony_ci * Stores some capabilities of a D3D backend.
21cb93a386Sopenharmony_ci */
22cb93a386Sopenharmony_ciclass GrD3DCaps : public GrCaps {
23cb93a386Sopenharmony_cipublic:
24cb93a386Sopenharmony_ci    /**
25cb93a386Sopenharmony_ci     * Creates a GrD3DCaps 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    GrD3DCaps(const GrContextOptions& contextOptions, IDXGIAdapter1*, ID3D12Device*);
29cb93a386Sopenharmony_ci
30cb93a386Sopenharmony_ci    bool isFormatSRGB(const GrBackendFormat&) const override;
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci    bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override;
33cb93a386Sopenharmony_ci    bool isFormatTexturable(DXGI_FORMAT) const;
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci    bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ci    bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
38cb93a386Sopenharmony_ci                                       int sampleCount = 1) const override;
39cb93a386Sopenharmony_ci    bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override;
40cb93a386Sopenharmony_ci    bool isFormatRenderable(DXGI_FORMAT, int sampleCount) const;
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ci    bool isFormatUnorderedAccessible(DXGI_FORMAT) const;
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci    int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override;
45cb93a386Sopenharmony_ci    int getRenderTargetSampleCount(int requestedCount, DXGI_FORMAT) const;
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ci    int maxRenderTargetSampleCount(const GrBackendFormat&) const override;
48cb93a386Sopenharmony_ci    int maxRenderTargetSampleCount(DXGI_FORMAT) const;
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci    GrColorType getFormatColorType(DXGI_FORMAT) const;
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ci    SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
53cb93a386Sopenharmony_ci                                                 const GrBackendFormat& surfaceFormat,
54cb93a386Sopenharmony_ci                                                 GrColorType srcColorType) const override;
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ci    SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ci    /**
59cb93a386Sopenharmony_ci     * Returns both a supported and most preferred stencil format to use in draws.
60cb93a386Sopenharmony_ci     */
61cb93a386Sopenharmony_ci    DXGI_FORMAT preferredStencilFormat() const {
62cb93a386Sopenharmony_ci        return fPreferredStencilFormat;
63cb93a386Sopenharmony_ci    }
64cb93a386Sopenharmony_ci    static int GetStencilFormatTotalBitCount(DXGI_FORMAT format) {
65cb93a386Sopenharmony_ci        switch (format) {
66cb93a386Sopenharmony_ci        case DXGI_FORMAT_D24_UNORM_S8_UINT:
67cb93a386Sopenharmony_ci            return 32;
68cb93a386Sopenharmony_ci        case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
69cb93a386Sopenharmony_ci            // DXGI_FORMAT_D32_FLOAT_S8X24_UINT has 24 unused bits at the end so total bits is 64.
70cb93a386Sopenharmony_ci            return 64;
71cb93a386Sopenharmony_ci        default:
72cb93a386Sopenharmony_ci            SkASSERT(false);
73cb93a386Sopenharmony_ci            return 0;
74cb93a386Sopenharmony_ci        }
75cb93a386Sopenharmony_ci    }
76cb93a386Sopenharmony_ci
77cb93a386Sopenharmony_ci    /**
78cb93a386Sopenharmony_ci     * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
79cb93a386Sopenharmony_ci     * the surface is not a render target, otherwise it is the number of samples in the render
80cb93a386Sopenharmony_ci     * target.
81cb93a386Sopenharmony_ci     */
82cb93a386Sopenharmony_ci    bool canCopyTexture(DXGI_FORMAT dstFormat, int dstSampleCnt,
83cb93a386Sopenharmony_ci                        DXGI_FORMAT srcFormat, int srcSamplecnt) const;
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci    bool canCopyAsResolve(DXGI_FORMAT dstFormat, int dstSampleCnt,
86cb93a386Sopenharmony_ci                          DXGI_FORMAT srcFormat, int srcSamplecnt) const;
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ci    GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci    DXGI_FORMAT getFormatFromColorType(GrColorType colorType) const {
91cb93a386Sopenharmony_ci        int idx = static_cast<int>(colorType);
92cb93a386Sopenharmony_ci        return fColorTypeToFormatTable[idx];
93cb93a386Sopenharmony_ci    }
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci    GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override;
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci    uint64_t computeFormatKey(const GrBackendFormat&) const override;
98cb93a386Sopenharmony_ci
99cb93a386Sopenharmony_ci    void addExtraSamplerKey(GrProcessorKeyBuilder*,
100cb93a386Sopenharmony_ci                            GrSamplerState,
101cb93a386Sopenharmony_ci                            const GrBackendFormat&) const override;
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci    GrProgramDesc makeDesc(GrRenderTarget*,
104cb93a386Sopenharmony_ci                           const GrProgramInfo&,
105cb93a386Sopenharmony_ci                           ProgramDescOverrideFlags) const override;
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ci    bool resolveSubresourceRegionSupport() const { return fResolveSubresourceRegionSupport; }
108cb93a386Sopenharmony_ci    bool standardSwizzleLayoutSupport() const { return fStandardSwizzleLayoutSupport; }
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci#if GR_TEST_UTILS
111cb93a386Sopenharmony_ci    std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
112cb93a386Sopenharmony_ci#endif
113cb93a386Sopenharmony_ci
114cb93a386Sopenharmony_ciprivate:
115cb93a386Sopenharmony_ci    enum D3DVendor {
116cb93a386Sopenharmony_ci        kAMD_D3DVendor = 0x1002,
117cb93a386Sopenharmony_ci        kARM_D3DVendor = 0x13B5,
118cb93a386Sopenharmony_ci        kImagination_D3DVendor = 0x1010,
119cb93a386Sopenharmony_ci        kIntel_D3DVendor = 0x8086,
120cb93a386Sopenharmony_ci        kNVIDIA_D3DVendor = 0x10DE,
121cb93a386Sopenharmony_ci        kQualcomm_D3DVendor = 0x5143,
122cb93a386Sopenharmony_ci    };
123cb93a386Sopenharmony_ci
124cb93a386Sopenharmony_ci    void init(const GrContextOptions& contextOptions, IDXGIAdapter1*, ID3D12Device*);
125cb93a386Sopenharmony_ci
126cb93a386Sopenharmony_ci    void initGrCaps(const D3D12_FEATURE_DATA_D3D12_OPTIONS&,
127cb93a386Sopenharmony_ci                    ID3D12Device*);
128cb93a386Sopenharmony_ci    void initShaderCaps(int vendorID, const D3D12_FEATURE_DATA_D3D12_OPTIONS& optionsDesc);
129cb93a386Sopenharmony_ci
130cb93a386Sopenharmony_ci    void initFormatTable(const DXGI_ADAPTER_DESC&, ID3D12Device*);
131cb93a386Sopenharmony_ci    void initStencilFormat(ID3D12Device*);
132cb93a386Sopenharmony_ci
133cb93a386Sopenharmony_ci    void applyDriverCorrectnessWorkarounds(int vendorID);
134cb93a386Sopenharmony_ci
135cb93a386Sopenharmony_ci    bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
136cb93a386Sopenharmony_ci    bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
137cb93a386Sopenharmony_ci                          const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
138cb93a386Sopenharmony_ci    GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override;
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ci    bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
141cb93a386Sopenharmony_ci
142cb93a386Sopenharmony_ci    SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
143cb93a386Sopenharmony_ci                                                 GrColorType) const override;
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci    GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
146cb93a386Sopenharmony_ci
147cb93a386Sopenharmony_ci    // ColorTypeInfo for a specific format
148cb93a386Sopenharmony_ci    struct ColorTypeInfo {
149cb93a386Sopenharmony_ci        GrColorType fColorType = GrColorType::kUnknown;
150cb93a386Sopenharmony_ci        enum {
151cb93a386Sopenharmony_ci            kUploadData_Flag = 0x1,
152cb93a386Sopenharmony_ci            // Does Ganesh itself support rendering to this colorType & format pair. Renderability
153cb93a386Sopenharmony_ci            // still additionally depends on if the format itself is renderable.
154cb93a386Sopenharmony_ci            kRenderable_Flag = 0x2,
155cb93a386Sopenharmony_ci            // Indicates that this colorType is supported only if we are wrapping a texture with
156cb93a386Sopenharmony_ci            // the given format and colorType. We do not allow creation with this pair.
157cb93a386Sopenharmony_ci            kWrappedOnly_Flag = 0x4,
158cb93a386Sopenharmony_ci        };
159cb93a386Sopenharmony_ci        uint32_t fFlags = 0;
160cb93a386Sopenharmony_ci
161cb93a386Sopenharmony_ci        GrSwizzle fReadSwizzle;
162cb93a386Sopenharmony_ci        GrSwizzle fWriteSwizzle;
163cb93a386Sopenharmony_ci    };
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_ci    struct FormatInfo {
166cb93a386Sopenharmony_ci        uint32_t colorTypeFlags(GrColorType colorType) const {
167cb93a386Sopenharmony_ci            for (int i = 0; i < fColorTypeInfoCount; ++i) {
168cb93a386Sopenharmony_ci                if (fColorTypeInfos[i].fColorType == colorType) {
169cb93a386Sopenharmony_ci                    return fColorTypeInfos[i].fFlags;
170cb93a386Sopenharmony_ci                }
171cb93a386Sopenharmony_ci            }
172cb93a386Sopenharmony_ci            return 0;
173cb93a386Sopenharmony_ci        }
174cb93a386Sopenharmony_ci
175cb93a386Sopenharmony_ci        void init(const DXGI_ADAPTER_DESC&, ID3D12Device*, DXGI_FORMAT);
176cb93a386Sopenharmony_ci        static void InitFormatFlags(const D3D12_FEATURE_DATA_FORMAT_SUPPORT&, uint16_t* flags);
177cb93a386Sopenharmony_ci        void initSampleCounts(const DXGI_ADAPTER_DESC& adapterDesc, ID3D12Device*, DXGI_FORMAT);
178cb93a386Sopenharmony_ci
179cb93a386Sopenharmony_ci        enum {
180cb93a386Sopenharmony_ci            kTexturable_Flag = 0x1, // Can be sampled in a shader
181cb93a386Sopenharmony_ci            kRenderable_Flag = 0x2, // Rendertarget and blendable
182cb93a386Sopenharmony_ci            kMSAA_Flag = 0x4,
183cb93a386Sopenharmony_ci            kResolve_Flag = 0x8,
184cb93a386Sopenharmony_ci            kUnorderedAccess_Flag = 0x10,
185cb93a386Sopenharmony_ci        };
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ci        uint16_t fFlags = 0;
188cb93a386Sopenharmony_ci
189cb93a386Sopenharmony_ci        SkTDArray<int> fColorSampleCounts;
190cb93a386Sopenharmony_ci
191cb93a386Sopenharmony_ci        // This GrColorType represents how the actually GPU format lays out its memory. This is used
192cb93a386Sopenharmony_ci        // for uploading data to backend textures to make sure we've arranged the memory in the
193cb93a386Sopenharmony_ci        // correct order.
194cb93a386Sopenharmony_ci        GrColorType fFormatColorType = GrColorType::kUnknown;
195cb93a386Sopenharmony_ci
196cb93a386Sopenharmony_ci        std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
197cb93a386Sopenharmony_ci        int fColorTypeInfoCount = 0;
198cb93a386Sopenharmony_ci    };
199cb93a386Sopenharmony_ci    static const size_t kNumDxgiFormats = 15;
200cb93a386Sopenharmony_ci    FormatInfo fFormatTable[kNumDxgiFormats];
201cb93a386Sopenharmony_ci
202cb93a386Sopenharmony_ci    FormatInfo& getFormatInfo(DXGI_FORMAT);
203cb93a386Sopenharmony_ci    const FormatInfo& getFormatInfo(DXGI_FORMAT) const;
204cb93a386Sopenharmony_ci
205cb93a386Sopenharmony_ci    DXGI_FORMAT fColorTypeToFormatTable[kGrColorTypeCnt];
206cb93a386Sopenharmony_ci    void setColorType(GrColorType, std::initializer_list<DXGI_FORMAT> formats);
207cb93a386Sopenharmony_ci
208cb93a386Sopenharmony_ci    int fMaxPerStageShaderResourceViews;
209cb93a386Sopenharmony_ci    int fMaxPerStageUnorderedAccessViews;
210cb93a386Sopenharmony_ci
211cb93a386Sopenharmony_ci    DXGI_FORMAT fPreferredStencilFormat;
212cb93a386Sopenharmony_ci
213cb93a386Sopenharmony_ci    bool fResolveSubresourceRegionSupport : 1;
214cb93a386Sopenharmony_ci    bool fStandardSwizzleLayoutSupport : 1;
215cb93a386Sopenharmony_ci
216cb93a386Sopenharmony_ci    using INHERITED = GrCaps;
217cb93a386Sopenharmony_ci};
218cb93a386Sopenharmony_ci
219cb93a386Sopenharmony_ci#endif
220