Add a bindBuffers() call to GrOpsRenderPass
Adds a bindBuffers() call and removes the GrBuffer arguments from the draw calls. Change-Id: I43c2dd8afe80c41e48c1d9d5210affcfe6f095fc Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273840 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
4c0ffe7820
commit
ded437003d
@ -200,30 +200,33 @@ inline void GrMesh::setVertexData(sk_sp<const GrBuffer> vertexBuffer, int baseVe
|
||||
inline void GrMesh::draw(GrOpsRenderPass* opsRenderPass) const {
|
||||
if (this->isInstanced()) {
|
||||
if (!this->isIndexed()) {
|
||||
opsRenderPass->drawInstanced(fInstanceBuffer.get(), fInstanceData.fInstanceCount,
|
||||
fInstanceData.fBaseInstance, fVertexBuffer.get(),
|
||||
opsRenderPass->bindBuffers(nullptr, fInstanceBuffer.get(), fVertexBuffer.get());
|
||||
opsRenderPass->drawInstanced(fInstanceData.fInstanceCount, fInstanceData.fBaseInstance,
|
||||
fInstanceNonIndexData.fVertexCount, fBaseVertex);
|
||||
} else {
|
||||
opsRenderPass->bindBuffers(fIndexBuffer.get(), fInstanceBuffer.get(),
|
||||
fVertexBuffer.get(), this->primitiveRestart());
|
||||
opsRenderPass->drawIndexedInstanced(
|
||||
fIndexBuffer.get(), fInstanceIndexData.fIndexCount, 0, this->primitiveRestart(),
|
||||
fInstanceBuffer.get(), fInstanceData.fInstanceCount,
|
||||
fInstanceData.fBaseInstance, fVertexBuffer.get(), fBaseVertex);
|
||||
fInstanceIndexData.fIndexCount, 0, fInstanceData.fInstanceCount,
|
||||
fInstanceData.fBaseInstance, fBaseVertex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->isIndexed()) {
|
||||
SkASSERT(fNonIndexNonInstanceData.fVertexCount > 0);
|
||||
opsRenderPass->draw(fVertexBuffer.get(), fNonIndexNonInstanceData.fVertexCount,
|
||||
fBaseVertex);
|
||||
opsRenderPass->bindBuffers(nullptr, nullptr, fVertexBuffer.get());
|
||||
opsRenderPass->draw(fNonIndexNonInstanceData.fVertexCount, fBaseVertex);
|
||||
return;
|
||||
}
|
||||
|
||||
opsRenderPass->bindBuffers(fIndexBuffer.get(), nullptr, fVertexBuffer.get(),
|
||||
this->primitiveRestart());
|
||||
|
||||
if (0 == fIndexData.fPatternRepeatCount) {
|
||||
opsRenderPass->drawIndexed(
|
||||
fIndexBuffer.get(), fIndexData.fIndexCount, fNonPatternIndexData.fBaseIndex,
|
||||
this->primitiveRestart(), fNonPatternIndexData.fMinIndexValue,
|
||||
fNonPatternIndexData.fMaxIndexValue, fVertexBuffer.get(), fBaseVertex);
|
||||
opsRenderPass->drawIndexed(fIndexData.fIndexCount, fNonPatternIndexData.fBaseIndex,
|
||||
fNonPatternIndexData.fMinIndexValue,
|
||||
fNonPatternIndexData.fMaxIndexValue, fBaseVertex);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -237,8 +240,7 @@ inline void GrMesh::draw(GrOpsRenderPass* opsRenderPass) const {
|
||||
int minIndexValue = 0;
|
||||
int maxIndexValue = fPatternData.fVertexCount * repeatCount - 1;
|
||||
SkASSERT(!(fFlags & Flags::kUsePrimitiveRestart));
|
||||
opsRenderPass->drawIndexed(fIndexBuffer.get(), indexCount, 0, this->primitiveRestart(),
|
||||
minIndexValue, maxIndexValue, fVertexBuffer.get(),
|
||||
opsRenderPass->drawIndexed(indexCount, 0, minIndexValue, maxIndexValue,
|
||||
fBaseVertex + fPatternData.fVertexCount * baseRepetition);
|
||||
baseRepetition += repeatCount;
|
||||
} while (baseRepetition < fIndexData.fPatternRepeatCount);
|
||||
|
@ -91,8 +91,11 @@ void GrOpsRenderPass::bindPipeline(const GrProgramInfo& programInfo, const SkRec
|
||||
}
|
||||
fTextureBindingStatus = (hasTextures) ?
|
||||
DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
|
||||
fHasVertexAttributes = programInfo.primProc().hasVertexAttributes();
|
||||
fHasInstanceAttributes = programInfo.primProc().hasInstanceAttributes();
|
||||
fHasIndexBuffer = false;
|
||||
fInstanceBufferStatus = (programInfo.primProc().hasInstanceAttributes()) ?
|
||||
DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
|
||||
fVertexBufferStatus = (programInfo.primProc().hasVertexAttributes()) ?
|
||||
DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
|
||||
#endif
|
||||
|
||||
fDrawPipelineStatus = DrawPipelineStatus::kOk;
|
||||
@ -149,6 +152,36 @@ void GrOpsRenderPass::drawMeshes(const GrProgramInfo& programInfo, const GrMesh
|
||||
}
|
||||
}
|
||||
|
||||
void GrOpsRenderPass::bindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart primRestart) {
|
||||
if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
|
||||
SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
if (indexBuffer) {
|
||||
fHasIndexBuffer = true;
|
||||
}
|
||||
|
||||
SkASSERT((DynamicStateStatus::kDisabled == fInstanceBufferStatus) != SkToBool(instanceBuffer));
|
||||
if (instanceBuffer) {
|
||||
fInstanceBufferStatus = DynamicStateStatus::kConfigured;
|
||||
}
|
||||
|
||||
SkASSERT((DynamicStateStatus::kDisabled == fVertexBufferStatus) != SkToBool(vertexBuffer));
|
||||
if (vertexBuffer) {
|
||||
fVertexBufferStatus = DynamicStateStatus::kConfigured;
|
||||
}
|
||||
|
||||
if (GrPrimitiveRestart::kYes == primRestart) {
|
||||
SkASSERT(this->gpu()->caps()->usePrimitiveRestart());
|
||||
}
|
||||
#endif
|
||||
|
||||
this->onBindBuffers(indexBuffer, instanceBuffer, vertexBuffer, primRestart);
|
||||
}
|
||||
|
||||
bool GrOpsRenderPass::prepareToDraw() {
|
||||
if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
|
||||
SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
|
||||
@ -164,52 +197,45 @@ bool GrOpsRenderPass::prepareToDraw() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrOpsRenderPass::draw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) {
|
||||
void GrOpsRenderPass::draw(int vertexCount, int baseVertex) {
|
||||
if (!this->prepareToDraw()) {
|
||||
return;
|
||||
}
|
||||
SkASSERT(SkToBool(vertexBuffer) == fHasVertexAttributes);
|
||||
this->onDraw(vertexBuffer, vertexCount, baseVertex);
|
||||
SkASSERT(!fHasIndexBuffer);
|
||||
SkASSERT(DynamicStateStatus::kConfigured != fInstanceBufferStatus);
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
|
||||
this->onDraw(vertexCount, baseVertex);
|
||||
}
|
||||
|
||||
void GrOpsRenderPass::drawIndexed(const GrBuffer* indexBuffer, int indexCount,
|
||||
int baseIndex, GrPrimitiveRestart primitiveRestart,
|
||||
uint16_t minIndexValue, uint16_t maxIndexValue,
|
||||
const GrBuffer* vertexBuffer, int baseVertex) {
|
||||
void GrOpsRenderPass::drawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) {
|
||||
if (!this->prepareToDraw()) {
|
||||
return;
|
||||
}
|
||||
SkASSERT(GrPrimitiveRestart::kNo == primitiveRestart ||
|
||||
this->gpu()->caps()->usePrimitiveRestart());
|
||||
SkASSERT(SkToBool(vertexBuffer) == fHasVertexAttributes);
|
||||
this->onDrawIndexed(indexBuffer, indexCount, baseIndex, primitiveRestart, minIndexValue,
|
||||
maxIndexValue, vertexBuffer, baseVertex);
|
||||
SkASSERT(fHasIndexBuffer);
|
||||
SkASSERT(DynamicStateStatus::kConfigured != fInstanceBufferStatus);
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
|
||||
this->onDrawIndexed(indexCount, baseIndex, minIndexValue, maxIndexValue, baseVertex);
|
||||
}
|
||||
|
||||
void GrOpsRenderPass::drawInstanced(const GrBuffer* instanceBuffer, int instanceCount, int
|
||||
baseInstance, const GrBuffer* vertexBuffer, int vertexCount,
|
||||
void GrOpsRenderPass::drawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||
int baseVertex) {
|
||||
if (!this->prepareToDraw()) {
|
||||
return;
|
||||
}
|
||||
SkASSERT(SkToBool(vertexBuffer) == fHasVertexAttributes);
|
||||
SkASSERT(SkToBool(instanceBuffer) == fHasInstanceAttributes);
|
||||
this->onDrawInstanced(instanceBuffer, instanceCount, baseInstance, vertexBuffer, vertexCount,
|
||||
baseVertex);
|
||||
SkASSERT(!fHasIndexBuffer);
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
|
||||
this->onDrawInstanced(instanceCount, baseInstance, vertexCount, baseVertex);
|
||||
}
|
||||
|
||||
void GrOpsRenderPass::drawIndexedInstanced(
|
||||
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart primitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer, int baseVertex) {
|
||||
void GrOpsRenderPass::drawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
|
||||
int baseInstance, int baseVertex) {
|
||||
if (!this->prepareToDraw()) {
|
||||
return;
|
||||
}
|
||||
SkASSERT(GrPrimitiveRestart::kNo == primitiveRestart ||
|
||||
this->gpu()->caps()->usePrimitiveRestart());
|
||||
SkASSERT(SkToBool(vertexBuffer) == fHasVertexAttributes);
|
||||
SkASSERT(SkToBool(instanceBuffer) == fHasInstanceAttributes);
|
||||
this->onDrawIndexedInstanced(indexBuffer, indexCount, baseIndex, primitiveRestart,
|
||||
instanceBuffer, instanceCount, baseInstance, vertexBuffer,
|
||||
baseVertex);
|
||||
SkASSERT(fHasIndexBuffer);
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fInstanceBufferStatus);
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fVertexBufferStatus);
|
||||
this->onDrawIndexedInstanced(indexCount, baseIndex, instanceCount, baseInstance, baseVertex);
|
||||
}
|
||||
|
@ -66,9 +66,14 @@ public:
|
||||
// again with a different array for primProcTextures. (On subsequent calls, if the backend is
|
||||
// capable of updating the primitive processor textures independently, then it will
|
||||
// automatically skip binding textures from GrPipeline.)
|
||||
//
|
||||
// If the current program does not use textures, this is a no-op.
|
||||
void bindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrSurfaceProxy* const primProcTextures[]);
|
||||
|
||||
void bindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart = GrPrimitiveRestart::kNo);
|
||||
|
||||
// Draws the given array of meshes using the current pipeline state. The client must call
|
||||
// bindPipeline() before using this method.
|
||||
//
|
||||
@ -76,18 +81,19 @@ public:
|
||||
// setScissor() and bindTextures() on the client's behalf.
|
||||
void drawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount);
|
||||
|
||||
// These methods issue draws using the current pipeline state. The client must call
|
||||
// bindPipeline(), followed by setScissor() and/or bindTextures() if applicable, before using
|
||||
// these methods.
|
||||
void draw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex);
|
||||
void drawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex, GrPrimitiveRestart,
|
||||
uint16_t minIndexValue, uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
|
||||
// These methods issue draws using the current pipeline state. Before drawing, the caller must
|
||||
// configure the pipeline and dynamic state:
|
||||
//
|
||||
// - Call bindPipeline()
|
||||
// - If the scissor test is enabled, call setScissorRect()
|
||||
// - If the current program uses textures, call bindTextures()
|
||||
// - Call bindBuffers() (even if all buffers are null)
|
||||
void draw(int vertexCount, int baseVertex);
|
||||
void drawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue,
|
||||
int baseVertex);
|
||||
void drawInstanced(const GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
|
||||
const GrBuffer* vertexBuffer, int vertexCount, int baseVertex);
|
||||
void drawIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer, int baseVertex);
|
||||
void drawInstanced(int instanceCount, int baseInstance, int vertexCount, int baseVertex);
|
||||
void drawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
|
||||
int baseVertex);
|
||||
|
||||
// Performs an upload of vertex data in the middle of a set of a set of draws
|
||||
virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
|
||||
@ -132,17 +138,15 @@ private:
|
||||
virtual void onSetScissorRect(const SkIRect&) = 0;
|
||||
virtual bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrSurfaceProxy* const primProcTextures[]) = 0;
|
||||
virtual void onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) = 0;
|
||||
virtual void onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, uint16_t minIndexValue, uint16_t maxIndexValue,
|
||||
const GrBuffer* vertexBuffer, int baseVertex) = 0;
|
||||
virtual void onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer, int vertexCount,
|
||||
virtual void onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart) = 0;
|
||||
virtual void onDraw(int vertexCount, int baseVertex) = 0;
|
||||
virtual void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) = 0;
|
||||
virtual void onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||
int baseVertex) = 0;
|
||||
virtual void onDrawIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, const GrBuffer* instanceBuffer,
|
||||
int instanceCount, int baseInstance,
|
||||
const GrBuffer* vertexBuffer, int baseVertex) = 0;
|
||||
virtual void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
|
||||
int baseInstance, int baseVertex) = 0;
|
||||
virtual void onClear(const GrFixedClip&, const SkPMColor4f&) = 0;
|
||||
virtual void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0;
|
||||
virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
|
||||
@ -165,8 +169,9 @@ private:
|
||||
|
||||
DynamicStateStatus fScissorStatus = DynamicStateStatus::kDisabled;
|
||||
DynamicStateStatus fTextureBindingStatus = DynamicStateStatus::kDisabled;
|
||||
bool fHasVertexAttributes = false;
|
||||
bool fHasInstanceAttributes = false;
|
||||
bool fHasIndexBuffer = false;
|
||||
DynamicStateStatus fInstanceBufferStatus = DynamicStateStatus::kDisabled;
|
||||
DynamicStateStatus fVertexBufferStatus = DynamicStateStatus::kDisabled;
|
||||
#endif
|
||||
|
||||
typedef GrOpsRenderPass INHERITED;
|
||||
|
@ -46,9 +46,9 @@ bool GrGLOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrGLOpsRenderPass::setupGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer,
|
||||
int baseVertex, const GrBuffer* instanceBuffer,
|
||||
int baseInstance, GrPrimitiveRestart primitiveRestart) {
|
||||
void GrGLOpsRenderPass::onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer,
|
||||
GrPrimitiveRestart primitiveRestart) {
|
||||
SkASSERT((primitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer);
|
||||
GrGLProgram* program = fGpu->currentProgram();
|
||||
if (!program) {
|
||||
@ -56,7 +56,29 @@ void GrGLOpsRenderPass::setupGeometry(const GrBuffer* indexBuffer, const GrBuffe
|
||||
}
|
||||
|
||||
int numAttribs = program->numVertexAttributes() + program->numInstanceAttributes();
|
||||
auto* attribState = fGpu->bindInternalVertexArray(indexBuffer, numAttribs, primitiveRestart);
|
||||
fAttribArrayState = fGpu->bindInternalVertexArray(indexBuffer, numAttribs, primitiveRestart);
|
||||
|
||||
if (indexBuffer) {
|
||||
if (indexBuffer->isCpuBuffer()) {
|
||||
auto* cpuIndexBuffer = static_cast<const GrCpuBuffer*>(indexBuffer);
|
||||
fIndexPointer = reinterpret_cast<const uint16_t*>(cpuIndexBuffer->data());
|
||||
} else {
|
||||
fIndexPointer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// We defer binding of instance and vertex buffers because GL does not (always) support base
|
||||
// instance and/or base vertex.
|
||||
fDeferredInstanceBuffer = sk_ref_sp(instanceBuffer);
|
||||
fDeferredVertexBuffer = sk_ref_sp(vertexBuffer);
|
||||
}
|
||||
|
||||
void GrGLOpsRenderPass::setupGeometry(const GrBuffer* vertexBuffer, int baseVertex,
|
||||
const GrBuffer* instanceBuffer, int baseInstance) {
|
||||
GrGLProgram* program = fGpu->currentProgram();
|
||||
if (!program) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (int vertexStride = program->vertexStride()) {
|
||||
SkASSERT(vertexBuffer);
|
||||
@ -66,8 +88,9 @@ void GrGLOpsRenderPass::setupGeometry(const GrBuffer* indexBuffer, const GrBuffe
|
||||
for (int i = 0; i < program->numVertexAttributes(); ++i) {
|
||||
const auto& attrib = program->vertexAttribute(i);
|
||||
static constexpr int kDivisor = 0;
|
||||
attribState->set(fGpu, attrib.fLocation, vertexBuffer, attrib.fCPUType, attrib.fGPUType,
|
||||
vertexStride, bufferOffset + attrib.fOffset, kDivisor);
|
||||
fAttribArrayState->set(fGpu, attrib.fLocation, vertexBuffer, attrib.fCPUType,
|
||||
attrib.fGPUType, vertexStride, bufferOffset + attrib.fOffset,
|
||||
kDivisor);
|
||||
}
|
||||
}
|
||||
if (int instanceStride = program->instanceStride()) {
|
||||
@ -79,69 +102,55 @@ void GrGLOpsRenderPass::setupGeometry(const GrBuffer* indexBuffer, const GrBuffe
|
||||
for (int i = 0; i < program->numInstanceAttributes(); ++i, ++attribIdx) {
|
||||
const auto& attrib = program->instanceAttribute(i);
|
||||
static constexpr int kDivisor = 1;
|
||||
attribState->set(fGpu, attrib.fLocation, instanceBuffer, attrib.fCPUType,
|
||||
attrib.fGPUType, instanceStride, bufferOffset + attrib.fOffset,
|
||||
kDivisor);
|
||||
fAttribArrayState->set(fGpu, attrib.fLocation, instanceBuffer, attrib.fCPUType,
|
||||
attrib.fGPUType, instanceStride, bufferOffset + attrib.fOffset,
|
||||
kDivisor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const GrGLvoid* get_gl_index_ptr(const GrBuffer* indexBuffer, int baseIndex) {
|
||||
size_t baseOffset = baseIndex * sizeof(uint16_t);
|
||||
if (indexBuffer->isCpuBuffer()) {
|
||||
return static_cast<const GrCpuBuffer*>(indexBuffer)->data() + baseOffset;
|
||||
} else {
|
||||
return reinterpret_cast<const GrGLvoid*>(baseOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLOpsRenderPass::onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) {
|
||||
void GrGLOpsRenderPass::onDraw(int vertexCount, int baseVertex) {
|
||||
if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
|
||||
this->setupGeometry(nullptr, vertexBuffer, baseVertex, nullptr, 0, GrPrimitiveRestart::kNo);
|
||||
this->setupGeometry(fDeferredVertexBuffer.get(), baseVertex, nullptr, 0);
|
||||
fGpu->drawArrays(fPrimitiveType, 0, vertexCount);
|
||||
return;
|
||||
}
|
||||
|
||||
this->setupGeometry(nullptr, vertexBuffer, 0, nullptr, 0, GrPrimitiveRestart::kNo);
|
||||
this->setupGeometry(fDeferredVertexBuffer.get(), 0, nullptr, 0);
|
||||
fGpu->drawArrays(fPrimitiveType, baseVertex, vertexCount);
|
||||
}
|
||||
|
||||
void GrGLOpsRenderPass::onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart primitiveRestart, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
|
||||
int baseVertex) {
|
||||
const GrGLvoid* indexPtr = get_gl_index_ptr(indexBuffer, baseIndex);
|
||||
this->setupGeometry(indexBuffer, vertexBuffer, baseVertex, nullptr, 0, primitiveRestart);
|
||||
void GrGLOpsRenderPass::onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) {
|
||||
this->setupGeometry(fDeferredVertexBuffer.get(), baseVertex, nullptr, 0);
|
||||
if (fGpu->glCaps().drawRangeElementsSupport()) {
|
||||
fGpu->drawRangeElements(fPrimitiveType, minIndexValue, maxIndexValue, indexCount,
|
||||
GR_GL_UNSIGNED_SHORT, indexPtr);
|
||||
GR_GL_UNSIGNED_SHORT, fIndexPointer + baseIndex);
|
||||
} else {
|
||||
fGpu->drawElements(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT, indexPtr);
|
||||
fGpu->drawElements(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT,
|
||||
fIndexPointer + baseIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLOpsRenderPass::onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer,
|
||||
int vertexCount, int baseVertex) {
|
||||
void GrGLOpsRenderPass::onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||
int baseVertex) {
|
||||
int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
|
||||
for (int i = 0; i < instanceCount; i += maxInstances) {
|
||||
this->setupGeometry(nullptr, vertexBuffer, 0, instanceBuffer, baseInstance + i,
|
||||
GrPrimitiveRestart::kNo);
|
||||
this->setupGeometry(fDeferredVertexBuffer.get(), 0, fDeferredInstanceBuffer.get(),
|
||||
baseInstance + i);
|
||||
fGpu->drawArraysInstanced(fPrimitiveType, baseVertex, vertexCount,
|
||||
std::min(instanceCount - i, maxInstances));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLOpsRenderPass::onDrawIndexedInstanced(
|
||||
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart primitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer, int baseVertex) {
|
||||
const GrGLvoid* indexPtr = get_gl_index_ptr(indexBuffer, baseIndex);
|
||||
void GrGLOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
|
||||
int baseInstance, int baseVertex) {
|
||||
int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
|
||||
for (int i = 0; i < instanceCount; i += maxInstances) {
|
||||
this->setupGeometry(indexBuffer, vertexBuffer, baseVertex,
|
||||
instanceBuffer, baseInstance + i, primitiveRestart);
|
||||
fGpu->drawElementsInstanced(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT, indexPtr,
|
||||
this->setupGeometry(fDeferredVertexBuffer.get(), baseVertex, fDeferredInstanceBuffer.get(),
|
||||
baseInstance + i);
|
||||
fGpu->drawElementsInstanced(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT,
|
||||
fIndexPointer + baseIndex,
|
||||
std::min(instanceCount - i, maxInstances));
|
||||
}
|
||||
}
|
||||
|
@ -49,23 +49,21 @@ public:
|
||||
private:
|
||||
GrGpu* gpu() override { return fGpu; }
|
||||
|
||||
void setupGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer, int baseVertex,
|
||||
const GrBuffer* instanceBuffer, int baseInstance,
|
||||
GrPrimitiveRestart enablePrimitiveRestart);
|
||||
void setupGeometry(const GrBuffer* vertexBuffer, int baseVertex, const GrBuffer* instanceBuffer,
|
||||
int baseInstance);
|
||||
|
||||
bool onBindPipeline(const GrProgramInfo& programInfo, const SkRect& drawBounds) override;
|
||||
void onSetScissorRect(const SkIRect& scissor) override;
|
||||
bool onBindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
|
||||
const GrSurfaceProxy* const primProcTextures[]) override;
|
||||
void onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override;
|
||||
void onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, uint16_t minIndexValue, uint16_t maxIndexValue,
|
||||
const GrBuffer* vertexBuffer, int baseVertex) override;
|
||||
void onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
|
||||
const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override;
|
||||
void onDrawIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, const GrBuffer* instanceBuffer,
|
||||
int instanceCount, int baseInstance, const GrBuffer* vertexBuffer,
|
||||
void onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart) override;
|
||||
void onDraw(int vertexCount, int baseVertex) override;
|
||||
void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) override;
|
||||
void onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||
int baseVertex) override;
|
||||
void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
|
||||
int baseVertex) override;
|
||||
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override;
|
||||
void onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) override;
|
||||
@ -77,6 +75,16 @@ private:
|
||||
|
||||
// Per-pipeline state.
|
||||
GrPrimitiveType fPrimitiveType;
|
||||
GrGLAttribArrayState* fAttribArrayState = nullptr;
|
||||
|
||||
// If using an index buffer, this gets set during onBindBuffers. It is either the CPU address of
|
||||
// the indices, or nullptr if they reside physically in GPU memory.
|
||||
const uint16_t* fIndexPointer;
|
||||
|
||||
// We may defer binding of instance and vertex buffers because GL does not always support a base
|
||||
// instance and/or vertex.
|
||||
sk_sp<const GrBuffer> fDeferredInstanceBuffer;
|
||||
sk_sp<const GrBuffer> fDeferredVertexBuffer;
|
||||
|
||||
typedef GrOpsRenderPass INHERITED;
|
||||
};
|
||||
|
@ -34,35 +34,17 @@ public:
|
||||
int numDraws() const { return fNumDraws; }
|
||||
|
||||
private:
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect&) override {
|
||||
return true;
|
||||
}
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect&) override { return true; }
|
||||
void onSetScissorRect(const SkIRect&) override {}
|
||||
bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrSurfaceProxy* const primProcTextures[]) override {
|
||||
return true;
|
||||
}
|
||||
void onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override {
|
||||
this->dummyDraw();
|
||||
}
|
||||
void onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, uint16_t minIndexValue, uint16_t maxIndexValue,
|
||||
const GrBuffer* vertexBuffer, int baseVertex) override {
|
||||
this->dummyDraw();
|
||||
}
|
||||
void onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
|
||||
const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override {
|
||||
this->dummyDraw();
|
||||
}
|
||||
void onDrawIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, const GrBuffer* instanceBuffer,
|
||||
int instanceCount, int baseInstance, const GrBuffer* vertexBuffer,
|
||||
int baseVertex) override {
|
||||
this->dummyDraw();
|
||||
}
|
||||
void onClear(const GrFixedClip&, const SkPMColor4f&) override {
|
||||
this->markRenderTargetDirty();
|
||||
}
|
||||
const GrSurfaceProxy* const primProcTextures[]) override { return true; }
|
||||
void onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart) override {}
|
||||
void onDraw(int, int) override { this->dummyDraw(); }
|
||||
void onDrawIndexed(int, int, uint16_t, uint16_t, int) override { this->dummyDraw(); }
|
||||
void onDrawInstanced(int, int, int, int) override { this->dummyDraw(); }
|
||||
void onDrawIndexedInstanced(int, int, int, int, int) override { this->dummyDraw(); }
|
||||
void onClear(const GrFixedClip&, const SkPMColor4f&) override { this->markRenderTargetDirty(); }
|
||||
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {}
|
||||
void dummyDraw() {
|
||||
this->markRenderTargetDirty();
|
||||
|
@ -43,15 +43,14 @@ private:
|
||||
void onSetScissorRect(const SkIRect&) override;
|
||||
bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrSurfaceProxy* const primProcTextures[]) override;
|
||||
void onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override;
|
||||
void onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, uint16_t minIndexValue, uint16_t maxIndexValue,
|
||||
const GrBuffer* vertexBuffer, int baseVertex) override;
|
||||
void onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
|
||||
const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override;
|
||||
void onDrawIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, const GrBuffer* instanceBuffer,
|
||||
int instanceCount, int baseInstance, const GrBuffer* vertexBuffer,
|
||||
void onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart) override;
|
||||
void onDraw(int vertexCount, int baseVertex) override;
|
||||
void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) override;
|
||||
void onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||
int baseVertex) override;
|
||||
void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
|
||||
int baseVertex) override;
|
||||
|
||||
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override;
|
||||
@ -61,11 +60,8 @@ private:
|
||||
void setupRenderPass(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
|
||||
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo);
|
||||
|
||||
void bindGeometry(const GrBuffer* vertexBuffer, size_t vertexOffset,
|
||||
const GrBuffer* instanceBuffer);
|
||||
|
||||
void setVertexBuffer(id<MTLRenderCommandEncoder>, const GrMtlBuffer*, size_t offset,
|
||||
size_t index);
|
||||
size_t inputBufferIndex);
|
||||
void resetBufferBindings();
|
||||
void precreateCmdEncoder();
|
||||
|
||||
@ -76,6 +72,12 @@ private:
|
||||
MTLPrimitiveType fActivePrimitiveType;
|
||||
MTLRenderPassDescriptor* fRenderPassDesc;
|
||||
SkRect fBounds;
|
||||
|
||||
// The index buffer in metal is an argument to the draw call, rather than a stateful binding.
|
||||
sk_sp<const GrMtlBuffer> fIndexBuffer;
|
||||
|
||||
// We defer binding of the vertex buffer because Metal doesn't have baseVertex for drawIndexed.
|
||||
sk_sp<const GrMtlBuffer> fDeferredVertexBuffer;
|
||||
size_t fCurrentVertexStride;
|
||||
|
||||
static constexpr size_t kNumBindings = GrMtlUniformHandler::kLastUniformBinding + 3;
|
||||
|
@ -246,70 +246,63 @@ void GrMtlOpsRenderPass::setupRenderPass(
|
||||
fActiveRenderCmdEncoder = nil;
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::bindGeometry(const GrBuffer* vertexBuffer,
|
||||
size_t vertexOffset,
|
||||
const GrBuffer* instanceBuffer) {
|
||||
size_t bufferIndex = GrMtlUniformHandler::kLastUniformBinding + 1;
|
||||
void GrMtlOpsRenderPass::onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer,
|
||||
GrPrimitiveRestart primRestart) {
|
||||
SkASSERT(GrPrimitiveRestart::kNo == primRestart);
|
||||
int inputBufferIndex = 0;
|
||||
if (vertexBuffer) {
|
||||
SkASSERT(!vertexBuffer->isCpuBuffer());
|
||||
SkASSERT(!static_cast<const GrGpuBuffer*>(vertexBuffer)->isMapped());
|
||||
|
||||
const GrMtlBuffer* grMtlBuffer = static_cast<const GrMtlBuffer*>(vertexBuffer);
|
||||
this->setVertexBuffer(fActiveRenderCmdEncoder, grMtlBuffer, vertexOffset, bufferIndex++);
|
||||
fDeferredVertexBuffer = sk_ref_sp(static_cast<const GrMtlBuffer*>(vertexBuffer));
|
||||
++inputBufferIndex;
|
||||
}
|
||||
if (instanceBuffer) {
|
||||
SkASSERT(!instanceBuffer->isCpuBuffer());
|
||||
SkASSERT(!static_cast<const GrGpuBuffer*>(instanceBuffer)->isMapped());
|
||||
|
||||
const GrMtlBuffer* grMtlBuffer = static_cast<const GrMtlBuffer*>(instanceBuffer);
|
||||
this->setVertexBuffer(fActiveRenderCmdEncoder, grMtlBuffer, 0, bufferIndex++);
|
||||
this->setVertexBuffer(fActiveRenderCmdEncoder, grMtlBuffer, 0, inputBufferIndex++);
|
||||
}
|
||||
if (indexBuffer) {
|
||||
SkASSERT(!indexBuffer->isCpuBuffer());
|
||||
SkASSERT(!static_cast<const GrGpuBuffer*>(indexBuffer)->isMapped());
|
||||
fIndexBuffer = sk_ref_sp(static_cast<const GrMtlBuffer*>(indexBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) {
|
||||
void GrMtlOpsRenderPass::onDraw(int vertexCount, int baseVertex) {
|
||||
SkASSERT(fActivePipelineState);
|
||||
SkASSERT(nil != fActiveRenderCmdEncoder);
|
||||
this->bindGeometry(vertexBuffer, 0, nullptr);
|
||||
this->setVertexBuffer(fActiveRenderCmdEncoder, fDeferredVertexBuffer.get(), 0, 0);
|
||||
|
||||
[fActiveRenderCmdEncoder drawPrimitives:fActivePrimitiveType
|
||||
vertexStart:baseVertex
|
||||
vertexCount:vertexCount];
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart primitiveRestart, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
|
||||
int baseVertex) {
|
||||
void GrMtlOpsRenderPass::onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) {
|
||||
SkASSERT(fActivePipelineState);
|
||||
SkASSERT(nil != fActiveRenderCmdEncoder);
|
||||
this->bindGeometry(vertexBuffer, fCurrentVertexStride*baseVertex, nullptr);
|
||||
SkASSERT(fIndexBuffer);
|
||||
this->setVertexBuffer(fActiveRenderCmdEncoder, fDeferredVertexBuffer.get(),
|
||||
fCurrentVertexStride * baseVertex, 0);
|
||||
|
||||
id<MTLBuffer> mtlIndexBuffer = nil;
|
||||
if (indexBuffer) {
|
||||
SkASSERT(!indexBuffer->isCpuBuffer());
|
||||
SkASSERT(!static_cast<const GrGpuBuffer*>(indexBuffer)->isMapped());
|
||||
|
||||
mtlIndexBuffer = static_cast<const GrMtlBuffer*>(indexBuffer)->mtlBuffer();
|
||||
SkASSERT(mtlIndexBuffer);
|
||||
}
|
||||
|
||||
SkASSERT(primitiveRestart == GrPrimitiveRestart::kNo);
|
||||
size_t indexOffset = static_cast<const GrMtlBuffer*>(indexBuffer)->offset() +
|
||||
sizeof(uint16_t) * baseIndex;
|
||||
size_t indexOffset = fIndexBuffer->offset() + sizeof(uint16_t) * baseIndex;
|
||||
[fActiveRenderCmdEncoder drawIndexedPrimitives:fActivePrimitiveType
|
||||
indexCount:indexCount
|
||||
indexType:MTLIndexTypeUInt16
|
||||
indexBuffer:mtlIndexBuffer
|
||||
indexBuffer:fIndexBuffer->mtlBuffer()
|
||||
indexBufferOffset:indexOffset];
|
||||
fGpu->stats()->incNumDraws();
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer,
|
||||
int vertexCount, int baseVertex) {
|
||||
void GrMtlOpsRenderPass::onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||
int baseVertex) {
|
||||
SkASSERT(fActivePipelineState);
|
||||
SkASSERT(nil != fActiveRenderCmdEncoder);
|
||||
this->bindGeometry(vertexBuffer, 0, instanceBuffer);
|
||||
this->setVertexBuffer(fActiveRenderCmdEncoder, fDeferredVertexBuffer.get(), 0, 0);
|
||||
|
||||
if (@available(macOS 10.11, iOS 9.0, *)) {
|
||||
[fActiveRenderCmdEncoder drawPrimitives:fActivePrimitiveType
|
||||
@ -323,31 +316,18 @@ void GrMtlOpsRenderPass::onDrawInstanced(const GrBuffer* instanceBuffer, int ins
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::onDrawIndexedInstanced(
|
||||
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart primitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer, int baseVertex) {
|
||||
int indexCount, int baseIndex, int instanceCount, int baseInstance, int baseVertex) {
|
||||
SkASSERT(fActivePipelineState);
|
||||
SkASSERT(nil != fActiveRenderCmdEncoder);
|
||||
this->bindGeometry(vertexBuffer, 0, instanceBuffer);
|
||||
|
||||
id<MTLBuffer> mtlIndexBuffer = nil;
|
||||
if (indexBuffer) {
|
||||
SkASSERT(!indexBuffer->isCpuBuffer());
|
||||
SkASSERT(!static_cast<const GrGpuBuffer*>(indexBuffer)->isMapped());
|
||||
|
||||
mtlIndexBuffer = static_cast<const GrMtlBuffer*>(indexBuffer)->mtlBuffer();
|
||||
SkASSERT(mtlIndexBuffer);
|
||||
}
|
||||
|
||||
SkASSERT(primitiveRestart == GrPrimitiveRestart::kNo);
|
||||
size_t indexOffset = static_cast<const GrMtlBuffer*>(indexBuffer)->offset() +
|
||||
sizeof(uint16_t) * baseIndex;
|
||||
SkASSERT(fIndexBuffer);
|
||||
this->setVertexBuffer(fActiveRenderCmdEncoder, fDeferredVertexBuffer.get(), 0, 0);
|
||||
|
||||
size_t indexOffset = fIndexBuffer->offset() + sizeof(uint16_t) * baseIndex;
|
||||
if (@available(macOS 10.11, iOS 9.0, *)) {
|
||||
[fActiveRenderCmdEncoder drawIndexedPrimitives:fActivePrimitiveType
|
||||
indexCount:indexCount
|
||||
indexType:MTLIndexTypeUInt16
|
||||
indexBuffer:mtlIndexBuffer
|
||||
indexBuffer:fIndexBuffer->mtlBuffer()
|
||||
indexBufferOffset:indexOffset
|
||||
instanceCount:instanceCount
|
||||
baseVertex:baseVertex
|
||||
@ -361,7 +341,9 @@ void GrMtlOpsRenderPass::onDrawIndexedInstanced(
|
||||
void GrMtlOpsRenderPass::setVertexBuffer(id<MTLRenderCommandEncoder> encoder,
|
||||
const GrMtlBuffer* buffer,
|
||||
size_t vertexOffset,
|
||||
size_t index) {
|
||||
size_t inputBufferIndex) {
|
||||
constexpr static int kFirstBufferBindingIdx = GrMtlUniformHandler::kLastUniformBinding + 1;
|
||||
int index = inputBufferIndex + kFirstBufferBindingIdx;
|
||||
SkASSERT(index < 4);
|
||||
id<MTLBuffer> mtlVertexBuffer = buffer->mtlBuffer();
|
||||
SkASSERT(mtlVertexBuffer);
|
||||
|
@ -443,42 +443,6 @@ void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state, GrDeferredTextureUpl
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrVkOpsRenderPass::bindGeometry(const GrGpuBuffer* indexBuffer,
|
||||
const GrGpuBuffer* vertexBuffer,
|
||||
const GrGpuBuffer* instanceBuffer) {
|
||||
GrVkCommandBuffer* currCmdBuf = this->currentCommandBuffer();
|
||||
// There is no need to put any memory barriers to make sure host writes have finished here.
|
||||
// When a command buffer is submitted to a queue, there is an implicit memory barrier that
|
||||
// occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
|
||||
// an active RenderPass.
|
||||
|
||||
// Here our vertex and instance inputs need to match the same 0-based bindings they were
|
||||
// assigned in GrVkPipeline. That is, vertex first (if any) followed by instance.
|
||||
uint32_t binding = 0;
|
||||
|
||||
if (vertexBuffer) {
|
||||
SkASSERT(vertexBuffer);
|
||||
SkASSERT(!vertexBuffer->isMapped());
|
||||
|
||||
currCmdBuf->bindInputBuffer(fGpu, binding++,
|
||||
static_cast<const GrVkVertexBuffer*>(vertexBuffer));
|
||||
}
|
||||
|
||||
if (instanceBuffer) {
|
||||
SkASSERT(instanceBuffer);
|
||||
SkASSERT(!instanceBuffer->isMapped());
|
||||
|
||||
currCmdBuf->bindInputBuffer(fGpu, binding++,
|
||||
static_cast<const GrVkVertexBuffer*>(instanceBuffer));
|
||||
}
|
||||
if (indexBuffer) {
|
||||
SkASSERT(indexBuffer);
|
||||
SkASSERT(!indexBuffer->isMapped());
|
||||
|
||||
currCmdBuf->bindIndexBuffer(fGpu, static_cast<const GrVkIndexBuffer*>(indexBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void check_sampled_texture(GrTexture* tex, GrRenderTarget* rt, GrVkGpu* gpu) {
|
||||
SkASSERT(!tex->isProtected() || (rt->isProtected() && gpu->protectedContext()));
|
||||
@ -582,45 +546,70 @@ void GrVkOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
|
||||
bool GrVkOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrSurfaceProxy* const primProcTextures[]) {
|
||||
SkASSERT(fCurrentPipelineState);
|
||||
return fCurrentPipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcTextures,
|
||||
this->currentCommandBuffer());
|
||||
}
|
||||
|
||||
void GrVkOpsRenderPass::onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer,
|
||||
void GrVkOpsRenderPass::onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer,
|
||||
GrPrimitiveRestart primRestart) {
|
||||
SkASSERT(GrPrimitiveRestart::kNo == primRestart);
|
||||
if (!fCurrentRenderPass) {
|
||||
SkASSERT(fGpu->isDeviceLost());
|
||||
return;
|
||||
}
|
||||
SkASSERT(fCurrentPipelineState);
|
||||
SkASSERT(!fGpu->caps()->usePrimitiveRestart()); // Ignore primitiveRestart parameter.
|
||||
|
||||
GrVkCommandBuffer* currCmdBuf = this->currentCommandBuffer();
|
||||
SkASSERT(currCmdBuf);
|
||||
|
||||
// There is no need to put any memory barriers to make sure host writes have finished here.
|
||||
// When a command buffer is submitted to a queue, there is an implicit memory barrier that
|
||||
// occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
|
||||
// an active RenderPass.
|
||||
|
||||
// Here our vertex and instance inputs need to match the same 0-based bindings they were
|
||||
// assigned in GrVkPipeline. That is, vertex first (if any) followed by instance.
|
||||
uint32_t binding = 0;
|
||||
if (auto* vkVertexBuffer = static_cast<const GrVkVertexBuffer*>(vertexBuffer)) {
|
||||
SkASSERT(!vkVertexBuffer->isCpuBuffer());
|
||||
SkASSERT(!vkVertexBuffer->isMapped());
|
||||
currCmdBuf->bindInputBuffer(fGpu, binding++, vkVertexBuffer);
|
||||
}
|
||||
if (auto* vkInstanceBuffer = static_cast<const GrVkVertexBuffer*>(instanceBuffer)) {
|
||||
SkASSERT(!vkInstanceBuffer->isCpuBuffer());
|
||||
SkASSERT(!vkInstanceBuffer->isMapped());
|
||||
currCmdBuf->bindInputBuffer(fGpu, binding++, vkInstanceBuffer);
|
||||
}
|
||||
if (auto* vkIndexBuffer = static_cast<const GrVkIndexBuffer*>(indexBuffer)) {
|
||||
SkASSERT(!vkIndexBuffer->isCpuBuffer());
|
||||
SkASSERT(!vkIndexBuffer->isMapped());
|
||||
currCmdBuf->bindIndexBuffer(fGpu, vkIndexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void GrVkOpsRenderPass::onDrawInstanced(int instanceCount,
|
||||
int baseInstance,
|
||||
int vertexCount, int baseVertex) {
|
||||
if (!fCurrentRenderPass) {
|
||||
SkASSERT(fGpu->isDeviceLost());
|
||||
return;
|
||||
}
|
||||
SkASSERT(fCurrentPipelineState);
|
||||
SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
|
||||
SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
|
||||
auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
|
||||
auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
|
||||
this->bindGeometry(nullptr, gpuVertexBuffer, gpuInstanceBuffer);
|
||||
this->currentCommandBuffer()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
|
||||
fGpu->stats()->incNumDraws();
|
||||
fCurrentCBIsEmpty = false;
|
||||
}
|
||||
|
||||
void GrVkOpsRenderPass::onDrawIndexedInstanced(
|
||||
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart primitiveRestart, const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, const GrBuffer* vertexBuffer, int baseVertex) {
|
||||
void GrVkOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount,
|
||||
int baseInstance, int baseVertex) {
|
||||
if (!fCurrentRenderPass) {
|
||||
SkASSERT(fGpu->isDeviceLost());
|
||||
return;
|
||||
}
|
||||
SkASSERT(fCurrentPipelineState);
|
||||
SkASSERT(primitiveRestart == GrPrimitiveRestart::kNo);
|
||||
SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
|
||||
SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
|
||||
SkASSERT(!indexBuffer->isCpuBuffer());
|
||||
auto gpuIndexxBuffer = static_cast<const GrGpuBuffer*>(indexBuffer);
|
||||
auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
|
||||
auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
|
||||
this->bindGeometry(gpuIndexxBuffer, gpuVertexBuffer, gpuInstanceBuffer);
|
||||
this->currentCommandBuffer()->drawIndexed(fGpu, indexCount, instanceCount,
|
||||
baseIndex, baseVertex, baseInstance);
|
||||
fGpu->stats()->incNumDraws();
|
||||
|
@ -63,30 +63,22 @@ private:
|
||||
|
||||
GrVkCommandBuffer* currentCommandBuffer();
|
||||
|
||||
// Bind vertex and index buffers
|
||||
void bindGeometry(const GrGpuBuffer* indexBuffer,
|
||||
const GrGpuBuffer* vertexBuffer,
|
||||
const GrGpuBuffer* instanceBuffer);
|
||||
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override;
|
||||
void onSetScissorRect(const SkIRect&) override;
|
||||
bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrSurfaceProxy* const primProcTextures[]) override;
|
||||
void onDraw(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override {
|
||||
this->onDrawInstanced(nullptr, 1, 0, vertexBuffer, vertexCount, baseVertex);
|
||||
void onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart) override;
|
||||
void onDraw(int vertexCount, int baseVertex) override {
|
||||
this->onDrawInstanced(1, 0, vertexCount, baseVertex);
|
||||
}
|
||||
void onDrawIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart primitiveRestart, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
|
||||
int baseVertex) override {
|
||||
this->onDrawIndexedInstanced(indexBuffer, indexCount, baseIndex, primitiveRestart, nullptr,
|
||||
1, 0, vertexBuffer, baseVertex);
|
||||
void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) override {
|
||||
this->onDrawIndexedInstanced(indexCount, baseIndex, 1, 0, baseVertex);
|
||||
}
|
||||
void onDrawInstanced(const GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
|
||||
const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) override;
|
||||
void onDrawIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
GrPrimitiveRestart, const GrBuffer* instanceBuffer,
|
||||
int instanceCount, int baseInstance, const GrBuffer* vertexBuffer,
|
||||
void onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||
int baseVertex) override;
|
||||
void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
|
||||
int baseVertex) override;
|
||||
|
||||
void onClear(const GrFixedClip&, const SkPMColor4f& color) override;
|
||||
|
Loading…
Reference in New Issue
Block a user