diff --git a/include/gpu/d3d/GrD3DTypes.h b/include/gpu/d3d/GrD3DTypes.h index 53f499c874..33c079dab1 100644 --- a/include/gpu/d3d/GrD3DTypes.h +++ b/include/gpu/d3d/GrD3DTypes.h @@ -166,6 +166,11 @@ public: D3D12_RESOURCE_STATES initialResourceState, sk_sp* allocation, const D3D12_CLEAR_VALUE*) = 0; + virtual gr_cp createAliasingResource(sk_sp& 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, diff --git a/src/gpu/d3d/GrD3DAMDMemoryAllocator.cpp b/src/gpu/d3d/GrD3DAMDMemoryAllocator.cpp index 32ece37711..74bd2795a5 100644 --- a/src/gpu/d3d/GrD3DAMDMemoryAllocator.cpp +++ b/src/gpu/d3d/GrD3DAMDMemoryAllocator.cpp @@ -9,7 +9,7 @@ #include "src/gpu/d3d/GrD3DUtil.h" sk_sp GrD3DAMDMemoryAllocator::Make(IDXGIAdapter* adapter, - ID3D12Device* device) { + ID3D12Device* device) { D3D12MA::ALLOCATOR_DESC allocatorDesc = {}; allocatorDesc.pAdapter = adapter; allocatorDesc.pDevice = device; @@ -46,3 +46,19 @@ gr_cp GrD3DAMDMemoryAllocator::createResource( allocation->reset(new Alloc(d3d12maAllocation)); return resource; } + +gr_cp GrD3DAMDMemoryAllocator::createAliasingResource( + sk_sp& allocation, uint64_t localOffset, + const D3D12_RESOURCE_DESC* resourceDesc, D3D12_RESOURCE_STATES initialResourceState, + const D3D12_CLEAR_VALUE* clearValue) { + Alloc* alloc = (Alloc*)allocation.get(); + gr_cp resource; + HRESULT hr = fAllocator->CreateAliasingResource(alloc->fAllocation, localOffset, resourceDesc, + initialResourceState, clearValue, + IID_PPV_ARGS(&resource)); + if (!SUCCEEDED(hr)) { + return nullptr; + } + + return resource; +} diff --git a/src/gpu/d3d/GrD3DAMDMemoryAllocator.h b/src/gpu/d3d/GrD3DAMDMemoryAllocator.h index a6fff7d75a..fba7674cb4 100644 --- a/src/gpu/d3d/GrD3DAMDMemoryAllocator.h +++ b/src/gpu/d3d/GrD3DAMDMemoryAllocator.h @@ -31,6 +31,12 @@ public: sk_sp* allocation, const D3D12_CLEAR_VALUE*) override; + gr_cp createAliasingResource(sk_sp& allocation, + uint64_t localOffset, + const D3D12_RESOURCE_DESC*, + D3D12_RESOURCE_STATES initialResourceState, + const D3D12_CLEAR_VALUE*) override; + class Alloc : public GrD3DAlloc { public: Alloc(D3D12MA::Allocation* allocation) : fAllocation(allocation) {} @@ -38,6 +44,7 @@ public: fAllocation->Release(); } private: + friend class GrD3DAMDMemoryAllocator; D3D12MA::Allocation* fAllocation; }; diff --git a/src/gpu/d3d/GrD3DTexture.cpp b/src/gpu/d3d/GrD3DTexture.cpp index 83e3694b77..9960b7b9cb 100644 --- a/src/gpu/d3d/GrD3DTexture.cpp +++ b/src/gpu/d3d/GrD3DTexture.cpp @@ -108,6 +108,31 @@ sk_sp GrD3DTexture::MakeWrappedTexture(GrD3DGpu* gpu, ioType)); } +sk_sp GrD3DTexture::MakeAliasingTexture(GrD3DGpu* gpu, + sk_sp originalTexture, + DXGI_FORMAT format) { + GrD3DTextureResourceInfo info = originalTexture->fInfo; + D3D12_RESOURCE_DESC desc = originalTexture->d3dResource()->GetDesc(); + desc.Format = format; + + info.fResource = gpu->memoryAllocator()->createAliasingResource(info.fAlloc, 0, &desc, + info.fResourceState, nullptr); + if (!info.fResource) { + return false; + } + + sk_sp state( + new GrD3DResourceState(static_cast(info.fResourceState))); + + GrD3DDescriptorHeap::CPUHandle shaderResourceView = + gpu->resourceProvider().createShaderResourceView(info.fResource.get()); + + GrD3DTexture* tex = new GrD3DTexture(gpu, SkBudgeted::kNo, originalTexture->dimensions(), + info, std::move(state), shaderResourceView, + originalTexture->mipmapStatus()); + return sk_sp(tex); +} + void GrD3DTexture::onRelease() { GrD3DGpu* gpu = this->getD3DGpu(); gpu->resourceProvider().recycleShaderView(fShaderResourceView); diff --git a/src/gpu/d3d/GrD3DTexture.h b/src/gpu/d3d/GrD3DTexture.h index e57dd29ab9..ddfecd4346 100644 --- a/src/gpu/d3d/GrD3DTexture.h +++ b/src/gpu/d3d/GrD3DTexture.h @@ -30,6 +30,10 @@ public: const GrD3DTextureResourceInfo&, sk_sp); + static sk_sp MakeAliasingTexture(GrD3DGpu*, + sk_sp, + DXGI_FORMAT); + ~GrD3DTexture() override {} GrBackendTexture getBackendTexture() const override;