mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
[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:
parent
9039c6975a
commit
d8261ade9e
8 changed files with 221 additions and 53 deletions
|
@ -46,6 +46,8 @@ typedef struct vulkan_ctx_s {
|
|||
VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain
|
||||
struct hashtab_s *shadermodules;
|
||||
struct hashtab_s *setLayouts;
|
||||
struct hashtab_s *pipelineLayouts;
|
||||
struct hashtab_s *renderPasses;
|
||||
struct shadermodule_s *shadermodule_freelist;
|
||||
|
||||
VkCommandPool cmdpool;
|
||||
|
|
|
@ -13,6 +13,7 @@ vkgen_dat_src= \
|
|||
libs/video/renderer/vulkan/vkgen/vkfieldstring.r \
|
||||
libs/video/renderer/vulkan/vkgen/vkfieldtype.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/vktype.r \
|
||||
libs/video/renderer/vulkan/vkgen/vulkan.r
|
||||
|
|
|
@ -115,7 +115,7 @@ skip_value(string name)
|
|||
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, "static 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");
|
||||
|
@ -138,7 +138,6 @@ skip_value(string name)
|
|||
" const plitem_t *item, void *data, plitem_t *messages,"
|
||||
" void *context);\n",
|
||||
[self name]);
|
||||
fprintf (header_file, "extern exprenum_t %s_enum;\n", [self name]);
|
||||
}
|
||||
|
||||
-(void) writeSymtabInit
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "vkgen.h"
|
||||
#include "vkstruct.h"
|
||||
#include "vkenum.h"
|
||||
#include "vkhandle.h"
|
||||
|
||||
static AutoreleasePool *autorelease_pool;
|
||||
static void
|
||||
|
@ -148,6 +149,7 @@ main(int argc, string *argv)
|
|||
QFile plist_file;
|
||||
PLItem *plist;
|
||||
PLItem *search;
|
||||
PLItem *handles;
|
||||
|
||||
arp_start ();
|
||||
|
||||
|
@ -171,6 +173,7 @@ main(int argc, string *argv)
|
|||
printf ("%s not a dictionary\n", plist_filename);
|
||||
}
|
||||
search = [[plist getObjectForKey: "search"] retain];
|
||||
handles = [[plist getObjectForKey: "handles"] retain];
|
||||
parse = [[plist getObjectForKey: "parse"] retain];
|
||||
|
||||
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]) {
|
||||
id obj = [queue objectAtIndex:0];
|
||||
[queue removeObjectAtIndex:0];
|
||||
|
@ -241,6 +255,10 @@ main(int argc, string *argv)
|
|||
[obj writeTable];
|
||||
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, "vkgen_init_symtabs (exprctx_t *context)\n");
|
||||
fprintf (output_file, "{\n");
|
||||
|
|
8
libs/video/renderer/vulkan/vkgen/vkhandle.h
Normal file
8
libs/video/renderer/vulkan/vkgen/vkhandle.h
Normal 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
|
56
libs/video/renderer/vulkan/vkgen/vkhandle.r
Normal file
56
libs/video/renderer/vulkan/vkgen/vkhandle.r
Normal 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);
|
||||
}
|
|
@ -361,82 +361,61 @@ parse_VkShaderModule (const plitem_t *item, void **data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
typedef struct setlayout_s {
|
||||
typedef struct handleref_s {
|
||||
char *name;
|
||||
VkDescriptorSetLayout layout;
|
||||
} setlayout_t;
|
||||
uint64_t handle;
|
||||
} handleref_t;
|
||||
|
||||
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
|
||||
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;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
dfunc->vkDestroyDescriptorSetLayout (device->dev, setLayout->layout, 0);
|
||||
free (setLayout->name);
|
||||
free (setLayout);
|
||||
dfunc->vkDestroyDescriptorSetLayout (device->dev, layout, 0);
|
||||
handleref_free (handleref, ctx);
|
||||
}
|
||||
|
||||
static hashtab_t *enum_symtab;
|
||||
|
||||
static int
|
||||
parse_VkDescriptorSetLayout (const plfield_t *field, const plitem_t *item,
|
||||
void *data, plitem_t *messages, void *context)
|
||||
parse_BasePipeline (const plitem_t *item, void **data,
|
||||
plitem_t *messages, parsectx_t *context)
|
||||
{
|
||||
__auto_type layout = (setlayout_t *) data;
|
||||
vulkan_ctx_t *ctx = ((parsectx_t *) context)->vctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
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;
|
||||
*(VkPipeline *) data = 0;
|
||||
PL_Message (messages, item, "not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "libs/video/renderer/vulkan/vkparse.cinc"
|
||||
|
||||
static plelement_t setLayout_data = {
|
||||
QFDictionary,
|
||||
sizeof (setlayout_t),
|
||||
sizeof (handleref_t),
|
||||
malloc,
|
||||
parse_VkDescriptorSetLayout,
|
||||
parse_VkDescriptorSetLayout_handleref,
|
||||
0,
|
||||
};
|
||||
|
||||
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 {
|
||||
qfv_attachmentdescription_t *attachments;
|
||||
qfv_subpassparametersset_t *subpasses;
|
||||
|
@ -541,7 +520,7 @@ QFV_ParseDescriptorSetLayouts (vulkan_ctx_t *ctx, plitem_t *sets)
|
|||
exprctx.hashlinks = ctx->hashlinks;
|
||||
|
||||
if (!ctx->setLayouts) {
|
||||
ctx->setLayouts = Hash_NewTable (23, setLayout_getkey, setLayout_free,
|
||||
ctx->setLayouts = Hash_NewTable (23, handleref_getkey, setLayout_free,
|
||||
ctx, &exprctx.hashlinks);
|
||||
}
|
||||
int res = PL_ParseSymtab (&setLayout_field, sets, ctx->setLayouts,
|
||||
|
|
|
@ -17,8 +17,26 @@
|
|||
VkDescriptorSetLayoutCreateInfo,
|
||||
VkPushConstantRange,
|
||||
VkPipelineLayoutCreateInfo,
|
||||
VkGraphicsPipelineCreateInfo,
|
||||
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 = {
|
||||
qfv_swapchain_s = {
|
||||
.name = qfv_swapchain_t;
|
||||
|
@ -52,6 +70,24 @@
|
|||
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 = {
|
||||
mapEntries = {
|
||||
type = (array, VkSpecializationMapEntry);
|
||||
|
@ -200,6 +236,75 @@
|
|||
size = pushConstantRangeCount;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue