OP_NAME = 5,
OP_MEMBER_NAME = 6,
OP_ENTRY_POINT = 15,
+ OP_EXECUTION_MODE = 16,
OP_TYPE_VOID = 19,
OP_TYPE_BOOL = 20,
OP_TYPE_INT = 21,
OP_ACCESS_CHAIN = 65,
OP_DECORATE = 71,
OP_MEMBER_DECORATE = 72,
+ OP_COPY_OBJECT = 83,
+ OP_PHI = 245,
OP_SELECTION_MERGE = 247,
OP_LABEL = 248,
OP_BRANCH = 249,
OP_RETURN_VALUE = 254,
OP_UNREACHABLE = 255,
+ EXEC_LOCAL_SIZE = 17,
+
DECO_SPEC_ID = 1,
DECO_ARRAY_STRIDE = 6,
DECO_MATRIX_STRIDE = 7,
}
}
+ for(const EntryPoint &e: entry_points)
+ flags[e.id] = 0;
for(const Variable &v: variables)
flags[v.id] = 0;
for(const InstructionBlock &b: blocks)
unsigned start = new_code.size();
new_code.push_back(opcode);
new_code.push_back(*(op+1));
- new_code.push_back(*(op+2));
+ unsigned func_id = *(op+2);
+ new_code.push_back(func_id);
- unsigned i=3;
+ unsigned i = 3;
while(i<word_count)
{
unsigned word = *(op+i++);
new_code.push_back(word);
- if(!(word&(word>>8)&(word>>16)&(word>>24)&0xFF))
+ // Strings are nul-terminated and nul-padded
+ if(!(word>>24))
break;
}
+ unsigned var_count = 0;
for(; i<word_count; ++i)
{
unsigned id = *(op+i);
if(flags[id])
+ {
+ ++var_count;
new_code.push_back(id);
+ }
}
- new_code[start] |= (new_code.size()-start)<<16;
+ if(var_count)
+ {
+ flags[func_id] = 1;
+ new_code[start] |= (new_code.size()-start)<<16;
+ }
+ else
+ new_code.resize(start);
copy = false;
}
+ else if(opcode==OP_EXECUTION_MODE)
+ copy = flags[*(op+1)];
else if(opcode==OP_SPEC_CONSTANT_TRUE || opcode==OP_SPEC_CONSTANT_FALSE)
{
unsigned id = *(op+2);
}
}
}
+ else if(opcode==OP_PHI)
+ {
+ unsigned active_count = 0;
+ unsigned result_id = 0;
+ for(unsigned i=3; i<word_count; i+=2)
+ if(flags[*(op+i+1)])
+ {
+ ++active_count;
+ result_id = *(op+i);
+ }
+
+ if(active_count==1)
+ {
+ new_code.push_back(0x40000 | OP_COPY_OBJECT);
+ new_code.push_back(*(op+1));
+ new_code.push_back(*(op+2));
+ new_code.push_back(result_id);
+ copy = false;
+ }
+ }
}
if(copy)
case OP_NAME: reflect_name(op); break;
case OP_MEMBER_NAME: reflect_member_name(op); break;
case OP_ENTRY_POINT: reflect_entry_point(op); break;
+ case OP_EXECUTION_MODE: reflect_execution_mode(op); break;
case OP_TYPE_VOID: reflect_void_type(op); break;
case OP_TYPE_BOOL: reflect_bool_type(op); break;
case OP_TYPE_INT: reflect_int_type(op); break;
entry.globals.push_back(&variables[*op]);
}
+void SpirVModule::Reflection::reflect_execution_mode(CodeIterator op)
+{
+ EntryPoint &entry = entry_points[*(op+1)];
+ unsigned mode = *(op+2);
+ if(mode==EXEC_LOCAL_SIZE)
+ {
+ entry.compute_local_size.x = *(op+3);
+ entry.compute_local_size.y = *(op+4);
+ entry.compute_local_size.z = *(op+5);
+ }
+}
+
void SpirVModule::Reflection::reflect_void_type(CodeIterator op)
{
types[*(op+1)].type = VOID;
void SpirVModule::Reflection::reflect_image_type(CodeIterator op)
{
TypeInfo &type = types[*(op+1)];
- DataType sample = types[*(op+2)].type;
+ DataType sample_type = types[*(op+2)].type;
unsigned dimensions = *(op+3);
bool depth = *(op+4)==1;
bool array = *(op+5);
- type.type = static_cast<DataType>((depth*0x200000) | (array*0x80000) | ((dimensions+1)<<16) | sample);
+ bool sampled = *(op+7)==1;
+ type.type = static_cast<DataType>((depth*0x200000) | (sampled*0x100000) | (array*0x80000) |
+ ((dimensions+1)<<16) | sample_type);
}
void SpirVModule::Reflection::reflect_sampled_image_type(CodeIterator op)