mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-19 07:51:08 +00:00
[vkgen] Improve .type parse spec handling
.dictionary can ask for standard parsing via a .parse key (value is ignored currently). Fields can use $auto to use standard parsing for that field. If either is used, the plist field descriptors are written.
This commit is contained in:
parent
d89ad6b00f
commit
868db37461
7 changed files with 857 additions and 115 deletions
|
@ -75,6 +75,7 @@ typedef struct qfv_taskinfo_s {
|
|||
typedef struct qfv_attachmentrefinfo_s {
|
||||
const char *name;
|
||||
VkImageLayout layout;
|
||||
VkPipelineColorBlendAttachmentState blend;
|
||||
} qfv_attachmentrefinfo_t;
|
||||
|
||||
typedef struct qfv_attachmentsetinfo_s {
|
||||
|
@ -94,6 +95,20 @@ typedef struct qfv_pipelineinfo_s {
|
|||
qfv_reference_t pipeline;
|
||||
uint32_t num_tasks;
|
||||
qfv_taskinfo_t *tasks;
|
||||
|
||||
VkPipelineCreateFlags flags;
|
||||
uint32_t num_graph_stages;
|
||||
const VkPipelineShaderStageCreateInfo *graph_stages;
|
||||
const VkPipelineVertexInputStateCreateInfo *vertexInput;
|
||||
const VkPipelineInputAssemblyStateCreateInfo *inputAssembly;
|
||||
const VkPipelineTessellationStateCreateInfo *tessellation;
|
||||
const VkPipelineViewportStateCreateInfo *viewport;
|
||||
const VkPipelineRasterizationStateCreateInfo *rasterization;
|
||||
const VkPipelineMultisampleStateCreateInfo *multisample;
|
||||
const VkPipelineDepthStencilStateCreateInfo *depthStencil;
|
||||
const VkPipelineColorBlendStateCreateInfo *colorBlend;
|
||||
const VkPipelineDynamicStateCreateInfo *dynamic;
|
||||
qfv_reference_t *layout;
|
||||
} qfv_pipelineinfo_t;
|
||||
|
||||
typedef struct qfv_subpassinfo_s {
|
||||
|
@ -105,6 +120,7 @@ typedef struct qfv_subpassinfo_s {
|
|||
qfv_attachmentrefinfo_t *attachments;
|
||||
uint32_t num_pipelines;
|
||||
qfv_pipelineinfo_t *pipelines;
|
||||
qfv_pipelineinfo_t *base_pipeline;
|
||||
} qfv_subpassinfo_t;
|
||||
|
||||
typedef struct qfv_framebufferinfo_s {
|
||||
|
@ -137,6 +153,7 @@ typedef struct qfv_renderinfo_s {
|
|||
typedef struct qfv_renderctx_s {
|
||||
struct hashctx_s *hashctx;
|
||||
exprtab_t task_functions;
|
||||
qfv_renderinfo_t *renderinfo;
|
||||
} qfv_renderctx_t;
|
||||
|
||||
typedef struct qfv_label_s {
|
||||
|
|
|
@ -1034,16 +1034,6 @@
|
|||
},
|
||||
);
|
||||
vertexInput = $properties.vertexInput.iqm;
|
||||
/*vertexInput = {
|
||||
bindings = (
|
||||
"$properties.vertexInput.iqm.bindings[0]",
|
||||
);
|
||||
attributes = (
|
||||
"$properties.vertexInput.iqm.attributes[0]",
|
||||
"$properties.vertexInput.iqm.attributes[1]",
|
||||
"$properties.vertexInput.iqm.attributes[2]",
|
||||
);
|
||||
};*/
|
||||
inputAssembly = $properties.inputAssembly.iqm;
|
||||
layout = iqm_layout;
|
||||
};
|
||||
|
|
|
@ -131,7 +131,7 @@ QFV_LoadRenderPass (vulkan_ctx_t *ctx)
|
|||
__auto_type rctx = ctx->render_context;
|
||||
|
||||
plitem_t *item = Vulkan_GetConfig (ctx, "main_def");
|
||||
QFV_ParseRenderInfo (ctx, item, rctx);
|
||||
rctx->renderinfo = QFV_ParseRenderInfo (ctx, item, rctx);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -69,6 +69,431 @@ properties = {
|
|||
finalLayout = color_attachment_optimal;
|
||||
clearValue = { color = "[0, 0, 0, 1]"; };
|
||||
};
|
||||
|
||||
cw_cull_back = {
|
||||
depthClampEnable = false;
|
||||
rasterizerDiscardEnable = false;
|
||||
polygonMode = fill;
|
||||
cullMode = back;
|
||||
frontFace = clockwise;
|
||||
depthBiasEnable = false;
|
||||
lineWidth = 1;
|
||||
};
|
||||
counter_cw_cull_back = {
|
||||
depthClampEnable = false;
|
||||
rasterizerDiscardEnable = false;
|
||||
polygonMode = fill;
|
||||
cullMode = back;
|
||||
frontFace = counter_clockwise;
|
||||
depthBiasEnable = false;
|
||||
lineWidth = 1;
|
||||
};
|
||||
depth_test_and_write = {
|
||||
depthTestEnable = true;
|
||||
depthWriteEnable = true;
|
||||
depthCompareOp = less_or_equal;
|
||||
depthBoundsTestEnable = false;
|
||||
stencilTestEnable = false;
|
||||
};
|
||||
depth_test_only = {
|
||||
depthTestEnable = true;
|
||||
depthWriteEnable = false;
|
||||
depthCompareOp = less_or_equal;
|
||||
depthBoundsTestEnable = false;
|
||||
stencilTestEnable = false;
|
||||
};
|
||||
depth_disable = {
|
||||
depthTestEnable = false;
|
||||
depthWriteEnable = false;
|
||||
depthCompareOp = less_or_equal;
|
||||
depthBoundsTestEnable = false;
|
||||
stencilTestEnable = false;
|
||||
};
|
||||
blend_disable = {
|
||||
blendEnable = false;
|
||||
srcColorBlendFactor = src_alpha;
|
||||
dstColorBlendFactor = one_minus_src_alpha;
|
||||
colorBlendOp = add;
|
||||
srcAlphaBlendFactor = src_alpha;
|
||||
dstAlphaBlendFactor = one_minus_src_alpha;
|
||||
alphaBlendOp = add;
|
||||
colorWriteMask = r|g|b|a;
|
||||
};
|
||||
pipeline_base = {
|
||||
viewport = {
|
||||
viewports = (
|
||||
{
|
||||
x = 0; y = 0;
|
||||
width = 640; height = 480;
|
||||
minDepth = 0; maxDepth = 1;
|
||||
}
|
||||
);
|
||||
scissors = (
|
||||
{
|
||||
offset = { x = 0; y = 0; };
|
||||
extent = { width = 640; height = 480; };
|
||||
},
|
||||
);
|
||||
};
|
||||
rasterization = $cw_cull_back;
|
||||
multisample = {
|
||||
rasterizationSamples = $msaaSamples;
|
||||
sampleShadingEnable = false;
|
||||
minSampleShading = 0.5f;
|
||||
alphaToCoverageEnable = false;
|
||||
alphaToOneEnable = false;
|
||||
};
|
||||
depthStencil = $depth_test_only;
|
||||
colorBlend = {
|
||||
logicOpEnable = false;
|
||||
};
|
||||
dynamic = {
|
||||
dynamicState = ( viewport, scissor );
|
||||
};
|
||||
};
|
||||
compose_base = {
|
||||
@inherit = $pipeline_base;
|
||||
vertexInput = {
|
||||
bindings = ();
|
||||
attributes = ();
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = triangle_list;
|
||||
primitiveRestartEnable = false;
|
||||
};
|
||||
};
|
||||
|
||||
brush = {
|
||||
shader = {
|
||||
depth_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/bsp_depth.vert;
|
||||
};
|
||||
gbuf_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/bsp_gbuf.vert;
|
||||
};
|
||||
gbuf_geometry = {
|
||||
stage = geometry;
|
||||
name = main;
|
||||
module = $builtin/bsp_gbuf.geom;
|
||||
};
|
||||
gbuf_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/bsp_gbuf.frag;
|
||||
};
|
||||
quake_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/quakebsp.vert;
|
||||
};
|
||||
sky_specialization = {
|
||||
mapEntries = (
|
||||
// doSkyBox
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
// doSkySheet
|
||||
{ size = 4; offset = 4; constantID = 1; },
|
||||
);
|
||||
};
|
||||
skybox_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/bsp_sky.frag;
|
||||
specializationInfo = {
|
||||
@inherit = $brush.shader.sky_specialization;
|
||||
// doSkyBox, doSkySheet
|
||||
data = "array(1, 0)";
|
||||
};
|
||||
};
|
||||
skysheet_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/bsp_sky.frag;
|
||||
specializationInfo = {
|
||||
@inherit = $brush.shader.sky_specialization;
|
||||
// doSkyBox, doSkySheet
|
||||
data = "array(0, 1)";
|
||||
};
|
||||
};
|
||||
turb_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/bsp_turb.frag;
|
||||
};
|
||||
};
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
{ binding = 0; stride = "2 * 4 * 4"; inputRate = vertex; },
|
||||
{ binding = 1; stride = "4"; inputRate = instance; },
|
||||
);
|
||||
attributes = (
|
||||
{ location = 0; binding = 0; format = r32g32b32a32_sfloat; offset = 0; },
|
||||
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
{ location = 2; binding = 1; format = r32_uint; offset = 0; },
|
||||
);
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = triangle_fan;
|
||||
primitiveRestartEnable = true;
|
||||
};
|
||||
layout = {
|
||||
setLayouts = (matrix_set, entity_set, oit_set, texture_set, texture_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 0;
|
||||
size = "4 * 4 + 4 + 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
alias = {
|
||||
shader = {
|
||||
depth_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/alias_depth.vert;
|
||||
};
|
||||
gbuf_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/alias.vert;
|
||||
};
|
||||
gbuf_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/alias_gbuf.frag;
|
||||
};
|
||||
};
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
{ binding = 0; stride = "2 * 4 * 4"; inputRate = vertex; },
|
||||
{ binding = 1; stride = "2 * 4 * 4"; inputRate = vertex; },
|
||||
{ binding = 2; stride = "2 * 4"; inputRate = instance; },
|
||||
);
|
||||
attributes = (
|
||||
{ location = 0; binding = 0; format = r32g32b32a32_sfloat; offset = 0; },
|
||||
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
{ location = 2; binding = 1; format = r32g32b32a32_sfloat; offset = 0; },
|
||||
{ location = 3; binding = 1; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
{ location = 4; binding = 2; format = r32g32_sfloat; offset = 0; },
|
||||
);
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = triangle_list;
|
||||
primitiveRestartEnable = false;
|
||||
};
|
||||
layout = {
|
||||
setLayouts = (matrix_set, texture_set, texture_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
offset = 0;
|
||||
size = "16 * 4 + 4";
|
||||
},
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 68;
|
||||
size = "3 * 4 + 2 * 4 * 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
iqm = {
|
||||
shader = {
|
||||
specialization = {
|
||||
mapEntries = (
|
||||
// IQMDepthOnly
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
);
|
||||
};
|
||||
depth_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/iqm.vert;
|
||||
specializationInfo = {
|
||||
@inherit = $iqm.shader.specialization;
|
||||
// IQMDepthOnly
|
||||
data = "array(1)";
|
||||
};
|
||||
};
|
||||
gbuf_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/iqm.vert;
|
||||
specializationInfo = {
|
||||
@inherit = $iqm.shader.specialization;
|
||||
// IQMDepthOnly
|
||||
data = "array(0)";
|
||||
};
|
||||
};
|
||||
gbuf_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/iqm.frag;
|
||||
};
|
||||
};
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
{ binding = 0; stride = 20; inputRate = vertex; },
|
||||
{ binding = 1; stride = 40; inputRate = vertex; },
|
||||
);
|
||||
attributes = (
|
||||
{ location = 0; binding = 0; format = r32g32b32_sfloat; offset = 0; }, // position
|
||||
{ location = 1; binding = 0; format = r8g8b8a8_uint; offset = 12; }, // bonindices
|
||||
{ location = 2; binding = 0; format = r8g8b8a8_unorm; offset = 16; }, // boneweights
|
||||
|
||||
{ location = 3; binding = 1; format = r32g32_sfloat; offset = 0; }, // texcoord
|
||||
{ location = 4; binding = 1; format = r32g32b32_sfloat; offset = 8; }, // normal
|
||||
{ location = 5; binding = 1; format = r32g32b32a32_sfloat; offset = 20; }, // tangent
|
||||
{ location = 6; binding = 1; format = r8g8b8a8_unorm; offset = 36; }, // color
|
||||
|
||||
);
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = triangle_list;
|
||||
primitiveRestartEnable = false;
|
||||
};
|
||||
layout = {
|
||||
setLayouts = (matrix_set, texture_set, bone_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
offset = 0;
|
||||
size = "16 * 4 + 4";
|
||||
},
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 68;
|
||||
size = "3 * 4 + 2 * 4 * 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
sprite = {
|
||||
shader = {
|
||||
depth_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/sprite_depth.vert;
|
||||
};
|
||||
depth_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/sprite_depth.frag;
|
||||
};
|
||||
gbuf_vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/sprite_gbuf.vert;
|
||||
};
|
||||
gbuf_fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/sprite_gbuf.frag;
|
||||
};
|
||||
};
|
||||
vertexInput = {
|
||||
bindings = ();
|
||||
attributes = ();
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = triangle_strip;
|
||||
// never draw more than 4 verts
|
||||
primitiveRestartEnable = false;
|
||||
};
|
||||
layout = {
|
||||
setLayouts = (matrix_set, sprite_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
offset = 0;
|
||||
// note: overlap with fragment is for the frame number
|
||||
size = "16 * 4 + 4";
|
||||
},
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 64;
|
||||
// note: overlap with vertex to share frame number
|
||||
size = "2 * 4 + 2 * 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
particle = {
|
||||
shader = {
|
||||
vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/particle.vert;
|
||||
};
|
||||
geometry = {
|
||||
stage = geometry;
|
||||
name = main;
|
||||
module = $builtin/particle.geom;
|
||||
};
|
||||
fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/particle.frag;
|
||||
};
|
||||
};
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
{ binding = 0; stride = "4 * 4 * 4"; inputRate = instance; },
|
||||
);
|
||||
attributes = (
|
||||
{ location = 0; binding = 0; format = r32g32b32a32_sfloat; offset = 0; },
|
||||
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||
{ location = 2; binding = 0; format = r32g32b32a32_sfloat; offset = 32; },
|
||||
{ location = 3; binding = 0; format = r32g32b32a32_sfloat; offset = 48; },
|
||||
);
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = point_list;
|
||||
primitiveRestartEnable = false;
|
||||
};
|
||||
layout = {
|
||||
setLayouts = (matrix_set, texture_set, oit_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
offset = 0;
|
||||
size = "16 * 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
fstriangle = {
|
||||
shader = {
|
||||
vertex = {
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/fstriangle.vert;
|
||||
};
|
||||
};
|
||||
};
|
||||
lighting = {
|
||||
shader = {
|
||||
fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/lighting.frag;
|
||||
};
|
||||
};
|
||||
};
|
||||
compose = {
|
||||
shader = {
|
||||
fragment = {
|
||||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/compose.frag;
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
images = {
|
||||
depth = {
|
||||
|
@ -194,37 +619,88 @@ renderpasses = {
|
|||
};
|
||||
preserve = (color, emission, normal, position, output);
|
||||
};
|
||||
|
||||
base_pipeline = {
|
||||
@inherit = $pipeline_base;
|
||||
depthStencil = $depth_test_and_write;
|
||||
};
|
||||
pipelines = {
|
||||
bsp:depth = {
|
||||
color = $color.bsp;
|
||||
pipeline = bsp_depth;
|
||||
tasks = (
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, solid); },
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, sky); },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$brush.shader.depth_vertex,
|
||||
);
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
"$brush.vertexInput.bindings[0]",
|
||||
"$brush.vertexInput.bindings[1]",
|
||||
);
|
||||
attributes = (
|
||||
"$brush.vertexInput.attributes[0]",
|
||||
"$brush.vertexInput.attributes[1]",
|
||||
);
|
||||
};
|
||||
inputAssembly = $brush.inputAssembly;
|
||||
layout = $brush.layout;
|
||||
};
|
||||
alias:depth = {
|
||||
color = $color.alias;
|
||||
pipeline = alias_depth;
|
||||
tasks = (
|
||||
{ func = "alias_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$alias.shader.depth_vertex,
|
||||
);
|
||||
vertexInput = {
|
||||
// depth pass doesn't use UVs
|
||||
bindings = (
|
||||
"$alias.vertexInput.bindings[0]",
|
||||
"$alias.vertexInput.bindings[1]",
|
||||
);
|
||||
attributes = (
|
||||
"$alias.vertexInput.attributes[0]",
|
||||
"$alias.vertexInput.attributes[1]",
|
||||
"$alias.vertexInput.attributes[2]",
|
||||
"$alias.vertexInput.attributes[3]",
|
||||
);
|
||||
};
|
||||
inputAssembly = $alias.inputAssembly;
|
||||
layout = $alias.layout;
|
||||
};
|
||||
iqm:depth = {
|
||||
color = $color.iqm;
|
||||
pipeline = iqm_depth;
|
||||
tasks = (
|
||||
{ func = "iqm_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$iqm.shader.depth_vertex,
|
||||
);
|
||||
vertexInput = $iqm.vertexInput;
|
||||
inputAssembly = $iqm.inputAssembly;
|
||||
layout = $iqm.layout;
|
||||
};
|
||||
sprite:depth = {
|
||||
color = $color.sprite;
|
||||
pipeline = sprite_depth;
|
||||
tasks = (
|
||||
{ func = "sprite_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$sprite.shader.depth_vertex,
|
||||
$sprite.shader.depth_fragment,
|
||||
);
|
||||
vertexInput = $sprite.vertexInput;
|
||||
inputAssembly = $sprite.inputAssembly;
|
||||
layout = $sprite.layout;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -239,32 +715,71 @@ renderpasses = {
|
|||
};
|
||||
preserve = (color, emission, normal, position, output);
|
||||
};
|
||||
base_pipeline = $pipeline_base;
|
||||
pipelines = {
|
||||
bsp:sky = {
|
||||
bsp:skybox = {
|
||||
color = $color.bsp;
|
||||
pipeline = $bsp_sky_pipeline;
|
||||
tasks = (
|
||||
// FIXME sky should not use OIT
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, sky); },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$brush.shader.quake_vertex,
|
||||
$brush.shader.skybox_fragment,
|
||||
);
|
||||
vertexInput = $brush.vertexInput;
|
||||
inputAssembly = $brush.inputAssembly;
|
||||
layout = $brush.layout;
|
||||
};
|
||||
bsp:skysheet = {
|
||||
color = $color.bsp;
|
||||
tasks = (
|
||||
// FIXME sky should not use OIT
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, sky); },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$brush.shader.quake_vertex,
|
||||
$brush.shader.skysheet_fragment,
|
||||
);
|
||||
vertexInput = $brush.vertexInput;
|
||||
inputAssembly = $brush.inputAssembly;
|
||||
layout = $brush.layout;
|
||||
};
|
||||
bsp:trans = {
|
||||
color = $color.bsp;
|
||||
pipeline = bsp_turb;
|
||||
tasks = (
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, translucent); },
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, turbulent); },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$brush.shader.quake_vertex,
|
||||
$brush.shader.turb_fragment,
|
||||
);
|
||||
vertexInput = $brush.vertexInput;
|
||||
inputAssembly = $brush.inputAssembly;
|
||||
layout = $brush.layout;
|
||||
};
|
||||
particles:trans = {
|
||||
color = $color.particles;
|
||||
pipeline = partdraw;
|
||||
tasks = (
|
||||
{ func = particles_draw; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$particle.shader.vertex,
|
||||
$particle.shader.geometry,
|
||||
$particle.shader.fragment,
|
||||
);
|
||||
vertexInput = $particle.vertexInput;
|
||||
inputAssembly = $particle.inputAssembly;
|
||||
layout = $particle.layout;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -275,47 +790,89 @@ renderpasses = {
|
|||
};
|
||||
attachments = {
|
||||
color = {
|
||||
color = color_attachment_optimal;
|
||||
emission = color_attachment_optimal;
|
||||
normal = color_attachment_optimal;
|
||||
position = color_attachment_optimal;
|
||||
color = {
|
||||
layout = color_attachment_optimal;
|
||||
blend = $blend_disable;
|
||||
};
|
||||
emission = {
|
||||
layout = color_attachment_optimal;
|
||||
blend = $blend_disable;
|
||||
};
|
||||
normal = {
|
||||
layout = color_attachment_optimal;
|
||||
blend = $blend_disable;
|
||||
};
|
||||
position = {
|
||||
layout = color_attachment_optimal;
|
||||
blend = $blend_disable;
|
||||
};
|
||||
};
|
||||
depth = {
|
||||
depth = depth_stencil_read_only_optimal;
|
||||
};
|
||||
preserve = (output);
|
||||
};
|
||||
base_pipeline = $pipeline_base;
|
||||
pipelines = {
|
||||
bsp:gbuffer = {
|
||||
color = $color.bsp;
|
||||
pipeline = bsp_gbuf;
|
||||
tasks = (
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, solid); },
|
||||
{ func = bsp_draw_queue;
|
||||
params = (main, sky); },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$brush.shader.gbuf_vertex,
|
||||
$brush.shader.gbuf_geometry,
|
||||
$brush.shader.gbuf_fragment,
|
||||
);
|
||||
vertexInput = $brush.vertexInput;
|
||||
inputAssembly = $brush.inputAssembly;
|
||||
layout = $brush.layout;
|
||||
};
|
||||
alias:gbuffer = {
|
||||
color = $color.alias;
|
||||
pipeline = alias_gbuf;
|
||||
tasks = (
|
||||
{ func = "alias_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$alias.shader.gbuf_vertex,
|
||||
$alias.shader.gbuf_fragment,
|
||||
);
|
||||
vertexInput = $alias.vertexInput;
|
||||
inputAssembly = $alias.inputAssembly;
|
||||
layout = $alias.layout;
|
||||
};
|
||||
iqm:gbuffer = {
|
||||
color = $color.iqm;
|
||||
pipeline = iqm_gbuf;
|
||||
tasks = (
|
||||
{ func = "iqm_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$iqm.shader.gbuf_vertex,
|
||||
$iqm.shader.gbuf_fragment,
|
||||
);
|
||||
vertexInput = $iqm.vertexInput;
|
||||
inputAssembly = $iqm.inputAssembly;
|
||||
layout = $iqm.layout;
|
||||
};
|
||||
sprite:gbuffer = {
|
||||
color = $color.sprite;
|
||||
pipeline = sprite_gbuf;
|
||||
tasks = (
|
||||
{ func = "sprite_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$sprite.shader.gbuf_vertex,
|
||||
$sprite.shader.gbuf_fragment,
|
||||
);
|
||||
vertexInput = $sprite.vertexInput;
|
||||
inputAssembly = $sprite.inputAssembly;
|
||||
layout = $sprite.layout;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -333,17 +890,27 @@ renderpasses = {
|
|||
position = shader_read_only_optimal;
|
||||
};
|
||||
color = {
|
||||
opaque = color_attachment_optimal;
|
||||
opaque = {
|
||||
layout = color_attachment_optimal;
|
||||
blend = $blend_disable;
|
||||
};
|
||||
};
|
||||
preserve = (output);
|
||||
};
|
||||
pipelines = {
|
||||
lights = {
|
||||
@inherit = $compose_base;
|
||||
|
||||
color = $color.lights;
|
||||
pipeline = lighting;
|
||||
tasks = (
|
||||
{ func = "lights_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$fstriangle.shader.vertex,
|
||||
$lighting.shader.fragment,
|
||||
);
|
||||
layout = lighting.layout;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -363,17 +930,24 @@ renderpasses = {
|
|||
};
|
||||
pipelines = {
|
||||
compose = {
|
||||
@inherit = $compose_base;
|
||||
|
||||
color = $color.compose;
|
||||
pipeline = compose;
|
||||
tasks = (
|
||||
{ func = "compose_draw"; },
|
||||
);
|
||||
|
||||
stages = (
|
||||
$fstriangle.shader.vertex,
|
||||
$compose.shader.fragment,
|
||||
);
|
||||
layout = compose.layout;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/* deferred_cube = {
|
||||
/*deferred_cube = {
|
||||
@inherit = $renderpasses.deferred;
|
||||
@next = (VkRenderPassMultiviewCreateInfo, {
|
||||
viewMasks = (0x3fu, 0x3fu, 0x3fu, 0x3fu, 0x3fu);
|
||||
|
|
|
@ -123,6 +123,57 @@ write_function_tail (Struct *self)
|
|||
fprintf (output_file, "}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
write_parse_type (Struct *self)
|
||||
{
|
||||
fprintf (output_file, "\t\treturn PL_ParseStruct (%s_fields, item, data, "
|
||||
"messages, context);\n", [self outname]);
|
||||
}
|
||||
|
||||
static void
|
||||
write_auto_parse (Struct *self, string field)
|
||||
{
|
||||
fprintf (output_file, "\t\tdo {\n");
|
||||
fprintf (output_file, "\t\t\tplfield_t *f = find_field (%s_fields, %s, "
|
||||
"item, messages);\n", [self outname], sprintf ("\"%s\"", field));
|
||||
fprintf (output_file, "\t\t\tif (!f) {\n");
|
||||
fprintf (output_file, "\t\t\t\treturn 0;");
|
||||
fprintf (output_file, "\t\t\t};\n");
|
||||
fprintf (output_file, "\t\t\tf->parser (f, item, &%s, messages, context);\n",
|
||||
sprintf ("((%s *) data)->%s", [self outname], field));
|
||||
fprintf (output_file, "\t\t} while (0);\n");
|
||||
}
|
||||
|
||||
static int
|
||||
check_need_table (Struct *self, PLItem *field_dict, string type)
|
||||
{
|
||||
string key = nil;
|
||||
switch (type) {
|
||||
case "QFDictionary": key = ".dictionary"; break;
|
||||
case "QFArray": key = ".array"; break;
|
||||
case "QFBinary": key = ".binary"; break;
|
||||
case "QFString": key = ".string"; break;
|
||||
}
|
||||
PLItem *type_obj = [field_dict getObjectForKey:key];
|
||||
int count = [type_obj numKeys];
|
||||
if (!count) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
string field = [type_obj keyAtIndex:i];
|
||||
PLItem *item = [type_obj getObjectForKey:field];
|
||||
string str = [item string];
|
||||
|
||||
if (field == ".parse") {
|
||||
return 1;
|
||||
}
|
||||
if (str == "$auto") {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
write_type (Struct *self, PLItem *field_dict, string type)
|
||||
{
|
||||
|
@ -145,6 +196,11 @@ write_type (Struct *self, PLItem *field_dict, string type)
|
|||
PLItem *item = [type_obj getObjectForKey:field];
|
||||
string str = [item string];
|
||||
|
||||
if (field == ".parse") {
|
||||
write_parse_type (self);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (str) {
|
||||
case "$item.string":
|
||||
str = "vkstrdup (context, PL_String (item))";
|
||||
|
@ -158,6 +214,9 @@ write_type (Struct *self, PLItem *field_dict, string type)
|
|||
case "$index":
|
||||
str = "field->offset";
|
||||
break;
|
||||
case "$auto":
|
||||
write_auto_parse (self, field);
|
||||
continue;
|
||||
}
|
||||
fprintf (output_file, "\t\t((%s *) data)->%s = %s;\n", [self outname],
|
||||
field, str);
|
||||
|
@ -166,6 +225,45 @@ write_type (Struct *self, PLItem *field_dict, string type)
|
|||
fprintf (output_file, "\t}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
write_parser (Struct *self, int have_sType, PLItem *only)
|
||||
{
|
||||
write_function_head (self);
|
||||
if (have_sType) {
|
||||
fprintf (output_file, "\t((%s *) data)->sType", [self outname]);
|
||||
fprintf (output_file, " = %s;\n", [self sTypeName]);
|
||||
}
|
||||
if (self.label_field) {
|
||||
fprintf (output_file, "\t((%s *) data)->%s", [self outname],
|
||||
self.label_field);
|
||||
fprintf (output_file, " = vkstrdup (context, field->name);\n");
|
||||
}
|
||||
if (only) {
|
||||
fprintf (output_file, "\tplfield_t *f = &%s_fields[0];\n",
|
||||
[self outname]);
|
||||
fprintf (output_file,
|
||||
"\tif (!PL_CheckType (PL_Type (item), f->type)) {\n"
|
||||
"\t\tPL_TypeMismatch (messages, item, "
|
||||
"f->name, f->type, PL_Type (item));\n"
|
||||
"\t\treturn 0;\n"
|
||||
"\t}\n"
|
||||
"\tvoid *flddata = (byte *)data + f->offset;\n"
|
||||
"\treturn f->parser (f, item, flddata, messages, "
|
||||
"context);\n");
|
||||
} else {
|
||||
fprintf (output_file,
|
||||
"\tif (PL_Type (item) == QFString\n"
|
||||
"\t\t&& !(item = parse_reference (item, \"%s\", "
|
||||
"messages, context))) {\n"
|
||||
"\t\treturn 0;\n"
|
||||
"\t}\n"
|
||||
"\treturn PL_ParseStruct (%s_fields, item, data, "
|
||||
"messages, context);\n",
|
||||
[self outname], [self outname]);
|
||||
}
|
||||
write_function_tail (self);
|
||||
}
|
||||
|
||||
static void
|
||||
write_cexpr (Struct *self, Array *field_defs)
|
||||
{
|
||||
|
@ -210,6 +308,61 @@ write_cexpr (Struct *self, Array *field_defs)
|
|||
fprintf (header_file, "extern exprtype_t %s_type;\n", [self outname]);
|
||||
}
|
||||
|
||||
static void
|
||||
write_table (Struct *self, PLItem *field_dict, Array *field_defs,
|
||||
PLItem *only, int need_parser)
|
||||
{
|
||||
qfot_type_t *type = self.type;
|
||||
int have_sType = 0;
|
||||
int have_pNext = 0;
|
||||
int readonly = [field_dict string] == "readonly";
|
||||
|
||||
for (int i = 0; i < type.strct.num_fields; i++) {
|
||||
qfot_var_t *field = &type.strct.fields[i];
|
||||
if (field.name == "sType") {
|
||||
have_sType = 1;
|
||||
}
|
||||
if (field.name == "pNext") {
|
||||
have_pNext = 1;
|
||||
self.write_symtab = 1;
|
||||
}
|
||||
}
|
||||
for (int i = [field_defs count]; i-- > 0; ) {
|
||||
FieldDef *field_def = [field_defs objectAtIndex:i];
|
||||
[field_def writeParseData];
|
||||
}
|
||||
if (!readonly) {
|
||||
fprintf (output_file, "static plfield_t %s_fields[] = {\n",
|
||||
[self outname]);
|
||||
if (!only) {
|
||||
fprintf (output_file,
|
||||
"\t{\"@inherit\", 0, QFString, parse_inherit, "
|
||||
"&%s_fields},\n", [self outname]);
|
||||
}
|
||||
if (have_pNext) {
|
||||
fprintf (output_file,
|
||||
"\t{\"@next\", field_offset (%s, pNext), "
|
||||
"QFArray, parse_next, 0},", [self outname]);
|
||||
}
|
||||
for (int i = [field_defs count]; i-- > 0; ) {
|
||||
FieldDef *field_def = [field_defs objectAtIndex:i];
|
||||
[field_def writeField];
|
||||
}
|
||||
fprintf (output_file, "\t{ }\n");
|
||||
fprintf (output_file, "};\n");
|
||||
|
||||
if (need_parser) {
|
||||
write_parser (self, have_sType, only);
|
||||
}
|
||||
if (have_pNext) {
|
||||
fprintf (output_file, "static parserref_t %s_parser = ",
|
||||
[self outname]);
|
||||
fprintf (output_file, "{\"%s\", %s, sizeof(%s)};\n",
|
||||
[self outname], [self parseFunc], [self outname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void) writeTable
|
||||
{
|
||||
if ([parse string] == "skip") {
|
||||
|
@ -278,7 +431,19 @@ write_cexpr (Struct *self, Array *field_defs)
|
|||
if ([field_dict getObjectForKey:".type"]) {
|
||||
PLItem *type = [field_dict getObjectForKey:".type"];
|
||||
string str = [type string];
|
||||
int need_table = 0;
|
||||
|
||||
if (str) {
|
||||
need_table |= check_need_table (self, field_dict, str);
|
||||
} else {
|
||||
for (int i = [type count]; i-- > 0; ) {
|
||||
string str = [[type getObjectAtIndex:i] string];
|
||||
need_table |= check_need_table (self, field_dict, str);
|
||||
}
|
||||
}
|
||||
if (need_table) {
|
||||
write_table (self, field_dict, field_defs, only, 0);
|
||||
}
|
||||
write_function_head (self);
|
||||
fprintf (output_file, "\tpltype_t type = PL_Type (item);\n");
|
||||
if (str) {
|
||||
|
@ -298,85 +463,7 @@ write_cexpr (Struct *self, Array *field_defs)
|
|||
return;
|
||||
}
|
||||
|
||||
int have_sType = 0;
|
||||
int have_pNext = 0;
|
||||
int readonly = [field_dict string] == "readonly";
|
||||
|
||||
for (int i = 0; i < type.strct.num_fields; i++) {
|
||||
qfot_var_t *field = &type.strct.fields[i];
|
||||
if (field.name == "sType") {
|
||||
have_sType = 1;
|
||||
}
|
||||
if (field.name == "pNext") {
|
||||
have_pNext = 1;
|
||||
write_symtab = 1;
|
||||
}
|
||||
}
|
||||
for (int i = [field_defs count]; i-- > 0; ) {
|
||||
FieldDef *field_def = [field_defs objectAtIndex:i];
|
||||
[field_def writeParseData];
|
||||
}
|
||||
if (!readonly) {
|
||||
fprintf (output_file, "static plfield_t %s_fields[] = {\n",
|
||||
[self outname]);
|
||||
if (!only) {
|
||||
fprintf (output_file,
|
||||
"\t{\"@inherit\", 0, QFString, parse_inherit, "
|
||||
"&%s_fields},\n", [self outname]);
|
||||
}
|
||||
if (have_pNext) {
|
||||
fprintf (output_file,
|
||||
"\t{\"@next\", field_offset (%s, pNext), "
|
||||
"QFArray, parse_next, 0},", [self outname]);
|
||||
}
|
||||
for (int i = [field_defs count]; i-- > 0; ) {
|
||||
FieldDef *field_def = [field_defs objectAtIndex:i];
|
||||
[field_def writeField];
|
||||
}
|
||||
fprintf (output_file, "\t{ }\n");
|
||||
fprintf (output_file, "};\n");
|
||||
|
||||
write_function_head (self);
|
||||
if (have_sType) {
|
||||
fprintf (output_file, "\t((%s *) data)->sType", [self outname]);
|
||||
fprintf (output_file, " = %s;\n", [self sTypeName]);
|
||||
}
|
||||
if (label_field) {
|
||||
fprintf (output_file, "\t((%s *) data)->%s", [self outname],
|
||||
label_field);
|
||||
fprintf (output_file, " = vkstrdup (context, field->name);\n");
|
||||
}
|
||||
if (only) {
|
||||
fprintf (output_file, "\tplfield_t *f = &%s_fields[0];\n",
|
||||
[self outname]);
|
||||
fprintf (output_file,
|
||||
"\tif (!PL_CheckType (PL_Type (item), f->type)) {\n"
|
||||
"\t\tPL_TypeMismatch (messages, item, "
|
||||
"f->name, f->type, PL_Type (item));\n"
|
||||
"\t\treturn 0;\n"
|
||||
"\t}\n"
|
||||
"\tvoid *flddata = (byte *)data + f->offset;\n"
|
||||
"\treturn f->parser (f, item, flddata, messages, "
|
||||
"context);\n");
|
||||
} else {
|
||||
fprintf (output_file,
|
||||
"\tif (PL_Type (item) == QFString\n"
|
||||
"\t\t&& !(item = parse_reference (item, \"%s\", "
|
||||
"messages, context))) {\n"
|
||||
"\t\treturn 0;\n"
|
||||
"\t}\n"
|
||||
"\treturn PL_ParseStruct (%s_fields, item, data, "
|
||||
"messages, context);\n",
|
||||
[self outname], [self outname]);
|
||||
}
|
||||
write_function_tail (self);
|
||||
if (have_pNext) {
|
||||
fprintf (output_file, "static parserref_t %s_parser = ",
|
||||
[self outname]);
|
||||
fprintf (output_file, "{\"%s\", %s, sizeof(%s)};\n",
|
||||
[self outname], [self parseFunc], [self outname]);
|
||||
}
|
||||
}
|
||||
write_table (self, field_dict, field_defs, only, 1);
|
||||
|
||||
write_cexpr (self, field_defs);
|
||||
}
|
||||
|
|
|
@ -152,6 +152,19 @@ typedef struct parse_custom_s {
|
|||
size_t num_offsets;
|
||||
} parse_custom_t;
|
||||
|
||||
static plfield_t *__attribute__((used))
|
||||
find_field (plfield_t *fields, const char *field_name,
|
||||
const plitem_t *item, plitem_t *messages)
|
||||
{
|
||||
for (plfield_t *f = fields; f->name; f++) {
|
||||
if (strcmp (f->name, field_name) == 0) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
PL_Message (messages, item, "error: unknown field %s", field_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_basic (const plfield_t *field, const plitem_t *item,
|
||||
void *data, plitem_t *messages, void *context)
|
||||
|
@ -355,7 +368,7 @@ parse_single (const plfield_t *field, const plitem_t *item,
|
|||
return 0;
|
||||
}
|
||||
|
||||
plfield_t f = { 0, 0, single->type, single->parser, 0 };
|
||||
plfield_t f = { field->name, 0, single->type, single->parser, 0 };
|
||||
void *value = vkparse_alloc (context, single->stride);
|
||||
memset (value, 0, single->stride);
|
||||
if (!single->parser (&f, item, value, messages, context)) {
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
qfv_framebufferinfo_t,
|
||||
qfv_renderpassinfo_t,
|
||||
qfv_renderinfo_t,
|
||||
qfv_pipelinespec_t,
|
||||
);
|
||||
parse = {
|
||||
VkSubpassDescription = {
|
||||
|
@ -436,7 +437,16 @@
|
|||
};
|
||||
qfv_attachmentrefinfo_s = {
|
||||
.name = qfv_attachmentrefinfo_t;
|
||||
.only = layout;
|
||||
.type = (QFString, QFDictionary);
|
||||
.string = {
|
||||
name = $name;
|
||||
layout = $auto;
|
||||
};
|
||||
.dictionary = {
|
||||
.parse = auto;
|
||||
};
|
||||
layout = auto;
|
||||
blend = auto;
|
||||
};
|
||||
qfv_attachmentsetinfo_s = {
|
||||
.name = qfv_attachmentsetinfo_t;
|
||||
|
@ -477,12 +487,58 @@
|
|||
type = string;
|
||||
string = name;
|
||||
};
|
||||
pipeline = auto;
|
||||
tasks = {
|
||||
type = (array, qfv_taskinfo_t);
|
||||
size = num_tasks;
|
||||
values = tasks;
|
||||
}
|
||||
};
|
||||
|
||||
flags = auto;
|
||||
stages = {
|
||||
type = (array, VkPipelineShaderStageCreateInfo);
|
||||
size = num_graph_stages;
|
||||
values = graph_stages;
|
||||
};
|
||||
vertexInput = {
|
||||
type = (single, VkPipelineVertexInputStateCreateInfo);
|
||||
value = vertexInput;
|
||||
};
|
||||
inputAssembly = {
|
||||
type = (single, VkPipelineInputAssemblyStateCreateInfo);
|
||||
value = inputAssembly;
|
||||
};
|
||||
tessellation = {
|
||||
type = (single, VkPipelineTessellationStateCreateInfo);
|
||||
value = tessellation;
|
||||
};
|
||||
viewport = {
|
||||
type = (single, VkPipelineViewportStateCreateInfo);
|
||||
value = viewport;
|
||||
};
|
||||
rasterization = {
|
||||
type = (single, VkPipelineRasterizationStateCreateInfo);
|
||||
value = rasterization;
|
||||
};
|
||||
multisample = {
|
||||
type = (single, VkPipelineMultisampleStateCreateInfo);
|
||||
value = multisample;
|
||||
};
|
||||
depthStencil = {
|
||||
type = (single, VkPipelineDepthStencilStateCreateInfo);
|
||||
value = depthStencil;
|
||||
};
|
||||
colorBlend = {
|
||||
type = (single, VkPipelineColorBlendStateCreateInfo);
|
||||
value = colorBlend;
|
||||
};
|
||||
dynamic = {
|
||||
type = (single, VkPipelineDynamicStateCreateInfo);
|
||||
value = dynamic;
|
||||
};
|
||||
layout = {
|
||||
type = (single, qfv_reference_t);
|
||||
value = layout;
|
||||
};
|
||||
};
|
||||
qfv_subpassinfo_s = {
|
||||
.name = qfv_subpassinfo_t;
|
||||
|
@ -505,6 +561,11 @@
|
|||
size = num_pipelines;
|
||||
values = pipelines;
|
||||
};
|
||||
base_pipeline = {
|
||||
//type = (labeledsingle, qfv_pipelineinfo_t, name);
|
||||
type = (single, qfv_pipelineinfo_t, name);
|
||||
value = base_pipeline;
|
||||
};
|
||||
};
|
||||
qfv_framebufferinfo_s = {
|
||||
.name = qfv_framebufferinfo_t;
|
||||
|
@ -557,6 +618,6 @@
|
|||
size = num_renderpasses;
|
||||
values = renderpasses;
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue