[vulkan] Generate code for vulkan handles

The handles can be created in place or in resource blocks and referred
to by name (resource block code gen next).
This commit is contained in:
Bill Currie 2021-01-05 08:38:35 +09:00
parent 9039c6975a
commit d8261ade9e
8 changed files with 221 additions and 53 deletions

View file

@ -46,6 +46,8 @@ typedef struct vulkan_ctx_s {
VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain
struct hashtab_s *shadermodules; struct hashtab_s *shadermodules;
struct hashtab_s *setLayouts; struct hashtab_s *setLayouts;
struct hashtab_s *pipelineLayouts;
struct hashtab_s *renderPasses;
struct shadermodule_s *shadermodule_freelist; struct shadermodule_s *shadermodule_freelist;
VkCommandPool cmdpool; VkCommandPool cmdpool;

View file

@ -13,6 +13,7 @@ vkgen_dat_src= \
libs/video/renderer/vulkan/vkgen/vkfieldstring.r \ libs/video/renderer/vulkan/vkgen/vkfieldstring.r \
libs/video/renderer/vulkan/vkgen/vkfieldtype.r \ libs/video/renderer/vulkan/vkgen/vkfieldtype.r \
libs/video/renderer/vulkan/vkgen/vkgen.r \ libs/video/renderer/vulkan/vkgen/vkgen.r \
libs/video/renderer/vulkan/vkgen/vkhandle.r \
libs/video/renderer/vulkan/vkgen/vkstruct.r \ libs/video/renderer/vulkan/vkgen/vkstruct.r \
libs/video/renderer/vulkan/vkgen/vktype.r \ libs/video/renderer/vulkan/vkgen/vktype.r \
libs/video/renderer/vulkan/vkgen/vulkan.r libs/video/renderer/vulkan/vkgen/vulkan.r

View file

@ -115,7 +115,7 @@ skip_value(string name)
fprintf (output_file, "static exprtab_t %s_symtab = {\n", [self name]); fprintf (output_file, "static exprtab_t %s_symtab = {\n", [self name]);
fprintf (output_file, "\t%s_symbols,\n", [self name]); fprintf (output_file, "\t%s_symbols,\n", [self name]);
fprintf (output_file, "};\n"); fprintf (output_file, "};\n");
fprintf (output_file, "exprenum_t %s_enum = {\n", [self name]); fprintf (output_file, "static exprenum_t %s_enum = {\n", [self name]);
fprintf (output_file, "\t&%s_type,\n", [self name]); fprintf (output_file, "\t&%s_type,\n", [self name]);
fprintf (output_file, "\t&%s_symtab,\n", [self name]); fprintf (output_file, "\t&%s_symtab,\n", [self name]);
fprintf (output_file, "};\n"); fprintf (output_file, "};\n");
@ -138,7 +138,6 @@ skip_value(string name)
" const plitem_t *item, void *data, plitem_t *messages," " const plitem_t *item, void *data, plitem_t *messages,"
" void *context);\n", " void *context);\n",
[self name]); [self name]);
fprintf (header_file, "extern exprenum_t %s_enum;\n", [self name]);
} }
-(void) writeSymtabInit -(void) writeSymtabInit

View file

@ -10,6 +10,7 @@
#include "vkgen.h" #include "vkgen.h"
#include "vkstruct.h" #include "vkstruct.h"
#include "vkenum.h" #include "vkenum.h"
#include "vkhandle.h"
static AutoreleasePool *autorelease_pool; static AutoreleasePool *autorelease_pool;
static void static void
@ -148,6 +149,7 @@ main(int argc, string *argv)
QFile plist_file; QFile plist_file;
PLItem *plist; PLItem *plist;
PLItem *search; PLItem *search;
PLItem *handles;
arp_start (); arp_start ();
@ -171,6 +173,7 @@ main(int argc, string *argv)
printf ("%s not a dictionary\n", plist_filename); printf ("%s not a dictionary\n", plist_filename);
} }
search = [[plist getObjectForKey: "search"] retain]; search = [[plist getObjectForKey: "search"] retain];
handles = [[plist getObjectForKey: "handles"] retain];
parse = [[plist getObjectForKey: "parse"] retain]; parse = [[plist getObjectForKey: "parse"] retain];
encodings = PR_FindGlobal (".type_encodings"); encodings = PR_FindGlobal (".type_encodings");
@ -195,6 +198,17 @@ main(int argc, string *argv)
} }
} }
PLItem *handle_keys = [handles allKeys];
for (int i = [handle_keys count]; i-- > 0; ) {
string search_name = [[handle_keys getObjectAtIndex:i] string];
id obj = (id) Hash_Find (available_types, search_name);
obj = [obj resolveType];
printf("handle: %d %s\n", obj, class_get_class_name([obj class]));
if (obj && [obj class] == [Struct class]) {
[obj addToQueue];
}
}
while ([queue count]) { while ([queue count]) {
id obj = [queue objectAtIndex:0]; id obj = [queue objectAtIndex:0];
[queue removeObjectAtIndex:0]; [queue removeObjectAtIndex:0];
@ -241,6 +255,10 @@ main(int argc, string *argv)
[obj writeTable]; [obj writeTable];
arp_end (); arp_end ();
} }
for (int i = [handle_keys count]; i-- > 0; ) {
string key = [[handle_keys getObjectAtIndex:i] string];
output_handle (key, [handles getObjectForKey: key]);
}
fprintf (output_file, "static void\n"); fprintf (output_file, "static void\n");
fprintf (output_file, "vkgen_init_symtabs (exprctx_t *context)\n"); fprintf (output_file, "vkgen_init_symtabs (exprctx_t *context)\n");
fprintf (output_file, "{\n"); fprintf (output_file, "{\n");

View file

@ -0,0 +1,8 @@
#ifndef __renderer_vulkan_vkgen_vkhandle_h
#define __renderer_vulkan_vkgen_vkhandle_h
@class PLItem;
void output_handle (string name, PLItem *handle);
#endif//__renderer_vulkan_vkgen_vkhandle_h

View file

@ -0,0 +1,56 @@
#include <string.h>
#include <PropertyList.h>
#include "vkgen.h"
#include "vkhandle.h"
void
output_handle (string name, PLItem *handle)
{
string symtab = str_hold ([[handle getObjectForKey:"symtab"] string]);
string class = str_hold ([[handle getObjectForKey:"class"] string]);
string create = str_hold ([[handle getObjectForKey:"create"] string]);
fprintf (output_file, "static int parse_%s (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context)\n", name);
fprintf (output_file, "{\n");
fprintf (output_file, "\t__auto_type handle = (%s *) data;\n", name);
fprintf (output_file, "\tvulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx;\n");
fprintf (output_file, "\tqfv_device_t *device = ctx->device;\n");
fprintf (output_file, "\tqfv_devfuncs_t *dfunc = device->funcs;\n");
fprintf (output_file, "\tif (PL_Type (item) == QFString) {\n");
fprintf (output_file, "\t\tconst char *name = PL_String (item);\n");
fprintf (output_file, "\t\thandleref_t *hr = Hash_Find (ctx->%s, name);\n", symtab);
fprintf (output_file, "\t\tif (!hr) {\n");
fprintf (output_file, "\t\t\tPL_Message (messages, item, \"undefined %s %%s\", name);\n", class);
fprintf (output_file, "\t\t\treturn 0;\n");
fprintf (output_file, "\t\t}\n");
fprintf (output_file, "\t\t*handle = (%s) hr->handle;\n", name);
fprintf (output_file, "\t\treturn 1;\n");
fprintf (output_file, "\t}\n");
fprintf (output_file, "\t%sCreateInfo createInfo = {};\n", name);
fprintf (output_file, "\tif (!parse_%sCreateInfo (0, item, &createInfo, messages, context)) {\n", name);
fprintf (output_file, "\t\treturn 0;\n");
fprintf (output_file, "\t}\n");
fprintf (output_file, "\tVkResult res;\n");
fprintf (output_file, "\tres = dfunc->%s (device->dev, &createInfo, 0, handle);\n", create);
fprintf (output_file, "\tif (res != VK_SUCCESS) {\n");
fprintf (output_file, "\t\tPL_Message (messages, item, \"could not create %s\");\n", class);
fprintf (output_file, "\t\treturn 0;\n");
fprintf (output_file, "\t}\n");
fprintf (output_file, "\treturn 1;\n");
fprintf (output_file, "}\n");
fprintf (output_file, "int parse_%s_handleref (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context)\n", name);
fprintf (output_file, "{\n");
fprintf (output_file, "\thandleref_t *handleref = data;\n");
fprintf (output_file, "\thandleref->name = strdup (field->name);\n");
fprintf (output_file, "\treturn parse_%s (field, item, &handleref->handle, messages, context);\n", name);
fprintf (output_file, "}\n");
fprintf (header_file, "static int parse_%s (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context);\n", name);
fprintf (header_file, "int parse_%s_handleref (const plfield_t *field, const plitem_t *item, void *data, plitem_t *messages, void *context);\n", name);
str_free (symtab);
str_free (class);
str_free (create);
}

View file

@ -361,82 +361,61 @@ parse_VkShaderModule (const plitem_t *item, void **data,
return 0; return 0;
} }
typedef struct setlayout_s { typedef struct handleref_s {
char *name; char *name;
VkDescriptorSetLayout layout; uint64_t handle;
} setlayout_t; } handleref_t;
static const char * static const char *
setLayout_getkey (const void *sl, void *unused) handleref_getkey (const void *hr, void *unused)
{ {
return ((setlayout_t *)sl)->name; return ((handleref_t *)hr)->name;
} }
static void static void
setLayout_free (void *sl, void *_ctx) handleref_free (void *hr, void *_ctx)
{ {
__auto_type setLayout = (setlayout_t *) sl; __auto_type handleref = (handleref_t *) hr;
free (handleref->name);
free (handleref);
}
static void
setLayout_free (void *hr, void *_ctx)
{
__auto_type handleref = (handleref_t *) hr;
__auto_type layout = (VkDescriptorSetLayout) handleref->handle;
__auto_type ctx = (vulkan_ctx_t *) _ctx; __auto_type ctx = (vulkan_ctx_t *) _ctx;
qfv_device_t *device = ctx->device; qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs; qfv_devfuncs_t *dfunc = device->funcs;
dfunc->vkDestroyDescriptorSetLayout (device->dev, setLayout->layout, 0); dfunc->vkDestroyDescriptorSetLayout (device->dev, layout, 0);
free (setLayout->name); handleref_free (handleref, ctx);
free (setLayout);
} }
static hashtab_t *enum_symtab;
static int static int
parse_VkDescriptorSetLayout (const plfield_t *field, const plitem_t *item, parse_BasePipeline (const plitem_t *item, void **data,
void *data, plitem_t *messages, void *context) plitem_t *messages, parsectx_t *context)
{ {
__auto_type layout = (setlayout_t *) data; *(VkPipeline *) data = 0;
vulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx; PL_Message (messages, item, "not implemented");
qfv_device_t *device = ctx->device; return 0;
qfv_devfuncs_t *dfunc = device->funcs;
if (PL_Type (item) == QFString) {
// accessing a named set layout
const char *name = PL_String (item);
setlayout_t *l = Hash_Find (ctx->setLayouts, name);
if (!l) {
PL_Message (messages, item, "undefined set layout %s", name);
return 0;
}
*layout = *l;
return 1;
}
VkDescriptorSetLayoutCreateInfo createInfo = {};
if (!parse_VkDescriptorSetLayoutCreateInfo (0, item, &createInfo,
messages, context)) {
return 0;
}
layout->name = strdup (field->name);
VkResult res;
res = dfunc->vkCreateDescriptorSetLayout (device->dev, &createInfo, 0,
&layout->layout);
if (res != VK_SUCCESS) {
PL_Message (messages, item, "could not create set layout");
return 0;
}
return 1;
} }
#include "libs/video/renderer/vulkan/vkparse.cinc"
static plelement_t setLayout_data = { static plelement_t setLayout_data = {
QFDictionary, QFDictionary,
sizeof (setlayout_t), sizeof (handleref_t),
malloc, malloc,
parse_VkDescriptorSetLayout, parse_VkDescriptorSetLayout_handleref,
0, 0,
}; };
static plfield_t setLayout_field = { 0, 0, QFDictionary, 0, &setLayout_data }; static plfield_t setLayout_field = { 0, 0, QFDictionary, 0, &setLayout_data };
static hashtab_t *enum_symtab;
#include "libs/video/renderer/vulkan/vkparse.cinc"
typedef struct qfv_renderpass_s { typedef struct qfv_renderpass_s {
qfv_attachmentdescription_t *attachments; qfv_attachmentdescription_t *attachments;
qfv_subpassparametersset_t *subpasses; qfv_subpassparametersset_t *subpasses;
@ -541,7 +520,7 @@ QFV_ParseDescriptorSetLayouts (vulkan_ctx_t *ctx, plitem_t *sets)
exprctx.hashlinks = ctx->hashlinks; exprctx.hashlinks = ctx->hashlinks;
if (!ctx->setLayouts) { if (!ctx->setLayouts) {
ctx->setLayouts = Hash_NewTable (23, setLayout_getkey, setLayout_free, ctx->setLayouts = Hash_NewTable (23, handleref_getkey, setLayout_free,
ctx, &exprctx.hashlinks); ctx, &exprctx.hashlinks);
} }
int res = PL_ParseSymtab (&setLayout_field, sets, ctx->setLayouts, int res = PL_ParseSymtab (&setLayout_field, sets, ctx->setLayouts,

View file

@ -17,8 +17,26 @@
VkDescriptorSetLayoutCreateInfo, VkDescriptorSetLayoutCreateInfo,
VkPushConstantRange, VkPushConstantRange,
VkPipelineLayoutCreateInfo, VkPipelineLayoutCreateInfo,
VkGraphicsPipelineCreateInfo,
qfv_swapchain_t, qfv_swapchain_t,
); );
handles = {
VkDescriptorSetLayout = {
symtab = setLayouts;
class = "set layout";
create = vkCreateDescriptorSetLayout;
};
VkRenderPass = {
symtab = renderPasses;
class = "render pass";
create = vkCreateRenderPass;
};
VkPipelineLayout = {
symtab = pipelineLayouts;
class = "pipeline layout";
create = vkCreatePipelineLayout;
};
};
parse = { parse = {
qfv_swapchain_s = { qfv_swapchain_s = {
.name = qfv_swapchain_t; .name = qfv_swapchain_t;
@ -52,6 +70,24 @@
values = pPreserveAttachments; values = pPreserveAttachments;
}; };
}; };
VkRenderPassCreateInfo = {
//flags = auto; reserved for future use (Bits enum does not exist)
attachments = {
type = (array, VkAttachmentDescription);
size = attachmentCount;
values = pAttachments;
};
subpasses = {
type = (array, VkSubpassDescription);
size = subpassCount;
values = pSubpasses;
};
dependencies = {
type = (array, VkSubpassDependency);
size = dependencyCount;
values = pDependencies;
};
};
VkSpecializationInfo = { VkSpecializationInfo = {
mapEntries = { mapEntries = {
type = (array, VkSpecializationMapEntry); type = (array, VkSpecializationMapEntry);
@ -200,6 +236,75 @@
size = pushConstantRangeCount; size = pushConstantRangeCount;
values = pPushConstantRanges; values = pPushConstantRanges;
}; };
};
VkPipelineTessellationStateCreateInfo = {
//flags = auto; reserved for future use (Bits enum does not exist)
patchControlPoints = auto;
};
VkGraphicsPipelineCreateInfo = {
flags = auto;
stages = {
type = (array, VkPipelineShaderStageCreateInfo);
size = stageCount;
values = pStages;
};
vertexInput = {
type = (single, VkPipelineVertexInputStateCreateInfo);
value = pVertexInputState;
};
inputAssembly = {
type = (single, VkPipelineInputAssemblyStateCreateInfo);
value = pInputAssemblyState;
};
tessellation = {
type = (single, VkPipelineTessellationStateCreateInfo);
value = pTessellationState;
};
viewport = {
type = (single, VkPipelineViewportStateCreateInfo);
value = pViewportState;
};
rasterization = {
type = (single, VkPipelineRasterizationStateCreateInfo);
value = pRasterizationState;
};
multisample = {
type = (single, VkPipelineMultisampleStateCreateInfo);
value = pMultisampleState;
};
depthStencil = {
type = (single, VkPipelineDepthStencilStateCreateInfo);
value = pDepthStencilState;
};
colorBlend = {
type = (single, VkPipelineColorBlendStateCreateInfo);
value = pColorBlendState;
};
dynamic = {
type = (single, VkPipelineDynamicStateCreateInfo);
value = pDynamicState;
};
layout = {
type = (single, {
parse_type = (QFDictionary, QFString);
type = VkPipelineLayout;
parser = parse_VkPipelineLayout;
});
value = layout;
};
renderPass = {
type = (single, {
parse_type = (QFDictionary, QFString);
type = VkRenderPass;
parser = parse_VkRenderPass;
});
value = renderPass;
};
basePipelineHandle = {
type = (custom, QFString, parse_BasePipeline);
fields = (basePipelineHandle);
};
basePipelineIndex = auto;
} }
} }
} }