Add GrD3DPipeline.

This allows me to separate the wrapper around the ID3D12PipelineState
from the other data we track with GrD3DPipelineState. In this way I can
create a GrD3DPipeline directly for compute experiments without worrying
about managing graphics-specific objects. In the long run, we'll
probably need GrD3DGraphicsPipelineState and GrD3DComputePipelineState.

Change-Id: I36ff90a93b6e53fae217aaca3f6e0e76d698aa57
Bug: skia:10446
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/389896
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2021-03-29 13:41:03 -04:00 committed by Skia Commit-Bot
parent 2299df2f56
commit 7b41798fd6
12 changed files with 88 additions and 50 deletions

View File

@ -743,6 +743,7 @@ skia_direct3d_sources = [
"$_src/gpu/d3d/GrD3DGpu.h",
"$_src/gpu/d3d/GrD3DOpsRenderPass.cpp",
"$_src/gpu/d3d/GrD3DOpsRenderPass.h",
"$_src/gpu/d3d/GrD3DPipeline.h",
"$_src/gpu/d3d/GrD3DPipelineState.cpp",
"$_src/gpu/d3d/GrD3DPipelineState.h",
"$_src/gpu/d3d/GrD3DPipelineStateBuilder.cpp",

View File

@ -12,7 +12,7 @@
#include "src/gpu/d3d/GrD3DBuffer.h"
#include "src/gpu/d3d/GrD3DCommandSignature.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DPipelineState.h"
#include "src/gpu/d3d/GrD3DPipeline.h"
#include "src/gpu/d3d/GrD3DRenderTarget.h"
#include "src/gpu/d3d/GrD3DTexture.h"
#include "src/gpu/d3d/GrD3DTextureResource.h"
@ -216,7 +216,7 @@ std::unique_ptr<GrD3DDirectCommandList> GrD3DDirectCommandList::Make(ID3D12Devic
GrD3DDirectCommandList::GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,
gr_cp<ID3D12GraphicsCommandList> commandList)
: GrD3DCommandList(std::move(allocator), std::move(commandList))
, fCurrentPipelineState(nullptr)
, fCurrentPipeline(nullptr)
, fCurrentRootSignature(nullptr)
, fCurrentVertexBuffer(nullptr)
, fCurrentVertexStride(0)
@ -230,7 +230,7 @@ GrD3DDirectCommandList::GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> all
}
void GrD3DDirectCommandList::onReset() {
fCurrentPipelineState = nullptr;
fCurrentPipeline = nullptr;
fCurrentRootSignature = nullptr;
fCurrentVertexBuffer = nullptr;
fCurrentVertexStride = 0;
@ -243,12 +243,12 @@ void GrD3DDirectCommandList::onReset() {
fCurrentSamplerDescriptorHeap = nullptr;
}
void GrD3DDirectCommandList::setPipelineState(sk_sp<GrD3DPipelineState> pipelineState) {
void GrD3DDirectCommandList::setPipelineState(const sk_sp<GrD3DPipeline>& pipeline) {
SkASSERT(fIsActive);
if (pipelineState.get() != fCurrentPipelineState) {
fCommandList->SetPipelineState(pipelineState->pipelineState());
this->addResource(std::move(pipelineState));
fCurrentPipelineState = pipelineState.get();
if (pipeline.get() != fCurrentPipeline) {
fCommandList->SetPipelineState(pipeline->d3dPipelineState());
this->addResource(std::move(pipeline));
fCurrentPipeline = pipeline.get();
this->setDefaultSamplePositions();
}
}

View File

@ -20,7 +20,7 @@ class GrD3DGpu;
class GrD3DBuffer;
class GrD3DCommandSignature;
class GrD3DConstantRingBuffer;
class GrD3DPipelineState;
class GrD3DPipeline;
class GrD3DRenderTarget;
class GrD3DRootSignature;
class GrD3DAttachment;
@ -149,7 +149,7 @@ public:
~GrD3DDirectCommandList() override = default;
void setPipelineState(sk_sp<GrD3DPipelineState> pipelineState);
void setPipelineState(const sk_sp<GrD3DPipeline>& pipeline);
void setStencilRef(unsigned int stencilRef);
void setBlendFactor(const float blendFactor[4]);
@ -200,7 +200,7 @@ private:
void onReset() override;
const GrD3DPipelineState* fCurrentPipelineState;
const GrD3DPipeline* fCurrentPipeline;
const GrD3DRootSignature* fCurrentRootSignature;
const GrBuffer* fCurrentVertexBuffer;
size_t fCurrentVertexStride;

View File

@ -182,7 +182,7 @@ bool GrD3DOpsRenderPass::onBindPipeline(const GrProgramInfo& info, const SkRect&
}
fGpu->currentCommandList()->setGraphicsRootSignature(fCurrentPipelineState->rootSignature());
fGpu->currentCommandList()->setPipelineState(fCurrentPipelineState);
fGpu->currentCommandList()->setPipelineState(fCurrentPipelineState->pipeline());
if (info.pipeline().isHWAntialiasState()) {
fGpu->currentCommandList()->setDefaultSamplePositions();
} else {

View File

@ -63,7 +63,7 @@ private:
GrD3DGpu* fGpu;
sk_sp<GrD3DPipelineState> fCurrentPipelineState;
GrD3DPipelineState* fCurrentPipelineState = nullptr;
SkIRect fBounds;
SkIRect fCurrentPipelineBounds;

View File

@ -0,0 +1,43 @@
/*
* 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 GrD3DPipeline_DEFINED
#define GrD3DPipeline_DEFINED
#include "include/gpu/d3d/GrD3DTypes.h"
#include "src/gpu/GrManagedResource.h"
class GrD3DPipeline : public GrManagedResource {
public:
static sk_sp<GrD3DPipeline> Make(gr_cp<ID3D12PipelineState> pipelineState) {
return sk_sp<GrD3DPipeline>(new GrD3DPipeline(std::move(pipelineState)));
}
#ifdef SK_TRACE_MANAGED_RESOURCES
/** Output a human-readable dump of this resource's information
*/
void dumpInfo() const override {
SkDebugf("GrD3DPipeline: %p (%d refs)\n", fPipelineState.get(), this->getRefCnt());
}
#endif
// This will be called right before this class is destroyed and there is no reason to explicitly
// release the fPipelineState cause the gr_cp will handle that in the dtor.
void freeGPUData() const override {}
ID3D12PipelineState* d3dPipelineState() const { return fPipelineState.get(); }
private:
GrD3DPipeline(gr_cp<ID3D12PipelineState> pipelineState)
: fPipelineState(std::move(pipelineState)) {
}
gr_cp<ID3D12PipelineState> fPipelineState;
using INHERITED = GrManagedResource;
};
#endif

View File

@ -12,6 +12,7 @@
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/d3d/GrD3DBuffer.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DPipeline.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
#include "src/gpu/d3d/GrD3DTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
@ -19,7 +20,7 @@
#include "src/gpu/glsl/GrGLSLXferProcessor.h"
GrD3DPipelineState::GrD3DPipelineState(
gr_cp<ID3D12PipelineState> pipelineState,
sk_sp<GrD3DPipeline> pipeline,
sk_sp<GrD3DRootSignature> rootSignature,
const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
const UniformInfoArray& uniforms, uint32_t uniformSize,
@ -29,7 +30,7 @@ GrD3DPipelineState::GrD3DPipelineState(
std::vector<std::unique_ptr<GrGLSLFragmentProcessor>> fpImpls,
size_t vertexStride,
size_t instanceStride)
: fPipelineState(std::move(pipelineState))
: fPipeline(std::move(pipeline))
, fRootSignature(std::move(rootSignature))
, fBuiltinUniformHandles(builtinUniformHandles)
, fGeometryProcessor(std::move(geometryProcessor))

View File

@ -19,14 +19,15 @@
class GrD3DDirectCommandList;
class GrD3DGpu;
class GrD3DPipeline;
class GrD3DRootSignature;
class GrProgramInfo;
class GrD3DPipelineState : public GrManagedResource {
class GrD3DPipelineState {
public:
using UniformInfoArray = GrD3DPipelineStateDataManager::UniformInfoArray;
GrD3DPipelineState(gr_cp<ID3D12PipelineState> pipelineState,
GrD3DPipelineState(sk_sp<GrD3DPipeline> pipeline,
sk_sp<GrD3DRootSignature> rootSignature,
const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
const UniformInfoArray& uniforms,
@ -38,19 +39,7 @@ public:
size_t vertexStride,
size_t instanceStride);
#ifdef SK_TRACE_MANAGED_RESOURCES
/** Output a human-readable dump of this resource's information
*/
void dumpInfo() const override {
SkDebugf("GrD3DPipelineState: %p (%d refs)\n", fPipelineState.get(), this->getRefCnt());
}
#endif
// This will be called right before this class is destroyed and there is no reason to explicitly
// release the fPipelineState cause the gr_cp will handle that in the dtor.
void freeGPUData() const override {}
ID3D12PipelineState* pipelineState() const { return fPipelineState.get(); }
const sk_sp<GrD3DPipeline>& pipeline() const { return fPipeline; }
const sk_sp<GrD3DRootSignature>& rootSignature() const { return fRootSignature; }
void setAndBindConstants(GrD3DGpu*, const GrRenderTarget*, const GrProgramInfo&);
@ -110,7 +99,7 @@ private:
// Helper for setData() that sets the view matrix and loads the render target height uniform
void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin);
gr_cp<ID3D12PipelineState> fPipelineState;
sk_sp<GrD3DPipeline> fPipeline;
sk_sp<GrD3DRootSignature> fRootSignature;
// Tracks the current render target uniforms stored in the vertex buffer.

View File

@ -19,6 +19,7 @@
#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DPipeline.h"
#include "src/gpu/d3d/GrD3DRenderTarget.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
#include "src/gpu/d3d/GrD3DUtil.h"
@ -26,7 +27,7 @@
#include <d3dcompiler.h>
sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::MakePipelineState(
std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::MakePipelineState(
GrD3DGpu* gpu,
GrRenderTarget* renderTarget,
const GrProgramDesc& desc,
@ -545,7 +546,7 @@ gr_cp<ID3D12PipelineState> create_pipeline_state(
static constexpr SkFourByteTag kHLSL_Tag = SkSetFourByteTag('H', 'L', 'S', 'L');
static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
TRACE_EVENT0("skia.shaders", TRACE_FUNC);
// We need to enable the following extensions so that the compiler can correctly make spir-v
@ -652,8 +653,10 @@ sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
fGpu, fProgramInfo, rootSig, std::move(shaders[kVertex_GrShaderType]),
std::move(shaders[kGeometry_GrShaderType]), std::move(shaders[kFragment_GrShaderType]),
rt->dxgiFormat(), rt->stencilDxgiFormat(), rt->sampleQualityPattern());
sk_sp<GrD3DPipeline> pipeline = GrD3DPipeline::Make(std::move(pipelineState));
return sk_sp<GrD3DPipelineState>(new GrD3DPipelineState(std::move(pipelineState),
return std::unique_ptr<GrD3DPipelineState>(
new GrD3DPipelineState(std::move(pipeline),
std::move(rootSig),
fUniformHandles,
fUniformHandler.fUniforms,

View File

@ -27,10 +27,10 @@ public:
*
* @return the created pipeline if generation was successful; nullptr otherwise
*/
static sk_sp<GrD3DPipelineState> MakePipelineState(GrD3DGpu*,
GrRenderTarget*,
const GrProgramDesc&,
const GrProgramInfo&);
static std::unique_ptr<GrD3DPipelineState> MakePipelineState(GrD3DGpu*,
GrRenderTarget*,
const GrProgramDesc&,
const GrProgramInfo&);
const GrCaps* caps() const override;
@ -45,7 +45,7 @@ private:
GrD3DPipelineStateBuilder(GrD3DGpu*, GrRenderTarget*, const GrProgramDesc&,
const GrProgramInfo&);
sk_sp<GrD3DPipelineState> finalize();
std::unique_ptr<GrD3DPipelineState> finalize();
bool loadHLSLFromCache(SkReadBuffer* reader, gr_cp<ID3DBlob> shaders[]);

View File

@ -193,7 +193,7 @@ sk_sp<GrD3DDescriptorTable> GrD3DResourceProvider::findOrCreateSamplerTable(
return fShaderResourceDescriptorTableCache.findOrCreateDescTable(samplers, createFunc);
}
sk_sp<GrD3DPipelineState> GrD3DResourceProvider::findOrCreateCompatiblePipelineState(
GrD3DPipelineState* GrD3DResourceProvider::findOrCreateCompatiblePipelineState(
GrRenderTarget* rt, const GrProgramInfo& info) {
return fPipelineStateCache->refPipelineState(rt, info);
}
@ -230,11 +230,11 @@ static const bool c_DisplayMtlPipelineCache{false};
#endif
struct GrD3DResourceProvider::PipelineStateCache::Entry {
Entry(GrD3DGpu* gpu, sk_sp<GrD3DPipelineState> pipelineState)
Entry(GrD3DGpu* gpu, std::unique_ptr<GrD3DPipelineState> pipelineState)
: fGpu(gpu), fPipelineState(std::move(pipelineState)) {}
GrD3DGpu* fGpu;
sk_sp<GrD3DPipelineState> fPipelineState;
std::unique_ptr<GrD3DPipelineState> fPipelineState;
};
GrD3DResourceProvider::PipelineStateCache::PipelineStateCache(GrD3DGpu* gpu)
@ -265,7 +265,7 @@ void GrD3DResourceProvider::PipelineStateCache::release() {
fMap.reset();
}
sk_sp<GrD3DPipelineState> GrD3DResourceProvider::PipelineStateCache::refPipelineState(
GrD3DPipelineState* GrD3DResourceProvider::PipelineStateCache::refPipelineState(
GrRenderTarget* renderTarget, const GrProgramInfo& programInfo) {
#ifdef GR_PIPELINE_STATE_CACHE_STATS
++fTotalRequests;
@ -284,16 +284,16 @@ sk_sp<GrD3DPipelineState> GrD3DResourceProvider::PipelineStateCache::refPipeline
#ifdef GR_PIPELINE_STATE_CACHE_STATS
++fCacheMisses;
#endif
sk_sp<GrD3DPipelineState> pipelineState = GrD3DPipelineStateBuilder::MakePipelineState(
fGpu, renderTarget, desc, programInfo);
std::unique_ptr<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).get();
}
return (*entry)->fPipelineState;
return ((*entry)->fPipelineState).get();
}
void GrD3DResourceProvider::PipelineStateCache::markPipelineStateUniformsDirty() {

View File

@ -17,6 +17,7 @@
#include "src/gpu/d3d/GrD3DCommandSignature.h"
#include "src/gpu/d3d/GrD3DCpuDescriptorManager.h"
#include "src/gpu/d3d/GrD3DDescriptorTableManager.h"
#include "src/gpu/d3d/GrD3DPipeline.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
#include "src/gpu/d3d/GrD3DUtil.h"
@ -66,8 +67,8 @@ public:
return &fDescriptorTableManager;
}
sk_sp<GrD3DPipelineState> findOrCreateCompatiblePipelineState(GrRenderTarget*,
const GrProgramInfo&);
GrD3DPipelineState* findOrCreateCompatiblePipelineState(GrRenderTarget*,
const GrProgramInfo&);
D3D12_GPU_VIRTUAL_ADDRESS uploadConstantData(void* data, size_t size);
void prepForSubmit();
@ -89,7 +90,7 @@ private:
~PipelineStateCache();
void release();
sk_sp<GrD3DPipelineState> refPipelineState(GrRenderTarget*, const GrProgramInfo&);
GrD3DPipelineState* refPipelineState(GrRenderTarget*, const GrProgramInfo&);
void markPipelineStateUniformsDirty();