Remove shims for reordering indirect draw command signatures
Change-Id: I0eb48cc8a7721cc0fbdfa579b36db5e6ed0aa695 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/368917 Reviewed-by: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
9374617a4c
commit
b849f7a791
@ -8,12 +8,28 @@
|
||||
#ifndef GrDrawIndirectCommand_DEFINED
|
||||
#define GrDrawIndirectCommand_DEFINED
|
||||
|
||||
#include "src/gpu/GrCaps.h"
|
||||
#include <array>
|
||||
#include <stdint.h>
|
||||
#include <utility>
|
||||
|
||||
// Draw commands on the GPU are simple tuples of uint32_t. The ordering is backend-specific.
|
||||
using GrDrawIndirectCommand = std::array<uint32_t, 4>;
|
||||
using GrDrawIndexedIndirectCommand = std::array<uint32_t, 5>;
|
||||
struct GrDrawIndirectCommand {
|
||||
uint32_t fVertexCount;
|
||||
uint32_t fInstanceCount;
|
||||
int32_t fBaseVertex;
|
||||
uint32_t fBaseInstance;
|
||||
};
|
||||
|
||||
static_assert(sizeof(GrDrawIndirectCommand) == 16, "GrDrawIndirectCommand must be tightly packed");
|
||||
|
||||
struct GrDrawIndexedIndirectCommand {
|
||||
uint32_t fIndexCount;
|
||||
uint32_t fInstanceCount;
|
||||
uint32_t fBaseIndex;
|
||||
int32_t fBaseVertex;
|
||||
uint32_t fBaseInstance;
|
||||
};
|
||||
|
||||
static_assert(sizeof(GrDrawIndexedIndirectCommand) == 20,
|
||||
"GrDrawIndexedIndirectCommand must be tightly packed");
|
||||
|
||||
// Helper for writing commands to an indirect draw buffer. Usage:
|
||||
//
|
||||
@ -37,7 +53,7 @@ public:
|
||||
bool isValid() const { return fData != nullptr; }
|
||||
|
||||
inline void write(uint32_t instanceCount, uint32_t baseInstance, uint32_t vertexCount,
|
||||
uint32_t baseVertex, const GrCaps&) {
|
||||
int32_t baseVertex) {
|
||||
*fData++ = {vertexCount, instanceCount, baseVertex, baseInstance};
|
||||
}
|
||||
|
||||
@ -68,7 +84,7 @@ public:
|
||||
bool isValid() const { return fData != nullptr; }
|
||||
|
||||
inline void writeIndexed(uint32_t indexCount, uint32_t baseIndex, uint32_t instanceCount,
|
||||
uint32_t baseInstance, uint32_t baseVertex, const GrCaps&) {
|
||||
uint32_t baseInstance, int32_t baseVertex) {
|
||||
*fData++ = {indexCount, instanceCount, baseIndex, baseVertex, baseInstance};
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,6 @@ void GrOpsRenderPass::drawIndirect(const GrBuffer* drawIndirectBuffer, size_t bu
|
||||
auto* cmds = reinterpret_cast<const GrDrawIndirectCommand*>(
|
||||
cpuIndirectBuffer->data() + bufferOffset);
|
||||
for (int i = 0; i < drawCount; ++i) {
|
||||
// TODO: SkASSERT(caps.drawIndirectSignature() == standard);
|
||||
auto [vertexCount, instanceCount, baseVertex, baseInstance] = cmds[i];
|
||||
this->onDrawInstanced(instanceCount, baseInstance, vertexCount, baseVertex);
|
||||
}
|
||||
@ -317,7 +316,6 @@ void GrOpsRenderPass::drawIndexedIndirect(const GrBuffer* drawIndirectBuffer, si
|
||||
auto* cmds = reinterpret_cast<const GrDrawIndexedIndirectCommand*>(
|
||||
cpuIndirectBuffer->data() + bufferOffset);
|
||||
for (int i = 0; i < drawCount; ++i) {
|
||||
// TODO: SkASSERT(caps.drawIndirectSignature() == standard);
|
||||
auto [indexCount, instanceCount, baseIndex, baseVertex, baseInstance] = cmds[i];
|
||||
this->onDrawIndexedInstanced(indexCount, baseIndex, instanceCount, baseInstance,
|
||||
baseVertex);
|
||||
|
@ -286,7 +286,6 @@ void GrGLOpsRenderPass::multiDrawArraysANGLEOrWebGL(const GrBuffer* drawIndirect
|
||||
while (drawCount) {
|
||||
int countInBatch = std::min(drawCount, kMaxDrawCountPerBatch);
|
||||
for (int i = 0; i < countInBatch; ++i) {
|
||||
// TODO: SkASSERT(caps.drawIndirectSignature() == standard);
|
||||
auto [vertexCount, instanceCount, baseVertex, baseInstance] = cmds[i];
|
||||
fFirsts[i] = baseVertex;
|
||||
fCounts[i] = vertexCount;
|
||||
@ -360,7 +359,6 @@ void GrGLOpsRenderPass::multiDrawElementsANGLEOrWebGL(const GrBuffer* drawIndire
|
||||
while (drawCount) {
|
||||
int countInBatch = std::min(drawCount, kMaxDrawCountPerBatch);
|
||||
for (int i = 0; i < countInBatch; ++i) {
|
||||
// TODO: SkASSERT(caps.drawIndirectSignature() == standard);
|
||||
auto [indexCount, instanceCount, baseIndex, baseVertex, baseInstance] = cmds[i];
|
||||
fCounts[i] = indexCount;
|
||||
fIndices[i] = this->offsetForBaseIndex(baseIndex);
|
||||
|
@ -49,10 +49,9 @@ GrPathIndirectTessellator::GrPathIndirectTessellator(const SkMatrix& viewMatrix,
|
||||
void GrPathIndirectTessellator::prepare(GrMeshDrawOp::Target* target, const SkMatrix& viewMatrix,
|
||||
const SkPath& path,
|
||||
const BreadcrumbTriangleList* breadcrumbTriangleList) {
|
||||
const GrCaps& caps = target->caps();
|
||||
SkASSERT(fTotalInstanceCount == 0);
|
||||
SkASSERT(fIndirectDrawCount == 0);
|
||||
SkASSERT(caps.drawInstancedSupport());
|
||||
SkASSERT(target->caps().drawInstancedSupport());
|
||||
|
||||
int instanceLockCount = fOuterCurveInstanceCount;
|
||||
if (fDrawInnerFan) {
|
||||
@ -129,7 +128,7 @@ void GrPathIndirectTessellator::prepare(GrMeshDrawOp::Target* target, const SkMa
|
||||
SkASSERT(fIndirectDrawCount < indirectLockCnt);
|
||||
GrMiddleOutCubicShader::WriteDrawTrianglesIndirectCmd(&indirectWriter,
|
||||
numTrianglesAtBeginningOfData,
|
||||
fBaseInstance, caps);
|
||||
fBaseInstance);
|
||||
++fIndirectDrawCount;
|
||||
runningInstanceCount = numTrianglesAtBeginningOfData;
|
||||
}
|
||||
@ -144,8 +143,7 @@ void GrPathIndirectTessellator::prepare(GrMeshDrawOp::Target* target, const SkMa
|
||||
SkASSERT(fIndirectDrawCount < indirectLockCnt);
|
||||
GrMiddleOutCubicShader::WriteDrawCubicsIndirectCmd(&indirectWriter, resolveLevel,
|
||||
instanceCountAtCurrLevel,
|
||||
fBaseInstance + runningInstanceCount,
|
||||
caps);
|
||||
fBaseInstance + runningInstanceCount);
|
||||
++fIndirectDrawCount;
|
||||
runningInstanceCount += instanceCountAtCurrLevel;
|
||||
}
|
||||
|
@ -168,24 +168,23 @@ public:
|
||||
// the parametric sense) line segments.
|
||||
static void WriteDrawCubicsIndirectCmd(GrDrawIndexedIndirectWriter* indirectWriter,
|
||||
int resolveLevel, uint32_t instanceCount,
|
||||
uint32_t baseInstance, const GrCaps& caps) {
|
||||
uint32_t baseInstance) {
|
||||
SkASSERT(resolveLevel > 0 && resolveLevel <= GrTessellationPathRenderer::kMaxResolveLevel);
|
||||
// Starting at baseIndex=3, the index buffer triangulates a cubic with 2^kMaxResolveLevel
|
||||
// line segments. Each index value corresponds to a parametric T value on the curve. Since
|
||||
// the triangles are arranged in "middle-out" order, we can conveniently control the
|
||||
// resolveLevel by changing only the indexCount.
|
||||
uint32_t indexCount = NumVerticesAtResolveLevel(resolveLevel);
|
||||
indirectWriter->writeIndexed(indexCount, 3, instanceCount, baseInstance, 0, caps);
|
||||
indirectWriter->writeIndexed(indexCount, 3, instanceCount, baseInstance, 0);
|
||||
}
|
||||
|
||||
// For performance reasons we can often express triangles as an indirect cubic draw and sneak
|
||||
// them in alongside the other indirect draws. This method configures an indirect draw to emit
|
||||
// the triangle [P0, P1, P2] from a 4-point instance.
|
||||
static void WriteDrawTrianglesIndirectCmd(GrDrawIndexedIndirectWriter* indirectWriter,
|
||||
uint32_t instanceCount, uint32_t baseInstance,
|
||||
const GrCaps& caps) {
|
||||
uint32_t instanceCount, uint32_t baseInstance) {
|
||||
// Indices 0,1,2 have special index values that emit points P0, P1, and P2 respectively.
|
||||
indirectWriter->writeIndexed(3, 0, instanceCount, baseInstance, 0, caps);
|
||||
indirectWriter->writeIndexed(3, 0, instanceCount, baseInstance, 0);
|
||||
}
|
||||
|
||||
// Returns the index buffer that should be bound when drawing with this shader.
|
||||
|
@ -614,8 +614,6 @@ void GrStrokeIndirectTessellator::prepare(GrMeshDrawOp::Target* target, const Sk
|
||||
return;
|
||||
}
|
||||
|
||||
const GrCaps& caps = target->caps();
|
||||
|
||||
// Allocate enough indirect commands for every resolve level. We will putBack the unused ones
|
||||
// at the end.
|
||||
GrDrawIndirectWriter indirectWriter = target->makeDrawIndirectSpace(kMaxResolveLevel + 1,
|
||||
@ -649,7 +647,7 @@ void GrStrokeIndirectTessellator::prepare(GrMeshDrawOp::Target* target, const Sk
|
||||
if (fResolveLevelCounts[i]) {
|
||||
int numEdges = numExtraEdgesInJoin + num_edges_in_resolve_level(i);
|
||||
indirectWriter.write(fResolveLevelCounts[i], baseInstance + currentInstanceIdx,
|
||||
numEdges * 2, 0, caps);
|
||||
numEdges * 2, 0);
|
||||
++fDrawIndirectCount;
|
||||
numEdgesPerResolveLevel[i] = numEdges;
|
||||
instanceWriters[i] = baseWriter.makeOffset(instanceStride * currentInstanceIdx);
|
||||
|
@ -355,11 +355,9 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrMeshTest, reporter, ctxInfo) {
|
||||
if (indexed) {
|
||||
int baseIndex = 1 + y * 6;
|
||||
indexedIndirectWriter.writeIndexed(6, baseIndex, kBoxCountX,
|
||||
y * kBoxCountX, baseVertex,
|
||||
*dContext->priv().caps());
|
||||
y * kBoxCountX, baseVertex);
|
||||
} else {
|
||||
indirectWriter.write(kBoxCountX, y * kBoxCountX, 4, baseVertex,
|
||||
*dContext->priv().caps());
|
||||
indirectWriter.write(kBoxCountX, y * kBoxCountX, 4, baseVertex);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -435,17 +435,15 @@ void GrStrokeIndirectTessellator::verifyBuffers(skiatest::Reporter* r, GrMockOpT
|
||||
GrStrokeTessellateShader::Tolerances tolerances(viewMatrix.getMaxScale(), stroke.getWidth());
|
||||
float tolerance = test_tolerance(stroke.getJoin());
|
||||
for (int i = 0; i < fDrawIndirectCount; ++i) {
|
||||
// TODO: SkASSERT(caps.drawIndirectCmdSignature() == standard);
|
||||
auto [vertexCount, instanceCount, baseVertex, baseInstance] = *indirect++;
|
||||
int numExtraEdgesInJoin = (stroke.getJoin() == SkPaint::kMiter_Join) ? 4 : 3;
|
||||
int numStrokeEdges = vertexCount/2 - numExtraEdgesInJoin;
|
||||
int numStrokeEdges = indirect->fVertexCount/2 - numExtraEdgesInJoin;
|
||||
int numSegments = numStrokeEdges - 1;
|
||||
bool isPow2 = !(numSegments & (numSegments - 1));
|
||||
REPORTER_ASSERT(r, isPow2);
|
||||
int resolveLevel = sk_float_nextlog2(numSegments);
|
||||
REPORTER_ASSERT(r, 1 << resolveLevel == numSegments);
|
||||
for (unsigned j = 0; j < instanceCount; ++j) {
|
||||
SkASSERT(fabsf(instance->fNumTotalEdges) == vertexCount/2);
|
||||
for (unsigned j = 0; j < indirect->fInstanceCount; ++j) {
|
||||
SkASSERT(fabsf(instance->fNumTotalEdges) == indirect->fVertexCount/2);
|
||||
const SkPoint* p = instance->fPts;
|
||||
float numParametricSegments = GrWangsFormula::cubic(
|
||||
tolerances.fParametricIntolerance, p);
|
||||
@ -478,5 +476,6 @@ void GrStrokeIndirectTessellator::verifyBuffers(skiatest::Reporter* r, GrMockOpT
|
||||
}
|
||||
++instance;
|
||||
}
|
||||
++indirect;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user