HLSL: ignore geometry attributes on non-GS stages.

If a shader includes a mixture of several stages, such as HS and GS,
the non-stage output geometry should be ignored, lest it conflict
with the stage output.
This commit is contained in:
LoopDawg 2017-11-15 11:33:25 -07:00
parent 4036ef154f
commit 7573a2ab7f
4 changed files with 1283 additions and 0 deletions

File diff suppressed because it is too large Load Diff

119
Test/hlsl.gs-hs-mix.tesc Normal file
View File

@ -0,0 +1,119 @@
cbuffer UniformBlock0 : register(b0)
{
float4x4 model_view_matrix;
float4x4 proj_matrix;
float4x4 model_view_proj_matrix;
float3x3 normal_matrix;
float3 color;
float3 view_dir;
float3 tess_factor;
};
// =============================================================================
// Hull Shader
// =============================================================================
struct HSInput {
float3 PositionWS : POSITION;
float3 NormalWS : NORMAL;
};
struct HSOutput {
float3 PositionWS : POSITION;
};
struct HSTrianglePatchConstant {
float EdgeTessFactor[3] : SV_TessFactor;
float InsideTessFactor : SV_InsideTessFactor;
float3 NormalWS[3] : NORMAL;
};
HSTrianglePatchConstant HSPatchConstant(InputPatch<HSInput, 3> patch)
{
float3 roundedEdgeTessFactor = tess_factor;
float roundedInsideTessFactor = 3;
float insideTessFactor = 1;
HSTrianglePatchConstant result;
// Edge and inside tessellation factors
result.EdgeTessFactor[0] = roundedEdgeTessFactor.x;
result.EdgeTessFactor[1] = roundedEdgeTessFactor.y;
result.EdgeTessFactor[2] = roundedEdgeTessFactor.z;
result.InsideTessFactor = roundedInsideTessFactor;
// Constant data
result.NormalWS[0] = patch[0].NormalWS;
result.NormalWS[1] = patch[1].NormalWS;
result.NormalWS[2] = patch[2].NormalWS;
return result;
}
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_ccw")]
[outputcontrolpoints(3)]
[patchconstantfunc("HSPatchConstant")]
HSOutput HSMain(
InputPatch<HSInput, 3> patch,
uint id : SV_OutputControlPointID
)
{
HSOutput output;
output.PositionWS = patch[id].PositionWS;
return output;
}
// =============================================================================
// Geometry Shader
// =============================================================================
struct GSVertexInput {
float3 PositionWS : POSITION;
float3 NormalWS : NORMAL;
};
struct GSVertexOutput {
float4 PositionCS : SV_POSITION;
};
[maxvertexcount(6)]
void GSMain(
triangle GSVertexInput input[3],
inout LineStream<GSVertexOutput> output
)
{
float3 P0 = input[0].PositionWS.xyz;
float3 P1 = input[1].PositionWS.xyz;
float3 P2 = input[2].PositionWS.xyz;
GSVertexOutput vertex;
// Totally hacky...
P0.z += 0.001;
P1.z += 0.001;
P2.z += 0.001;
float4 Q0 = mul(proj_matrix, float4(P0, 1.0));
float4 Q1 = mul(proj_matrix, float4(P1, 1.0));
float4 Q2 = mul(proj_matrix, float4(P2, 1.0));
// Edge 0
vertex.PositionCS = Q0;
output.Append(vertex);
vertex.PositionCS = Q1;
output.Append(vertex);
output.RestartStrip();
// Edge 1
vertex.PositionCS = Q1;
output.Append(vertex);
vertex.PositionCS = Q2;
output.Append(vertex);
output.RestartStrip();
// Edge 2
vertex.PositionCS = Q2;
output.Append(vertex);
vertex.PositionCS = Q0;
output.Append(vertex);
output.RestartStrip();
}

View File

@ -172,6 +172,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.getdimensions.dx10.vert", "main"},
{"hlsl.getsampleposition.dx10.frag", "main"},
{"hlsl.global-const-init.frag", "main"},
{"hlsl.gs-hs-mix.tesc", "HSMain"},
{"hlsl.domain.1.tese", "main"},
{"hlsl.domain.2.tese", "main"},
{"hlsl.domain.3.tese", "main"},

View File

@ -8559,6 +8559,11 @@ bool HlslParseContext::handleInputGeometry(const TSourceLoc& loc, const TLayoutG
//
bool HlslParseContext::handleOutputGeometry(const TSourceLoc& loc, const TLayoutGeometry& geometry)
{
// If this is not a geometry shader, ignore. It might be a mixed shader including several stages.
// Since that's an OK situation, return true for success.
if (language != EShLangGeometry)
return true;
switch (geometry) {
case ElgPoints:
case ElgLineStrip: