Merge pull request #426 from KhronosGroup/fix-425

Do not declare constant composites inline in HLSL.
This commit is contained in:
Hans-Kristian Arntzen 2018-02-02 10:35:41 +01:00 коммит произвёл GitHub
Родитель a1857a4d58 5d9df6a31c
Коммит d4b0625cbd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 302 добавлений и 4 удалений

Просмотреть файл

@ -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;