Overhaul clip/cull distance support in GLSL.
This commit is contained in:
Родитель
11bbccb54a
Коммит
fb3f92a3ff
|
@ -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
|
||||
|
||||
out float gl_ClipDistance[4];
|
||||
out float gl_CullDistance[3];
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(10.0);
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
gl_ClipDistance[1] = 4.0;
|
||||
gl_CullDistance[0] = 4.0;
|
||||
gl_CullDistance[1] = 9.0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
out float gl_ClipDistance[4];
|
||||
out float gl_CullDistance[3];
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(10.0);
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
gl_ClipDistance[1] = 4.0;
|
||||
gl_CullDistance[0] = 4.0;
|
||||
gl_CullDistance[1] = 9.0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
out float gl_ClipDistance[4];
|
||||
out float gl_CullDistance[3];
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(10.0);
|
||||
gl_ClipDistance[0] = 1.0;
|
||||
gl_ClipDistance[1] = 4.0;
|
||||
gl_CullDistance[0] = 4.0;
|
||||
gl_CullDistance[1] = 9.0;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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 =
|
||||
type.storage == StorageClassInput ? compiler.active_input_builtins : compiler.active_output_builtins;
|
||||
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];
|
||||
if (decorations.builtin)
|
||||
{
|
||||
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]);
|
||||
|
@ -3871,6 +3899,8 @@ void Compiler::update_active_builtins()
|
|||
{
|
||||
active_input_builtins = 0;
|
||||
active_output_builtins = 0;
|
||||
cull_distance_count = 0;
|
||||
clip_distance_count = 0;
|
||||
ActiveBuiltinHandler handler(*this);
|
||||
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;
|
||||
Compiler &compiler;
|
||||
|
||||
void handle_builtin(const SPIRType &type, spv::BuiltIn builtin);
|
||||
};
|
||||
|
||||
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_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.
|
||||
void update_active_builtins();
|
||||
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))
|
||||
statement("float gl_PointSize;");
|
||||
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))
|
||||
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;
|
||||
if (builtin_array)
|
||||
|
@ -1927,7 +1927,7 @@ void CompilerGLSL::emit_resources()
|
|||
emit_pls();
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
@ -1946,6 +1946,18 @@ void CompilerGLSL::emit_resources()
|
|||
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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче