Jump to content
  • Advertisement
Sign in to follow this  
Mr_Fox

HLSL keywords 'out' works differently than 'return'?

This topic is 943 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey Guys,

 

I have the following vs and ps working properly

struct PosTex
{
	float4 Pos : SV_Position;
	float2 Tex : TEXCOORD0;
};

PosTex vs_heightmap_main( in uint VertID : SV_VertexID)
{
	PosTex output;
	uint2 xy = uint2(VertID % DepthInfraredReso.x, VertID / DepthInfraredReso.x);
	float z = DepthMap[xy] * 0.001f;
	float4 pos = float4((xy - DepthCxyFxy.xy) / DepthCxyFxy.zw * z, z, 1.f);
	float4 pos_col = mul( Depth2Color, pos );
	output.Tex= pos_col.xy / pos_col.z * ColorCxyFxy.zw + ColorCxyFxy.xy;
	pos = pos * float4(1.f,-1.f,1.f,1.f) + Offset;
	output.Pos = mul( ViewProjMat, pos );
	return output;
}

float4 psmain(PosTex input ) : SV_Target0
{
	return ColorMap[input.Tex];
}

Then after reading something about the HLSL keyword 'in' 'out' 'inout' I decide to play around  with it. So I modified the previous code as the following

void vs_heightmap_main( in uint VertID : SV_VertexID, out float4 Pos : SV_Position, out float2 Tex : TEXCOORD0)
{
	uint2 xy = uint2(VertID % DepthInfraredReso.x, VertID / DepthInfraredReso.x);
	float z = DepthMap[xy] * 0.001f;
	float4 pos = float4((xy - DepthCxyFxy.xy) / DepthCxyFxy.zw * z, z, 1.f);
	float4 pos_col = mul( Depth2Color, pos );
	Tex= pos_col.xy / pos_col.z * ColorCxyFxy.zw + ColorCxyFxy.xy;
	pos = pos * float4(1.f,-1.f,1.f,1.f) + Offset;
	Pos = mul( ViewProjMat, pos );
}

float4 psmain(float2 Tex:TEXCOORD0 ) : SV_Target0
{
	return ColorMap[Tex];
} 

Basically I get rid of vs return and use the 'out' keyword to pass data in between shader stages, but I only end up getting error:

 

Vertex Shader - Pixel Shader linkage error: Signatures between stages are incompatible. Semantic 'TEXCOORD' is defined for mismatched hardware registers between the output stage and input stage. 

 

So there must be something I missed about when and how to use out keyword. It will be greatly appreciated if someone could enlightening me on that.

 

Thanks

Share this post


Link to post
Share on other sites
Advertisement

Try adding "float4 pos : SV_POSITION" as an input to the Pixel Shader before your texture coordinate input. Does that resolve the error?

Share this post


Link to post
Share on other sites

Try adding "float4 pos : SV_POSITION" as an input to the Pixel Shader before your texture coordinate input. Does that resolve the error?

Yes, that solves the problem. But why is this necessary? my ps never use the float4 pos. and SV_Position in vs should already indicates that pos is the final vertex pos for rasterizer, why this param need to go to ps?

 

Also can I safely say that any data which can be placed after 'return' could instead be placed in input param list with keyword 'out'? And if yes, which one is preferred?  Does 'out' in input param list incur extra copy of the data which will not happen if use return?

 

Thanks again  

 

 

P.S. I double checked, the order (in vs input param list, and ps input param list) is also very important, basically they should be in same order

Edited by Mr_Fox

Share this post


Link to post
Share on other sites
I believe in your 1st approach you create a local object for the output structure, which you return in the end. In the 2nd approach you directly use the return value/object of the function.

Share this post


Link to post
Share on other sites

So it looks like I can safely switch using 'return' or 'out' keyword as I like in vs. But when I try to do the same thing in gs, the situation seems a little bit tricky:

void gs_surface_main( point uint VertID[1] : POSITION0, inout TriangleStream<TexPos> TriStream )

since the TriangleStream uses template like format, I think there is no way to use 'out' params to replace <TexPos> if we have multiple data in TexPos

Share this post


Link to post
Share on other sites
Not sure if it's possible, but to be sure what you're doing I'd use a local variable.
Personally I do this also with class member functions containing more then 1 line of code.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!