From 6ca06a577a46d6fdf6bc762c83f151761f9c589d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 20 Sep 2024 01:39:44 +0900 Subject: [PATCH] [qfcc] Make capabilities and memory model configurable While I'm not happy with the module "creation" (at least it's limited to two places), setting it up with spir-v capabilities and memory model seems quite nice and should play nicely with being set up from within source code, though using uint constant expressions might be overkill. --- tools/qfcc/include/qfcc.h | 2 ++ tools/qfcc/include/spirv.h | 31 +++++++++++++++++++++++++++++++ tools/qfcc/source/glsl-builtins.c | 20 ++++++++++++++++++++ tools/qfcc/source/qc-parse.y | 18 ++++++++++++++++++ tools/qfcc/source/spirv.c | 31 +++++++++++++++++++++++++------ 5 files changed, 96 insertions(+), 6 deletions(-) diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index be82eca36..0f5cf8a3d 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -93,6 +93,8 @@ typedef struct pr_info_s { struct pr_lineno_s *linenos; int linenos_size; int num_linenos; + + struct module_s *module; } pr_info_t; extern pr_info_t pr; diff --git a/tools/qfcc/include/spirv.h b/tools/qfcc/include/spirv.h index bfe7ae6c2..89f69d31a 100644 --- a/tools/qfcc/include/spirv.h +++ b/tools/qfcc/include/spirv.h @@ -28,6 +28,37 @@ #ifndef __spirv_h #define __spirv_h +#include + +#include "tools/qfcc/include/defspace.h" +#include "tools/qfcc/include/expr.h" + +typedef struct entrypoint_s { + struct entrypoint_s *next; + SpvExecutionModel model; + const char *name; + attribute_t *modes; + ex_list_t interface; ///< list of symbols forming interface +} entrypoint_t; + +typedef struct module_s { + ex_list_t capabilities; + ex_list_t extensions; + ex_list_t extinst_imports; + const expr_t *addressing_model; + const expr_t *memory_model; + entrypoint_t *entry_points; + defspace_t *strings; + defspace_t *names; + defspace_t *decorations; + defspace_t *globals; + defspace_t *func_import; + defspace_t *func_code; +} module_t; + +void spirv_add_capability (module_t *module, SpvCapability capability); +void spirv_set_addressing_model (module_t *module, SpvAddressingModel model); +void spirv_set_memory_model (module_t *module, SpvMemoryModel model); bool spirv_write (struct pr_info_s *pr, const char *filename); #endif//__spirv_h diff --git a/tools/qfcc/source/glsl-builtins.c b/tools/qfcc/source/glsl-builtins.c index 419e3eea8..d4a61a57e 100644 --- a/tools/qfcc/source/glsl-builtins.c +++ b/tools/qfcc/source/glsl-builtins.c @@ -30,7 +30,9 @@ #include "tools/qfcc/include/diagnostic.h" #include "tools/qfcc/include/glsl-lang.h" +#include "tools/qfcc/include/qfcc.h" #include "tools/qfcc/include/rua-lang.h" +#include "tools/qfcc/include/spirv.h" #define SRC_LINE_EXP2(l,f) "#line " #l " " #f "\n" #define SRC_LINE_EXP(l,f) SRC_LINE_EXP2(l,f) @@ -915,6 +917,12 @@ glsl_parse_vars (const char *var_src) static void glsl_init_common (void) { + static module_t module; //FIXME probably not what I want + pr.module = &module; + + spirv_set_addressing_model (pr.module, SpvAddressingModelLogical); + spirv_set_memory_model (pr.module, SpvMemoryModelGLSL450); + current_language.initialized = true; glsl_block_clear (); qc_parse_string (glsl_general_functions); @@ -926,6 +934,8 @@ glsl_init_comp (void) { glsl_init_common (); glsl_parse_vars (glsl_compute_vars); + + spirv_add_capability (pr.module, SpvCapabilityShader); } void @@ -933,6 +943,8 @@ glsl_init_vert (void) { glsl_init_common (); glsl_parse_vars (glsl_Vulkan_vertex_vars); + + spirv_add_capability (pr.module, SpvCapabilityShader); } void @@ -940,6 +952,8 @@ glsl_init_tesc (void) { glsl_init_common (); glsl_parse_vars (glsl_tesselation_control_vars); + + spirv_add_capability (pr.module, SpvCapabilityTessellation); } void @@ -947,6 +961,8 @@ glsl_init_tese (void) { glsl_init_common (); glsl_parse_vars (glsl_tesselation_evaluation_vars); + + spirv_add_capability (pr.module, SpvCapabilityTessellation); } void @@ -955,6 +971,8 @@ glsl_init_geom (void) glsl_init_common (); glsl_parse_vars (glsl_geometry_vars); qc_parse_string (glsl_geometry_functions); + + spirv_add_capability (pr.module, SpvCapabilityGeometry); } void @@ -962,4 +980,6 @@ glsl_init_frag (void) { glsl_init_common (); glsl_parse_vars (glsl_fragment_vars); + + spirv_add_capability (pr.module, SpvCapabilityShader); } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 94a02190b..85f023ecd 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -73,6 +73,7 @@ #include "tools/qfcc/include/reloc.h" #include "tools/qfcc/include/rua-lang.h" #include "tools/qfcc/include/shared.h" +#include "tools/qfcc/include/spirv.h" #include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/struct.h" #include "tools/qfcc/include/switch.h" @@ -3086,7 +3087,24 @@ static int qc_finish (const char *file) return pr.error_count; } +static void +rua_init (void) +{ + current_language.initialized = true; + if (options.code.spirv) { + static module_t module; //FIXME probably not what I want + pr.module = &module; + + spirv_add_capability (pr.module, SpvCapabilityShader); + //FIXME sufficient? phys 32/storage? + spirv_set_addressing_model (pr.module, SpvAddressingModelLogical); + //FIXME look into Vulkan, or even configurable + spirv_set_memory_model (pr.module, SpvMemoryModelGLSL450); + } +} + language_t lang_ruamoko = { + .init = rua_init, .parse = qc_yyparse, .finish = qc_finish, }; diff --git a/tools/qfcc/source/spirv.c b/tools/qfcc/source/spirv.c index b456f6368..67cd6b638 100644 --- a/tools/qfcc/source/spirv.c +++ b/tools/qfcc/source/spirv.c @@ -30,8 +30,6 @@ #include -#include - #include "QF/quakeio.h" #include "tools/qfcc/include/def.h" @@ -409,11 +407,13 @@ spirv_write (struct pr_info_s *pr, const char *filename) D_var_o(int, header, 3) = 0; // Filled in later D_var_o(int, header, 4) = 0; // Reserved + for (auto cap = pr->module->capabilities.head; cap; cap = cap->next) { + spirv_Capability (expr_uint (cap->expr), ctx.space); + } + //FIXME none of these should be hard-coded - spirv_Capability (SpvCapabilityShader, ctx.space); - //spirv_Capability (SpvCapabilityLinkage, ctx.space); - spirv_MemoryModel (SpvAddressingModelLogical, SpvMemoryModelGLSL450, - ctx.space); + spirv_MemoryModel (expr_uint (pr->module->addressing_model), + expr_uint (pr->module->memory_model), ctx.space); auto srcid = spirv_String (pr->src_name, &ctx); spirv_Source (0, 1, srcid, nullptr, &ctx); @@ -442,3 +442,22 @@ spirv_write (struct pr_info_s *pr, const char *filename) Qclose (file); return false; } + +void +spirv_add_capability (module_t *module, SpvCapability capability) +{ + auto cap = new_uint_expr (capability); + list_append (&module->capabilities, cap); +} + +void +spirv_set_addressing_model (module_t *module, SpvAddressingModel model) +{ + module->addressing_model = new_uint_expr (model); +} + +void +spirv_set_memory_model (module_t *module, SpvMemoryModel model) +{ + module->memory_model = new_uint_expr (model); +}