diff --git a/src/client/cl_cin.c b/src/client/cl_cin.c index 91961282..777a3b90 100644 --- a/src/client/cl_cin.c +++ b/src/client/cl_cin.c @@ -860,7 +860,7 @@ SCR_PlayCinematic(char *arg) int i; /* 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 + 1] = ((i >> 2) & 0x7) << 5; diff --git a/src/client/refresh/vk/vk_common.c b/src/client/refresh/vk/vk_common.c index 0d75a3cf..9ae1b56b 100644 --- a/src/client/refresh/vk/vk_common.c +++ b/src/client/refresh/vk/vk_common.c @@ -1076,40 +1076,64 @@ static int NextPow2(int v) // internal helper 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 bufferSize = 3 * vk_config.triangle_index_count * sizeof(uint16_t); uint16_t *iboData = NULL; uint16_t *fanData = malloc(bufferSize); uint16_t *stripData = malloc(bufferSize); - // fill the index buffer so that we can emulate triangle fans via triangle lists - for (int i = 0; i < vk_config.triangle_index_count; ++i) - { - 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; - } - } + GenFanIndexes(fanData, 0, vk_config.triangle_index_count); + GenStripIndexes(stripData, 0, vk_config.triangle_index_count); 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); return *vk_triangleFanIbo; } -VkBuffer QVk_GetTriangleStripIbo(VkDeviceSize indexCount) +VkBuffer +QVk_GetTriangleStripIbo(VkDeviceSize indexCount) { QVk_CheckTriangleIbo(indexCount); diff --git a/src/client/refresh/vk/vk_mesh.c b/src/client/refresh/vk/vk_mesh.c index 957b0fc9..cd7ff568 100644 --- a/src/client/refresh/vk/vk_mesh.c +++ b/src/client/refresh/vk/vk_mesh.c @@ -189,10 +189,9 @@ Mesh_Free(void) static void Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffset, - int *order, int *order_end, - float alpha, int leftHandOffset, int translucentIdx, + int *order, int *order_end, float alpha, qvkpipeline_t *pipeline, 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 pipeCounters[2] = { 0, 0 }; @@ -326,12 +325,10 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs drawInfo[pipelineIdx][pipeCounters[pipelineIdx]].firstVertex = vertCounts[pipelineIdx]; } - // 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 } }; + VkBuffer fan, strip; + fan = QVk_GetTriangleFanIbo(numtis); + strip = QVk_GetTriangleStripIbo(numtis); + for (int p = 0; p < 2; 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); memcpy(vertData, vertList[p], vaoSize); - QVk_BindPipeline(&pipelines[translucentIdx][leftHandOffset]); + QVk_BindPipeline(pipeline); 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); if (p == TRIANGLE_STRIP) { 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++) { @@ -360,7 +357,7 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs { 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++) { @@ -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, move, frontv, backv); - num_mesh_nodes = paliashdr->num_meshes; - mesh_nodes = (dmdxmesh_t *)((char*)paliashdr + paliashdr->ofs_meshes); - VkDescriptorSet descriptorSets[] = { skin->vk_texture.descriptorSet, 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++) { Vk_DrawAliasFrameLerpCommands(descriptorSets, &uboOffset, order + mesh_nodes[i].ofs_glcmds, order + Q_min(paliashdr->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, - 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); } }