vk: share buffers and pipeline select for whole mesh

Move gen Strip/Fan index to separate functions.
This commit is contained in:
Denis Pauk 2024-08-02 13:52:30 +03:00
parent a0745ba023
commit 06167fc711
3 changed files with 79 additions and 48 deletions

View File

@ -860,7 +860,7 @@ SCR_PlayCinematic(char *arg)
int i; int i;
/* palette r:2bit, g:3bit, b:3bit */ /* palette r:2bit, g:3bit, b:3bit */
for (i = 0; i < sizeof(cl.cinematicpalette); i++) for (i = 0; i < sizeof(cl.cinematicpalette) / 3; i++)
{ {
cl.cinematicpalette[i * 3 + 0] = ((i >> 0) & 0x3) << 6; cl.cinematicpalette[i * 3 + 0] = ((i >> 0) & 0x3) << 6;
cl.cinematicpalette[i * 3 + 1] = ((i >> 2) & 0x7) << 5; cl.cinematicpalette[i * 3 + 1] = ((i >> 2) & 0x7) << 5;

View File

@ -1076,40 +1076,64 @@ static int NextPow2(int v)
// internal helper // internal helper
static uint8_t *QVk_GetIndexBuffer(VkDeviceSize size, VkDeviceSize *dstOffset, int currentBufferIdx); static uint8_t *QVk_GetIndexBuffer(VkDeviceSize size, VkDeviceSize *dstOffset, int currentBufferIdx);
static void RebuildTriangleIndexBuffer()
static void
GenFanIndexes(uint16_t *data, int from, int to)
{
int i;
// fill the index buffer so that we can emulate triangle fans via triangle lists
for (i = from; i < to; i++)
{
*data = from;
data ++;
*data = i + 1;
data++;
*data = i + 2;
data ++;
}
}
static void
GenStripIndexes(uint16_t *data, int from, int to)
{
int i;
// fill the index buffer so that we can emulate triangle strips via triangle lists
for (i = from + 2; i < to + 2; i++)
{
if ((i%2) == 0)
{
*data = i - 2;
data ++;
*data = i - 1;
data ++;
*data = i;
data ++;
}
else
{
*data = i;
data ++;
*data = i - 1;
data ++;
*data = i - 2;
data ++;
}
}
}
static void
RebuildTriangleIndexBuffer()
{ {
int idx = 0;
VkDeviceSize dstOffset = 0; VkDeviceSize dstOffset = 0;
VkDeviceSize bufferSize = 3 * vk_config.triangle_index_count * sizeof(uint16_t); VkDeviceSize bufferSize = 3 * vk_config.triangle_index_count * sizeof(uint16_t);
uint16_t *iboData = NULL; uint16_t *iboData = NULL;
uint16_t *fanData = malloc(bufferSize); uint16_t *fanData = malloc(bufferSize);
uint16_t *stripData = malloc(bufferSize); uint16_t *stripData = malloc(bufferSize);
// fill the index buffer so that we can emulate triangle fans via triangle lists GenFanIndexes(fanData, 0, vk_config.triangle_index_count);
for (int i = 0; i < vk_config.triangle_index_count; ++i) GenStripIndexes(stripData, 0, vk_config.triangle_index_count);
{
fanData[idx++] = 0;
fanData[idx++] = i + 1;
fanData[idx++] = i + 2;
}
// fill the index buffer so that we can emulate triangle strips via triangle lists
idx = 0;
for (int i = 2; i < (vk_config.triangle_index_count + 2); ++i)
{
if ((i%2) == 0)
{
stripData[idx++] = i - 2;
stripData[idx++] = i - 1;
stripData[idx++] = i;
}
else
{
stripData[idx++] = i;
stripData[idx++] = i - 1;
stripData[idx++] = i - 2;
}
}
for (int i = 0; i < NUM_DYNBUFFERS; ++i) for (int i = 0; i < NUM_DYNBUFFERS; ++i)
{ {
@ -2634,14 +2658,16 @@ QVk_CheckTriangleIbo(VkDeviceSize indexCount)
} }
} }
VkBuffer QVk_GetTriangleFanIbo(VkDeviceSize indexCount) VkBuffer
QVk_GetTriangleFanIbo(VkDeviceSize indexCount)
{ {
QVk_CheckTriangleIbo(indexCount); QVk_CheckTriangleIbo(indexCount);
return *vk_triangleFanIbo; return *vk_triangleFanIbo;
} }
VkBuffer QVk_GetTriangleStripIbo(VkDeviceSize indexCount) VkBuffer
QVk_GetTriangleStripIbo(VkDeviceSize indexCount)
{ {
QVk_CheckTriangleIbo(indexCount); QVk_CheckTriangleIbo(indexCount);

View File

@ -189,10 +189,9 @@ Mesh_Free(void)
static void static void
Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffset, Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffset,
int *order, int *order_end, int *order, int *order_end, float alpha, qvkpipeline_t *pipeline,
float alpha, int leftHandOffset, int translucentIdx,
dxtrivertx_t *verts, vec4_t *s_lerped, int verts_count, const float *shadelight, dxtrivertx_t *verts, vec4_t *s_lerped, int verts_count, const float *shadelight,
const float *shadevector, qboolean iscolor) const float *shadevector, qboolean iscolor, int numtis)
{ {
int vertCounts[2] = { 0, 0 }; int vertCounts[2] = { 0, 0 };
int pipeCounters[2] = { 0, 0 }; int pipeCounters[2] = { 0, 0 };
@ -326,12 +325,10 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs
drawInfo[pipelineIdx][pipeCounters[pipelineIdx]].firstVertex = vertCounts[pipelineIdx]; drawInfo[pipelineIdx][pipeCounters[pipelineIdx]].firstVertex = vertCounts[pipelineIdx];
} }
// player configuration screen model is using the UI renderpass VkBuffer fan, strip;
int pidx = (r_newrefdef.rdflags & RDF_NOWORLDMODEL) ? RP_UI : RP_WORLD; fan = QVk_GetTriangleFanIbo(numtis);
// non-depth write alias models don't occur with RF_WEAPONMODEL set, so no need for additional left-handed pipelines strip = QVk_GetTriangleStripIbo(numtis);
qvkpipeline_t pipelines[2][2] = {
{ vk_drawModelPipelineFan[pidx], vk_drawLefthandModelPipelineFan },
{ vk_drawNoDepthModelPipelineFan, vk_drawLefthandModelPipelineFan } };
for (int p = 0; p < 2; p++) for (int p = 0; p < 2; p++)
{ {
VkDeviceSize vaoSize = sizeof(modelvert) * vertCounts[p]; VkDeviceSize vaoSize = sizeof(modelvert) * vertCounts[p];
@ -340,16 +337,16 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs
uint8_t *vertData = QVk_GetVertexBuffer(vaoSize, &vbo, &vboOffset); uint8_t *vertData = QVk_GetVertexBuffer(vaoSize, &vbo, &vboOffset);
memcpy(vertData, vertList[p], vaoSize); memcpy(vertData, vertList[p], vaoSize);
QVk_BindPipeline(&pipelines[translucentIdx][leftHandOffset]); QVk_BindPipeline(pipeline);
vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelines[translucentIdx][leftHandOffset].layout, 0, 2, descriptorSets, 1, uboOffset); pipeline->layout, 0, 2, descriptorSets, 1, uboOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset);
if (p == TRIANGLE_STRIP) if (p == TRIANGLE_STRIP)
{ {
int i; int i;
vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleStripIbo(maxTriangleFanIdxCnt), 0, VK_INDEX_TYPE_UINT16); vkCmdBindIndexBuffer(vk_activeCmdbuffer, strip, 0, VK_INDEX_TYPE_UINT16);
for (i = 0; i < pipeCounters[p]; i++) for (i = 0; i < pipeCounters[p]; i++)
{ {
@ -360,7 +357,7 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs
{ {
int i; int i;
vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo(maxTriangleFanIdxCnt), 0, VK_INDEX_TYPE_UINT16); vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, 0, VK_INDEX_TYPE_UINT16);
for (i = 0; i < pipeCounters[p]; i++) for (i = 0; i < pipeCounters[p]; i++)
{ {
@ -440,23 +437,31 @@ Vk_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, (float*)s_lerped, R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, (float*)s_lerped,
move, frontv, backv); move, frontv, backv);
num_mesh_nodes = paliashdr->num_meshes;
mesh_nodes = (dmdxmesh_t *)((char*)paliashdr + paliashdr->ofs_meshes);
VkDescriptorSet descriptorSets[] = { VkDescriptorSet descriptorSets[] = {
skin->vk_texture.descriptorSet, skin->vk_texture.descriptorSet,
uboDescriptorSet uboDescriptorSet
}; };
// player configuration screen model is using the UI renderpass
int pidx = (r_newrefdef.rdflags & RDF_NOWORLDMODEL) ? RP_UI : RP_WORLD;
// non-depth write alias models don't occur with RF_WEAPONMODEL set, so no need for additional left-handed pipelines
qvkpipeline_t pipelines[2][2] = {
{ vk_drawModelPipelineFan[pidx], vk_drawLefthandModelPipelineFan },
{ vk_drawNoDepthModelPipelineFan, vk_drawLefthandModelPipelineFan } };
num_mesh_nodes = paliashdr->num_meshes;
mesh_nodes = (dmdxmesh_t *)((char*)paliashdr + paliashdr->ofs_meshes);
for (i = 0; i < num_mesh_nodes; i++) for (i = 0; i < num_mesh_nodes; i++)
{ {
Vk_DrawAliasFrameLerpCommands(descriptorSets, &uboOffset, Vk_DrawAliasFrameLerpCommands(descriptorSets, &uboOffset,
order + mesh_nodes[i].ofs_glcmds, order + mesh_nodes[i].ofs_glcmds,
order + Q_min(paliashdr->num_glcmds, order + Q_min(paliashdr->num_glcmds,
mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds), mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds),
alpha, leftHandOffset, translucentIdx, verts, alpha, &pipelines[translucentIdx][leftHandOffset], verts,
s_lerped, paliashdr->num_xyz, shadelight, shadevector, s_lerped, paliashdr->num_xyz, shadelight, shadevector,
currententity->flags & (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE)); currententity->flags & (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE),
paliashdr->num_tris);
} }
} }