diff --git a/src/client/refresh/vk/header/local.h b/src/client/refresh/vk/header/local.h index a61695ac..859cf8b1 100644 --- a/src/client/refresh/vk/header/local.h +++ b/src/client/refresh/vk/header/local.h @@ -270,9 +270,6 @@ typedef struct uint32_t uniform_buffer_usage; uint32_t uniform_buffer_max_usage; uint32_t uniform_buffer_size; - uint32_t triangle_index_usage; - uint32_t triangle_index_max_usage; - uint32_t triangle_index_count; } vkconfig_t; #define MAX_LIGHTMAPS 256 diff --git a/src/client/refresh/vk/header/qvk.h b/src/client/refresh/vk/header/qvk.h index c5dc2ba6..555b86b2 100644 --- a/src/client/refresh/vk/header/qvk.h +++ b/src/client/refresh/vk/header/qvk.h @@ -329,8 +329,8 @@ void QVk_DestroyPipeline(qvkpipeline_t *pipeline); uint8_t* QVk_GetVertexBuffer(VkDeviceSize size, VkBuffer *dstBuffer, VkDeviceSize *dstOffset); uint8_t* QVk_GetUniformBuffer(VkDeviceSize size, uint32_t *dstOffset, VkDescriptorSet *dstUboDescriptorSet); uint8_t* QVk_GetStagingBuffer(VkDeviceSize size, int alignment, VkCommandBuffer *cmdBuffer, VkBuffer *buffer, uint32_t *dstOffset); -VkBuffer QVk_GetTriangleFanIbo(VkDeviceSize indexCount); -VkBuffer QVk_GetTriangleStripIbo(VkDeviceSize indexCount); +VkBuffer QVk_GetTriangleFanIbo(VkDeviceSize indexCount, VkDeviceSize *dstOffset); +VkBuffer QVk_GetTriangleStripIbo(VkDeviceSize indexCount, VkDeviceSize *dstOffset); void QVk_DrawColorRect(float *ubo, VkDeviceSize uboSize, qvkrenderpasstype_t rpType); void QVk_DrawTexRect(const float *ubo, VkDeviceSize uboSize, qvktexture_t *texture); void QVk_BindPipeline(qvkpipeline_t *pipeline); diff --git a/src/client/refresh/vk/vk_common.c b/src/client/refresh/vk/vk_common.c index 47349c69..e89b1be8 100644 --- a/src/client/refresh/vk/vk_common.c +++ b/src/client/refresh/vk/vk_common.c @@ -235,11 +235,11 @@ static VkDescriptorSet vk_uboDescriptorSets[NUM_DYNBUFFERS]; static qvkstagingbuffer_t vk_stagingBuffers[NUM_DYNBUFFERS]; static int vk_activeDynBufferIdx = 0; static int vk_activeSwapBufferIdx = 0; - -// index buffer for triangle fan/strip emulation - all because Metal/MoltenVK don't support them -static VkBuffer *vk_triangleFanIbo = NULL; -static VkBuffer *vk_triangleStripIbo = NULL; -static uint32_t vk_triangleFanIboUsage = 0; +static int vk_dynIndex = 0; +/* cache tri between calls */ +static VkBuffer *vk_fanBuffercache = NULL; +static VkDeviceSize vk_fanOffset = 0; +static int vk_fanBuffersize = 0; // swap buffers used if primary dynamic buffers get full #define NUM_SWAPBUFFER_SLOTS 4 @@ -258,8 +258,6 @@ static VkDescriptorSet *vk_swapDescriptorSets[NUM_SWAPBUFFER_SLOTS]; #define UNIFORM_BUFFER_SIZE (2048 * 1024) // staging buffer is constant in size but has a max limit beyond which it will be submitted #define STAGING_BUFFER_MAXSIZE (8192 * 1024) -// initial index count in triangle fan buffer - assuming 200 indices (200*3 = 600 triangles) per object -#define TRIANGLE_INDEX_CNT 200 // Vulkan common descriptor sets for UBO, primary texture sampler and optional lightmap texture static VkDescriptorSetLayout vk_uboDescSetLayout; @@ -1123,33 +1121,19 @@ GenStripIndexes(uint16_t *data, int from, int to) } } -static void -UpdateIndexBuffer(int index, uint16_t *data, VkDeviceSize bufferSize, VkDeviceSize *dstOffset) +static VkBuffer* +UpdateIndexBuffer(uint16_t *data, VkDeviceSize bufferSize, VkDeviceSize *dstOffset) { uint16_t *iboData = NULL; - VK_VERIFY(buffer_invalidate(&vk_dynIndexBuffers[index].resource)); - iboData = (uint16_t *)QVk_GetIndexBuffer(bufferSize, dstOffset, index); + vk_dynIndex = (vk_dynIndex + 1) % NUM_DYNBUFFERS; + + VK_VERIFY(buffer_invalidate(&vk_dynIndexBuffers[vk_dynIndex].resource)); + iboData = (uint16_t *)QVk_GetIndexBuffer(bufferSize, dstOffset, vk_dynIndex); memcpy(iboData, data, bufferSize); - VK_VERIFY(buffer_flush(&vk_dynIndexBuffers[index].resource)); -} + VK_VERIFY(buffer_flush(&vk_dynIndexBuffers[vk_dynIndex].resource)); -static void -RebuildTriangleIndexBuffer() -{ - VkDeviceSize dstOffset = 0; - VkDeviceSize bufferSize = 3 * vk_config.triangle_index_count * sizeof(uint16_t); - uint16_t *data = malloc(bufferSize); - - GenFanIndexes(data, 0, vk_config.triangle_index_count); - UpdateIndexBuffer(0, data, bufferSize, &dstOffset); - vk_triangleFanIbo = &vk_dynIndexBuffers[0].resource.buffer; - - GenStripIndexes(data, 0, vk_config.triangle_index_count); - UpdateIndexBuffer(1, data, bufferSize, &dstOffset); - vk_triangleStripIbo = &vk_dynIndexBuffers[1].resource.buffer; - - free(data); + return &vk_dynIndexBuffers[vk_dynIndex].resource.buffer; } static void CreateStagingBuffer(VkDeviceSize size, qvkstagingbuffer_t *dstBuffer, int i) @@ -1786,9 +1770,6 @@ qboolean QVk_Init(void) vk_config.uniform_buffer_usage = 0; vk_config.uniform_buffer_max_usage = 0; vk_config.uniform_buffer_size = UNIFORM_BUFFER_SIZE; - vk_config.triangle_index_usage = 0; - vk_config.triangle_index_max_usage = 0; - vk_config.triangle_index_count = TRIANGLE_INDEX_CNT; #ifdef USE_SDL3 if (!SDL_Vulkan_GetInstanceExtensions(&extCount)) @@ -2157,9 +2138,10 @@ qboolean QVk_Init(void) CreateDynamicBuffers(); // create staging buffers CreateStagingBuffers(); - // assign a dynamic index buffer for triangle fan emulation - RebuildTriangleIndexBuffer(); - vk_triangleFanIboUsage = ROUNDUP(3 * vk_config.triangle_index_count * sizeof(uint16_t), 4); + /* reset fan buffer */ + vk_fanOffset = 0; + vk_fanBuffersize = 512; + vk_fanBuffercache = NULL; CreatePipelines(); CreateSamplers(); @@ -2194,10 +2176,11 @@ VkResult QVk_BeginFrame(const VkViewport* viewport, const VkRect2D* scissor) vk_state.current_pipeline = VK_NULL_HANDLE; vk_state.current_renderpass = RP_COUNT; vk_config.vertex_buffer_usage = 0; - // triangle fan index buffer data will not be cleared between frames unless the buffer itself is too small - vk_config.index_buffer_usage = vk_triangleFanIboUsage; + vk_config.index_buffer_usage = 0; vk_config.uniform_buffer_usage = 0; - vk_config.triangle_index_usage = 0; + /* reset fan buffer */ + vk_fanOffset = 0; + vk_fanBuffercache = NULL; ReleaseSwapBuffers(); @@ -2221,8 +2204,7 @@ VkResult QVk_BeginFrame(const VkViewport* viewport, const VkRect2D* scissor) vk_activeDynBufferIdx = (vk_activeDynBufferIdx + 1) % NUM_DYNBUFFERS; vk_dynUniformBuffers[vk_activeDynBufferIdx].currentOffset = 0; vk_dynVertexBuffers[vk_activeDynBufferIdx].currentOffset = 0; - // triangle fan index data is placed in the beginning of the buffer - vk_dynIndexBuffers[vk_activeDynBufferIdx].currentOffset = vk_triangleFanIboUsage; + vk_dynIndexBuffers[vk_activeDynBufferIdx].currentOffset = 0; VK_VERIFY(buffer_invalidate(&vk_dynUniformBuffers[vk_activeDynBufferIdx].resource)); VK_VERIFY(buffer_invalidate(&vk_dynVertexBuffers[vk_activeDynBufferIdx].resource)); VK_VERIFY(buffer_invalidate(&vk_dynIndexBuffers[vk_activeDynBufferIdx].resource)); @@ -2635,40 +2617,50 @@ uint8_t *QVk_GetStagingBuffer(VkDeviceSize size, int alignment, VkCommandBuffer return data; } -static void -QVk_CheckTriangleIbo(VkDeviceSize indexCount) +VkBuffer +QVk_GetTriangleFanIbo(VkDeviceSize indexCount, VkDeviceSize *dstOffset) { - if (indexCount > vk_config.triangle_index_usage) - vk_config.triangle_index_usage = indexCount; + VkDeviceSize bufferSize; + VkBuffer *buffer; + uint16_t *data; - if (vk_config.triangle_index_usage > vk_config.triangle_index_max_usage) - vk_config.triangle_index_max_usage = vk_config.triangle_index_usage; - - if (indexCount > vk_config.triangle_index_count) + if (vk_fanBuffercache && (vk_fanBuffersize > indexCount)) { - vk_config.triangle_index_count *= BUFFER_RESIZE_FACTOR; - R_Printf(PRINT_ALL, "%s: Resizing triangle index buffer to %u indices.\n", - __func__, vk_config.triangle_index_count); - RebuildTriangleIndexBuffer(); - - vk_triangleFanIboUsage = ROUNDUP(3 * vk_config.triangle_index_count * sizeof(uint16_t), 4); + *dstOffset = vk_fanOffset; + return *vk_fanBuffercache; } + + indexCount = ROUNDUP(Q_max(indexCount, vk_fanBuffersize), 4); + + bufferSize = 3 * indexCount * sizeof(uint16_t); + data = malloc(bufferSize); + + GenFanIndexes(data, 0, indexCount); + buffer = UpdateIndexBuffer(data, bufferSize, dstOffset); + + free(data); + + /* save to cache */ + vk_fanOffset = *dstOffset; + vk_fanBuffersize = indexCount; + vk_fanBuffercache = buffer; + + return *buffer; } VkBuffer -QVk_GetTriangleFanIbo(VkDeviceSize indexCount) +QVk_GetTriangleStripIbo(VkDeviceSize indexCount, VkDeviceSize *dstOffset) { - QVk_CheckTriangleIbo(indexCount); + VkDeviceSize bufferSize = 3 * indexCount * sizeof(uint16_t); + uint16_t *data = malloc(bufferSize); + VkBuffer *buffer; - return *vk_triangleFanIbo; -} + GenStripIndexes(data, 0, indexCount); + buffer = UpdateIndexBuffer(data, bufferSize, dstOffset); -VkBuffer -QVk_GetTriangleStripIbo(VkDeviceSize indexCount) -{ - QVk_CheckTriangleIbo(indexCount); + free(data); - return *vk_triangleStripIbo; + return *buffer; } void QVk_SubmitStagingBuffers() diff --git a/src/client/refresh/vk/vk_light.c b/src/client/refresh/vk/vk_light.c index 127e402f..e8b3d176 100644 --- a/src/client/refresh/vk/vk_light.c +++ b/src/client/refresh/vk/vk_light.c @@ -33,13 +33,14 @@ vec3_t lightspot; static void R_RenderDlight(dlight_t *light) { - VkDescriptorSet uboDescriptorSet; - uint8_t *vertData, *uboData; - VkDeviceSize vboOffset; - uint32_t uboOffset; - VkBuffer vbo; - int i, j; - float rad; + VkDescriptorSet uboDescriptorSet; + uint32_t uboOffset, fanOffset; + uint8_t *vertData, *uboData; + VkDeviceSize vboOffset; + VkBuffer vbo; + VkBuffer fan; + float rad; + int i, j; rad = light->intensity * 0.35; @@ -77,9 +78,10 @@ R_RenderDlight(dlight_t *light) memcpy(vertData, lightVerts, sizeof(lightVerts)); memcpy(uboData, r_viewproj_matrix, sizeof(r_viewproj_matrix)); + fan = QVk_GetTriangleFanIbo(48, &fanOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawDLightPipeline.layout, 0, 1, &uboDescriptorSet, 1, &uboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo(48), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, 48, 1, 0, 0, 0); } diff --git a/src/client/refresh/vk/vk_main.c b/src/client/refresh/vk/vk_main.c index ce35c45d..40f3074f 100644 --- a/src/client/refresh/vk/vk_main.c +++ b/src/client/refresh/vk/vk_main.c @@ -291,8 +291,8 @@ R_DrawNullModel(entity_t *currententity) verts[i][2] = shadelight[2]; } - VkBuffer vbo; - VkDeviceSize vboOffset; + VkBuffer vbo, fan; + VkDeviceSize vboOffset, fanOffset; uint32_t uboOffset; VkDescriptorSet uboDescriptorSet; uint8_t *vertData = QVk_GetVertexBuffer(sizeof(verts), &vbo, &vboOffset); @@ -300,10 +300,11 @@ R_DrawNullModel(entity_t *currententity) memcpy(vertData, verts, sizeof(verts)); memcpy(uboData, model, sizeof(model)); + fan = QVk_GetTriangleFanIbo(12, &fanOffset); QVk_BindPipeline(&vk_drawNullModelPipeline); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawNullModelPipeline.layout, 0, 1, &uboDescriptorSet, 1, &uboOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo(12), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, 12, 1, 0, 0, 0); vkCmdDrawIndexed(vk_activeCmdbuffer, 12, 1, 0, 6, 0); } diff --git a/src/client/refresh/vk/vk_mesh.c b/src/client/refresh/vk/vk_mesh.c index 850adfd4..68e46057 100644 --- a/src/client/refresh/vk/vk_mesh.c +++ b/src/client/refresh/vk/vk_mesh.c @@ -195,6 +195,7 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs { int vertCounts[2] = { 0, 0 }; int pipeCounters[2] = { 0, 0 }; + VkDeviceSize fanOffset, stripOffset; VkBuffer fan, strip; if (Mesh_VertsRealloc(verts_count)) @@ -202,8 +203,8 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs Com_Error(ERR_FATAL, "%s: can't allocate memory", __func__); } - fan = QVk_GetTriangleFanIbo(num_tris); - strip = QVk_GetTriangleStripIbo(num_tris); + fan = QVk_GetTriangleFanIbo(num_tris, &fanOffset); + strip = QVk_GetTriangleStripIbo(num_tris, &stripOffset); drawInfo[0][0].firstVertex = 0; drawInfo[1][0].firstVertex = 0; @@ -344,7 +345,7 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs { int i; - vkCmdBindIndexBuffer(vk_activeCmdbuffer, strip, 0 /* buffer offset */, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, strip, stripOffset, VK_INDEX_TYPE_UINT16); for (i = 0; i < pipeCounters[p]; i++) { @@ -355,7 +356,7 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs { int i; - vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, 0 /* buffer offset */, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); for (i = 0; i < pipeCounters[p]; i++) { @@ -468,10 +469,11 @@ Vk_DrawAliasShadow(int *order, int *order_end, int posenum, float height, float lheight, vec4_t *s_lerped, const float *shadevector, uint32_t *uboOffset, VkDescriptorSet *uboDescriptorSet, int num_tris) { + VkDeviceSize fanOffset, stripOffset; VkBuffer fan, strip; - fan = QVk_GetTriangleFanIbo(num_tris); - strip = QVk_GetTriangleStripIbo(num_tris); + fan = QVk_GetTriangleFanIbo(num_tris, &fanOffset); + strip = QVk_GetTriangleStripIbo(num_tris, &stripOffset); while (1) { @@ -540,12 +542,12 @@ Vk_DrawAliasShadow(int *order, int *order_end, int posenum, if (pipelineIdx == TRIANGLE_STRIP) { - vkCmdBindIndexBuffer(vk_activeCmdbuffer, strip, 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, strip, stripOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (i - 2) * 3, 1, 0, 0, 0); } else { - vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (i - 2) * 3, 1, 0, 0, 0); } } diff --git a/src/client/refresh/vk/vk_surf.c b/src/client/refresh/vk/vk_surf.c index 5a70f1a4..85a81bdf 100644 --- a/src/client/refresh/vk/vk_surf.c +++ b/src/client/refresh/vk/vk_surf.c @@ -41,8 +41,8 @@ DrawVkPoly(mpoly_t *p, image_t *texture, const float *color) { QVk_BindPipeline(&vk_drawPolyPipeline); - VkBuffer vbo; - VkDeviceSize vboOffset; + VkBuffer vbo, fan; + VkDeviceSize vboOffset, fanOffset; uint32_t uboOffset; VkDescriptorSet uboDescriptorSet; uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * p->numverts, &vbo, &vboOffset); @@ -60,9 +60,10 @@ DrawVkPoly(mpoly_t *p, image_t *texture, const float *color) vkCmdPushConstants(vk_activeCmdbuffer, vk_drawTexQuadPipeline[vk_state.current_renderpass].layout, VK_SHADER_STAGE_FRAGMENT_BIT, 17 * sizeof(float), sizeof(gamma), &gamma); + fan = QVk_GetTriangleFanIbo((p->numverts - 2) * 3, &fanOffset); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyPipeline.layout, 0, 2, descriptorSets, 1, &uboOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo((p->numverts - 2) * 3), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (p->numverts - 2) * 3, 1, 0, 0, 0); } @@ -98,8 +99,9 @@ DrawVkFlowingPoly(msurface_t *fa, image_t *texture, const float *color) QVk_BindPipeline(&vk_drawPolyPipeline); - VkBuffer vbo; - VkDeviceSize vboOffset; + + VkDeviceSize vboOffset, fanOffset; + VkBuffer vbo, fan; uint32_t uboOffset; VkDescriptorSet uboDescriptorSet; uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * p->numverts, &vbo, &vboOffset); @@ -117,9 +119,11 @@ DrawVkFlowingPoly(msurface_t *fa, image_t *texture, const float *color) vkCmdPushConstants(vk_activeCmdbuffer, vk_drawTexQuadPipeline[vk_state.current_renderpass].layout, VK_SHADER_STAGE_FRAGMENT_BIT, 17 * sizeof(float), sizeof(gamma), &gamma); + + fan = QVk_GetTriangleFanIbo((p->numverts - 2) * 3, &fanOffset); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyPipeline.layout, 0, 2, descriptorSets, 1, &uboOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo((p->numverts - 2) * 3), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (p->numverts - 2) * 3, 1, 0, 0, 0); } @@ -494,6 +498,9 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha for (p = surf->polys; p; p = p->chain) { + VkBuffer fan; + VkDeviceSize fanOffset; + memcpy(verts_buffer, p->verts, sizeof(mvtx_t) * nv); for (i = 0; i < nv; i++) @@ -505,29 +512,36 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); memcpy(vertData, verts_buffer, sizeof(mvtx_t) * nv); + fan = QVk_GetTriangleFanIbo((nv - 2) * 3, &fanOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo((nv - 2) * 3), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (nv - 2) * 3, 1, 0, 0, 0); } } else { - VkBuffer vbo; VkDeviceSize vboOffset; + VkBuffer vbo; VkDescriptorSet descriptorSets[] = { image->vk_texture.descriptorSet, uboDescriptorSet, vk_state.lightmap_textures[lmtex].descriptorSet }; + vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyLmapPipeline.layout, 0, 3, descriptorSets, 1, &uboOffset); for (p = surf->polys; p; p = p->chain) { - uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); + VkDeviceSize fanOffset; + uint8_t *vertData; + VkBuffer fan; + + vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); memcpy(vertData, p->verts, sizeof(mvtx_t) * nv); + fan = QVk_GetTriangleFanIbo((nv - 2) * 3, &fanOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo((nv - 2) * 3), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (nv - 2) * 3, 1, 0, 0, 0); } } @@ -548,6 +562,10 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha for (p = surf->polys; p; p = p->chain) { + VkDeviceSize vboOffset, fanOffset; + VkBuffer vbo, fan; + uint8_t *vertData; + memcpy(verts_buffer, p->verts, sizeof(mvtx_t) * nv); for (i = 0; i < nv; i++) @@ -556,9 +574,7 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha verts_buffer[i].texCoord[1] += tscroll; } - VkBuffer vbo; - VkDeviceSize vboOffset; - uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); + vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); memcpy(vertData, verts_buffer, sizeof(mvtx_t) * nv); VkDescriptorSet descriptorSets[] = { @@ -566,9 +582,11 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha uboDescriptorSet, vk_state.lightmap_textures[lmtex].descriptorSet }; + + fan = QVk_GetTriangleFanIbo((nv - 2) * 3, &fanOffset); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyLmapPipeline.layout, 0, 3, descriptorSets, 1, &uboOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo((nv - 2) * 3), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (nv - 2) * 3, 1, 0, 0, 0); } } @@ -578,9 +596,11 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha //========== for (p = surf->polys; p; p = p->chain) { - VkBuffer vbo; - VkDeviceSize vboOffset; - uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); + VkDeviceSize vboOffset, fanOffset; + VkBuffer vbo, fan; + uint8_t *vertData; + + vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); memcpy(vertData, p->verts, sizeof(mvtx_t) * nv); VkDescriptorSet descriptorSets[] = { @@ -588,9 +608,11 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha uboDescriptorSet, vk_state.lightmap_textures[lmtex].descriptorSet }; + + fan = QVk_GetTriangleFanIbo((nv - 2) * 3, &fanOffset); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyLmapPipeline.layout, 0, 3, descriptorSets, 1, &uboOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo((nv - 2) * 3), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (nv - 2) * 3, 1, 0, 0, 0); } //========== diff --git a/src/client/refresh/vk/vk_warp.c b/src/client/refresh/vk/vk_warp.c index 932760c2..1205b1e6 100644 --- a/src/client/refresh/vk/vk_warp.c +++ b/src/client/refresh/vk/vk_warp.c @@ -126,6 +126,9 @@ EmitWaterPolys(msurface_t *fa, image_t *texture, const float *modelMatrix, for (bp = fa->polys; bp; bp = bp->next) { + VkDeviceSize fanOffset; + VkBuffer fan; + p = bp; if (Mesh_VertsRealloc(p->numverts)) @@ -143,8 +146,9 @@ EmitWaterPolys(msurface_t *fa, image_t *texture, const float *modelMatrix, uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * p->numverts, &vbo, &vboOffset); memcpy(vertData, verts_buffer, sizeof(mvtx_t) * p->numverts); + fan = QVk_GetTriangleFanIbo((p->numverts - 2) * 3, &fanOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); - vkCmdBindIndexBuffer(vk_activeCmdbuffer, QVk_GetTriangleFanIbo((p->numverts - 2) * 3), 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(vk_activeCmdbuffer, fan, fanOffset, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_activeCmdbuffer, (p->numverts - 2) * 3, 1, 0, 0, 0); } }