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