mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-16 06:11:15 +00:00
[vulkan] Merge lighting updates into one packet
While QFV_PacketScatterBuffer works on only one destination buffer, it turns out it's still useful for scattering to multiple buffers, just with multiple calls. This makes it pretty easy to combine multiple buffer updates into a single staging buffer packet, resulting in reducing lighting's packet use from up to 7 to just one, drastically reducing the pressure on the stating buffer packet pool, and thus reducing the chances of QFV_PacketAcquire stalling.
This commit is contained in:
parent
fccd06c5bf
commit
7ff0e95c52
2 changed files with 95 additions and 48 deletions
|
@ -60,7 +60,7 @@ enum {
|
|||
};
|
||||
|
||||
typedef struct qfv_light_render_s {
|
||||
// mat_id (13) map_id (5) layer (11) type (2)
|
||||
// mat_id (0,13) map_id (13,5) layer (18,11) type (29,2)
|
||||
uint32_t id_data;
|
||||
// light style (6)
|
||||
uint32_t style;
|
||||
|
|
|
@ -473,13 +473,7 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
|
||||
auto bb = &bufferBarriers[qfv_BB_TransferWrite_to_UniformRead];
|
||||
|
||||
auto packet = QFV_PacketAcquire (ctx->staging);
|
||||
vec4f_t *styles = QFV_PacketExtend (packet, sizeof (vec4f_t[NumStyles]));
|
||||
for (int i = 0; i < NumStyles; i++) {
|
||||
styles[i] = (vec4f_t) { 1, 1, 1, d_lightstylevalue[i] / 65536.0};
|
||||
}
|
||||
QFV_PacketCopyBuffer (packet, lframe->style_buffer, 0, bb);
|
||||
QFV_PacketSubmit (packet);
|
||||
size_t packet_size = 0;
|
||||
|
||||
uint32_t light_ids[ST_COUNT][MaxLights];
|
||||
uint32_t entids[ST_COUNT][MaxLights];
|
||||
|
@ -513,30 +507,82 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
queue[mode].count++;
|
||||
}
|
||||
|
||||
packet_size += sizeof (vec4f_t[NumStyles]);
|
||||
if (queue[ST_CASCADE].count) {
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
uint32_t mat_count = queue[ST_CASCADE].count * num_cascade;
|
||||
mat4f_t *mats = QFV_PacketExtend (packet, sizeof (mat4f_t[mat_count]));
|
||||
packet_size += sizeof (mat4f_t[mat_count]);
|
||||
}
|
||||
if (ndlight) {
|
||||
packet_size += sizeof (mat4f_t[ndlight * 6]);
|
||||
packet_size += sizeof (light_t[ndlight]);
|
||||
packet_size += sizeof (qfv_light_render_t[ndlight]);
|
||||
}
|
||||
if (light_count) {
|
||||
// light ids
|
||||
packet_size += sizeof (uint32_t[light_count]);
|
||||
// ent ids
|
||||
packet_size += sizeof (uint32_t[light_count]);
|
||||
}
|
||||
|
||||
auto packet = QFV_PacketAcquire (ctx->staging);
|
||||
byte *packet_start = QFV_PacketExtend (packet, packet_size);
|
||||
byte *packet_data = packet_start;
|
||||
|
||||
qfv_scatter_t style_scatter = {
|
||||
.srcOffset = 0,
|
||||
.dstOffset = 0,
|
||||
.length = sizeof (vec4f_t[NumStyles]),
|
||||
};
|
||||
auto styles = (vec4f_t *) packet_data;
|
||||
packet_data += style_scatter.length;
|
||||
for (int i = 0; i < NumStyles; i++) {
|
||||
styles[i] = (vec4f_t) { 1, 1, 1, d_lightstylevalue[i] / 65536.0};
|
||||
}
|
||||
QFV_PacketScatterBuffer (packet, lframe->style_buffer,
|
||||
1, &style_scatter, bb);
|
||||
|
||||
if (queue[ST_CASCADE].count) {
|
||||
uint32_t mat_count = queue[ST_CASCADE].count * num_cascade;
|
||||
auto mats = (mat4f_t *) packet_data;
|
||||
auto base = packet_data - packet_start;
|
||||
packet_data += sizeof (mat4f_t[mat_count]);
|
||||
qfv_scatter_t scatter[queue[ST_CASCADE].count];
|
||||
for (uint32_t i = 0; i < queue[ST_CASCADE].count; i++) {
|
||||
auto r = &lctx->light_control.a[light_ids[ST_CASCADE][i]];
|
||||
auto light = get_light (entids[ST_CASCADE][i], lctx->scene->reg);
|
||||
cascade_mats (&mats[i * num_cascade], light->position, ctx);
|
||||
scatter[i] = (qfv_scatter_t) {
|
||||
.srcOffset = sizeof (mat4f_t[i * num_cascade]),
|
||||
.srcOffset = base + sizeof (mat4f_t[i * num_cascade]),
|
||||
.dstOffset = sizeof (mat4f_t[r->matrix_id]),
|
||||
.length = sizeof (mat4f_t[num_cascade]),
|
||||
};
|
||||
}
|
||||
QFV_PacketScatterBuffer (packet, lframe->shadowmat_buffer,
|
||||
queue[ST_CASCADE].count, scatter, bb);
|
||||
QFV_PacketSubmit (packet);
|
||||
}
|
||||
|
||||
if (ndlight) {
|
||||
light_count += ndlight;
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
light_t *lights = QFV_PacketExtend (packet, sizeof (light_t[ndlight]));
|
||||
|
||||
auto mats = (mat4f_t *) packet_data;
|
||||
qfv_scatter_t mat_scatter = {
|
||||
.srcOffset = packet_data - packet_start,
|
||||
.dstOffset = sizeof (mat4f_t[lctx->dynamic_matrix_base]),
|
||||
.length = sizeof (mat4f_t[ndlight * 6]),
|
||||
};
|
||||
for (int i = 0; i < ndlight; i++) {
|
||||
cube_mats (&mats[i * 6], dynamic_lights[i]->origin);
|
||||
}
|
||||
QFV_PacketScatterBuffer (packet, lframe->shadowmat_buffer,
|
||||
1, &mat_scatter, bb);
|
||||
|
||||
auto lights = (light_t *) packet_data;
|
||||
qfv_scatter_t light_scatter = {
|
||||
.srcOffset = packet_data - packet_start,
|
||||
.dstOffset = sizeof (light_t[lctx->dynamic_base]),
|
||||
.length = sizeof (light_t[ndlight]),
|
||||
};
|
||||
packet_data += light_scatter.length;
|
||||
for (int i = 0; i < ndlight; i++) {
|
||||
uint32_t id = lctx->dynamic_base + i;
|
||||
set_lightid (dynamic_light_entities[i], lctx->scene->reg, id);
|
||||
|
@ -555,13 +601,16 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
// full sphere, normal light (not ambient)
|
||||
lights[i].direction = (vec4f_t) { 0, 0, 1, 1 };
|
||||
}
|
||||
VkDeviceSize dlight_offset = sizeof (light_t[lctx->dynamic_base]);
|
||||
QFV_PacketCopyBuffer (packet, lframe->light_buffer, dlight_offset, bb);
|
||||
QFV_PacketSubmit (packet);
|
||||
QFV_PacketScatterBuffer (packet, lframe->light_buffer,
|
||||
1, &light_scatter, bb);
|
||||
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
uint32_t r_size = sizeof (qfv_light_render_t[ndlight]);
|
||||
qfv_light_render_t *render = QFV_PacketExtend (packet, r_size);
|
||||
auto render = (qfv_light_render_t *) packet_data;
|
||||
qfv_scatter_t render_scatter = {
|
||||
.srcOffset = packet_data - packet_start,
|
||||
.dstOffset = sizeof (qfv_light_render_t[lctx->dynamic_base]),
|
||||
.length = sizeof (qfv_light_render_t[ndlight]),
|
||||
};
|
||||
packet_data += render_scatter.length;
|
||||
for (int i = 0; i < ndlight; i++) {
|
||||
auto r = &lctx->light_control.a[lctx->dynamic_base + i];
|
||||
render[i] = (qfv_light_render_t) {
|
||||
|
@ -570,19 +619,8 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
};
|
||||
render[i].id_data |= 0x80000000; // no style
|
||||
}
|
||||
dlight_offset = sizeof (qfv_light_render_t[lctx->dynamic_base]);
|
||||
QFV_PacketCopyBuffer (packet, lframe->render_buffer, dlight_offset, bb);
|
||||
QFV_PacketSubmit (packet);
|
||||
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
uint32_t msize = sizeof (mat4f_t[ndlight * 6]);
|
||||
mat4f_t *mats = QFV_PacketExtend (packet, msize);
|
||||
for (int i = 0; i < ndlight; i++) {
|
||||
cube_mats (&mats[i * 6], dynamic_lights[i]->origin);
|
||||
}
|
||||
VkDeviceSize mat_offset = sizeof (mat4f_t[lctx->dynamic_matrix_base]);
|
||||
QFV_PacketCopyBuffer (packet, lframe->shadowmat_buffer, mat_offset, bb);
|
||||
QFV_PacketSubmit (packet);
|
||||
QFV_PacketScatterBuffer (packet, lframe->render_buffer,
|
||||
1, &render_scatter, bb);
|
||||
}
|
||||
if (developer & SYS_lighting) {
|
||||
Vulkan_Draw_String (vid.width - 32, 8,
|
||||
|
@ -594,28 +632,37 @@ lighting_update_lights (const exprval_t **params, exprval_t *result,
|
|||
for (int i = 1; i < ST_COUNT; i++) {
|
||||
queue[i].start = queue[i - 1].start + queue[i - 1].count;
|
||||
}
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
uint32_t *lids = QFV_PacketExtend (packet,
|
||||
sizeof (uint32_t[light_count]));
|
||||
auto lids = (uint32_t *) packet_data;
|
||||
qfv_scatter_t lid_scatter = {
|
||||
.srcOffset = packet_data - packet_start,
|
||||
.dstOffset = 0,
|
||||
.length = sizeof (uint32_t[light_count]),
|
||||
};
|
||||
packet_data += lid_scatter.length;
|
||||
for (int i = 0; i < ST_COUNT; i++) {
|
||||
memcpy (lids + queue[i].start, light_ids[i],
|
||||
sizeof (uint32_t[queue[i].count]));
|
||||
}
|
||||
QFV_PacketCopyBuffer (packet, lframe->id_buffer, 0,
|
||||
QFV_PacketScatterBuffer (packet, lframe->id_buffer,
|
||||
1, &lid_scatter,
|
||||
&bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]);
|
||||
QFV_PacketSubmit (packet);
|
||||
|
||||
packet = QFV_PacketAcquire (ctx->staging);
|
||||
uint32_t *eids = QFV_PacketExtend (packet,
|
||||
sizeof (uint32_t[light_count]));
|
||||
auto eids = (uint32_t *) packet_data;
|
||||
qfv_scatter_t eid_scatter = {
|
||||
.srcOffset = packet_data - packet_start,
|
||||
.dstOffset = 0,
|
||||
.length = sizeof (uint32_t[light_count]),
|
||||
};
|
||||
packet_data += eid_scatter.length;
|
||||
for (int i = 0; i < ST_COUNT; i++) {
|
||||
memcpy (eids + queue[i].start, entids[i],
|
||||
sizeof (uint32_t[queue[i].count]));
|
||||
}
|
||||
QFV_PacketCopyBuffer (packet, lframe->entid_buffer, 0,
|
||||
QFV_PacketScatterBuffer (packet, lframe->entid_buffer,
|
||||
1, &eid_scatter,
|
||||
&bufferBarriers[qfv_BB_TransferWrite_to_IndexRead]);
|
||||
QFV_PacketSubmit (packet);
|
||||
}
|
||||
QFV_PacketSubmit (packet);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1039,7 +1086,7 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
+ sizeof (qfv_resobj_t)
|
||||
// default shadow map and views
|
||||
+ 3 * sizeof (qfv_resobj_t)
|
||||
// light entids
|
||||
// light matrices
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light ids
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
|
@ -1049,7 +1096,7 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light styles
|
||||
+ sizeof (qfv_resobj_t[frames])
|
||||
// light matrices
|
||||
// light entids
|
||||
+ sizeof (qfv_resobj_t[frames]));
|
||||
lctx->light_resources[0] = (qfv_resource_t) {
|
||||
.name = "lights",
|
||||
|
@ -1063,12 +1110,12 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
|
|||
auto default_map = &splat_inds[1];
|
||||
auto default_view_cube = &default_map[1];
|
||||
auto default_view_2d = &default_view_cube[1];
|
||||
auto light_entids = &default_view_2d[1];
|
||||
auto light_ids = &light_entids[frames];
|
||||
auto light_mats = &default_view_2d[1];
|
||||
auto light_ids = &light_mats[frames];
|
||||
auto light_data = &light_ids[frames];
|
||||
auto light_render = &light_data[frames];
|
||||
auto light_styles = &light_render[frames];
|
||||
auto light_mats = &light_styles[frames];
|
||||
auto light_entids = &light_styles[frames];
|
||||
splat_verts[0] = (qfv_resobj_t) {
|
||||
.name = "splat:vertices",
|
||||
.type = qfv_res_buffer,
|
||||
|
|
Loading…
Reference in a new issue