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_usage;
uint32_t uniform_buffer_max_usage; uint32_t uniform_buffer_max_usage;
uint32_t uniform_buffer_size; uint32_t uniform_buffer_size;
uint32_t triangle_index_usage;
uint32_t triangle_index_max_usage;
uint32_t triangle_index_count;
} vkconfig_t; } vkconfig_t;
#define MAX_LIGHTMAPS 256 #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_GetVertexBuffer(VkDeviceSize size, VkBuffer *dstBuffer, VkDeviceSize *dstOffset);
uint8_t* QVk_GetUniformBuffer(VkDeviceSize size, uint32_t *dstOffset, VkDescriptorSet *dstUboDescriptorSet); 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); uint8_t* QVk_GetStagingBuffer(VkDeviceSize size, int alignment, VkCommandBuffer *cmdBuffer, VkBuffer *buffer, uint32_t *dstOffset);
VkBuffer QVk_GetTriangleFanIbo(VkDeviceSize indexCount); VkBuffer QVk_GetTriangleFanIbo(VkDeviceSize indexCount, VkDeviceSize *dstOffset);
VkBuffer QVk_GetTriangleStripIbo(VkDeviceSize indexCount); VkBuffer QVk_GetTriangleStripIbo(VkDeviceSize indexCount, VkDeviceSize *dstOffset);
void QVk_DrawColorRect(float *ubo, VkDeviceSize uboSize, qvkrenderpasstype_t rpType); void QVk_DrawColorRect(float *ubo, VkDeviceSize uboSize, qvkrenderpasstype_t rpType);
void QVk_DrawTexRect(const float *ubo, VkDeviceSize uboSize, qvktexture_t *texture); void QVk_DrawTexRect(const float *ubo, VkDeviceSize uboSize, qvktexture_t *texture);
void QVk_BindPipeline(qvkpipeline_t *pipeline); 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 qvkstagingbuffer_t vk_stagingBuffers[NUM_DYNBUFFERS];
static int vk_activeDynBufferIdx = 0; static int vk_activeDynBufferIdx = 0;
static int vk_activeSwapBufferIdx = 0; static int vk_activeSwapBufferIdx = 0;
static int vk_dynIndex = 0;
// index buffer for triangle fan/strip emulation - all because Metal/MoltenVK don't support them /* cache tri between calls */
static VkBuffer *vk_triangleFanIbo = NULL; static VkBuffer *vk_fanBuffercache = NULL;
static VkBuffer *vk_triangleStripIbo = NULL; static VkDeviceSize vk_fanOffset = 0;
static uint32_t vk_triangleFanIboUsage = 0; static int vk_fanBuffersize = 0;
// swap buffers used if primary dynamic buffers get full // swap buffers used if primary dynamic buffers get full
#define NUM_SWAPBUFFER_SLOTS 4 #define NUM_SWAPBUFFER_SLOTS 4
@ -258,8 +258,6 @@ static VkDescriptorSet *vk_swapDescriptorSets[NUM_SWAPBUFFER_SLOTS];
#define UNIFORM_BUFFER_SIZE (2048 * 1024) #define UNIFORM_BUFFER_SIZE (2048 * 1024)
// staging buffer is constant in size but has a max limit beyond which it will be submitted // staging buffer is constant in size but has a max limit beyond which it will be submitted
#define STAGING_BUFFER_MAXSIZE (8192 * 1024) #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 // Vulkan common descriptor sets for UBO, primary texture sampler and optional lightmap texture
static VkDescriptorSetLayout vk_uboDescSetLayout; static VkDescriptorSetLayout vk_uboDescSetLayout;
@ -1123,33 +1121,19 @@ GenStripIndexes(uint16_t *data, int from, int to)
} }
} }
static void static VkBuffer*
UpdateIndexBuffer(int index, uint16_t *data, VkDeviceSize bufferSize, VkDeviceSize *dstOffset) UpdateIndexBuffer(uint16_t *data, VkDeviceSize bufferSize, VkDeviceSize *dstOffset)
{ {
uint16_t *iboData = NULL; uint16_t *iboData = NULL;
VK_VERIFY(buffer_invalidate(&vk_dynIndexBuffers[index].resource)); vk_dynIndex = (vk_dynIndex + 1) % NUM_DYNBUFFERS;
iboData = (uint16_t *)QVk_GetIndexBuffer(bufferSize, dstOffset, index);
VK_VERIFY(buffer_invalidate(&vk_dynIndexBuffers[vk_dynIndex].resource));
iboData = (uint16_t *)QVk_GetIndexBuffer(bufferSize, dstOffset, vk_dynIndex);
memcpy(iboData, data, bufferSize); memcpy(iboData, data, bufferSize);
VK_VERIFY(buffer_flush(&vk_dynIndexBuffers[index].resource)); VK_VERIFY(buffer_flush(&vk_dynIndexBuffers[vk_dynIndex].resource));
}
static void return &vk_dynIndexBuffers[vk_dynIndex].resource.buffer;
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);
} }
static void CreateStagingBuffer(VkDeviceSize size, qvkstagingbuffer_t *dstBuffer, int i) 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_usage = 0;
vk_config.uniform_buffer_max_usage = 0; vk_config.uniform_buffer_max_usage = 0;
vk_config.uniform_buffer_size = UNIFORM_BUFFER_SIZE; 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 #ifdef USE_SDL3
if (!SDL_Vulkan_GetInstanceExtensions(&extCount)) if (!SDL_Vulkan_GetInstanceExtensions(&extCount))
@ -2157,9 +2138,10 @@ qboolean QVk_Init(void)
CreateDynamicBuffers(); CreateDynamicBuffers();
// create staging buffers // create staging buffers
CreateStagingBuffers(); CreateStagingBuffers();
// assign a dynamic index buffer for triangle fan emulation /* reset fan buffer */
RebuildTriangleIndexBuffer(); vk_fanOffset = 0;
vk_triangleFanIboUsage = ROUNDUP(3 * vk_config.triangle_index_count * sizeof(uint16_t), 4); vk_fanBuffersize = 512;
vk_fanBuffercache = NULL;
CreatePipelines(); CreatePipelines();
CreateSamplers(); CreateSamplers();
@ -2194,10 +2176,11 @@ VkResult QVk_BeginFrame(const VkViewport* viewport, const VkRect2D* scissor)
vk_state.current_pipeline = VK_NULL_HANDLE; vk_state.current_pipeline = VK_NULL_HANDLE;
vk_state.current_renderpass = RP_COUNT; vk_state.current_renderpass = RP_COUNT;
vk_config.vertex_buffer_usage = 0; 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 = 0;
vk_config.index_buffer_usage = vk_triangleFanIboUsage;
vk_config.uniform_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(); ReleaseSwapBuffers();
@ -2221,8 +2204,7 @@ VkResult QVk_BeginFrame(const VkViewport* viewport, const VkRect2D* scissor)
vk_activeDynBufferIdx = (vk_activeDynBufferIdx + 1) % NUM_DYNBUFFERS; vk_activeDynBufferIdx = (vk_activeDynBufferIdx + 1) % NUM_DYNBUFFERS;
vk_dynUniformBuffers[vk_activeDynBufferIdx].currentOffset = 0; vk_dynUniformBuffers[vk_activeDynBufferIdx].currentOffset = 0;
vk_dynVertexBuffers[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 = 0;
vk_dynIndexBuffers[vk_activeDynBufferIdx].currentOffset = vk_triangleFanIboUsage;
VK_VERIFY(buffer_invalidate(&vk_dynUniformBuffers[vk_activeDynBufferIdx].resource)); VK_VERIFY(buffer_invalidate(&vk_dynUniformBuffers[vk_activeDynBufferIdx].resource));
VK_VERIFY(buffer_invalidate(&vk_dynVertexBuffers[vk_activeDynBufferIdx].resource)); VK_VERIFY(buffer_invalidate(&vk_dynVertexBuffers[vk_activeDynBufferIdx].resource));
VK_VERIFY(buffer_invalidate(&vk_dynIndexBuffers[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; return data;
} }
static void VkBuffer
QVk_CheckTriangleIbo(VkDeviceSize indexCount) QVk_GetTriangleFanIbo(VkDeviceSize indexCount, VkDeviceSize *dstOffset)
{ {
if (indexCount > vk_config.triangle_index_usage) VkDeviceSize bufferSize;
vk_config.triangle_index_usage = indexCount; VkBuffer *buffer;
uint16_t *data;
if (vk_config.triangle_index_usage > vk_config.triangle_index_max_usage) if (vk_fanBuffercache && (vk_fanBuffersize > indexCount))
vk_config.triangle_index_max_usage = vk_config.triangle_index_usage;
if (indexCount > vk_config.triangle_index_count)
{ {
vk_config.triangle_index_count *= BUFFER_RESIZE_FACTOR; *dstOffset = vk_fanOffset;
R_Printf(PRINT_ALL, "%s: Resizing triangle index buffer to %u indices.\n", return *vk_fanBuffercache;
__func__, vk_config.triangle_index_count);
RebuildTriangleIndexBuffer();
vk_triangleFanIboUsage = ROUNDUP(3 * vk_config.triangle_index_count * sizeof(uint16_t), 4);
} }
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 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 free(data);
QVk_GetTriangleStripIbo(VkDeviceSize indexCount)
{
QVk_CheckTriangleIbo(indexCount);
return *vk_triangleStripIbo; return *buffer;
} }
void QVk_SubmitStagingBuffers() void QVk_SubmitStagingBuffers()

View File

@ -34,12 +34,13 @@ static void
R_RenderDlight(dlight_t *light) R_RenderDlight(dlight_t *light)
{ {
VkDescriptorSet uboDescriptorSet; VkDescriptorSet uboDescriptorSet;
uint32_t uboOffset, fanOffset;
uint8_t *vertData, *uboData; uint8_t *vertData, *uboData;
VkDeviceSize vboOffset; VkDeviceSize vboOffset;
uint32_t uboOffset;
VkBuffer vbo; VkBuffer vbo;
int i, j; VkBuffer fan;
float rad; float rad;
int i, j;
rad = light->intensity * 0.35; rad = light->intensity * 0.35;
@ -77,9 +78,10 @@ R_RenderDlight(dlight_t *light)
memcpy(vertData, lightVerts, sizeof(lightVerts)); memcpy(vertData, lightVerts, sizeof(lightVerts));
memcpy(uboData, r_viewproj_matrix, sizeof(r_viewproj_matrix)); memcpy(uboData, r_viewproj_matrix, sizeof(r_viewproj_matrix));
fan = QVk_GetTriangleFanIbo(48, &fanOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset);
vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawDLightPipeline.layout, 0, 1, &uboDescriptorSet, 1, &uboOffset); 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); vkCmdDrawIndexed(vk_activeCmdbuffer, 48, 1, 0, 0, 0);
} }

View File

@ -291,8 +291,8 @@ R_DrawNullModel(entity_t *currententity)
verts[i][2] = shadelight[2]; verts[i][2] = shadelight[2];
} }
VkBuffer vbo; VkBuffer vbo, fan;
VkDeviceSize vboOffset; VkDeviceSize vboOffset, fanOffset;
uint32_t uboOffset; uint32_t uboOffset;
VkDescriptorSet uboDescriptorSet; VkDescriptorSet uboDescriptorSet;
uint8_t *vertData = QVk_GetVertexBuffer(sizeof(verts), &vbo, &vboOffset); uint8_t *vertData = QVk_GetVertexBuffer(sizeof(verts), &vbo, &vboOffset);
@ -300,10 +300,11 @@ R_DrawNullModel(entity_t *currententity)
memcpy(vertData, verts, sizeof(verts)); memcpy(vertData, verts, sizeof(verts));
memcpy(uboData, model, sizeof(model)); memcpy(uboData, model, sizeof(model));
fan = QVk_GetTriangleFanIbo(12, &fanOffset);
QVk_BindPipeline(&vk_drawNullModelPipeline); QVk_BindPipeline(&vk_drawNullModelPipeline);
vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawNullModelPipeline.layout, 0, 1, &uboDescriptorSet, 1, &uboOffset); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawNullModelPipeline.layout, 0, 1, &uboDescriptorSet, 1, &uboOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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, 0, 0);
vkCmdDrawIndexed(vk_activeCmdbuffer, 12, 1, 0, 6, 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 vertCounts[2] = { 0, 0 };
int pipeCounters[2] = { 0, 0 }; int pipeCounters[2] = { 0, 0 };
VkDeviceSize fanOffset, stripOffset;
VkBuffer fan, strip; VkBuffer fan, strip;
if (Mesh_VertsRealloc(verts_count)) 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__); Com_Error(ERR_FATAL, "%s: can't allocate memory", __func__);
} }
fan = QVk_GetTriangleFanIbo(num_tris); fan = QVk_GetTriangleFanIbo(num_tris, &fanOffset);
strip = QVk_GetTriangleStripIbo(num_tris); strip = QVk_GetTriangleStripIbo(num_tris, &stripOffset);
drawInfo[0][0].firstVertex = 0; drawInfo[0][0].firstVertex = 0;
drawInfo[1][0].firstVertex = 0; drawInfo[1][0].firstVertex = 0;
@ -344,7 +345,7 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs
{ {
int i; 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++) for (i = 0; i < pipeCounters[p]; i++)
{ {
@ -355,7 +356,7 @@ Vk_DrawAliasFrameLerpCommands(VkDescriptorSet *descriptorSets, uint32_t *uboOffs
{ {
int i; 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++) 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, float height, float lheight, vec4_t *s_lerped, const float *shadevector,
uint32_t *uboOffset, VkDescriptorSet *uboDescriptorSet, int num_tris) uint32_t *uboOffset, VkDescriptorSet *uboDescriptorSet, int num_tris)
{ {
VkDeviceSize fanOffset, stripOffset;
VkBuffer fan, strip; VkBuffer fan, strip;
fan = QVk_GetTriangleFanIbo(num_tris); fan = QVk_GetTriangleFanIbo(num_tris, &fanOffset);
strip = QVk_GetTriangleStripIbo(num_tris); strip = QVk_GetTriangleStripIbo(num_tris, &stripOffset);
while (1) while (1)
{ {
@ -540,12 +542,12 @@ Vk_DrawAliasShadow(int *order, int *order_end, int posenum,
if (pipelineIdx == TRIANGLE_STRIP) 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); vkCmdDrawIndexed(vk_activeCmdbuffer, (i - 2) * 3, 1, 0, 0, 0);
} }
else 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); 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); QVk_BindPipeline(&vk_drawPolyPipeline);
VkBuffer vbo; VkBuffer vbo, fan;
VkDeviceSize vboOffset; VkDeviceSize vboOffset, fanOffset;
uint32_t uboOffset; uint32_t uboOffset;
VkDescriptorSet uboDescriptorSet; VkDescriptorSet uboDescriptorSet;
uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * p->numverts, &vbo, &vboOffset); 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, vkCmdPushConstants(vk_activeCmdbuffer, vk_drawTexQuadPipeline[vk_state.current_renderpass].layout,
VK_SHADER_STAGE_FRAGMENT_BIT, 17 * sizeof(float), sizeof(gamma), &gamma); 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); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyPipeline.layout, 0, 2, descriptorSets, 1, &uboOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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); 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); QVk_BindPipeline(&vk_drawPolyPipeline);
VkBuffer vbo;
VkDeviceSize vboOffset; VkDeviceSize vboOffset, fanOffset;
VkBuffer vbo, fan;
uint32_t uboOffset; uint32_t uboOffset;
VkDescriptorSet uboDescriptorSet; VkDescriptorSet uboDescriptorSet;
uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * p->numverts, &vbo, &vboOffset); 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, vkCmdPushConstants(vk_activeCmdbuffer, vk_drawTexQuadPipeline[vk_state.current_renderpass].layout,
VK_SHADER_STAGE_FRAGMENT_BIT, 17 * sizeof(float), sizeof(gamma), &gamma); 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); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyPipeline.layout, 0, 2, descriptorSets, 1, &uboOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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); 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) for (p = surf->polys; p; p = p->chain)
{ {
VkBuffer fan;
VkDeviceSize fanOffset;
memcpy(verts_buffer, p->verts, sizeof(mvtx_t) * nv); memcpy(verts_buffer, p->verts, sizeof(mvtx_t) * nv);
for (i = 0; i < nv; i++) 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); uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset);
memcpy(vertData, verts_buffer, sizeof(mvtx_t) * nv); memcpy(vertData, verts_buffer, sizeof(mvtx_t) * nv);
fan = QVk_GetTriangleFanIbo((nv - 2) * 3, &fanOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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); vkCmdDrawIndexed(vk_activeCmdbuffer, (nv - 2) * 3, 1, 0, 0, 0);
} }
} }
else else
{ {
VkBuffer vbo;
VkDeviceSize vboOffset; VkDeviceSize vboOffset;
VkBuffer vbo;
VkDescriptorSet descriptorSets[] = { VkDescriptorSet descriptorSets[] = {
image->vk_texture.descriptorSet, image->vk_texture.descriptorSet,
uboDescriptorSet, uboDescriptorSet,
vk_state.lightmap_textures[lmtex].descriptorSet vk_state.lightmap_textures[lmtex].descriptorSet
}; };
vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyLmapPipeline.layout, 0, 3, descriptorSets, 1, &uboOffset); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyLmapPipeline.layout, 0, 3, descriptorSets, 1, &uboOffset);
for (p = surf->polys; p; p = p->chain) 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); memcpy(vertData, p->verts, sizeof(mvtx_t) * nv);
fan = QVk_GetTriangleFanIbo((nv - 2) * 3, &fanOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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); 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) 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); memcpy(verts_buffer, p->verts, sizeof(mvtx_t) * nv);
for (i = 0; i < nv; i++) 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; verts_buffer[i].texCoord[1] += tscroll;
} }
VkBuffer vbo; vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset);
VkDeviceSize vboOffset;
uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset);
memcpy(vertData, verts_buffer, sizeof(mvtx_t) * nv); memcpy(vertData, verts_buffer, sizeof(mvtx_t) * nv);
VkDescriptorSet descriptorSets[] = { VkDescriptorSet descriptorSets[] = {
@ -566,9 +582,11 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha
uboDescriptorSet, uboDescriptorSet,
vk_state.lightmap_textures[lmtex].descriptorSet 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); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyLmapPipeline.layout, 0, 3, descriptorSets, 1, &uboOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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); 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) for (p = surf->polys; p; p = p->chain)
{ {
VkBuffer vbo; VkDeviceSize vboOffset, fanOffset;
VkDeviceSize vboOffset; VkBuffer vbo, fan;
uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset); uint8_t *vertData;
vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * nv, &vbo, &vboOffset);
memcpy(vertData, p->verts, sizeof(mvtx_t) * nv); memcpy(vertData, p->verts, sizeof(mvtx_t) * nv);
VkDescriptorSet descriptorSets[] = { VkDescriptorSet descriptorSets[] = {
@ -588,9 +608,11 @@ Vk_RenderLightmappedPoly(msurface_t *surf, const float *modelMatrix, float alpha
uboDescriptorSet, uboDescriptorSet,
vk_state.lightmap_textures[lmtex].descriptorSet 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); vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawPolyLmapPipeline.layout, 0, 3, descriptorSets, 1, &uboOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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); 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) for (bp = fa->polys; bp; bp = bp->next)
{ {
VkDeviceSize fanOffset;
VkBuffer fan;
p = bp; p = bp;
if (Mesh_VertsRealloc(p->numverts)) 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); uint8_t *vertData = QVk_GetVertexBuffer(sizeof(mvtx_t) * p->numverts, &vbo, &vboOffset);
memcpy(vertData, verts_buffer, sizeof(mvtx_t) * p->numverts); memcpy(vertData, verts_buffer, sizeof(mvtx_t) * p->numverts);
fan = QVk_GetTriangleFanIbo((p->numverts - 2) * 3, &fanOffset);
vkCmdBindVertexBuffers(vk_activeCmdbuffer, 0, 1, &vbo, &vboOffset); 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); vkCmdDrawIndexed(vk_activeCmdbuffer, (p->numverts - 2) * 3, 1, 0, 0, 0);
} }
} }