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