mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[qfcc] Improve spir-v entry point handling
It's still not great (mostly on the language side, I think), but different glsl shader types get the correct model and fragment shaders even get the correct mode.
This commit is contained in:
parent
4998968169
commit
a93c109988
3 changed files with 50 additions and 23 deletions
|
@ -43,17 +43,19 @@ typedef struct entrypoint_s {
|
|||
const char *name;
|
||||
attribute_t *modes;
|
||||
ex_list_t interface; ///< list of symbols forming interface
|
||||
struct DARRAY_TYPE (symbol_t *) interface_syms;
|
||||
struct function_s *func;
|
||||
} entrypoint_t;
|
||||
|
||||
typedef struct module_s {
|
||||
ex_list_t capabilities;
|
||||
ex_list_t extensions;
|
||||
SpvExecutionModel default_model;
|
||||
symtab_t *extinst_imports;
|
||||
const expr_t *addressing_model;
|
||||
const expr_t *memory_model;
|
||||
struct DARRAY_TYPE (symbol_t *) interface_syms;
|
||||
//entrypoint_t *entry_points;
|
||||
defspace_t *entry_points;
|
||||
entrypoint_t *entry_points;
|
||||
defspace_t *entry_point_space;
|
||||
defspace_t *exec_modes;
|
||||
// debug
|
||||
defspace_t *strings;
|
||||
|
|
|
@ -1014,6 +1014,7 @@ glsl_init_vert (rua_ctx_t *ctx)
|
|||
glsl_parse_vars (glsl_Vulkan_vertex_vars, ctx);
|
||||
|
||||
spirv_add_capability (pr.module, SpvCapabilityShader);
|
||||
pr.module->default_model = SpvExecutionModelVertex;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1023,6 +1024,7 @@ glsl_init_tesc (rua_ctx_t *ctx)
|
|||
glsl_parse_vars (glsl_tesselation_control_vars, ctx);
|
||||
|
||||
spirv_add_capability (pr.module, SpvCapabilityTessellation);
|
||||
pr.module->default_model = SpvExecutionModelTessellationControl;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1032,6 +1034,7 @@ glsl_init_tese (rua_ctx_t *ctx)
|
|||
glsl_parse_vars (glsl_tesselation_evaluation_vars, ctx);
|
||||
|
||||
spirv_add_capability (pr.module, SpvCapabilityTessellation);
|
||||
pr.module->default_model = SpvExecutionModelTessellationEvaluation;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1043,6 +1046,7 @@ glsl_init_geom (rua_ctx_t *ctx)
|
|||
qc_parse_string (glsl_geometry_functions, &rua_ctx);
|
||||
|
||||
spirv_add_capability (pr.module, SpvCapabilityGeometry);
|
||||
pr.module->default_model = SpvExecutionModelGeometry;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1052,4 +1056,5 @@ glsl_init_frag (rua_ctx_t *ctx)
|
|||
glsl_parse_vars (glsl_fragment_vars, ctx);
|
||||
|
||||
spirv_add_capability (pr.module, SpvCapabilityShader);
|
||||
pr.module->default_model = SpvExecutionModelFragment;
|
||||
}
|
||||
|
|
|
@ -706,7 +706,7 @@ spirv_variable (symbol_t *sym, spirvctx_t *ctx)
|
|||
if (storage == SpvStorageClassFunction) {
|
||||
space = ctx->decl_space;
|
||||
} else {
|
||||
DARRAY_APPEND (&ctx->module->interface_syms, sym);
|
||||
DARRAY_APPEND (&ctx->module->entry_points->interface_syms, sym);
|
||||
}
|
||||
auto type = sym->type;
|
||||
unsigned tid = type_id (type, ctx);
|
||||
|
@ -813,19 +813,28 @@ spirv_function (function_t *func, spirvctx_t *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
spirv_EntryPoint (unsigned func_id, const char *func_name,
|
||||
SpvExecutionModel model, spirvctx_t *ctx)
|
||||
spirv_EntryPoint (entrypoint_t *entrypoint, spirvctx_t *ctx)
|
||||
{
|
||||
int len = strlen (func_name) + 1;
|
||||
|
||||
unsigned func_id = spirv_function (entrypoint->func, ctx);
|
||||
int len = strlen (entrypoint->name) + 1;
|
||||
int iface_start = 3 + RUP(len, 4) / 4;
|
||||
auto linkage = ctx->module->entry_points;
|
||||
int count = ctx->module->interface_syms.size;
|
||||
auto linkage = ctx->module->entry_point_space;
|
||||
auto interface_syms = &entrypoint->interface_syms;
|
||||
int count = interface_syms->size;
|
||||
auto insn = spirv_new_insn (SpvOpEntryPoint, iface_start + count, linkage);
|
||||
INSN (insn, 1) = model;
|
||||
INSN (insn, 1) = entrypoint->model;
|
||||
INSN (insn, 2) = func_id;
|
||||
memcpy (&INSN (insn, 3), func_name, len);
|
||||
memcpy (&INSN (insn, 3), entrypoint->name, len);
|
||||
for (int i = 0; i < count; i++) {
|
||||
INSN (insn, iface_start + i) = ctx->module->interface_syms.a[i]->id;
|
||||
INSN (insn, iface_start + i) = interface_syms->a[i]->id;
|
||||
}
|
||||
|
||||
auto exec_modes = ctx->module->exec_modes;
|
||||
for (auto m = entrypoint->modes; m; m = m->next) {
|
||||
insn = spirv_new_insn (SpvOpExecutionMode, 3, exec_modes);
|
||||
INSN (insn, 1) = func_id;
|
||||
INSN (insn, 2) = expr_integral (m->params);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1825,7 +1834,7 @@ spirv_emit_expr (const expr_t *e, spirvctx_t *ctx)
|
|||
bool
|
||||
spirv_write (struct pr_info_s *pr, const char *filename)
|
||||
{
|
||||
pr->module->entry_points = defspace_new (ds_backed);
|
||||
pr->module->entry_point_space = defspace_new (ds_backed);
|
||||
pr->module->exec_modes = defspace_new (ds_backed);
|
||||
pr->module->strings = defspace_new (ds_backed);
|
||||
pr->module->names = defspace_new (ds_backed);
|
||||
|
@ -1834,7 +1843,6 @@ spirv_write (struct pr_info_s *pr, const char *filename)
|
|||
pr->module->globals = defspace_new (ds_backed);
|
||||
pr->module->func_declarations = defspace_new (ds_backed);
|
||||
pr->module->func_definitions = defspace_new (ds_backed);
|
||||
DARRAY_INIT (&pr->module->interface_syms, 16);
|
||||
|
||||
spirvctx_t ctx = {
|
||||
.module = pr->module,
|
||||
|
@ -1852,14 +1860,8 @@ spirv_write (struct pr_info_s *pr, const char *filename)
|
|||
INSN (header, 3) = 0; // Filled in later
|
||||
INSN (header, 4) = 0; // Reserved
|
||||
|
||||
for (auto func = pr->func_head; func; func = func->next)
|
||||
{
|
||||
auto func_id = spirv_function (func, &ctx);
|
||||
if (strncmp ("main", func->o_name, 4) == 0
|
||||
&& (!func->o_name[4] || func->o_name[4] == '|')) {
|
||||
auto model = SpvExecutionModelVertex;//FIXME
|
||||
spirv_EntryPoint (func_id, func->o_name, model, &ctx);
|
||||
}
|
||||
for (auto ep = pr->module->entry_points; ep; ep = ep->next) {
|
||||
spirv_EntryPoint (ep, &ctx);
|
||||
}
|
||||
|
||||
auto mod = pr->module;
|
||||
|
@ -1885,7 +1887,7 @@ spirv_write (struct pr_info_s *pr, const char *filename)
|
|||
}
|
||||
|
||||
INSN (header, 3) = ctx.id + 1;
|
||||
ADD_DATA (space, mod->entry_points);
|
||||
ADD_DATA (space, mod->entry_point_space);
|
||||
ADD_DATA (space, mod->exec_modes);
|
||||
ADD_DATA (space, mod->strings);
|
||||
ADD_DATA (space, mod->names);
|
||||
|
@ -1986,6 +1988,24 @@ static void
|
|||
spirv_build_code (function_t *func, const expr_t *statements)
|
||||
{
|
||||
func->exprs = statements;
|
||||
if (strncmp ("main", func->o_name, 4) == 0
|
||||
&& (!func->o_name[4] || func->o_name[4] == '|')) {
|
||||
attribute_t *mode = nullptr;
|
||||
if (pr.module->default_model == SpvExecutionModelFragment) {
|
||||
mode = new_attribute ("mode",
|
||||
new_int_expr (SpvExecutionModeOriginUpperLeft, false));
|
||||
}
|
||||
entrypoint_t *ep = malloc (sizeof (entrypoint_t));
|
||||
*(ep) = (entrypoint_t) {
|
||||
.next = pr.module->entry_points,
|
||||
.model = pr.module->default_model,
|
||||
.name = "main",
|
||||
.modes = mode,
|
||||
.interface_syms = DARRAY_STATIC_INIT (16),
|
||||
.func = func,
|
||||
};
|
||||
pr.module->entry_points = ep;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue