mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-16 06:11:15 +00:00
[vulkan] Start work on a render job system
The jobs will become the core of the renderer, with each job step being one of a render pass, compute pass, or processor (CPU-only) task. The steps support dependencies, which will allow for threading the system in the future. Currently, just the structures, parse support, and prototype job specification (render.plist) have been implemented. No conversion to working data is done yet, and many things, in particular resources, will need to be reworked, but this gets the basic design in.
This commit is contained in:
parent
374ca602a7
commit
4cf1c167bd
6 changed files with 256 additions and 2 deletions
|
@ -123,6 +123,9 @@ typedef struct qfv_pipelineinfo_s {
|
|||
qfv_taskinfo_t *tasks;
|
||||
|
||||
VkPipelineCreateFlags flags;
|
||||
VkPipelineShaderStageCreateInfo *compute_stage;
|
||||
uint32_t dispatch[3];
|
||||
|
||||
uint32_t num_graph_stages;
|
||||
const VkPipelineShaderStageCreateInfo *graph_stages;
|
||||
const VkPipelineVertexInputStateCreateInfo *vertexInput;
|
||||
|
@ -167,7 +170,18 @@ typedef struct qfv_renderpassinfo_s {
|
|||
qfv_subpassinfo_t *subpasses;
|
||||
} qfv_renderpassinfo_t;
|
||||
|
||||
typedef struct qfv_computeinfo_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
|
||||
uint32_t num_pipelines;
|
||||
qfv_pipelineinfo_t *pipelines;
|
||||
} qfv_computeinfo_t;
|
||||
|
||||
typedef struct qfv_renderinfo_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
|
||||
struct memsuper_s *memsuper;
|
||||
struct plitem_s *plitem;
|
||||
uint32_t num_images;
|
||||
|
@ -183,6 +197,33 @@ typedef struct qfv_renderinfo_s {
|
|||
qfv_layoutinfo_t *layouts;
|
||||
} qfv_renderinfo_t;
|
||||
|
||||
typedef struct qfv_processinfo_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
|
||||
uint32_t num_tasks;
|
||||
qfv_taskinfo_t *tasks;
|
||||
} qfv_processinfo_t;
|
||||
|
||||
typedef struct qfv_stepinfo_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
|
||||
uint32_t num_dependencies;
|
||||
qfv_reference_t *dependencies;
|
||||
|
||||
qfv_renderinfo_t *render;
|
||||
qfv_computeinfo_t *compute;
|
||||
qfv_processinfo_t *process;
|
||||
} qfv_stepinfo_t;
|
||||
|
||||
typedef struct qfv_jobinfo_s {
|
||||
struct memsuper_s *memsuper;
|
||||
|
||||
uint32_t num_steps;
|
||||
qfv_stepinfo_t *steps;
|
||||
} qfv_jobinfo_t;
|
||||
|
||||
typedef struct qfv_label_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
|
|
|
@ -196,7 +196,15 @@ count_sp_stuff (qfv_subpassinfo_t *spi, objcount_t *counts)
|
|||
if (spi->attachments) {
|
||||
count_as_stuff (spi->attachments, counts);
|
||||
}
|
||||
counts->num_pipelines += spi->num_pipelines;
|
||||
for (uint32_t i = 0; i < spi->num_pipelines; i++) {
|
||||
__auto_type pli = &spi->pipelines[i];
|
||||
if (pli->num_graph_stages && !pli->compute_stage) {
|
||||
counts->num_pipelines++;
|
||||
} else {
|
||||
Sys_Error ("%s:%s: invalid graphics pipeline",
|
||||
spi->name, pli->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
91
libs/video/renderer/vulkan/render.plist
Normal file
91
libs/video/renderer/vulkan/render.plist
Normal file
|
@ -0,0 +1,91 @@
|
|||
properties = {
|
||||
partphysics_layout = {
|
||||
setLayouts = (particle_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = compute;
|
||||
offset = 0;
|
||||
size = "4 * 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
partupdate_layout = {
|
||||
setLayouts = (particle_set, particle_set, particle_set);
|
||||
};
|
||||
};
|
||||
descriptorSetLayouts = {
|
||||
particle_set = {
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
descriptorType = storage_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = compute;
|
||||
},
|
||||
{
|
||||
binding = 1;
|
||||
descriptorType = storage_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = compute;
|
||||
},
|
||||
{
|
||||
binding = 2;
|
||||
descriptorType = storage_buffer;
|
||||
descriptorCount = 1;
|
||||
stageFlags = compute;
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
tasks = {
|
||||
particles = {
|
||||
compute = {
|
||||
pipelines = {
|
||||
part:update = {
|
||||
color = "[0.3, 0.8, 0.9]";
|
||||
tasks = (
|
||||
{ func = "update_particles"; }
|
||||
);
|
||||
stage = {
|
||||
name = main;
|
||||
module = $builtin/partupdate.comp;
|
||||
};
|
||||
layout = partupdate_layout;
|
||||
};
|
||||
part:physics = {
|
||||
color = "[0.6, 0.8, 0.9]";
|
||||
tasks = (
|
||||
{ func = "particle_physics"; }
|
||||
);
|
||||
stage = {
|
||||
name = main;
|
||||
module = $builtin/partphysics.comp;
|
||||
};
|
||||
layout = partphysics_layout;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
shadow = {
|
||||
//currently empty
|
||||
};
|
||||
translucent = {
|
||||
tasks = (
|
||||
{ func = "clear_translucent"; },
|
||||
)
|
||||
};
|
||||
main = {
|
||||
depenencies = (particles, shadow, translucent);
|
||||
renderpass = main_def;
|
||||
};
|
||||
preoutput = {
|
||||
tasks = (
|
||||
{ func = "acquire_output"; },
|
||||
{ func = "update_input"; },
|
||||
);
|
||||
};
|
||||
output = {
|
||||
depenencies = (main, preoutput);
|
||||
renderpass = output;
|
||||
};
|
||||
};
|
|
@ -2362,6 +2362,62 @@ QFV_ParseRenderInfo (vulkan_ctx_t *ctx, plitem_t *item, qfv_renderctx_t *rctx)
|
|||
return ri;
|
||||
}
|
||||
|
||||
struct qfv_jobinfo_s *
|
||||
QFV_ParseJobInfo (vulkan_ctx_t *ctx, plitem_t *item, qfv_renderctx_t *rctx)
|
||||
{
|
||||
memsuper_t *memsuper = new_memsuper ();
|
||||
qfv_jobinfo_t *ri = cmemalloc (memsuper, sizeof (qfv_jobinfo_t));
|
||||
*ri = (qfv_jobinfo_t) { .memsuper = memsuper };
|
||||
|
||||
scriptctx_t *sctx = ctx->script_context;
|
||||
plitem_t *messages = PL_NewArray ();
|
||||
|
||||
exprctx_t exprctx = {
|
||||
.symtab = &root_symtab,
|
||||
.messages = messages,
|
||||
.hashctx = &sctx->hashctx,
|
||||
.memsuper = memsuper,
|
||||
};
|
||||
parsectx_t parsectx = {
|
||||
.ectx = &exprctx,
|
||||
.vctx = ctx,
|
||||
.data = rctx,
|
||||
};
|
||||
|
||||
static const char *extra_items[] = {
|
||||
"images",
|
||||
"views",
|
||||
"renderpasses",
|
||||
0
|
||||
};
|
||||
exprsym_t var_syms[] = {
|
||||
{"output", &qfv_output_t_type, &sctx->output},
|
||||
{"frames", &vulkan_frameset_t_type, &ctx->frames},
|
||||
{"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples},
|
||||
{"physDevLimits", &VkPhysicalDeviceLimits_type,
|
||||
&ctx->device->physDev->properties->limits },
|
||||
{}
|
||||
};
|
||||
exprctx.external_variables = QFV_CreateSymtab (item, "properties",
|
||||
extra_items, var_syms,
|
||||
&exprctx);
|
||||
|
||||
int ret;
|
||||
if (!(ret = parse_qfv_jobinfo_t (0, item, ri, messages, &parsectx))) {
|
||||
for (int i = 0; i < PL_A_NumObjects (messages); i++) {
|
||||
Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i)));
|
||||
}
|
||||
}
|
||||
QFV_DestroySymtab (exprctx.external_variables);
|
||||
PL_Free (messages);
|
||||
if (!ret) {
|
||||
delete_memsuper (memsuper);
|
||||
ri = 0;
|
||||
}
|
||||
|
||||
return ri;
|
||||
}
|
||||
|
||||
int
|
||||
QFV_ParseLayoutInfo (vulkan_ctx_t *ctx, memsuper_t *memsuper,
|
||||
exprtab_t *symtab, const char *ref,
|
||||
|
|
|
@ -90,4 +90,6 @@ struct memsuper_s;
|
|||
int QFV_ParseLayoutInfo (vulkan_ctx_t *ctx, struct memsuper_s *memsuper,
|
||||
exprtab_t *symtab, const char *ref,
|
||||
qfv_layoutinfo_t *layout);
|
||||
struct qfv_jobinfo_s *QFV_ParseJobInfo (vulkan_ctx_t *ctx, plitem_t *item,
|
||||
struct qfv_renderctx_s *rctx);
|
||||
#endif//__vkparse_h
|
||||
|
|
|
@ -48,7 +48,10 @@
|
|||
qfv_framebufferinfo_t,
|
||||
qfv_renderpassinfo_t,
|
||||
qfv_renderinfo_t,
|
||||
qfv_pipelinespec_t,
|
||||
qfv_computeinfo_t,
|
||||
qfv_processinfo_t,
|
||||
qfv_stepinfo_t,
|
||||
qfv_jobinfo_t,
|
||||
);
|
||||
parse = {
|
||||
VkSubpassDescription = {
|
||||
|
@ -513,6 +516,11 @@
|
|||
size = num_graph_stages;
|
||||
values = graph_stages;
|
||||
};
|
||||
stage = {
|
||||
type = (single, VkPipelineShaderStageCreateInfo);
|
||||
value = compute_stage;
|
||||
};
|
||||
dispatch = auto;
|
||||
vertexInput = {
|
||||
type = (single, VkPipelineVertexInputStateCreateInfo);
|
||||
value = vertexInput;
|
||||
|
@ -616,8 +624,18 @@
|
|||
values = bindings;
|
||||
};
|
||||
};
|
||||
qfv_computeinfo_s = {
|
||||
.name = qfv_computeinfo_t;
|
||||
color = auto;
|
||||
pipelines = {
|
||||
type = (labeledarray, qfv_pipelineinfo_t, name);
|
||||
size = num_pipelines;
|
||||
values = pipelines;
|
||||
};
|
||||
};
|
||||
qfv_renderinfo_s = {
|
||||
.name = qfv_renderinfo_t;
|
||||
color = auto;
|
||||
properties = ignore;
|
||||
output = ignore;
|
||||
images = {
|
||||
|
@ -641,5 +659,43 @@
|
|||
values = descriptorsets;
|
||||
};
|
||||
};
|
||||
qfv_processinfo_s = {
|
||||
.name = qfv_processinfo_t;
|
||||
color = auto;
|
||||
tasks = {
|
||||
type = (array, qfv_taskinfo_t);
|
||||
size = num_tasks;
|
||||
values = tasks;
|
||||
};
|
||||
};
|
||||
qfv_stepinfo_s = {
|
||||
.name = qfv_stepinfo_t;
|
||||
color = auto;
|
||||
dependencies = {
|
||||
type = (array, qfv_reference_t);
|
||||
size = num_dependencies;
|
||||
values = dependencies;
|
||||
};
|
||||
render = {
|
||||
type = (single, qfv_renderinfo_t);
|
||||
value = render;
|
||||
};
|
||||
compute = {
|
||||
type = (single, qfv_computeinfo_t);
|
||||
value = compute;
|
||||
};
|
||||
process = {
|
||||
type = (single, qfv_processinfo_t);
|
||||
value = process;
|
||||
};
|
||||
};
|
||||
qfv_jobinfo_s = {
|
||||
.name = qfv_jobinfo_t;
|
||||
steps = {
|
||||
type = (array, qfv_stepinfo_t);
|
||||
size = num_steps;
|
||||
values = steps;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue