diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index 2675d3036..411fcf4db 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -41,6 +41,7 @@ typedef struct vulkan_ctx_s { struct qfv_instance_s *instance; struct qfv_device_s *device; struct qfv_swapchain_s *swapchain; + struct hashlink_s *hashlinks; //FIXME want per thread VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain VkCommandPool cmdpool; diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index 1077ef6ca..e2b71bf07 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -233,12 +233,15 @@ libs_video_renderer_vid_render_vulkan_la_SOURCES = \ libs/video/renderer/vulkan/vkparse.lo: libs/video/renderer/vulkan/vkparse.c $(vkparse_src) -libs/video/renderer/vulkan/vulkan_vid_common.lo: libs/video/renderer/vulkan/vulkan_vid_common.c $(pipeline_gen) +libs/video/renderer/vulkan/vulkan_vid_common.lo: libs/video/renderer/vulkan/vulkan_vid_common.c ${vkparse_src} $(pipeline_gen) qwaq_curses = ruamoko/qwaq/qwaq-curses$(EXEEXT) +vkparse_cinc = libs/video/renderer/vulkan/vkparse.cinc +vkparse_hinc = libs/video/renderer/vulkan/vkparse.hinc vkparse_src = \ - libs/video/renderer/vulkan/vkparse.inc + ${vkparse_cinc} \ + ${vkparse_hinc} vkparse_plist = \ $(srcdir)/libs/video/renderer/vulkan/vkparse.plist @@ -247,9 +250,13 @@ V_VKGEN_ = $(V_VKGEN_@AM_DEFAULT_V@) V_VKGEN_0 = @echo " VKGEN " $@; V_VKGEN_1 = -libs/video/renderer/vulkan/vkparse.inc: $(vkgen) $(qwaq_curses) $(vkparse_plist) - $(V_VKGEN)$(qwaq_curses) $(vkgen) -- $(vkparse_plist) $@.t &&\ - $(am__mv) $@.t $@ +${vkparse_cinc}: $(vkgen) $(qwaq_curses) $(vkparse_plist) + $(V_VKGEN)$(qwaq_curses) $(vkgen) -- $(vkparse_plist) ${vkparse_cinc}.t ${vkparse_hinc}.t &&\ + $(am__mv) ${vkparse_cinc}.t ${vkparse_cinc} &&\ + $(am__mv) ${vkparse_hinc}.t ${vkparse_hinc} + +${vkparse_hinc}: ${vkparse_cinc} +# do nothing: hinc generated at the same time as cinc CLEANFILES += \ libs/video/renderer/glsl/*.vc \ diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 1c594aee0..a8e1c36c9 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -14,18 +14,18 @@ }, { flags = 0; - format = $swapchain.format; - samples = $msaaSamples; + format = VK_FORMAT_D32_SFLOAT; + samples = $cvars.msaaSamples; loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - storeOp = VK_ATTACHMENT_STORE_OP_STORE; + storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; }, { flags = 0; - format = VK_FORMAT_D32_SFLOAT; + format = $swapchain.format; samples = VK_SAMPLE_COUNT_1_BIT; loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -37,6 +37,7 @@ ); subpasses = ( { + pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; colorAttachments = ( { attachment = 0; @@ -51,7 +52,7 @@ ); depthStencilAttachment = { attachment = 1; - layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; }; preserveAttachments = (); }, diff --git a/libs/video/renderer/vulkan/vkgen/vkalias.r b/libs/video/renderer/vulkan/vkgen/vkalias.r index 6228ac230..132e6291a 100644 --- a/libs/video/renderer/vulkan/vkgen/vkalias.r +++ b/libs/video/renderer/vulkan/vkgen/vkalias.r @@ -50,6 +50,24 @@ } } +-(string) cexprType +{ + Type *alias = [Type findType:type.alias.full_type]; + string name = [self name]; + + if ([alias name] == "VkFlags") { + if (str_mid (name, -5) == "Flags") { + string tag = str_mid (name, 0, -1) + "Bits"; + id enumObj = [(id) Hash_Find (available_types, tag) resolveType]; + return [enumObj cexprType]; + } + } + if (name == "uint32_t") { + return "cexpr_uint"; + } + return [alias cexprType]; +} + -(string) parseType { Type *alias = [Type findType:type.alias.full_type]; diff --git a/libs/video/renderer/vulkan/vkgen/vkenum.h b/libs/video/renderer/vulkan/vkgen/vkenum.h index 5deb7ff6f..6694c24cb 100644 --- a/libs/video/renderer/vulkan/vkgen/vkenum.h +++ b/libs/video/renderer/vulkan/vkgen/vkenum.h @@ -3,11 +3,14 @@ #include "vktype.h" +@class PLItem; + @interface Enum: Type { int prefix_length; } -(void) writeTable; +-(void) writeSymtabInit:(PLItem *) parse; @end #endif//__renderer_vulkan_vkgen_vkenum_h diff --git a/libs/video/renderer/vulkan/vkgen/vkenum.r b/libs/video/renderer/vulkan/vkgen/vkenum.r index 768e4b8d4..e3894902a 100644 --- a/libs/video/renderer/vulkan/vkgen/vkenum.r +++ b/libs/video/renderer/vulkan/vkgen/vkenum.r @@ -50,6 +50,15 @@ } } +static int +skip_value(string name) +{ + return (str_str (name, "_MAX_ENUM") >= 0 + || str_str (name, "_BEGIN_RANGE") >= 0 + || str_str (name, "_END_RANGE") >= 0 + || str_str (name, "_RANGE_SIZE") >= 0); +} + -(void) writeTable { int strip_bit = 0; @@ -57,16 +66,37 @@ strip_bit = 1; } - fprintf (output_file, "enumval_t %s_values[] = {\n", [self name]); - for (int i = 0; i < type.strct.num_fields; i++) { + fprintf (output_file, "static exprtype_t %s_type = {\n", [self name]); + fprintf (output_file, "\t\"%s\",\n", [self name]); + fprintf (output_file, "\tsizeof (int),\n"); + if (strip_bit) { + fprintf (output_file, "\tflag_binops,\n"); + fprintf (output_file, "\tflag_unops,\n"); + } else { + fprintf (output_file, "\t0,\n"); + fprintf (output_file, "\t0,\n"); + } + fprintf (output_file, "};\n"); + + fprintf (output_file, "static %s %s_values[] = {\n", [self name], [self name]); + for (int i = 0, index = 0; i < type.strct.num_fields; i++) { qfot_var_t *var = &type.strct.fields[i]; - if (str_str (var.name, "_MAX_ENUM") >= 0 - || str_str (var.name, "_BEGIN_RANGE") >= 0 - || str_str (var.name, "_END_RANGE") >= 0 - || str_str (var.name, "_RANGE_SIZE") >= 0) { + if (skip_value (var.name)) { continue; } - fprintf (output_file, "\t{\"%s\", %d},\n", var.name, var.offset); + fprintf (output_file, "\t%s, // %d 0x%x\n", + var.name, var.offset, var.offset); + index++; + } + fprintf (output_file, "};\n"); + fprintf (output_file, "static exprsym_t %s_symbols[] = {\n", [self name]); + for (int i = 0, index = 0; i < type.strct.num_fields; i++) { + qfot_var_t *var = &type.strct.fields[i]; + if (skip_value (var.name)) { + continue; + } + fprintf (output_file, "\t{\"%s\", &%s_type, %s_values + %d},\n", + var.name, [self name], [self name], index); if (prefix_length) { string shortname = str_mid (var.name, prefix_length); if (strip_bit) { @@ -75,12 +105,33 @@ shortname = str_mid (shortname, 0, bit_pos); } } - fprintf (output_file, "\t{\"%s\", %d},\n", str_lower(shortname), - var.offset); + fprintf (output_file, "\t{\"%s\", &%s_type, %s_values + %d},\n", + str_lower(shortname), [self name], [self name], index); } + index++; } fprintf (output_file, "\t{ }\n"); fprintf (output_file, "};\n"); + fprintf (output_file, "static exprtab_t %s_symtab = {\n", [self name]); + fprintf (output_file, "\t%s_symbols,\n", [self name]); + fprintf (output_file, "};\n"); + fprintf (output_file, "exprenum_t %s_enum = {\n", [self name]); + fprintf (output_file, "\t&%s_type,\n", [self name]); + fprintf (output_file, "\t&%s_symtab,\n", [self name]); + fprintf (output_file, "};\n"); + + fprintf (header_file, "extern exprenum_t %s_enum;\n", [self name]); +} + +-(void) writeSymtabInit:(PLItem *) parse +{ + fprintf (output_file, "\tcexpr_init_symtab (&%s_symtab, context);\n", + [self name]); +} + +-(string) cexprType +{ + return [self name] + "_type"; } -(string) parseType @@ -90,14 +141,11 @@ -(string) parseFunc { - if (str_mid([self name], -8) == "FlagBits") { - return "parse_flags"; - } return "parse_enum"; } -(string) parseData { - return [self name] + "_values"; + return "&" + [self name] + "_enum"; } @end diff --git a/libs/video/renderer/vulkan/vkgen/vkgen.h b/libs/video/renderer/vulkan/vkgen/vkgen.h index 0d488abe8..e60499f25 100644 --- a/libs/video/renderer/vulkan/vkgen/vkgen.h +++ b/libs/video/renderer/vulkan/vkgen/vkgen.h @@ -13,6 +13,7 @@ void fprintf (QFile file, string format, ...); extern Array *queue; extern Array *output_types; extern QFile output_file; +extern QFile header_file; extern hashtab_t *processed_types; extern hashtab_t *available_types; diff --git a/libs/video/renderer/vulkan/vkgen/vkgen.r b/libs/video/renderer/vulkan/vkgen/vkgen.r index 7744d0cdc..025e3d2cc 100644 --- a/libs/video/renderer/vulkan/vkgen/vkgen.r +++ b/libs/video/renderer/vulkan/vkgen/vkgen.r @@ -25,7 +25,6 @@ arp_end (void) autorelease_pool = nil; } - void printf (string fmt, ...) = #0; void fprintf (QFile file, string format, ...) @@ -39,6 +38,7 @@ Array *queue; Array *output_types; QFile output_file; +QFile header_file; qfot_type_encodings_t *encodings; @@ -135,7 +135,7 @@ get_object_key (void *obj, void *unused) void usage (string name) { - printf ("%s [plist file] [output file]\n", name); + printf ("%s [plist file] [output file] [header file]\n", name); } int @@ -151,7 +151,7 @@ main(int argc, string *argv) arp_start (); - if (argc != 3) { + if (argc != 4) { usage (argv[0]); return 1; } @@ -211,6 +211,7 @@ main(int argc, string *argv) arp_end (); output_file = Qopen (argv[2], "wt"); + header_file = Qopen (argv[3], "wt"); for (int i = [output_types count]; i-- > 0; ) { id obj = [output_types objectAtIndex:i]; if ([obj name] == "VkStructureType") { @@ -237,6 +238,20 @@ main(int argc, string *argv) [obj writeTable:parse]; arp_end (); } + fprintf (output_file, "static void\n"); + fprintf (output_file, "vkgen_init_symtabs (exprctx_t *context)\n"); + fprintf (output_file, "{\n"); + for (int i = [output_types count]; i-- > 0; ) { + id obj = [output_types objectAtIndex:i]; + if ([obj name] == "VkStructureType") { + continue; + } + arp_start (); + [obj writeSymtabInit:parse]; + arp_end (); + } + fprintf (output_file, "}\n"); Qclose (output_file); + Qclose (header_file); return 0; } diff --git a/libs/video/renderer/vulkan/vkgen/vkstruct.h b/libs/video/renderer/vulkan/vkgen/vkstruct.h index 246d23070..c251cb4c0 100644 --- a/libs/video/renderer/vulkan/vkgen/vkstruct.h +++ b/libs/video/renderer/vulkan/vkgen/vkstruct.h @@ -13,6 +13,7 @@ } -(void) forEachFieldCall: (varfunc) func; -(void) writeTable: (PLItem *) parse; +-(void) writeSymtabInit:(PLItem *) parse; @end #endif//__renderer_vulkan_vkgen_vkstruct_h diff --git a/libs/video/renderer/vulkan/vkgen/vkstruct.r b/libs/video/renderer/vulkan/vkgen/vkstruct.r index b1bf22960..4c9040cb6 100644 --- a/libs/video/renderer/vulkan/vkgen/vkstruct.r +++ b/libs/video/renderer/vulkan/vkgen/vkstruct.r @@ -162,7 +162,11 @@ fprintf (output_file, "\t{ }\n"); fprintf (output_file, "};\n"); - fprintf (output_file, "static int parse_%s (const plfield_t *field," + fprintf (header_file, "int parse_%s (const plfield_t *field," + " const plitem_t *item, void *data, plitem_t *messages," + " void *context);\n", + name); + fprintf (output_file, "int parse_%s (const plfield_t *field," " const plitem_t *item, void *data, plitem_t *messages," " void *context)\n", name); @@ -172,6 +176,95 @@ " context);\n", name); fprintf (output_file, "}\n"); + + fprintf (output_file, "static exprsym_t %s_symbols[] = {\n", name); + if (field_defs) { + PLItem *field_def; + qfot_var_t *field; + + for (int i = [field_defs count]; i-- > 0; ) { + string field_name = [[field_defs getObjectAtIndex:i] string]; + field_def = [field_dict getObjectForKey:field_name]; + PLItem *type_desc = [field_def getObjectForKey:"type"]; + string type_record; + string type_type; + string size_field = nil; + string value_field = nil; + + if (str_mid(field_name, 0, 1) == ".") { + continue; + } + field_def = [field_dict getObjectForKey:field_name]; + if ([field_def string] == "auto") { + field = [self findField:field_name]; + if (!field) { + continue; + } + field_type = [Type findType: field.type]; + fprintf (output_file, + "\t{\"%s\", &%s, (void *) field_offset (%s, %s)},\n", + field_name, [field_type cexprType], name, field_name); + } else { + type_record = [[type_desc getObjectAtIndex:0] string]; + if (type_record == "single") { + value_field = [[field_def getObjectForKey:"value"] string]; + } else { + value_field = [[field_def getObjectForKey:"values"] string]; + } + if (!value_field) { + value_field = field_name; + } + fprintf (output_file, + "\t{\"%s\", 0/*FIXME*/," + " (void *) field_offset (%s, %s)},\n", + field_name, name, value_field); + } + } + } else { + for (int i = 0; i < type.strct.num_fields; i++) { + qfot_var_t *field = &type.strct.fields[i]; + if (field.name == "sType" || field.name == "pNext") { + continue; + } + field_type = [Type findType: field.type]; + fprintf (output_file, + "\t{\"%s\", &%s, (void *) field_offset (%s, %s)},\n", + field.name, [field_type cexprType], name, field.name); + } + } + fprintf (output_file, "\t{ }\n"); + fprintf (output_file, "};\n"); + + fprintf (output_file, "static exprtab_t %s_symtab = {\n", name); + fprintf (output_file, "\t%s_symbols,\n", name); + fprintf (output_file, "};\n"); + + fprintf (output_file, "exprtype_t %s_type = {\n", name); + fprintf (output_file, "\t\"%s\",\n", name); + fprintf (output_file, "\tsizeof (%s),\n", name); + fprintf (output_file, "\tcexpr_struct_binops,\n"); + fprintf (output_file, "\t0,\n"); + fprintf (output_file, "\t&%s_symtab,\n", name); + fprintf (output_file, "};\n"); + fprintf (header_file, "extern exprtype_t %s_type;\n", name); +} + +-(void) writeSymtabInit:(PLItem *) parse +{ + string name = [self name]; + PLItem *field_dict = [parse getObjectForKey:name]; + PLItem *new_name = [field_dict getObjectForKey:".name"]; + + if (new_name) { + name = [new_name string]; + } + + fprintf (output_file, "\tcexpr_init_symtab (&%s_symtab, context);\n", name); +} + +-(string) cexprType +{ + return [self name] + "_type"; } -(string) parseType diff --git a/libs/video/renderer/vulkan/vkgen/vktype.h b/libs/video/renderer/vulkan/vkgen/vktype.h index fc5a53c84..0008c83ab 100644 --- a/libs/video/renderer/vulkan/vkgen/vktype.h +++ b/libs/video/renderer/vulkan/vkgen/vktype.h @@ -19,6 +19,7 @@ -(Type *) resolveType; +(Type *) findType: (qfot_type_t *) type; +(Type *) lookup: (string) name; +-(string) cexprType; -(string) parseType; -(string) parseFunc; -(string) parseData; diff --git a/libs/video/renderer/vulkan/vkgen/vktype.r b/libs/video/renderer/vulkan/vkgen/vktype.r index caa7ac057..5d6c1b7ae 100644 --- a/libs/video/renderer/vulkan/vkgen/vktype.r +++ b/libs/video/renderer/vulkan/vkgen/vktype.r @@ -91,6 +91,11 @@ static string get_type_key (void *type, void *unused) return self; } +-(string) cexprType +{ + return "cexpr_" + [self name]; +} + -(string) parseType { return "no parse"; diff --git a/libs/video/renderer/vulkan/vkgen/vulkan.r b/libs/video/renderer/vulkan/vkgen/vulkan.r index 46b720d0c..a2a53be7c 100644 --- a/libs/video/renderer/vulkan/vkgen/vulkan.r +++ b/libs/video/renderer/vulkan/vkgen/vulkan.r @@ -1,2 +1,3 @@ #define __x86_64__ #include +#include "QF/Vulkan/swapchain.h" diff --git a/libs/video/renderer/vulkan/vkparse.c b/libs/video/renderer/vulkan/vkparse.c index a4b037202..55798c185 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -38,6 +38,8 @@ # include #endif +#include "QF/cexpr.h" +#include "QF/cmem.h" #include "QF/cvar.h" #include "QF/dstring.h" #include "QF/input.h" @@ -64,10 +66,41 @@ #include "util.h" #include "vkparse.h" -typedef struct enumval_s { - const char *name; - int value; -} enumval_t; +static void flag_or (const exprval_t *val1, const exprval_t *val2, + exprval_t *result, exprctx_t *ctx) +{ + *(int *) (result->value) = *(int *) (val1->value) | *(int *) (val2->value); +} + +static void flag_and (const exprval_t *val1, const exprval_t *val2, + exprval_t *result, exprctx_t *ctx) +{ + *(int *) (result->value) = *(int *) (val1->value) & *(int *) (val2->value); +} + +static void flag_cast_int (const exprval_t *val1, const exprval_t *val2, + exprval_t *result, exprctx_t *ctx) +{ + // FIXME should check value is valid + *(int *) (result->value) = *(int *) (val2->value); +} + +static void flag_not (const exprval_t *val, exprval_t *result, exprctx_t *ctx) +{ + *(int *) (result->value) = ~(*(int *) (val->value)); +} + +binop_t flag_binops[] = { + { '|', 0, 0, flag_or }, + { '&', 0, 0, flag_and }, + { '=', &cexpr_int, 0, flag_cast_int }, + {} +}; + +unop_t flag_unops[] = { + { '~', 0, flag_not }, + {} +}; typedef struct parse_single_s { pltype_t type; @@ -84,20 +117,8 @@ typedef struct parse_array_s { size_t size_offset; } parse_array_t; -static int find_enum (const char *valstr, enumval_t *enumval, int *val) -{ - while (enumval->name && strcmp (enumval->name, valstr) != 0) { - enumval++; - } - if (enumval->name) { - *val = enumval->value; - return 1; - } - return 0; -} - static int parse_uint32_t (const plfield_t *field, const plitem_t *item, - void *data, plitem_t *messages, void *ctx) + void *data, plitem_t *messages, void *context) { int ret = 1; const char *valstr = PL_String (item); @@ -125,47 +146,25 @@ static int parse_uint32_t (const plfield_t *field, const plitem_t *item, } static int parse_enum (const plfield_t *field, const plitem_t *item, - void *data, plitem_t *messages, void *ctx) + void *data, plitem_t *messages, void *context) { int ret = 1; - int val; + __auto_type enm = (exprenum_t *) field->data; + exprctx_t ectx = *(exprctx_t *)context; + exprval_t result = { enm->type, data }; + ectx.symtab = enm->symtab; + ectx.result = &result; const char *valstr = PL_String (item); - __auto_type enumval = (enumval_t *) field->data; - //Sys_Printf ("parse_enum: %s %zd %d %p %p %s\n", - // field->name, field->offset, field->type, field->parser, - // field->data, valstr); - if (find_enum (valstr, enumval, &val)) { - *(int *) data = val; - } else { - PL_Message (messages, item, "invalid enum: %s", valstr); - ret = 0; - } - return ret; -} - -static int parse_flags (const plfield_t *field, const plitem_t *item, - void *data, plitem_t *messages, void *ctx) -{ - int ret = 1; - int val; - const char *valstr = PL_String (item); - __auto_type enumval = (enumval_t *) field->data; - //Sys_Printf ("parse_flags: %s %zd %d %p %p %s\n", - // field->name, field->offset, field->type, field->parser, - // field->data, valstr); - if (find_enum (valstr, enumval, &val)) { - *(int *) data = val; - } else if (strcmp (valstr, "0") == 0) { - *(int *) data = 0; - } else { - PL_Message (messages, item, "invalid enum: %s", valstr); - ret = 0; - } + Sys_Printf ("parse_enum: %s %zd %d %p %p %s\n", + field->name, field->offset, field->type, field->parser, + field->data, valstr); + ret = !cexpr_parse_enum (enm, valstr, &ectx, data); + Sys_Printf (" %d\n", *(int *)data); return ret; } static int parse_single (const plfield_t *field, const plitem_t *item, - void *data, plitem_t *messages, void *ctx) + void *data, plitem_t *messages, void *context) { __auto_type single = (parse_single_t *) field->data; void *flddata = (byte *)data + single->value_offset; @@ -180,7 +179,7 @@ static int parse_single (const plfield_t *field, const plitem_t *item, plfield_t f = { 0, 0, single->type, single->parser, 0 }; void *value = calloc (1, single->stride); - if (!single->parser (&f, item, value, messages, ctx)) { + if (!single->parser (&f, item, value, messages, context)) { free (value); return 0; } @@ -190,7 +189,7 @@ static int parse_single (const plfield_t *field, const plitem_t *item, } static int parse_array (const plfield_t *field, const plitem_t *item, - void *data, plitem_t *messages, void *ctx) + void *data, plitem_t *messages, void *context) { __auto_type array = (parse_array_t *) field->data; __auto_type value = (void **) ((byte *)data + array->value_offset); @@ -213,7 +212,7 @@ static int parse_array (const plfield_t *field, const plitem_t *item, // field->data, data); //Sys_Printf (" %d %zd %p %zd %zd\n", array->type, array->stride, // array->parser, array->value_offset, array->size_offset); - if (!PL_ParseArray (&f, item, &arr, messages, ctx)) { + if (!PL_ParseArray (&f, item, &arr, messages, context)) { return 0; } *value = malloc (array->stride * arr->size); @@ -225,7 +224,7 @@ static int parse_array (const plfield_t *field, const plitem_t *item, return 1; } -#include "libs/video/renderer/vulkan/vkparse.inc" +#include "libs/video/renderer/vulkan/vkparse.cinc" typedef struct qfv_renderpass_s { qfv_attachmentdescription_t *attachments; @@ -268,20 +267,37 @@ static plfield_t renderpass_fields[] = { }; VkRenderPass -QFV_ParseRenderPass (qfv_device_t *device, plitem_t *plist) +QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist) { + qfv_device_t *device = ctx->device; qfv_renderpass_t renderpass_data = {}; plitem_t *messages = PL_NewArray (); VkRenderPass renderpass; + exprsym_t var_syms[] = { + {"swapchain", &qfv_swapchain_t_type, ctx->swapchain}, + {} + }; + exprtab_t vars_tab = { var_syms, 0 }; + exprctx_t exprctx = {}; + + exprctx.external_variables = &vars_tab; + exprctx.memsuper = new_memsuper (); + exprctx.messages = messages; + exprctx.hashlinks = ctx->hashlinks; + + cexpr_init_symtab (&vars_tab, &exprctx); if (!PL_ParseDictionary (renderpass_fields, plist, - &renderpass_data, messages, 0)) { + &renderpass_data, messages, &exprctx)) { for (int i = 0; i < PL_A_NumObjects (messages); i++) { Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i))); } return 0; } PL_Free (messages); + delete_memsuper (exprctx.memsuper); + ctx->hashlinks = exprctx.hashlinks; + renderpass = QFV_CreateRenderPass (device, renderpass_data.attachments, renderpass_data.subpasses, @@ -299,3 +315,10 @@ QFV_ParseRenderPass (qfv_device_t *device, plitem_t *plist) free (renderpass_data.dependencies); return renderpass; } + +void +QFV_InitParse (void) +{ + exprctx_t context = {}; + vkgen_init_symtabs (&context); +} diff --git a/libs/video/renderer/vulkan/vkparse.h b/libs/video/renderer/vulkan/vkparse.h index 0d14eecbe..ae8a30af9 100644 --- a/libs/video/renderer/vulkan/vkparse.h +++ b/libs/video/renderer/vulkan/vkparse.h @@ -2,9 +2,9 @@ #define __vkparse_h #include "QF/Vulkan/renderpass.h" +#include "libs/video/renderer/vulkan/vkparse.hinc" -VkRenderPass -QFV_ParseRenderPass (qfv_device_t *device, plitem_t *plist); - +VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist); +void QFV_InitParse (void); #endif//__vkparse_h diff --git a/libs/video/renderer/vulkan/vkparse.plist b/libs/video/renderer/vulkan/vkparse.plist index 017025426..1441a0267 100644 --- a/libs/video/renderer/vulkan/vkparse.plist +++ b/libs/video/renderer/vulkan/vkparse.plist @@ -3,8 +3,13 @@ VkAttachmentDescription, VkSubpassDescription, VkSubpassDependency, + qfv_swapchain_t, ); parse = { + qfv_swapchain_s = { + .name = qfv_swapchain_t; + format = auto; + }; VkSubpassDescription = { flags = auto; pipelineBindPoint = auto; diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index 6f0ba9892..b0d285ed6 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -39,6 +39,8 @@ # include #endif +#include "QF/cexpr.h" +#include "QF/cmem.h" #include "QF/cvar.h" #include "QF/dstring.h" #include "QF/input.h" @@ -63,12 +65,14 @@ #include "vid_vulkan.h" #include "util.h" +#include "vkparse.h" static const char quakeforge_pipeline[] = #include "libs/video/renderer/vulkan/qfpipeline.plc" ; cvar_t *vulkan_presentation_mode; +cvar_t *msaaSamples; static void vulkan_presentation_mode_f (cvar_t *var) @@ -87,6 +91,19 @@ vulkan_presentation_mode_f (cvar_t *var) } } +static void +msaaSamples_f (cvar_t *var) +{ + exprctx_t context = {}; + context.memsuper = new_memsuper(); + + if (cexpr_parse_enum (&VkSampleCountFlagBits_enum, var->string, &context, + &var->int_val)) { + Sys_Printf ("Invalid MSAA samples, using 1\n"); + var->int_val = VK_SAMPLE_COUNT_1_BIT; + } +} + static void Vulkan_Init_Cvars (void) { @@ -100,6 +117,9 @@ Vulkan_Init_Cvars (void) CVAR_NONE, vulkan_presentation_mode_f, "desired presentation mode (may fall " "back to fifo)."); + msaaSamples = Cvar_Get ("msaaSamples", "VK_SAMPLE_COUNT_1_BIT", + CVAR_NONE, msaaSamples_f, + "desired MSAA sample size."); } static const char *instance_extensions[] = { @@ -116,8 +136,8 @@ void Vulkan_Init_Common (vulkan_ctx_t *ctx) { Sys_Printf ("Vulkan_Init_Common\n"); + QFV_InitParse (); Vulkan_Init_Cvars (); - ctx->instance = QFV_CreateInstance (ctx, PACKAGE_STRING, 0x000702ff, 0, instance_extensions);//FIXME version }