From 3eadce263ccd27258dff997a587aab8593114691 Mon Sep 17 00:00:00 2001 From: Jim Van Verth <jvanverth@google.com> Date: Mon, 1 Jun 2020 11:34:49 -0400 Subject: [PATCH] Create ring buffer for managing D3D uniforms. * Adds a base class for the ring buffer (to be used by Metal as well), which tracks the current available space. APIs will need to implement creation of the buffer in the subclass. * The API implementation will need to store SubmitData on command buffer submit, and then pass it to finishSubmit when the command buffer finishes. Change-Id: I4cc5e4a72d259ee9d15dac0e964819d4562da3d7 Bug: skia:9935 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291936 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com> --- gn/gpu.gni | 4 + src/gpu/GrRingBuffer.cpp | 89 +++++++++++++++++++ src/gpu/GrRingBuffer.h | 69 ++++++++++++++ src/gpu/d3d/GrD3DCommandList.cpp | 17 +++- src/gpu/d3d/GrD3DCommandList.h | 7 ++ src/gpu/d3d/GrD3DConstantRingBuffer.cpp | 30 +++++++ src/gpu/d3d/GrD3DConstantRingBuffer.h | 33 +++++++ src/gpu/d3d/GrD3DGpu.cpp | 2 + src/gpu/d3d/GrD3DOpsRenderPass.cpp | 2 +- src/gpu/d3d/GrD3DPipelineState.cpp | 5 +- src/gpu/d3d/GrD3DPipelineState.h | 2 +- src/gpu/d3d/GrD3DPipelineStateDataManager.cpp | 13 +++ src/gpu/d3d/GrD3DPipelineStateDataManager.h | 7 +- src/gpu/d3d/GrD3DResourceProvider.cpp | 31 ++++++- src/gpu/d3d/GrD3DResourceProvider.h | 6 ++ 15 files changed, 310 insertions(+), 7 deletions(-) create mode 100644 src/gpu/GrRingBuffer.cpp create mode 100644 src/gpu/GrRingBuffer.h create mode 100644 src/gpu/d3d/GrD3DConstantRingBuffer.cpp create mode 100644 src/gpu/d3d/GrD3DConstantRingBuffer.h diff --git a/gn/gpu.gni b/gn/gpu.gni index e81d03ea45..ab27ce4cd1 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -179,6 +179,8 @@ skia_gpu_sources = [ "$_src/gpu/GrResourceProvider.cpp", "$_src/gpu/GrResourceProvider.h", "$_src/gpu/GrResourceProviderPriv.h", + "$_src/gpu/GrRingBuffer.cpp", + "$_src/gpu/GrRingBuffer.h", "$_src/gpu/GrSPIRVUniformHandler.cpp", "$_src/gpu/GrSPIRVUniformHandler.h", "$_src/gpu/GrSPIRVVaryingHandler.cpp", @@ -755,6 +757,8 @@ skia_direct3d_sources = [ "$_src/gpu/d3d/GrD3DCaps.h", "$_src/gpu/d3d/GrD3DCommandList.cpp", "$_src/gpu/d3d/GrD3DCommandList.h", + "$_src/gpu/d3d/GrD3DConstantRingBuffer.cpp", + "$_src/gpu/d3d/GrD3DConstantRingBuffer.h", "$_src/gpu/d3d/GrD3DCpuDescriptorManager.cpp", "$_src/gpu/d3d/GrD3DCpuDescriptorManager.h", "$_src/gpu/d3d/GrD3DDescriptorHeap.cpp", diff --git a/src/gpu/GrRingBuffer.cpp b/src/gpu/GrRingBuffer.cpp new file mode 100644 index 0000000000..c9014286de --- /dev/null +++ b/src/gpu/GrRingBuffer.cpp @@ -0,0 +1,89 @@ +/* + * 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/GrRingBuffer.h" + +// Get offset into buffer that has enough space for size +// Returns fTotalSize if no space +size_t GrRingBuffer::getAllocationOffset(size_t size) { + // capture current state locally (because fTail could be overwritten by the completion handler) + size_t head, tail; + SkAutoSpinlock lock(fMutex); + head = fHead; + tail = fTail; + + // The head and tail indices increment without bound, wrapping with overflow, + // so we need to mod them down to the actual bounds of the allocation to determine + // which blocks are available. + size_t modHead = head & (fTotalSize - 1); + size_t modTail = tail & (fTotalSize - 1); + + bool full = (head != tail && modHead == modTail); + + if (full) { + return fTotalSize; + } + + // case 1: free space lies at the beginning and/or the end of the buffer + if (modHead >= modTail) { + // check for room at the end + if (fTotalSize - modHead < size) { + // no room at the end, check the beginning + if (modTail < size) { + // no room at the beginning + return fTotalSize; + } + // we are going to allocate from the beginning, adjust head to '0' position + head += fTotalSize - modHead; + modHead = 0; + } + // case 2: free space lies in the middle of the buffer, check for room there + } else if (modTail - modHead < size) { + // no room in the middle + return fTotalSize; + } + + fHead = GrAlignTo(head + size, fAlignment); + return modHead; +} + +GrRingBuffer::Slice GrRingBuffer::suballocate(size_t size) { + size_t offset = this->getAllocationOffset(size); + if (offset < fTotalSize) { + return { fBuffer, offset }; + } + + // Try to grow allocation (old allocation will age out). + fTotalSize *= 2; + fBuffer = this->createBuffer(fTotalSize); + SkASSERT(fBuffer); + SkAutoSpinlock lock(fMutex); + fHead = 0; + fTail = 0; + fGenID++; + offset = this->getAllocationOffset(size); + SkASSERT(offset < fTotalSize); + return { fBuffer, offset }; +} + +// used when current command buffer/command list is submitted +GrRingBuffer::SubmitData GrRingBuffer::startSubmit() { + SubmitData submitData; + SkAutoSpinlock lock(fMutex); + submitData.fBuffer = fBuffer; + submitData.fLastHead = fHead; + submitData.fGenID = fGenID; + return submitData; +} + +// used when current command buffer/command list is completed +void GrRingBuffer::finishSubmit(const GrRingBuffer::SubmitData& submitData) { + SkAutoSpinlock lock(fMutex); + if (submitData.fGenID == fGenID) { + fTail = submitData.fLastHead; + } +} diff --git a/src/gpu/GrRingBuffer.h b/src/gpu/GrRingBuffer.h new file mode 100644 index 0000000000..f8169220ea --- /dev/null +++ b/src/gpu/GrRingBuffer.h @@ -0,0 +1,69 @@ +/* + * 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 GrRingBuffer_DEFINED +#define GrRingBuffer_DEFINED + +#include "src/gpu/GrGpuBuffer.h" + +#include "include/private/SkSpinlock.h" + +/** + * A wrapper for a GPU buffer that allocates slices in a continuous ring + */ +class GrRingBuffer : public SkRefCnt { +public: + GrRingBuffer(sk_sp<GrGpuBuffer> buffer, size_t size, size_t alignment) + : fBuffer(std::move(buffer)) + , fTotalSize(size) + , fAlignment(alignment) + , fHead(0) + , fTail(0) + , fGenID(0) { + // We increment fHead and fTail without bound and let overflow handle any wrapping. + // Because of this, size needs to be a power of two. + SkASSERT(SkIsPow2(size)); + } + virtual ~GrRingBuffer() = default; + + struct Slice { + sk_sp<GrGpuBuffer> fBuffer; + size_t fOffset; + }; + + Slice suballocate(size_t size); + + class SubmitData { + public: + GrGpuBuffer* buffer() const { return fBuffer.get(); } + private: + friend class GrRingBuffer; + sk_sp<GrGpuBuffer> fBuffer; + size_t fLastHead; + size_t fGenID; + }; + // Backends should call startSubmit() at submit time, and finishSubmit() when the + // command buffer/list finishes. + SubmitData startSubmit(); + void finishSubmit(const SubmitData&); + + size_t size() const { return fTotalSize; } + +private: + virtual sk_sp<GrGpuBuffer> createBuffer(size_t size) = 0; + size_t getAllocationOffset(size_t size); + + sk_sp<GrGpuBuffer> fBuffer; + size_t fTotalSize; + size_t fAlignment; + size_t fHead SK_GUARDED_BY(fMutex); // where we start allocating + size_t fTail SK_GUARDED_BY(fMutex); // where we start deallocating + uint64_t fGenID SK_GUARDED_BY(fMutex); // incremented when createBuffer is called + SkSpinlock fMutex; +}; + +#endif diff --git a/src/gpu/d3d/GrD3DCommandList.cpp b/src/gpu/d3d/GrD3DCommandList.cpp index 541b973d27..4703bbbbdd 100644 --- a/src/gpu/d3d/GrD3DCommandList.cpp +++ b/src/gpu/d3d/GrD3DCommandList.cpp @@ -200,7 +200,8 @@ GrD3DDirectCommandList::GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> all , fCurrentVertexStride(0) , fCurrentInstanceBuffer(nullptr) , fCurrentInstanceStride(0) - , fCurrentIndexBuffer(nullptr) { + , fCurrentIndexBuffer(nullptr) + , fCurrentConstantRingBuffer(nullptr) { } void GrD3DDirectCommandList::onReset() { @@ -210,6 +211,10 @@ void GrD3DDirectCommandList::onReset() { fCurrentInstanceBuffer = nullptr; fCurrentInstanceStride = 0; fCurrentIndexBuffer = nullptr; + if (fCurrentConstantRingBuffer) { + fCurrentConstantRingBuffer->finishSubmit(fConstantRingBufferSubmitData); + fCurrentConstantRingBuffer = nullptr; + } } void GrD3DDirectCommandList::setPipelineState(sk_sp<GrD3DPipelineState> pipelineState) { @@ -218,6 +223,16 @@ void GrD3DDirectCommandList::setPipelineState(sk_sp<GrD3DPipelineState> pipeline this->addResource(std::move(pipelineState)); } +void GrD3DDirectCommandList::setCurrentConstantBuffer( + const sk_sp<GrD3DConstantRingBuffer>& constantBuffer) { + fCurrentConstantRingBuffer = constantBuffer.get(); + if (fCurrentConstantRingBuffer) { + fConstantRingBufferSubmitData = constantBuffer->startSubmit(); + this->addResource( + static_cast<GrD3DBuffer*>(fConstantRingBufferSubmitData.buffer())->resource()); + } +} + void GrD3DDirectCommandList::setStencilRef(unsigned int stencilRef) { SkASSERT(fIsActive); fCommandList->OMSetStencilRef(stencilRef); diff --git a/src/gpu/d3d/GrD3DCommandList.h b/src/gpu/d3d/GrD3DCommandList.h index e662437d1f..86d51da7e0 100644 --- a/src/gpu/d3d/GrD3DCommandList.h +++ b/src/gpu/d3d/GrD3DCommandList.h @@ -12,11 +12,13 @@ #include "include/gpu/d3d/GrD3DTypes.h" #include "include/private/SkColorData.h" #include "src/gpu/GrManagedResource.h" +#include "src/gpu/d3d/GrD3DConstantRingBuffer.h" #include <memory> class GrD3DGpu; class GrD3DBuffer; +class GrD3DConstantRingBuffer; class GrD3DPipelineState; class GrD3DRenderTarget; class GrD3DRootSignature; @@ -122,6 +124,8 @@ public: void setPipelineState(sk_sp<GrD3DPipelineState> pipelineState); + void setCurrentConstantBuffer(const sk_sp<GrD3DConstantRingBuffer>& constantBuffer); + void setStencilRef(unsigned int stencilRef); void setBlendFactor(const float blendFactor[4]); void setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology); @@ -154,6 +158,9 @@ private: const GrD3DBuffer* fCurrentInstanceBuffer; size_t fCurrentInstanceStride; const GrD3DBuffer* fCurrentIndexBuffer; + + GrD3DConstantRingBuffer* fCurrentConstantRingBuffer; + GrD3DConstantRingBuffer::SubmitData fConstantRingBufferSubmitData; }; class GrD3DCopyCommandList : public GrD3DCommandList { diff --git a/src/gpu/d3d/GrD3DConstantRingBuffer.cpp b/src/gpu/d3d/GrD3DConstantRingBuffer.cpp new file mode 100644 index 0000000000..cf719c7745 --- /dev/null +++ b/src/gpu/d3d/GrD3DConstantRingBuffer.cpp @@ -0,0 +1,30 @@ +/* + * 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/GrD3DConstantRingBuffer.h" + +#include "src/gpu/d3d/GrD3DBuffer.h" +#include "src/gpu/d3d/GrD3DGpu.h" + +sk_sp<GrD3DConstantRingBuffer> GrD3DConstantRingBuffer::Make(GrD3DGpu* gpu, size_t size, + size_t alignment) { + sk_sp<GrGpuBuffer> buffer = GrD3DBuffer::Make(gpu, size, GrGpuBufferType::kVertex, + kDynamic_GrAccessPattern); + if (!buffer) { + return nullptr; + } + + return sk_sp<GrD3DConstantRingBuffer>(new GrD3DConstantRingBuffer(std::move(buffer), size, + alignment, gpu)); +} + +sk_sp<GrGpuBuffer> GrD3DConstantRingBuffer::createBuffer(size_t size) { + // Make sure the old buffer is added to the current command list + fGpu->resourceProvider().prepForSubmit(); + + return GrD3DBuffer::Make(fGpu, size, GrGpuBufferType::kVertex, kDynamic_GrAccessPattern); +} diff --git a/src/gpu/d3d/GrD3DConstantRingBuffer.h b/src/gpu/d3d/GrD3DConstantRingBuffer.h new file mode 100644 index 0000000000..0a4bbf6067 --- /dev/null +++ b/src/gpu/d3d/GrD3DConstantRingBuffer.h @@ -0,0 +1,33 @@ +/* + * 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 GrD3DConstantRingBuffer_DEFINED + +#define GrD3DConstantRingBuffer_DEFINED + +#include "src/gpu/GrRingBuffer.h" + +class GrD3DGpu; + +class GrD3DConstantRingBuffer : public GrRingBuffer { +public: + static sk_sp<GrD3DConstantRingBuffer> Make(GrD3DGpu* gpu, size_t size, size_t alignment); + +private: + GrD3DConstantRingBuffer(sk_sp<GrGpuBuffer> buffer, size_t size, size_t alignment, GrD3DGpu* gpu) + : INHERITED(std::move(buffer), size, alignment) + , fGpu(gpu) {} + ~GrD3DConstantRingBuffer() override = default; + + sk_sp<GrGpuBuffer> createBuffer(size_t size) override; + + GrD3DGpu* fGpu; + + typedef GrRingBuffer INHERITED; +}; + +#endif diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp index c41ae081e0..7a50f01008 100644 --- a/src/gpu/d3d/GrD3DGpu.cpp +++ b/src/gpu/d3d/GrD3DGpu.cpp @@ -111,6 +111,8 @@ GrOpsRenderPass* GrD3DGpu::getOpsRenderPass( bool GrD3DGpu::submitDirectCommandList(SyncQueue sync) { SkASSERT(fCurrentDirectCommandList); + fResourceProvider.prepForSubmit(); + GrD3DDirectCommandList::SubmitResult result = fCurrentDirectCommandList->submit(fQueue.get()); if (result == GrD3DDirectCommandList::SubmitResult::kFailure) { return false; diff --git a/src/gpu/d3d/GrD3DOpsRenderPass.cpp b/src/gpu/d3d/GrD3DOpsRenderPass.cpp index 45315e00c4..7280d58ab8 100644 --- a/src/gpu/d3d/GrD3DOpsRenderPass.cpp +++ b/src/gpu/d3d/GrD3DOpsRenderPass.cpp @@ -160,7 +160,7 @@ bool GrD3DOpsRenderPass::onBindPipeline(const GrProgramInfo& info, const SkRect& return false; } - fCurrentPipelineState->setData(fRenderTarget, info); + fCurrentPipelineState->setData(fGpu, fRenderTarget, info); fGpu->currentCommandList()->setGraphicsRootSignature(fCurrentPipelineState->rootSignature()); fGpu->currentCommandList()->setPipelineState(fCurrentPipelineState); diff --git a/src/gpu/d3d/GrD3DPipelineState.cpp b/src/gpu/d3d/GrD3DPipelineState.cpp index c140e7fd82..f025fed641 100644 --- a/src/gpu/d3d/GrD3DPipelineState.cpp +++ b/src/gpu/d3d/GrD3DPipelineState.cpp @@ -42,7 +42,7 @@ GrD3DPipelineState::GrD3DPipelineState( , fVertexStride(vertexStride) , fInstanceStride(instanceStride) {} -void GrD3DPipelineState::setData(const GrRenderTarget* renderTarget, +void GrD3DPipelineState::setData(GrD3DGpu* gpu, const GrRenderTarget* renderTarget, const GrProgramInfo& programInfo) { this->setRenderTargetState(renderTarget, programInfo.origin()); @@ -62,6 +62,9 @@ void GrD3DPipelineState::setData(const GrRenderTarget* renderTarget, fXferProcessor->setData(fDataManager, programInfo.pipeline().getXferProcessor(), dstTexture, offset); } + + // TODO: use returned virtual address to create a CBV and set in command list + (void) fDataManager.uploadConstants(gpu); } void GrD3DPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) { diff --git a/src/gpu/d3d/GrD3DPipelineState.h b/src/gpu/d3d/GrD3DPipelineState.h index ecd8a3b3f0..a62d44545c 100644 --- a/src/gpu/d3d/GrD3DPipelineState.h +++ b/src/gpu/d3d/GrD3DPipelineState.h @@ -52,7 +52,7 @@ public: ID3D12PipelineState* pipelineState() const { return fPipelineState.get(); } const sk_sp<GrD3DRootSignature>& rootSignature() const { return fRootSignature; } - void setData(const GrRenderTarget* renderTarget, const GrProgramInfo& programInfo); + void setData(GrD3DGpu*, const GrRenderTarget* renderTarget, const GrProgramInfo& programInfo); void setAndBindTextures(const GrPrimitiveProcessor& primProc, const GrSurfaceProxy* const primProcTextures[], diff --git a/src/gpu/d3d/GrD3DPipelineStateDataManager.cpp b/src/gpu/d3d/GrD3DPipelineStateDataManager.cpp index 9326099646..a611d7c315 100644 --- a/src/gpu/d3d/GrD3DPipelineStateDataManager.cpp +++ b/src/gpu/d3d/GrD3DPipelineStateDataManager.cpp @@ -7,6 +7,9 @@ #include "src/gpu/d3d/GrD3DPipelineStateDataManager.h" +#include "src/gpu/d3d/GrD3DGpu.h" +#include "src/gpu/d3d/GrD3DResourceProvider.h" + GrD3DPipelineStateDataManager::GrD3DPipelineStateDataManager(const UniformInfoArray& uniforms, uint32_t uniformSize) : INHERITED(uniforms.count(), uniformSize) { @@ -26,3 +29,13 @@ GrD3DPipelineStateDataManager::GrD3DPipelineStateDataManager(const UniformInfoAr ++i; } } + +D3D12_GPU_VIRTUAL_ADDRESS GrD3DPipelineStateDataManager::uploadConstants(GrD3DGpu* gpu) { + if (fUniformsDirty) { + fConstantBufferAddress = gpu->resourceProvider().uploadConstantData(fUniformData.get(), + fUniformSize); + fUniformsDirty = false; + } + + return fConstantBufferAddress; +} diff --git a/src/gpu/d3d/GrD3DPipelineStateDataManager.h b/src/gpu/d3d/GrD3DPipelineStateDataManager.h index 14d9c2ea6a..15a41abc42 100644 --- a/src/gpu/d3d/GrD3DPipelineStateDataManager.h +++ b/src/gpu/d3d/GrD3DPipelineStateDataManager.h @@ -13,6 +13,9 @@ #include "include/gpu/d3d/GrD3DTypes.h" #include "src/gpu/GrSPIRVUniformHandler.h" +class GrD3DConstantRingBuffer; +class GrD3DGpu; + class GrD3DPipelineStateDataManager : public GrUniformDataManager { public: typedef GrSPIRVUniformHandler::UniformInfoArray UniformInfoArray; @@ -20,9 +23,11 @@ public: GrD3DPipelineStateDataManager(const UniformInfoArray&, uint32_t uniformSize); - // TODO: upload to uniform buffer + D3D12_GPU_VIRTUAL_ADDRESS uploadConstants(GrD3DGpu* gpu); private: + D3D12_GPU_VIRTUAL_ADDRESS fConstantBufferAddress; + typedef GrUniformDataManager INHERITED; }; diff --git a/src/gpu/d3d/GrD3DResourceProvider.cpp b/src/gpu/d3d/GrD3DResourceProvider.cpp index f7b5543922..f6810deb46 100644 --- a/src/gpu/d3d/GrD3DResourceProvider.cpp +++ b/src/gpu/d3d/GrD3DResourceProvider.cpp @@ -9,6 +9,7 @@ #include "include/gpu/GrContextOptions.h" #include "src/gpu/GrContextPriv.h" +#include "src/gpu/d3d/GrD3DBuffer.h" #include "src/gpu/d3d/GrD3DCommandList.h" #include "src/gpu/d3d/GrD3DGpu.h" #include "src/gpu/d3d/GrD3DPipelineState.h" @@ -17,8 +18,7 @@ GrD3DResourceProvider::GrD3DResourceProvider(GrD3DGpu* gpu) : fGpu(gpu) , fCpuDescriptorManager(gpu) - , fPipelineStateCache(new PipelineStateCache(gpu)) { -} + , fPipelineStateCache(new PipelineStateCache(gpu)) {} std::unique_ptr<GrD3DDirectCommandList> GrD3DResourceProvider::findOrCreateDirectCommandList() { if (fAvailableDirectCommandLists.count()) { @@ -99,6 +99,33 @@ sk_sp<GrD3DPipelineState> GrD3DResourceProvider::findOrCreateCompatiblePipelineS return fPipelineStateCache->refPipelineState(rt, info); } +D3D12_GPU_VIRTUAL_ADDRESS GrD3DResourceProvider::uploadConstantData(void* data, size_t size) { + // constant size has to be aligned to 256 + constexpr int kConstantAlignment = 256; + + // Due to dependency on the resource cache we can't initialize this in the constructor, so + // we do so it here. + if (!fConstantBuffer) { + fConstantBuffer = GrD3DConstantRingBuffer::Make(fGpu, 128 * 1024, kConstantAlignment); + SkASSERT(fConstantBuffer); + } + + // upload the data + size_t paddedSize = GrAlignTo(size, kConstantAlignment); + GrRingBuffer::Slice slice = fConstantBuffer->suballocate(paddedSize); + char* destPtr = static_cast<char*>(slice.fBuffer->map()) + slice.fOffset; + memcpy(destPtr, data, size); + + // create the associated constant buffer view descriptor + GrD3DBuffer* d3dBuffer = static_cast<GrD3DBuffer*>(slice.fBuffer.get()); + D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = d3dBuffer->d3dResource()->GetGPUVirtualAddress(); + return gpuAddress + slice.fOffset; +} + +void GrD3DResourceProvider::prepForSubmit() { + fGpu->currentCommandList()->setCurrentConstantBuffer(fConstantBuffer); +} + //////////////////////////////////////////////////////////////////////////////////////////////// #ifdef GR_PIPELINE_STATE_CACHE_STATS diff --git a/src/gpu/d3d/GrD3DResourceProvider.h b/src/gpu/d3d/GrD3DResourceProvider.h index 5e7db628ce..0d7b8289fa 100644 --- a/src/gpu/d3d/GrD3DResourceProvider.h +++ b/src/gpu/d3d/GrD3DResourceProvider.h @@ -12,6 +12,7 @@ #include "include/private/SkTArray.h" #include "src/core/SkLRUCache.h" #include "src/gpu/GrProgramDesc.h" +#include "src/gpu/d3d/GrD3DConstantRingBuffer.h" #include "src/gpu/d3d/GrD3DCpuDescriptorManager.h" #include "src/gpu/d3d/GrD3DRootSignature.h" @@ -51,6 +52,9 @@ public: sk_sp<GrD3DPipelineState> findOrCreateCompatiblePipelineState(GrRenderTarget*, const GrProgramInfo&); + D3D12_GPU_VIRTUAL_ADDRESS uploadConstantData(void* data, size_t size); + void prepForSubmit(); + private: #ifdef SK_DEBUG #define GR_PIPELINE_STATE_CACHE_STATS @@ -89,6 +93,8 @@ private: GrD3DCpuDescriptorManager fCpuDescriptorManager; + sk_sp<GrD3DConstantRingBuffer> fConstantBuffer; + std::unique_ptr<PipelineStateCache> fPipelineStateCache; };