From 5cdf1c402f35de292e823950f9b847307e6e5416 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Tue, 6 Aug 2024 13:51:33 +0200 Subject: [PATCH] Output the structs in SPIR-V --- Sources/backends/hlsl.c | 96 +-------------------------------------- Sources/backends/spirv.c | 33 ++++++++++++-- Sources/backends/util.c | 98 ++++++++++++++++++++++++++++++++++++++++ Sources/backends/util.h | 8 ++++ 4 files changed, 137 insertions(+), 98 deletions(-) create mode 100644 Sources/backends/util.c create mode 100644 Sources/backends/util.h diff --git a/Sources/backends/hlsl.c b/Sources/backends/hlsl.c index c09f952..644c9d2 100644 --- a/Sources/backends/hlsl.c +++ b/Sources/backends/hlsl.c @@ -10,6 +10,7 @@ #include "d3d11.h" #include "d3d12.h" #include "d3d9.h" +#include "util.h" #include #include @@ -105,101 +106,6 @@ static void write_bytecode(char *hlsl, char *directory, const char *filename, co } } -static void find_referenced_functions(function *f, function **functions, size_t *functions_size) { - if (f->block == NULL) { - // built-in - return; - } - - uint8_t *data = f->code.o; - size_t size = f->code.size; - - size_t index = 0; - while (index < size) { - opcode *o = (opcode *)&data[index]; - switch (o->type) { - case OPCODE_CALL: { - for (function_id i = 0; get_function(i) != NULL; ++i) { - function *f = get_function(i); - if (f->name == o->op_call.func) { - if (f->block == NULL) { - // built-in - break; - } - - bool found = false; - for (size_t j = 0; j < *functions_size; ++j) { - if (functions[j]->name == o->op_call.func) { - found = true; - break; - } - } - if (!found) { - functions[*functions_size] = f; - *functions_size += 1; - find_referenced_functions(f, functions, functions_size); - } - break; - } - } - break; - } - } - - index += o->size; - } -} - -static void add_found_type(type_id t, type_id *types, size_t *types_size) { - for (size_t i = 0; i < *types_size; ++i) { - if (types[i] == t) { - return; - } - } - - types[*types_size] = t; - *types_size += 1; -} - -static void find_referenced_types(function *f, type_id *types, size_t *types_size) { - if (f->block == NULL) { - // built-in - return; - } - - function *functions[256]; - size_t functions_size = 0; - - functions[functions_size] = f; - functions_size += 1; - - find_referenced_functions(f, functions, &functions_size); - - for (size_t l = 0; l < functions_size; ++l) { - function *func = functions[l]; - debug_context context = {0}; - check(func->parameter_type.type != NO_TYPE, context, "Parameter type missing"); - add_found_type(func->parameter_type.type, types, types_size); - check(func->return_type.type != NO_TYPE, context, "Return type missing"); - add_found_type(func->return_type.type, types, types_size); - - uint8_t *data = functions[l]->code.o; - size_t size = functions[l]->code.size; - - size_t index = 0; - while (index < size) { - opcode *o = (opcode *)&data[index]; - switch (o->type) { - case OPCODE_VAR: - add_found_type(o->op_var.var.type.type, types, types_size); - break; - } - - index += o->size; - } - } -} - static void find_referenced_global_for_var(variable v, global_id *globals, size_t *globals_size) { for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { global g = get_global(j); diff --git a/Sources/backends/spirv.c b/Sources/backends/spirv.c index 1c470f9..e37f625 100644 --- a/Sources/backends/spirv.c +++ b/Sources/backends/spirv.c @@ -9,6 +9,8 @@ #include "../libs/stb_ds.h" +#include "util.h" + #include #include #include @@ -496,7 +498,32 @@ static void write_base_types(instructions_buffer *constants, type_id vertex_inpu float_input_pointer_type = write_type_pointer(constants, STORAGE_CLASS_INPUT, spirv_float_type); } -static void write_types(instructions_buffer *constants) { +static void write_types(instructions_buffer *constants, function *main) { + type_id types[256]; + size_t types_size = 0; + find_referenced_types(main, types, &types_size); + + for (size_t i = 0; i < types_size; ++i) { + type *t = get_type(types[i]); + + if (!t->built_in && t->attribute != add_name("pipe")) { + spirv_id member_types[256]; + uint16_t member_types_size = 0; + for (size_t j = 0; j < t->members.size; ++j) { + member_types[member_types_size] = convert_type_to_spirv_id(t->members.m[j].type.type); + member_types_size += 1; + assert(member_types_size < 256); + } + spirv_id struct_type = write_type_struct(constants, member_types, member_types_size); + + complex_type ct; + ct.type = types[i]; + ct.pointer = (uint16_t) false; + ct.storage = (uint16_t)STORAGE_CLASS_NONE; + hmput(type_map, ct, struct_type); + } + } + size_t size = hmlenu(type_map); for (size_t i = 0; i < size; ++i) { complex_type type = type_map[i].key; @@ -1014,7 +1041,7 @@ static void spirv_export_vertex(char *directory, function *main) { write_functions(&instructions, main, entry_point, SHADER_STAGE_VERTEX, vertex_input, input_var, vertex_output, output_var); - write_types(&constants); + write_types(&constants, main); // header write_magic_number(&header); @@ -1081,7 +1108,7 @@ static void spirv_export_fragment(char *directory, function *main) { write_functions(&instructions, main, entry_point, SHADER_STAGE_FRAGMENT, pixel_input, input_var, NO_TYPE, output_var); - write_types(&constants); + write_types(&constants, main); // header write_magic_number(&header); diff --git a/Sources/backends/util.c b/Sources/backends/util.c new file mode 100644 index 0000000..35dcb94 --- /dev/null +++ b/Sources/backends/util.c @@ -0,0 +1,98 @@ +#include "util.h" + +#include "../errors.h" + +void find_referenced_functions(function *f, function **functions, size_t *functions_size) { + if (f->block == NULL) { + // built-in + return; + } + + uint8_t *data = f->code.o; + size_t size = f->code.size; + + size_t index = 0; + while (index < size) { + opcode *o = (opcode *)&data[index]; + switch (o->type) { + case OPCODE_CALL: { + for (function_id i = 0; get_function(i) != NULL; ++i) { + function *f = get_function(i); + if (f->name == o->op_call.func) { + if (f->block == NULL) { + // built-in + break; + } + + bool found = false; + for (size_t j = 0; j < *functions_size; ++j) { + if (functions[j]->name == o->op_call.func) { + found = true; + break; + } + } + if (!found) { + functions[*functions_size] = f; + *functions_size += 1; + find_referenced_functions(f, functions, functions_size); + } + break; + } + } + break; + } + } + + index += o->size; + } +} + +static void add_found_type(type_id t, type_id *types, size_t *types_size) { + for (size_t i = 0; i < *types_size; ++i) { + if (types[i] == t) { + return; + } + } + + types[*types_size] = t; + *types_size += 1; +} + +void find_referenced_types(function *f, type_id *types, size_t *types_size) { + if (f->block == NULL) { + // built-in + return; + } + + function *functions[256]; + size_t functions_size = 0; + + functions[functions_size] = f; + functions_size += 1; + + find_referenced_functions(f, functions, &functions_size); + + for (size_t l = 0; l < functions_size; ++l) { + function *func = functions[l]; + debug_context context = {0}; + check(func->parameter_type.type != NO_TYPE, context, "Parameter type missing"); + add_found_type(func->parameter_type.type, types, types_size); + check(func->return_type.type != NO_TYPE, context, "Return type missing"); + add_found_type(func->return_type.type, types, types_size); + + uint8_t *data = functions[l]->code.o; + size_t size = functions[l]->code.size; + + size_t index = 0; + while (index < size) { + opcode *o = (opcode *)&data[index]; + switch (o->type) { + case OPCODE_VAR: + add_found_type(o->op_var.var.type.type, types, types_size); + break; + } + + index += o->size; + } + } +} \ No newline at end of file diff --git a/Sources/backends/util.h b/Sources/backends/util.h new file mode 100644 index 0000000..8cb1c04 --- /dev/null +++ b/Sources/backends/util.h @@ -0,0 +1,8 @@ +#pragma once + +#include "../functions.h" + +#include + +void find_referenced_functions(function *f, function **functions, size_t *functions_size); +void find_referenced_types(function *f, type_id *types, size_t *types_size);