Jump to content

  • Log In with Google      Sign In   
  • Create Account


Not enough PS input registers


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 schupf   Members   -  Reputation: 216

Like
0Likes
Like

Posted 08 January 2012 - 09:47 AM

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.

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!

Sponsor:

#2 Rattenhirn   Crossbones+   -  Reputation: 1690

Like
0Likes
Like

Posted 08 January 2012 - 11:47 AM

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...

#3 Adam_42   Crossbones+   -  Reputation: 2419

Like
0Likes
Like

Posted 08 January 2012 - 11:55 AM

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.

#4 schupf   Members   -  Reputation: 216

Like
0Likes
Like

Posted 08 January 2012 - 01:13 PM

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+?

#5 Adam_42   Crossbones+   -  Reputation: 2419

Like
0Likes
Like

Posted 09 January 2012 - 08:36 AM

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.

#6 schupf   Members   -  Reputation: 216

Like
0Likes
Like

Posted 12 January 2012 - 08:33 AM


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.

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?

#7 Adam_42   Crossbones+   -  Reputation: 2419

Like
0Likes
Like

Posted 12 January 2012 - 09:12 AM

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.

#8 schupf   Members   -  Reputation: 216

Like
0Likes
Like

Posted 12 January 2012 - 02:26 PM

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

SetVertexShaderConstant and

SetPixelShaderConstant() set these c# registersdi


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

SetVertexShaderConstant and which one is set by calling

SetPixelShaderConstant

?



On this site:

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?

#9 turch   Members   -  Reputation: 590

Like
0Likes
Like

Posted 12 January 2012 - 02:50 PM

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

SetVertexShaderConstant and which one is set by calling

SetPixelShaderConstant

?


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.

#10 schupf   Members   -  Reputation: 216

Like
0Likes
Like

Posted 12 January 2012 - 04:39 PM

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?

#11 turch   Members   -  Reputation: 590

Like
0Likes
Like

Posted 12 January 2012 - 04:45 PM

Yes, exactly. What you were doing was redundantly defining the constants in both the pixel and vertex shaders, roughly halving your number of registers.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS