mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
[vulkan] Implement pipeline layout creation
It seems to work when parsing the layouts. They can be created in-line (in theory) or in a "setLayouts" node and then referenced by name.
This commit is contained in:
parent
e4f75791ce
commit
d919a85c8e
6 changed files with 302 additions and 1 deletions
|
@ -45,6 +45,7 @@ typedef struct vulkan_ctx_s {
|
|||
struct hashlink_s *hashlinks; //FIXME want per thread
|
||||
VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain
|
||||
struct hashtab_s *shadermodules;
|
||||
struct hashtab_s *setLayouts;
|
||||
struct shadermodule_s *shadermodule_freelist;
|
||||
|
||||
VkCommandPool cmdpool;
|
||||
|
|
|
@ -14,6 +14,37 @@
|
|||
file = $builtin/pushcolor.frag;
|
||||
},
|
||||
);
|
||||
setLayouts = {
|
||||
something = {
|
||||
flags = 0;
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
descriptorType = sampled_image;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 1;
|
||||
descriptorType = uniform_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = vertex;
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
pipelineLayouts = {
|
||||
something = {
|
||||
setLayouts = (something);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 0;
|
||||
size = "4 * 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
renderpass = {
|
||||
attachments = (
|
||||
{
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "QF/vid.h"
|
||||
#include "QF/simd/vec4f.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/descriptor.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
|
@ -329,6 +330,21 @@ parse_custom (const plfield_t *field, const plitem_t *item,
|
|||
return custom->parse (item, offsets, messages, context);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_RGBA (const plitem_t *item, void **data,
|
||||
plitem_t *messages, parsectx_t *context)
|
||||
{
|
||||
int ret = 1;
|
||||
exprctx_t ectx = *context->ectx;
|
||||
exprval_t result = { &cexpr_vector, data[0] };
|
||||
ectx.symtab = 0;
|
||||
ectx.result = &result;
|
||||
const char *valstr = PL_String (item);
|
||||
Sys_Printf ("parse_RGBA: %s\n", valstr);
|
||||
ret = !cexpr_eval_string (valstr, &ectx);
|
||||
Sys_Printf (" "VEC4F_FMT"\n", VEC4_EXP (*(vec4f_t *)data[0]));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_VkShaderModule (const plitem_t *item, void **data,
|
||||
|
@ -344,6 +360,79 @@ parse_VkShaderModule (const plitem_t *item, void **data,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct setlayout_s {
|
||||
char *name;
|
||||
VkDescriptorSetLayout layout;
|
||||
} setlayout_t;
|
||||
|
||||
static const char *
|
||||
setLayout_getkey (const void *sl, void *unused)
|
||||
{
|
||||
return ((setlayout_t *)sl)->name;
|
||||
}
|
||||
|
||||
static void
|
||||
setLayout_free (void *sl, void *_ctx)
|
||||
{
|
||||
__auto_type setLayout = (setlayout_t *) sl;
|
||||
__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);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_VkDescriptorSetLayout (const plfield_t *field, const plitem_t *item,
|
||||
void *data, plitem_t *messages, void *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;
|
||||
}
|
||||
|
||||
static plelement_t setLayout_data = {
|
||||
QFDictionary,
|
||||
sizeof (setlayout_t),
|
||||
malloc,
|
||||
parse_VkDescriptorSetLayout,
|
||||
0,
|
||||
};
|
||||
|
||||
static plfield_t setLayout_field = { 0, 0, QFDictionary, 0, &setLayout_data };
|
||||
|
||||
static hashtab_t *enum_symtab;
|
||||
|
||||
#include "libs/video/renderer/vulkan/vkparse.cinc"
|
||||
|
@ -440,6 +529,33 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
return renderpass;
|
||||
}
|
||||
|
||||
void
|
||||
QFV_ParseDescriptorSetLayouts (vulkan_ctx_t *ctx, plitem_t *sets)
|
||||
{
|
||||
plitem_t *messages = PL_NewArray ();
|
||||
exprctx_t exprctx = {};
|
||||
parsectx_t parsectx = { &exprctx, ctx };
|
||||
|
||||
exprctx.memsuper = new_memsuper ();
|
||||
exprctx.messages = messages;
|
||||
exprctx.hashlinks = ctx->hashlinks;
|
||||
|
||||
if (!ctx->setLayouts) {
|
||||
ctx->setLayouts = Hash_NewTable (23, setLayout_getkey, setLayout_free,
|
||||
ctx, &exprctx.hashlinks);
|
||||
}
|
||||
int res = PL_ParseSymtab (&setLayout_field, sets, ctx->setLayouts,
|
||||
messages, &parsectx);
|
||||
if (!res || developer->int_val & SYS_VULKAN) {
|
||||
for (int i = 0; i < PL_A_NumObjects (messages); i++) {
|
||||
Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i)));
|
||||
}
|
||||
}
|
||||
PL_Free (messages);
|
||||
delete_memsuper (exprctx.memsuper);
|
||||
ctx->hashlinks = exprctx.hashlinks;
|
||||
}
|
||||
|
||||
static const char *
|
||||
enum_symtab_getkey (const void *e, void *unused)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@ typedef struct parsectx_s {
|
|||
struct vulkan_ctx_s *vctx;
|
||||
} parsectx_t;
|
||||
|
||||
|
||||
void QFV_ParseDescriptorSetLayouts (vulkan_ctx_t *ctx, plitem_t *sets);
|
||||
VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist);
|
||||
void QFV_InitParse (void);
|
||||
exprenum_t *QFV_GetEnum (const char *name);
|
||||
|
|
|
@ -5,6 +5,18 @@
|
|||
VkSubpassDependency,
|
||||
VkSpecializationInfo,
|
||||
VkPipelineShaderStageCreateInfo,
|
||||
VkPipelineVertexInputStateCreateInfo,
|
||||
VkPipelineInputAssemblyStateCreateInfo,
|
||||
VkPipelineViewportStateCreateInfo,
|
||||
VkPipelineRasterizationStateCreateInfo,
|
||||
VkPipelineMultisampleStateCreateInfo,
|
||||
VkPipelineDepthStencilStateCreateInfo,
|
||||
VkPipelineColorBlendStateCreateInfo,
|
||||
VkPipelineDynamicStateCreateInfo,
|
||||
VkDescriptorSetLayoutBinding,
|
||||
VkDescriptorSetLayoutCreateInfo,
|
||||
VkPushConstantRange,
|
||||
VkPipelineLayoutCreateInfo,
|
||||
qfv_swapchain_t,
|
||||
);
|
||||
parse = {
|
||||
|
@ -69,5 +81,125 @@
|
|||
};
|
||||
};
|
||||
VkShaderModuleCreateInfo = skip;
|
||||
VkDescriptorSetLayoutBinding = {
|
||||
binding = auto;
|
||||
descriptorType = auto;
|
||||
descriptorCount = auto;
|
||||
stageFlags = auto;
|
||||
// skip pImmutableSamplers (default to 0) until I know how it works
|
||||
};
|
||||
VkDescriptorSetLayoutCreateInfo = {
|
||||
flags = auto;
|
||||
bindings = {
|
||||
type = (array, VkDescriptorSetLayoutBinding);
|
||||
size = bindingCount;
|
||||
values = pBindings;
|
||||
};
|
||||
};
|
||||
VkPipelineVertexInputStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
bindings = {
|
||||
type = (array, VkVertexInputBindingDescription);
|
||||
size = vertexBindingDescriptionCount;
|
||||
values = pVertexBindingDescriptions;
|
||||
};
|
||||
attributes = {
|
||||
type = (array, VkVertexInputAttributeDescription);
|
||||
size = vertexAttributeDescriptionCount;
|
||||
values = pVertexAttributeDescriptions;
|
||||
};
|
||||
};
|
||||
VkPipelineInputAssemblyStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
topology = auto;
|
||||
primitiveRestartEnable = auto;
|
||||
};
|
||||
VkPipelineViewportStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
//FIXME redo as one array
|
||||
viewports = {
|
||||
type = (array, VkViewport);
|
||||
size = viewportCount;
|
||||
values = pViewports;
|
||||
};
|
||||
scissors = {
|
||||
type = (array, VkRect2D);
|
||||
size = scissorCount;
|
||||
values = pScissors;
|
||||
};
|
||||
};
|
||||
VkPipelineRasterizationStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
depthClampEnable = auto;
|
||||
rasterizerDiscardEnable = auto;
|
||||
polygonMode = auto;
|
||||
cullMode = auto;
|
||||
frontFace = auto;
|
||||
depthBiasEnable = auto;
|
||||
depthBiasConstantFactor = auto;
|
||||
depthBiasClamp = auto;
|
||||
depthBiasSlopeFactor = auto;
|
||||
lineWidth = auto;
|
||||
};
|
||||
VkPipelineMultisampleStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
rasterizationSamples = auto;
|
||||
sampleShadingEnable = auto;
|
||||
minSampleShading = auto;
|
||||
//pSampleMask = auto; FIXME disabled until correct size is known
|
||||
alphaToCoverageEnable = auto;
|
||||
alphaToOneEnable = auto;
|
||||
};
|
||||
VkPipelineDepthStencilStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
depthTestEnable = auto;
|
||||
depthWriteEnable = auto;
|
||||
depthCompareOp = auto;
|
||||
depthBoundsTestEnable = auto;
|
||||
stencilTestEnable = auto;
|
||||
front = auto;
|
||||
back = auto;
|
||||
minDepthBounds = auto;
|
||||
maxDepthBounds = auto;
|
||||
};
|
||||
VkPipelineColorBlendStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
logicOpEnable = auto;
|
||||
logicOp = auto;
|
||||
attachments = {
|
||||
type = (array, VkPipelineColorBlendAttachmentState);
|
||||
size = attachmentCount;
|
||||
values = pAttachments;
|
||||
};
|
||||
blendConstants = {
|
||||
type = (custom, QFString, parse_RGBA);
|
||||
fields = (blendConstants);
|
||||
};
|
||||
};
|
||||
VkPipelineDynamicStateCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
dynamicState = {
|
||||
type = (array, VkDynamicState);
|
||||
size = dynamicStateCount;
|
||||
values = pDynamicStates;
|
||||
};
|
||||
};
|
||||
VkPipelineLayoutCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
setLayouts = {
|
||||
type = (array, {
|
||||
parse_type = (QFDictionary, QFString);
|
||||
type = VkDescriptorSetLayout;
|
||||
parser = parse_VkDescriptorSetLayout;
|
||||
});
|
||||
size = setLayoutCount;
|
||||
values = pSetLayouts;
|
||||
};
|
||||
pushConstantRanges = {
|
||||
type = (array, VkPushConstantRange);
|
||||
size = pushConstantRangeCount;
|
||||
values = pPushConstantRanges;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "QF/va.h"
|
||||
#include "QF/vid.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/descriptor.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
|
@ -401,8 +402,10 @@ Vulkan_DestroyRenderPass (vulkan_ctx_t *ctx)
|
|||
void
|
||||
Vulkan_CreatePipelines (vulkan_ctx_t *ctx)
|
||||
{
|
||||
plitem_t *item = qfv_load_pipeline ();
|
||||
plitem_t *pipeline_def = qfv_load_pipeline ();
|
||||
plitem_t *item;
|
||||
|
||||
item = pipeline_def;
|
||||
if (!item || !(item = PL_ObjectForKey (item, "modules"))) {
|
||||
Sys_Printf ("error loading modules\n");
|
||||
} else {
|
||||
|
@ -424,6 +427,22 @@ Vulkan_CreatePipelines (vulkan_ctx_t *ctx)
|
|||
QFV_RegisterShaderModule (ctx, name, module);
|
||||
}
|
||||
}
|
||||
|
||||
item = pipeline_def;
|
||||
if (!item || !(item = PL_ObjectForKey (item, "setLayouts"))) {
|
||||
Sys_Printf ("error loading setLayouts\n");
|
||||
} else {
|
||||
Sys_Printf ("Found setLayouts\n");
|
||||
QFV_ParseDescriptorSetLayouts (ctx, item);
|
||||
}
|
||||
|
||||
/*item = pipeline_def;
|
||||
if (!item || !(item = PL_ObjectForKey (item, "pipelineLayouts"))) {
|
||||
Sys_Printf ("error loading pipelineLayouts\n");
|
||||
} else {
|
||||
Sys_Printf ("Found pipelineLayouts\n");
|
||||
QFV_ParsePipelineLayouts (ctx, item);
|
||||
}*/
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue