mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-21 11:11:37 +00:00
[vulkan] Make push constant ranges structured
Being able to specify the types in the push constant ranges makes it a lot easier to get the specification correct. I never did like having to do the offsets and sizes by hand as it was quite error prone. Right now, float, int, uint, vec3, vec4 and mat4 are supported, and adheres to layout std430.
This commit is contained in:
parent
c1b85a3db7
commit
b0d1c0e75b
4 changed files with 180 additions and 82 deletions
|
@ -35,12 +35,35 @@ typedef struct qfv_descriptorsetlayoutinfo_s {
|
|||
VkDescriptorSetLayout setLayout;
|
||||
} qfv_descriptorsetlayoutinfo_t;
|
||||
|
||||
typedef enum qfv_type_t {
|
||||
qfv_float,
|
||||
qfv_int,
|
||||
qfv_uint,
|
||||
qfv_vec3,
|
||||
qfv_vec4,
|
||||
qfv_mat4,
|
||||
} qfv_type_t;
|
||||
|
||||
typedef struct qfv_pushconstantinfo_s {
|
||||
const char *name;
|
||||
int line;
|
||||
qfv_type_t type;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
} qfv_pushconstantinfo_t;
|
||||
|
||||
typedef struct qfv_pushconstantrangeinfo_s {
|
||||
VkShaderStageFlags stageFlags;
|
||||
uint32_t num_pushconstants;
|
||||
qfv_pushconstantinfo_t *pushconstants;
|
||||
} qfv_pushconstantrangeinfo_t;
|
||||
|
||||
typedef struct qfv_layoutinfo_s {
|
||||
const char *name;
|
||||
uint32_t num_sets;
|
||||
qfv_reference_t *sets;
|
||||
uint32_t num_ranges;
|
||||
VkPushConstantRange *ranges;
|
||||
uint32_t num_pushconstantranges;
|
||||
qfv_pushconstantrangeinfo_t *pushconstantranges;
|
||||
VkPipelineLayout layout;
|
||||
} qfv_layoutinfo_t;
|
||||
|
||||
|
|
|
@ -374,6 +374,61 @@ find_descriptorSet (const qfv_reference_t *ref, objstate_t *s)
|
|||
s->rpi->name, s->spi->name, ref->line, ref->name);
|
||||
}
|
||||
|
||||
#define RUP(x,a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
|
||||
static uint32_t
|
||||
parse_pushconstantrange (VkPushConstantRange *range,
|
||||
qfv_pushconstantrangeinfo_t *pushconstantrange,
|
||||
uint32_t offset, objstate_t *s)
|
||||
{
|
||||
uint32_t range_offset = ~0u;
|
||||
for (uint32_t i = 0; i < pushconstantrange->num_pushconstants; i++) {
|
||||
__auto_type pushconstant = & pushconstantrange->pushconstants[i];
|
||||
uint32_t size = 0;
|
||||
if (pushconstant->offset != ~0u) {
|
||||
offset = pushconstant->offset;
|
||||
}
|
||||
if (pushconstant->size != ~0u) {
|
||||
size = pushconstant->size;
|
||||
} else {
|
||||
switch (pushconstant->type) {
|
||||
case qfv_float:
|
||||
case qfv_int:
|
||||
case qfv_uint:
|
||||
size = sizeof (int32_t);
|
||||
offset = RUP (offset, sizeof (int32_t));
|
||||
break;
|
||||
case qfv_vec3:
|
||||
size = sizeof (vec3_t);
|
||||
offset = RUP (offset, sizeof (vec4f_t));
|
||||
break;
|
||||
case qfv_vec4:
|
||||
size = sizeof (vec4f_t);
|
||||
offset = RUP (offset, sizeof (vec4f_t));
|
||||
break;
|
||||
case qfv_mat4:
|
||||
size = sizeof (mat4f_t);
|
||||
offset = RUP (offset, sizeof (vec4f_t));
|
||||
break;
|
||||
default:
|
||||
Sys_Error ("%s.%s:%s:%d invalid type: %d",
|
||||
s->rpi->name, s->spi->name, pushconstant->name,
|
||||
pushconstant->line, pushconstant->type);
|
||||
}
|
||||
}
|
||||
if (range_offset == ~0u) {
|
||||
range_offset = offset;
|
||||
}
|
||||
offset += size;
|
||||
}
|
||||
*range = (VkPushConstantRange) {
|
||||
.stageFlags = pushconstantrange->stageFlags,
|
||||
.offset = range_offset,
|
||||
.size = offset - range_offset,
|
||||
};
|
||||
return offset;
|
||||
}
|
||||
|
||||
static qfv_layoutinfo_t *
|
||||
find_layout (const qfv_reference_t *ref, objstate_t *s)
|
||||
{
|
||||
|
@ -393,12 +448,19 @@ find_layout (const qfv_reference_t *ref, objstate_t *s)
|
|||
for (uint32_t i = 0; i < li->num_sets; i++) {
|
||||
sets[i] = find_descriptorSet (&li->sets[i], s);
|
||||
}
|
||||
VkPushConstantRange ranges[li->num_pushconstantranges];
|
||||
uint32_t offset = 0;
|
||||
for (uint32_t i = 0; i < li->num_pushconstantranges; i++) {
|
||||
offset = parse_pushconstantrange (&ranges[i],
|
||||
&li->pushconstantranges[i],
|
||||
offset, s);
|
||||
}
|
||||
VkPipelineLayoutCreateInfo cInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = li->num_sets,
|
||||
.pSetLayouts = sets,
|
||||
.pushConstantRangeCount = li->num_ranges,
|
||||
.pPushConstantRanges = li->ranges,
|
||||
.pushConstantRangeCount = li->num_pushconstantranges,
|
||||
.pPushConstantRanges = ranges,
|
||||
};
|
||||
qfv_device_t *device = s->ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
|
|
@ -244,14 +244,16 @@ properties = {
|
|||
primitiveRestartEnable = true;
|
||||
};
|
||||
layout = {
|
||||
descriptorSets = (matrix_set, entity_set, oit_set, texture_set, texture_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 0;
|
||||
size = "4 * 4 + 4 + 4 + 4";
|
||||
},
|
||||
);
|
||||
descriptorSets = (matrix_set, entity_set, oit_set, texture_set,
|
||||
texture_set);
|
||||
pushConstants = {
|
||||
fragment = {
|
||||
fog = vec4;
|
||||
time = float;
|
||||
alpha = float;
|
||||
turb_scale = float;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
alias = {
|
||||
|
@ -292,18 +294,10 @@ properties = {
|
|||
};
|
||||
layout = {
|
||||
descriptorSets = (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";
|
||||
},
|
||||
);
|
||||
pushConstants = {
|
||||
vertex = { Model = mat4; blend = float; };
|
||||
fragment = { colors = uint; base_color = vec4; fog = vec4; };
|
||||
};
|
||||
};
|
||||
};
|
||||
iqm = {
|
||||
|
@ -363,18 +357,18 @@ properties = {
|
|||
};
|
||||
layout = {
|
||||
descriptorSets = (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";
|
||||
},
|
||||
);
|
||||
pushConstants = {
|
||||
vertex = {
|
||||
Model = mat4;
|
||||
blend = float;
|
||||
};
|
||||
fragment = {
|
||||
colorA = uint;
|
||||
colorB = uint;
|
||||
base_color = vec4;
|
||||
fog = vec4;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
sprite = {
|
||||
|
@ -411,20 +405,18 @@ properties = {
|
|||
};
|
||||
layout = {
|
||||
descriptorSets = (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";
|
||||
},
|
||||
);
|
||||
pushConstants = {
|
||||
vertex = {
|
||||
Model = mat4;
|
||||
frame = int;
|
||||
};
|
||||
fragment = {
|
||||
overlap = { offset = 64; type = int; };
|
||||
frame = int;
|
||||
spriteind = int;
|
||||
fog = vec4;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
particle = {
|
||||
|
@ -463,23 +455,15 @@ properties = {
|
|||
layout = {
|
||||
draw = {
|
||||
descriptorSets = (matrix_set, texture_set, oit_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
offset = 0;
|
||||
size = "16 * 4";
|
||||
},
|
||||
);
|
||||
pushConstants = {
|
||||
vertex = { Model = mat4; };
|
||||
};
|
||||
};
|
||||
physics = {
|
||||
descriptorSets = (particle_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = compute;
|
||||
offset = 0;
|
||||
size = "4 * 4 + 4";
|
||||
},
|
||||
);
|
||||
pushConstants = {
|
||||
compute = { gravity = vec4; dT = float; };
|
||||
};
|
||||
};
|
||||
update = {
|
||||
descriptorSets = (particle_set, particle_set, particle_set);
|
||||
|
@ -544,13 +528,9 @@ properties = {
|
|||
};
|
||||
layout = {
|
||||
descriptorSets = (matrix_set, output_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 0;
|
||||
size = "4";
|
||||
}
|
||||
);
|
||||
pushConstants = {
|
||||
fragment = { time = float; };
|
||||
};
|
||||
};
|
||||
};
|
||||
fisheye = {
|
||||
|
@ -564,13 +544,9 @@ properties = {
|
|||
};
|
||||
layout = {
|
||||
descriptorSets = (matrix_set, output_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = fragment;
|
||||
offset = 0;
|
||||
size = "2 * 4";
|
||||
}
|
||||
);
|
||||
pushConstants = {
|
||||
fragment = { fov = float; aspect = float; };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -43,6 +43,8 @@ search = (
|
|||
qfv_attachmentrefinfo_t,
|
||||
qfv_attachmentsetinfo_t,
|
||||
qfv_taskinfo_t,
|
||||
qfv_pushconstantinfo_t,
|
||||
qfv_pushconstantrangeinfo_t,
|
||||
qfv_layoutinfo_t,
|
||||
qfv_pipelineinfo_t,
|
||||
qfv_subpassinfo_t,
|
||||
|
@ -485,6 +487,41 @@ parse = {
|
|||
values = preserve;
|
||||
};
|
||||
};
|
||||
qfv_pushconstantinfo_s = {
|
||||
.name = qfv_pushconstantinfo_t;
|
||||
.type = (QFString, QFDictionary);
|
||||
.dictionary = {
|
||||
offset = -1;
|
||||
size = -1;
|
||||
.parse = auto;
|
||||
name = $name;
|
||||
line = $item.line;
|
||||
};
|
||||
.string = {
|
||||
offset = -1;
|
||||
size = -1;
|
||||
name = $name;
|
||||
line = $item.line;
|
||||
type = $auto;
|
||||
};
|
||||
type = auto;
|
||||
//stageFlags = auto;
|
||||
offset = auto;
|
||||
size = auto;
|
||||
};
|
||||
qfv_pushconstantrangeinfo_s = {
|
||||
.name = qfv_pushconstantrangeinfo_t;
|
||||
.type = (QFDictionary);
|
||||
.dictionary = {
|
||||
.parse = {
|
||||
type = (labeledarray, qfv_pushconstantinfo_t, name);
|
||||
size = num_pushconstants;
|
||||
values = pushconstants;
|
||||
};
|
||||
stageFlags = $name.auto;
|
||||
};
|
||||
stageFlags = auto;
|
||||
};
|
||||
qfv_layoutinfo_s = {
|
||||
.name = qfv_layoutinfo_t;
|
||||
descriptorSets = {
|
||||
|
@ -492,10 +529,10 @@ parse = {
|
|||
size = num_sets;
|
||||
values = sets;
|
||||
};
|
||||
pushConstantRanges = {
|
||||
type = (array, VkPushConstantRange);
|
||||
size = num_ranges;
|
||||
values = ranges;
|
||||
pushConstants = {
|
||||
type = (labeledarray, qfv_pushconstantrangeinfo_t, stageFlags);
|
||||
size = num_pushconstantranges;
|
||||
values = pushconstantranges;
|
||||
};
|
||||
};
|
||||
qfv_pipelineinfo_s = {
|
||||
|
|
Loading…
Reference in a new issue