Merge pull request #465 from KhronosGroup/fix-445
Overhaul Clip/CullDistance in GLSL and HLSL.
This commit is contained in:
commit
3f64f56037
30
reference/opt/shaders-hlsl/frag/clip-cull-distance.frag
Normal file
30
reference/opt/shaders-hlsl/frag/clip-cull-distance.frag
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
static float gl_ClipDistance[2];
|
||||||
|
static float gl_CullDistance[1];
|
||||||
|
static float FragColor;
|
||||||
|
|
||||||
|
struct SPIRV_Cross_Input
|
||||||
|
{
|
||||||
|
float2 gl_ClipDistance0 : SV_ClipDistance0;
|
||||||
|
float 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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
frag_main();
|
||||||
|
SPIRV_Cross_Output stage_output;
|
||||||
|
stage_output.FragColor = FragColor;
|
||||||
|
return stage_output;
|
||||||
|
}
|
28
reference/opt/shaders-hlsl/vert/clip-cull-distance.vert
Normal file
28
reference/opt/shaders-hlsl/vert/clip-cull-distance.vert
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
static float4 gl_Position;
|
||||||
|
static float gl_ClipDistance[2];
|
||||||
|
static float gl_CullDistance[1];
|
||||||
|
struct SPIRV_Cross_Output
|
||||||
|
{
|
||||||
|
float4 gl_Position : SV_Position;
|
||||||
|
float2 gl_ClipDistance0 : SV_ClipDistance0;
|
||||||
|
float 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
return stage_output;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
in float gl_ClipDistance[4];
|
||||||
|
in float gl_CullDistance[3];
|
||||||
|
|
||||||
|
layout(location = 0) out float FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = gl_ClipDistance[0] + gl_CullDistance[0];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
out gl_PerVertex
|
||||||
|
{
|
||||||
|
vec4 gl_Position;
|
||||||
|
float gl_PointSize;
|
||||||
|
float gl_ClipDistance[4];
|
||||||
|
float gl_CullDistance[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(1.0);
|
||||||
|
gl_ClipDistance[0] = 0.0;
|
||||||
|
gl_ClipDistance[1] = 0.0;
|
||||||
|
gl_ClipDistance[2] = 0.0;
|
||||||
|
gl_ClipDistance[3] = 0.0;
|
||||||
|
gl_CullDistance[1] = 4.0;
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,15 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
out float gl_ClipDistance[4];
|
||||||
|
out float gl_CullDistance[3];
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4(10.0);
|
gl_Position = vec4(1.0);
|
||||||
gl_ClipDistance[0] = 1.0;
|
gl_ClipDistance[0] = 0.0;
|
||||||
gl_ClipDistance[1] = 4.0;
|
gl_ClipDistance[1] = 0.0;
|
||||||
gl_CullDistance[0] = 4.0;
|
gl_ClipDistance[2] = 0.0;
|
||||||
gl_CullDistance[1] = 9.0;
|
gl_ClipDistance[3] = 0.0;
|
||||||
|
gl_CullDistance[1] = 4.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
reference/shaders-hlsl/frag/clip-cull-distance.frag
Normal file
30
reference/shaders-hlsl/frag/clip-cull-distance.frag
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
static float gl_ClipDistance[2];
|
||||||
|
static float gl_CullDistance[1];
|
||||||
|
static float FragColor;
|
||||||
|
|
||||||
|
struct SPIRV_Cross_Input
|
||||||
|
{
|
||||||
|
float2 gl_ClipDistance0 : SV_ClipDistance0;
|
||||||
|
float 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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
frag_main();
|
||||||
|
SPIRV_Cross_Output stage_output;
|
||||||
|
stage_output.FragColor = FragColor;
|
||||||
|
return stage_output;
|
||||||
|
}
|
28
reference/shaders-hlsl/vert/clip-cull-distance.vert
Normal file
28
reference/shaders-hlsl/vert/clip-cull-distance.vert
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
static float4 gl_Position;
|
||||||
|
static float gl_ClipDistance[2];
|
||||||
|
static float gl_CullDistance[1];
|
||||||
|
struct SPIRV_Cross_Output
|
||||||
|
{
|
||||||
|
float4 gl_Position : SV_Position;
|
||||||
|
float2 gl_ClipDistance0 : SV_ClipDistance0;
|
||||||
|
float 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
return stage_output;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
in float gl_ClipDistance[4];
|
||||||
|
in float gl_CullDistance[3];
|
||||||
|
|
||||||
|
layout(location = 0) out float FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = gl_ClipDistance[0] + gl_CullDistance[0];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
out gl_PerVertex
|
||||||
|
{
|
||||||
|
vec4 gl_Position;
|
||||||
|
float gl_PointSize;
|
||||||
|
float gl_ClipDistance[4];
|
||||||
|
float gl_CullDistance[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(1.0);
|
||||||
|
gl_ClipDistance[0] = 0.0;
|
||||||
|
gl_ClipDistance[1] = 0.0;
|
||||||
|
gl_ClipDistance[2] = 0.0;
|
||||||
|
gl_ClipDistance[3] = 0.0;
|
||||||
|
gl_CullDistance[1] = 4.0;
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,15 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
out float gl_ClipDistance[4];
|
||||||
|
out float gl_CullDistance[3];
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4(10.0);
|
gl_Position = vec4(1.0);
|
||||||
gl_ClipDistance[0] = 1.0;
|
gl_ClipDistance[0] = 0.0;
|
||||||
gl_ClipDistance[1] = 4.0;
|
gl_ClipDistance[1] = 0.0;
|
||||||
gl_CullDistance[0] = 4.0;
|
gl_ClipDistance[2] = 0.0;
|
||||||
gl_CullDistance[1] = 9.0;
|
gl_ClipDistance[3] = 0.0;
|
||||||
|
gl_CullDistance[1] = 4.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
shaders-hlsl/frag/clip-cull-distance.frag
Normal file
12
shaders-hlsl/frag/clip-cull-distance.frag
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
in float gl_ClipDistance[2];
|
||||||
|
in float gl_CullDistance[1];
|
||||||
|
|
||||||
|
layout(location = 0) out float FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = gl_ClipDistance[0] + gl_CullDistance[0] + gl_ClipDistance[1];
|
||||||
|
}
|
||||||
|
|
11
shaders-hlsl/vert/clip-cull-distance.vert
Normal file
11
shaders-hlsl/vert/clip-cull-distance.vert
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#version 450
|
||||||
|
out float gl_ClipDistance[2];
|
||||||
|
out float gl_CullDistance[1];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(1.0);
|
||||||
|
gl_ClipDistance[0] = 0.0;
|
||||||
|
gl_ClipDistance[1] = 0.0;
|
||||||
|
gl_CullDistance[0] = 4.0;
|
||||||
|
}
|
12
shaders/desktop-only/frag/clip-cull-distance.desktop.frag
Normal file
12
shaders/desktop-only/frag/clip-cull-distance.desktop.frag
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
in float gl_ClipDistance[4];
|
||||||
|
in float gl_CullDistance[3];
|
||||||
|
|
||||||
|
layout(location = 0) out float FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = gl_ClipDistance[0] + gl_CullDistance[0];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
#version 450
|
||||||
|
out float gl_ClipDistance[4];
|
||||||
|
out float gl_CullDistance[3];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(1.0);
|
||||||
|
gl_ClipDistance[0] = 0.0;
|
||||||
|
gl_ClipDistance[1] = 0.0;
|
||||||
|
gl_ClipDistance[2] = 0.0;
|
||||||
|
gl_ClipDistance[3] = 0.0;
|
||||||
|
gl_CullDistance[1] = 4.0;
|
||||||
|
}
|
@ -1,10 +1,13 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
out float gl_ClipDistance[4];
|
||||||
|
out float gl_CullDistance[3];
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4(10.0);
|
gl_Position = vec4(1.0);
|
||||||
gl_ClipDistance[0] = 1.0;
|
gl_ClipDistance[0] = 0.0;
|
||||||
gl_ClipDistance[1] = 4.0;
|
gl_ClipDistance[1] = 0.0;
|
||||||
gl_CullDistance[0] = 4.0;
|
gl_ClipDistance[2] = 0.0;
|
||||||
gl_CullDistance[1] = 9.0;
|
gl_ClipDistance[3] = 0.0;
|
||||||
|
gl_CullDistance[1] = 4.0;
|
||||||
}
|
}
|
||||||
|
@ -3749,6 +3749,30 @@ bool Compiler::get_common_basic_type(const SPIRType &type, SPIRType::BaseType &b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Compiler::ActiveBuiltinHandler::handle_builtin(const SPIRType &type, BuiltIn builtin)
|
||||||
|
{
|
||||||
|
// If used, we will need to explicitly declare a new array size for these builtins.
|
||||||
|
|
||||||
|
if (builtin == BuiltInClipDistance)
|
||||||
|
{
|
||||||
|
if (!type.array_size_literal[0])
|
||||||
|
SPIRV_CROSS_THROW("Array size for ClipDistance must be a literal.");
|
||||||
|
uint32_t array_size = type.array[0];
|
||||||
|
if (array_size == 0)
|
||||||
|
SPIRV_CROSS_THROW("Array size for ClipDistance must not be unsized.");
|
||||||
|
compiler.clip_distance_count = array_size;
|
||||||
|
}
|
||||||
|
else if (builtin == BuiltInCullDistance)
|
||||||
|
{
|
||||||
|
if (!type.array_size_literal[0])
|
||||||
|
SPIRV_CROSS_THROW("Array size for CullDistance must be a literal.");
|
||||||
|
uint32_t array_size = type.array[0];
|
||||||
|
if (array_size == 0)
|
||||||
|
SPIRV_CROSS_THROW("Array size for CullDistance must not be unsized.");
|
||||||
|
compiler.cull_distance_count = array_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
|
bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
|
||||||
{
|
{
|
||||||
const auto add_if_builtin = [&](uint32_t id) {
|
const auto add_if_builtin = [&](uint32_t id) {
|
||||||
@ -3761,6 +3785,7 @@ bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args
|
|||||||
auto &flags =
|
auto &flags =
|
||||||
type.storage == StorageClassInput ? compiler.active_input_builtins : compiler.active_output_builtins;
|
type.storage == StorageClassInput ? compiler.active_input_builtins : compiler.active_output_builtins;
|
||||||
flags |= 1ull << compiler.meta[id].decoration.builtin_type;
|
flags |= 1ull << compiler.meta[id].decoration.builtin_type;
|
||||||
|
handle_builtin(type, compiler.meta[id].decoration.builtin_type);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3846,7 +3871,10 @@ bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args
|
|||||||
{
|
{
|
||||||
auto &decorations = compiler.meta[type->self].members[index];
|
auto &decorations = compiler.meta[type->self].members[index];
|
||||||
if (decorations.builtin)
|
if (decorations.builtin)
|
||||||
|
{
|
||||||
flags |= 1ull << decorations.builtin_type;
|
flags |= 1ull << decorations.builtin_type;
|
||||||
|
handle_builtin(compiler.get<SPIRType>(type->member_types[index]), decorations.builtin_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type = &compiler.get<SPIRType>(type->member_types[index]);
|
type = &compiler.get<SPIRType>(type->member_types[index]);
|
||||||
@ -3871,6 +3899,8 @@ void Compiler::update_active_builtins()
|
|||||||
{
|
{
|
||||||
active_input_builtins = 0;
|
active_input_builtins = 0;
|
||||||
active_output_builtins = 0;
|
active_output_builtins = 0;
|
||||||
|
cull_distance_count = 0;
|
||||||
|
clip_distance_count = 0;
|
||||||
ActiveBuiltinHandler handler(*this);
|
ActiveBuiltinHandler handler(*this);
|
||||||
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
|
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
|
||||||
}
|
}
|
||||||
|
@ -715,6 +715,8 @@ protected:
|
|||||||
|
|
||||||
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
|
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
|
||||||
Compiler &compiler;
|
Compiler &compiler;
|
||||||
|
|
||||||
|
void handle_builtin(const SPIRType &type, spv::BuiltIn builtin);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHandler &handler) const;
|
bool traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHandler &handler) const;
|
||||||
@ -735,6 +737,9 @@ protected:
|
|||||||
|
|
||||||
uint64_t active_input_builtins = 0;
|
uint64_t active_input_builtins = 0;
|
||||||
uint64_t active_output_builtins = 0;
|
uint64_t active_output_builtins = 0;
|
||||||
|
uint32_t clip_distance_count = 0;
|
||||||
|
uint32_t cull_distance_count = 0;
|
||||||
|
|
||||||
// Traverses all reachable opcodes and sets active_builtins to a bitmask of all builtin variables which are accessed in the shader.
|
// Traverses all reachable opcodes and sets active_builtins to a bitmask of all builtin variables which are accessed in the shader.
|
||||||
void update_active_builtins();
|
void update_active_builtins();
|
||||||
bool has_active_builtin(spv::BuiltIn builtin, spv::StorageClass storage);
|
bool has_active_builtin(spv::BuiltIn builtin, spv::StorageClass storage);
|
||||||
|
@ -1871,9 +1871,9 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo
|
|||||||
if (emitted_builtins & (1ull << BuiltInPointSize))
|
if (emitted_builtins & (1ull << BuiltInPointSize))
|
||||||
statement("float gl_PointSize;");
|
statement("float gl_PointSize;");
|
||||||
if (emitted_builtins & (1ull << BuiltInClipDistance))
|
if (emitted_builtins & (1ull << BuiltInClipDistance))
|
||||||
statement("float gl_ClipDistance[];"); // TODO: Do we need a fixed array size here?
|
statement("float gl_ClipDistance[", clip_distance_count, "];");
|
||||||
if (emitted_builtins & (1ull << BuiltInCullDistance))
|
if (emitted_builtins & (1ull << BuiltInCullDistance))
|
||||||
statement("float gl_CullDistance[];"); // TODO: Do we need a fixed array size here?
|
statement("float gl_CullDistance[", cull_distance_count, "];");
|
||||||
|
|
||||||
bool tessellation = model == ExecutionModelTessellationEvaluation || model == ExecutionModelTessellationControl;
|
bool tessellation = model == ExecutionModelTessellationEvaluation || model == ExecutionModelTessellationControl;
|
||||||
if (builtin_array)
|
if (builtin_array)
|
||||||
@ -1927,7 +1927,7 @@ void CompilerGLSL::emit_resources()
|
|||||||
emit_pls();
|
emit_pls();
|
||||||
|
|
||||||
// Emit custom gl_PerVertex for SSO compatibility.
|
// Emit custom gl_PerVertex for SSO compatibility.
|
||||||
if (options.separate_shader_objects && !options.es)
|
if (options.separate_shader_objects && !options.es && execution.model != ExecutionModelFragment)
|
||||||
{
|
{
|
||||||
switch (execution.model)
|
switch (execution.model)
|
||||||
{
|
{
|
||||||
@ -1946,6 +1946,18 @@ void CompilerGLSL::emit_resources()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Need to redeclare clip/cull distance with explicit size to use them.
|
||||||
|
// SPIR-V mandates these builtins have a size declared.
|
||||||
|
const char *storage = execution.model == ExecutionModelFragment ? "in" : "out";
|
||||||
|
if (clip_distance_count != 0)
|
||||||
|
statement(storage, " float gl_ClipDistance[", clip_distance_count, "];");
|
||||||
|
if (cull_distance_count != 0)
|
||||||
|
statement(storage, " float gl_CullDistance[", cull_distance_count, "];");
|
||||||
|
if (clip_distance_count != 0 || cull_distance_count != 0)
|
||||||
|
statement("");
|
||||||
|
}
|
||||||
|
|
||||||
bool emitted = false;
|
bool emitted = false;
|
||||||
|
|
||||||
|
116
spirv_hlsl.cpp
116
spirv_hlsl.cpp
@ -509,6 +509,40 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
|
|||||||
semantic = legacy ? "DEPTH" : "SV_Depth";
|
semantic = legacy ? "DEPTH" : "SV_Depth";
|
||||||
break;
|
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:
|
case BuiltInPointSize:
|
||||||
// If point_size_compat is enabled, just ignore PointSize.
|
// 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,
|
// 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.
|
// Handled specially.
|
||||||
break;
|
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:
|
default:
|
||||||
SPIRV_CROSS_THROW("Unsupported builtin in HLSL.");
|
SPIRV_CROSS_THROW("Unsupported builtin in HLSL.");
|
||||||
break;
|
break;
|
||||||
@ -807,6 +875,7 @@ void CompilerHLSL::emit_builtin_variables()
|
|||||||
|
|
||||||
const char *type = nullptr;
|
const char *type = nullptr;
|
||||||
auto builtin = static_cast<BuiltIn>(i);
|
auto builtin = static_cast<BuiltIn>(i);
|
||||||
|
uint32_t array_size = 0;
|
||||||
|
|
||||||
switch (builtin)
|
switch (builtin)
|
||||||
{
|
{
|
||||||
@ -855,6 +924,16 @@ void CompilerHLSL::emit_builtin_variables()
|
|||||||
// Handled specially.
|
// Handled specially.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BuiltInClipDistance:
|
||||||
|
array_size = clip_distance_count;
|
||||||
|
type = "float";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BuiltInCullDistance:
|
||||||
|
array_size = cull_distance_count;
|
||||||
|
type = "float";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin)));
|
SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin)));
|
||||||
break;
|
break;
|
||||||
@ -865,8 +944,13 @@ void CompilerHLSL::emit_builtin_variables()
|
|||||||
// need to distinguish that when we add support for that.
|
// need to distinguish that when we add support for that.
|
||||||
|
|
||||||
if (type)
|
if (type)
|
||||||
|
{
|
||||||
|
if (array_size)
|
||||||
|
statement("static ", type, " ", builtin_to_glsl(builtin, storage), "[", array_size, "];");
|
||||||
|
else
|
||||||
statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
|
statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerHLSL::emit_composite_constants()
|
void CompilerHLSL::emit_composite_constants()
|
||||||
@ -1843,7 +1927,16 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BuiltInNumWorkgroups:
|
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 < cull_distance_count; cull++)
|
||||||
|
statement("gl_CullDistance[", cull, "] = stage_input.gl_CullDistance", cull / 4, ".", "xyzw"[cull & 3], ";");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1938,8 +2031,25 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
|||||||
if (i == BuiltInPointSize)
|
if (i == BuiltInPointSize)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto builtin = builtin_to_glsl(static_cast<BuiltIn>(i), StorageClassOutput);
|
switch (static_cast<BuiltIn>(i))
|
||||||
statement("stage_output.", builtin, " = ", builtin, ";");
|
{
|
||||||
|
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)
|
for (auto &id : ids)
|
||||||
|
Loading…
Reference in New Issue
Block a user