Skip to content

Commit

Permalink
Fix a bunch of Metal things
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Oct 6, 2023
1 parent e46c8fb commit fe5efbf
Showing 1 changed file with 61 additions and 40 deletions.
101 changes: 61 additions & 40 deletions Sources/backends/metal.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,23 +287,6 @@ static void write_types(char *metal, size_t *offset) {

static int global_register_indices[512];

static void write_globals(char *metal, size_t *offset) {
for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) {
global g = get_global(i);
int register_index = global_register_indices[i];

if (g.type == sampler_type_id) {
*offset += sprintf(&metal[*offset], "SamplerState _%" PRIu64 " : register(s%i);\n\n", g.var_index, register_index);
}
else if (g.type == tex2d_type_id) {
*offset += sprintf(&metal[*offset], "Texture2D<float4> _%" PRIu64 " : register(t%i);\n\n", g.var_index, register_index);
}
else if (g.type == texcube_type_id) {
*offset += sprintf(&metal[*offset], "TextureCube<float4> _%" PRIu64 " : register(t%i);\n\n", g.var_index, register_index);
}
}
}

static function_id vertex_functions[256];
static size_t vertex_functions_size = 0;
static function_id fragment_functions[256];
Expand All @@ -327,7 +310,7 @@ static bool is_fragment_function(function_id f) {
return false;
}

static void write_functions(char *metal, size_t *offset) {
static void write_functions(char *code, size_t *offset) {
for (function_id i = 0; get_function(i) != NULL; ++i) {
function *f = get_function(i);

Expand Down Expand Up @@ -363,8 +346,10 @@ static void write_functions(char *metal, size_t *offset) {
int register_index = global_register_indices[globals[i]];

if (g.type == sampler_type_id) {
buffers_offset += sprintf(&buffers[buffers_offset], ", sampler<float> _%" PRIu64 " [[sampler(%i)]]", g.var_index, register_index);
}
else if (g.type == tex2d_type_id) {
buffers_offset += sprintf(&buffers[buffers_offset], ", texture2d<float> _%" PRIu64 " [[texture(%i)]]", g.var_index, register_index);
}
else if (g.type == texcube_type_id) {
}
Expand All @@ -378,26 +363,26 @@ static void write_functions(char *metal, size_t *offset) {
}

if (is_vertex_function(i)) {
*offset += sprintf(&metal[*offset], "vertex %s %s(%s _%" PRIu64 "%s) {\n", type_string(f->return_type.type), get_name(f->name),
*offset += sprintf(&code[*offset], "vertex %s %s(%s _%" PRIu64 " [[stage_in]]%s) {\n", type_string(f->return_type.type), get_name(f->name),
type_string(f->parameter_type.type), parameter_id, buffers);
}
else if (is_fragment_function(i)) {
if (f->return_type.array_size > 0) {
*offset += sprintf(&metal[*offset], "struct _render_targets {\n");
*offset += sprintf(&code[*offset], "struct _render_targets {\n");
for (uint32_t j = 0; j < f->return_type.array_size; ++j) {
*offset += sprintf(&metal[*offset], "\t%s _%i : SV_Target%i;\n", type_string(f->return_type.type), j, j);
*offset += sprintf(&code[*offset], "\t%s _%i : SV_Target%i;\n", type_string(f->return_type.type), j, j);
}
*offset += sprintf(&metal[*offset], "};\n\n");
*offset += sprintf(&metal[*offset], "_render_targets main(%s _%" PRIu64 ") {\n", type_string(f->parameter_type.type), parameter_id);
*offset += sprintf(&code[*offset], "};\n\n");
*offset += sprintf(&code[*offset], "_render_targets main(%s _%" PRIu64 ") {\n", type_string(f->parameter_type.type), parameter_id);
}
else {
*offset += sprintf(&metal[*offset], "fragment %s %s(%s _%" PRIu64 "%s) [[color(0)]] {\n", type_string(f->return_type.type), get_name(f->name),
*offset += sprintf(&code[*offset], "fragment ColorOut %s(%s _%" PRIu64 " [[stage_in]]%s) {\n", get_name(f->name),
type_string(f->parameter_type.type), parameter_id, buffers);
}
}

else {
*offset += sprintf(&metal[*offset], "%s %s(%s _%" PRIu64 ") {\n", type_string(f->return_type.type), get_name(f->name),
*offset += sprintf(&code[*offset], "%s %s(%s _%" PRIu64 ") {\n", type_string(f->return_type.type), get_name(f->name),
type_string(f->parameter_type.type), parameter_id);
}

Expand All @@ -415,50 +400,84 @@ static void write_functions(char *metal, size_t *offset) {
}
}

*offset += sprintf(&metal[*offset], "\t%s _%" PRIu64 " = _%" PRIu64, type_string(o->op_load_member.to.type.type), o->op_load_member.to.index,
*offset += sprintf(&code[*offset], "\t%s _%" PRIu64 " = _%" PRIu64, type_string(o->op_load_member.to.type.type), o->op_load_member.to.index,
o->op_load_member.from.index);
type *s = get_type(o->op_load_member.member_parent_type);
for (size_t i = 0; i < o->op_load_member.member_indices_size; ++i) {
*offset += sprintf(&metal[*offset], ".%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
*offset += sprintf(&code[*offset], ".%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
s = get_type(s->members.m[o->op_load_member.member_indices[i]].type.type);
}
*offset += sprintf(&metal[*offset], ";\n");
*offset += sprintf(&code[*offset], ";\n");
break;
}
case OPCODE_RETURN: {
if (o->size > offsetof(opcode, op_return)) {
if (is_fragment_function(i) && f->return_type.array_size > 0) {
*offset += sprintf(&metal[*offset], "\t{\n");
*offset += sprintf(&metal[*offset], "\t\t_render_targets rts;\n");
*offset += sprintf(&code[*offset], "\t{\n");
*offset += sprintf(&code[*offset], "\t\t_render_targets rts;\n");
for (uint32_t j = 0; j < f->return_type.array_size; ++j) {
*offset += sprintf(&metal[*offset], "\t\trts._%i = _%" PRIu64 "[%i];\n", j, o->op_return.var.index, j);
*offset += sprintf(&code[*offset], "\t\trts._%i = _%" PRIu64 "[%i];\n", j, o->op_return.var.index, j);
}
*offset += sprintf(&metal[*offset], "\t\treturn rts;\n");
*offset += sprintf(&metal[*offset], "\t}\n");
*offset += sprintf(&code[*offset], "\t\treturn rts;\n");
*offset += sprintf(&code[*offset], "\t}\n");
}
else if (is_fragment_function(i)) {
*offset += sprintf(&code[*offset], "\t{\n");
*offset += sprintf(&code[*offset], "\t\tColorOut out;\n");
*offset += sprintf(&code[*offset], "\t\tout.out = _%" PRIu64 ";\n", o->op_return.var.index);
*offset += sprintf(&code[*offset], "\t\treturn out;\n");
*offset += sprintf(&code[*offset], "\t}\n");
}
else {
*offset += sprintf(&metal[*offset], "\treturn _%" PRIu64 ";\n", o->op_return.var.index);
*offset += sprintf(&code[*offset], "\treturn _%" PRIu64 ";\n", o->op_return.var.index);
}
}
else {
*offset += sprintf(&metal[*offset], "\treturn;\n");
*offset += sprintf(&code[*offset], "\treturn;\n");
}
break;
}
case OPCODE_CALL: {
debug_context context = {0};
if (o->op_call.func == add_name("sample")) {
check(o->op_call.parameters_size == 3, context, "sample requires three parameters");
*offset +=
sprintf(&code[*offset], "\t%s _%" PRIu64 " = _%" PRIu64 ".sample(_%" PRIu64 ", _%" PRIu64 ");\n", type_string(o->op_call.var.type.type),
o->op_call.var.index, o->op_call.parameters[0].index, o->op_call.parameters[1].index, o->op_call.parameters[2].index);
}
else if (o->op_call.func == add_name("sample_lod")) {
check(o->op_call.parameters_size == 4, context, "sample_lod requires four parameters");
*offset += sprintf(&code[*offset], "\t%s _%" PRIu64 " = _%" PRIu64 ".sampleLevel(_%" PRIu64 ", _%" PRIu64 ", _%" PRIu64 ");\n",
type_string(o->op_call.var.type.type), o->op_call.var.index, o->op_call.parameters[0].index,
o->op_call.parameters[1].index, o->op_call.parameters[2].index, o->op_call.parameters[3].index);
}
else {
*offset += sprintf(&code[*offset], "\t%s _%" PRIu64 " = %s(", type_string(o->op_call.var.type.type), o->op_call.var.index,
function_string(o->op_call.func));
if (o->op_call.parameters_size > 0) {
*offset += sprintf(&code[*offset], "_%" PRIu64, o->op_call.parameters[0].index);
for (uint8_t i = 1; i < o->op_call.parameters_size; ++i) {
*offset += sprintf(&code[*offset], ", _%" PRIu64, o->op_call.parameters[i].index);
}
}
*offset += sprintf(&code[*offset], ");\n");
}
break;
}
case OPCODE_MULTIPLY: {
*offset += sprintf(&metal[*offset], "\t%s _%" PRIu64 " = _%" PRIu64 " * _%" PRIu64 ";\n", type_string(o->op_multiply.result.type.type),
*offset += sprintf(&code[*offset], "\t%s _%" PRIu64 " = _%" PRIu64 " * _%" PRIu64 ";\n", type_string(o->op_multiply.result.type.type),
o->op_multiply.result.index, o->op_multiply.left.index, o->op_multiply.right.index);
break;
}
default:
cstyle_write_opcode(metal, offset, o, type_string);
cstyle_write_opcode(code, offset, o, type_string);
break;
}

index += o->size;
}

*offset += sprintf(&metal[*offset], "}\n\n");
*offset += sprintf(&code[*offset], "}\n\n");
}
}

Expand All @@ -472,9 +491,11 @@ static void metal_export_everything(char *directory) {
offset += sprintf(&metal[offset], "#include <simd/simd.h>\n\n");
offset += sprintf(&metal[offset], "using namespace metal;\n\n");

write_types(metal, &offset);
offset += sprintf(&metal[offset], "struct ColorOut {\n");
offset += sprintf(&metal[offset], "\tfloat4 out [[color(0)]];\n");
offset += sprintf(&metal[offset], "};\n\n");

write_globals(metal, &offset);
write_types(metal, &offset);

write_functions(metal, &offset);

Expand Down

0 comments on commit fe5efbf

Please sign in to comment.