Skip to content

Commit 13eddf9

Browse files
authored
Add WEBGL_multi_draw_instanced_base_vertex_base_instance bindings (#12282)
Add WEBGL_multi_draw_instanced_base_vertex_base_instance function bindings to emscripten. Add a test to verify the new functions hook up properly. Also fix a small bug in webgl2_simple_enable_extensions.c mentioned in #12280 (Thanks @kainino0x for catching the issue)
1 parent 101bac9 commit 13eddf9

13 files changed

+290
-14
lines changed

src/library_html5_webgl.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ var LibraryHtml5WebGL = {
323323
#endif
324324
#if MAX_WEBGL_VERSION >= 2
325325
'_webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance',
326+
'_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance',
326327
#endif
327328
'_webgl_enable_WEBGL_multi_draw',
328329
#endif
@@ -349,6 +350,7 @@ var LibraryHtml5WebGL = {
349350

350351
#if MAX_WEBGL_VERSION >= 2
351352
if (extString == 'WEBGL_draw_instanced_base_vertex_base_instance') __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx);
353+
if (extString == 'WEBGL_multi_draw_instanced_base_vertex_base_instance') __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx);
352354
#endif
353355

354356
if (extString == 'WEBGL_multi_draw') __webgl_enable_WEBGL_multi_draw(GLctx);
@@ -360,7 +362,8 @@ var LibraryHtml5WebGL = {
360362
'OES_vertex_array_object',
361363
'WEBGL_draw_buffers',
362364
'WEBGL_multi_draw',
363-
'WEBGL_draw_instanced_base_vertex_base_instance'].indexOf(extString) >= 0) {
365+
'WEBGL_draw_instanced_base_vertex_base_instance',
366+
'WEBGL_multi_draw_instanced_base_vertex_base_instance'].indexOf(extString) >= 0) {
364367
console.error('When building with -s GL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=0, function emscripten_webgl_enable_extension() cannot be used to enable extension '
365368
+ extString + '! Use one of the functions emscripten_webgl_enable_*() to enable it!');
366369
}

src/library_webgl.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ var LibraryGL = {
148148
#endif
149149
#if MAX_WEBGL_VERSION >= 2
150150
'_webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance',
151+
'_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance',
151152
#endif
152153
'_webgl_enable_WEBGL_multi_draw',
153154
],
@@ -1081,6 +1082,7 @@ var LibraryGL = {
10811082
#if MAX_WEBGL_VERSION >= 2
10821083
// Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active)
10831084
__webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx);
1085+
__webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx);
10841086
#endif
10851087

10861088
GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");

src/library_webgl2.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,13 +976,18 @@ var LibraryWebGL2 = {
976976
_glDrawElements(mode, count, type, indices);
977977
},
978978

979+
glDrawArraysInstancedBaseInstanceWEBGL_sig: 'viiiii',
979980
glDrawArraysInstancedBaseInstanceWEBGL: function(mode, first, count, instanceCount, baseInstance) {
980981
GLctx.dibvbi['drawArraysInstancedBaseInstanceWEBGL'](mode, first, count, instanceCount, baseInstance);
981982
},
983+
glDrawArraysInstancedBaseInstance: 'glDrawArraysInstancedBaseInstanceWEBGL',
984+
glDrawArraysInstancedBaseInstanceANGLE: 'glDrawArraysInstancedBaseInstanceWEBGL',
982985

986+
glDrawElementsInstancedBaseVertexBaseInstanceWEBGL_sig: 'viiiiiii',
983987
glDrawElementsInstancedBaseVertexBaseInstanceWEBGL: function(mode, count, type, offset, instanceCount, baseVertex, baseinstance) {
984988
GLctx.dibvbi['drawElementsInstancedBaseVertexBaseInstanceWEBGL'](mode, count, type, offset, instanceCount, baseVertex, baseinstance);
985989
},
990+
glDrawElementsInstancedBaseVertexBaseInstanceANGLE: 'glDrawElementsInstancedBaseVertexBaseInstanceWEBGL',
986991

987992
_webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance: function(ctx) {
988993
// Closure is expected to be allowed to minify the '.dibvbi' property, so not accessing it quoted.
@@ -994,6 +999,51 @@ var LibraryWebGL2 = {
994999
return __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GL.contexts[ctx].GLctx);
9951000
},
9961001

1002+
glMultiDrawArraysInstancedBaseInstanceWEBGL__sig: 'viiiiii',
1003+
glMultiDrawArraysInstancedBaseInstanceWEBGL: function(mode, firsts, counts, instanceCounts, baseInstances, drawCount) {
1004+
GLctx.mdibvbi['multiDrawArraysInstancedBaseInstanceWEBGL'](
1005+
mode,
1006+
HEAP32,
1007+
firsts >> 2,
1008+
HEAP32,
1009+
counts >> 2,
1010+
HEAP32,
1011+
instanceCounts >> 2,
1012+
HEAPU32,
1013+
baseInstances >> 2,
1014+
drawCount);
1015+
},
1016+
glMultiDrawArraysInstancedBaseInstanceANGLE: 'glMultiDrawArraysInstancedBaseInstanceWEBGL',
1017+
1018+
glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL__sig: 'viiiiiiii',
1019+
glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL: function(mode, counts, type, offsets, instanceCounts, baseVertices, baseInstances, drawCount) {
1020+
GLctx.mdibvbi['multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL'](
1021+
mode,
1022+
HEAP32,
1023+
counts >> 2,
1024+
type,
1025+
HEAP32,
1026+
offsets >> 2,
1027+
HEAP32,
1028+
instanceCounts >> 2,
1029+
HEAP32,
1030+
baseVertices >> 2,
1031+
HEAPU32,
1032+
baseInstances >> 2,
1033+
drawCount);
1034+
},
1035+
glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE: 'glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL',
1036+
1037+
_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance: function(ctx) {
1038+
// Closure is expected to be allowed to minify the '.mdibvbi' property, so not accessing it quoted.
1039+
return !!(ctx.mdibvbi = ctx.getExtension('WEBGL_multi_draw_instanced_base_vertex_base_instance'));
1040+
},
1041+
1042+
emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance__deps: ['_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance'],
1043+
emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance: function(ctx) {
1044+
return __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GL.contexts[ctx].GLctx);
1045+
},
1046+
9971047
glVertexAttribI4i__sig: 'viiiii',
9981048
glVertexAttribI4ui__sig: 'viiiii',
9991049
glCopyBufferSubData__sig: 'viiiii',

src/settings.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@ var GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS = 1;
387387
// enable any WebGL extension. If false, to save code size,
388388
// emscripten_webgl_enable_extension() cannot be called to enable any of extensions
389389
// 'ANGLE_instanced_arrays', 'OES_vertex_array_object', 'WEBGL_draw_buffers',
390-
// 'WEBGL_multi_draw', or 'WEBGL_draw_instanced_base_vertex_base_instance',
390+
// 'WEBGL_multi_draw', 'WEBGL_draw_instanced_base_vertex_base_instance',
391+
// or 'WEBGL_multi_draw_instanced_base_vertex_base_instance',
391392
// but the dedicated functions emscripten_webgl_enable_*()
392393
// found in html5.h are used to enable each of those extensions.
393394
// This way code size is increased only for the extensions that are actually used.

system/include/emscripten/html5_webgl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ extern EM_BOOL emscripten_webgl_enable_WEBGL_draw_instanced_base_vertex_base_ins
7070

7171
extern EM_BOOL emscripten_webgl_enable_WEBGL_multi_draw(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context);
7272

73+
extern EM_BOOL emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context);
74+
7375
typedef EM_BOOL (*em_webgl_context_callback)(int eventType, const void *reserved, void *userData);
7476
extern EMSCRIPTEN_RESULT emscripten_set_webglcontextlost_callback_on_thread(const char *target, void *userData, EM_BOOL useCapture, em_webgl_context_callback callback, pthread_t targetThread);
7577
extern EMSCRIPTEN_RESULT emscripten_set_webglcontextrestored_callback_on_thread(const char *target, void *userData, EM_BOOL useCapture, em_webgl_context_callback callback, pthread_t targetThread);

system/include/webgl/webgl1_ext.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,12 @@ WEBGL_APICALL void GL_APIENTRY emscripten_webgl_getSupportedAstcProfiles(GLsizei
231231
// 40. https://www.khronos.org/registry/webgl/extensions/WEBGL_multi_draw/
232232
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawArraysWEBGL(GLenum mode, const GLint* firsts, const GLsizei* counts, GLsizei drawcount);
233233
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawArraysInstancedWEBGL(GLenum mode, const GLint* firsts, const GLsizei* counts, const GLsizei* instanceCounts, GLsizei drawcount);
234-
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawElementsWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLsizei* offsets, GLsizei drawcount);
235-
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawElementsInstancedWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLsizei* offsets, const GLsizei* instanceCounts, GLsizei drawcount);
234+
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawElementsWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLvoid* const* offsets, GLsizei drawcount);
235+
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawElementsInstancedWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLvoid* const* offsets, const GLsizei* instanceCounts, GLsizei drawcount);
236236
WEBGL_APICALL void GL_APIENTRY glMultiDrawArraysWEBGL(GLenum mode, const GLint* firsts, const GLsizei* counts, GLsizei drawcount);
237237
WEBGL_APICALL void GL_APIENTRY glMultiDrawArraysInstancedWEBGL(GLenum mode, const GLint* firsts, const GLsizei* counts, const GLsizei* instanceCounts, GLsizei drawcount);
238-
WEBGL_APICALL void GL_APIENTRY glMultiDrawElementsWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLsizei* offsets, GLsizei drawcount);
239-
WEBGL_APICALL void GL_APIENTRY glMultiDrawElementsInstancedWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLsizei* offsets, const GLsizei* instanceCounts, GLsizei drawcount);
238+
WEBGL_APICALL void GL_APIENTRY glMultiDrawElementsWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLvoid* const* offsets, GLsizei drawcount);
239+
WEBGL_APICALL void GL_APIENTRY glMultiDrawElementsInstancedWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLvoid* const* offsets, const GLsizei* instanceCounts, GLsizei drawcount);
240240

241241
// 44. https://www.khronos.org/registry/webgl/extensions/EXT_texture_norm16/
242242
#define GL_R16_EXT 0x822A

system/include/webgl/webgl2_ext.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ WEBGL_APICALL void GL_APIENTRY emscripten_webgl2_queryCounterEXT(GLuint query, G
1111

1212
// 46. https://www.khronos.org/registry/webgl/extensions/WEBGL_draw_instanced_base_vertex_base_instance/
1313
WEBGL_APICALL void GL_APIENTRY emscripten_glDrawArraysInstancedBaseInstanceWEBGL(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount, GLuint baseInstance);
14-
WEBGL_APICALL void GL_APIENTRY emscripten_glDrawElementsInstancedBaseVertexBaseInstanceWEBGL(GLenum mode, GLsizei count, GLenum type, const void *offset, GLsizei instanceCount, GLint baseVertex, GLuint baseinstance);
14+
WEBGL_APICALL void GL_APIENTRY emscripten_glDrawElementsInstancedBaseVertexBaseInstanceWEBGL(GLenum mode, GLsizei count, GLenum type, const void *offset, GLsizei instanceCount, GLint baseVertex, GLuint baseInstance);
1515
WEBGL_APICALL void GL_APIENTRY glDrawArraysInstancedBaseInstanceWEBGL(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount, GLuint baseInstance);
16-
WEBGL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceWEBGL(GLenum mode, GLsizei count, GLenum type, const void *offset, GLsizei instanceCount, GLint baseVertex, GLuint baseinstance);
16+
WEBGL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceWEBGL(GLenum mode, GLsizei count, GLenum type, const void *offset, GLsizei instanceCount, GLint baseVertex, GLuint baseInstance);
17+
18+
// 47. https://www.khronos.org/registry/webgl/extensions/WEBGL_multi_draw_instanced_base_vertex_base_instance/
19+
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawArraysInstancedBaseInstanceWEBGL(GLenum mode, const GLint* firsts, const GLsizei* counts, const GLsizei* instanceCounts, const GLuint* baseInstances, GLsizei drawCount);
20+
WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLvoid* const* offsets, const GLsizei* instanceCounts, const GLint* baseVertices, const GLuint* baseInstances, GLsizei drawCount);
21+
WEBGL_APICALL void GL_APIENTRY glMultiDrawArraysInstancedBaseInstanceWEBGL(GLenum mode, const GLint* firsts, const GLsizei* counts, const GLsizei* instanceCounts, const GLuint* baseInstances, GLsizei drawCount);
22+
WEBGL_APICALL void GL_APIENTRY glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(GLenum mode, const GLsizei* counts, GLenum type, const GLvoid* const* offsets, const GLsizei* instanceCounts, const GLint* baseVertices, const GLuint* baseinstances, GLsizei drawCount);

tests/test_browser.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4161,6 +4161,24 @@ def test_webgl_multi_draw(self):
41614161
self.btest('webgl_multi_draw_test.c', reference='webgl_multi_draw.png',
41624162
args=['-lGL', '-s', 'OFFSCREEN_FRAMEBUFFER=1', '-DMULTI_DRAW_ELEMENTS_INSTANCED=1', '-DEXPLICIT_SWAP=1'])
41634163

4164+
# Tests for base_vertex/base_instance extension
4165+
# For testing WebGL draft extensions like this, if using chrome as the browser,
4166+
# We might want to append the --enable-webgl-draft-extensions to the EMTEST_BROWSER env arg.
4167+
# If testing on Mac, you also need --use-cmd-decoder=passthrough to get this extension.
4168+
# Also there is a known bug with Mac Intel baseInstance which can fail producing the expected image result.
4169+
@requires_graphics_hardware
4170+
def test_webgl_draw_base_vertex_base_instance(self):
4171+
for multiDraw in [0, 1]:
4172+
for drawElements in [0, 1]:
4173+
self.btest('webgl_draw_base_vertex_base_instance_test.c', reference='webgl_draw_instanced_base_vertex_base_instance.png',
4174+
args=['-lGL',
4175+
'-s', 'MAX_WEBGL_VERSION=2',
4176+
'-s', 'OFFSCREEN_FRAMEBUFFER=1',
4177+
'-DMULTI_DRAW=' + str(multiDraw),
4178+
'-DDRAW_ELEMENTS=' + str(drawElements),
4179+
'-DEXPLICIT_SWAP=1',
4180+
'-DWEBGL_CONTEXT_VERSION=2'])
4181+
41644182
# Tests that -s OFFSCREEN_FRAMEBUFFER=1 rendering works.
41654183
@requires_graphics_hardware
41664184
def test_webgl_offscreen_framebuffer(self):

tests/webgl2_simple_enable_extensions.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ int main()
3434
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context;
3535
EMSCRIPTEN_RESULT res;
3636
EmscriptenWebGLContextAttributes attrs;
37-
attrs.majorVersion = WEBGL_CONTEXT_VERSION;
3837
emscripten_webgl_init_context_attributes(&attrs);
38+
attrs.majorVersion = WEBGL_CONTEXT_VERSION;
3939
context = emscripten_webgl_create_context("#canvas", &attrs);
4040
assert(context > 0); // Must have received a valid context.
4141
res = emscripten_webgl_make_context_current(context);
@@ -58,12 +58,16 @@ int main()
5858
if (hasext(exts, "WEBGL_multi_draw"))
5959
assert(emscripten_webgl_enable_WEBGL_multi_draw(context));
6060

61+
if (hasext(exts, "WEBGL_multi_draw_instanced_base_vertex_base_instance"))
62+
assert(emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(context));
63+
6164
#if WEBGL_SIMPLE_ENABLE_EXTENSION
6265
assert(hasext(exts, "ANGLE_instanced_arrays") == emscripten_webgl_enable_extension(context, "ANGLE_instanced_arrays"));
6366
assert(hasext(exts, "OES_vertex_array_object") == emscripten_webgl_enable_extension(context, "OES_vertex_array_object"));
6467
assert(hasext(exts, "WEBGL_draw_buffers") == emscripten_webgl_enable_extension(context, "WEBGL_draw_buffers"));
6568
assert(hasext(exts, "WEBGL_draw_instanced_base_vertex_base_instance") == emscripten_webgl_enable_extension(context, "WEBGL_draw_instanced_base_vertex_base_instance"));
6669
assert(hasext(exts, "WEBGL_multi_draw") == emscripten_webgl_enable_extension(context, "WEBGL_multi_draw"));
70+
assert(hasext(exts, "WEBGL_multi_draw_instanced_base_vertex_base_instance") == emscripten_webgl_enable_extension(context, "WEBGL_multi_draw_instanced_base_vertex_base_instance"));
6771
#endif
6872

6973
#ifdef REPORT_RESULT

0 commit comments

Comments
 (0)