Fix SpecConstantComposite if input is SpecConstantOp.

This commit is contained in:
Hans-Kristian Arntzen 2018-05-15 11:16:06 +02:00
Родитель c74dc4578a
Коммит 3951b9456f
8 изменённых файлов: 232 добавлений и 4 удалений

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

@ -0,0 +1,16 @@
#version 450
layout(location = 0) flat out int _4;
void main()
{
vec4 _64 = vec4(0.0);
_64.y = float(((-10) + 2));
vec4 _68 = _64;
_68.z = float((100u % 5u));
vec4 _52 = _68 + vec4(ivec4(20, 30, 0, 0));
vec2 _56 = _52.xy + vec2(ivec2(ivec4(20, 30, 0, 0).y, ivec4(20, 30, 0, 0).x));
gl_Position = vec4(_56.x, _56.y, _52.z, _52.w);
_4 = ivec4(20, 30, 0, 0).y;
}

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

@ -0,0 +1,20 @@
#version 450
layout(constant_id = 201) const int _7 = -10;
layout(constant_id = 202) const uint _8 = 100u;
const ivec4 _30 = ivec4(20, 30, 0, 0);
layout(location = 0) flat out int _4;
void main()
{
vec4 _64 = vec4(0.0);
_64.y = float((_7 + 2));
vec4 _68 = _64;
_68.z = float((_8 % 5u));
vec4 _52 = _68 + vec4(_30);
vec2 _56 = _52.xy + vec2(ivec2(_30.y, _30.x));
gl_Position = vec4(_56.x, _56.y, _52.z, _52.w);
_4 = _30.y;
}

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

@ -0,0 +1,16 @@
#version 450
layout(location = 0) flat out int _4;
void main()
{
vec4 pos = vec4(0.0);
pos.y += float(((-10) + 2));
pos.z += float((100u % 5u));
pos += vec4(ivec4(20, 30, 0, 0));
vec2 _56 = pos.xy + vec2(ivec2(ivec4(20, 30, 0, 0).y, ivec4(20, 30, 0, 0).x));
pos = vec4(_56.x, _56.y, pos.z, pos.w);
gl_Position = pos;
_4 = ivec4(20, 30, 0, 0).y;
}

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

@ -0,0 +1,21 @@
#version 450
layout(constant_id = 201) const int _7 = -10;
layout(constant_id = 202) const uint _8 = 100u;
layout(constant_id = 200) const float _9 = 3.141590118408203125;
const ivec4 _30 = ivec4(20, 30, 0, 0);
layout(location = 0) flat out int _4;
void main()
{
vec4 pos = vec4(0.0);
pos.y += float((_7 + 2));
pos.z += float((_8 % 5u));
pos += vec4(_30);
vec2 _56 = pos.xy + vec2(ivec2(_30.y, _30.x));
pos = vec4(_56.x, _56.y, pos.z, pos.w);
gl_Position = pos;
_4 = _30.y;
}

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

@ -0,0 +1,98 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 1
; Bound: 58
; Schema: 0
OpCapability Shader
OpCapability ClipDistance
OpCapability CullDistance
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %52 %output
OpSource GLSL 450
OpName %4 "main"
OpName %9 "pos"
OpName %50 "gl_PerVertex"
OpMemberName %50 0 "gl_Position"
OpMemberName %50 1 "gl_PointSize"
OpMemberName %50 2 "gl_ClipDistance"
OpMemberName %50 3 "gl_CullDistance"
OpName %52 ""
OpDecorate %13 SpecId 201
OpDecorate %24 SpecId 202
OpMemberDecorate %50 0 BuiltIn Position
OpMemberDecorate %50 1 BuiltIn PointSize
OpMemberDecorate %50 2 BuiltIn ClipDistance
OpMemberDecorate %50 3 BuiltIn CullDistance
OpDecorate %50 Block
OpDecorate %57 SpecId 200
OpDecorate %output Flat
OpDecorate %output Location 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypePointer Function %7
%10 = OpConstant %6 0
%11 = OpConstantComposite %7 %10 %10 %10 %10
%12 = OpTypeInt 32 1
%int_ptr = OpTypePointer Output %12
%13 = OpSpecConstant %12 -10
%14 = OpConstant %12 2
%15 = OpSpecConstantOp %12 IAdd %13 %14
%17 = OpTypeInt 32 0
%18 = OpConstant %17 1
%19 = OpTypePointer Function %6
%24 = OpSpecConstant %17 100
%25 = OpConstant %17 5
%26 = OpSpecConstantOp %17 UMod %24 %25
%28 = OpConstant %17 2
%33 = OpConstant %12 20
%34 = OpConstant %12 30
%35 = OpTypeVector %12 4
%36 = OpSpecConstantComposite %35 %33 %34 %15 %15
%40 = OpTypeVector %12 2
%41 = OpSpecConstantOp %40 VectorShuffle %36 %36 1 0
%foo = OpSpecConstantOp %12 CompositeExtract %36 1
%42 = OpTypeVector %6 2
%49 = OpTypeArray %6 %18
%50 = OpTypeStruct %7 %6 %49 %49
%51 = OpTypePointer Output %50
%52 = OpVariable %51 Output
%output = OpVariable %int_ptr Output
%53 = OpConstant %12 0
%55 = OpTypePointer Output %7
%57 = OpSpecConstant %6 3.14159
%4 = OpFunction %2 None %3
%5 = OpLabel
%9 = OpVariable %8 Function
OpStore %9 %11
%16 = OpConvertSToF %6 %15
%20 = OpAccessChain %19 %9 %18
%21 = OpLoad %6 %20
%22 = OpFAdd %6 %21 %16
%23 = OpAccessChain %19 %9 %18
OpStore %23 %22
%27 = OpConvertUToF %6 %26
%29 = OpAccessChain %19 %9 %28
%30 = OpLoad %6 %29
%31 = OpFAdd %6 %30 %27
%32 = OpAccessChain %19 %9 %28
OpStore %32 %31
%37 = OpConvertSToF %7 %36
%38 = OpLoad %7 %9
%39 = OpFAdd %7 %38 %37
OpStore %9 %39
%43 = OpConvertSToF %42 %41
%44 = OpLoad %7 %9
%45 = OpVectorShuffle %42 %44 %44 0 1
%46 = OpFAdd %42 %45 %43
%47 = OpLoad %7 %9
%48 = OpVectorShuffle %7 %47 %46 4 5 2 3
OpStore %9 %48
%54 = OpLoad %7 %9
%56 = OpAccessChain %55 %52 %53
OpStore %56 %54
OpStore %output %foo
OpReturn
OpFunctionEnd

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

@ -1017,6 +1017,8 @@ struct SPIRConstant : IVariant
{
}
SPIRConstant() = default;
SPIRConstant(uint32_t constant_type_, const uint32_t *elements, uint32_t num_elements, bool specialized)
: constant_type(constant_type_)
, specialization(specialized)
@ -1080,9 +1082,11 @@ struct SPIRConstant : IVariant
uint32_t constant_type;
ConstantMatrix m;
bool specialization = false; // If this constant is a specialization constant (i.e. created with OpSpecConstant*).
bool is_used_as_array_length =
false; // If this constant is used as an array length which creates specialization restrictions on some backends.
// If this constant is a specialization constant (i.e. created with OpSpecConstant*).
bool specialization = false;
// If this constant is used as an array length which creates specialization restrictions on some backends.
bool is_used_as_array_length = false;
// For composites which are constant arrays, etc.
std::vector<uint32_t> subconstants;

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

@ -2023,9 +2023,27 @@ void Compiler::parse(const Instruction &instruction)
if (elements > 4)
SPIRV_CROSS_THROW("OpConstantComposite only supports 1, 2, 3 and 4 elements.");
SPIRConstant remapped_constant_ops[4];
const SPIRConstant *c[4];
for (uint32_t i = 0; i < elements; i++)
c[i] = &get<SPIRConstant>(ops[2 + i]);
{
// Specialization constants operations can also be part of this.
// We do not know their value, so any attempt to query SPIRConstant later
// will fail. We can only propagate the ID of the expression and use to_expression on it.
auto *constant_op = maybe_get<SPIRConstantOp>(ops[2 + i]);
if (constant_op)
{
if (op == OpConstantComposite)
SPIRV_CROSS_THROW("Specialization constant operation used in OpConstantComposite.");
remapped_constant_ops[i].make_null(get<SPIRType>(constant_op->basetype));
remapped_constant_ops[i].self = constant_op->self;
remapped_constant_ops[i].constant_type = constant_op->basetype;
c[i] = &remapped_constant_ops[i];
}
else
c[i] = &get<SPIRConstant>(ops[2 + i]);
}
set<SPIRConstant>(id, type, c, elements, op == OpSpecConstantComposite);
}
break;

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

@ -2559,6 +2559,41 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
break;
}
case OpVectorShuffle:
{
string expr = type_to_glsl_constructor(type);
expr += "(";
uint32_t left_components = expression_type(cop.arguments[0]).vecsize;
string left_arg = to_enclosed_expression(cop.arguments[0]);
string right_arg = to_enclosed_expression(cop.arguments[1]);
for (uint32_t i = 2; i < uint32_t(cop.arguments.size()); i++)
{
uint32_t index = cop.arguments[i];
if (index >= left_components)
expr += right_arg + "." + "xyzw"[index - left_components];
else
expr += left_arg + "." + "xyzw"[index];
if (i + 1 < uint32_t(cop.arguments.size()))
expr += ", ";
}
expr += ")";
return expr;
}
case OpCompositeExtract:
{
auto expr = access_chain_internal(cop.arguments[0], &cop.arguments[1],
uint32_t(cop.arguments.size() - 1), true, false);
return expr;
}
case OpCompositeInsert:
SPIRV_CROSS_THROW("OpCompositeInsert spec constant op is not supported.");
default:
// Some opcodes are unimplemented here, these are currently not possible to test from glslang.
SPIRV_CROSS_THROW("Unimplemented spec constant op.");