/* * Copyright 2020 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrD3DCaps_DEFINED #define GrD3DCaps_DEFINED #include "src/gpu/GrCaps.h" #include "include/gpu/d3d/GrD3DTypes.h" #include "src/gpu/d3d/GrD3DAttachment.h" class GrShaderCaps; /** * Stores some capabilities of a D3D backend. */ class GrD3DCaps : public GrCaps { public: /** * Creates a GrD3DCaps that is set such that nothing is supported. The init function should * be called to fill out the caps. */ GrD3DCaps(const GrContextOptions& contextOptions, IDXGIAdapter1*, ID3D12Device*); bool isFormatSRGB(const GrBackendFormat&) const override; bool isFormatTexturable(const GrBackendFormat&) const override; bool isFormatTexturable(DXGI_FORMAT) const; bool isFormatCopyable(const GrBackendFormat&) const override { return true; } bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, int sampleCount = 1) const override; bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; bool isFormatRenderable(DXGI_FORMAT, int sampleCount) const; bool isFormatUnorderedAccessible(DXGI_FORMAT) const; int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override; int getRenderTargetSampleCount(int requestedCount, DXGI_FORMAT) const; int maxRenderTargetSampleCount(const GrBackendFormat&) const override; int maxRenderTargetSampleCount(DXGI_FORMAT) const; GrColorType getFormatColorType(DXGI_FORMAT) const; SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, const GrBackendFormat& surfaceFormat, GrColorType srcColorType) const override; SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override; /** * Returns both a supported and most preferred stencil format to use in draws. */ DXGI_FORMAT preferredStencilFormat() const { return fPreferredStencilFormat; } static int GetStencilFormatTotalBitCount(DXGI_FORMAT format) { switch (format) { case DXGI_FORMAT_D24_UNORM_S8_UINT: return 32; case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: // DXGI_FORMAT_D32_FLOAT_S8X24_UINT has 24 unused bits at the end so total bits is 64. return 64; default: SkASSERT(false); return 0; } } /** * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means * the surface is not a render target, otherwise it is the number of samples in the render * target. */ bool canCopyTexture(DXGI_FORMAT dstFormat, int dstSampleCnt, DXGI_FORMAT srcFormat, int srcSamplecnt) const; bool canCopyAsResolve(DXGI_FORMAT dstFormat, int dstSampleCnt, DXGI_FORMAT srcFormat, int srcSamplecnt) const; GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override; DXGI_FORMAT getFormatFromColorType(GrColorType colorType) const { int idx = static_cast(colorType); return fColorTypeToFormatTable[idx]; } GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override; uint64_t computeFormatKey(const GrBackendFormat&) const override; void addExtraSamplerKey(GrProcessorKeyBuilder*, GrSamplerState, const GrBackendFormat&) const override; GrProgramDesc makeDesc(GrRenderTarget*, const GrProgramInfo&, ProgramDescOverrideFlags) const override; #if GR_TEST_UTILS std::vector getTestingCombinations() const override; #endif private: enum D3DVendor { kAMD_D3DVendor = 0x1002, kARM_D3DVendor = 0x13B5, kImagination_D3DVendor = 0x1010, kIntel_D3DVendor = 0x8086, kNVIDIA_D3DVendor = 0x10DE, kQualcomm_D3DVendor = 0x5143, }; void init(const GrContextOptions& contextOptions, IDXGIAdapter1*, ID3D12Device*); void initGrCaps(const D3D12_FEATURE_DATA_D3D12_OPTIONS&, ID3D12Device*); void initShaderCaps(int vendorID, const D3D12_FEATURE_DATA_D3D12_OPTIONS& optionsDesc); void initFormatTable(const DXGI_ADAPTER_DESC&, ID3D12Device*); void initStencilFormat(ID3D12Device*); void applyDriverCorrectnessWorkarounds(int vendorID); bool onSurfaceSupportsWritePixels(const GrSurface*) const override; bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) const override; GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override; bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override; SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&, GrColorType) const override; GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override; // ColorTypeInfo for a specific format struct ColorTypeInfo { GrColorType fColorType = GrColorType::kUnknown; enum { kUploadData_Flag = 0x1, // Does Ganesh itself support rendering to this colorType & format pair. Renderability // still additionally depends on if the format itself is renderable. kRenderable_Flag = 0x2, // Indicates that this colorType is supported only if we are wrapping a texture with // the given format and colorType. We do not allow creation with this pair. kWrappedOnly_Flag = 0x4, }; uint32_t fFlags = 0; GrSwizzle fReadSwizzle; GrSwizzle fWriteSwizzle; }; struct FormatInfo { uint32_t colorTypeFlags(GrColorType colorType) const { for (int i = 0; i < fColorTypeInfoCount; ++i) { if (fColorTypeInfos[i].fColorType == colorType) { return fColorTypeInfos[i].fFlags; } } return 0; } void init(const DXGI_ADAPTER_DESC&, ID3D12Device*, DXGI_FORMAT); static void InitFormatFlags(const D3D12_FEATURE_DATA_FORMAT_SUPPORT&, uint16_t* flags); void initSampleCounts(const DXGI_ADAPTER_DESC& adapterDesc, ID3D12Device*, DXGI_FORMAT); enum { kTexturable_Flag = 0x1, // Can be sampled in a shader kRenderable_Flag = 0x2, // Rendertarget and blendable kMSAA_Flag = 0x4, kResolve_Flag = 0x8, kUnorderedAccess_Flag = 0x10, }; uint16_t fFlags = 0; SkTDArray fColorSampleCounts; // This GrColorType represents how the actually GPU format lays out its memory. This is used // for uploading data to backend textures to make sure we've arranged the memory in the // correct order. GrColorType fFormatColorType = GrColorType::kUnknown; std::unique_ptr fColorTypeInfos; int fColorTypeInfoCount = 0; }; static const size_t kNumDxgiFormats = 15; FormatInfo fFormatTable[kNumDxgiFormats]; FormatInfo& getFormatInfo(DXGI_FORMAT); const FormatInfo& getFormatInfo(DXGI_FORMAT) const; DXGI_FORMAT fColorTypeToFormatTable[kGrColorTypeCnt]; void setColorType(GrColorType, std::initializer_list formats); int fMaxPerStageShaderResourceViews; int fMaxPerStageUnorderedAccessViews; DXGI_FORMAT fPreferredStencilFormat; using INHERITED = GrCaps; }; #endif