typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsInstancedProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid *indices, GrGLsizei primcount);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsIndirectProc)(GrGLenum mode, GrGLenum type, const GrGLvoid* indirect);
+typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawRangeElementsProc)(GrGLenum mode, GrGLuint start, GrGLuint end, GrGLsizei count, GrGLenum type, const GrGLvoid* indices);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableProc)(GrGLenum cap);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableVertexAttribArrayProc)(GrGLuint index);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEndQueryProc)(GrGLenum target);
GrGLFunction<GrGLDrawElementsProc> fDrawElements;
GrGLFunction<GrGLDrawElementsIndirectProc> fDrawElementsIndirect;
GrGLFunction<GrGLDrawElementsInstancedProc> fDrawElementsInstanced;
+ GrGLFunction<GrGLDrawRangeElementsProc> fDrawRangeElements;
GrGLFunction<GrGLEnableProc> fEnable;
GrGLFunction<GrGLEnableVertexAttribArrayProc> fEnableVertexAttribArray;
GrGLFunction<GrGLEndQueryProc> fEndQuery;
GET_PROC(DrawArraysIndirect);
GET_PROC(DrawElementsIndirect);
}
-
+ if (glVer >= GR_GL_VER(2,0)) {
+ GET_PROC(DrawRangeElements);
+ }
GET_PROC(Enable);
GET_PROC(EnableVertexAttribArray);
GET_PROC(EndQuery);
}
GET_PROC(DrawElements);
+ if (version >= GR_GL_VER(3,0)) {
+ GET_PROC(DrawRangeElements);
+ }
GET_PROC(Enable);
GET_PROC(EnableVertexAttribArray);
GET_PROC(Finish);
(fDrawIndirectSupport &&
!fBaseInstanceSupport && // The ARB extension has no base inst.
ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
+ fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
} else {
fDrawIndirectSupport = version >= GR_GL_VER(3,1);
fMultiDrawIndirectSupport = fDrawIndirectSupport &&
ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
fBaseInstanceSupport = fDrawIndirectSupport &&
ctxInfo.hasExtension("GL_EXT_base_instance");
+ fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
}
this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
/// draw commands cannot be used unless we have base instance support.
bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; }
+ /// Is there support for glDrawRangeElements?
+ bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; }
+
/// Are the baseInstance fields supported in indirect draw commands?
bool baseInstanceSupport() const { return fBaseInstanceSupport; }
bool fES2CompatibilitySupport : 1;
bool fDrawInstancedSupport : 1;
bool fDrawIndirectSupport : 1;
+ bool fDrawRangeElementsSupport : 1;
bool fMultiDrawIndirectSupport : 1;
bool fBaseInstanceSupport : 1;
bool fUseNonVBOVertexAndIndexDynamicData : 1;
const GrMesh& mesh = meshes[i];
GrMesh::Iterator iter;
- const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
+ const GrNonInstancedMesh* nonInstMesh = iter.init(mesh);
do {
size_t indexOffsetInBytes = 0;
- this->setupGeometry(primProc, *nonIdxMesh, &indexOffsetInBytes);
- if (nonIdxMesh->isIndexed()) {
+ this->setupGeometry(primProc, *nonInstMesh, &indexOffsetInBytes);
+ if (nonInstMesh->isIndexed()) {
GrGLvoid* indices =
- reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) *
- nonIdxMesh->startIndex());
+ reinterpret_cast<GrGLvoid*>(indexOffsetInBytes +
+ sizeof(uint16_t) * nonInstMesh->startIndex());
// info.startVertex() was accounted for by setupGeometry.
- GL_CALL(DrawElements(gPrimitiveType2GLMode[nonIdxMesh->primitiveType()],
- nonIdxMesh->indexCount(),
- GR_GL_UNSIGNED_SHORT,
- indices));
+ if (this->glCaps().drawRangeElementsSupport()) {
+ // We assume here that the batch that generated the mesh used the full
+ // 0..vertexCount()-1 range.
+ int start = 0;
+ int end = nonInstMesh->vertexCount() - 1;
+ GL_CALL(DrawRangeElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
+ start, end,
+ nonInstMesh->indexCount(),
+ GR_GL_UNSIGNED_SHORT,
+ indices));
+ } else {
+ GL_CALL(DrawElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
+ nonInstMesh->indexCount(),
+ GR_GL_UNSIGNED_SHORT,
+ indices));
+ }
} else {
// Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account
// for startVertex in the DrawElements case. So we always rely on setupGeometry to
// have accounted for startVertex.
- GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonIdxMesh->primitiveType()], 0,
- nonIdxMesh->vertexCount()));
+ GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonInstMesh->primitiveType()], 0,
+ nonInstMesh->vertexCount()));
}
fStats.incNumDraws();
- } while ((nonIdxMesh = iter.next()));
+ } while ((nonInstMesh = iter.next()));
}
if (fHWPLSEnabled && plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState) {
}
}
+ if (kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(2,0)) {
+ if (nullptr == fFunctions.fDrawRangeElements) {
+ RETURN_FALSE_INTERFACE;
+ }
+ } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) {
+ if (nullptr == fFunctions.fDrawRangeElements) {
+ RETURN_FALSE_INTERFACE;
+ }
+ }
+
return true;
}
fFunctions.fDrawElements = bind_to_member(this, &GrGLTestInterface::drawElements);
fFunctions.fDrawElementsInstanced = bind_to_member(this, &GrGLTestInterface::drawElementsInstanced);
fFunctions.fDrawElementsIndirect = bind_to_member(this, &GrGLTestInterface::drawElementsIndirect);
+ fFunctions.fDrawRangeElements = bind_to_member(this, &GrGLTestInterface::drawRangeElements);
fFunctions.fEnable = bind_to_member(this, &GrGLTestInterface::enable);
fFunctions.fEnableVertexAttribArray = bind_to_member(this, &GrGLTestInterface::enableVertexAttribArray);
fFunctions.fEndQuery = bind_to_member(this, &GrGLTestInterface::endQuery);
virtual GrGLvoid drawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
virtual GrGLvoid drawElementsInstanced(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid *indices, GrGLsizei primcount) {}
virtual GrGLvoid drawElementsIndirect(GrGLenum mode, GrGLenum type, const GrGLvoid* indirect) {}
+ virtual GrGLvoid drawRangeElements(GrGLenum mode, GrGLuint start, GrGLuint end, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
virtual GrGLvoid enable(GrGLenum cap) {}
virtual GrGLvoid enableVertexAttribArray(GrGLuint index) {}
virtual GrGLvoid endQuery(GrGLenum target) {}