vk: rework fan index buffer cache

This commit is contained in:
Denis Pauk 2024-08-03 13:48:56 +03:00
parent d9a240a935
commit cd16e9884d
8 changed files with 126 additions and 106 deletions

View file

@ -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

View file

@ -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);

View file

@ -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()

View file

@ -34,12 +34,13 @@ static void
R_RenderDlight(dlight_t *light)
{
VkDescriptorSet uboDescriptorSet;
uint32_t uboOffset, fanOffset;
uint8_t *vertData, *uboData;
VkDeviceSize vboOffset;
uint32_t uboOffset;
VkBuffer vbo;
int i, j;
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);
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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);
}
//==========

View file

@ -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);
}
}