Declare specialization constants in HLSL.
This commit is contained in:
parent
0d14448b4d
commit
98c76eed69
77
reference/shaders-hlsl/frag/spec-constant.frag
Normal file
77
reference/shaders-hlsl/frag/spec-constant.frag
Normal file
@ -0,0 +1,77 @@
|
||||
const float a = 1.0f;
|
||||
const float b = 2.0f;
|
||||
const int c = 3;
|
||||
const int d = 4;
|
||||
const uint e = 5u;
|
||||
const uint f = 6u;
|
||||
const bool g = false;
|
||||
const bool h = true;
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float elems[(d + 2)];
|
||||
};
|
||||
|
||||
static float4 FragColor;
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
float t0 = a;
|
||||
float t1 = b;
|
||||
uint c0 = (uint(c) + 0u);
|
||||
int c1 = (-c);
|
||||
int c2 = (~c);
|
||||
int c3 = (c + d);
|
||||
int c4 = (c - d);
|
||||
int c5 = (c * d);
|
||||
int c6 = (c / d);
|
||||
uint c7 = (e / f);
|
||||
int c8 = (c % d);
|
||||
uint c9 = (e % f);
|
||||
int c10 = (c >> d);
|
||||
uint c11 = (e >> f);
|
||||
int c12 = (c << d);
|
||||
int c13 = (c | d);
|
||||
int c14 = (c ^ d);
|
||||
int c15 = (c & d);
|
||||
bool c16 = (g || h);
|
||||
bool c17 = (g && h);
|
||||
bool c18 = (!g);
|
||||
bool c19 = (g == h);
|
||||
bool c20 = (g != h);
|
||||
bool c21 = (c == d);
|
||||
bool c22 = (c != d);
|
||||
bool c23 = (c < d);
|
||||
bool c24 = (e < f);
|
||||
bool c25 = (c > d);
|
||||
bool c26 = (e > f);
|
||||
bool c27 = (c <= d);
|
||||
bool c28 = (e <= f);
|
||||
bool c29 = (c >= d);
|
||||
bool c30 = (e >= f);
|
||||
int c31 = c8 + c3;
|
||||
int c32 = int(e + 0u);
|
||||
bool c33 = (c != int(0u));
|
||||
bool c34 = (e != 0u);
|
||||
int c35 = int(g);
|
||||
uint c36 = uint(g);
|
||||
float c37 = float(g);
|
||||
float _113 = t0 + t1;
|
||||
float vec0[(c + 3)][8];
|
||||
float vec1[(c + 2)];
|
||||
Foo foo;
|
||||
FragColor = ((float4(_113, _113, _113, _113) + float4(vec0[0][0], vec0[0][0], vec0[0][0], vec0[0][0])) + float4(vec1[0], vec1[0], vec1[0], vec1[0])) + float4(foo.elems[c], foo.elems[c], foo.elems[c], foo.elems[c]);
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main()
|
||||
{
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
77
shaders-hlsl/frag/spec-constant.frag
Normal file
77
shaders-hlsl/frag/spec-constant.frag
Normal file
@ -0,0 +1,77 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(constant_id = 1) const float a = 1.0;
|
||||
layout(constant_id = 2) const float b = 2.0;
|
||||
layout(constant_id = 3) const int c = 3;
|
||||
layout(constant_id = 4) const int d = 4;
|
||||
layout(constant_id = 5) const uint e = 5u;
|
||||
layout(constant_id = 6) const uint f = 6u;
|
||||
layout(constant_id = 7) const bool g = false;
|
||||
layout(constant_id = 8) const bool h = true;
|
||||
// glslang doesn't seem to support partial spec constants or composites yet, so only test the basics.
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float elems[d + 2];
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
float t0 = a;
|
||||
float t1 = b;
|
||||
|
||||
uint c0 = uint(c); // OpIAdd with different types.
|
||||
// FConvert, float-to-double.
|
||||
int c1 = -c; // SNegate
|
||||
int c2 = ~c; // OpNot
|
||||
int c3 = c + d; // OpIAdd
|
||||
int c4 = c - d; // OpISub
|
||||
int c5 = c * d; // OpIMul
|
||||
int c6 = c / d; // OpSDiv
|
||||
uint c7 = e / f; // OpUDiv
|
||||
int c8 = c % d; // OpSMod
|
||||
uint c9 = e % f; // OpUMod
|
||||
// TODO: OpSRem, any way to access this in GLSL?
|
||||
int c10 = c >> d; // OpShiftRightArithmetic
|
||||
uint c11 = e >> f; // OpShiftRightLogical
|
||||
int c12 = c << d; // OpShiftLeftLogical
|
||||
int c13 = c | d; // OpBitwiseOr
|
||||
int c14 = c ^ d; // OpBitwiseXor
|
||||
int c15 = c & d; // OpBitwiseAnd
|
||||
// VectorShuffle, CompositeExtract, CompositeInsert, not testable atm.
|
||||
bool c16 = g || h; // OpLogicalOr
|
||||
bool c17 = g && h; // OpLogicalAnd
|
||||
bool c18 = !g; // OpLogicalNot
|
||||
bool c19 = g == h; // OpLogicalEqual
|
||||
bool c20 = g != h; // OpLogicalNotEqual
|
||||
// OpSelect not testable atm.
|
||||
bool c21 = c == d; // OpIEqual
|
||||
bool c22 = c != d; // OpINotEqual
|
||||
bool c23 = c < d; // OpSLessThan
|
||||
bool c24 = e < f; // OpULessThan
|
||||
bool c25 = c > d; // OpSGreaterThan
|
||||
bool c26 = e > f; // OpUGreaterThan
|
||||
bool c27 = c <= d; // OpSLessThanEqual
|
||||
bool c28 = e <= f; // OpULessThanEqual
|
||||
bool c29 = c >= d; // OpSGreaterThanEqual
|
||||
bool c30 = e >= f; // OpUGreaterThanEqual
|
||||
// OpQuantizeToF16 not testable atm.
|
||||
|
||||
int c31 = c8 + c3;
|
||||
|
||||
int c32 = int(e); // OpIAdd with different types.
|
||||
bool c33 = bool(c); // int -> bool
|
||||
bool c34 = bool(e); // uint -> bool
|
||||
int c35 = int(g); // bool -> int
|
||||
uint c36 = uint(g); // bool -> uint
|
||||
float c37 = float(g); // bool -> float
|
||||
|
||||
// Flexible sized arrays with spec constants and spec constant ops.
|
||||
float vec0[c + 3][8];
|
||||
float vec1[c + 2];
|
||||
|
||||
Foo foo;
|
||||
FragColor = vec4(t0 + t1) + vec0[0][0] + vec1[0] + foo.elems[c];
|
||||
}
|
@ -583,10 +583,35 @@ void CompilerHLSL::emit_builtin_variables()
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_specialization_constants()
|
||||
{
|
||||
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);
|
||||
auto name = to_name(c.self);
|
||||
|
||||
statement("const ", variable_decl(type, name), " = ", constant_expression(c), ";");
|
||||
emitted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (emitted)
|
||||
statement("");
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_resources()
|
||||
{
|
||||
auto &execution = get_entry_point();
|
||||
|
||||
emit_specialization_constants();
|
||||
|
||||
// Output all basic struct types which are not Block or BufferBlock as these are declared inplace
|
||||
// when such variables are instantiated.
|
||||
for (auto &id : ids)
|
||||
|
@ -80,6 +80,7 @@ private:
|
||||
void emit_uniform(const SPIRVariable &var) override;
|
||||
void emit_modern_uniform(const SPIRVariable &var);
|
||||
void emit_legacy_uniform(const SPIRVariable &var);
|
||||
void emit_specialization_constants();
|
||||
std::string layout_for_member(const SPIRType &type, uint32_t index) override;
|
||||
std::string to_interpolation_qualifiers(uint64_t flags) override;
|
||||
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;
|
||||
|
Loading…
Reference in New Issue
Block a user