Future of ARB_fragment_program ?

Cass,
I must say I’m a bit befuddled by your use of “ISA”, “ABI” and the parallels you have been drawing between C++ to x86-compilers and shader APIs.

ARB_fragment_program (and PS2.x for that matter) may be dubbed “assembly” interfaces, but they clearly are not native machine code interfaces, and as such cannot be an ABIs. Yes, they define an instruction sets, not expressions, so ISA may be an appropriate term, even though I wouldn’t call it that, based on the “usual” meaning of ISA as it is known to me.

Whatever, my point is that ARB_fragment_program does not expose the machine. You can make arbitrary changes to instruction encodings and it will still be possible to transparently support ARB_fragment_program. This is not the case with x86 assembly, where all details are open for (ab)use and are relied upon.

One very important example is that ARB_fp abstracts away the register count.
(I know that PS2.x pretends that it doesn’t, but then I don’t quite believe that current drivers care much about whether a temporary is called r12 or funky_thing.)
IMO this alone is proof that ARB_fp is not an assembly language but rather a high(er)-level language … without scopes and expressions.

Somehow developers are able to deal with this, and I’m don’t see how GLSL changes that.
It used to be pretty obvious and transparent as to what was and wasn’t available. You just check the extension string; if the driver didn’t expose ARB_crossbar, you didn’t use it. The unspoken and unwritten pact between the driver developers and ISVs was that the things that were exposed (as well as a well-known subset of standard OpenGL functionality) would run in hardware.

With glslang, we just have no idea. A shader that ran today just fine may break because some moron on the ATi driver staff happened to change the compiler and it now blows the instruction limit where it did not before. Is there a solution for this?

By contrast, if a driver suddenly stops supporting ARB_crossbar, the software can detect this and turn off features appropriately. So, while it still is a driver bug, the game doesn’t suddenly run in software.

Basically, drivers can screw ISVs post release already. This just gives them a really, really easy way to do it. And it will happen. There’s no guarentee that an implementation of glslang will ever compile and run any shader at reasonable speed, and if it can’t, there’s no way to tell why. These are not acceptable risks for software development.

And I guarentee you that it will be one of the reasons why OpenGL will be used less and less frequently in games.

ARB_fragment_program (and PS2.x for that matter) may be dubbed “assembly” interfaces, but they clearly are not native machine code interfaces, and as such cannot be an ABIs.
Cass’s use of the term “ABI” is more for the idea that it is a standardized interface that is easily supported across multiple “compilers”. You can compile a C library on GCC (for Win32) and link it to a C program compiled with VC++.

One very important example is that ARB_fp abstracts away the register count.
If I recall correctly, the P4 has far more actual hardware registers than x86 calls for. What they do is they map registers from the native hardware to what the x86 opcode is looking for.

x86 is not (any longer) “native assembly”; modern x86 chips have microcoded “compilers” that translate x86 commands into native internal opcodes that are then executed. x86 now exists solely as an interface; a single target for compilers to compile to that multiple chips can code for.

However, I fundamentally dislike the idea of making hardware specifically for an ISA. I don’t like the fact that the ISA compilers for modern x86 chips are a part of the chip and not the external compiler. I understand why it is, but I still don’t like it. Most important of all, this must never happen with graphics shaders. The minute someone starts adding transistors for the purpose of making some outdated ISA work is a bad day for everyone; it’s the first step on the way to what x86 is now.

The way around that is to make the ISA good enough to handle a plethora of hardware, such that hardware vendors do not consider trying to rebuild their hardware to look more like the ISA. The compilation from the ISA to the hardware needs to be a real process, and the ISA should not in any way influence how hardware is made.

It used to be pretty obvious and transparent as to what was and wasn’t available. You just check the extension string; if the driver didn’t expose ARB_crossbar, you didn’t use it. The unspoken and unwritten pact between the driver developers and ISVs was that the things that were exposed (as well as a well-known subset of standard OpenGL functionality) would run in hardware.

Are you really sure about this? because as far as I know this is true just in one direction, this is, if the extension is exposed it runs in hardware, but the opposite is not true (if not exposed, it doesn’t mean that it would run in software).

My GFFX doesn’t expose ARB_texture_env_crossbar but it supports it through GL1.4, and it works fine.

If I had looked at the extensions string I would never had used a feature in a wide range of hardware that supports it.

Originally posted by martinho_:
[b]Are you really sure about this? because as far as I know this is true just in one direction, this is, if the extension is exposed it runs in hardware, but the opposite is not true (if not exposed, it doesn’t mean that it would run in software).

My GFFX doesn’t expose ARB_texture_env_crossbar but it supports it through GL1.4, and it works fine.

If I had looked at the extensions string I would never had used a feature in a wide range of hardware that supports it.[/b]
That’s a good question. The unwritten rule that NVIDIA has followed has always been to always try to support the latest version of OpenGL, but not expose the corresponding extensions for functionality when there’s no direct hardware support.

The texture_env_crossbar example is an exception.
It’s not about hardware functionality, it’s about interoperation with other supported extensions.
If I remember correctly, we don’t support the extension because it conflicts with texture_env_combine4. This issue was corrected when the functionality was added to the 1.4 core.

The extension says:

ARB_texture_env_core:
If a texture environment for a given texture unit references a texture unit that is disabled or does not have a valid texture object bound to it, then it is as if texture blending is disabled for the given texture unit. Every texture unit implicitly references the texture object that is bound to it, regardless of the texture function specified by COMBINE_RGB_ARB or COMBINE_ALPHA_ARB.

The core says:

OpenGL core spec:
If a texture unit is disabled or has an invalid or incomplete texture (as defined in section 3.8.10) bound to it, then blending is disabled for that texture unit. If the texture environment for a given enabled texture unit references a disabled texture unit, or an invalid or incomplete texture that is bound to another unit, then the results of texture blending are undefined.

The core doesn’t define the behavior if you reference a disabled or incomplete texture in a stage where texture blending is enabled, but the ARB spec requires you to disable blending for that unit.

The ARB spec here wouldn’t have extended very well to ARBfp or GLSL anyway. If you think of this extension as being implemented as an ARBfp, we couldn’t just generate the program based on the combine state. We’d also have to re-generate and reload the program every time a texture is bound or enabled/disabled nulling out groups of instructions that correspond to that “blend unit”.

Not all that attractive, huh?

Anyway, just wanted to clear up that point since texture_env_crossbar is a bad example of how we try to convey hardware capabilities. Clearly your GeForceFX supports the 1.4 functionality, but we don’t support the extension because all the extra hassle of implementing it correctly.

Originally posted by martinho_:
if the extension is exposed it runs in hardware, but the opposite is not true
isnt that wrong taking ARB_vertex_program on older Nvidia Hardware as example, like I think even TNT supports the extension, but surely doesnt do it on GPU.

nevertheless I am quite a noob to all this shader stuff, but I prefer the low-level approach the ASM like extensions offer. It’s more like “you see exactly what you do” it helps you doing the minimal you need for an effect. While of course some cool compiler could take over that job, the hlsl stuff is still way too new I think, to have great compilers that both work fine and optimize well.

it would be cool if feature wise the ARB_programs would hold up to the HLSL so that personal preference/backup/comparison is possible, just like if one would favor Cg synatx over GLSL…

but then again its understandable when architecture differs so much and people have to write big compilers for hlsl and asm, that they would minimize work and do just one.

Originally posted by Korval:
With glslang, we just have no idea. A shader that ran today just fine may break because some moron on the ATi driver staff happened to change the compiler and it now blows the instruction limit where it did not before. Is there a solution for this?

If you offend them, they won’t come.


By contrast, if a driver suddenly stops supporting ARB_crossbar, the software can detect this and turn off features appropriately. So, while it still is a driver bug, the game doesn’t suddenly run in software.

Look at my suggestion #3
A static well defined behavior is what is needed. In my suggestion, I said disable optimization, but we could have the option of certain optimization such as conserve temp registers, conserve ALU instructions, don’t unroll, …

Now I know the ARB is really squimish about solutions that will have a short term scope, so I suggest that an proprietary extension (or multivendor) be written, and in 10 years, it could be dropped.

Having a way to query instr. count is good too because it will give us an idea of how heavy the shader actually is.

If the rumors are correct, MS will drop shader targets.
You can bet they won’t let dumb issues like these slip.

Originally posted by cass:
This is all speculation, of course, but it’s why I think ARB_fp and ARB_vp will be around for quite a while.
I second that. From the Steam database :

NVidia GeForce FX 5600-5200/GeForce 3/4		23.83 %
NVidia GeForce4 MX/2/1				17.51 %
ATI Radeon X600/9700/9500/9600/9650/9550 	15.87 %
ATI Radeon X800/9800 				13.72 %
ATI Radeon X300/9200/9100/9000/8500/7000 	8.94 %
NVidia GeForce FX 5950-5700 			6.65 %
NVidia GeForce 6800 				2.70 %
NVidia TNT2/TNT 				1.54 %
Intel 8xx 					2.57 %
SiS 7xx/6xx/3xx 				1.03 %
ATI Radeon/Rage 128/Rage 			0.84 %
S3 Graphics ProSavageDDR 			0.59 %
3Dfx Voodoo 3 					0.13 %
PowerVR KYRO/KYRO II 				0.11 %
Trident Video Accelerator Blade 3D/ProMedia 	0.08 %
Autres 						3.82 %

We see that a huge part of today’s market has no support for high level shaders (except cg).

EDIT : cards are grouped not only according to their features but also according to whether they are fast enought to make their feature useable.

I see this topic evolved quite a bit but I still wanted to say I’m against dropping ASM-like interfaces. Besides the fact I like ARB_vp and ARB_fp quite a bit for their syntax, I also hard that some compilers actually translate to ASM before going to “native” code. This is after all what some compilers do if I’m not wrong.
If this is true I would hate to see ASM dropped because it in fact would be still avaiable.
I also don’t think the time has come for this. There are still some people who uses ASM on CPU right now (need to recall RDTSC or CPUID?). Sure GPUs are much evolved but I think we can all live with it. Who cannot still have a choice after all.
I also agree about the handwritten-shader problem. I still have to carefully consider how much can I automate in a shader generation system but I still think a large majority of shaders will be built “at runtime”.
Notice that RenderMan itself could prove me wrong however this was just to put in my two cents.

There will always be people who’ve got plenty of time to bugger about with asm trying to outdo compilers. But there will always be a majority who have more imagination and just want a way of expressing it quickly, so they can move on to the next exciting thing. On the whole, I want performance to be the drivers responsibility whenever possible, so long as I follow basic guidelines - this is why I’m not pushing for an opengl extension to allow me to push hardware byte codes directly to the card…that’s not my job, that’s why opengl exists, as a hardware abstraction.

If you offend them, they won’t come.
Who won’t come where?

A static well defined behavior is what is needed. In my suggestion, I said disable optimization, but we could have the option of certain optimization such as conserve temp registers, conserve ALU instructions, don’t unroll, …
That’s silly. If the hardware can compile a shader in some way such that it fits and does what it is asked to, then it should do that. I shouldn’t have to tell it, “Try to make this shader fit within your ill-defined resource limits.” It should do that as a matter of course. Failure to compile should be a last resort, not a standard fallback.

EDIT : cards are grouped not only according to their features but also according to whether they are fast enought to make their feature useable.
Poor grouping. “Cooking” the data to benifit your argument is of no value to anyone.

A glslang shader can easily be a small thing or a big thing. While 5200 cards are going to be slow with any kind of cross-platform shader code, 5600’s are rather servicable for smaller shaders.

More importantly, the chunk of cards that can’t use shaders is getting smaller, not bigger.

There will always be people who’ve got plenty of time to bugger about with asm trying to outdo compilers.
It’s not just a question of “outdoing compilers”; it’s a question of getting shaders to work. How likely is it for a driver update to push a shader that was once barely within the limits outside of those limits? For glslang, it is very likely. For ARB_vp/fp, it is highly unlikely.

To have a driver release break your game would suck. Considering that boneheaded driver development can already screw your game over, let’s not give them more opportunities to break your software.

Originally posted by Korval:
[QB] [quote]EDIT : cards are grouped not only according to their features but also according to whether they are fast enought to make their feature useable.
Poor grouping. “Cooking” the data to benifit your argument is of no value to anyone.

A glslang shader can easily be a small thing or a big thing. While 5200 cards are going to be slow with any kind of cross-platform shader code, 5600’s are rather servicable for smaller shaders.[/QUOTE]Feel free to read directly the source:
http://www.steampowered.com/status/survey.html

And fx5600 cannot run HL2 in DX9 path smoothly. This card is definitely not a glsl target (that is if you use glsl to do something more interesting than the fixed path). Everyone knows fx sux with floating fp.

More importantly, the chunk of cards that can’t use shaders is getting smaller, not bigger.
That’s 1) a good thing 2) obvious.
Still I would not like to prevent a big part of the market buying my games just because I was lazy or because I choose a too advanced technology. Today I use arb vp/fp/cg, tomorrow I might use glsl.

Feel free to read directly the source:
I get approximately 41.99%. Not half, but then again, this is the population that is growing.

And yes, this includes FX’s 5600 or better. Equally importantly, ARB_fp exhibits the same problem with FX hardware that glslang does, so it is not guarenteed to be slower due to the use of glslang.

Today I use arb vp/fp/cg, tomorrow I might use glsl.
But every card that supports ARB_fp supports glslang. So it isn’t a question of lack of support so much as lack of good, trusted support.

Originally posted by Korval:
Who won’t come where?
Who : ATI’s staff. Their driver developers.
Where: these boards.

That’s silly. If the hardware can compile a shader in some way such that it fits and does what it is asked to, then it should do that. I shouldn’t have to tell it, “Try to make this shader fit within your ill-defined resource limits.” It should do that as a matter of course. Failure to compile should be a last resort, not a standard fallback.

OK, let me reword it. Let’s say today you have driver version 30.1 installed.
Your shader runs fine and you release your product.
2 months later, a new driver is released, version 30.2) and your shader hits a limit, whatever that may be.
You know that 30.1 was good enough.
Why not have 30.2 contain 30.1’s GLSL compiler and allow us to tell it to use that version?

It doesn’t need to be about hitting instruction limits or temp register limits.
It could be about performance. What if 30.1 was better for your shader? I have encountered this case, but not the former.

It’s better to stand away from the hw’s limits. Developers should just educate themselves.
For the performance, we can’t do squat.

Who : ATI’s staff. Their driver developers.
Where: these boards.

Good. They need to be working on their drivers anyway.

What if 30.1 was better for your shader?
Yes, but how do we know that 30.1 was “best” for our shader? All we knew was that 30.1 worked.

It’s better to stand away from the hw’s limits. Developers should just educate themselves.
Educate themselves on what? Do we now have to write a glslang compiler to know how close to instruction limits we are? There is no way a priori to know how close a given shader is to the limits. We don’t even know what the limits are (unless we have an assembly language spec that tells us what the limits are, that is). How can you code to limitations that you don’t know under an environment that tries its best to hide these limitations?

This “guess and check” refrain from glslang proponents is getting tiresome. The idea that developing for OpenGL means that every shader should be compiled and tested on every card made in the last 2 years with every driver made in the last 2 years is just nonsense, especially when there is specific knowledge out there as to whether or not the shader should fit with particular hardware. It’d be one thing if it were a software issue that had a signficant reason to vary from driver release to driver release. But these are hardware limitations being dicated through a highly transparent software interface.

But every card that supports ARB_fp supports glslang. So it isn’t a question of lack of support so much as lack of good, trusted support.[/QB]
I should have said “using Cg” or “using fx integer fp path as much as possible”, sorry for the misunderstanding.

There will always be people who’ve got plenty of time to bugger about with asm trying to outdo compilers. But there will always be a majority who have more imagination and just want a way of expressing it quickly, so they can move on to the next exciting thing. On the whole, I want performance to be the drivers responsibility whenever possible, so long as I follow basic guidelines - this is why I’m not pushing for an opengl extension to allow me to push hardware byte codes directly to the card…that’s not my job, that’s why opengl exists, as a hardware abstraction.

I couldn’t agree more with this.

Although I admit that it’s been painful at times to work with glsl it’s important to remember that this is in its infancy. As the hardware becomes capable of more, a high level language will be quite handy for creating shaders that are as of today only imaginable. Although we still have ASM languages now for CPU targets would you develop an application using them? This is an inevitable step in the right direction. I’m pretty sure that the ARB_vp/fp will stick around for quite some time (if they ever even go away at all, which im not sure that they should).

Who : ATI’s staff. Their driver developers.
Where: these boards.
Good. They need to be working on their drivers anyway.

Hah, nice…
Korval, unless you’re writing your own drivers, unfortuanately you work with what they give you.
It’s nice to know that when we voice our concerns, ideas, etc… in these forums that those in the position to take these things into consideration are listening.

Yes, but how do we know that 30.1 was “best” for our shader? All we knew was that 30.1 worked
Think of a way.

There is no way a priori to know how close a given shader is to the limits. We don’t even know what the limits are (unless we have an assembly language spec that tells us what the limits are, that is).
For getting limits at run time, see suggestion #1 in my posts way way above.

I’m aware of what the X800 and the Gf6800 can do and I’m sure everyone here does as well. That’s what I meant by developers educating themselves.

I think my 4 points (way way above) covered the essentials. And doing EXT_vp2/EXT_fp2 is not a bad idea either.

I’m aware of what the X800 and the Gf6800 can do and I’m sure everyone here does as well. That’s what I meant by developers educating themselves.
Great. That’s two cards. What about i915, Wildcat VP, Volari and other future cards that may support GLSL? Having to know how each card works defeats the purpose of having a device-independent API. :frowning:

Originally posted by idr:
[quote]I’m aware of what the X800 and the Gf6800 can do and I’m sure everyone here does as well. That’s what I meant by developers educating themselves.
Great. That’s two cards. What about i915, Wildcat VP, Volari and other future cards that may support GLSL? Having to know how each card works defeats the purpose of having a device-independent API. :frowning:
[/QUOTE]That’s a fair criticism, but it’s not acceptable for most software vendors to fall of the hardware-accelerated path. Until falling off the fast path is a rare exception and not the norm developers will need to be keenly aware of the limitations of particular classes of hardware.

Making that determination today is easier with the ASM APIs since they expose these limitations more explicitly.

The ASM APIs will probably continue to expose these features (with ever-larger minimum requirements) even when it is unlikely that developers will bump into them.

Having to know how each card works defeats the purpose of having a device-independent API.
And yet, we know plenty about each card. We can ask how many textures we can bind; we aren’t forced to keep binding more textures until the card runs out. We know how big textures can be; we don’t simply call glTexImage2D and check the error to see if it worked.

And yet, this is exactly what we’re asked to do with shaders. The only difference is that it is not entirely simple to specify these limits in a meaningful way.