INeedANap


I am using D3DXCreateEffect to create a vertex and pixel shader HLSL effect. The process I use to create and activate the effect is the same every time, I am only changing the pixel shader code, and here's what happens:

My program renders about 50 fps generally with CPU usage around 4% and when I do a trivial RGB to BGR color swap with the following shader, this usage remains:

PS_OUTPUT RenderScenePS( VS_OUTPUT In )
{
PS_OUTPUT Output;
// Lookup mesh texture and modulate it with diffuse
Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * In.Diffuse;
float r = Output.RGBColor.r;
Output.RGBColor.r = Output.RGBColor.b;
Output.RGBColor.b = r;
return Output;
}

So with this shader the rendering does a dynamic RGB to BGR swap entirely on the GPU I figure, because the CPU usage is still around only 4%. Now I just change the shader, nothing else in any of the code anywhere, to this:

PS_OUTPUT RenderScenePS( VS_OUTPUT In )
{
PS_OUTPUT Output;

// Lookup mesh texture and modulate it with diffuse
Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * In.Diffuse;

// Demo: 4-bit grayscale
float avg = (Output.RGBColor.r + Output.RGBColor.g + Output.RGBColor.b) / 3.0f;
avg = round(avg*16.0f) / 16.0f;
Output.RGBColor.r = avg;
Output.RGBColor.g = avg;
Output.RGBColor.b = avg;

return Output;
}

To me this seems simple enough but for reason my CPU usage goes way up when this shader is running (and the system lags like crazy). The rendering shows the grayscale image, so it is working, but the CPU usage is off the charts. I thought shaders were supposed to execute entirely on the GPU so I'm confused how it's possible that my CPU usage is going up unless something needs to be emulated in software. In my D3DXCreateEffect call I have the D3DXSHADER_NO_PRESHADER flag, (along with the not cloneable flag) which seems to be the only CPU-related flag available. My video card should be more than capable of such a shader even though it's not an ultra-powerful card (NVIDIA GeForceFX 5200).

What would cause a pixel shader to use the CPU power



Re: HLSL shader(s) using CPU instead of GPU

Jack Hoxley


It can't switch to using the CPU in the way you seem to suggest - that would require you to pull down your device and recreate it with the reference rasterizer. Vertex processing can run on the CPU but not pixel processing.

That said, I don't know why you'd see this characteristic - but I'd hazard a guess it isn't directly the shader you're using. More likely the change has caused a bottleneck somewhere, or you're starting to see more draw-call overhead (etc..)

Stepping through your frame in PIX and doing some decent profiling might help you find the true reason for the performance difference.

hth
Jack