kakashidinho / metalangle

MetalANGLE: OpenGL ES to Metal API translation layer
Other
462 stars 65 forks source link

Undefined symbols for OES suffixed #8

Open misl6 opened 4 years ago

misl6 commented 4 years ago

First of all, thank you very much for this project, could save a lot of opensource softwares and frameworks in the near future from Apple's OpenGLES-geddon!

I've started to migrate a Open Source framework for iOS from OpenGLES to MetalANGLE, and at this time is gone quite smooth.

Unfortunately, some symbols seems to be undefined for me, starting from the -OES ones:

_glBlendEquationOES _glBlendEquationSeparateOES _glBlendFuncSeparateOES

I've seen that the -OES functions seems to be managed by the GL_GLEXT_PROTOTYPES.

misl6 commented 4 years ago

Managed by the same directive, also glLabelObjectEXT seems to be undefined for me

kakashidinho commented 4 years ago

Hi, glBlendEquationOES is an OpenGLES 1 extension. Currently angle doesn't support this GLES1 extension. Though glBlendEquation is available as core function for GLES2 and above. Is your project using GLES1? Could you try to migrate it to use GLES2 and above? I could try to add glBlendEquationOES extension to GLES1 backend, however, GLES1 is not main focus at this moment.

For glLabelObjectEXT, this is just a debug extension, I can easily implement it if needed. But for now, you can just add #define glLabelObjectEXT(...) // empty function, it won't affect any existing GL functionalities.

kakashidinho commented 4 years ago

Alternatively though I haven’t tried myself. Could you try to define those OES functions to be non OES equivalents. For example, #define glBlendEquationOES glBlendEquation. Let try to see whether angle front end allows this or not. Even though glBlendEquation is already available. Officially it is not GLES1 core function, hence the OES extension was added by GL committee. But angle might already allows this function to be called by GLES1 context.

misl6 commented 4 years ago

My project relies on sdl2 for some parts, and sdl2 it's still using these symbols :cry:

Probably a patch that disables the usage of these symbols on iOS should work. I will keep you updated. I also noticed some other symbols (_KEAGL- suffixed (constants)) that seems to are undefined too.

misl6 commented 4 years ago

I managed to get the OpenGLES 1 extensions out by disabling a (RN) unneeded renderer.

Now, seems that the remaining undefined symbols are the following (all related to the SDL2 part):

Screenshot 2020-04-18 at 16 53 11

Let me know if you prefere to have separate issues for these.

kakashidinho commented 4 years ago

These Apple's EAGL symbols have been replaced by MGL symbols provided by MetalANGLE's MGLKit. I don't plan to complete replace Apple's classes like that. I just simple provide MGLKit classes having similar roles but with different names. You might have to do a bit of modifications in order to migrate to MetalANGLE. I will provide a more detailed tutorial on how to replace Apple's EAGL & GLKit classes with MetalANGLE's MGLKit classes soon. For now, you can see the example app on how to setup MGLContext (equivalent to Apple's EAGLContext) here

glResolveMultisampleFramebufferAPPLE is not supported, though you might want to use equivalent function glBlitFramebuffer or use automatic resolve with glFramebufferTexture2DMultisampleEXT.

Do you have any sample projects using sdl2 currently? So that I can try to demonstrate the porting code myself.

misl6 commented 4 years ago

Understood. I think that I have to implement these changes on the sdl2 side.

I just wrote a WIP PR for the porting I'm on right now (https://github.com/kivy/kivy-ios/pull/448). It probably needs no changes or nothing special on our framework side.

All the edits will probably be on the sdl2 side.

kakashidinho commented 4 years ago

FYI, I have added some guides for porting Apple's EAGL to MGL here. Hope it's useful.

kakashidinho commented 4 years ago

Alternatively, you can switch to use SDL's EGL backend instead of iOS's native EAGL backend. angle implements EGL 1.5 API, so it can work with SDL's EGL backend out of the box, you don't need to modify SDL in this case, or there might some little changes (such as the franework path if I presume correctly).

In this case, just needs to pass an iOS's CALayer to SDL_EGL_CreateSurface function.

misl6 commented 4 years ago

The guide you added It's very helpful!

My first thought was to edit https://github.com/spurious/SDL-mirror/blob/master/src/video/uikit/SDL_uikitopengles.m and https://github.com/spurious/SDL-mirror/blob/master/src/video/uikit/SDL_uikitopenglview.m in order to get the same thing running w/ MGLKit without making any change on our side.

I managed to get something working last weekend, but the view is reporting a size of 0x0 :disappointed:

I will continue to dig into this during the next weekend.

In this case, just needs to pass an iOS's CALayer to SDL_EGL_CreateSurface function.

Basically, you're suggesting to create a MetalView via UIKit_Metal_CreateView and then use SDL_EGL_CreateSurface on it's layer?

kakashidinho commented 4 years ago

I meant you can pass CALayer created by anything, not just UIKit_Metal_CreateView. It may be a layer of your own view. But the layer must be CALayer or it subclass. Anw, if you want to continue the MGLKit route, may I see your tentative changes? so I could try to see if I could give some suggestions. It's also an opportunity for me to see if there is any bug. After looking at SDL_uikitopenglview.m I think you can omit a lot of code if you use MetalANGLE's MGLLayer. No need for creating separated msaa framebuffer and useglBlitFramebuffer or anything similar to resolve it, because everything will be done automatically internally by angle's default framebuffer.

I can also try to write some SDL_uikitopenglview.m modifications as examples later when I have more free time.

misl6 commented 4 years ago

I surely left something bad while doing some testing, but I just pushed my last weekend work on a separate branch: https://github.com/misl6/SDL-mirror/tree/metalangle Seems that is really near to work, but as said before, reports a 0x0 sized window on UIKit_GL_GetDrawableSize

TheSpydog commented 4 years ago

@misl6 Do you have an active GL context when you call GL_GetDrawableSize? SDL2 always reports 0x0 on UIKit if there's no context.

kakashidinho commented 4 years ago

@misl6 I think I know why it returned 0x0. It was because MGLLayer.drawableSize return 0x0 if you call it too early, currently it would only return actual size after the first call of [MGLContext setCurrentContext:context forLayer:mgllayer].

In your case the UIKit_GL_GetDrawableSize() will return backingWidthxbackingHeight pair which you obtained in SDL_uikitopenglview:141.

I have a fix 88bcc5ec for this early zero size problem. I suggest you change the UIKit_GL_GetDrawableSize() function to update the actual backingWidth=MGLLayer.drawableSize.width every time the call is invoked. Since technically, the size of the view is not a fixed value, user can resize it on macOS or rotate it on iOS (thus swapping the width & height value).

Thanks for the actual use case, it is very helpful for me. It will be mentioned in the doc.

misl6 commented 4 years ago

I had some time while waiting for a build and I tried the latest changes you made yesterday. Now the MGLLayer.drawableSize it's updating!

Unfortunately seems that I still have some issues:

P.S: I did some cleanup + edits on my SDL/metalangle branch and pushed it right now.

Will continue to work on it when I have some free time, meanwhile I hope it's something helpful.

kakashidinho commented 4 years ago

@misl6, I downloaded your repo and tried to test it. Did you encounter the errors when running the SDL's testgles sample app? If so, this sample app is using GLES1 and AFIK the GLES1 is not actively maintained by ANGLE project, since Google's main attentions are GLES2+ so that they can be used by WebGL1 and WebGL2. I checked the ANGLE's GLES1 implementation and at current state, it is quite buggy/incomplete/not fully conformant.

I have made some modifications in SDL's testgles sample code to use GLES2 instead of GLES1, you might want to take a look. However, do you think it is an issue for your project if GLES1 is not fully supported by MetalANGLE/ANGLE?

Anw, I tested SDL's testdraw2 & testsprite2 sample apps and they are running fine without any modifications (aside from changing the linking framework). I detected some bugs in MetalANGLE's multisample settings after running the SDL tests. If you want to try again, don't enable msaa for now.

Imgur

kakashidinho commented 4 years ago

OK, I know why there is unusual multisample surface creation pattern in the SDL's sample app. Basically inside UIKit_GL_MakeCurrent you didn't call [MGLContext setCurrentContext: forLayer:] to make the layer become active layer for default framebuffer. You only called [MGLContext setCurrentContext:] without any layer. By right, the MetalANGLE code shouldn't crash in this case, but making context current without any layer before a draw call is not recommended. Context without active layer can be used to create OpenGL resources but for drawing you need an active layer.

I have made a UIKit_GL_MakeCurrent's change in the SDL fork as an example, you might take a look.

Here is SDL's testgles screenshot after converting to GLES2: Imgur

misl6 commented 4 years ago

I'm testing it over our framework (https://github.com/kivy/kivy).

The sprites2 example is also working for me, but the fireworks one seems to fail.

On our side, I'm pretty sure, that We're OpenGLES2 compliant, but I think that the code definitely needs some checks.

We're surely covering some special case only for Apple, and probably some code needs to be migrated.

I will keep you posted, is on my schedule for the weekend.

misl6 commented 4 years ago

I'm back! Just got one of our demo apps working. :tada:

Unfortunately, I had to disable mipmapping, cause, when calling glTexSubImage with a glGenerateMipmap image, that error was thrown:

Execution of the command buffer was aborted due to an error during execution.."
kakashidinho commented 4 years ago

Great to know. Is it possible to upload your demo app at some point so that I may take a look at what has gone wrong.

misl6 commented 4 years ago

I'm using the "Touchtracer" example in our framework demo folder (https://github.com/kivy/kivy).

Unfortunately there are a lot of things to build via the custom toolchain, but feel free to ping me on kivy Discord server in the #dev section, if you prefere.

kakashidinho commented 4 years ago

I run the touchtracer demo app. Didn't get any crash. I don't think glGenerateMipmap is disabled in my build. Which device you used to test?

kakashidinho commented 4 years ago

Wow, thanks to you, I noticed that MetalANGLE mipmap generation shader doesn't work well on older iPhones. It ran fine on my iPhone XR, but when I ran it on iPhone 6, "Execution of the command buffer was aborted due to an error during execution.." happened. If you didn't bring this up, I would haven't noticed this. Will fix it.

kakashidinho commented 4 years ago

"Execution of the command buffer was aborted due to an error during execution.." fixed in latest master version.

misl6 commented 4 years ago

Both devices I tested on have the A10 Fusion chip, so it confirms that the fix was needed for iOS GPU family 3 and below as I can see from your code.

I'm going to do a full rebuild + rebasing of the PR in order to test it, but you got it certainly fixed. Thank you.