Add GrD3DDescriptorHeap.
Adds a wrapper around ID3D12DescriptorHeap, which manages allocations of descriptors from the heap. Change-Id: Idc3bdb43640639114de5d0520c339f9e0173e26f Bug: skia:9935 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/286338 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
3c873afcd7
commit
2ba8ba26f9
@ -743,6 +743,8 @@ skia_direct3d_sources = [
|
||||
"$_src/gpu/d3d/GrD3DCaps.h",
|
||||
"$_src/gpu/d3d/GrD3DCommandList.cpp",
|
||||
"$_src/gpu/d3d/GrD3DCommandList.h",
|
||||
"$_src/gpu/d3d/GrD3DDescriptorHeap.cpp",
|
||||
"$_src/gpu/d3d/GrD3DDescriptorHeap.h",
|
||||
"$_src/gpu/d3d/GrD3DGpu.cpp",
|
||||
"$_src/gpu/d3d/GrD3DGpu.h",
|
||||
"$_src/gpu/d3d/GrD3DOpsRenderPass.cpp",
|
||||
|
91
src/gpu/d3d/GrD3DDescriptorHeap.cpp
Normal file
91
src/gpu/d3d/GrD3DDescriptorHeap.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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/GrD3DDescriptorHeap.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
|
||||
sk_sp<GrD3DDescriptorHeap> GrD3DDescriptorHeap::Make(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type,
|
||||
unsigned int numDescriptors,
|
||||
D3D12_DESCRIPTOR_HEAP_FLAGS flags) {
|
||||
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
|
||||
heapDesc.Type = type;
|
||||
heapDesc.NumDescriptors = numDescriptors;
|
||||
heapDesc.Flags = flags;
|
||||
|
||||
ID3D12DescriptorHeap* heap;
|
||||
gpu->device()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap));
|
||||
|
||||
return sk_sp<GrD3DDescriptorHeap>(
|
||||
new GrD3DDescriptorHeap(std::move(gr_cp<ID3D12DescriptorHeap>(heap)), heapDesc,
|
||||
gpu->device()->GetDescriptorHandleIncrementSize(type)));
|
||||
}
|
||||
|
||||
GrD3DDescriptorHeap::GrD3DDescriptorHeap(const gr_cp<ID3D12DescriptorHeap>& heap,
|
||||
const D3D12_DESCRIPTOR_HEAP_DESC& descriptor,
|
||||
unsigned int handleIncrementSize)
|
||||
: fHeap(heap)
|
||||
, fHandleIncrementSize(handleIncrementSize)
|
||||
, fFreeBlocks(descriptor.NumDescriptors) {
|
||||
// set all the bits in freeBlocks
|
||||
for (UINT i = 0; i < descriptor.NumDescriptors; ++i) {
|
||||
fFreeBlocks.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DDescriptorHeap::allocateCPUHandle() {
|
||||
// valid only for non-shader-visible heaps
|
||||
SkASSERT(!SkToBool(fHeap->GetDesc().Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE));
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = fHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
int freeIndex = fFreeBlocks.leadingBitIndex();
|
||||
SkASSERT(freeIndex >= 0);
|
||||
handle.ptr += freeIndex * fHandleIncrementSize;
|
||||
fFreeBlocks.clear(freeIndex);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE GrD3DDescriptorHeap::allocateGPUHandle() {
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE handle = fHeap->GetGPUDescriptorHandleForHeapStart();
|
||||
int freeIndex = fFreeBlocks.leadingBitIndex();
|
||||
SkASSERT(freeIndex >= 0);
|
||||
handle.ptr += freeIndex * fHandleIncrementSize;
|
||||
fFreeBlocks.clear(freeIndex);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void GrD3DDescriptorHeap::freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE* handle) {
|
||||
// valid only for non-shader-visible heaps
|
||||
SkASSERT(!SkToBool(fHeap->GetDesc().Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE));
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE heapStart = fHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
// Make sure this handle belongs to this heap
|
||||
SkASSERT(handle->ptr >= heapStart.ptr);
|
||||
SIZE_T index = (handle->ptr - heapStart.ptr) / fHandleIncrementSize;
|
||||
SkASSERT(index < fHeap->GetDesc().NumDescriptors);
|
||||
fFreeBlocks.set(index);
|
||||
handle->ptr = 0;
|
||||
}
|
||||
|
||||
void GrD3DDescriptorHeap::freeGPUHandle(D3D12_GPU_DESCRIPTOR_HANDLE* handle) {
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE heapStart = fHeap->GetGPUDescriptorHandleForHeapStart();
|
||||
// Make sure this handle belongs to this heap
|
||||
SkASSERT(handle->ptr >= heapStart.ptr);
|
||||
SIZE_T index = (handle->ptr - heapStart.ptr) / fHandleIncrementSize;
|
||||
SkASSERT(index < fHeap->GetDesc().NumDescriptors);
|
||||
fFreeBlocks.set(index);
|
||||
handle->ptr = 0;
|
||||
}
|
||||
|
||||
#ifdef SK_TRACE_MANAGED_RESOURCES
|
||||
/** Output a human-readable dump of this resource's information
|
||||
*/
|
||||
void GrD3DDescriptorHeap::dumpInfo() const {
|
||||
SkDebugf("GrD3DDescriptorHeap: %d (%d refs)\n", fHeap.get(), this->getRefCnt());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
47
src/gpu/d3d/GrD3DDescriptorHeap.h
Normal file
47
src/gpu/d3d/GrD3DDescriptorHeap.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 GrD3DDescriptorHeap_DEFINED
|
||||
#define GrD3DDescriptorHeap_DEFINED
|
||||
|
||||
#include "include/gpu/d3d/GrD3DTypes.h"
|
||||
#include "src/gpu/GrManagedResource.h"
|
||||
#include "src/utils/SkBitSet.h"
|
||||
|
||||
class GrD3DGpu;
|
||||
|
||||
class GrD3DDescriptorHeap : public GrManagedResource {
|
||||
public:
|
||||
static sk_sp<GrD3DDescriptorHeap> Make(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE,
|
||||
unsigned int numDescriptors,
|
||||
D3D12_DESCRIPTOR_HEAP_FLAGS);
|
||||
|
||||
~GrD3DDescriptorHeap() override = default;
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE allocateCPUHandle(); // valid only for non-shader-visible heaps
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE allocateGPUHandle();
|
||||
void freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE*);
|
||||
void freeGPUHandle(D3D12_GPU_DESCRIPTOR_HANDLE*);
|
||||
|
||||
#ifdef SK_TRACE_MANAGED_RESOURCES
|
||||
/** Output a human-readable dump of this resource's information
|
||||
*/
|
||||
void dumpInfo() const override;
|
||||
#endif
|
||||
|
||||
void freeGPUData() const override {}
|
||||
|
||||
private:
|
||||
GrD3DDescriptorHeap(const gr_cp<ID3D12DescriptorHeap>&, const D3D12_DESCRIPTOR_HEAP_DESC&,
|
||||
unsigned int handleIncrementSize);
|
||||
|
||||
gr_cp<ID3D12DescriptorHeap> fHeap;
|
||||
size_t fHandleIncrementSize;
|
||||
SkBitSet fFreeBlocks;
|
||||
};
|
||||
|
||||
#endif
|
@ -9,6 +9,7 @@
|
||||
#define SkBitSet_DEFINED
|
||||
|
||||
#include "include/private/SkTemplates.h"
|
||||
#include "src/core/SkMathPriv.h"
|
||||
|
||||
class SkBitSet {
|
||||
public:
|
||||
@ -28,6 +29,14 @@ public:
|
||||
*chunk |= mask;
|
||||
}
|
||||
|
||||
/** Set the value of the index-th bit to false. */
|
||||
void clear(int index) {
|
||||
uint32_t mask = ~(1 << (index & 31));
|
||||
uint32_t* chunk = this->internalGet(index);
|
||||
SkASSERT(chunk);
|
||||
*chunk &= mask;
|
||||
}
|
||||
|
||||
bool has(int index) const {
|
||||
const uint32_t* chunk = this->internalGet(index);
|
||||
uint32_t mask = 1 << (index & 31);
|
||||
@ -50,6 +59,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the index of the first set bit
|
||||
// Returns -1 if no bits are set
|
||||
int leadingBitIndex() {
|
||||
const uint32_t* data = fBitData.get();
|
||||
for (unsigned i = 0; i < fDwordCount; ++i) {
|
||||
if (uint32_t value = data[i]) { // There are set bits
|
||||
int index = SkPrevLog2(value);
|
||||
return index + i * 32;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<uint32_t, SkFunctionWrapper<void(void*), sk_free>> fBitData;
|
||||
size_t fDwordCount; // Dword (32-bit) count of the bitset.
|
||||
|
Loading…
Reference in New Issue
Block a user