0
0
Fork 0
mirror of https://git.code.sf.net/p/quake/quakeforge synced 2025-03-21 18:01:15 +00:00

[vulkan] Hook up the expression parser

The pipeline parser still isn't hooked up yet as something isn't quite
right, but it seems all the parsing works.
This commit is contained in:
Bill Currie 2020-12-21 18:38:31 +09:00
parent 4649294a27
commit 96df447c45
17 changed files with 332 additions and 89 deletions

View file

@ -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;

View file

@ -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 \

View file

@ -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 = ();
},

View file

@ -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];

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -13,6 +13,7 @@
}
-(void) forEachFieldCall: (varfunc) func;
-(void) writeTable: (PLItem *) parse;
-(void) writeSymtabInit:(PLItem *) parse;
@end
#endif//__renderer_vulkan_vkgen_vkstruct_h

View file

@ -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

View file

@ -19,6 +19,7 @@
-(Type *) resolveType;
+(Type *) findType: (qfot_type_t *) type;
+(Type *) lookup: (string) name;
-(string) cexprType;
-(string) parseType;
-(string) parseFunc;
-(string) parseData;

View file

@ -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";

View file

@ -1,2 +1,3 @@
#define __x86_64__
#include </usr/include/vulkan/vulkan.h>
#include "QF/Vulkan/swapchain.h"

View file

@ -38,6 +38,8 @@
# include <strings.h>
#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);
}

View file

@ -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

View file

@ -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;

View file

@ -39,6 +39,8 @@
# include <strings.h>
#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
}