diff options
Diffstat (limited to 'gfx/skia/skia/include/gpu/d3d/GrD3DTypes.h')
-rw-r--r-- | gfx/skia/skia/include/gpu/d3d/GrD3DTypes.h | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/gfx/skia/skia/include/gpu/d3d/GrD3DTypes.h b/gfx/skia/skia/include/gpu/d3d/GrD3DTypes.h new file mode 100644 index 0000000000..b595422e86 --- /dev/null +++ b/gfx/skia/skia/include/gpu/d3d/GrD3DTypes.h @@ -0,0 +1,248 @@ + +/* + * 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 GrD3DTypes_DEFINED +#define GrD3DTypes_DEFINED + +// This file includes d3d12.h, which in turn includes windows.h, which redefines many +// common identifiers such as: +// * interface +// * small +// * near +// * far +// * CreateSemaphore +// * MemoryBarrier +// +// You should only include this header if you need the Direct3D definitions and are +// prepared to rename those identifiers. + +#include "include/core/SkRefCnt.h" +#include "include/gpu/GpuTypes.h" +#include <d3d12.h> +#include <dxgi1_4.h> + +class GrD3DGpu; + + /** Check if the argument is non-null, and if so, call obj->AddRef() and return obj. + */ +template <typename T> static inline T* GrSafeComAddRef(T* obj) { + if (obj) { + obj->AddRef(); + } + return obj; +} + +/** Check if the argument is non-null, and if so, call obj->Release() + */ +template <typename T> static inline void GrSafeComRelease(T* obj) { + if (obj) { + obj->Release(); + } +} + +template <typename T> class gr_cp { +public: + using element_type = T; + + constexpr gr_cp() : fObject(nullptr) {} + constexpr gr_cp(std::nullptr_t) : fObject(nullptr) {} + + /** + * Shares the underlying object by calling AddRef(), so that both the argument and the newly + * created gr_cp both have a reference to it. + */ + gr_cp(const gr_cp<T>& that) : fObject(GrSafeComAddRef(that.get())) {} + + /** + * Move the underlying object from the argument to the newly created gr_cp. Afterwards only + * the new gr_cp will have a reference to the object, and the argument will point to null. + * No call to AddRef() or Release() will be made. + */ + gr_cp(gr_cp<T>&& that) : fObject(that.release()) {} + + /** + * Adopt the bare object into the newly created gr_cp. + * No call to AddRef() or Release() will be made. + */ + explicit gr_cp(T* obj) { + fObject = obj; + } + + /** + * Calls Release() on the underlying object pointer. + */ + ~gr_cp() { + GrSafeComRelease(fObject); + SkDEBUGCODE(fObject = nullptr); + } + + /** + * Shares the underlying object referenced by the argument by calling AddRef() on it. If this + * gr_cp previously had a reference to an object (i.e. not null) it will call Release() + * on that object. + */ + gr_cp<T>& operator=(const gr_cp<T>& that) { + if (this != &that) { + this->reset(GrSafeComAddRef(that.get())); + } + return *this; + } + + /** + * Move the underlying object from the argument to the gr_cp. If the gr_cp + * previously held a reference to another object, Release() will be called on that object. + * No call to AddRef() will be made. + */ + gr_cp<T>& operator=(gr_cp<T>&& that) { + this->reset(that.release()); + return *this; + } + + explicit operator bool() const { return this->get() != nullptr; } + + T* get() const { return fObject; } + T* operator->() const { return fObject; } + T** operator&() { return &fObject; } + + /** + * Adopt the new object, and call Release() on any previously held object (if not null). + * No call to AddRef() will be made. + */ + void reset(T* object = nullptr) { + T* oldObject = fObject; + fObject = object; + GrSafeComRelease(oldObject); + } + + /** + * Shares the new object by calling AddRef() on it. If this gr_cp previously had a + * reference to an object (i.e. not null) it will call Release() on that object. + */ + void retain(T* object) { + if (this->fObject != object) { + this->reset(GrSafeComAddRef(object)); + } + } + + /** + * Return the original object, and set the internal object to nullptr. + * The caller must assume ownership of the object, and manage its reference count directly. + * No call to Release() will be made. + */ + T* SK_WARN_UNUSED_RESULT release() { + T* obj = fObject; + fObject = nullptr; + return obj; + } + +private: + T* fObject; +}; + +template <typename T> inline bool operator==(const gr_cp<T>& a, + const gr_cp<T>& b) { + return a.get() == b.get(); +} + +template <typename T> inline bool operator!=(const gr_cp<T>& a, + const gr_cp<T>& b) { + return a.get() != b.get(); +} + +// interface classes for the GPU memory allocator +class GrD3DAlloc : public SkRefCnt { +public: + ~GrD3DAlloc() override = default; +}; + +class GrD3DMemoryAllocator : public SkRefCnt { +public: + virtual gr_cp<ID3D12Resource> createResource(D3D12_HEAP_TYPE, const D3D12_RESOURCE_DESC*, + D3D12_RESOURCE_STATES initialResourceState, + sk_sp<GrD3DAlloc>* allocation, + const D3D12_CLEAR_VALUE*) = 0; + virtual gr_cp<ID3D12Resource> createAliasingResource(sk_sp<GrD3DAlloc>& allocation, + uint64_t localOffset, + const D3D12_RESOURCE_DESC*, + D3D12_RESOURCE_STATES initialResourceState, + const D3D12_CLEAR_VALUE*) = 0; +}; + +// Note: there is no notion of Borrowed or Adopted resources in the D3D backend, +// so Ganesh will ref fResource once it's asked to wrap it. +// Clients are responsible for releasing their own ref to avoid memory leaks. +struct GrD3DTextureResourceInfo { + gr_cp<ID3D12Resource> fResource = nullptr; + sk_sp<GrD3DAlloc> fAlloc = nullptr; + D3D12_RESOURCE_STATES fResourceState = D3D12_RESOURCE_STATE_COMMON; + DXGI_FORMAT fFormat = DXGI_FORMAT_UNKNOWN; + uint32_t fSampleCount = 1; + uint32_t fLevelCount = 0; + unsigned int fSampleQualityPattern = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN; + skgpu::Protected fProtected = skgpu::Protected::kNo; + + GrD3DTextureResourceInfo() = default; + + GrD3DTextureResourceInfo(ID3D12Resource* resource, + const sk_sp<GrD3DAlloc> alloc, + D3D12_RESOURCE_STATES resourceState, + DXGI_FORMAT format, + uint32_t sampleCount, + uint32_t levelCount, + unsigned int sampleQualityLevel, + skgpu::Protected isProtected = skgpu::Protected::kNo) + : fResource(resource) + , fAlloc(alloc) + , fResourceState(resourceState) + , fFormat(format) + , fSampleCount(sampleCount) + , fLevelCount(levelCount) + , fSampleQualityPattern(sampleQualityLevel) + , fProtected(isProtected) {} + + GrD3DTextureResourceInfo(const GrD3DTextureResourceInfo& info, + D3D12_RESOURCE_STATES resourceState) + : fResource(info.fResource) + , fAlloc(info.fAlloc) + , fResourceState(resourceState) + , fFormat(info.fFormat) + , fSampleCount(info.fSampleCount) + , fLevelCount(info.fLevelCount) + , fSampleQualityPattern(info.fSampleQualityPattern) + , fProtected(info.fProtected) {} + +#if GR_TEST_UTILS + bool operator==(const GrD3DTextureResourceInfo& that) const { + return fResource == that.fResource && fResourceState == that.fResourceState && + fFormat == that.fFormat && fSampleCount == that.fSampleCount && + fLevelCount == that.fLevelCount && + fSampleQualityPattern == that.fSampleQualityPattern && fProtected == that.fProtected; + } +#endif +}; + +struct GrD3DFenceInfo { + GrD3DFenceInfo() + : fFence(nullptr) + , fValue(0) { + } + + gr_cp<ID3D12Fence> fFence; + uint64_t fValue; // signal value for the fence +}; + +struct GrD3DSurfaceInfo { + uint32_t fSampleCount = 1; + uint32_t fLevelCount = 0; + skgpu::Protected fProtected = skgpu::Protected::kNo; + + DXGI_FORMAT fFormat = DXGI_FORMAT_UNKNOWN; + unsigned int fSampleQualityPattern = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN; +}; + +#endif |