Implement support for indirect draws
Change-Id: Ib1c0570d747bf9f46be3486f37eba3af53ed1e3d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281642
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrOpsRenderPass.cpp b/src/gpu/GrOpsRenderPass.cpp
index 8167363..060b9fc 100644
--- a/src/gpu/GrOpsRenderPass.cpp
+++ b/src/gpu/GrOpsRenderPass.cpp
@@ -265,6 +265,61 @@
this->onDrawIndexedInstanced(indexCount, baseIndex, instanceCount, baseInstance, baseVertex);
}
+void GrOpsRenderPass::drawIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset,
+ int drawCount) {
+ SkASSERT(this->gpu()->caps()->drawInstancedSupport());
+ SkASSERT(drawIndirectBuffer->isCpuBuffer() ||
+ !static_cast<const GrGpuBuffer*>(drawIndirectBuffer)->isMapped());
+ if (!this->prepareToDraw()) {
+ return;
+ }
+ SkASSERT(!fHasIndexBuffer);
+ SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
+ SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
+ if (!this->gpu()->caps()->nativeDrawIndirectSupport()) {
+ // Polyfill indirect draws with looping instanced calls.
+ SkASSERT(drawIndirectBuffer->isCpuBuffer());
+ auto cpuIndirectBuffer = static_cast<const GrCpuBuffer*>(drawIndirectBuffer);
+ auto cmd = reinterpret_cast<const GrDrawIndirectCommand*>(
+ cpuIndirectBuffer->data() + bufferOffset);
+ auto end = cmd + drawCount;
+ for (; cmd != end; ++cmd) {
+ this->onDrawInstanced(cmd->fInstanceCount, cmd->fBaseInstance, cmd->fVertexCount,
+ cmd->fBaseVertex);
+ }
+ return;
+ }
+ this->onDrawIndirect(drawIndirectBuffer, bufferOffset, drawCount);
+}
+
+void GrOpsRenderPass::drawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t bufferOffset,
+ int drawCount) {
+ SkASSERT(this->gpu()->caps()->drawInstancedSupport());
+ SkASSERT(drawIndirectBuffer->isCpuBuffer() ||
+ !static_cast<const GrGpuBuffer*>(drawIndirectBuffer)->isMapped());
+ if (!this->prepareToDraw()) {
+ return;
+ }
+ SkASSERT(fHasIndexBuffer);
+ SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
+ SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
+ if (!this->gpu()->caps()->nativeDrawIndirectSupport() ||
+ this->gpu()->caps()->nativeDrawIndexedIndirectIsBroken()) {
+ // Polyfill indexedIndirect draws with looping indexedInstanced calls.
+ SkASSERT(drawIndirectBuffer->isCpuBuffer());
+ auto cpuIndirectBuffer = static_cast<const GrCpuBuffer*>(drawIndirectBuffer);
+ auto cmd = reinterpret_cast<const GrDrawIndexedIndirectCommand*>(
+ cpuIndirectBuffer->data() + bufferOffset);
+ auto end = cmd + drawCount;
+ for (; cmd != end; ++cmd) {
+ this->onDrawIndexedInstanced(cmd->fIndexCount, cmd->fBaseIndex, cmd->fInstanceCount,
+ cmd->fBaseInstance, cmd->fBaseVertex);
+ }
+ return;
+ }
+ this->onDrawIndexedIndirect(drawIndirectBuffer, bufferOffset, drawCount);
+}
+
void GrOpsRenderPass::drawIndexPattern(int patternIndexCount, int patternRepeatCount,
int maxPatternRepetitionsInIndexBuffer,
int patternVertexCount, int baseVertex) {