aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar cdalton <cdalton@nvidia.com>2016-02-05 10:09:51 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-05 10:09:51 -0800
commit06604b95622359640a1c2028b885646deda28d52 (patch)
tree5ef3c819b4039da55a0a915921243fa9e1e5f662 /src/gpu/gl
parentaf8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2 (diff)
Add GL indirect drawing APIs
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLAssembleInterface.cpp66
-rw-r--r--src/gpu/gl/GrGLCaps.cpp17
-rw-r--r--src/gpu/gl/GrGLCaps.h14
-rw-r--r--src/gpu/gl/GrGLDefines.h2
-rw-r--r--src/gpu/gl/GrGLInterface.cpp16
5 files changed, 95 insertions, 20 deletions
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index 6b578f34fc..30eed62c5e 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -138,6 +138,19 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC(DrawBuffer);
GET_PROC(DrawBuffers);
GET_PROC(DrawElements);
+
+ if (glVer >= GR_GL_VER(3,1) || extensions.has("GL_ARB_draw_instanced") ||
+ extensions.has("GL_EXT_draw_instanced")) {
+ GET_PROC(DrawArraysInstanced);
+ GET_PROC(DrawElementsInstanced);
+ }
+
+ if (glVer >= GR_GL_VER(4,0)) {
+ // We don't use ARB_draw_indirect because it does not support a base instance.
+ GET_PROC(DrawArraysIndirect);
+ GET_PROC(DrawElementsIndirect);
+ }
+
GET_PROC(Enable);
GET_PROC(EnableVertexAttribArray);
GET_PROC(EndQuery);
@@ -228,6 +241,11 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC(VertexAttrib2fv);
GET_PROC(VertexAttrib3fv);
GET_PROC(VertexAttrib4fv);
+
+ if (glVer >= GR_GL_VER(3,2) || extensions.has("GL_ARB_instanced_arrays")) {
+ GET_PROC(VertexAttribDivisor);
+ }
+
GET_PROC(VertexAttribPointer);
GET_PROC(Viewport);
GET_PROC(BindFragDataLocationIndexed);
@@ -338,14 +356,10 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC(GetProgramResourceLocation);
}
- if (glVer >= GR_GL_VER(3,1) || extensions.has("GL_ARB_draw_instanced") ||
- extensions.has("GL_EXT_draw_instanced")) {
- GET_PROC(DrawArraysInstanced);
- GET_PROC(DrawElementsInstanced);
- }
-
- if (glVer >= GR_GL_VER(3,2) || extensions.has("GL_ARB_instanced_arrays")) {
- GET_PROC(VertexAttribDivisor);
+ if (glVer >= GR_GL_VER(4,3)) {
+ // We don't use ARB_multi_draw_indirect because it does not support GL_DRAW_INDIRECT_BUFFER.
+ GET_PROC(MultiDrawArraysIndirect);
+ GET_PROC(MultiDrawElementsIndirect);
}
if (extensions.has("GL_NV_bindless_texture")) {
@@ -564,6 +578,20 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
GET_PROC(Disable);
GET_PROC(DisableVertexAttribArray);
GET_PROC(DrawArrays);
+
+ if (version >= GR_GL_VER(3,0)) {
+ GET_PROC(DrawArraysInstanced);
+ GET_PROC(DrawElementsInstanced);
+ } else if (extensions.has("GL_EXT_draw_instanced")) {
+ GET_PROC_SUFFIX(DrawArraysInstanced, EXT);
+ GET_PROC_SUFFIX(DrawElementsInstanced, EXT);
+ }
+
+ if (version >= GR_GL_VER(3,1)) {
+ GET_PROC(DrawArraysIndirect);
+ GET_PROC(DrawElementsIndirect);
+ }
+
GET_PROC(DrawElements);
GET_PROC(Enable);
GET_PROC(EnableVertexAttribArray);
@@ -643,6 +671,13 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
GET_PROC(VertexAttrib2fv);
GET_PROC(VertexAttrib3fv);
GET_PROC(VertexAttrib4fv);
+
+ if (version >= GR_GL_VER(3,0)) {
+ GET_PROC(VertexAttribDivisor);
+ } else if (extensions.has("GL_EXT_instanced_arrays")) {
+ GET_PROC_SUFFIX(VertexAttribDivisor, EXT);
+ }
+
GET_PROC(VertexAttribPointer);
GET_PROC(Viewport);
GET_PROC(BindFramebuffer);
@@ -779,18 +814,9 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
GET_PROC_SUFFIX(CoverageModulation, CHROMIUM);
}
- if (version >= GR_GL_VER(3,0)) {
- GET_PROC(DrawArraysInstanced);
- GET_PROC(DrawElementsInstanced);
- } else if (extensions.has("GL_EXT_draw_instanced")) {
- GET_PROC_SUFFIX(DrawArraysInstanced, EXT);
- GET_PROC_SUFFIX(DrawElementsInstanced, EXT);
- }
-
- if (version >= GR_GL_VER(3,0)) {
- GET_PROC(VertexAttribDivisor);
- } else if (extensions.has("GL_EXT_instanced_arrays")) {
- GET_PROC_SUFFIX(VertexAttribDivisor, EXT);
+ if (extensions.has("GL_EXT_multi_draw_indirect")) {
+ GET_PROC_SUFFIX(MultiDrawArraysIndirect, EXT);
+ GET_PROC_SUFFIX(MultiDrawElementsIndirect, EXT);
}
if (extensions.has("GL_NV_bindless_texture")) {
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 1a87274b45..a913fbeca2 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -41,6 +41,9 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
fDebugSupport = false;
fES2CompatibilitySupport = false;
fMultisampleDisableSupport = false;
+ fDrawIndirectSupport = false;
+ fMultiDrawIndirectSupport = false;
+ fBaseInstanceSupport = false;
fUseNonVBOVertexAndIndexDynamicData = false;
fIsCoreProfile = false;
fBindFragDataLocationSupport = false;
@@ -482,6 +485,17 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
}
+ if (kGL_GrGLStandard == standard) {
+ // We don't use ARB_draw_indirect because it does not support a base instance.
+ // We don't use ARB_multi_draw_indirect because it does not support GL_DRAW_INDIRECT_BUFFER.
+ fDrawIndirectSupport =
+ fMultiDrawIndirectSupport = fBaseInstanceSupport = version >= GR_GL_VER(4,3);
+ } else {
+ fDrawIndirectSupport = version >= GR_GL_VER(3,1);
+ fMultiDrawIndirectSupport = ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
+ fBaseInstanceSupport = ctxInfo.hasExtension("GL_EXT_base_instance");
+ }
+
this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
if (contextOptions.fUseShaderSwizzling) {
@@ -936,6 +950,9 @@ SkString GrGLCaps::dump() const {
r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
+ r.appendf("Draw indirect support: %s\n", (fDrawIndirectSupport ? "YES" : "NO"));
+ r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO"));
+ r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO"));
r.appendf("Use non-VBO for dynamic data: %s\n",
(fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 044ecce814..abfcc285b7 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -283,6 +283,17 @@ public:
/// Can we call glDisable(GL_MULTISAMPLE)?
bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
+ /// Is there support for glDraw*Indirect? Note that the baseInstance fields of indirect draw
+ /// commands cannot be used unless we have base instance support.
+ bool drawIndirectSupport() const { return fDrawIndirectSupport; }
+
+ /// Is there support for glMultiDraw*Indirect? Note that the baseInstance fields of indirect
+ /// draw commands cannot be used unless we have base instance support.
+ bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; }
+
+ /// Are the baseInstance fields supported in indirect draw commands?
+ bool baseInstanceSupport() const { return fBaseInstanceSupport; }
+
/// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
@@ -378,6 +389,9 @@ private:
bool fDebugSupport : 1;
bool fES2CompatibilitySupport : 1;
bool fMultisampleDisableSupport : 1;
+ bool fDrawIndirectSupport : 1;
+ bool fMultiDrawIndirectSupport : 1;
+ bool fBaseInstanceSupport : 1;
bool fUseNonVBOVertexAndIndexDynamicData : 1;
bool fIsCoreProfile : 1;
bool fBindFragDataLocationSupport : 1;
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index a759413c5a..9be769fb85 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -108,8 +108,10 @@
/* Buffer Objects */
#define GR_GL_ARRAY_BUFFER 0x8892
#define GR_GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GR_GL_DRAW_INDIRECT_BUFFER 0x8F3F
#define GR_GL_ARRAY_BUFFER_BINDING 0x8894
#define GR_GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GR_GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
#define GR_GL_PIXEL_PACK_BUFFER 0x88EB
#define GR_GL_PIXEL_UNPACK_BUFFER 0x88EC
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index b8d7db6b2e..925f081b34 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -579,6 +579,22 @@ bool GrGLInterface::validate() const {
}
}
+ if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) ||
+ (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
+ if (NULL == fFunctions.fDrawArraysIndirect ||
+ NULL == fFunctions.fDrawElementsIndirect) {
+ RETURN_FALSE_INTERFACE
+ }
+ }
+
+ if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) ||
+ (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_multi_draw_indirect"))) {
+ if (NULL == fFunctions.fMultiDrawArraysIndirect ||
+ NULL == fFunctions.fMultiDrawElementsIndirect) {
+ RETURN_FALSE_INTERFACE
+ }
+ }
+
if (fExtensions.has("GL_NV_bindless_texture")) {
if (nullptr == fFunctions.fGetTextureHandle ||
nullptr == fFunctions.fGetTextureSamplerHandle ||