Not enough PS input registers

Started by
9 comments, last by turch 12 years, 3 months ago
Hello,

I am using DX9 and targeting Shader Model 2.

All my shader files include a common shader file, which looks like this:


float4x4 auWorldMat : register(c0);
float4x4 auWorldInvTransMat : register(c4);
float4x4 auViewMat : register(c8);
float4x4 auProjMat : register(c12);
float4x4 auViewProjMat : register(c16);
float3 auCameraPosition : register(c20);
float auTimeDt : register(c21);
float auTimeAbs : register(c22);

float4 auMat_EmissiveColor : register(c23);
float4 auMat_AmbientColor : register(c24);
float4 auMat_DiffuseColor : register(c25);
float4 auMat_SpecularColor : register(c26);

float3 auLight0_Position : register(c30);
float3 auLight0_Direction : register(c31);
float4 auLight0_AttenAndRange : register(c32);
float4 auLight0_AmbientColor : register(c33);
float4 auLight0_DiffuseColor : register(c34);
etc...


My engine sets these values every frame per SetVertexShaderConstantF or SetPixelShaderConstantF().
Unfortunately I just run into the following problem:
I have a pixel shader, that reads auLight0_DiffuseColor, which gives the following compile error:
error X5200: (Second source param) Invalid register number: 34. Max allowed for this type is 31.
, which apparently only has 32 c# input registers.[/quote]
Apparently SM2.0 PS only support 32 c# input registers.

So what would be the best way to fix this problem?
Upgrade to SM3.0 (my game should also run on old hardware (Win XP). Is SM3.0 standard even for old machines?)

Or should I put all values that are read exclusively by the PS into the first c# registers and move Vertex Shader specific variables (like
world matrix, proj matrix etc.) into the higher registers?

Thanks!
Advertisement
Each of these registers can hold 4 floats, so you can put some of those single float parameters into the same register. This is slightly less convenient, but is pretty much the only way of using registers more efficiently

Example:

float4 auTime : register(c22);

main(...)
{
auTimeDt = auTime.x;
auTimeAbs = auTime.y;
// we've got space for two more floats here...
}




As for your question about SM 3.0 being standard on "old" hardware, depends on what you define as "old" hardware.

If you don't want to target SM 2.0 cards, then move to SM 3.0...
Normally you'd let the hlsl compiler do the constant register allocation and it will return you a constant table to tell you where it's allocated them. The downside of that approach is that you'll have to set all the constants up every time you switch shader, because the register numbers can change.

If you don't want to do that then you should definitely reuse the same register numbers for both the pixel and vertex shader - they won't conflict.

By the way almost all PS 2.0 cards I know of are Intel motherboard integrated ones, and are rather slow.


If you don't want to do that then you should definitely reuse the same register numbers for both the pixel and vertex shader - they won't conflict.

I already use some of these uniforms for VS and PS. For example all material and lighting uniforms are set for the PS and VS (per SetVertexShaderConstant/SetPixelShaderConstant).
Wouldn't it be the best idea to put all PS uniforms into register C0-C31 and all pure VS uniforms (viewmatrix, projMatrix etc) into Registers C31+?

Wouldn't it be the best idea to put all PS uniforms into register C0-C31 and all pure VS uniforms (viewmatrix, projMatrix etc) into Registers C31+?


If you don't want to make full use of the available vertex shader registers then you could do that.

[quote name='schupf' timestamp='1326049990' post='4900715']
Wouldn't it be the best idea to put all PS uniforms into register C0-C31 and all pure VS uniforms (viewmatrix, projMatrix etc) into Registers C31+?


If you don't want to make full use of the available vertex shader registers then you could do that.
[/quote]
Uhm, what do you mean with "vertex shader registers"? I thought the c# registers are shared between PS and VS, arent they? Are there additional registers (writable by the C++ host code) specific for the VS?
The pixel shader and vertex shader constant registers are completely separate.

That is SetVertexShaderConstant(0, foo); SetPixelShaderConstant(0, bar); will set two independent values for the first constant - one for the vertex shader and one for the pixel shader.
I did not know this.

I thought the only registers that are available from the C++ Host code are the c# registers and I thought [color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

SetVertexShaderConstant and

[/font][color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

SetPixelShaderConstant() set these c# registersdi

[/font]
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

If PS and VS have different registers: How are they called? Which register is set if I call

[/font][color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

SetVertexShaderConstant and which one is set by calling

[/font][color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

SetPixelShaderConstant

[/font][color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

?

[/font]

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

On this site:

[/font]http://msdn.microsoft.com/en-us/library/windows/desktop/bb172961(v=vs.85).aspx are the register types. Which one can be set from C++ Host code?



[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

If PS and VS have different registers: How are they called? Which register is set if I call [/font]


[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

SetVertexShaderConstant and which one is set by calling [/font]


[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

SetPixelShaderConstant[/font]


[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

?[/font]




SetVertexShaderConstantF will set the vertex shader constant registers (c# in the msdn link).
SetPixelShaderConstantF will set the pixel shader constant register (c# in the pixel shader version of your link)

There are also integer and boolean versions of the above (same as above but with I and B instead of F, and i# / b# on the msdn pages).

The pixel and vertex shaders both have their own float, integer, and boolean constant registers. They are completely separate, the pixel shader cannot access data in a vertex shader constant and vice versa.
Ah, I see.

In my first posting I showed part of my common shader file that declared all my variables that might be used by pixel or vertex shaders. I included this file in ALL my pixel and vertex shader source files. Since PS and VS have their own c# registers I guess it would make more sense to split this file into a common shader file for all pixel shaders and one for all vertex shaders?

This topic is closed to new replies.

Advertisement