summaryrefslogtreecommitdiff
path: root/gen_gl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gen_gl.c')
-rw-r--r--gen_gl.c436
1 files changed, 424 insertions, 12 deletions
diff --git a/gen_gl.c b/gen_gl.c
index aabd13f..1b3f3d2 100644
--- a/gen_gl.c
+++ b/gen_gl.c
@@ -6,10 +6,25 @@ exit
#define KIT_IMPLEMENTATION
#include "include/kit.inl.h"
-#define MB *1024 * 1024
#define GL_FOLDER ".gl_registry"
#define GL_REPO "https://github.com/KhronosGroup/OpenGL-Registry"
+typedef struct {
+ str_t name;
+ str_t value;
+} enum_t;
+
+typedef struct {
+ str_t name;
+ str_builder_t return_type;
+ DA(str_builder_t) arguments;
+} proc_t;
+
+typedef struct {
+ str_t name;
+ DA(str_t) procs;
+} feature_t;
+
int main(int argc, char **argv) {
if (path_type(SZ("." PATH_DELIM GL_FOLDER)) == PATH_NONE) {
int s = system("git clone --quiet --depth 1 " GL_REPO
@@ -36,24 +51,18 @@ int main(int argc, char **argv) {
return 1;
}
- // FIXME
- // Optimize memory use
- i64 arena_size = 100 MB;
- u8 *arena = kit_alloc_dispatch(NULL, KIT_ALLOCATE, arena_size, 0,
- NULL);
- kit_allocator_t alloc = kit_alloc_buffer(arena_size, arena);
-
- is_handle_t is = is_wrap_file(f, &alloc);
struct timespec t0, t1;
+ is_handle_t is = is_wrap_file(f, NULL);
+
timespec_get(&t0, TIME_UTC);
- xml_parse_result_t res = xml_parse(is, &alloc);
+ xml_parse_result_t res = xml_parse(is, NULL);
timespec_get(&t1, TIME_UTC);
+
is_destroy(is);
fclose(f);
if (res.status != KIT_OK) {
printf("XML parse failed.\n");
- kit_alloc_dispatch(NULL, KIT_DEALLOCATE, 0, 0, arena);
return 1;
}
@@ -61,8 +70,411 @@ int main(int argc, char **argv) {
(t1.tv_nsec - t0.tv_nsec + 500000) / 1000000;
printf("XML parsed in %lld milliseconds.\n", diff);
+ DA(enum_t) enums;
+ DA(proc_t) procs;
+ DA(feature_t) features;
+
+#define DESTROY_ALL_ \
+ for (i64 i_ = 0; i_ < procs.size; i_++) { \
+ for (i64 j_ = 0; j_ < procs.values[i_].arguments.size; j_++) \
+ DA_DESTROY(procs.values[i_].arguments.values[j_]); \
+ DA_DESTROY(procs.values[i_].return_type); \
+ DA_DESTROY(procs.values[i_].arguments); \
+ } \
+ for (i64 i_ = 0; i_ < features.size; i_++) \
+ DA_DESTROY(features.values[i_].procs); \
+ DA_DESTROY(enums); \
+ DA_DESTROY(procs); \
+ DA_DESTROY(features)
+
+ DA_INIT(enums, 0, NULL);
+ DA_INIT(procs, 0, NULL);
+ DA_INIT(features, 0, NULL);
+
+ xml_t *registry = res.xml.children.values + 1;
+
+ for (i64 i = 0; i < registry->children.size; i++) {
+ xml_t *tag_enums = registry->children.values + i;
+ if (!AR_EQUAL(tag_enums->tag, SZ("enums")))
+ continue;
+
+ for (i64 j = 0; j < tag_enums->children.size; j++) {
+ xml_t *tag_enum = tag_enums->children.values + j;
+ if (!AR_EQUAL(tag_enum->tag, SZ("enum")))
+ continue;
+ xml_property_t *pro_name = NULL;
+ xml_property_t *pro_value = NULL;
+ for (i64 k = 0; k < tag_enum->properties.size; k++) {
+ xml_property_t *pro = tag_enum->properties.values + k;
+ if (AR_EQUAL(pro->name, SZ("name")))
+ pro_name = pro;
+ else if (AR_EQUAL(pro->name, SZ("value")))
+ pro_value = pro;
+ }
+ if (pro_name == NULL || pro_value == NULL)
+ continue;
+
+ i8 found = 0;
+ for (i64 k = 0; k < enums.size; k++)
+ if (AR_EQUAL(pro_name->value, enums.values[k].name)) {
+ found = 1;
+ break;
+ }
+ if (found)
+ continue;
+
+ i64 n = enums.size;
+ DA_RESIZE(enums, n + 1);
+
+ if (enums.size != n + 1) {
+ printf("Bad alloc.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ enums.values[n].name = WRAP_STR(pro_name->value);
+ enums.values[n].value = WRAP_STR(pro_value->value);
+ }
+ }
+
+ for (i64 i = 0; i < registry->children.size; i++) {
+ xml_t *tag_commands = registry->children.values + i;
+ if (!AR_EQUAL(tag_commands->tag, SZ("commands")))
+ continue;
+
+ for (i64 j = 0; j < tag_commands->children.size; j++) {
+ xml_t *tag_command = tag_commands->children.values + j;
+ if (!AR_EQUAL(tag_command->tag, SZ("command")))
+ continue;
+
+ xml_t *tag_proto = NULL;
+ xml_t *tag_name = NULL;
+
+ for (i64 k = 0; k < tag_command->children.size; k++) {
+ tag_proto = tag_command->children.values + k;
+ if (!AR_EQUAL(tag_proto->tag, SZ("proto")))
+ continue;
+
+ for (i64 l = 0; l < tag_proto->children.size; l++)
+ if (AR_EQUAL(tag_proto->children.values[l].tag,
+ SZ("name"))) {
+ tag_name = tag_proto->children.values + l;
+ break;
+ }
+
+ break;
+ }
+
+ if (tag_proto == NULL || tag_name == NULL)
+ continue;
+
+ i64 n = procs.size;
+ DA_RESIZE(procs, n + 1);
+
+ if (procs.size != n + 1) {
+ printf("Bad alloc.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ procs.values[n].name = WRAP_STR(tag_name->text);
+ procs.values[n].return_type =
+ xml_full_text(tag_proto, NULL).text;
+ procs.values[n].return_type.size -= procs.values[n].name.size;
+
+ DA_INIT(procs.values[n].arguments,
+ tag_command->children.size - 1, NULL);
+
+ if (procs.values[n].arguments.size !=
+ tag_command->children.size - 1) {
+ printf("Bad alloc.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ procs.values[n].arguments.size = 0;
+
+ for (i64 k = 0; k < tag_command->children.size; k++) {
+ xml_t *tag_param = tag_command->children.values + k;
+ if (AR_EQUAL(tag_param->tag, SZ("param")))
+ procs.values[n]
+ .arguments.values[procs.values[n].arguments.size++] =
+ xml_full_text(tag_param, NULL).text;
+ }
+ }
+ }
+
+ for (i64 i = 0; i < registry->children.size; i++) {
+ xml_t *tag_feature = registry->children.values + i;
+ if (!AR_EQUAL(tag_feature->tag, SZ("feature")))
+ continue;
+
+ xml_property_t *pro_name = NULL;
+ for (i64 k = 0; k < tag_feature->properties.size; k++) {
+ xml_property_t *pro = tag_feature->properties.values + k;
+ if (AR_EQUAL(pro->name, SZ("name")))
+ pro_name = pro;
+ }
+ if (pro_name == NULL)
+ continue;
+
+ i64 n = features.size;
+ DA_RESIZE(features, n + 1);
+
+ if (features.size != n + 1) {
+ printf("Bad alloc.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ features.values[n].name = WRAP_STR(pro_name->value);
+ DA_INIT(features.values[n].procs, 0, NULL);
+
+ for (i64 j = 0; j < tag_feature->children.size; j++) {
+ xml_t *tag_require = tag_feature->children.values + j;
+ if (!AR_EQUAL(tag_require->tag, SZ("require")))
+ continue;
+
+ i64 m = features.values[n].procs.size;
+ DA_RESIZE(features.values[n].procs,
+ m + tag_require->children.size);
+
+ if (features.values[n].procs.size !=
+ m + tag_require->children.size) {
+ printf("Bad alloc.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ features.values[n].procs.size = m;
+
+ for (i64 k = 0; k < tag_require->children.size; k++) {
+ xml_t *tag_command = tag_require->children.values + k;
+ if (!AR_EQUAL(tag_command->tag, SZ("command")))
+ continue;
+
+ pro_name = NULL;
+ for (i64 k = 0; k < tag_command->properties.size; k++) {
+ xml_property_t *pro = tag_command->properties.values + k;
+ if (AR_EQUAL(pro->name, SZ("name")))
+ pro_name = pro;
+ }
+ if (pro_name == NULL)
+ continue;
+
+ features.values[n]
+ .procs.values[features.values[n].procs.size++] = WRAP_STR(
+ pro_name->value);
+ }
+ }
+
+ if (features.values[n].procs.size == 0) {
+ DA_DESTROY(features.values[n].procs);
+ --features.size;
+ }
+ }
+
+ for (i64 r = 0; r < registry->children.size; r++) {
+ xml_t *tag_extensions = registry->children.values + r;
+ if (!AR_EQUAL(tag_extensions->tag, SZ("extensions")))
+ continue;
+
+ for (i64 i = 0; i < tag_extensions->children.size; i++) {
+ xml_t *tag_extension = tag_extensions->children.values + i;
+ if (!AR_EQUAL(tag_extension->tag, SZ("extension")))
+ continue;
+
+ xml_property_t *pro_name = NULL;
+ for (i64 k = 0; k < tag_extension->properties.size; k++) {
+ xml_property_t *pro = tag_extension->properties.values + k;
+ if (AR_EQUAL(pro->name, SZ("name")))
+ pro_name = pro;
+ }
+ if (pro_name == NULL)
+ continue;
+
+ i64 n = features.size;
+ DA_RESIZE(features, n + 1);
+
+ if (features.size != n + 1) {
+ printf("Bad alloc.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ features.values[n].name = WRAP_STR(pro_name->value);
+ DA_INIT(features.values[n].procs, 0, NULL);
+
+ for (i64 j = 0; j < tag_extension->children.size; j++) {
+ xml_t *tag_require = tag_extension->children.values + j;
+ if (!AR_EQUAL(tag_require->tag, SZ("require")))
+ continue;
+
+ i64 m = features.values[n].procs.size;
+ DA_RESIZE(features.values[n].procs,
+ m + tag_require->children.size);
+
+ if (features.values[n].procs.size !=
+ m + tag_require->children.size) {
+ printf("Bad alloc.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ features.values[n].procs.size = m;
+
+ for (i64 k = 0; k < tag_require->children.size; k++) {
+ xml_t *tag_command = tag_require->children.values + k;
+ if (!AR_EQUAL(tag_command->tag, SZ("command")))
+ continue;
+
+ pro_name = NULL;
+ for (i64 k = 0; k < tag_command->properties.size; k++) {
+ xml_property_t *pro = tag_command->properties.values + k;
+ if (AR_EQUAL(pro->name, SZ("name")))
+ pro_name = pro;
+ }
+ if (pro_name == NULL)
+ continue;
+
+ features.values[n]
+ .procs.values[features.values[n].procs.size++] =
+ WRAP_STR(pro_name->value);
+ }
+ }
+
+ if (features.values[n].procs.size == 0) {
+ DA_DESTROY(features.values[n].procs);
+ --features.size;
+ }
+ }
+ }
+
+ f = fopen("kit_gl.h", "wb");
+
+ if (f == NULL) {
+ printf("Failed to write kit_gl.inl.h.\n");
+ DESTROY_ALL_;
+ return 1;
+ }
+
+ fprintf(f, "#include <stdint.h>\n");
+ fprintf(f, "#include <stddef.h>\n");
+ fprintf(f, "#ifdef _WIN32\n");
+ fprintf(f, "# define GL_API_ENTRY __stdcall\n");
+ fprintf(f, "#else\n");
+ fprintf(f, "# define GL_API_ENTRY\n");
+ fprintf(f, "#endif\n");
+ fprintf(f, "typedef unsigned GLenum;\n");
+ fprintf(f, "typedef unsigned char GLboolean;\n");
+ fprintf(f, "typedef unsigned GLbitfield;\n");
+ fprintf(f, "typedef signed char GLbyte;\n");
+ fprintf(f, "typedef unsigned char GLubyte;\n");
+ fprintf(f, "typedef signed short GLshort;\n");
+ fprintf(f, "typedef unsigned short GLushort;\n");
+ fprintf(f, "typedef int GLint;\n");
+ fprintf(f, "typedef unsigned GLuint;\n");
+ fprintf(f, "typedef int GLclampx;\n");
+ fprintf(f, "typedef int GLsizei;\n");
+ fprintf(f, "typedef float GLfloat;\n");
+ fprintf(f, "typedef float GLclampf;\n");
+ fprintf(f, "typedef double GLdouble;\n");
+ fprintf(f, "typedef double GLclampd;\n");
+ fprintf(f, "typedef void * GLeglClientBufferEXT;\n");
+ fprintf(f, "typedef void * GLeglImageOES;\n");
+ fprintf(f, "typedef char GLchar;\n");
+ fprintf(f, "typedef char GLcharARB;\n");
+ fprintf(f, "#ifdef __APPLE__\n");
+ fprintf(f, " typedef void * GLhandleARB;\n");
+ fprintf(f, "#else\n");
+ fprintf(f, " typedef unsigned GLhandleARB;\n");
+ fprintf(f, "#endif\n");
+ fprintf(f, "typedef unsigned short GLhalf;\n");
+ fprintf(f, "typedef unsigned short GLhalfARB;\n");
+ fprintf(f, "typedef int GLfixed;\n");
+ fprintf(f, "typedef intptr_t GLintptr;\n");
+ fprintf(f, "typedef intptr_t GLintptrARB;\n");
+ fprintf(f, "typedef intptr_t GLsizeiptr;\n");
+ fprintf(f, "typedef intptr_t GLsizeiptrARB;\n");
+ fprintf(f, "typedef long long GLint64;\n");
+ fprintf(f, "typedef long long GLint64EXT;\n");
+ fprintf(f, "typedef unsigned long long GLuint64;\n");
+ fprintf(f, "typedef unsigned long long GLuint64EXT;\n");
+ fprintf(f, "typedef unsigned short GLhalfNV;\n");
+ fprintf(f, "typedef intptr_t GLvdpauSurfaceNV;\n");
+ fprintf(f, "typedef struct __GLsync * GLsync;\n");
+ fprintf(f, "struct _cl_context;\n");
+ fprintf(f, "struct _cl_event;\n");
+ fprintf(f,
+ "typedef void (GL_API_ENTRY *GLDEBUGPROC)(GLenum "
+ "source,GLenum type,GLuint id,GLenum severity,GLsizei "
+ "length,const GLchar *message,const void *userParam);\n");
+ fprintf(f,
+ "typedef void (GL_API_ENTRY *GLDEBUGPROCARB)(GLenum "
+ "source,GLenum type,GLuint id,GLenum severity,GLsizei "
+ "length,const GLchar *message,const void *userParam);\n");
+ fprintf(f,
+ "typedef void (GL_API_ENTRY *GLDEBUGPROCKHR)(GLenum "
+ "source,GLenum type,GLuint id,GLenum severity,GLsizei "
+ "length,const GLchar *message,const void *userParam);\n");
+ fprintf(f, "typedef void (GL_API_ENTRY *GLDEBUGPROCAMD)(GLuint "
+ "id,GLenum category,GLenum severity,GLsizei "
+ "length,const GLchar *message,void *userParam);\n");
+ fprintf(f, "typedef void (GL_API_ENTRY *GLVULKANPROCNV)(void);\n");
+
+ for (i64 i = 0; i < enums.size; i++)
+ fprintf(f, "#define %-80s %s\n", BS(enums.values[i].name),
+ BS(enums.values[i].value));
+
+ for (i64 i = 0; i < procs.size; i++) {
+ fprintf(f, "typedef %-20s(* proc_%-56s)(",
+ BS(procs.values[i].return_type),
+ BS(procs.values[i].name));
+ for (i64 j = 0; j < procs.values[i].arguments.size; j++) {
+ if (j > 0)
+ fprintf(f, ", ");
+ fprintf(f, "%s", BS(procs.values[i].arguments.values[j]));
+ }
+ fprintf(f, ");\n");
+ }
+
+ for (i64 i = 0; i < procs.size; i++)
+ fprintf(f, "extern proc_%-56s %s;\n", BS(procs.values[i].name),
+ BS(procs.values[i].name));
+
+ fprintf(f, "int gl_load_procs(void);\n");
+
+ fclose(f);
+
+ f = fopen("kit_gl.inl.h", "wb");
+
+ fprintf(f, "#include \"kit_gl.h\"\n");
+
+ for (i64 i = 0; i < procs.size; i++)
+ fprintf(f, "proc_%-56s %-56s= NULL;\n", BS(procs.values[i].name),
+ BS(procs.values[i].name));
+
+ fprintf(f, "#ifndef GL_LOAD_PROC\n");
+ fprintf(f, "# define GL_LOAD_PROC(name_)\n");
+ fprintf(f, "#endif\n");
+
+ fprintf(f, "int gl_load_procs(void) {\n");
+
+ for (i64 i = 0; i < features.size; i++) {
+ fprintf(f, "#ifdef %s\n", BS(features.values[i].name));
+ for (i64 j = 0; j < features.values[i].procs.size; j++)
+ fprintf(f, " GL_LOAD_PROC(%s);\n",
+ BS(features.values[i].procs.values[j]));
+ fprintf(f, "#endif\n");
+ }
+
+ fprintf(f, " return 1;\n");
+ fprintf(f, "}\n");
+
+ fclose(f);
+
+ DESTROY_ALL_;
xml_destroy(&res.xml);
- kit_alloc_dispatch(NULL, KIT_DEALLOCATE, 0, 0, arena);
return 0;
}