Support OpConstantNull.

This commit is contained in:
Hans-Kristian Arntzen 2017-08-03 14:32:07 +02:00
parent 98b0c29f9d
commit 48ccde3779
6 changed files with 155 additions and 3 deletions

View File

@ -0,0 +1,22 @@
#version 310 es
precision mediump float;
precision highp int;
struct D
{
vec4 a;
float b;
};
layout(location = 0) out float FragColor;
void main()
{
float a = 0.0;
vec4 b = vec4(0.0);
mat2x3 c = mat2x3(vec3(0.0), vec3(0.0));
D d = D(vec4(0.0), 0.0);
vec4 e[4] = vec4[](vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0));
FragColor = a;
}

View File

@ -0,0 +1,85 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 1
; Bound: 45
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %FragColor
OpExecutionMode %main OriginUpperLeft
OpSource ESSL 310
OpName %main "main"
OpName %a "a"
OpName %b "b"
OpName %c "c"
OpName %D "D"
OpMemberName %D 0 "a"
OpMemberName %D 1 "b"
OpName %d "d"
OpName %e "e"
OpName %FragColor "FragColor"
OpDecorate %a RelaxedPrecision
OpDecorate %b RelaxedPrecision
OpDecorate %c RelaxedPrecision
OpMemberDecorate %D 0 RelaxedPrecision
OpMemberDecorate %D 1 RelaxedPrecision
OpDecorate %e RelaxedPrecision
OpDecorate %FragColor RelaxedPrecision
OpDecorate %FragColor Location 0
OpDecorate %44 RelaxedPrecision
OpDecorate %float_1 RelaxedPrecision
OpDecorate %14 RelaxedPrecision
OpDecorate %23 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Function_float = OpTypePointer Function %float
%float_1 = OpConstantNull %float
%v4float = OpTypeVector %float 4
%_ptr_Function_v4float = OpTypePointer Function %v4float
%float_2 = OpConstantNull %float
%14 = OpConstantNull %v4float
%v3float = OpTypeVector %float 3
%mat2v3float = OpTypeMatrix %v3float 2
%_ptr_Function_mat2v3float = OpTypePointer Function %mat2v3float
%float_4 = OpConstantNull %float
%20 = OpConstantNull %v3float
%float_5 = OpConstantNull %float
%22 = OpConstantNull %v3float
%23 = OpConstantNull %mat2v3float
%D = OpTypeStruct %v4float %float
%_ptr_Function_D = OpTypePointer Function %D
%27 = OpConstantNull %D
%uint = OpTypeInt 32 0
%uint_4 = OpConstant %uint 4
%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4
%_ptr_Function__arr_v4float_uint_4 = OpTypePointer Function %_arr_v4float_uint_4
%float_10 = OpConstantNull %float
%34 = OpConstantNull %v4float
%float_11 = OpConstantNull %float
%36 = OpConstantNull %v4float
%float_12 = OpConstantNull %float
%38 = OpConstantNull %v4float
%float_13 = OpConstantNull %float
%40 = OpConstantNull %v4float
%41 = OpConstantNull %_arr_v4float_uint_4
%_ptr_Output_float = OpTypePointer Output %float
%FragColor = OpVariable %_ptr_Output_float Output
%main = OpFunction %void None %3
%5 = OpLabel
%a = OpVariable %_ptr_Function_float Function
%b = OpVariable %_ptr_Function_v4float Function
%c = OpVariable %_ptr_Function_mat2v3float Function
%d = OpVariable %_ptr_Function_D Function
%e = OpVariable %_ptr_Function__arr_v4float_uint_4 Function
OpStore %a %float_1
OpStore %b %14
OpStore %c %23
OpStore %d %27
OpStore %e %41
%44 = OpLoad %float %a
OpStore %FragColor %44
OpReturn
OpFunctionEnd

View File

@ -729,10 +729,17 @@ struct SPIRConstant : IVariant
return m.columns;
}
inline void make_null(const SPIRType &constant_type_)
{
std::memset(&m, 0, sizeof(m));
m.columns = constant_type_.columns;
for (auto &c : m.c)
c.vecsize = constant_type_.vecsize;
}
SPIRConstant(uint32_t constant_type_)
: constant_type(constant_type_)
{
std::memset(&m, 0, sizeof(m));
}
SPIRConstant(uint32_t constant_type_, const uint32_t *elements, uint32_t num_elements)

View File

@ -1654,7 +1654,7 @@ void Compiler::parse(const Instruction &instruction)
{
uint32_t id = ops[1];
uint32_t type = ops[0];
set<SPIRConstant>(id, type);
make_constant_null(id, type);
break;
}
@ -3556,3 +3556,39 @@ bool Compiler::buffer_get_hlsl_counter_buffer(uint32_t id, uint32_t &counter_id)
}
return false;
}
void Compiler::make_constant_null(uint32_t id, uint32_t type)
{
auto &constant_type = get<SPIRType>(type);
if (!constant_type.array.empty())
{
assert(constant_type.parent_type);
uint32_t parent_id = increase_bound_by(1);
make_constant_null(parent_id, constant_type.parent_type);
if (!constant_type.array_size_literal.back())
SPIRV_CROSS_THROW("Array size of OpConstantNull must be a literal.");
vector<uint32_t> elements(constant_type.array.back());
for (uint32_t i = 0; i < constant_type.array.back(); i++)
elements[i] = parent_id;
set<SPIRConstant>(id, type, elements.data(), elements.size());
}
else if (!constant_type.member_types.empty())
{
uint32_t member_ids = increase_bound_by(constant_type.member_types.size());
vector<uint32_t> elements(constant_type.member_types.size());
for (uint32_t i = 0; i < constant_type.member_types.size(); i++)
{
make_constant_null(member_ids + i, constant_type.member_types[i]);
elements[i] = member_ids + i;
}
set<SPIRConstant>(id, type, elements.data(), elements.size());
}
else
{
auto &constant = set<SPIRConstant>(id, type);
constant.make_null(constant_type);
}
}

View File

@ -668,6 +668,8 @@ protected:
void add_hierarchy_to_comparison_samplers(uint32_t sampler);
};
void make_constant_null(uint32_t id, uint32_t type);
};
}

View File

@ -2140,7 +2140,7 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c)
if (subc.specialization && options.vulkan_semantics)
res += to_name(elem);
else
res += constant_expression(get<SPIRConstant>(elem));
res += constant_expression(subc);
if (&elem != &c.subconstants.back())
res += ", ";