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;
|
const char *name;
|
||||||
attribute_t *modes;
|
attribute_t *modes;
|
||||||
ex_list_t interface; ///< list of symbols forming interface
|
ex_list_t interface; ///< list of symbols forming interface
|
||||||
|
struct DARRAY_TYPE (symbol_t *) interface_syms;
|
||||||
|
struct function_s *func;
|
||||||
} entrypoint_t;
|
} entrypoint_t;
|
||||||
|
|
||||||
typedef struct module_s {
|
typedef struct module_s {
|
||||||
ex_list_t capabilities;
|
ex_list_t capabilities;
|
||||||
ex_list_t extensions;
|
ex_list_t extensions;
|
||||||
|
SpvExecutionModel default_model;
|
||||||
symtab_t *extinst_imports;
|
symtab_t *extinst_imports;
|
||||||
const expr_t *addressing_model;
|
const expr_t *addressing_model;
|
||||||
const expr_t *memory_model;
|
const expr_t *memory_model;
|
||||||
struct DARRAY_TYPE (symbol_t *) interface_syms;
|
entrypoint_t *entry_points;
|
||||||
//entrypoint_t *entry_points;
|
defspace_t *entry_point_space;
|
||||||
defspace_t *entry_points;
|
|
||||||
defspace_t *exec_modes;
|
defspace_t *exec_modes;
|
||||||
// debug
|
// debug
|
||||||
defspace_t *strings;
|
defspace_t *strings;
|
||||||
|
|
|
@ -1014,6 +1014,7 @@ glsl_init_vert (rua_ctx_t *ctx)
|
||||||
glsl_parse_vars (glsl_Vulkan_vertex_vars, ctx);
|
glsl_parse_vars (glsl_Vulkan_vertex_vars, ctx);
|
||||||
|
|
||||||
spirv_add_capability (pr.module, SpvCapabilityShader);
|
spirv_add_capability (pr.module, SpvCapabilityShader);
|
||||||
|
pr.module->default_model = SpvExecutionModelVertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1023,6 +1024,7 @@ glsl_init_tesc (rua_ctx_t *ctx)
|
||||||
glsl_parse_vars (glsl_tesselation_control_vars, ctx);
|
glsl_parse_vars (glsl_tesselation_control_vars, ctx);
|
||||||
|
|
||||||
spirv_add_capability (pr.module, SpvCapabilityTessellation);
|
spirv_add_capability (pr.module, SpvCapabilityTessellation);
|
||||||
|
pr.module->default_model = SpvExecutionModelTessellationControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1032,6 +1034,7 @@ glsl_init_tese (rua_ctx_t *ctx)
|
||||||
glsl_parse_vars (glsl_tesselation_evaluation_vars, ctx);
|
glsl_parse_vars (glsl_tesselation_evaluation_vars, ctx);
|
||||||
|
|
||||||
spirv_add_capability (pr.module, SpvCapabilityTessellation);
|
spirv_add_capability (pr.module, SpvCapabilityTessellation);
|
||||||
|
pr.module->default_model = SpvExecutionModelTessellationEvaluation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1043,6 +1046,7 @@ glsl_init_geom (rua_ctx_t *ctx)
|
||||||
qc_parse_string (glsl_geometry_functions, &rua_ctx);
|
qc_parse_string (glsl_geometry_functions, &rua_ctx);
|
||||||
|
|
||||||
spirv_add_capability (pr.module, SpvCapabilityGeometry);
|
spirv_add_capability (pr.module, SpvCapabilityGeometry);
|
||||||
|
pr.module->default_model = SpvExecutionModelGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1052,4 +1056,5 @@ glsl_init_frag (rua_ctx_t *ctx)
|
||||||
glsl_parse_vars (glsl_fragment_vars, ctx);
|
glsl_parse_vars (glsl_fragment_vars, ctx);
|
||||||
|
|
||||||
spirv_add_capability (pr.module, SpvCapabilityShader);
|
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) {
|
if (storage == SpvStorageClassFunction) {
|
||||||
space = ctx->decl_space;
|
space = ctx->decl_space;
|
||||||
} else {
|
} else {
|
||||||
DARRAY_APPEND (&ctx->module->interface_syms, sym);
|
DARRAY_APPEND (&ctx->module->entry_points->interface_syms, sym);
|
||||||
}
|
}
|
||||||
auto type = sym->type;
|
auto type = sym->type;
|
||||||
unsigned tid = type_id (type, ctx);
|
unsigned tid = type_id (type, ctx);
|
||||||
|
@ -813,19 +813,28 @@ spirv_function (function_t *func, spirvctx_t *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
spirv_EntryPoint (unsigned func_id, const char *func_name,
|
spirv_EntryPoint (entrypoint_t *entrypoint, spirvctx_t *ctx)
|
||||||
SpvExecutionModel model, 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;
|
int iface_start = 3 + RUP(len, 4) / 4;
|
||||||
auto linkage = ctx->module->entry_points;
|
auto linkage = ctx->module->entry_point_space;
|
||||||
int count = ctx->module->interface_syms.size;
|
auto interface_syms = &entrypoint->interface_syms;
|
||||||
|
int count = interface_syms->size;
|
||||||
auto insn = spirv_new_insn (SpvOpEntryPoint, iface_start + count, linkage);
|
auto insn = spirv_new_insn (SpvOpEntryPoint, iface_start + count, linkage);
|
||||||
INSN (insn, 1) = model;
|
INSN (insn, 1) = entrypoint->model;
|
||||||
INSN (insn, 2) = func_id;
|
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++) {
|
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
|
bool
|
||||||
spirv_write (struct pr_info_s *pr, const char *filename)
|
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->exec_modes = defspace_new (ds_backed);
|
||||||
pr->module->strings = defspace_new (ds_backed);
|
pr->module->strings = defspace_new (ds_backed);
|
||||||
pr->module->names = 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->globals = defspace_new (ds_backed);
|
||||||
pr->module->func_declarations = defspace_new (ds_backed);
|
pr->module->func_declarations = defspace_new (ds_backed);
|
||||||
pr->module->func_definitions = defspace_new (ds_backed);
|
pr->module->func_definitions = defspace_new (ds_backed);
|
||||||
DARRAY_INIT (&pr->module->interface_syms, 16);
|
|
||||||
|
|
||||||
spirvctx_t ctx = {
|
spirvctx_t ctx = {
|
||||||
.module = pr->module,
|
.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, 3) = 0; // Filled in later
|
||||||
INSN (header, 4) = 0; // Reserved
|
INSN (header, 4) = 0; // Reserved
|
||||||
|
|
||||||
for (auto func = pr->func_head; func; func = func->next)
|
for (auto ep = pr->module->entry_points; ep; ep = ep->next) {
|
||||||
{
|
spirv_EntryPoint (ep, &ctx);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mod = pr->module;
|
auto mod = pr->module;
|
||||||
|
@ -1885,7 +1887,7 @@ spirv_write (struct pr_info_s *pr, const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
INSN (header, 3) = ctx.id + 1;
|
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->exec_modes);
|
||||||
ADD_DATA (space, mod->strings);
|
ADD_DATA (space, mod->strings);
|
||||||
ADD_DATA (space, mod->names);
|
ADD_DATA (space, mod->names);
|
||||||
|
@ -1986,6 +1988,24 @@ static void
|
||||||
spirv_build_code (function_t *func, const expr_t *statements)
|
spirv_build_code (function_t *func, const expr_t *statements)
|
||||||
{
|
{
|
||||||
func->exprs = 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
|
static void
|
||||||
|
|
Loading…
Reference in a new issue