James-Jones / HLSLCrossCompiler

Other
468 stars 81 forks source link

output variable declared multiple times when variables are packed in single register #25

Closed albertodemichelis closed 10 years ago

albertodemichelis commented 10 years ago

I found a situation that is not handled. When an output contains several components that are then packed in a single register, the crosscompiler emits the "out" variable multiple times with the same name(eg. VtxGeoOutput).

In the following example ParticleTexCoordScaleU,ParticleTexCoordScaleV and ParticleUVOrigin are all packed into register 2, the crosscompiler outputs "layout(location = 2) out vec4 VtxGeoOutput2;" 3 times. Probably a simple fix would be to keep track of what output has been already declared and skip the subsequent declarations.

btw, thank you for this very useful project

Heres some data:

// hlsl input structure for a VS struct VS_particle0_GATHER_Output { float4 PixelPosition : SV_Position; float4 ParticleColor : COMPUTED0; float ParticleTexCoordScaleU : COMPUTED1; float ParticleTexCoordScaleV : COMPUTED2; float4 TLPosProj : COMPUTED3; float2 ParticleUVOrigin : COMPUTED4; float4 TRPosProj : COMPUTED5; float4 BLPosProj : COMPUTED6; float4 BRPosProj : COMPUTED7;

};

//D3DCompiler disassembly

// Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // SV_Position 0 xyzw 0 POS float xyzw // COMPUTED 0 xyzw 1 NONE float xyzw // COMPUTED 1 x 2 NONE float x
// COMPUTED 2 y 2 NONE float y
// COMPUTED 4 zw 2 NONE float zw // COMPUTED 3 xyzw 3 NONE float xyzw // COMPUTED 5 xyzw 4 NONE float xyzw // COMPUTED 6 xyzw 5 NONE float xyzw // COMPUTED 7 xyzw 6 NONE float xyzw //

//HLSLCrossCompiler output declarations

layout(location = 1) out vec4 VtxGeoOutput1;

define Output1 VtxGeoOutput1

layout(location = 2) out vec4 VtxGeoOutput2; //1

define Output2 VtxGeoOutput2

layout(location = 2) out vec4 VtxGeoOutput2; //2 layout(location = 2) out vec4 VtxGeoOutput2; //3 times layout(location = 3) out vec4 VtxGeoOutput3;

define Output3 VtxGeoOutput3

layout(location = 4) out vec4 VtxGeoOutput4;

define Output4 VtxGeoOutput4

layout(location = 5) out vec4 VtxGeoOutput5;

define Output5 VtxGeoOutput5

layout(location = 6) out vec4 VtxGeoOutput6;

define Output6 VtxGeoOutput6

James-Jones commented 10 years ago

I'm not able to reproduce this with the information given. There is already a mechanism to handle multiple declarations (see the OutputNeedsDeclaring function and its call sites).

dcl_output_siv o0.xyzw, position dcl_output o1.xyzw dcl_output o2.x dcl_output o2.y dcl_output o2.zw dcl_output o3.xyzw

layout(location = 1) out vec4 VtxGeoOutput1;

define Output1 VtxGeoOutput1

layout(location = 2) out vec4 VtxGeoOutput2;

define Output2 VtxGeoOutput2

layout(location = 3) out vec4 VtxGeoOutput3;

define Output3 VtxGeoOutput3

struct VSInput { float4 PixelPosition : inPOSITION; float4 ParticleColor : inCOMPUTED0; float ParticleTexCoordScaleU : inCOMPUTED1; float ParticleTexCoordScaleV : inCOMPUTED2; float4 TLPosProj : inCOMPUTED3; float2 ParticleUVOrigin : inCOMPUTED4; };

struct VS_particle0_GATHER_Output { float4 PixelPosition : SV_Position; float4 ParticleColor : COMPUTED0; float ParticleTexCoordScaleU : COMPUTED1; float ParticleTexCoordScaleV : COMPUTED2; float4 TLPosProj : COMPUTED3; float2 ParticleUVOrigin : COMPUTED4; };

VS_particle0_GATHER_Output main( VSInput vsIn ) { VS_particle0_GATHER_Output vsOut;

vsOut.PixelPosition = vsIn.PixelPosition;
vsOut.ParticleColor = vsIn.ParticleColor;
vsOut.ParticleTexCoordScaleU = vsIn.ParticleTexCoordScaleU;
vsOut.ParticleTexCoordScaleV = vsIn.ParticleTexCoordScaleV;
vsOut.TLPosProj = vsIn.TLPosProj;
vsOut.ParticleUVOrigin = vsIn.ParticleUVOrigin;

return vsOut;

}

albertodemichelis commented 10 years ago

Yes you are right. I'm sorry, I'm an idiot, I was trying to add a custom flag and broke this function. About this, in my engine I specify the input attributes locations from the application using glBindAttribLocation so would be great to have a flag to disable explicit input locations in the shader (that's how I broken the output thing).