11

To start with my main question:

Can I use pixel shader model 3, 4 or 5 in my FireMonkey applications?

I want to be able to dynamically create pixel shaders in my FireMonkey program. To do that, I now compile a pixel shader using fxc.exe that comes with the DirectX SDK, and load the compiled code into my TShaderFilter descendant. That works fine (let me know if you're interested in how I do that).

However, I can only get things to work if I compile with ps_2_0 as a target profile.

I'm currently running into limitations of shader model 2.0. For example loops seem to be unrolled by the compiler, and there's a maximum number of instructions that you can have in level 2 shaders. Because of that, the number of possibilities are pretty limited.


Example: The shader code below creates a mandelbrot fractal. If I set Iterations too high, it doesn't compile. Error message:

error X5608: Compiled shader code uses too many arithmetic instruction slots (78). Max. allowed by the target (ps_2_0) is 64.

#define Iterations 12

float2 Pan;
float Zoom;
float Aspect;
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
{
    float2 c = (texCoord - 0.5) * Zoom * float2(1, Aspect) - Pan;
    float2 v = 0;        
    for (int n = 0; n < Iterations; n++)
    {
        v = float2(v.x * v.x - v.y * v.y, v.x * v.y * 2) + c;
    }        
    return (dot(v, v) > 1) ? 1 : 0;
}

With shader model ps_3_0 I can compile with more iterations, but the compiled shader doesn't seem to work in FireMonkey. I don't get any error message; I just get a red image as a result.


Does anyone here have any idea on how to get around this, or is FireMonkey just not capable of utilizing the full potential of my graphics card?

Note, I've seen that the minimum requirement for FireMonkey is a graphics card with shader level 2.0, but it's not clear if that means you cannot use shader level 3 or higher.

Wouter van Nifterick
  • 22,500
  • 7
  • 72
  • 117
  • 3
    +1, interesting question! I'd be interested in reading how you're compiling and using shaders, too. – David Apr 16 '12 at 09:05

1 Answers1

3

This answer is correct at the time of writing, but will possibly change as FireMonkey develops:

You cannot use PixelShader or ShaderModel 3.0 or higher, as FireMonkey (under Windows) uses DirectX 9, while PixelShader/ShaderModel 3.0+ are features of DirectX 10. If you look in Winapi.D3DX9.pas (lines 2871-2872), you'll be able to confirm that ps_3_0 is not a valid token here, while in Winapi.D3DX10.pas (lines 3224-3230) it is supported.

So, the only way you'd be able to use PixelShader/ShaderModel 3.0+ would be to either modify FireMonkey yourself to use a DirectX 10 context, or request (with the backing of others) that Embarcadero change this for you.

LaKraven
  • 5,676
  • 2
  • 21
  • 49
  • 1
    I think this is wrong. DirectX 9.0c (from 2004) supports shader model 3.0. SM2 came with the original DirectX9.0 release, but 9.0c is eight years old and is very standard. DirectX 10 introduced SM4. I haven't checked the Pascal translations, and so maybe they're missing a valid token, but this means that if FMX uses DirectX 9 it should definitely be capable of using SM3. – David May 14 '12 at 09:37
  • You may be right. What I can say with certainty is that Delphi's translation for DX9 does *not* provide the ps_3_0 flag. I'm not entirely sure whether DirectX 9.0c added SM 3.0 and PS 3.0, but Delphi's headers certainly don't. – LaKraven May 17 '12 at 17:12