Skip to content

Commit d342cc9

Browse files
jvanverthSkia Commit-Bot
authored and
Skia Commit-Bot
committed
Add indirect draws to D3D.
Adds GrD3D12CommandSignature, needed to pass to ExecuteIndirect(). Change-Id: I24aa395d710414eba0464aa4e2cb0a87721bcb12 Bug: skia:10482 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301378 Reviewed-by: Chris Dalton <[email protected]> Commit-Queue: Jim Van Verth <[email protected]>
1 parent e29f9e2 commit d342cc9

12 files changed

+159
-6
lines changed

gn/gpu.gni

+2
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ skia_direct3d_sources = [
764764
"$_src/gpu/d3d/GrD3DCaps.h",
765765
"$_src/gpu/d3d/GrD3DCommandList.cpp",
766766
"$_src/gpu/d3d/GrD3DCommandList.h",
767+
"$_src/gpu/d3d/GrD3DCommandSignature.cpp",
768+
"$_src/gpu/d3d/GrD3DCommandSignature.h",
767769
"$_src/gpu/d3d/GrD3DConstantRingBuffer.cpp",
768770
"$_src/gpu/d3d/GrD3DConstantRingBuffer.h",
769771
"$_src/gpu/d3d/GrD3DCpuDescriptorManager.cpp",

src/gpu/d3d/GrD3DBuffer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ void GrD3DBuffer::validate() const {
263263
SkASSERT(!fResource ||
264264
this->intendedType() == GrGpuBufferType::kVertex ||
265265
this->intendedType() == GrGpuBufferType::kIndex ||
266-
//this->intendedType() == GrGpuBufferType::kDrawIndirect ||
266+
this->intendedType() == GrGpuBufferType::kDrawIndirect ||
267267
this->intendedType() == GrGpuBufferType::kXferCpuToGpu ||
268268
this->intendedType() == GrGpuBufferType::kXferGpuToCpu);
269269
SkASSERT(!fMappedResource || !fResource ||

src/gpu/d3d/GrD3DCaps.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ GrD3DCaps::GrD3DCaps(const GrContextOptions& contextOptions, IDXGIAdapter1* adap
3333
fGpuTracingSupport = false; //TODO: figure this out
3434
fOversizedStencilSupport = false; //TODO: figure this out
3535
fDrawInstancedSupport = true;
36+
fNativeDrawIndirectSupport = true;
3637

3738
fSemaphoreSupport = true;
3839
fFenceSyncSupport = true;

src/gpu/d3d/GrD3DCommandList.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "src/gpu/GrScissorState.h"
1111
#include "src/gpu/d3d/GrD3DBuffer.h"
12+
#include "src/gpu/d3d/GrD3DCommandSignature.h"
1213
#include "src/gpu/d3d/GrD3DGpu.h"
1314
#include "src/gpu/d3d/GrD3DPipelineState.h"
1415
#include "src/gpu/d3d/GrD3DRenderTarget.h"
@@ -338,6 +339,19 @@ void GrD3DDirectCommandList::drawIndexedInstanced(unsigned int indexCount,
338339
startInstance);
339340
}
340341

342+
void GrD3DDirectCommandList::executeIndirect(const sk_sp<GrD3DCommandSignature> commandSignature,
343+
unsigned int maxCommandCount,
344+
const GrD3DBuffer* argumentBuffer,
345+
size_t argumentBufferOffset) {
346+
SkASSERT(fIsActive);
347+
this->addingWork();
348+
this->addResource(commandSignature);
349+
this->addResource(argumentBuffer->resource());
350+
fCommandList->ExecuteIndirect(commandSignature->commandSignature(), maxCommandCount,
351+
argumentBuffer->d3dResource(), argumentBufferOffset,
352+
nullptr, 0);
353+
}
354+
341355
void GrD3DDirectCommandList::clearRenderTargetView(const GrD3DRenderTarget* renderTarget,
342356
const SkPMColor4f& color,
343357
const D3D12_RECT* rect) {
@@ -382,7 +396,7 @@ void GrD3DDirectCommandList::setRenderTarget(const GrD3DRenderTarget* renderTarg
382396
}
383397

384398
void GrD3DDirectCommandList::resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
385-
UINT dstX, UINT dstY,
399+
unsigned int dstX, unsigned int dstY,
386400
const GrD3DTextureResource* srcTexture,
387401
D3D12_RECT* srcRect) {
388402
SkASSERT(dstTexture->dxgiFormat() == srcTexture->dxgiFormat());

src/gpu/d3d/GrD3DCommandList.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
class GrD3DGpu;
2020
class GrD3DBuffer;
21+
class GrD3DCommandSignature;
2122
class GrD3DConstantRingBuffer;
2223
class GrD3DPipelineState;
2324
class GrD3DRenderTarget;
@@ -149,14 +150,16 @@ class GrD3DDirectCommandList : public GrD3DCommandList {
149150
void drawIndexedInstanced(unsigned int indexCount, unsigned int instanceCount,
150151
unsigned int startIndex, unsigned int baseVertex,
151152
unsigned int startInstance);
153+
void executeIndirect(const sk_sp<GrD3DCommandSignature> commandSig, unsigned int maxCommandCnt,
154+
const GrD3DBuffer* argumentBuffer, size_t argumentBufferOffset);
152155

153156
void clearRenderTargetView(const GrD3DRenderTarget* renderTarget, const SkPMColor4f& color,
154157
const D3D12_RECT* rect);
155158
void clearDepthStencilView(const GrD3DStencilAttachment*, uint8_t stencilClearValue,
156159
const D3D12_RECT* rect);
157160
void setRenderTarget(const GrD3DRenderTarget* renderTarget);
158161
void resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
159-
UINT dstX, UINT dstY,
162+
unsigned int dstX, unsigned int dstY,
160163
const GrD3DTextureResource* srcTexture,
161164
D3D12_RECT* srcRect);
162165

src/gpu/d3d/GrD3DCommandSignature.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
*
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include "src/gpu/d3d/GrD3DCommandSignature.h"
9+
10+
#include "src/gpu/d3d/GrD3DGpu.h"
11+
12+
sk_sp<GrD3DCommandSignature> GrD3DCommandSignature::Make(GrD3DGpu* gpu, ForIndexed forIndexed,
13+
unsigned int slot) {
14+
bool indexed = (forIndexed == ForIndexed::kYes);
15+
D3D12_INDIRECT_ARGUMENT_DESC argumentDesc = {};
16+
argumentDesc.Type = indexed ? D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED
17+
: D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
18+
argumentDesc.VertexBuffer.Slot = slot;
19+
20+
D3D12_COMMAND_SIGNATURE_DESC commandSigDesc = {};
21+
commandSigDesc.ByteStride = indexed ? sizeof(D3D12_DRAW_INDEXED_ARGUMENTS)
22+
: sizeof(D3D12_DRAW_ARGUMENTS);
23+
commandSigDesc.NumArgumentDescs = 1;
24+
commandSigDesc.pArgumentDescs = &argumentDesc;
25+
commandSigDesc.NodeMask = 0;
26+
27+
gr_cp<ID3D12CommandSignature> commandSig;
28+
HRESULT hr = gpu->device()->CreateCommandSignature(&commandSigDesc, nullptr,
29+
IID_PPV_ARGS(&commandSig));
30+
if (!SUCCEEDED(hr)) {
31+
SkDebugf("Failed to create command signature.\n");
32+
return nullptr;
33+
}
34+
35+
return sk_sp<GrD3DCommandSignature>(new GrD3DCommandSignature(std::move(commandSig),
36+
forIndexed, slot));
37+
}

src/gpu/d3d/GrD3DCommandSignature.h

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
*
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#ifndef GrD3DCommandSignature_DEFINED
9+
#define GrD3DCommandSignature_DEFINED
10+
11+
#include "include/gpu/d3d/GrD3DTypes.h"
12+
#include "src/gpu/GrManagedResource.h"
13+
14+
class GrD3DGpu;
15+
16+
class GrD3DCommandSignature : public GrManagedResource {
17+
public:
18+
enum class ForIndexed : bool {
19+
kYes = true,
20+
kNo = false
21+
};
22+
static sk_sp<GrD3DCommandSignature> Make(GrD3DGpu* gpu, ForIndexed indexed, unsigned int slot);
23+
24+
bool isCompatible(ForIndexed indexed, unsigned int slot) const {
25+
return (fIndexed == indexed && fSlot == slot);
26+
}
27+
28+
ID3D12CommandSignature* commandSignature() const { return fCommandSignature.get(); }
29+
30+
#ifdef SK_TRACE_MANAGED_RESOURCES
31+
/** Output a human-readable dump of this resource's information
32+
*/
33+
void dumpInfo() const override {
34+
SkDebugf("GrD3DCommandSignature: %p, (%d refs)\n",
35+
fCommandSignature.get(), this->getRefCnt());
36+
}
37+
#endif
38+
39+
private:
40+
GrD3DCommandSignature(gr_cp<ID3D12CommandSignature> commandSignature, ForIndexed indexed,
41+
unsigned int slot)
42+
: fCommandSignature(commandSignature)
43+
, fIndexed(indexed)
44+
, fSlot(slot) {}
45+
46+
// This will be called right before this class is destroyed and there is no reason to explicitly
47+
// release the fCommandSignature cause the gr_cp will handle that in the dtor.
48+
void freeGPUData() const override {}
49+
50+
gr_cp<ID3D12CommandSignature> fCommandSignature;
51+
ForIndexed fIndexed;
52+
unsigned int fSlot;
53+
};
54+
55+
#endif

src/gpu/d3d/GrD3DOpsRenderPass.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "src/gpu/GrRenderTargetPriv.h"
1414
#include "src/gpu/GrStencilSettings.h"
1515
#include "src/gpu/d3d/GrD3DBuffer.h"
16+
#include "src/gpu/d3d/GrD3DCommandSignature.h"
1617
#include "src/gpu/d3d/GrD3DGpu.h"
1718
#include "src/gpu/d3d/GrD3DPipelineState.h"
1819
#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"
@@ -259,6 +260,26 @@ void GrD3DOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, i
259260
fGpu->stats()->incNumDraws();
260261
}
261262

263+
void GrD3DOpsRenderPass::onDrawIndirect(const GrBuffer* buffer, size_t offset, int drawCount) {
264+
constexpr unsigned int kSlot = 0;
265+
sk_sp<GrD3DCommandSignature> cmdSig = fGpu->resourceProvider().findOrCreateCommandSignature(
266+
GrD3DCommandSignature::ForIndexed::kNo, kSlot);
267+
fGpu->currentCommandList()->executeIndirect(cmdSig, drawCount,
268+
static_cast<const GrD3DBuffer*>(buffer), offset);
269+
fGpu->stats()->incNumDraws();
270+
}
271+
272+
void GrD3DOpsRenderPass::onDrawIndexedIndirect(const GrBuffer* buffer, size_t offset,
273+
int drawCount) {
274+
constexpr unsigned int kSlot = 0;
275+
sk_sp<GrD3DCommandSignature> cmdSig = fGpu->resourceProvider().findOrCreateCommandSignature(
276+
GrD3DCommandSignature::ForIndexed::kYes, kSlot);
277+
fGpu->currentCommandList()->executeIndirect(cmdSig, drawCount,
278+
static_cast<const GrD3DBuffer*>(buffer), offset);
279+
fGpu->stats()->incNumDraws();
280+
}
281+
282+
262283
static D3D12_RECT scissor_to_d3d_clear_rect(const GrScissorState& scissor,
263284
const GrSurface* surface,
264285
GrSurfaceOrigin origin) {

src/gpu/d3d/GrD3DOpsRenderPass.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class GrD3DOpsRenderPass : public GrOpsRenderPass {
5353
int baseVertex) override;
5454
void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
5555
int baseVertex) override;
56-
void onDrawIndirect(const GrBuffer*, size_t offset, int drawCount) override {}
57-
void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) override {}
56+
void onDrawIndirect(const GrBuffer*, size_t offset, int drawCount) override;
57+
void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) override;
5858

5959
void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override;
6060

src/gpu/d3d/GrD3DResourceProvider.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,21 @@ sk_sp<GrD3DRootSignature> GrD3DResourceProvider::findOrCreateRootSignature(int n
5959
return rootSig;
6060
}
6161

62+
sk_sp<GrD3DCommandSignature> GrD3DResourceProvider::findOrCreateCommandSignature(
63+
GrD3DCommandSignature::ForIndexed indexed, unsigned int slot) {
64+
for (int i = 0; i < fCommandSignatures.count(); ++i) {
65+
if (fCommandSignatures[i]->isCompatible(indexed, slot)) {
66+
return fCommandSignatures[i];
67+
}
68+
}
69+
70+
auto commandSig = GrD3DCommandSignature::Make(fGpu, indexed, slot);
71+
if (!commandSig) {
72+
return nullptr;
73+
}
74+
fCommandSignatures.push_back(commandSig);
75+
return commandSig;
76+
}
6277

6378
GrD3DDescriptorHeap::CPUHandle GrD3DResourceProvider::createRenderTargetView(
6479
ID3D12Resource* textureResource) {

src/gpu/d3d/GrD3DResourceProvider.h

+6
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
#include "include/private/SkTHash.h"
1414
#include "src/core/SkLRUCache.h"
1515
#include "src/gpu/GrProgramDesc.h"
16+
#include "src/gpu/d3d/GrD3DCommandSignature.h"
1617
#include "src/gpu/d3d/GrD3DConstantRingBuffer.h"
1718
#include "src/gpu/d3d/GrD3DCpuDescriptorManager.h"
1819
#include "src/gpu/d3d/GrD3DDescriptorTableManager.h"
1920
#include "src/gpu/d3d/GrD3DRootSignature.h"
2021

2122
#include <memory>
2223

24+
class GrD3DCommandSignature;
2325
class GrD3DDirectCommandList;
2426
class GrD3DGpu;
2527
class GrD3DPipelineState;
@@ -37,6 +39,9 @@ class GrD3DResourceProvider {
3739

3840
sk_sp<GrD3DRootSignature> findOrCreateRootSignature(int numTextureSamplers);
3941

42+
sk_sp<GrD3DCommandSignature> findOrCreateCommandSignature(GrD3DCommandSignature::ForIndexed,
43+
unsigned int slot);
44+
4045
GrD3DDescriptorHeap::CPUHandle createRenderTargetView(ID3D12Resource* textureResource);
4146
void recycleRenderTargetView(const GrD3DDescriptorHeap::CPUHandle&);
4247

@@ -108,6 +113,7 @@ class GrD3DResourceProvider {
108113

109114
SkSTArray<4, std::unique_ptr<GrD3DDirectCommandList>> fAvailableDirectCommandLists;
110115
SkSTArray<4, sk_sp<GrD3DRootSignature>> fRootSignatures;
116+
SkSTArray<2, sk_sp<GrD3DCommandSignature>> fCommandSignatures;
111117

112118
GrD3DCpuDescriptorManager fCpuDescriptorManager;
113119
GrD3DDescriptorTableManager fDescriptorTableManager;

src/gpu/d3d/GrD3DRootSignature.h

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ class GrD3DRootSignature : public GrManagedResource {
4343
// release the fRootSignature cause the gr_cp will handle that in the dtor.
4444
void freeGPUData() const override {}
4545

46-
// mutable needed so we can release the resource in freeGPUData
4746
gr_cp<ID3D12RootSignature> fRootSignature;
4847
int fNumTextureSamplers;
4948
};

0 commit comments

Comments
 (0)