diff --git a/Sources/backends/glsl.c b/Sources/backends/glsl.c index 970c066..6d571db 100644 --- a/Sources/backends/glsl.c +++ b/Sources/backends/glsl.c @@ -144,25 +144,25 @@ static void write_globals(char *glsl, size_t *offset, function *main) { find_referenced_globals(main, globals, &globals_size); for (size_t i = 0; i < globals_size; ++i) { - global g = get_global(globals[i]); + global *g = get_global(globals[i]); int register_index = global_register_indices[globals[i]]; - if (g.type == sampler_type_id) { + if (g->type == sampler_type_id) { } - else if (g.type == tex2d_type_id) { - *offset += sprintf(&glsl[*offset], "uniform sampler2D _%" PRIu64 ";\n\n", g.var_index); + else if (g->type == tex2d_type_id) { + *offset += sprintf(&glsl[*offset], "uniform sampler2D _%" PRIu64 ";\n\n", g->var_index); } - else if (g.type == texcube_type_id) { - *offset += sprintf(&glsl[*offset], "uniform samplerCube _%" PRIu64 ";\n\n", g.var_index); + else if (g->type == texcube_type_id) { + *offset += sprintf(&glsl[*offset], "uniform samplerCube _%" PRIu64 ";\n\n", g->var_index); } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { - *offset += sprintf(&glsl[*offset], "layout(std140) uniform _%" PRIu64 " {\n", g.var_index); - type *t = get_type(g.type); + *offset += sprintf(&glsl[*offset], "layout(std140) uniform _%" PRIu64 " {\n", g->var_index); + type *t = get_type(g->type); for (size_t i = 0; i < t->members.size; ++i) { *offset += - sprintf(&glsl[*offset], "\t%s _%" PRIu64 "_%s;\n", type_string(t->members.m[i].type.type), g.var_index, get_name(t->members.m[i].name)); + sprintf(&glsl[*offset], "\t%s _%" PRIu64 "_%s;\n", type_string(t->members.m[i].type.type), g->var_index, get_name(t->members.m[i].name)); } *offset += sprintf(&glsl[*offset], "};\n\n"); } @@ -311,10 +311,10 @@ static void write_functions(char *code, size_t *offset, shader_stage stage, type } case OPCODE_LOAD_MEMBER: { uint64_t global_var_index = 0; - for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { - global g = get_global(j); - if (o->op_load_member.from.index == g.var_index) { - global_var_index = g.var_index; + for (global_id j = 0; get_global(j)->type != NO_TYPE; ++j) { + global *g = get_global(j); + if (o->op_load_member.from.index == g->var_index) { + global_var_index = g->var_index; break; } } @@ -518,17 +518,17 @@ void glsl_export(char *directory) { memset(global_register_indices, 0, sizeof(global_register_indices)); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = sampler_index; sampler_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { global_register_indices[i] = texture_index; texture_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = cbuffer_index; diff --git a/Sources/backends/hlsl.c b/Sources/backends/hlsl.c index 7c03006..e0b3e97 100644 --- a/Sources/backends/hlsl.c +++ b/Sources/backends/hlsl.c @@ -4,6 +4,7 @@ #include "../errors.h" #include "../functions.h" #include "../parser.h" +#include "../sets.h" #include "../shader_stage.h" #include "../types.h" #include "cstyle.h" @@ -190,47 +191,47 @@ static void write_globals(char *hlsl, size_t *offset, function *main, function * } for (size_t i = 0; i < globals_size; ++i) { - global g = get_global(globals[i]); + global *g = get_global(globals[i]); int register_index = global_register_indices[globals[i]]; - if (g.type == sampler_type_id) { - *offset += sprintf(&hlsl[*offset], "SamplerState _%" PRIu64 " : register(s%i);\n\n", g.var_index, register_index); + if (g->type == sampler_type_id) { + *offset += sprintf(&hlsl[*offset], "SamplerState _%" PRIu64 " : register(s%i);\n\n", g->var_index, register_index); } - else if (g.type == tex2d_type_id) { - if (has_attribute(&g.attributes, add_name("write"))) { - *offset += sprintf(&hlsl[*offset], "RWTexture2D _%" PRIu64 " : register(u%i);\n\n", g.var_index, register_index); + else if (g->type == tex2d_type_id) { + if (has_attribute(&g->attributes, add_name("write"))) { + *offset += sprintf(&hlsl[*offset], "RWTexture2D _%" PRIu64 " : register(u%i);\n\n", g->var_index, register_index); } else { - *offset += sprintf(&hlsl[*offset], "Texture2D _%" PRIu64 " : register(t%i);\n\n", g.var_index, register_index); + *offset += sprintf(&hlsl[*offset], "Texture2D _%" PRIu64 " : register(t%i);\n\n", g->var_index, register_index); } } - else if (g.type == texcube_type_id) { - *offset += sprintf(&hlsl[*offset], "TextureCube _%" PRIu64 " : register(t%i);\n\n", g.var_index, register_index); + else if (g->type == texcube_type_id) { + *offset += sprintf(&hlsl[*offset], "TextureCube _%" PRIu64 " : register(t%i);\n\n", g->var_index, register_index); } - else if (g.type == bvh_type_id) { - *offset += sprintf(&hlsl[*offset], "RaytracingAccelerationStructure _%" PRIu64 " : register(t%i);\n\n", g.var_index, register_index); + else if (g->type == bvh_type_id) { + *offset += sprintf(&hlsl[*offset], "RaytracingAccelerationStructure _%" PRIu64 " : register(t%i);\n\n", g->var_index, register_index); } - else if (g.type == float_id) { - *offset += sprintf(&hlsl[*offset], "static const float _%" PRIu64 " = %f;\n\n", g.var_index, g.value.value.floats[0]); + else if (g->type == float_id) { + *offset += sprintf(&hlsl[*offset], "static const float _%" PRIu64 " = %f;\n\n", g->var_index, g->value.value.floats[0]); } - else if (g.type == float2_id) { - *offset += sprintf(&hlsl[*offset], "static const float2 _%" PRIu64 " = float2(%f, %f);\n\n", g.var_index, g.value.value.floats[0], - g.value.value.floats[1]); + else if (g->type == float2_id) { + *offset += sprintf(&hlsl[*offset], "static const float2 _%" PRIu64 " = float2(%f, %f);\n\n", g->var_index, g->value.value.floats[0], + g->value.value.floats[1]); } - else if (g.type == float3_id) { - *offset += sprintf(&hlsl[*offset], "static const float3 _%" PRIu64 " = float3(%f, %f, %f);\n\n", g.var_index, g.value.value.floats[0], - g.value.value.floats[1], g.value.value.floats[2]); + else if (g->type == float3_id) { + *offset += sprintf(&hlsl[*offset], "static const float3 _%" PRIu64 " = float3(%f, %f, %f);\n\n", g->var_index, g->value.value.floats[0], + g->value.value.floats[1], g->value.value.floats[2]); } - else if (g.type == float4_id) { - *offset += sprintf(&hlsl[*offset], "static const float4 _%" PRIu64 " = float4(%f, %f, %f, %f);\n\n", g.var_index, g.value.value.floats[0], - g.value.value.floats[1], g.value.value.floats[2], g.value.value.floats[3]); + else if (g->type == float4_id) { + *offset += sprintf(&hlsl[*offset], "static const float4 _%" PRIu64 " = float4(%f, %f, %f, %f);\n\n", g->var_index, g->value.value.floats[0], + g->value.value.floats[1], g->value.value.floats[2], g->value.value.floats[3]); } else { - *offset += sprintf(&hlsl[*offset], "cbuffer _%" PRIu64 " : register(b%i) {\n", g.var_index, register_index); - type *t = get_type(g.type); + *offset += sprintf(&hlsl[*offset], "cbuffer _%" PRIu64 " : register(b%i) {\n", g->var_index, register_index); + type *t = get_type(g->type); for (size_t i = 0; i < t->members.size; ++i) { *offset += - sprintf(&hlsl[*offset], "\t%s _%" PRIu64 "_%s;\n", type_string(t->members.m[i].type.type), g.var_index, get_name(t->members.m[i].name)); + sprintf(&hlsl[*offset], "\t%s _%" PRIu64 "_%s;\n", type_string(t->members.m[i].type.type), g->var_index, get_name(t->members.m[i].name)); } *offset += sprintf(&hlsl[*offset], "}\n\n"); } @@ -601,11 +602,11 @@ static void write_functions(char *hlsl, size_t *offset, shader_stage stage, func switch (o->type) { case OPCODE_LOAD_MEMBER: { uint64_t global_var_index = 0; - for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { - global g = get_global(j); - if (o->op_load_member.from.index == g.var_index) { - global_var_index = g.var_index; - if (get_type(g.type)->built_in) { + for (global_id j = 0; get_global(j) != NULL && get_global(j)->type != NO_TYPE; ++j) { + global *g = get_global(j); + if (o->op_load_member.from.index == g->var_index) { + global_var_index = g->var_index; + if (get_type(g->type)->built_in) { global_var_index = 0; } break; @@ -1028,14 +1029,14 @@ void hlsl_export(char *directory, api_kind d3d) { memset(global_register_indices, 0, sizeof(global_register_indices)); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i) != NULL && get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = sampler_index; sampler_index += 1; } - else if (g.type == tex2d_type_id) { - if (has_attribute(&g.attributes, add_name("write"))) { + else if (g->type == tex2d_type_id) { + if (has_attribute(&g->attributes, add_name("write"))) { global_register_indices[i] = uav_index; uav_index += 1; } @@ -1044,11 +1045,11 @@ void hlsl_export(char *directory, api_kind d3d) { srv_index += 1; } } - else if (g.type == texcube_type_id || g.type == bvh_type_id) { + else if (g->type == texcube_type_id || g->type == bvh_type_id) { global_register_indices[i] = srv_index; srv_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = cbv_index; diff --git a/Sources/backends/metal.c b/Sources/backends/metal.c index 33b3001..3ba6eb6 100644 --- a/Sources/backends/metal.c +++ b/Sources/backends/metal.c @@ -80,10 +80,10 @@ static void write_types(char *metal, size_t *offset) { char name[256]; bool found = false; - for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { - global g = get_global(j); - if (g.type == i) { - sprintf(name, "_%" PRIu64, g.var_index); + for (global_id j = 0; get_global(j)->type != NO_TYPE; ++j) { + global *g = get_global(j); + if (g->type == i) { + sprintf(name, "_%" PRIu64, g->var_index); found = true; break; } @@ -187,22 +187,22 @@ static void write_functions(char *code, size_t *offset) { size_t buffers_offset = 0; for (size_t i = 0; i < globals_size; ++i) { - global g = get_global(globals[i]); + global *g = get_global(globals[i]); int register_index = global_register_indices[globals[i]]; - if (g.type == sampler_type_id) { - buffers_offset += sprintf(&buffers[buffers_offset], ", sampler _%" PRIu64 " [[sampler(%i)]]", g.var_index, register_index); + if (g->type == sampler_type_id) { + buffers_offset += sprintf(&buffers[buffers_offset], ", sampler _%" PRIu64 " [[sampler(%i)]]", g->var_index, register_index); } - else if (g.type == tex2d_type_id) { - buffers_offset += sprintf(&buffers[buffers_offset], ", texture2d _%" PRIu64 " [[texture(%i)]]", g.var_index, register_index); + else if (g->type == tex2d_type_id) { + buffers_offset += sprintf(&buffers[buffers_offset], ", texture2d _%" PRIu64 " [[texture(%i)]]", g->var_index, register_index); } - else if (g.type == texcube_type_id) { - buffers_offset += sprintf(&buffers[buffers_offset], ", texturecube _%" PRIu64 " [[texture(%i)]]", g.var_index, register_index); + else if (g->type == texcube_type_id) { + buffers_offset += sprintf(&buffers[buffers_offset], ", texturecube _%" PRIu64 " [[texture(%i)]]", g->var_index, register_index); } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { - buffers_offset += sprintf(&buffers[buffers_offset], ", constant _%" PRIu64 "_type& _%" PRIu64 " [[buffer(%i)]]", g.var_index, g.var_index, + buffers_offset += sprintf(&buffers[buffers_offset], ", constant _%" PRIu64 "_type& _%" PRIu64 " [[buffer(%i)]]", g->var_index, g->var_index, register_index); } } @@ -262,10 +262,10 @@ static void write_functions(char *code, size_t *offset) { switch (o->type) { case OPCODE_LOAD_MEMBER: { uint64_t global_var_index = 0; - for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { - global g = get_global(j); - if (o->op_load_member.from.index == g.var_index) { - global_var_index = g.var_index; + for (global_id j = 0; get_global(j)->type != NO_TYPE; ++j) { + global *g = get_global(j); + if (o->op_load_member.from.index == g->var_index) { + global_var_index = g->var_index; break; } } @@ -390,17 +390,17 @@ void metal_export(char *directory) { memset(global_register_indices, 0, sizeof(global_register_indices)); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = sampler_index; sampler_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { global_register_indices[i] = texture_index; texture_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = cbuffer_index; diff --git a/Sources/backends/util.c b/Sources/backends/util.c index aec1c9a..9713904 100644 --- a/Sources/backends/util.c +++ b/Sources/backends/util.c @@ -13,9 +13,9 @@ void indent(char *code, size_t *offset, int indentation) { } 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); - if (v.index == g.var_index) { + for (global_id j = 0; get_global(j) != NULL && get_global(j)->type != NO_TYPE; ++j) { + global *g = get_global(j); + if (v.index == g->var_index) { bool found = false; for (size_t k = 0; k < *globals_size; ++k) { if (globals[k] == j) { diff --git a/Sources/backends/wgsl.c b/Sources/backends/wgsl.c index ed3d114..b80d420 100644 --- a/Sources/backends/wgsl.c +++ b/Sources/backends/wgsl.c @@ -122,10 +122,10 @@ static void write_types(char *wgsl, size_t *offset) { char name[256]; bool found = false; - for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { - global g = get_global(j); - if (g.type == i) { - sprintf(name, "_%" PRIu64, g.var_index); + for (global_id j = 0; get_global(j)->type != NO_TYPE; ++j) { + global *g = get_global(j); + if (g->type == i) { + sprintf(name, "_%" PRIu64, g->var_index); found = true; break; } @@ -171,31 +171,31 @@ static void write_types(char *wgsl, size_t *offset) { static int global_register_indices[512]; static void write_globals(char *wgsl, size_t *offset) { - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); + 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(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": sampler;\n\n", register_index, g.var_index); + if (g->type == sampler_type_id) { + *offset += sprintf(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": sampler;\n\n", register_index, g->var_index); } - else if (g.type == tex2d_type_id) { - *offset += sprintf(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": texture_2d;\n\n", register_index, g.var_index); + else if (g->type == tex2d_type_id) { + *offset += sprintf(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": texture_2d;\n\n", register_index, g->var_index); } - else if (g.type == texcube_type_id) { - *offset += sprintf(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": texture_cube;\n\n", register_index, g.var_index); + else if (g->type == texcube_type_id) { + *offset += sprintf(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": texture_cube;\n\n", register_index, g->var_index); } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { - type *t = get_type(g.type); + type *t = get_type(g->type); char type_name[256]; if (t->name != NO_NAME) { strcpy(type_name, get_name(t->name)); } else { - sprintf(type_name, "_%" PRIu64 "_type", g.var_index); + sprintf(type_name, "_%" PRIu64 "_type", g->var_index); } - *offset += sprintf(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": %s;\n\n", register_index, g.var_index, type_name); + *offset += sprintf(&wgsl[*offset], "@group(0) @binding(%i) var _%" PRIu64 ": %s;\n\n", register_index, g->var_index, type_name); } } } @@ -331,10 +331,10 @@ static void write_functions(char *code, size_t *offset) { break; case OPCODE_LOAD_MEMBER: { uint64_t global_var_index = 0; - for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { - global g = get_global(j); - if (o->op_load_member.from.index == g.var_index) { - global_var_index = g.var_index; + for (global_id j = 0; get_global(j)->type != NO_TYPE; ++j) { + global *g = get_global(j); + if (o->op_load_member.from.index == g->var_index) { + global_var_index = g->var_index; break; } } @@ -592,17 +592,17 @@ void wgsl_export(char *directory) { memset(global_register_indices, 0, sizeof(global_register_indices)); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = binding_index; binding_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { global_register_indices[i] = binding_index; binding_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = binding_index; diff --git a/Sources/compiler.c b/Sources/compiler.c index 9eb6ea3..b935087 100644 --- a/Sources/compiler.c +++ b/Sources/compiler.c @@ -8,7 +8,7 @@ #include typedef struct allocated_global { - global g; + global *g; uint64_t variable_id; } allocated_global; @@ -17,14 +17,13 @@ static size_t allocated_globals_size = 0; allocated_global find_allocated_global(name_id name) { for (size_t i = 0; i < allocated_globals_size; ++i) { - if (name == allocated_globals[i].g.name) { + if (name == allocated_globals[i].g->name) { return allocated_globals[i]; } } allocated_global a; - a.g.type = NO_TYPE; - a.g.name = NO_NAME; + a.g = NULL; a.variable_id = 0; return a; } @@ -56,10 +55,10 @@ variable find_variable(block *parent, name_id name) { variable local_var = find_local_var(parent, name); if (local_var.index == 0) { allocated_global global = find_allocated_global(name); - if (global.g.type != NO_TYPE && global.variable_id != 0) { + if (global.g->type != NO_TYPE && global.variable_id != 0) { variable v; init_type_ref(&v.type, NO_NAME); - v.type.type = global.g.type; + v.type.type = global.g->type; v.index = global.variable_id; return v; } @@ -846,12 +845,12 @@ static block_ids emit_statement(opcodes *code, block *parent, statement *stateme } void convert_globals(void) { - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); + for (global_id i = 0; get_global(i) != NULL && get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); type_ref t; init_type_ref(&t, NO_NAME); - t.type = g.type; + t.type = g->type; variable v = allocate_variable(t, VARIABLE_GLOBAL); allocated_globals[allocated_globals_size].g = g; allocated_globals[allocated_globals_size].variable_id = v.index; diff --git a/Sources/globals.c b/Sources/globals.c index 0e0532c..27fa168 100644 --- a/Sources/globals.c +++ b/Sources/globals.c @@ -89,28 +89,22 @@ global_id add_global_with_value(type_id type, attribute_list attributes, name_id return index; } -global find_global(name_id name) { +global *find_global(name_id name) { for (uint32_t i = 0; i < globals_size; ++i) { if (globals[i].name == name) { - return globals[i]; + return &globals[i]; } } - global g; - g.type = NO_TYPE; - g.name = NO_NAME; - return g; + return NULL; } -global get_global(global_id id) { +global *get_global(global_id id) { if (id >= globals_size) { - global g; - g.type = NO_TYPE; - g.name = NO_NAME; - return g; + return NULL; } - return globals[id]; + return &globals[id]; } void assign_global_var(global_id id, uint64_t var_index) { diff --git a/Sources/globals.h b/Sources/globals.h index 95e21b9..eeb3097 100644 --- a/Sources/globals.h +++ b/Sources/globals.h @@ -25,12 +25,15 @@ typedef struct global_value { } value; } global_value; +struct descriptor_set; + typedef struct global { name_id name; type_id type; uint64_t var_index; global_value value; attribute_list attributes; + struct descriptor_set *set; } global; void globals_init(void); @@ -38,8 +41,8 @@ void globals_init(void); global_id add_global(type_id type, attribute_list attributes, name_id name); global_id add_global_with_value(type_id type, attribute_list attributes, name_id name, global_value value); -global find_global(name_id name); +global *find_global(name_id name); -global get_global(global_id id); +global *get_global(global_id id); void assign_global_var(global_id id, uint64_t var_index); diff --git a/Sources/integrations/kinc.c b/Sources/integrations/kinc.c index 6f7bbfd..0655673 100644 --- a/Sources/integrations/kinc.c +++ b/Sources/integrations/kinc.c @@ -138,17 +138,17 @@ void kinc_export(char *directory, api_kind api) { if (api == API_WEBGPU) { int binding_index = 0; - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = binding_index; binding_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { global_register_indices[i] = binding_index; binding_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = binding_index; @@ -161,17 +161,17 @@ void kinc_export(char *directory, api_kind api) { int texture_index = 0; int sampler_index = 0; - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = sampler_index; sampler_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { global_register_indices[i] = texture_index; texture_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = cbuffer_index; @@ -241,22 +241,22 @@ void kinc_export(char *directory, api_kind api) { fprintf(output, "#include \n"); fprintf(output, "#include \n\n"); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == float_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == float_id) { } - else if (g.type == tex2d_type_id || g.type == texcube_type_id || g.type == sampler_type_id) { - fprintf(output, "extern int %s;\n", get_name(g.name)); + else if (g->type == tex2d_type_id || g->type == texcube_type_id || g->type == sampler_type_id) { + fprintf(output, "extern int %s;\n", get_name(g->name)); } else { - type *t = get_type(g.type); + type *t = get_type(g->type); char name[256]; if (t->name != NO_NAME) { strcpy(name, get_name(t->name)); } else { - strcpy(name, get_name(g.name)); + strcpy(name, get_name(g->name)); strcat(name, "_type"); } @@ -354,10 +354,10 @@ void kinc_export(char *directory, api_kind api) { fprintf(output, "\n#include \n\n"); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == tex2d_type_id || g.type == texcube_type_id || g.type == sampler_type_id) { - fprintf(output, "int %s = %i;\n", get_name(g.name), global_register_indices[i]); + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == tex2d_type_id || g->type == texcube_type_id || g->type == sampler_type_id) { + fprintf(output, "int %s = %i;\n", get_name(g->name), global_register_indices[i]); } } @@ -375,17 +375,17 @@ void kinc_export(char *directory, api_kind api) { fprintf(output, "kinc_g4_vertex_structure_t %s_structure;\n", get_name(t->name)); } - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type != tex2d_type_id && g.type != texcube_type_id && g.type != sampler_type_id && g.type != float_id) { - type *t = get_type(g.type); + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type != tex2d_type_id && g->type != texcube_type_id && g->type != sampler_type_id && g->type != float_id) { + type *t = get_type(g->type); char type_name[256]; if (t->name != NO_NAME) { strcpy(type_name, get_name(t->name)); } else { - strcpy(type_name, get_name(g.name)); + strcpy(type_name, get_name(g->name)); strcat(type_name, "_type"); } @@ -508,44 +508,44 @@ void kinc_export(char *directory, api_kind api) { else if (t->members.m[j].name == add_name("depth_mode")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "depth_mode expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.depth_mode = %s;\n\n", get_name(t->name), convert_compare_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.depth_mode = %s;\n\n", get_name(t->name), convert_compare_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("blend_source")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "blend_source expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("blend_destination")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "blend_destination expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("blend_operation")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "blend_operation expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("alpha_blend_source")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "alpha_blend_source expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.alpha_blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.alpha_blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("alpha_blend_destination")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "alpha_blend_destination expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.alpha_blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.alpha_blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("alpha_blend_operation")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "alpha_blend_operation expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.alpha_blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.alpha_blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g->value.value.ints[0])); } else { debug_context context = {0}; @@ -632,16 +632,16 @@ void kinc_export(char *directory, api_kind api) { find_referenced_globals(fragment_function, globals, &globals_size); for (global_id i = 0; i < globals_size; ++i) { - global g = get_global(globals[i]); - if (g.type == sampler_type_id) { + global *g = get_global(globals[i]); + if (g->type == sampler_type_id) { } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { fprintf(output, "\tkinc_g4_internal_opengl_setup_uniform_block(%s.impl.programId, \"_%" PRIu64 "\", %i);\n\n", get_name(t->name), - g.var_index, global_register_indices[i]); + g->var_index, global_register_indices[i]); } } } diff --git a/Sources/integrations/kope.c b/Sources/integrations/kope.c index 46e21ed..591fcb5 100644 --- a/Sources/integrations/kope.c +++ b/Sources/integrations/kope.c @@ -156,17 +156,17 @@ void kope_export(char *directory, api_kind api) { if (api == API_WEBGPU) { int binding_index = 0; - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = binding_index; binding_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { global_register_indices[i] = binding_index; binding_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = binding_index; @@ -179,17 +179,17 @@ void kope_export(char *directory, api_kind api) { int texture_index = 0; int sampler_index = 0; - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == sampler_type_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == sampler_type_id) { global_register_indices[i] = sampler_index; sampler_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { global_register_indices[i] = texture_index; texture_index += 1; } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { global_register_indices[i] = cbuffer_index; @@ -260,22 +260,22 @@ void kope_export(char *directory, api_kind api) { fprintf(output, "\nvoid kong_init(kope_g5_device *device);\n\n"); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == float_id) { + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == float_id) { } - else if (g.type == tex2d_type_id || g.type == texcube_type_id || g.type == sampler_type_id) { - fprintf(output, "extern int %s;\n", get_name(g.name)); + else if (g->type == tex2d_type_id || g->type == texcube_type_id || g->type == sampler_type_id) { + fprintf(output, "extern int %s;\n", get_name(g->name)); } else { - type *t = get_type(g.type); + type *t = get_type(g->type); char name[256]; if (t->name != NO_NAME) { strcpy(name, get_name(t->name)); } else { - strcpy(name, get_name(g.name)); + strcpy(name, get_name(g->name)); strcat(name, "_type"); } @@ -385,10 +385,10 @@ void kope_export(char *directory, api_kind api) { fprintf(output, "#include \n"); fprintf(output, "#include \n\n"); - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type == tex2d_type_id || g.type == texcube_type_id || g.type == sampler_type_id) { - fprintf(output, "int %s = %i;\n", get_name(g.name), global_register_indices[i]); + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type == tex2d_type_id || g->type == texcube_type_id || g->type == sampler_type_id) { + fprintf(output, "int %s = %i;\n", get_name(g->name), global_register_indices[i]); } } @@ -431,17 +431,17 @@ void kope_export(char *directory, api_kind api) { } } - for (global_id i = 0; get_global(i).type != NO_TYPE; ++i) { - global g = get_global(i); - if (g.type != tex2d_type_id && g.type != texcube_type_id && g.type != sampler_type_id && g.type != float_id) { - type *t = get_type(g.type); + for (global_id i = 0; get_global(i)->type != NO_TYPE; ++i) { + global *g = get_global(i); + if (g->type != tex2d_type_id && g->type != texcube_type_id && g->type != sampler_type_id && g->type != float_id) { + type *t = get_type(g->type); char type_name[256]; if (t->name != NO_NAME) { strcpy(type_name, get_name(t->name)); } else { - strcpy(type_name, get_name(g.name)); + strcpy(type_name, get_name(g->name)); strcat(type_name, "_type"); } @@ -550,44 +550,44 @@ void kope_export(char *directory, api_kind api) { else if (t->members.m[j].name == add_name("depth_mode")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "depth_mode expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.depth_mode = %s;\n\n", get_name(t->name), convert_compare_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.depth_mode = %s;\n\n", get_name(t->name), convert_compare_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("blend_source")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "blend_source expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("blend_destination")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "blend_destination expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("blend_operation")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "blend_operation expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("alpha_blend_source")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "alpha_blend_source expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.alpha_blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.alpha_blend_source = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("alpha_blend_destination")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "alpha_blend_destination expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.alpha_blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.alpha_blend_destination = %s;\n\n", get_name(t->name), convert_blend_mode(g->value.value.ints[0])); } else if (t->members.m[j].name == add_name("alpha_blend_operation")) { debug_context context = {0}; check(t->members.m[j].value.kind == TOKEN_IDENTIFIER, context, "alpha_blend_operation expects an identifier"); - global g = find_global(t->members.m[j].value.identifier); - fprintf(output, "\t%s.alpha_blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g.value.value.ints[0])); + global *g = find_global(t->members.m[j].value.identifier); + fprintf(output, "\t%s.alpha_blend_operation = %s;\n\n", get_name(t->name), convert_blend_op(g->value.value.ints[0])); } else { debug_context context = {0}; @@ -727,16 +727,16 @@ void kope_export(char *directory, api_kind api) { find_referenced_globals(fragment_function, globals, &globals_size); for (global_id i = 0; i < globals_size; ++i) { - global g = get_global(globals[i]); - if (g.type == sampler_type_id) { + global *g = get_global(globals[i]); + if (g->type == sampler_type_id) { } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g->type == tex2d_type_id || g->type == texcube_type_id) { } - else if (g.type == float_id) { + else if (g->type == float_id) { } else { fprintf(output, "\tkinc_g4_internal_opengl_setup_uniform_block(%s.impl.programId, \"_%" PRIu64 "\", %i);\n\n", get_name(t->name), - g.var_index, global_register_indices[i]); + g->var_index, global_register_indices[i]); } } } diff --git a/Sources/kong.c b/Sources/kong.c index 33d9011..d1e55fa 100644 --- a/Sources/kong.c +++ b/Sources/kong.c @@ -365,9 +365,9 @@ void resolve_types_in_expression(statement *parent, expression *e) { break; } case EXPRESSION_VARIABLE: { - global g = find_global(e->variable); - if (g.type != NO_TYPE) { - e->type.type = g.type; + global *g = find_global(e->variable); + if (g != NULL && g->type != NO_TYPE) { + e->type.type = g->type; } else { type_ref type = find_local_var_type(&parent->block, e->variable); diff --git a/Sources/parser.c b/Sources/parser.c index 1919692..2bc140c 100644 --- a/Sources/parser.c +++ b/Sources/parser.c @@ -1,6 +1,7 @@ #include "parser.h" #include "errors.h" #include "functions.h" +#include "sets.h" #include "tokenizer.h" #include "types.h" @@ -166,6 +167,7 @@ static double attribute_parameter_to_number(name_id attribute_name, name_id para static definition parse_definition(state_t *state) { attribute_list attributes = {0}; + descriptor_set *current_set = NULL; if (current(state).kind == TOKEN_HASH) { advance_state(state); @@ -185,8 +187,14 @@ static definition parse_definition(state_t *state) { while (current(state).kind != TOKEN_RIGHT_PAREN) { if (current(state).kind == TOKEN_IDENTIFIER) { - current_attribute.parameters[current_attribute.paramters_count] = - attribute_parameter_to_number(current_attribute.name, current(state).identifier); + if (current_attribute.name == add_name("set")) { + current_set = add_set(current(state).identifier); + current_attribute.parameters[current_attribute.paramters_count] = current_set->index; + } + else { + current_attribute.parameters[current_attribute.paramters_count] = + attribute_parameter_to_number(current_attribute.name, current(state).identifier); + } current_attribute.paramters_count += 1; advance_state(state); } @@ -221,11 +229,21 @@ static definition parse_definition(state_t *state) { switch (current(state).kind) { case TOKEN_STRUCT: { + if (current_set != NULL) { + debug_context context = {0}; + error(context, "A struct can not be assigned to a set"); + } + definition structy = parse_struct(state); get_type(structy.type)->attributes = attributes; return structy; } case TOKEN_FUNCTION: { + if (current_set != NULL) { + debug_context context = {0}; + error(context, "A function can not be assigned to a set"); + } + definition d = parse_function(state); function *f = get_function(d.function); f->attributes = attributes; @@ -233,6 +251,11 @@ static definition parse_definition(state_t *state) { } case TOKEN_CONST: { definition d = parse_const(state, attributes); + + if (current_set != NULL) { + add_definition_to_set(current_set, d); + } + return d; } default: { @@ -978,9 +1001,9 @@ static definition parse_struct_inner(state_t *state, name_id name) { init_type_ref(&member.type, add_name("float")); } else if (member.value.kind == TOKEN_IDENTIFIER) { - global g = find_global(member.value.identifier); - if (g.name != NO_NAME) { - init_type_ref(&member.type, get_type(g.type)->name); + global *g = find_global(member.value.identifier); + if (g != NULL && g->name != NO_NAME) { + init_type_ref(&member.type, get_type(g->type)->name); } else { init_type_ref(&member.type, add_name("fun")); diff --git a/Sources/sets.c b/Sources/sets.c new file mode 100644 index 0000000..bc94ef5 --- /dev/null +++ b/Sources/sets.c @@ -0,0 +1,44 @@ +#include "sets.h" + +#include "errors.h" + +static descriptor_set sets[MAX_SETS]; +static size_t sets_count = 0; + +descriptor_set *add_set(name_id name) { + for (size_t set_index = 0; set_index < sets_count; ++set_index) { + if (sets[set_index].name == name) { + return &sets[set_index]; + } + } + + if (sets_count >= MAX_SETS) { + debug_context context = {0}; + error(context, "Max set count of %i reached", MAX_SETS); + return NULL; + } + + descriptor_set *new_set = &sets[sets_count]; + new_set->name = name; + new_set->index = (uint32_t)sets_count; + new_set->definitions_count = 0; + + sets_count += 1; + + return new_set; +} + +void add_definition_to_set(descriptor_set *set, definition def) { + assert(def.kind != DEFINITION_FUNCTION && def.kind != DEFINITION_STRUCT); + + for (size_t definition_index = 0; definition_index < set->definitions_count; ++definition_index) { + if (set->definitions[definition_index].global = def.global) { + return; + } + } + + assert(get_global(def.global)->set == NULL); + get_global(def.global)->set = set; + set->definitions[set->definitions_count] = def; + set->definitions_count += 1; +} diff --git a/Sources/sets.h b/Sources/sets.h new file mode 100644 index 0000000..b8899aa --- /dev/null +++ b/Sources/sets.h @@ -0,0 +1,22 @@ +#ifndef KONG_SETS_HEADER +#define KONG_SETS_HEADER + +#include "names.h" +#include "parser.h" + +#define MAX_SET_DEFINITIONS 32 + +typedef struct descriptor_set { + uint32_t index; + name_id name; + definition definitions[MAX_SET_DEFINITIONS]; + size_t definitions_count; +} descriptor_set; + +#define MAX_SETS 256 + +descriptor_set *add_set(name_id name); + +void add_definition_to_set(descriptor_set *set, definition def); + +#endif