[vulkan] Clean up buffer barriers a bit

This even fixes a couple of minor issues that snuck past validation.
This commit is contained in:
Bill Currie 2021-04-24 15:47:31 +09:00
parent dc9b64fadd
commit 785be9d340
7 changed files with 123 additions and 109 deletions

View file

@ -7,6 +7,12 @@ typedef struct {
VkImageMemoryBarrier barrier; VkImageMemoryBarrier barrier;
} qfv_imagebarrier_t; } qfv_imagebarrier_t;
typedef struct {
VkPipelineStageFlags srcStages;
VkPipelineStageFlags dstStages;
VkBufferMemoryBarrier barrier;
} qfv_bufferbarrier_t;
//XXX Note: imageBarriers and the enum must be kept in sync //XXX Note: imageBarriers and the enum must be kept in sync
enum { enum {
qfv_LT_Undefined_to_TransferDst, qfv_LT_Undefined_to_TransferDst,
@ -18,6 +24,15 @@ enum {
qfv_LT_Undefined_to_Color, qfv_LT_Undefined_to_Color,
}; };
//XXX Note: bufferBarriers and the enum must be kept in sync
enum {
qfv_BB_Unknown_to_TransferWrite,
qfv_BB_TransferWrite_to_VertexAttrRead,
qfv_BB_TransferWrite_to_IndexRead,
qfv_BB_TransferWrite_to_UniformRead,
};
extern const qfv_imagebarrier_t imageBarriers[]; extern const qfv_imagebarrier_t imageBarriers[];
extern const qfv_bufferbarrier_t bufferBarriers[];
#endif//__QF_Vulkan_barrier_h #endif//__QF_Vulkan_barrier_h

View file

@ -407,23 +407,17 @@ Vulkan_Mod_MakeAliasModelDisplayLists (mod_alias_ctx_t *alias_ctx, void *_m,
header->poseverts = numverts; header->poseverts = numverts;
qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite];
VkBufferMemoryBarrier wr_barriers[] = { VkBufferMemoryBarrier wr_barriers[] = {
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier, bb.barrier, bb.barrier,
0, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
vbuff, 0, vert_size},
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
0, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
uvbuff, 0, uv_size},
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
0, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
ibuff, 0, ind_size},
}; };
dfunc->vkCmdPipelineBarrier (packet->cmd, wr_barriers[0].buffer = vbuff;
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, wr_barriers[0].size = vert_size;
VK_PIPELINE_STAGE_TRANSFER_BIT, wr_barriers[1].buffer = uvbuff;
wr_barriers[1].size = uv_size;
wr_barriers[2].buffer = ibuff;
wr_barriers[2].size = ind_size;
dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
0, 0, 0, 3, wr_barriers, 0, 0); 0, 0, 0, 3, wr_barriers, 0, 0);
VkBufferCopy copy_region[] = { VkBufferCopy copy_region[] = {
{ packet->offset, 0, vert_size }, { packet->offset, 0, vert_size },
@ -436,23 +430,21 @@ Vulkan_Mod_MakeAliasModelDisplayLists (mod_alias_ctx_t *alias_ctx, void *_m,
uvbuff, 1, &copy_region[1]); uvbuff, 1, &copy_region[1]);
dfunc->vkCmdCopyBuffer (packet->cmd, stage->buffer, dfunc->vkCmdCopyBuffer (packet->cmd, stage->buffer,
ibuff, 1, &copy_region[2]); ibuff, 1, &copy_region[2]);
// both qfv_BB_TransferWrite_to_VertexAttrRead and
// qfv_BB_TransferWrite_to_IndexRead have the same stage flags
bb = bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead];
VkBufferMemoryBarrier rd_barriers[] = { VkBufferMemoryBarrier rd_barriers[] = {
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead].barrier,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead].barrier,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, bufferBarriers[qfv_BB_TransferWrite_to_IndexRead].barrier,
vbuff, 0, vert_size },
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
uvbuff, 0, uv_size },
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
ibuff, 0, ind_size },
}; };
dfunc->vkCmdPipelineBarrier (packet->cmd, rd_barriers[0].buffer = vbuff;
VK_PIPELINE_STAGE_TRANSFER_BIT, rd_barriers[0].size = vert_size;
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, rd_barriers[1].buffer = uvbuff;
rd_barriers[1].size = uv_size;
rd_barriers[2].buffer = ibuff;
rd_barriers[2].size = ind_size;
dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
0, 0, 0, 3, rd_barriers, 0, 0); 0, 0, 0, 3, rd_barriers, 0, 0);
QFV_PacketSubmit (packet); QFV_PacketSubmit (packet);
QFV_DestroyStagingBuffer (stage); QFV_DestroyStagingBuffer (stage);

View file

@ -133,3 +133,47 @@ const qfv_imagebarrier_t imageBarriers[] = {
}, },
}, },
}; };
const qfv_bufferbarrier_t bufferBarriers[] = {
// unknown to transfer write
{
.srcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
.barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
0, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
},
},
// transfer write to vertex attribute read
{
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
.dstStages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
.barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
},
},
// transfer write to index read
{
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
.dstStages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
.barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
},
},
// transfer write to uniform read
// note: not necessarily optimal as it uses vertex shader for dst
{
.srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
.dstStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
.barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_UNIFORM_READ_BIT,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
},
},
};

View file

@ -581,29 +581,19 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
bctx->vertex_buffer_size = vertex_buffer_size; bctx->vertex_buffer_size = vertex_buffer_size;
} }
VkBufferMemoryBarrier wr_barrier = { qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite];
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = bctx->vertex_buffer;
0, VK_ACCESS_TRANSFER_WRITE_BIT, bb.barrier.size = vertex_buffer_size;
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
bctx->vertex_buffer, 0, vertex_buffer_size, 0, 0, 0, 1, &bb.barrier, 0, 0);
};
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, 0, 1, &wr_barrier, 0, 0);
VkBufferCopy copy_region = { packet->offset, 0, vertex_buffer_size }; VkBufferCopy copy_region = { packet->offset, 0, vertex_buffer_size };
dfunc->vkCmdCopyBuffer (packet->cmd, stage->buffer, dfunc->vkCmdCopyBuffer (packet->cmd, stage->buffer,
bctx->vertex_buffer, 1, &copy_region); bctx->vertex_buffer, 1, &copy_region);
VkBufferMemoryBarrier rd_barrier = { bb = bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead];
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = bctx->vertex_buffer;
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, bb.barrier.size = vertex_buffer_size;
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
bctx->vertex_buffer, 0, vertex_buffer_size, 0, 0, 0, 1, &bb.barrier, 0, 0);
};
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
0, 0, 0, 1, &rd_barrier, 0, 0);
QFV_PacketSubmit (packet); QFV_PacketSubmit (packet);
QFV_DestroyStagingBuffer (stage); QFV_DestroyStagingBuffer (stage);
} }

View file

@ -173,27 +173,19 @@ create_quad_buffers (vulkan_ctx_t *ctx)
*ind++ = -1; *ind++ = -1;
} }
VkBufferMemoryBarrier wr_barrier = { qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite];
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = ibuf;
0, VK_ACCESS_TRANSFER_WRITE_BIT, bb.barrier.size = ind_size;
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, ibuf, 0, ind_size dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
}; 0, 0, 0, 1, &bb.barrier, 0, 0);
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, 0, 1, &wr_barrier, 0, 0);
VkBufferCopy copy_region = { packet->offset, 0, ind_size }; VkBufferCopy copy_region = { packet->offset, 0, ind_size };
dfunc->vkCmdCopyBuffer (packet->cmd, ctx->staging->buffer, ibuf, dfunc->vkCmdCopyBuffer (packet->cmd, ctx->staging->buffer, ibuf,
1, &copy_region); 1, &copy_region);
VkBufferMemoryBarrier rd_barrier = { bb = bufferBarriers[qfv_BB_TransferWrite_to_IndexRead];
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = ibuf;
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT, bb.barrier.size = ind_size;
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, ibuf, 0, ind_size dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
}; 0, 0, 0, 1, &bb.barrier, 0, 0);
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
0, 0, 0, 1, &rd_barrier, 0, 0);
QFV_PacketSubmit (packet); QFV_PacketSubmit (packet);
} }

View file

@ -50,6 +50,7 @@
#include "QF/Vulkan/qf_lighting.h" #include "QF/Vulkan/qf_lighting.h"
#include "QF/Vulkan/qf_texture.h" #include "QF/Vulkan/qf_texture.h"
#include "QF/Vulkan/barrier.h"
#include "QF/Vulkan/buffer.h" #include "QF/Vulkan/buffer.h"
#include "QF/Vulkan/debug.h" #include "QF/Vulkan/debug.h"
#include "QF/Vulkan/descriptor.h" #include "QF/Vulkan/descriptor.h"
@ -125,7 +126,7 @@ update_lights (vulkan_ctx_t *ctx)
for (int i = 0; i < NUM_STYLES; i++) { for (int i = 0; i < NUM_STYLES; i++) {
light_data->intensity[i] = d_lightstylevalue[i] / 65536.0; light_data->intensity[i] = d_lightstylevalue[i] / 65536.0;
} }
// dynamic lights seem a tad fiant, so 16x map lights // dynamic lights seem a tad faint, so 16x map lights
light_data->intensity[64] = 1 / 16.0; light_data->intensity[64] = 1 / 16.0;
light_data->intensity[65] = 1 / 16.0; light_data->intensity[65] = 1 / 16.0;
light_data->intensity[66] = 1 / 16.0; light_data->intensity[66] = 1 / 16.0;
@ -155,31 +156,21 @@ update_lights (vulkan_ctx_t *ctx)
} }
} }
VkBufferMemoryBarrier wr_barriers[] = { qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite];
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = lframe->light_buffer;
0, VK_ACCESS_TRANSFER_WRITE_BIT, bb.barrier.size = sizeof (qfv_light_buffer_t);
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
lframe->light_buffer, 0, sizeof (qfv_light_buffer_t) }, 0, 0, 0, 1, &bb.barrier, 0, 0);
};
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, 0, 1, wr_barriers, 0, 0);
VkBufferCopy copy_region[] = { VkBufferCopy copy_region[] = {
{ packet->offset, 0, sizeof (qfv_light_buffer_t) }, { packet->offset, 0, sizeof (qfv_light_buffer_t) },
}; };
dfunc->vkCmdCopyBuffer (packet->cmd, ctx->staging->buffer, dfunc->vkCmdCopyBuffer (packet->cmd, ctx->staging->buffer,
lframe->light_buffer, 1, &copy_region[0]); lframe->light_buffer, 1, &copy_region[0]);
VkBufferMemoryBarrier rd_barriers[] = { bb = bufferBarriers[qfv_BB_TransferWrite_to_UniformRead];
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = lframe->light_buffer;
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, bb.barrier.size = sizeof (qfv_light_buffer_t);
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
lframe->light_buffer, 0, sizeof (qfv_light_buffer_t) }, 0, 0, 0, 1, &bb.barrier, 0, 0);
};
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
0, 0, 0, 1, rd_barriers, 0, 0);
QFV_PacketSubmit (packet); QFV_PacketSubmit (packet);
} }

View file

@ -348,31 +348,21 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx)
float *verts = QFV_PacketExtend (packet, sizeof (quad_vertices)); float *verts = QFV_PacketExtend (packet, sizeof (quad_vertices));
memcpy (verts, quad_vertices, sizeof (quad_vertices)); memcpy (verts, quad_vertices, sizeof (quad_vertices));
VkBufferMemoryBarrier wr_barriers[] = { qfv_bufferbarrier_t bb = bufferBarriers[qfv_BB_Unknown_to_TransferWrite];
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = ctx->quad_buffer;
0, VK_ACCESS_TRANSFER_WRITE_BIT, bb.barrier.size = sizeof (quad_vertices);
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
ctx->quad_buffer, 0, sizeof (quad_vertices) }, 0, 0, 0, 1, &bb.barrier, 0, 0);
};
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, 0, 1, wr_barriers, 0, 0);
VkBufferCopy copy_region[] = { VkBufferCopy copy_region[] = {
{ packet->offset, 0, sizeof (quad_vertices) }, { packet->offset, 0, sizeof (quad_vertices) },
}; };
dfunc->vkCmdCopyBuffer (packet->cmd, ctx->staging->buffer, dfunc->vkCmdCopyBuffer (packet->cmd, ctx->staging->buffer,
ctx->quad_buffer, 1, &copy_region[0]); ctx->quad_buffer, 1, &copy_region[0]);
VkBufferMemoryBarrier rd_barriers[] = { bb = bufferBarriers[qfv_BB_TransferWrite_to_VertexAttrRead];
{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 0, bb.barrier.buffer = ctx->quad_buffer;
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, bb.barrier.size = sizeof (quad_vertices);
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, dfunc->vkCmdPipelineBarrier (packet->cmd, bb.srcStages, bb.dstStages,
ctx->quad_buffer, 0, sizeof (quad_vertices) }, 0, 0, 0, 1, &bb.barrier, 0, 0);
};
dfunc->vkCmdPipelineBarrier (packet->cmd,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
0, 0, 0, 1, rd_barriers, 0, 0);
QFV_PacketSubmit (packet); QFV_PacketSubmit (packet);
} }