Add clip/cull-distance support to HLSL.

This commit is contained in:
Hans-Kristian Arntzen 2018-02-22 16:40:04 +01:00
Родитель fb3f92a3ff
Коммит 114c2c5e37
7 изменённых файлов: 260 добавлений и 4 удалений

Просмотреть файл

@ -0,0 +1,31 @@
static float gl_ClipDistance[2];
static float gl_CullDistance[2];
static float FragColor;
struct SPIRV_Cross_Input
{
float2 gl_ClipDistance0 : SV_ClipDistance0;
float2 gl_CullDistance0 : SV_CullDistance0;
};
struct SPIRV_Cross_Output
{
float FragColor : SV_Target0;
};
void frag_main()
{
FragColor = ((gl_ClipDistance[0] + gl_CullDistance[0]) + gl_ClipDistance[1]) + gl_CullDistance[1];
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_ClipDistance[0] = stage_input.gl_ClipDistance0.x;
gl_ClipDistance[1] = stage_input.gl_ClipDistance0.y;
gl_CullDistance[0] = stage_input.gl_CullDistance0.x;
gl_CullDistance[1] = stage_input.gl_CullDistance0.y;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

Просмотреть файл

@ -0,0 +1,30 @@
static float4 gl_Position;
static float gl_ClipDistance[2];
static float gl_CullDistance[2];
struct SPIRV_Cross_Output
{
float4 gl_Position : SV_Position;
float2 gl_ClipDistance0 : SV_ClipDistance0;
float2 gl_CullDistance0 : SV_CullDistance0;
};
void vert_main()
{
gl_Position = 1.0f.xxxx;
gl_ClipDistance[0] = 0.0f;
gl_ClipDistance[1] = 0.0f;
gl_CullDistance[0] = 4.0f;
gl_CullDistance[1] = 4.0f;
}
SPIRV_Cross_Output main()
{
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.gl_ClipDistance0.x = gl_ClipDistance[0];
stage_output.gl_ClipDistance0.y = gl_ClipDistance[1];
stage_output.gl_CullDistance0.x = gl_CullDistance[0];
stage_output.gl_CullDistance0.y = gl_CullDistance[1];
return stage_output;
}

Просмотреть файл

@ -0,0 +1,31 @@
static float gl_ClipDistance[2];
static float gl_CullDistance[2];
static float FragColor;
struct SPIRV_Cross_Input
{
float2 gl_ClipDistance0 : SV_ClipDistance0;
float2 gl_CullDistance0 : SV_CullDistance0;
};
struct SPIRV_Cross_Output
{
float FragColor : SV_Target0;
};
void frag_main()
{
FragColor = ((gl_ClipDistance[0] + gl_CullDistance[0]) + gl_ClipDistance[1]) + gl_CullDistance[1];
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_ClipDistance[0] = stage_input.gl_ClipDistance0.x;
gl_ClipDistance[1] = stage_input.gl_ClipDistance0.y;
gl_CullDistance[0] = stage_input.gl_CullDistance0.x;
gl_CullDistance[1] = stage_input.gl_CullDistance0.y;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

Просмотреть файл

@ -0,0 +1,30 @@
static float4 gl_Position;
static float gl_ClipDistance[2];
static float gl_CullDistance[2];
struct SPIRV_Cross_Output
{
float4 gl_Position : SV_Position;
float2 gl_ClipDistance0 : SV_ClipDistance0;
float2 gl_CullDistance0 : SV_CullDistance0;
};
void vert_main()
{
gl_Position = 1.0f.xxxx;
gl_ClipDistance[0] = 0.0f;
gl_ClipDistance[1] = 0.0f;
gl_CullDistance[0] = 4.0f;
gl_CullDistance[1] = 4.0f;
}
SPIRV_Cross_Output main()
{
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.gl_ClipDistance0.x = gl_ClipDistance[0];
stage_output.gl_ClipDistance0.y = gl_ClipDistance[1];
stage_output.gl_CullDistance0.x = gl_CullDistance[0];
stage_output.gl_CullDistance0.y = gl_CullDistance[1];
return stage_output;
}

Просмотреть файл

@ -0,0 +1,12 @@
#version 450
in float gl_ClipDistance[2];
in float gl_CullDistance[2];
layout(location = 0) out float FragColor;
void main()
{
FragColor = gl_ClipDistance[0] + gl_CullDistance[0] + gl_ClipDistance[1] + gl_CullDistance[1];
}

Просмотреть файл

@ -0,0 +1,12 @@
#version 450
out float gl_ClipDistance[2];
out float gl_CullDistance[2];
void main()
{
gl_Position = vec4(1.0);
gl_ClipDistance[0] = 0.0;
gl_ClipDistance[1] = 0.0;
gl_CullDistance[0] = 4.0;
gl_CullDistance[1] = 4.0;
}

Просмотреть файл

@ -509,6 +509,40 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
semantic = legacy ? "DEPTH" : "SV_Depth";
break;
case BuiltInClipDistance:
// HLSL is a bit weird here, use SV_ClipDistance0, SV_ClipDistance1 and so on with vectors.
for (uint32_t clip = 0; clip < clip_distance_count; clip += 4)
{
uint32_t to_declare = clip_distance_count - clip;
if (to_declare > 4)
to_declare = 4;
uint32_t semantic_index = clip / 4;
static const char *types[] = { "float", "float2", "float3", "float4" };
statement(types[to_declare - 1], " ",
builtin_to_glsl(builtin, StorageClassOutput),
semantic_index, " : SV_ClipDistance", semantic_index, ";");
}
break;
case BuiltInCullDistance:
// HLSL is a bit weird here, use SV_CullDistance0, SV_CullDistance1 and so on with vectors.
for (uint32_t cull = 0; cull < cull_distance_count; cull += 4)
{
uint32_t to_declare = cull_distance_count - cull;
if (to_declare > 4)
to_declare = 4;
uint32_t semantic_index = cull / 4;
static const char *types[] = { "float", "float2", "float3", "float4" };
statement(types[to_declare - 1], " ",
builtin_to_glsl(builtin, StorageClassOutput),
semantic_index, " : SV_CullDistance", semantic_index, ";");
}
break;
case BuiltInPointSize:
// If point_size_compat is enabled, just ignore PointSize.
// PointSize does not exist in HLSL, but some code bases might want to be able to use these shaders,
@ -598,6 +632,40 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
// Handled specially.
break;
case BuiltInClipDistance:
// HLSL is a bit weird here, use SV_ClipDistance0, SV_ClipDistance1 and so on with vectors.
for (uint32_t clip = 0; clip < clip_distance_count; clip += 4)
{
uint32_t to_declare = clip_distance_count - clip;
if (to_declare > 4)
to_declare = 4;
uint32_t semantic_index = clip / 4;
static const char *types[] = { "float", "float2", "float3", "float4" };
statement(types[to_declare - 1], " ",
builtin_to_glsl(builtin, StorageClassInput),
semantic_index, " : SV_ClipDistance", semantic_index, ";");
}
break;
case BuiltInCullDistance:
// HLSL is a bit weird here, use SV_CullDistance0, SV_CullDistance1 and so on with vectors.
for (uint32_t cull = 0; cull < cull_distance_count; cull += 4)
{
uint32_t to_declare = cull_distance_count - cull;
if (to_declare > 4)
to_declare = 4;
uint32_t semantic_index = cull / 4;
static const char *types[] = { "float", "float2", "float3", "float4" };
statement(types[to_declare - 1], " ",
builtin_to_glsl(builtin, StorageClassInput),
semantic_index, " : SV_CullDistance", semantic_index, ";");
}
break;
default:
SPIRV_CROSS_THROW("Unsupported builtin in HLSL.");
break;
@ -807,6 +875,7 @@ void CompilerHLSL::emit_builtin_variables()
const char *type = nullptr;
auto builtin = static_cast<BuiltIn>(i);
uint32_t array_size = 0;
switch (builtin)
{
@ -855,6 +924,16 @@ void CompilerHLSL::emit_builtin_variables()
// Handled specially.
break;
case BuiltInClipDistance:
array_size = clip_distance_count;
type = "float";
break;
case BuiltInCullDistance:
array_size = cull_distance_count;
type = "float";
break;
default:
SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin)));
break;
@ -865,7 +944,12 @@ void CompilerHLSL::emit_builtin_variables()
// need to distinguish that when we add support for that.
if (type)
statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
{
if (array_size)
statement("static ", type, " ", builtin_to_glsl(builtin, storage), "[", array_size, "];");
else
statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
}
}
}
@ -1843,7 +1927,16 @@ void CompilerHLSL::emit_hlsl_entry_point()
break;
case BuiltInNumWorkgroups:
// Handled specially.
break;
case BuiltInClipDistance:
for (uint32_t clip = 0; clip < clip_distance_count; clip++)
statement("gl_ClipDistance[", clip, "] = stage_input.gl_ClipDistance", clip / 4, ".", "xyzw"[clip & 3], ";");
break;
case BuiltInCullDistance:
for (uint32_t cull = 0; cull < clip_distance_count; cull++)
statement("gl_CullDistance[", cull, "] = stage_input.gl_CullDistance", cull / 4, ".", "xyzw"[cull & 3], ";");
break;
default:
@ -1938,8 +2031,25 @@ void CompilerHLSL::emit_hlsl_entry_point()
if (i == BuiltInPointSize)
continue;
auto builtin = builtin_to_glsl(static_cast<BuiltIn>(i), StorageClassOutput);
statement("stage_output.", builtin, " = ", builtin, ";");
switch (static_cast<BuiltIn>(i))
{
case BuiltInClipDistance:
for (uint32_t clip = 0; clip < clip_distance_count; clip++)
statement("stage_output.gl_ClipDistance", clip / 4, ".", "xyzw"[clip & 3], " = gl_ClipDistance[", clip, "];");
break;
case BuiltInCullDistance:
for (uint32_t cull = 0; cull < cull_distance_count; cull++)
statement("stage_output.gl_CullDistance", cull / 4, ".", "xyzw"[cull & 3], " = gl_CullDistance[", cull, "];");
break;
default:
{
auto builtin_expr = builtin_to_glsl(static_cast<BuiltIn>(i), StorageClassOutput);
statement("stage_output.", builtin_expr, " = ", builtin_expr, ";");
break;
}
}
}
for (auto &id : ids)