SDL OpenGL ES2 autobatching patch


#1

I do not know how to contribute, so I publish my patch here.
I wrote a simple autobatching for the OpenGL ES2 backend.
Perhaps this is not optimal, and someone can optimize it.
But now I can use a particle system with many calls to SDL_RenderCopyEx.

sdl_opengles2_batch.patch (43.9 KB)


#2

It’s funny you should mention this, because I’m working on something similar:

The demo there is in the GLES2 renderer, but I’m in the process of reworking this for the higher level so all the rendering backends can do batching.


#3

:laughing:


This is my old variant. New patch is compatible with SDL 2.0.8.
I look forward to your changes!
And it would be great to provide API for customizing shaders and working with vertices. For example, my dream, Spine on the SDL.

If you want, you can use my code without any references or restrictions. In my implementation, you can determine the maximum number of vertices at compile time.


#4

This is exciting! Will the batching work when rendering to a target texture as well as when using the default render target?


#5

I’ve found an error in my code.
When I flip by vertical I miss vertex_index_start, so correct code is
tmp = vertices[vertex_index_start + 0].pos[1];


#6

Mine is sitting in a branch that will merge after 2.0.9 is complete:

https://hg.libsdl.org/SDL/shortlog/SDL-ryan-batching-renderer


#7

Maybe it is better to move a color from the uniform to the vertex attribute?
In my games I use a particle system, and there are many particles with different colors, therefore, to avoid problems with batching, I keep the color at the vertex attribute.


#8

I noticed a bunch of float methods appeared, for non pixel aligned coordinates I presume? This is a major thing, why are bards not singing and dancing about this?

Also, I am being a bit thick. Is the only way to use your branch to compile from source? Do you have a DLL? I’m not seeing the float methods in the includes in the 2.0.9 release.


#9

lol! Please test it if you get a chance; lots of people have asked for this, but I need test cases!

It’s not in 2.0.9 (but it has now been merged, so it’s not on a branch any more). If you build the latest from revision control from source, you’ll have it.

–ryan.


#10

How about move color to the vertex attribute for opengles2?


#11

I’m all over this - it’s very exciting! (maybe not the best choice of phrase).

Just built with the VisualC project (ah yes, smaller DLL as you said before - Steam must have compiled with VS).

Initial observation: I’m drawing 10000 coloured filled boxes (SDL_SetRenderDrawColor & SDL_RenderFillRect). The new build is twice as slow as the official build’s DLL? I notice SDL_RenderDrawRect calls SDL_RenderDrawRectF, but it shouldn’t make it twice as slow? And resizing a window causes all drawing to stop working. Perhaps I’m building it wrong or it’s broken in a big way? I’m happy to start submitting bugs, but just making sure this is SDL’s side and not a VisualC & me specific thing?

Edit: the halting of any rendering after window resize only happens with the Direct3D renderer. A bug introduced after 2.0.9 release.


#12

Okay, quite concerned at the results on Windows. Just doing simple filled rects in openGL renderer in my test and without batching I’m getting 1000fps, with batching I’m getting 200fps - ouch. Even direct3d renderer gives me 800fps without, and 500fps with.

Am I missing something? Can someone supply a new DLL built with cmake for me? (so I know it’s not VisualC’s build that’s choking this). Anyone else joining me on the this batching quest?


#13

Did you set the hint ?
SDL_SetHint(SDL_HINT_RENDER_BATCHING, “1”);


#14

No, I didn’t know about this, sorry. That works, thank-you!

But it’s no faster than 2.0.9 release, so was it batching in the background anyway before? With this hint it’s the same speed it was before. post 2.0.9 it’s much slower (especially opengles2) unless you turn this hint on. I can’t see an improvement.

[edit] Unless this is specific to mobile?


#15

Okay wait, just re-tested everything. I’m getting 1600fps on 2.0.9, and 2200fps with Ryan’s new batching, so it does appear to work well (opengles2). On opengl I’m getting 2700 before, and 2950 now.


#16

Ok Great !

So, I think, if you don’t activate the hint, it works as a compatibility mode not to break existing games. It draws immediately when requested.
When you activate it, every commands get grouped and it draws in one shot.

see: https://hg.libsdl.org/SDL/diff/dc9108cd4340/include/SDL_hints.h

On mobile / Android, Dashboard “Android Vitals”, there is a metric named “Slow rendering” which will maybe better with this feature, let me know if you have the change to see that.


#17

Is there anything special we need to do to activate between-pixel alignment? I’m using the float drawing methods but rects are still aligning to pixels.

Edit: Scratch that(!) I had my AA NVIDIA settings all turned off :man_facepalming:. It works great now! It’s beautiful!


#19

The only way I could get things to draw between pixels was to set NVIDIA’s antialiasing mode to override applications. Is this because SDL_HINT_RENDER_SCALE_QUALITY anisotropic setting is not implemented? Currently textures have either no filtering, or linear filtering, neither of which allow the texture boundaries to fall outside of pixel alignment.


#20

The float stuff was thrown in quickly just to pass through without casting things to ints, but it’s not tested at all yet, so it’s likely there are obvious bugs to sort out still.


#21

That’s right, but you only need the hint if you request a specific renderer. If you call SDL_CreateRenderer() with a -1 index (and haven’t forced it with the SDL_RENDER_DRIVER hint), it’ll do batching, under the assumption that you won’t call OpenGL/Direct3D/whatever directly, since you might not have gotten any specific GPU API anyhow. If you tell SDL you need OpenGL or Direct3D or whatever, we have to assume you might call it at any time, and thus turn off batching. That being said, my testing with most renderer backends without batching is still faster than 2.0.9 due to other optimizations, but YMMV for several reasons.

It’s good practice to set the hint to allow batching anyhow, though, since an end-user might force a renderer with an environment variable, even if your app doesn’t call any lower level APIs.

(It’s also worth noting that Metal always does batching; because of the nature of its command queue, we can make guarantees that we can’t in the GL state machine. I expect a potential future Vulkan or Direct3D 12 renderer would be similar.)

In 2.1, we’ll probably remove this hint and make it so you must call SDL_RendererFlush() before touching a native API and always do batching otherwise.

–ryan.