GLSL/HLSL: Add legacy handling for int vertex attributes
This commit is contained in:
parent
49e4117c5f
commit
4ba13e0c1a
@ -0,0 +1,36 @@
|
||||
uniform float4 gl_HalfPixel;
|
||||
|
||||
static float4 gl_Position;
|
||||
static int4 attr_int4;
|
||||
static int attr_int1;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float4 attr_int4 : TEXCOORD0;
|
||||
float attr_int1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 gl_Position : POSITION;
|
||||
};
|
||||
|
||||
void vert_main()
|
||||
{
|
||||
gl_Position.x = float(attr_int4[attr_int1]);
|
||||
gl_Position.y = 0.0f;
|
||||
gl_Position.z = 0.0f;
|
||||
gl_Position.w = 0.0f;
|
||||
gl_Position.x = gl_Position.x - gl_HalfPixel.x * gl_Position.w;
|
||||
gl_Position.y = gl_Position.y + gl_HalfPixel.y * gl_Position.w;
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
attr_int4 = stage_input.attr_int4;
|
||||
attr_int1 = stage_input.attr_int1;
|
||||
vert_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.gl_Position = gl_Position;
|
||||
return stage_output;
|
||||
}
|
13
reference/opt/shaders/legacy/vert/int-attribute.legacy.vert
Normal file
13
reference/opt/shaders/legacy/vert/int-attribute.legacy.vert
Normal file
@ -0,0 +1,13 @@
|
||||
#version 100
|
||||
|
||||
attribute vec4 attr_int4;
|
||||
attribute float attr_int1;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position.x = float(int(attr_int4[int(attr_int1)]));
|
||||
gl_Position.y = 0.0;
|
||||
gl_Position.z = 0.0;
|
||||
gl_Position.w = 0.0;
|
||||
}
|
||||
|
36
reference/shaders-hlsl/vert/legacy-int-attribute.sm30.vert
Normal file
36
reference/shaders-hlsl/vert/legacy-int-attribute.sm30.vert
Normal file
@ -0,0 +1,36 @@
|
||||
uniform float4 gl_HalfPixel;
|
||||
|
||||
static float4 gl_Position;
|
||||
static int4 attr_int4;
|
||||
static int attr_int1;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float4 attr_int4 : TEXCOORD0;
|
||||
float attr_int1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 gl_Position : POSITION;
|
||||
};
|
||||
|
||||
void vert_main()
|
||||
{
|
||||
gl_Position.x = float(attr_int4[attr_int1]);
|
||||
gl_Position.y = 0.0f;
|
||||
gl_Position.z = 0.0f;
|
||||
gl_Position.w = 0.0f;
|
||||
gl_Position.x = gl_Position.x - gl_HalfPixel.x * gl_Position.w;
|
||||
gl_Position.y = gl_Position.y + gl_HalfPixel.y * gl_Position.w;
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
attr_int4 = stage_input.attr_int4;
|
||||
attr_int1 = stage_input.attr_int1;
|
||||
vert_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.gl_Position = gl_Position;
|
||||
return stage_output;
|
||||
}
|
13
reference/shaders/legacy/vert/int-attribute.legacy.vert
Normal file
13
reference/shaders/legacy/vert/int-attribute.legacy.vert
Normal file
@ -0,0 +1,13 @@
|
||||
#version 100
|
||||
|
||||
attribute vec4 attr_int4;
|
||||
attribute float attr_int1;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position.x = float(int(attr_int4[int(attr_int1)]));
|
||||
gl_Position.y = 0.0;
|
||||
gl_Position.z = 0.0;
|
||||
gl_Position.w = 0.0;
|
||||
}
|
||||
|
10
shaders-hlsl/vert/legacy-int-attribute.sm30.vert
Normal file
10
shaders-hlsl/vert/legacy-int-attribute.sm30.vert
Normal file
@ -0,0 +1,10 @@
|
||||
#version 310 es
|
||||
|
||||
layout(location=0) in ivec4 attr_int4;
|
||||
layout(location=1) in int attr_int1;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position.x = float(attr_int4[attr_int1]);
|
||||
gl_Position.yzw = vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
10
shaders/legacy/vert/int-attribute.legacy.vert
Normal file
10
shaders/legacy/vert/int-attribute.legacy.vert
Normal file
@ -0,0 +1,10 @@
|
||||
#version 310 es
|
||||
|
||||
layout(location=0) in ivec4 attr_int4;
|
||||
layout(location=1) in int attr_int1;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position.x = float(attr_int4[attr_int1]);
|
||||
gl_Position.yzw = vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
@ -2713,30 +2713,26 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
|
||||
{
|
||||
add_resource_name(var.self);
|
||||
|
||||
// Tessellation control and evaluation shaders must have either gl_MaxPatchVertices or unsized arrays for input arrays.
|
||||
// Legacy GLSL did not support int attributes, we automatically
|
||||
// declare them as float and cast them on load/store
|
||||
SPIRType newtype = type;
|
||||
if (is_legacy() && var.storage == StorageClassInput && type.basetype == SPIRType::Int)
|
||||
newtype.basetype = SPIRType::Float;
|
||||
|
||||
// Tessellation control and evaluation shaders must have either
|
||||
// gl_MaxPatchVertices or unsized arrays for input arrays.
|
||||
// Opt for unsized as it's the more "correct" variant to use.
|
||||
bool control_point_input_array = type.storage == StorageClassInput && !type.array.empty() &&
|
||||
if (type.storage == StorageClassInput && !type.array.empty() &&
|
||||
!has_decoration(var.self, DecorationPatch) &&
|
||||
(get_entry_point().model == ExecutionModelTessellationControl ||
|
||||
get_entry_point().model == ExecutionModelTessellationEvaluation);
|
||||
|
||||
uint32_t old_array_size = 0;
|
||||
bool old_array_size_literal = true;
|
||||
|
||||
if (control_point_input_array)
|
||||
get_entry_point().model == ExecutionModelTessellationEvaluation))
|
||||
{
|
||||
swap(type.array.back(), old_array_size);
|
||||
swap(type.array_size_literal.back(), old_array_size_literal);
|
||||
newtype.array.back() = 0;
|
||||
newtype.array_size_literal.back() = true;
|
||||
}
|
||||
|
||||
statement(layout_for_variable(var), to_qualifiers_glsl(var.self),
|
||||
variable_decl(type, to_name(var.self), var.self), ";");
|
||||
|
||||
if (control_point_input_array)
|
||||
{
|
||||
swap(type.array.back(), old_array_size);
|
||||
swap(type.array_size_literal.back(), old_array_size_literal);
|
||||
}
|
||||
variable_decl(newtype, to_name(var.self), var.self), ";");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16654,7 +16650,12 @@ void CompilerGLSL::cast_from_variable_load(uint32_t source_id, std::string &expr
|
||||
|
||||
// Only interested in standalone builtin variables.
|
||||
if (!has_decoration(source_id, DecorationBuiltIn))
|
||||
{
|
||||
// Except for int attributes in legacy GLSL, which are cast from float.
|
||||
if (is_legacy() && expr_type.basetype == SPIRType::Int && var && var->storage == StorageClassInput)
|
||||
expr = join(type_to_glsl(expr_type), "(", expr, ")");
|
||||
return;
|
||||
}
|
||||
|
||||
auto builtin = static_cast<BuiltIn>(get_decoration(source_id, DecorationBuiltIn));
|
||||
auto expected_type = expr_type.basetype;
|
||||
|
@ -1016,6 +1016,7 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
|
||||
|
||||
string binding;
|
||||
bool use_location_number = true;
|
||||
bool need_matrix_unroll = false;
|
||||
bool legacy = hlsl_options.shader_model <= 30;
|
||||
if (execution.model == ExecutionModelFragment && var.storage == StorageClassOutput)
|
||||
{
|
||||
@ -1031,6 +1032,12 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
|
||||
if (legacy) // COLOR must be a four-component vector on legacy shader model targets (HLSL ERR_COLOR_4COMP)
|
||||
type.vecsize = 4;
|
||||
}
|
||||
else if (var.storage == StorageClassInput && execution.model == ExecutionModelVertex)
|
||||
{
|
||||
need_matrix_unroll = true;
|
||||
if (legacy) // Inputs must be floating-point in legacy targets.
|
||||
type.basetype = SPIRType::Float;
|
||||
}
|
||||
|
||||
const auto get_vacant_location = [&]() -> uint32_t {
|
||||
for (uint32_t i = 0; i < 64; i++)
|
||||
@ -1039,8 +1046,6 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
|
||||
SPIRV_CROSS_THROW("All locations from 0 to 63 are exhausted.");
|
||||
};
|
||||
|
||||
bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex;
|
||||
|
||||
auto name = to_name(var.self);
|
||||
if (use_location_number)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user