blob: 7536f59091862c4ff8b3134e5c4eed778283b388 [file] [log] [blame]
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/d3d/GrD3DAttachmentViewManager.h"
#include "src/gpu/d3d/GrD3DGpu.h"
GrD3DAttachmentViewManager::GrD3DAttachmentViewManager(GrD3DGpu* gpu)
: fRTVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
, fDSVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_DSV) {}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::createRenderTargetView(
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fRTVDescriptorPool.allocateHandle(gpu);
gpu->device()->CreateRenderTargetView(textureResource, nullptr, descriptor);
return descriptor;
}
void GrD3DAttachmentViewManager::recycleRenderTargetView(
D3D12_CPU_DESCRIPTOR_HANDLE* rtvDescriptor) {
fRTVDescriptorPool.releaseHandle(rtvDescriptor);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::createDepthStencilView(
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fDSVDescriptorPool.allocateHandle(gpu);
gpu->device()->CreateDepthStencilView(textureResource, nullptr, descriptor);
return descriptor;
}
void GrD3DAttachmentViewManager::recycleDepthStencilView(
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
fDSVDescriptorPool.releaseHandle(dsvDescriptor);
}
////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrD3DAttachmentViewManager::Heap> GrD3DAttachmentViewManager::Heap::Make(
GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type, unsigned int numDescriptors) {
std::unique_ptr<GrD3DDescriptorHeap> heap =
GrD3DDescriptorHeap::Make(gpu, type, numDescriptors, D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
if (!heap) {
return nullptr;
}
return std::unique_ptr<Heap>(new Heap(heap, numDescriptors));
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::Heap::allocateCPUHandle() {
SkBitSet::OptionalIndex freeBlock = fFreeBlocks.findFirst();
SkASSERT(freeBlock);
fFreeBlocks.reset(*freeBlock);
--fFreeCount;
return fHeap->getCPUHandle(*freeBlock);
}
bool GrD3DAttachmentViewManager::Heap::freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE* handle) {
size_t index;
if (!fHeap->getIndex(*handle, &index)) {
return false;
}
fFreeBlocks.set(index);
++fFreeCount;
handle->ptr = 0;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
GrD3DAttachmentViewManager::HeapPool::HeapPool(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE heapType)
: fMaxAvailableDescriptors(32)
, fHeapType(heapType) {
std::unique_ptr<GrD3DAttachmentViewManager::Heap> heap =
GrD3DAttachmentViewManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
fDescriptorHeaps.push_back(std::move(heap));
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::HeapPool::allocateHandle(GrD3DGpu* gpu) {
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
if (fDescriptorHeaps[i]->canAllocate()) {
D3D12_CPU_DESCRIPTOR_HANDLE handle = fDescriptorHeaps[i]->allocateCPUHandle();
return handle;
}
}
// need to allocate more space
std::unique_ptr<GrD3DAttachmentViewManager::Heap> heap =
GrD3DAttachmentViewManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
fDescriptorHeaps.push_back(std::move(heap));
fMaxAvailableDescriptors *= 2;
D3D12_CPU_DESCRIPTOR_HANDLE handle =
fDescriptorHeaps[fDescriptorHeaps.size() - 1]->allocateCPUHandle();
return handle;
}
void GrD3DAttachmentViewManager::HeapPool::releaseHandle(
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
if (fDescriptorHeaps[i]->freeCPUHandle(dsvDescriptor)) {
return;
}
}
SkASSERT(false);
}