Skip to content

Bring some GL ES 3.0 functions to GetProcAddress #5951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 19, 2018

Conversation

kvark
Copy link
Contributor

@kvark kvark commented Dec 19, 2017

No description provided.

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

  1. Looks like there's a conflict that needs resolving.
  2. This looks right to me, but I don't remember if there isn't another necessary step here. We can verify that with adding a test, which we should do anyhow. We don't need to test them all, but at least one GL ES 3 method would be good. Can grep for related tests in tests/, might be easy to add to an existing GL ES 3 test, or an existing GetProcAddress one.

if (!strcmp(name, "glGetActiveUniformBlockiv")) return emscripten_glGetActiveUniformBlockiv;
if (!strcmp(name, "glGetActiveUniformBlockName")) return emscripten_glGetActiveUniformBlockName;
if (!strcmp(name, "glUniformBlockBinding")) return emscripten_glUniformBlockBinding;
// GLES 3.0 functions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume all the new lines are from here, and above this it was just removing the else? (which I agree is a nice change)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, exactly

@kvark
Copy link
Contributor Author

kvark commented Dec 19, 2017

Uh oh, noticed the following comment explaining the issue (in docs/optimizing/Optimizing-WebGL.rst):

Avoid using any of the *glGetProcAddress() API functions. Emscripten provides static linking to all of the GL API functions, even for all WebGL extensions. The *glGetProcAddress() API is only provided for compatibility to ease porting of existing code, but accessing WebGL via calling dynamically obtained function pointers is noticeably slower than direct function calls, due to extra function pointer security validation that dynamic dispatching has to do in asm.js/WebAssembly. Since Emscripten provides all of the GL entry points statically linked in, it is recommended to take advantage of this for best performance.

@kvark
Copy link
Contributor Author

kvark commented Dec 19, 2017

@kripken this behavior seems to contradict EGL specification:

eglGetProcAddress may be queried for all EGL and client API functions supported by the implementation (whether those functions are extensions or not, and whether they are supported by the current client API context or not).
For functions that are queryable with eglGetProcAddress, implementations may choose to also export those functions statically from the object libraries implementing those functions. However, portable clients cannot rely on this behavior.

:(

@kripken
Copy link
Member

kripken commented Dec 20, 2017

I don't understand, what's the contradiction?

@kvark
Copy link
Contributor Author

kvark commented Dec 20, 2017

@kripken if Emscripten is implementing context creation via EGL, it has to obey the EGL specification, which states that GetProcAddress should always give you the function pointers. In this case, the documentation paragraph I quoted is incorrect. If it is correct though, then my PR is not valid. So this is waiting for your confirmation on which side is right (EGL spec + my PR, or the current Emscripten docs).

Also, I found a largely similar (but better) work - #4829

@kripken
Copy link
Member

kripken commented Dec 20, 2017

@juj would know best what to do here. Also, the status of that other PR.

But I don't see a problem in the documentation paragraph - it just says the function pointers are slower, it doesn't say if they will or won't be supported? They should be supported, I think. Maybe we can improve the text there, but I'm not sure how?

@juj
Copy link
Collaborator

juj commented Dec 21, 2017

This PR looks good to me (will need rebasing to resolve merge conflict). We want to support both forms - querying via function pointers and static linking, and we encourage everyone to use static linking, because we have that opportunity. Static linking is faster in practice - invoking via dynamic pointers does show up in profiles as a few % unnecessary overhead, plus also *GetProcAddress() functions have a horrible dead code elimination issue: referencing a *GetProcAddress() function will cause all GL/EGL functions to be pulled in to the build since there is no machinery that would know which one of the functions will be queried at runtime, so all functions will need to be present. This is really bad for minimizing code size, so it's best for people not to rely on *GetProcAddress() to get the best code size.

Still, we do want to support *GetProcAddress() properly for good form and porting experience, so it is made available if necessary.

@kvark
Copy link
Contributor Author

kvark commented Dec 22, 2017

@juj thanks for clarifying. I rebased the PR now.
It's still lacking testing and full coverage of exported functions.

bors bot added a commit to gfx-rs/gfx that referenced this pull request Dec 29, 2017
1706: More Emscripten support r=msiglreith a=kvark

## Intro
This is a big follow-up to #1681 and #1685

After being blocked by rust-lang/rust#47023, I got stuff building in release, so continued porting the examples over. Note: there is a lot of shader code duplication, we need some (simple) templating/preprocessor there.

## Environment

OS: Linux + Firefox Nightly,

Emscripten: built from source with the following changes:
  - integrated emscripten-core/emscripten#5951
  - `USE_WEBGL2=1` is forcefully set in "settings.js"

## Status

🎉 Work 🎉 : triangle, cube, flowmap, blend, gamma, terrain, ubo_tilemap

Almost works: mipmap - see #1704

Not tested: deferred (too many shaders!), performance

Blocked by the lack of buffer mapping: instancing

Blocked by the lack of geometry/tessellation shader support: particle, render_target, terrain_tessellated

Fail to run: shadow, skybox - see #1705

## Proof
![gfx-emscripten-ubo_tilemap](https://user-images.githubusercontent.com/107301/34429974-5e6678d8-ec2d-11e7-91c7-2e4f3746e416.png)
kripken added a commit that referenced this pull request Jun 18, 2018
@kripken
Copy link
Member

kripken commented Jun 18, 2018

Hi @kvark - sorry this PR got forgotten!

I did some work to apply this over current incoming, here are two commits that should do that, first does the else removal, second adds your new functions here:

0dad387

953c3bf

I think you can start with current incoming, cherry-pick those two commits, and add yourself to AUTHORS, and then we can merge this.

kvark pushed a commit to kvark/emscripten that referenced this pull request Jun 19, 2018
@kvark
Copy link
Contributor Author

kvark commented Jun 19, 2018

@kripken please take another look

@kripken
Copy link
Member

kripken commented Jun 19, 2018

Great, thanks @kvark !

@kripken kripken merged commit d657775 into emscripten-core:incoming Jun 19, 2018
@kvark kvark deleted the gles3 branch June 19, 2018 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants