OpenGL: "Fragment Shader not supported by HW" on old ATI card - opengl

In our OpenGL game we've got a shader link failure on an ATI Radeon x800 card. glGetProgramInfoLog reports:
Fragment shader(s) failed to link, vertex shader(s) linked.
Fragment Shader not supported by HW
Some googling suggests that we may be hitting an ALU instruction limit, due to a very long fragment shader. Any way to verify that?
I wasn't able to find detailed specs for the x800, nor any way to query the instruction limit at runtime. And even if I was able to query it, how do I determine the number of instructions of my shader?

There are several limits your may hit:
maximum shader length
maximum number of texture indirections (this is the limit most easily crossed)
using unsupported features
Technically the X800 is a shader model 2 GPU, which as about what GLSL 1.20 provides. When I started shader programming with a Radeon 9800, and the X800 is just a upscaled 9800 technically, I quickly abandoned the idea of doing it with GLSL. It was just too limited. And like so often when computer has only limited resources and capabilites, the way out was using assembly. In that case I mean the assembly provided by ARB_fragment_program extension.

GLview is a great tool to easily view all the limitations and supported GL extensions of a GPU/driver combination. If I recall correctly, I previously used AMD GPU ShaderAnalyzer which allows you to see the assembly compiled version of GLSL shaders. NVidia offers the same functionality with the nvemulate tool.
The x800 is very limited in shader power compared to current GPUs. You would probably have to cut back on your shader complexity anyway for this lower-end GPU to achieve proper performance. If you have your GLSL version running, simply choosing different fragment shaders for the X800 will probably be the most sensible approach.

Related

D3D11 Writing to buffer in geometry shader

I have some working OpenGL code that I was asked to port to Direct3D 11.
In my code i am using Shader Storage Buffer Objects (SSBOs) to read and write data in a geometry shader.
I am pretty new of Direct3D programming. Thanks to google I've been able to identify the D3D equivalent of SSBOs, RWStructuredBuffer (I think).
The problem is that I am not sure at all I can use them in a geometry shader in D3D11, which, from what i understand, can generally only use up to 4 "stream out"s (are these some sort of transform feedback buffer?).
The question is: is there any way with D3D11/11.1 to do what I'm doing in OpenGL (that is writing to SSBOs from the geometry shader)?
UPDATE:
Just found this page: http://msdn.microsoft.com/en-us/library/windows/desktop/hh404562%28v=vs.85%29.aspx
If i understand correctly the section "Use UAVs at every pipeline stage", it seems that accessing such buffers is allowed in all shader stages.
Then i discovered that DX11.1 are available only on Windows 8, but some features are also ported to Windows 7.
Is this part of Direct3D included in those features available on Windows 7?
RWBuffers are not related to the geometry shader outputting geometry, they are found in compute shader mostly and in a less percentage in pixel shader, and as you spot, other stages needs D3D 11.1 and Windows 8.
What you are looking for is stream output. The API to bind buffers to the output of the geometry shader stage is ID3D11DeviceContext::SOSetTargets and buffers need to be created with the flag D3D11_BIND_STREAM_OUTPUT
Also, outputting geometry with a geometry shader was an addition from D3D10, in D3D11, it is often possible to have something at least as efficient and simpler with compute shaders. That's not an absolute advice of course.
The geometry shader is processed once per assembled primitive and can generate one or more primitives as a result.
The output of the geometry shader can be redirected towards an output buffer instead of passed on further for rasterization.
See this overview diagram of the pipeline and this description of the pipeline stages.
A geometry shader has access to other resources, bound via the GSSetShaderResources method on the device context. However, these are generally resources that are "fixed" at shader execution time such as constants and textures. The data that varies for each execution of the geometry shader is the input primitive to the shader.
just been pointed to this page:
http://nvidia.custhelp.com/app/answers/detail/a_id/3196/~/fermi-and-kepler-directx-api-support .
In short, nvidia does not support the feature on cards < Maxell.
This pretty much answers my question. :/

Are Shaders used in the latest OpenGL very early?

When i look to the 4th Edition of the Book "OpenGL SuperBible" it starts with Points / Lines drawing Polygons and later on Shaders are discussed. In the 6th Edition of the book, it starts directly with Shaders as the very first example. I didn't use OpenGL for a long time, but is it the way to start with Shaders?
Why is there the shift, is this because of going from fixed pipeline to Shaders?
To a limited extent it depends on exactly which branch of OpenGL you're talking about. OpenGL ES 2.0 has no path to the screen other than shaders — there's no matrix stack, no option to draw without shaders and none of the fixed-pipeline bonded built-in variables. WebGL is based on OpenGL ES 2.0 so it inherits all of that behaviour.
As per derhass' comment, all of the fixed stuff is deprecated in modern desktop GL and you can expect it to vanish over time. The quickest thing to check is probably the OpenGL 4.4 quick reference card. If the functionality you want isn't on there, it's not in the latest OpenGL.
As per your comment, Kronos defines OpenGL to be:
the only cross-platform graphics API that enables developers of
software for PC, workstation, and supercomputing hardware to create
high- performance, visually-compelling graphics software applications,
in markets such as CAD, content creation, energy, entertainment, game
development, manufacturing, medical, and virtual reality.
It more or less just exposes the hardware. The hardware can't do anything without shaders. Nobody in the industry wants to be maintaining shaders that emulate the old fixed functionality forever.
"About the only rendering you can do with OpenGL without shaders is clearing a window, which should give you a feel for how important they are when using OpenGL." - From OpenGL official guide
After OpenGL 3.1, the fixed-function pipeline was removed and shaders became mandatory.
So the SuperBible or the OpenGL Redbook begin by describing the new Programmable Pipeline early in discussions. Then they tell how to write and use a vertex and fragment shading program.
For your shader objects you now have to:
Create the shader (glCreateShader, glShaderSource)
Compile the shader source into an object (glCompileShader)
Verify the shader (glGetShaderInfoLog)
Then you link the shader object into your shader program:
Create shader program (glCreateProgram)
Attach the shader objects (glAttachShader)
Link the shader program (glLinkProgram)
Verify (glGetProgramInfoLog)
Use the shader (glUseProgram)
There is more to do now before you can render than in the previous fixed function pipeline. No doubt the programmable pipeline is more powerful, but it does make it more difficult just to begin rendering. And the shaders are now a core concept to learn.

Is it possible to use Cg shaders in WebGL?

I'm aware of that I can use GLSL shaders in WebGL via attachShader and compileShader, as I did in OpenGL. My problem is: how about shaders written in Cg? On desktop I need cgc to compile them, what's the corresponding tool in WebGL world?
Usually you don't want to.
You could compile your shaders into GLSL with cgc (-profile glslv or -profile glslf), then load them anywhere you want. There is, however, slight difference between desktop and ES GLSL (WebGL likely using ES specification), so it may require adding a little hints at the beginning of shader (like precision mediump float;, could easily be #ifdef'd/).
Of course you can't use some Cg functionality in this case - if it is missing in GLSL, cgc can do nothing. E.g. mapping uniforms to specified registers or settings varyings to specified interpolator.

Dynamic shader in OpenGL

CUDA 5 and OpenCL 2 introduce dynamic Parallelism (kernels launched by another kernel via a device API, not by the host API).
Is there an equivalent to this in OpenGL? Is it possible to simulate them with feedback loops? (I think not) They don't miss in OpenGL (maybe in GL 4.3 compute shader) (shadow, texture, etc).
According to this page, it seems that compute shaders in OpenGL don't support dynamic parallelism. You can only launch them with glDispatchCompute​() or glDispatchComputeIndirect​().
It is less possible for other shaders to have such support, because they are within the OpenGL processing stages.

How big can a WebGL fragment shader be?

I'm raytracing in the WebGL fragment shader, planning on using a dynamically generated fragment shader that contains the objects in my scene. As I add an object to my scene, I will be adding some lines to the fragment shader, so it could get pretty large. How big can it get and still work? Is it dependent on the graphics card?
The "safe" answer is that it depends on your hardware and drivers, but in practical terms they can be pretty crazy big. What JustSid said about performance does apply (bigger shader == slower shader) but it sounds like you're not exactly aiming for 60FPS here.
For a more in-depth breakdown of shader limits, check out http://en.wikipedia.org/wiki/High_Level_Shader_Language. The page is about Direct X shaders, but all the shader constraints apply to GLSL as well.
There are all kinds of limits on how big shaders can be. It's up the driver/gpu but it's also up to the machine and WebGL. Some WebGL implementations (chrome) run an internal timer. If a single GL command takes too long they'll kill WebGL ("Rats, WebGL hit a snag"). This can happen when a shader takes too long to compile.
Here's an example of a silly 100k shader where I ran a model through a script to generate a mesh in the shader itself. It runs for me on macOS on my Macbook Pro. It also runs on my iPhone6+. But when I try it in Windows the DirectX driver takes too long trying to optimize it and Chrome kills it.
It's fun to goof off and put geometry in your shader and it's fun to goof off with signed distance fields and ray marching type stuff but those techniques are more of a puzzle / plaything. They are not in any way performant. As a typical example this SDF based shader runs at about 1 frame per second fullscreen on my laptop, and yet my laptop is capable of displaying all of Los Santos from GTV5 at a reasonable framerate.
If you want performance you should really be using more standard techniques, putting your geometry in buffers and doing forward or deferred rendering.
You don't want to create massive fragment shaders since they tend to drain the performance very fast. You should, if possible, do any calculation either already on the CPU or in the vertex shader, but not for every pixel.