Add d3d pipeline state cache
Change-Id: Iab9d4288a54d0743dfbf94f078b206e5df3b5f87 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/287378 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
8842b37fc7
commit
b698ad3f2b
@ -139,9 +139,8 @@ bool GrD3DOpsRenderPass::onBindPipeline(const GrProgramInfo& info, const SkRect&
|
||||
fCurrentPipelineBounds.setEmpty();
|
||||
}
|
||||
|
||||
GrProgramDesc desc = fGpu->caps()->makeDesc(fRenderTarget, info);
|
||||
sk_sp<GrD3DPipelineState> pipelineState =
|
||||
GrD3DPipelineStateBuilder::CreatePipelineState(fGpu, fRenderTarget, desc, info);
|
||||
fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget, info);
|
||||
if (!pipelineState) {
|
||||
return false;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
typedef size_t shader_size;
|
||||
|
||||
sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::CreatePipelineState(
|
||||
sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::MakePipelineState(
|
||||
GrD3DGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrProgramDesc& desc,
|
||||
|
@ -29,9 +29,9 @@ public:
|
||||
* available to be used.
|
||||
* @return the created pipeline if generation was successful; nullptr otherwise
|
||||
*/
|
||||
static sk_sp<GrD3DPipelineState> CreatePipelineState(GrD3DGpu*, GrRenderTarget*,
|
||||
const GrProgramDesc&,
|
||||
const GrProgramInfo&);
|
||||
static sk_sp<GrD3DPipelineState> MakePipelineState(GrD3DGpu*, GrRenderTarget*,
|
||||
const GrProgramDesc&,
|
||||
const GrProgramInfo&);
|
||||
|
||||
const GrCaps* caps() const override;
|
||||
|
||||
|
@ -7,10 +7,16 @@
|
||||
|
||||
#include "src/gpu/d3d/GrD3DResourceProvider.h"
|
||||
|
||||
#include "include/gpu/GrContextOptions.h"
|
||||
#include "src/gpu/GrContextPriv.h"
|
||||
#include "src/gpu/d3d/GrD3DCommandList.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
#include "src/gpu/d3d/GrD3DPipelineState.h"
|
||||
#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"
|
||||
|
||||
GrD3DResourceProvider::GrD3DResourceProvider(GrD3DGpu* gpu) : fGpu(gpu) {
|
||||
GrD3DResourceProvider::GrD3DResourceProvider(GrD3DGpu* gpu)
|
||||
: fGpu(gpu)
|
||||
, fPipelineStateCache(new PipelineStateCache(gpu)) {
|
||||
// TODO: Change to handle growing the heap rather than a fixed size
|
||||
const int kMaxRenderTargetViews = 256;
|
||||
|
||||
@ -61,3 +67,78 @@ D3D12_CPU_DESCRIPTOR_HANDLE GrD3DResourceProvider::createRenderTargetView(
|
||||
void GrD3DResourceProvider::recycleRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE* rtvDescriptor) {
|
||||
fRTVDescriptorHeap->freeCPUHandle(rtvDescriptor);
|
||||
}
|
||||
|
||||
sk_sp<GrD3DPipelineState> GrD3DResourceProvider::findOrCreateCompatiblePipelineState(
|
||||
GrRenderTarget* rt, const GrProgramInfo& info) {
|
||||
return fPipelineStateCache->refPipelineState(rt, info);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
// Display pipeline state cache usage
|
||||
static const bool c_DisplayMtlPipelineCache{false};
|
||||
#endif
|
||||
|
||||
struct GrD3DResourceProvider::PipelineStateCache::Entry {
|
||||
Entry(GrD3DGpu* gpu, sk_sp<GrD3DPipelineState> pipelineState)
|
||||
: fGpu(gpu), fPipelineState(std::move(pipelineState)) {}
|
||||
|
||||
GrD3DGpu* fGpu;
|
||||
sk_sp<GrD3DPipelineState> fPipelineState;
|
||||
};
|
||||
|
||||
GrD3DResourceProvider::PipelineStateCache::PipelineStateCache(GrD3DGpu* gpu)
|
||||
: fMap(gpu->getContext()->priv().options().fRuntimeProgramCacheSize)
|
||||
, fGpu(gpu)
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
, fTotalRequests(0)
|
||||
, fCacheMisses(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
GrD3DResourceProvider::PipelineStateCache::~PipelineStateCache() {
|
||||
// dump stats
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
if (c_DisplayMtlPipelineCache) {
|
||||
SkDebugf("--- Pipeline State Cache ---\n");
|
||||
SkDebugf("Total requests: %d\n", fTotalRequests);
|
||||
SkDebugf("Cache misses: %d\n", fCacheMisses);
|
||||
SkDebugf("Cache miss %%: %f\n",
|
||||
(fTotalRequests > 0) ? 100.f * fCacheMisses / fTotalRequests : 0.f);
|
||||
SkDebugf("---------------------\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
sk_sp<GrD3DPipelineState> GrD3DResourceProvider::PipelineStateCache::refPipelineState(
|
||||
GrRenderTarget* renderTarget, const GrProgramInfo& programInfo) {
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
++fTotalRequests;
|
||||
#endif
|
||||
|
||||
const GrCaps* caps = fGpu->caps();
|
||||
|
||||
GrProgramDesc desc = caps->makeDesc(renderTarget, programInfo);
|
||||
if (!desc.isValid()) {
|
||||
GrCapsDebugf(fGpu->caps(), "Failed to build mtl program descriptor!\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Entry>* entry = fMap.find(desc);
|
||||
if (!entry) {
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
++fCacheMisses;
|
||||
#endif
|
||||
sk_sp<GrD3DPipelineState> pipelineState = GrD3DPipelineStateBuilder::MakePipelineState(
|
||||
fGpu, renderTarget, desc, programInfo);
|
||||
if (!pipelineState) {
|
||||
return nullptr;
|
||||
}
|
||||
entry = fMap.insert(desc, std::unique_ptr<Entry>(
|
||||
new Entry(fGpu, std::move(pipelineState))));
|
||||
return (*entry)->fPipelineState;
|
||||
}
|
||||
return (*entry)->fPipelineState;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "include/gpu/d3d/GrD3DTypes.h"
|
||||
#include "include/private/SkTArray.h"
|
||||
#include "src/core/SkLRUCache.h"
|
||||
#include "src/gpu/GrProgramDesc.h"
|
||||
#include "src/gpu/d3d/GrD3DDescriptorHeap.h"
|
||||
#include "src/gpu/d3d/GrD3DRootSignature.h"
|
||||
|
||||
@ -17,6 +19,7 @@
|
||||
|
||||
class GrD3DDirectCommandList;
|
||||
class GrD3DGpu;
|
||||
class GrD3DPipelineState;
|
||||
|
||||
class GrD3DResourceProvider {
|
||||
public:
|
||||
@ -31,13 +34,48 @@ public:
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE createRenderTargetView(ID3D12Resource* textureResource);
|
||||
void recycleRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE*);
|
||||
|
||||
sk_sp<GrD3DPipelineState> findOrCreateCompatiblePipelineState(GrRenderTarget*,
|
||||
const GrProgramInfo&);
|
||||
|
||||
private:
|
||||
#ifdef SK_DEBUG
|
||||
#define GR_PIPELINE_STATE_CACHE_STATS
|
||||
#endif
|
||||
|
||||
class PipelineStateCache : public ::SkNoncopyable {
|
||||
public:
|
||||
PipelineStateCache(GrD3DGpu* gpu);
|
||||
~PipelineStateCache();
|
||||
|
||||
sk_sp<GrD3DPipelineState> refPipelineState(GrRenderTarget*, const GrProgramInfo&);
|
||||
|
||||
private:
|
||||
struct Entry;
|
||||
|
||||
struct DescHash {
|
||||
uint32_t operator()(const GrProgramDesc& desc) const {
|
||||
return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
SkLRUCache<const GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
|
||||
|
||||
GrD3DGpu* fGpu;
|
||||
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
int fTotalRequests;
|
||||
int fCacheMisses;
|
||||
#endif
|
||||
};
|
||||
|
||||
GrD3DGpu* fGpu;
|
||||
|
||||
SkSTArray<4, std::unique_ptr<GrD3DDirectCommandList>> fAvailableDirectCommandLists;
|
||||
SkSTArray<4, sk_sp<GrD3DRootSignature>> fRootSignatures;
|
||||
|
||||
sk_sp<GrD3DDescriptorHeap> fRTVDescriptorHeap;
|
||||
|
||||
std::unique_ptr<PipelineStateCache> fPipelineStateCache;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user