1.1 vs 2.0 performance?


9 posts
by factoid » Mon Oct 29, 2012 2:50 pm
Is there any real difference in performance between the two versions? I'm working on an application which doesn't really require more than the fixed function operations exposed by GLES 1.1, but if 2.0 is also faster on the GPU, I'm more than happy to do the extra work to define the basic shaders.
Posts: 45
Joined: Tue Jul 17, 2012 5:35 am
by panik » Wed Oct 31, 2012 8:34 pm
I'm on the same boat. GLES 2.0 would do what I want (and more), but GLES 1.1 is already doing what I really need.

I remember reading a discussion on this somewhere, but I can't seem to find it back. But what I took out of that is that you can't really compare the two on performance, only on features. As in: How fast is a fragment shader in GLES 1.1, compared to GLES 2.0? There's no answer to that, because it's obviously the wrong question.

I don't have an answer to the good question (the one I think you're asking too): How do they compare in performance with 'the basic stuff'?.

The only reason I will switch to GLES 2.0 one day, is because it'll be a good learning experience and more 'future proof'. For now, I consider it a big feature that GLES 1.1 code is clean, short and simple. That will definitely change when switching to GLES 2.0.
User avatar
Posts: 277
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by factoid » Wed Oct 31, 2012 8:41 pm
The reason I ask is because, with work my company has done on iOS, the newer phones implement GL ES 2.0 to the determent of GL ES 1.1

So for example, if you've written a game in GL ES 1.1, you can get a boost to your frame rate by switching to GL ES 2.0 and providing basic "fixed function" shaders. If no one has an answer I'll probably attempt some benchmarking at some point in the future.

In my case, I don't need the advanced shader functions provided by programmable shaders, but I do want to maximize render speed.
Posts: 45
Joined: Tue Jul 17, 2012 5:35 am
by dom » Wed Oct 31, 2012 10:11 pm
There is no specific hardware for 1.1. It just uses some pre-canned shader code to implement each fixed function.
I wouldn't expect a significant difference in performance.
The 1.1 version may be quicker because the shader code was written by someone who really knows the hardware.
The 2.0 version may be quicker because you might know something about your data that the 1.1 code can't assume.

I'd certainly recommend 2.0 as programmable shaders are so much more powerful.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4105
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by factoid » Thu Nov 01, 2012 2:32 am
Thanks for the info, dom. I'll probably take the Knuthian approach and stick with 1.1 until I either require 2.0 functions or I determine that it's the GL stack (and not my rendering approach) that's the bottleneck. I'm only rendering unlit primitives with at most 1 texture.
Posts: 45
Joined: Tue Jul 17, 2012 5:35 am
by blu » Thu Nov 01, 2012 8:58 am
Normally, ES1.1 implementations sit on top of ES2 (basically as wrappers with extra state tracking), so the main difference you'd encounter in speed would come from the API assumptions about the render state which is relevant to your app's needs. For instance, ES1.1 needs to re-create shaders before draw whenever you change some lighting/material attribute in the ES1.1 state. Sometimes, ES1.1 might do that regardless, i.e. just regen its shaders not based on keeping track of what state changes occurred. Note that I'm not just referring to recompile, but the entire codegen -> compile -> link process. This is more involving than what some ES2 drivers do when they re-compile and re-link their shaders based on changes in the uniforms (read: shader arguments). Other than that, what dom said is true - the driver's shader codegen could potentially produce better code for a given setup, depending on a bunch of things, not last among which being developer's familiarity with the platform at hand.
Posts: 55
Joined: Tue Jul 17, 2012 9:57 pm
by Emanuele » Sat Nov 03, 2012 7:28 am
Hi blu, do you mind if I ask you if the "codegen -> compile -> link" bit is an educated guess or you have some inside information? I would hope that 1.1 drivers could just stitch and patch some pre-written code blocks together. Matching the current rendering state (I mean at enable/disable level) against
a few cached versions of the shaders looks also feasible. I have no inside information, but that is what I would do.
User avatar
Posts: 165
Joined: Wed Aug 03, 2011 5:28 pm
by blu » Mon Nov 05, 2012 2:31 pm
Emanuele wrote:Hi blu, do you mind if I ask you if the "codegen -> compile -> link" bit is an educated guess or you have some inside information? I would hope that 1.1 drivers could just stitch and patch some pre-written code blocks together.

Hi Emanuele. Yes, stitching & patching pre-existing blocks of code is normally how codegen is done in ES1.1 drivers. Apologies if the word 'codegen' sounds too abstract or pretentious.

Matching the current rendering state (I mean at enable/disable level) against
a few cached versions of the shaders looks also feasible. I have no inside information, but that is what I would do.

Well, part of the problem is that you need to produce one all-encompassing shader (of vertex + fragment parts) that covers the entire state, a 'ubershader' of the fixed pipeline state. Now, keeping just 'a few' cached versions of that could be tricky. I mean, you should definitely keep the top MRU one, but other than that, things might become statistically tough. Consider a rudimentary scenario based on confining light contributors, where each draw ends up with its own set of lights Li .. Lj enabled, where {Li, .., Lj} is an arbitrary non-empty subset of the pipeline's complete light set.

Even though the difference in the shaders might look utterly minimal at first glance - just different indexation in some structures or masking/unmasking different results, you may actually want to produce a new shader each and every time if you want to retain efficiency, i.e. avoid a control statement inside the shading loop of the vertex shader, potentially masking computationally-costly results and effectively wasting the engine's optimisation logic which worked hard picking relevant lights. So caching a few already-done shaders does not hurt here, but what benefits that'd provide would depend on the upper-level engine logic that decides which lights to use each draw. Actually, whether you might want to re-codegen/build your ubershader, versus paying the cost up front of any unwanted light contributors in your vertex shader, might be a decision which should be best considered with the knowledge of how big the vertex buffer for the draw is - for small-enough vertex buffers it could be cumulatively faster to re-use a more-inefficient vertex shader but avoid the codegen/build phase, which could end up more costly.

It's just a trivial example, but it illustrates the bane of ES1 - it has to be all sorts of 'smart' and perhaps apply various heuristics if it wants to be efficient - something which ES2 leaves to the right decision maker - the caller. In this regard, ES2 API is the better abstraction for the task of sending graphic primitives down to a contemporary GPU, whereas ES1 exists for legacy reasons alone. That does not mean you should never consider using ES1 for a new project running on ES2 hw, but it is a good enough counter-argument for most such cases.
Posts: 55
Joined: Tue Jul 17, 2012 9:57 pm
by Emanuele » Mon Nov 05, 2012 6:41 pm
It wasn't abstract or pretentious at all and to be honest I wasn't exactly clear about what I meant. My main issue was actually with the "compile" bit. The idea of a driver concatenating strings and doing the parsing at every state change just sounds wrong. I would expects the bits to be joined to be in binary format already and the patching mostly involving changing the attribute ids. A specialized linker if you will (maybe a bit smarter, but with less checks for sure, since the code is coming from a trusted source).

I agree that it might not work out, but betting that the application is keeping the number of states low is not so unreasonable IMO. In theory, the application could use a large number of combinations. In practice, it might just use baked lighting for the environment, one dynamic light for the actors, and simple texture mapping for the HUD.

More in general, if the driver is up to it, I think that, for a beginner, ES 1.1 would be a good place to start. Sure, there are some ugly bits (i.e. texture environment), but, on the other hand, there is less boilerplate to write and fewer things that can go wrong. Later on, porting some working ES 1.1 code to ES 2.0 would not be that difficult, and might actually be a good way to learn ES 2.0 (especially if at that point you are just focused on writing the shader yourself from scratch knowing what to aim for, as opposed to copying and pasting a shader written by someone else).
User avatar
Posts: 165
Joined: Wed Aug 03, 2011 5:28 pm