Merge pull request #426 from KhronosGroup/fix-425
Do not declare constant composites inline in HLSL.
This commit is contained in:
Коммит
d4b0625cbd
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче