Reflection reflection;
reflection.reflect_code(code);
+ map<const Constant *, unsigned> spec_indices;
+ for(map<unsigned, Constant>::const_iterator i=reflection.constants.begin(); i!=reflection.constants.end(); ++i)
+ if(i->second.constant_id>=0)
+ {
+ spec_indices[&i->second] = spec_constants.size();
+ spec_constants.push_back(i->second);
+ }
+
map<const Structure *, unsigned> struct_indices;
structs.reserve(reflection.structs.size());
for(map<unsigned, Structure>::const_iterator i=reflection.structs.begin(); i!=reflection.structs.end(); ++i)
map<const Structure *, unsigned>::const_iterator k = struct_indices.find(j->struct_type);
j->struct_type = (k!=struct_indices.end() ? &structs[k->second] : 0);
}
+ if(j->array_size_spec)
+ {
+ map<const Constant *, unsigned>::const_iterator k = spec_indices.find(j->array_size_spec);
+ j->array_size_spec = (k!=spec_indices.end() ? &spec_constants[k->second] : 0);
+ }
}
const StructMember *last_member = &i->members.back();
const StructMember *lm = &last_member->struct_type->members.back();
if(last_member->array_size)
last_offset += last_member->array_stride*(last_member->array_size-1);
+ else if(last_member->array_size_spec)
+ last_offset += last_member->array_stride*(last_member->array_size_spec->i_value-1);
last_offset += lm->offset;
last_member = lm;
}
}
for(vector<Variable>::iterator i=variables.begin(); i!=variables.end(); ++i)
+ {
if(i->struct_type)
{
map<const Structure *, unsigned>::const_iterator j = struct_indices.find(i->struct_type);
i->struct_type = (j!=struct_indices.end() ? &structs[j->second] : 0);
}
+ if(i->array_size_spec)
+ {
+ map<const Constant *, unsigned>::const_iterator j = spec_indices.find(i->array_size_spec);
+ i->array_size_spec = (j!=spec_indices.end() ? &spec_constants[j->second] : 0);
+ }
+ }
entry_points.reserve(reflection.entry_points.size());
for(map<unsigned, EntryPoint>::const_iterator i=reflection.entry_points.begin(); i!=reflection.entry_points.end(); ++i)
*j = (k!=var_indices.end() ? &variables[k->second] : 0);
}
}
-
- for(map<unsigned, Constant>::const_iterator i=reflection.constants.begin(); i!=reflection.constants.end(); ++i)
- if(i->second->constant_id>=0)
- spec_constants.push_back(i->second);
}
struct_type(0),
offset(0),
array_size(0),
+ array_size_spec(0),
array_stride(0),
matrix_stride(0)
{ }
SpirVModule::TypeInfo::TypeInfo():
type(VOID),
struct_type(0),
+ array_size_spec(0),
array_size(0),
array_stride(0),
storage(static_cast<StorageClass>(-1))
type.struct_type = elem.struct_type;
const Constant &size = constants[*(op+3)];
- if(size.type==INT || size.type==UNSIGNED_INT)
+ if(size.constant_id>=0)
+ type.array_size_spec = &size;
+ else if(size.type==INT || size.type==UNSIGNED_INT)
type.array_size = size.i_value;
}
mem->type = type.type;
mem->struct_type = type.struct_type;
mem->array_size = type.array_size;
+ mem->array_size_spec = type.array_size_spec;
mem->array_stride = type.array_stride;
}
}
var.type = type.type;
var.struct_type = type.struct_type;
var.array_size = type.array_size;
+ var.array_size_spec = type.array_size_spec;
}
void SpirVModule::Reflection::reflect_decorate(CodeIterator op)
const vector<UInt32> &code = mod.get_code();
glShaderBinary(stage_ids.size(), &stage_ids[0], GL_SHADER_BINARY_FORMAT_SPIR_V, &code[0], code.size()*4);
+ if(!spec_values.empty() && !transient)
+ transient = new TransientData;
+
const vector<SpirVModule::Constant> &spec_consts = mod.get_spec_constants();
vector<unsigned> spec_id_array;
vector<unsigned> spec_value_array;
{
spec_id_array.push_back(i->constant_id);
spec_value_array.push_back(j->second);
+ transient->spec_values[i->constant_id] = j->second;
}
}
glUniform1i(location, i->second);
}
}
-
- delete transient;
- transient = 0;
}
}
else if(module->get_format()==Module::SPIR_V)
collect_attributes();
}
+ delete transient;
+ transient = 0;
+
for(vector<UniformInfo>::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
require_type(i->type);
for(vector<AttributeInfo>::const_iterator i=attributes.begin(); i!=attributes.end(); ++i)
unsigned offset = base_offset+i->offset;
if(i->struct_type)
{
- if(i->array_size)
+ unsigned array_size = i->array_size;
+ if(i->array_size_spec)
+ {
+ array_size = i->array_size_spec->i_value;
+ if(transient)
+ {
+ map<unsigned, int>::const_iterator j = transient->spec_values.find(i->array_size_spec->constant_id);
+ if(j!=transient->spec_values.end())
+ array_size = j->second;
+ }
+ }
+
+ if(array_size)
{
- for(unsigned j=0; j<i->array_size; ++j, offset+=i->array_stride)
+ for(unsigned j=0; j<array_size; ++j, offset+=i->array_stride)
collect_block_uniforms(*i->struct_type, format("%s%s[%d].", prefix, i->name, j), offset, uniform_names);
}
else