return BUILTIN_SAMPLE_POSITION;
else if(name=="gl_FragDepth")
return BUILTIN_FRAG_DEPTH;
+ else if(name=="gl_NumWorkGroups")
+ return BUILTIN_NUM_WORKGROUPS;
+ else if(name=="gl_WorkGroupSize")
+ return BUILTIN_WORKGROUP_SIZE;
+ else if(name=="gl_WorkGroupID")
+ return BUILTIN_WORKGROUP_ID;
+ else if(name=="gl_LocalInvocationID")
+ return BUILTIN_LOCAL_INVOCATION_ID;
+ else if(name=="gl_GlobalInvocationID")
+ return BUILTIN_GLOBAL_INVOCATION_ID;
+ else if(name=="gl_LocalInvocationIndex")
+ return BUILTIN_LOCAL_INVOCATION_INDEX;
else
throw invalid_argument("SpirVGenerator::get_builtin_semantic");
}
case Stage::VERTEX: writer.write(0); break;
case Stage::GEOMETRY: writer.write(3); break;
case Stage::FRAGMENT: writer.write(4); break;
+ case Stage::COMPUTE: writer.write(5); break;
default: throw internal_error("unknown stage");
}
writer.write(func_id);
writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_INVOCATIONS, 1);
}
+ unsigned local_size[3] = { 0, 1, 1 };
+
for(const InterfaceLayout *i: interface_layouts)
{
for(const Layout::Qualifier &q: i->layout.qualifiers)
writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_OUTPUT_TRIANGLE_STRIP);
else if(q.name=="max_vertices")
writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_OUTPUT_VERTICES, q.value);
+ else if(q.name=="local_size_x")
+ local_size[0] = q.value;
+ else if(q.name=="local_size_y")
+ local_size[1] = q.value;
+ else if(q.name=="local_size_z")
+ local_size[2] = q.value;
}
}
+
+ if(stage->type==Stage::COMPUTE && local_size[0])
+ {
+ writer.begin_op(content.exec_modes, OP_EXECUTION_MODE);
+ writer.write(func_id);
+ writer.write(EXEC_LOCAL_SIZE);
+ for(unsigned j=0; j<3; ++j)
+ writer.write(local_size[j]);
+ writer.end_op(OP_EXECUTION_MODE);
+ }
}
void SpirVGenerator::visit(FunctionDeclaration &func)