Do not declare constant composites inline in HLSL.
Move arrays and structs out to their own global static constants. Also, replace illegal names in HLSL as well.
This commit is contained in:
Родитель
a1857a4d58
Коммит
5d9df6a31c
|
@ -0,0 +1,43 @@
|
|||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
|
||||
static const float _16[4] = { 1.0f, 4.0f, 3.0f, 2.0f };
|
||||
static const Foo _24 = { 10.0f, 20.0f };
|
||||
static const Foo _27 = { 30.0f, 40.0f };
|
||||
static const Foo _28[2] = { { 10.0f, 20.0f }, { 30.0f, 40.0f } };
|
||||
|
||||
static float4 FragColor;
|
||||
static int _line;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
nointerpolation int _line : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
static float lut[4];
|
||||
static Foo foos[2];
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
lut = _16;
|
||||
foos = _28;
|
||||
FragColor = lut[_line].xxxx;
|
||||
FragColor += (foos[_line].a * (foos[1 - _line].a)).xxxx;
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
_line = stage_input._line;
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
int line [[user(locn0)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float lut[4] = {1.0, 4.0, 3.0, 2.0};
|
||||
Foo foos[2] = {{10.0, 20.0}, {30.0, 40.0}};
|
||||
out.FragColor = float4(lut[in.line]);
|
||||
out.FragColor += float4(foos[in.line].a * (foos[1 - in.line].a));
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) flat in mediump int _line;
|
||||
float lut[4];
|
||||
Foo foos[2];
|
||||
|
||||
void main()
|
||||
{
|
||||
lut = float[](1.0, 4.0, 3.0, 2.0);
|
||||
foos = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0));
|
||||
FragColor = vec4(lut[_line]);
|
||||
FragColor += vec4(foos[_line].a * (foos[1 - _line].a));
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
|
||||
static const float _16[4] = { 1.0f, 4.0f, 3.0f, 2.0f };
|
||||
static const Foo _24 = { 10.0f, 20.0f };
|
||||
static const Foo _27 = { 30.0f, 40.0f };
|
||||
static const Foo _28[2] = { { 10.0f, 20.0f }, { 30.0f, 40.0f } };
|
||||
|
||||
static float4 FragColor;
|
||||
static int _line;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
nointerpolation int _line : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
static float lut[4];
|
||||
static Foo foos[2];
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
lut = _16;
|
||||
foos = _28;
|
||||
FragColor = lut[_line].xxxx;
|
||||
FragColor += (foos[_line].a * (foos[1 - _line].a)).xxxx;
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
_line = stage_input._line;
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
|
@ -4,6 +4,8 @@ struct B
|
|||
float b;
|
||||
};
|
||||
|
||||
static const B _80 = { 10.0f, 20.0f };
|
||||
|
||||
cbuffer _42 : register(b0)
|
||||
{
|
||||
int _42_some_value : packoffset(c0);
|
||||
|
@ -61,7 +63,7 @@ void frag_main()
|
|||
float4 param_3;
|
||||
branchy_inout_2(param_3);
|
||||
a = param_3;
|
||||
B b = { 10.0f, 20.0f };
|
||||
B b = _80;
|
||||
B param_4 = b;
|
||||
partial_inout(param_4);
|
||||
b = param_4;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
int line [[user(locn0)]];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float lut[4] = {1.0, 4.0, 3.0, 2.0};
|
||||
Foo foos[2] = {{10.0, 20.0}, {30.0, 40.0}};
|
||||
out.FragColor = float4(lut[in.line]);
|
||||
out.FragColor += float4(foos[in.line].a * (foos[1 - in.line].a));
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) flat in mediump int _line;
|
||||
float lut[4];
|
||||
Foo foos[2];
|
||||
|
||||
void main()
|
||||
{
|
||||
lut = float[](1.0, 4.0, 3.0, 2.0);
|
||||
foos = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0));
|
||||
FragColor = vec4(lut[_line]);
|
||||
FragColor += vec4(foos[_line].a * (foos[1 - _line].a));
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
float lut[4] = float[](1.0, 4.0, 3.0, 2.0);
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
Foo foos[2] = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0));
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) flat in int line;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(lut[line]);
|
||||
FragColor += foos[line].a * foos[1 - line].a;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
float lut[4] = float[](1.0, 4.0, 3.0, 2.0);
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
Foo foos[2] = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0));
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) flat in int line;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(lut[line]);
|
||||
FragColor += foos[line].a * foos[1 - line].a;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
float lut[4] = float[](1.0, 4.0, 3.0, 2.0);
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
};
|
||||
Foo foos[2] = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0));
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) flat in int line;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(lut[line]);
|
||||
FragColor += foos[line].a * foos[1 - line].a;
|
||||
}
|
|
@ -1634,10 +1634,10 @@ void CompilerGLSL::replace_illegal_names()
|
|||
"iimageCubeArray", "image1D", "image1DArray", "image2D", "image2DArray", "image2DMS", "image2DMSArray", "image2DRect",
|
||||
"image3D", "imageBuffer", "imageCube", "imageCubeArray", "in", "inline", "inout", "input", "int", "interface", "invariant",
|
||||
"isampler1D", "isampler1DArray", "isampler2D", "isampler2DArray", "isampler2DMS", "isampler2DMSArray", "isampler2DRect",
|
||||
"isampler3D", "isamplerBuffer", "isamplerCube", "isamplerCubeArray", "ivec2", "ivec3", "ivec4", "layout", "long", "lowp",
|
||||
"isampler3D", "isamplerBuffer", "isamplerCube", "isamplerCubeArray", "ivec2", "ivec3", "ivec4", "layout", "line", "linear", "long", "lowp",
|
||||
"mat2", "mat2x2", "mat2x3", "mat2x4", "mat3", "mat3x2", "mat3x3", "mat3x4", "mat4", "mat4x2", "mat4x3", "mat4x4", "mediump",
|
||||
"namespace", "noinline", "noperspective", "out", "output", "packed", "partition", "patch", "precision", "public", "readonly",
|
||||
"resource", "restrict", "return", "row_major", "sample", "sampler1D", "sampler1DArray", "sampler1DArrayShadow",
|
||||
"namespace", "noinline", "noperspective", "out", "output", "packed", "partition", "patch", "point", "precision", "public", "readonly",
|
||||
"resource", "restrict", "return", "row_major", "sample", "sampler", "sampler1D", "sampler1DArray", "sampler1DArrayShadow",
|
||||
"sampler1DShadow", "sampler2D", "sampler2DArray", "sampler2DArrayShadow", "sampler2DMS", "sampler2DMSArray",
|
||||
"sampler2DRect", "sampler2DRectShadow", "sampler2DShadow", "sampler3D", "sampler3DRect", "samplerBuffer",
|
||||
"samplerCube", "samplerCubeArray", "samplerCubeArrayShadow", "samplerCubeShadow", "short", "sizeof", "smooth", "static",
|
||||
|
@ -2256,6 +2256,7 @@ string CompilerGLSL::to_expression(uint32_t id)
|
|||
case TypeConstant:
|
||||
{
|
||||
auto &c = get<SPIRConstant>(id);
|
||||
auto &type = get<SPIRType>(c.constant_type);
|
||||
|
||||
// WorkGroupSize may be a constant.
|
||||
auto &dec = meta[c.self].decoration;
|
||||
|
@ -2263,6 +2264,10 @@ string CompilerGLSL::to_expression(uint32_t id)
|
|||
return builtin_to_glsl(dec.builtin_type, StorageClassGeneric);
|
||||
else if (c.specialization && options.vulkan_semantics)
|
||||
return to_name(id);
|
||||
else if (type.basetype == SPIRType::Struct && !backend.can_declare_struct_inline)
|
||||
return to_name(id);
|
||||
else if (!type.array.empty() && !backend.can_declare_arrays_inline)
|
||||
return to_name(id);
|
||||
else
|
||||
return constant_expression(c);
|
||||
}
|
||||
|
@ -5497,6 +5502,8 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||
|
||||
if (out_type.basetype == SPIRType::Struct && !backend.can_declare_struct_inline)
|
||||
forward = false;
|
||||
if (!out_type.array.empty() && !backend.can_declare_arrays_inline)
|
||||
forward = false;
|
||||
|
||||
string constructor_op;
|
||||
if (backend.use_initializer_list && composite)
|
||||
|
|
|
@ -323,6 +323,7 @@ protected:
|
|||
bool use_initializer_list = false;
|
||||
bool use_typed_initializer_list = false;
|
||||
bool can_declare_struct_inline = true;
|
||||
bool can_declare_arrays_inline = true;
|
||||
bool native_row_major_matrix = true;
|
||||
bool use_constructor_splatting = true;
|
||||
bool boolean_mix_support = true;
|
||||
|
|
|
@ -841,6 +841,34 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_composite_constants()
|
||||
{
|
||||
// HLSL cannot declare structs or arrays inline, so we must move them out to
|
||||
// global constants directly.
|
||||
bool emitted = false;
|
||||
|
||||
for (auto &id : ids)
|
||||
{
|
||||
if (id.get_type() == TypeConstant)
|
||||
{
|
||||
auto &c = id.get<SPIRConstant>();
|
||||
if (c.specialization)
|
||||
continue;
|
||||
|
||||
auto &type = get<SPIRType>(c.constant_type);
|
||||
if (type.basetype == SPIRType::Struct || !type.array.empty())
|
||||
{
|
||||
auto name = to_name(c.self);
|
||||
statement("static const ", variable_decl(type, name), " = ", constant_expression(c), ";");
|
||||
emitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (emitted)
|
||||
statement("");
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_specialization_constants()
|
||||
{
|
||||
bool emitted = false;
|
||||
|
@ -880,6 +908,8 @@ void CompilerHLSL::emit_resources()
|
|||
{
|
||||
auto &execution = get_entry_point();
|
||||
|
||||
replace_illegal_names();
|
||||
|
||||
emit_specialization_constants();
|
||||
|
||||
// Output all basic struct types which are not Block or BufferBlock as these are declared inplace
|
||||
|
@ -898,6 +928,8 @@ void CompilerHLSL::emit_resources()
|
|||
}
|
||||
}
|
||||
|
||||
emit_composite_constants();
|
||||
|
||||
bool emitted = false;
|
||||
|
||||
// Output UBOs and SSBOs
|
||||
|
@ -3648,6 +3680,7 @@ string CompilerHLSL::compile()
|
|||
backend.boolean_mix_support = false;
|
||||
backend.can_swizzle_scalar = true;
|
||||
backend.can_declare_struct_inline = false;
|
||||
backend.can_declare_arrays_inline = false;
|
||||
|
||||
update_active_builtins();
|
||||
analyze_sampler_comparison_states();
|
||||
|
|
|
@ -91,6 +91,7 @@ private:
|
|||
void emit_modern_uniform(const SPIRVariable &var);
|
||||
void emit_legacy_uniform(const SPIRVariable &var);
|
||||
void emit_specialization_constants();
|
||||
void emit_composite_constants();
|
||||
void emit_fixup() override;
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
||||
std::string layout_for_member(const SPIRType &type, uint32_t index) override;
|
||||
|
|
Загрузка…
Ссылка в новой задаче