Revert "Reland "Use glDraw.*BaseInstance calls to avoid deferred buffer binding""
This reverts commitd84b691950
. Reason for revert: seems like chrome's glInterface is maybe not setup correctly. Crashing on intel gpu chrome bots: https://logs.chromium.org/logs/chromium/buildbucket/cr-buildbucket.appspot.com/8884195221041295328/+/steps/trace_test_on__intel-hd-630-ubuntu-stable__GPU_on_Linux__retry_shards_with_patch__on_linux-intel-stable/0/stdout snippet: Crash reason: SIGABRT Crash address: 0x3e8000050b0 Process uptime: not available Thread 0 (crashed) 0 libc.so.6 + 0x43ed7 rax = 0x0000000000000000 rdx = 0x0000000000000000 rcx = 0x00007ff964c3ced7 rbx = 0x00002cc73685ddc0 rsi = 0x00007fffb9128960 rdi = 0x0000000000000002 rbp = 0x00007fffb9128bb0 rsp = 0x00007fffb9128960 r8 = 0x0000000000000000 r9 = 0x00007fffb9128960 r10 = 0x0000000000000008 r11 = 0x0000000000000246 r12 = 0x0000000000000048 r13 = 0x0000000000000000 r14 = 0x000000000000006c r15 = 0x0000000000000000 rip = 0x00007ff964c3ced7 Found by: given as instruction pointer in context 1 chrome!GrGLGpu::drawElementsInstancedBaseVertexBaseInstance(GrPrimitiveType, int, unsigned int, void const*, int, int, unsigned int)::$_81::operator()() const + 0x33 rbp = 0x00007fffb9128bc0 rsp = 0x00007fffb9128bc0 rip = 0x000055c5c1db6923 Found by: previous frame's frame pointer 2 chrome!drawElementsInstancedBaseVertexBaseInstance [GrGLGpu.cpp : 2306 + 0x5] rbp = 0x00007fffb9128c10 rsp = 0x00007fffb9128bd0 rip = 0x000055c5c1db68b6 Found by: call frame info 3 chrome!onDrawIndexed [GrGLOpsRenderPass.cpp : 144 + 0x16] Original change's description: > Reland "Use glDraw.*BaseInstance calls to avoid deferred buffer binding" > > This is a reland ofe8c963d474
> > Original change's description: > > Use glDraw.*BaseInstance calls to avoid deferred buffer binding > > > > Change-Id: I968dab317673051acc65f87ea76a0d657d89b3d2 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/279538 > > Commit-Queue: Chris Dalton <csmartdalton@google.com> > > Reviewed-by: Michael Ludwig <michaelludwig@google.com> > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Change-Id: I79b2d23e5e66d47214898a9068079b6fe2269599 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/280806 > Commit-Queue: Chris Dalton <csmartdalton@google.com> > Reviewed-by: Brian Salomon <bsalomon@google.com> TBR=bsalomon@google.com,csmartdalton@google.com,michaelludwig@google.com Change-Id: I1d2617f077676b6f36bb723615d527e4aa4b3efe No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281057 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
7c75226854
commit
b14b144458
@ -37,7 +37,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
|
|||||||
fDrawIndirectSupport = false;
|
fDrawIndirectSupport = false;
|
||||||
fDrawRangeElementsSupport = false;
|
fDrawRangeElementsSupport = false;
|
||||||
fMultiDrawIndirectSupport = false;
|
fMultiDrawIndirectSupport = false;
|
||||||
fBaseVertexBaseInstanceSupport = false;
|
fBaseInstanceSupport = false;
|
||||||
fUseNonVBOVertexAndIndexDynamicData = false;
|
fUseNonVBOVertexAndIndexDynamicData = false;
|
||||||
fIsCoreProfile = false;
|
fIsCoreProfile = false;
|
||||||
fBindFragDataLocationSupport = false;
|
fBindFragDataLocationSupport = false;
|
||||||
@ -625,17 +625,18 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
|||||||
if (GR_IS_GR_GL(standard)) {
|
if (GR_IS_GR_GL(standard)) {
|
||||||
fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
|
fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
|
||||||
ctxInfo.hasExtension("GL_ARB_draw_indirect");
|
ctxInfo.hasExtension("GL_ARB_draw_indirect");
|
||||||
fBaseVertexBaseInstanceSupport = version >= GR_GL_VER(4,2) ||
|
fBaseInstanceSupport = version >= GR_GL_VER(4,2);
|
||||||
ctxInfo.hasExtension("GL_ARB_base_instance");
|
|
||||||
fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
|
fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
|
||||||
ctxInfo.hasExtension("GL_ARB_multi_draw_indirect");
|
(fDrawIndirectSupport &&
|
||||||
|
!fBaseInstanceSupport && // The ARB extension has no base inst.
|
||||||
|
ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
|
||||||
fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
|
fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
|
||||||
} else if (GR_IS_GR_GL_ES(standard)) {
|
} else if (GR_IS_GR_GL_ES(standard)) {
|
||||||
fDrawIndirectSupport = version >= GR_GL_VER(3,1);
|
fDrawIndirectSupport = version >= GR_GL_VER(3,1);
|
||||||
fMultiDrawIndirectSupport = fDrawIndirectSupport &&
|
fMultiDrawIndirectSupport = fDrawIndirectSupport &&
|
||||||
ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
|
ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
|
||||||
fBaseVertexBaseInstanceSupport = ctxInfo.hasExtension("GL_EXT_base_instance") ||
|
fBaseInstanceSupport = ctxInfo.hasExtension("GL_EXT_base_instance") ||
|
||||||
ctxInfo.hasExtension("GL_ANGLE_base_vertex_base_instance");
|
ctxInfo.hasExtension("GL_ANGLE_base_vertex_base_instance");
|
||||||
fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
|
fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
|
||||||
} else if (GR_IS_GR_WEBGL(standard)) {
|
} else if (GR_IS_GR_WEBGL(standard)) {
|
||||||
// WebGL lacks indirect support, but drawRange was added in WebGL 2.0
|
// WebGL lacks indirect support, but drawRange was added in WebGL 2.0
|
||||||
@ -1183,7 +1184,7 @@ void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
|
|||||||
writer->appendBool("Debug support", fDebugSupport);
|
writer->appendBool("Debug support", fDebugSupport);
|
||||||
writer->appendBool("Draw indirect support", fDrawIndirectSupport);
|
writer->appendBool("Draw indirect support", fDrawIndirectSupport);
|
||||||
writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
|
writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
|
||||||
writer->appendBool("Base (vertex base) instance support", fBaseVertexBaseInstanceSupport);
|
writer->appendBool("Base instance support", fBaseInstanceSupport);
|
||||||
writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
|
writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
|
||||||
writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
|
writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
|
||||||
writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
|
writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
|
||||||
@ -3543,7 +3544,7 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
|
|||||||
// http://anglebug.com/4536
|
// http://anglebug.com/4536
|
||||||
if (ctxInfo.driver() == kANGLE_GrGLDriver &&
|
if (ctxInfo.driver() == kANGLE_GrGLDriver &&
|
||||||
ctxInfo.angleBackend() != GrGLANGLEBackend::kOpenGL) {
|
ctxInfo.angleBackend() != GrGLANGLEBackend::kOpenGL) {
|
||||||
fBaseVertexBaseInstanceSupport = false;
|
fBaseInstanceSupport = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
|
// Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
|
||||||
|
@ -324,9 +324,8 @@ public:
|
|||||||
/// Is there support for glDrawRangeElements?
|
/// Is there support for glDrawRangeElements?
|
||||||
bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; }
|
bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; }
|
||||||
|
|
||||||
/// Are the glDraw*Base(VertexBase)Instance methods, and baseInstance fields in indirect draw
|
/// Are the baseInstance fields supported in indirect draw commands?
|
||||||
//commands supported?
|
bool baseInstanceSupport() const { return fBaseInstanceSupport; }
|
||||||
bool baseVertexBaseInstanceSupport() const { return fBaseVertexBaseInstanceSupport; }
|
|
||||||
|
|
||||||
/// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
|
/// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
|
||||||
bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
|
bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
|
||||||
@ -529,7 +528,7 @@ private:
|
|||||||
bool fDrawIndirectSupport : 1;
|
bool fDrawIndirectSupport : 1;
|
||||||
bool fDrawRangeElementsSupport : 1;
|
bool fDrawRangeElementsSupport : 1;
|
||||||
bool fMultiDrawIndirectSupport : 1;
|
bool fMultiDrawIndirectSupport : 1;
|
||||||
bool fBaseVertexBaseInstanceSupport : 1;
|
bool fBaseInstanceSupport : 1;
|
||||||
bool fUseNonVBOVertexAndIndexDynamicData : 1;
|
bool fUseNonVBOVertexAndIndexDynamicData : 1;
|
||||||
bool fIsCoreProfile : 1;
|
bool fIsCoreProfile : 1;
|
||||||
bool fBindFragDataLocationSupport : 1;
|
bool fBindFragDataLocationSupport : 1;
|
||||||
|
@ -2274,43 +2274,19 @@ void GrGLGpu::drawRangeElements(GrPrimitiveType primitiveType, GrGLuint minIndex
|
|||||||
|
|
||||||
void GrGLGpu::drawArraysInstanced(GrPrimitiveType primitiveType, GrGLint baseVertex,
|
void GrGLGpu::drawArraysInstanced(GrPrimitiveType primitiveType, GrGLint baseVertex,
|
||||||
GrGLsizei vertexCount, GrGLsizei instanceCount) {
|
GrGLsizei vertexCount, GrGLsizei instanceCount) {
|
||||||
SkASSERT(this->glCaps().instanceAttribSupport());
|
|
||||||
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
|
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
|
||||||
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
|
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
|
||||||
GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, instanceCount));
|
GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, instanceCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLGpu::drawArraysInstancedBaseInstance(GrPrimitiveType primitiveType, GrGLint baseVertex,
|
|
||||||
GrGLsizei vertexCount, GrGLsizei instanceCount,
|
|
||||||
GrGLuint baseInstance) {
|
|
||||||
SkASSERT(this->glCaps().instanceAttribSupport());
|
|
||||||
SkASSERT(this->glCaps().baseVertexBaseInstanceSupport());
|
|
||||||
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
|
|
||||||
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
|
|
||||||
GL_CALL(DrawArraysInstancedBaseInstance(glPrimType, baseVertex, vertexCount, instanceCount,
|
|
||||||
baseInstance));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrGLGpu::drawElementsInstanced(GrPrimitiveType primitiveType, GrGLsizei indexCount,
|
void GrGLGpu::drawElementsInstanced(GrPrimitiveType primitiveType, GrGLsizei indexCount,
|
||||||
GrGLenum indexType, const void* indices,
|
GrGLenum indexType, const void* indices,
|
||||||
GrGLsizei instanceCount) {
|
GrGLsizei instanceCount) {
|
||||||
SkASSERT(this->glCaps().instanceAttribSupport());
|
|
||||||
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
|
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
|
||||||
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
|
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
|
||||||
GL_CALL(DrawElementsInstanced(glPrimType, indexCount, indexType, indices, instanceCount));
|
GL_CALL(DrawElementsInstanced(glPrimType, indexCount, indexType, indices, instanceCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLGpu::drawElementsInstancedBaseVertexBaseInstance(
|
|
||||||
GrPrimitiveType primitiveType, GrGLsizei indexCount, GrGLenum indexType,
|
|
||||||
const void* indices, GrGLsizei instanceCount, GrGLint baseVertex, GrGLuint baseInstance) {
|
|
||||||
SkASSERT(this->glCaps().instanceAttribSupport());
|
|
||||||
SkASSERT(this->glCaps().baseVertexBaseInstanceSupport());
|
|
||||||
SkASSERT(instanceCount <= this->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount));
|
|
||||||
GrGLenum glPrimType = this->prepareToDraw(primitiveType);
|
|
||||||
GL_CALL(DrawElementsInstancedBaseVertexBaseInstance(glPrimType, indexCount, indexType, indices,
|
|
||||||
instanceCount, baseVertex, baseInstance));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect,
|
void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect,
|
||||||
ForExternalIO) {
|
ForExternalIO) {
|
||||||
// Some extensions automatically resolves the texture when it is read.
|
// Some extensions automatically resolves the texture when it is read.
|
||||||
|
@ -113,13 +113,8 @@ public:
|
|||||||
GrGLsizei indexCount, GrGLenum indexType, const void* indices);
|
GrGLsizei indexCount, GrGLenum indexType, const void* indices);
|
||||||
void drawArraysInstanced(GrPrimitiveType, GrGLint baseVertex, GrGLsizei vertexCount,
|
void drawArraysInstanced(GrPrimitiveType, GrGLint baseVertex, GrGLsizei vertexCount,
|
||||||
GrGLsizei instanceCount);
|
GrGLsizei instanceCount);
|
||||||
void drawArraysInstancedBaseInstance(GrPrimitiveType, GrGLint baseVertex, GrGLsizei vertexCount,
|
|
||||||
GrGLsizei instanceCount, GrGLuint baseInstance);
|
|
||||||
void drawElementsInstanced(GrPrimitiveType, GrGLsizei indexCount, GrGLenum indexType,
|
void drawElementsInstanced(GrPrimitiveType, GrGLsizei indexCount, GrGLenum indexType,
|
||||||
const void* indices, GrGLsizei instanceCount);
|
const void* indices, GrGLsizei instanceCount);
|
||||||
void drawElementsInstancedBaseVertexBaseInstance(
|
|
||||||
GrPrimitiveType, GrGLsizei indexCount, GrGLenum indexType, const void* indices,
|
|
||||||
GrGLsizei instanceCount, GrGLint baseVertex, GrGLuint baseInstance);
|
|
||||||
|
|
||||||
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
|
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
|
||||||
// Thus this is the implementation of the clear call for the corresponding passthrough function
|
// Thus this is the implementation of the clear call for the corresponding passthrough function
|
||||||
|
@ -240,10 +240,7 @@ bool GrGLInterface::validate() const {
|
|||||||
(GR_IS_GR_GL_ES(fStandard) && (
|
(GR_IS_GR_GL_ES(fStandard) && (
|
||||||
fExtensions.has("GL_EXT_base_instance") ||
|
fExtensions.has("GL_EXT_base_instance") ||
|
||||||
fExtensions.has("GL_ANGLE_base_vertex_base_instance")))) {
|
fExtensions.has("GL_ANGLE_base_vertex_base_instance")))) {
|
||||||
if (!fFunctions.fDrawArraysInstancedBaseInstance ||
|
// all functions were marked optional or test_only
|
||||||
!fFunctions.fDrawElementsInstancedBaseVertexBaseInstance) {
|
|
||||||
RETURN_FALSE_INTERFACE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GR_IS_GR_GL(fStandard) ||
|
if (GR_IS_GR_GL(fStandard) ||
|
||||||
|
@ -48,7 +48,9 @@ bool GrGLOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
|
|||||||
const GrSurfaceProxy* const primProcTextures[],
|
const GrSurfaceProxy* const primProcTextures[],
|
||||||
const GrPipeline& pipeline) {
|
const GrPipeline& pipeline) {
|
||||||
GrGLProgram* program = fGpu->currentProgram();
|
GrGLProgram* program = fGpu->currentProgram();
|
||||||
SkASSERT(program);
|
if (!program) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
program->bindTextures(primProc, primProcTextures, pipeline);
|
program->bindTextures(primProc, primProcTextures, pipeline);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -58,7 +60,9 @@ void GrGLOpsRenderPass::onBindBuffers(const GrBuffer* indexBuffer, const GrBuffe
|
|||||||
GrPrimitiveRestart primitiveRestart) {
|
GrPrimitiveRestart primitiveRestart) {
|
||||||
SkASSERT((primitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer);
|
SkASSERT((primitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer);
|
||||||
GrGLProgram* program = fGpu->currentProgram();
|
GrGLProgram* program = fGpu->currentProgram();
|
||||||
SkASSERT(program);
|
if (!program) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int numAttribs = program->numVertexAttributes() + program->numInstanceAttributes();
|
int numAttribs = program->numVertexAttributes() + program->numInstanceAttributes();
|
||||||
fAttribArrayState = fGpu->bindInternalVertexArray(indexBuffer, numAttribs, primitiveRestart);
|
fAttribArrayState = fGpu->bindInternalVertexArray(indexBuffer, numAttribs, primitiveRestart);
|
||||||
@ -72,27 +76,32 @@ void GrGLOpsRenderPass::onBindBuffers(const GrBuffer* indexBuffer, const GrBuffe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fGpu->glCaps().baseVertexBaseInstanceSupport()) {
|
// We defer binding of instance and vertex buffers because GL does not (always) support base
|
||||||
// This platform does not support baseInstance. Defer binding of the instance buffer.
|
// instance and/or base vertex.
|
||||||
fActiveInstanceBuffer = sk_ref_sp(instanceBuffer);
|
fActiveInstanceBuffer = sk_ref_sp(instanceBuffer);
|
||||||
} else {
|
fActiveVertexBuffer = sk_ref_sp(vertexBuffer);
|
||||||
this->bindInstanceBuffer(instanceBuffer, 0);
|
|
||||||
}
|
|
||||||
if (!indexBuffer && fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
|
|
||||||
// There is a driver bug affecting glDrawArrays. Defer binding of the vertex buffer.
|
|
||||||
fActiveVertexBuffer = sk_ref_sp(vertexBuffer);
|
|
||||||
} else if (indexBuffer && !fGpu->glCaps().baseVertexBaseInstanceSupport()) {
|
|
||||||
// This platform does not support baseVertex with indexed draws. Defer binding of the
|
|
||||||
// vertex buffer.
|
|
||||||
fActiveVertexBuffer = sk_ref_sp(vertexBuffer);
|
|
||||||
} else {
|
|
||||||
this->bindVertexBuffer(vertexBuffer, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLOpsRenderPass::bindInstanceBuffer(const GrBuffer* instanceBuffer, int baseInstance) {
|
void GrGLOpsRenderPass::setupGeometry(const GrBuffer* vertexBuffer, int baseVertex,
|
||||||
|
const GrBuffer* instanceBuffer, int baseInstance) {
|
||||||
GrGLProgram* program = fGpu->currentProgram();
|
GrGLProgram* program = fGpu->currentProgram();
|
||||||
SkASSERT(program);
|
if (!program) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int vertexStride = program->vertexStride()) {
|
||||||
|
SkASSERT(vertexBuffer);
|
||||||
|
SkASSERT(vertexBuffer->isCpuBuffer() ||
|
||||||
|
!static_cast<const GrGpuBuffer*>(vertexBuffer)->isMapped());
|
||||||
|
size_t bufferOffset = baseVertex * static_cast<size_t>(vertexStride);
|
||||||
|
for (int i = 0; i < program->numVertexAttributes(); ++i) {
|
||||||
|
const auto& attrib = program->vertexAttribute(i);
|
||||||
|
static constexpr int kDivisor = 0;
|
||||||
|
fAttribArrayState->set(fGpu, attrib.fLocation, vertexBuffer, attrib.fCPUType,
|
||||||
|
attrib.fGPUType, vertexStride, bufferOffset + attrib.fOffset,
|
||||||
|
kDivisor);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (int instanceStride = program->instanceStride()) {
|
if (int instanceStride = program->instanceStride()) {
|
||||||
SkASSERT(instanceBuffer);
|
SkASSERT(instanceBuffer);
|
||||||
SkASSERT(instanceBuffer->isCpuBuffer() ||
|
SkASSERT(instanceBuffer->isCpuBuffer() ||
|
||||||
@ -109,47 +118,20 @@ void GrGLOpsRenderPass::bindInstanceBuffer(const GrBuffer* instanceBuffer, int b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLOpsRenderPass::bindVertexBuffer(const GrBuffer* vertexBuffer, int baseVertex) {
|
|
||||||
GrGLProgram* program = fGpu->currentProgram();
|
|
||||||
SkASSERT(program);
|
|
||||||
if (int vertexStride = program->vertexStride()) {
|
|
||||||
SkASSERT(vertexBuffer);
|
|
||||||
SkASSERT(vertexBuffer->isCpuBuffer() ||
|
|
||||||
!static_cast<const GrGpuBuffer*>(vertexBuffer)->isMapped());
|
|
||||||
size_t bufferOffset = baseVertex * static_cast<size_t>(vertexStride);
|
|
||||||
for (int i = 0; i < program->numVertexAttributes(); ++i) {
|
|
||||||
const auto& attrib = program->vertexAttribute(i);
|
|
||||||
static constexpr int kDivisor = 0;
|
|
||||||
fAttribArrayState->set(fGpu, attrib.fLocation, vertexBuffer, attrib.fCPUType,
|
|
||||||
attrib.fGPUType, vertexStride, bufferOffset + attrib.fOffset,
|
|
||||||
kDivisor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrGLOpsRenderPass::onDraw(int vertexCount, int baseVertex) {
|
void GrGLOpsRenderPass::onDraw(int vertexCount, int baseVertex) {
|
||||||
SkASSERT(!fActiveVertexBuffer || fGpu->glCaps().drawArraysBaseVertexIsBroken());
|
|
||||||
if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
|
if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
|
||||||
this->bindVertexBuffer(fActiveVertexBuffer.get(), baseVertex);
|
this->setupGeometry(fActiveVertexBuffer.get(), baseVertex, nullptr, 0);
|
||||||
baseVertex = 0;
|
fGpu->drawArrays(fPrimitiveType, 0, vertexCount);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->setupGeometry(fActiveVertexBuffer.get(), 0, nullptr, 0);
|
||||||
fGpu->drawArrays(fPrimitiveType, baseVertex, vertexCount);
|
fGpu->drawArrays(fPrimitiveType, baseVertex, vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLOpsRenderPass::onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
void GrGLOpsRenderPass::onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||||
uint16_t maxIndexValue, int baseVertex) {
|
uint16_t maxIndexValue, int baseVertex) {
|
||||||
if (fGpu->glCaps().baseVertexBaseInstanceSupport()) {
|
this->setupGeometry(fActiveVertexBuffer.get(), baseVertex, nullptr, 0);
|
||||||
SkASSERT(!fActiveVertexBuffer);
|
|
||||||
if (baseVertex != 0) {
|
|
||||||
fGpu->drawElementsInstancedBaseVertexBaseInstance(
|
|
||||||
fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT,
|
|
||||||
this->offsetForBaseIndex(baseIndex), 1, baseVertex, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this->bindVertexBuffer(fActiveVertexBuffer.get(), baseVertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fGpu->glCaps().drawRangeElementsSupport()) {
|
if (fGpu->glCaps().drawRangeElementsSupport()) {
|
||||||
fGpu->drawRangeElements(fPrimitiveType, minIndexValue, maxIndexValue, indexCount,
|
fGpu->drawRangeElements(fPrimitiveType, minIndexValue, maxIndexValue, indexCount,
|
||||||
GR_GL_UNSIGNED_SHORT, this->offsetForBaseIndex(baseIndex));
|
GR_GL_UNSIGNED_SHORT, this->offsetForBaseIndex(baseIndex));
|
||||||
@ -161,25 +143,12 @@ void GrGLOpsRenderPass::onDrawIndexed(int indexCount, int baseIndex, uint16_t mi
|
|||||||
|
|
||||||
void GrGLOpsRenderPass::onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
void GrGLOpsRenderPass::onDrawInstanced(int instanceCount, int baseInstance, int vertexCount,
|
||||||
int baseVertex) {
|
int baseVertex) {
|
||||||
SkASSERT(!fActiveVertexBuffer || fGpu->glCaps().drawArraysBaseVertexIsBroken());
|
|
||||||
if (fGpu->glCaps().drawArraysBaseVertexIsBroken()) {
|
|
||||||
// We weren't able to bind the vertex buffer during onBindBuffers because of a driver bug
|
|
||||||
// affecting glDrawArrays.
|
|
||||||
this->bindVertexBuffer(fActiveVertexBuffer.get(), 0);
|
|
||||||
}
|
|
||||||
int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
|
int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
|
||||||
for (int i = 0; i < instanceCount; i += maxInstances) {
|
for (int i = 0; i < instanceCount; i += maxInstances) {
|
||||||
int instanceCountForDraw = std::min(instanceCount - i, maxInstances);
|
this->setupGeometry(fActiveVertexBuffer.get(), 0, fActiveInstanceBuffer.get(),
|
||||||
int baseInstanceForDraw = baseInstance + i;
|
baseInstance + i);
|
||||||
if (fGpu->glCaps().baseVertexBaseInstanceSupport()) {
|
fGpu->drawArraysInstanced(fPrimitiveType, baseVertex, vertexCount,
|
||||||
SkASSERT(!fActiveInstanceBuffer);
|
std::min(instanceCount - i, maxInstances));
|
||||||
fGpu->drawArraysInstancedBaseInstance(fPrimitiveType, baseVertex, vertexCount,
|
|
||||||
instanceCountForDraw, baseInstanceForDraw);
|
|
||||||
} else {
|
|
||||||
this->bindInstanceBuffer(fActiveInstanceBuffer.get(), baseInstanceForDraw);
|
|
||||||
fGpu->drawArraysInstanced(fPrimitiveType, baseVertex, vertexCount,
|
|
||||||
instanceCountForDraw);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,21 +156,11 @@ void GrGLOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, in
|
|||||||
int baseInstance, int baseVertex) {
|
int baseInstance, int baseVertex) {
|
||||||
int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
|
int maxInstances = fGpu->glCaps().maxInstancesPerDrawWithoutCrashing(instanceCount);
|
||||||
for (int i = 0; i < instanceCount; i += maxInstances) {
|
for (int i = 0; i < instanceCount; i += maxInstances) {
|
||||||
int instanceCountForDraw = std::min(instanceCount - i, maxInstances);
|
this->setupGeometry(fActiveVertexBuffer.get(), baseVertex, fActiveInstanceBuffer.get(),
|
||||||
int baseInstanceForDraw = baseInstance + i;
|
baseInstance + i);
|
||||||
if (fGpu->glCaps().baseVertexBaseInstanceSupport()) {
|
fGpu->drawElementsInstanced(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT,
|
||||||
SkASSERT(!fActiveInstanceBuffer);
|
this->offsetForBaseIndex(baseIndex),
|
||||||
SkASSERT(!fActiveVertexBuffer);
|
std::min(instanceCount - i, maxInstances));
|
||||||
fGpu->drawElementsInstancedBaseVertexBaseInstance(
|
|
||||||
fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT,
|
|
||||||
this->offsetForBaseIndex(baseIndex), instanceCountForDraw, baseVertex,
|
|
||||||
baseInstanceForDraw);
|
|
||||||
} else {
|
|
||||||
this->bindInstanceBuffer(fActiveInstanceBuffer.get(), baseInstanceForDraw);
|
|
||||||
this->bindVertexBuffer(fActiveVertexBuffer.get(), baseVertex);
|
|
||||||
fGpu->drawElementsInstanced(fPrimitiveType, indexCount, GR_GL_UNSIGNED_SHORT,
|
|
||||||
this->offsetForBaseIndex(baseIndex), instanceCountForDraw);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
GrGpu* gpu() override { return fGpu; }
|
GrGpu* gpu() override { return fGpu; }
|
||||||
|
|
||||||
void bindInstanceBuffer(const GrBuffer*, int baseInstance);
|
void setupGeometry(const GrBuffer* vertexBuffer, int baseVertex, const GrBuffer* instanceBuffer,
|
||||||
void bindVertexBuffer(const GrBuffer*, int baseVertex);
|
int baseInstance);
|
||||||
|
|
||||||
const void* offsetForBaseIndex(int baseIndex) const {
|
const void* offsetForBaseIndex(int baseIndex) const {
|
||||||
if (!fIndexPointer) {
|
if (!fIndexPointer) {
|
||||||
|
@ -179,6 +179,9 @@
|
|||||||
"functions": [
|
"functions": [
|
||||||
"DrawArraysInstancedBaseInstance", "DrawElementsInstancedBaseVertexBaseInstance"
|
"DrawArraysInstancedBaseInstance", "DrawElementsInstancedBaseVertexBaseInstance"
|
||||||
],
|
],
|
||||||
|
"optional": [
|
||||||
|
"DrawArraysInstancedBaseInstance", "DrawElementsInstancedBaseVertexBaseInstance"
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // ES 3.0 has glDrawBuffers but not glDrawBuffer
|
{ // ES 3.0 has glDrawBuffers but not glDrawBuffer
|
||||||
|
Loading…
Reference in New Issue
Block a user