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/GrD3DCaps.h",
|
||||||
"$_src/gpu/d3d/GrD3DCommandList.cpp",
|
"$_src/gpu/d3d/GrD3DCommandList.cpp",
|
||||||
"$_src/gpu/d3d/GrD3DCommandList.h",
|
"$_src/gpu/d3d/GrD3DCommandList.h",
|
||||||
|
"$_src/gpu/d3d/GrD3DDescriptorHeap.cpp",
|
||||||
|
"$_src/gpu/d3d/GrD3DDescriptorHeap.h",
|
||||||
"$_src/gpu/d3d/GrD3DGpu.cpp",
|
"$_src/gpu/d3d/GrD3DGpu.cpp",
|
||||||
"$_src/gpu/d3d/GrD3DGpu.h",
|
"$_src/gpu/d3d/GrD3DGpu.h",
|
||||||
"$_src/gpu/d3d/GrD3DOpsRenderPass.cpp",
|
"$_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
|
#define SkBitSet_DEFINED
|
||||||
|
|
||||||
#include "include/private/SkTemplates.h"
|
#include "include/private/SkTemplates.h"
|
||||||
|
#include "src/core/SkMathPriv.h"
|
||||||
|
|
||||||
class SkBitSet {
|
class SkBitSet {
|
||||||
public:
|
public:
|
||||||
@ -28,6 +29,14 @@ public:
|
|||||||
*chunk |= mask;
|
*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 {
|
bool has(int index) const {
|
||||||
const uint32_t* chunk = this->internalGet(index);
|
const uint32_t* chunk = this->internalGet(index);
|
||||||
uint32_t mask = 1 << (index & 31);
|
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:
|
private:
|
||||||
std::unique_ptr<uint32_t, SkFunctionWrapper<void(void*), sk_free>> fBitData;
|
std::unique_ptr<uint32_t, SkFunctionWrapper<void(void*), sk_free>> fBitData;
|
||||||
size_t fDwordCount; // Dword (32-bit) count of the bitset.
|
size_t fDwordCount; // Dword (32-bit) count of the bitset.
|
||||||
|
Loading…
Reference in New Issue
Block a user