[vulkan] Add a scatter buffer copy function

Updating directional light CSM matrices made me realize I needed to be
able to send the contents of a packet to multiple locations in a buffer
(I may need to extend it to multiple buffers). Seems to work, but I have
only the one directional light with which to test.
This commit is contained in:
Bill Currie 2023-08-13 17:30:59 +09:00
parent 558e11e9b7
commit f3ca2f158b
2 changed files with 44 additions and 0 deletions

View file

@ -25,6 +25,11 @@ typedef struct qfv_stagebuf_s {
void *data;
} qfv_stagebuf_t;
typedef struct qfv_scatter_s {
VkDeviceSize srcOffset;
VkDeviceSize dstOffset;
VkDeviceSize length;
} qfv_scatter_t;
qfv_stagebuf_t *QFV_CreateStagingBuffer (struct qfv_device_s *device,
const char *name, size_t size,
@ -38,6 +43,9 @@ struct qfv_bufferbarrier_s;
void QFV_PacketCopyBuffer (qfv_packet_t *packet,
VkBuffer dstBuffer, VkDeviceSize offset,
const struct qfv_bufferbarrier_s *dstBarrier);
void QFV_PacketScatterBuffer (qfv_packet_t *packet, VkBuffer dstBuffer,
uint32_t count, qfv_scatter_t *scatter,
const struct qfv_bufferbarrier_s *dstBarrier);
struct qfv_imagebarrier_s;
void QFV_PacketCopyImage (qfv_packet_t *packet, VkImage dstImage,
int width, int height,

View file

@ -317,6 +317,42 @@ QFV_PacketCopyBuffer (qfv_packet_t *packet,
0, 0, 0, 1, &bb.barrier, 0, 0);
}
void
QFV_PacketScatterBuffer (qfv_packet_t *packet, VkBuffer dstBuffer,
uint32_t count, qfv_scatter_t *scatter,
const qfv_bufferbarrier_t *dstBarrier)
{
qfv_devfuncs_t *dfunc = packet->stage->device->funcs;
qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite];
VkBufferCopy copy_regions[count];
VkBufferMemoryBarrier barriers[count];
for (uint32_t i = 0; i < count; i++) {
barriers[i] = bb.barrier;
barriers[i].buffer = dstBuffer;
barriers[i].offset = scatter[i].dstOffset;
barriers[i].size = scatter[i].length;
copy_regions[i] = (VkBufferCopy) {
.srcOffset = packet->offset + scatter[i].srcOffset,
.dstOffset = scatter[i].dstOffset,
.size = scatter[i].length,
};
}
dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
0, 0, 0, count, barriers, 0, 0);
dfunc->vkCmdCopyBuffer (packet->cmd, packet->stage->buffer, dstBuffer,
count, copy_regions);
bb = *dstBarrier;
for (uint32_t i = 0; i < count; i++) {
barriers[i] = bb.barrier;
barriers[i].buffer = dstBuffer;
barriers[i].offset = scatter[i].dstOffset;
barriers[i].size = scatter[i].length;
}
dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
0, 0, 0, count, barriers, 0, 0);
}
void
QFV_PacketCopyImage (qfv_packet_t *packet, VkImage dstImage,
int width, int height,