mojoshader_vulkan.c
changeset 1276 89c389e4112f
parent 1275 7fc13cff18ff
child 1277 da61410edbc9
--- a/mojoshader_vulkan.c	Mon Jul 06 12:51:28 2020 -0400
+++ b/mojoshader_vulkan.c	Mon Jul 06 16:23:06 2020 -0400
@@ -20,8 +20,7 @@
 	typedef ret (VKAPI_CALL *vkfntype_MOJOSHADER_##func) params;
 #include "mojoshader_vulkan_vkfuncs.h"
 
-#define UBO_BUFFER_COUNT 8
-#define UBO_BUFFER_SIZE 1048576 /* ~1MB */
+#define UBO_BUFFER_SIZE 8000000 // 8MB
 
 // Internal struct defs...
 
@@ -35,11 +34,11 @@
 typedef struct MOJOSHADER_vkUniformBuffer
 {
     VkBuffer buffer;
+    VkDeviceMemory deviceMemory;
     VkDeviceSize bufferSize;
-    VkDeviceSize memoryOffset;
     VkDeviceSize dynamicOffset;
     VkDeviceSize currentBlockSize;
-    int32_t full; // Records frame on which it became full, -1 if not full
+    uint8_t *mapPointer;
 } MOJOSHADER_vkUniformBuffer;
 
 // Error state...
@@ -55,7 +54,7 @@
     set_error("out of memory");
 } // out_of_memory
 
-/* Max entries for each register file type */
+// Max entries for each register file type
 #define MAX_REG_FILE_F 8192
 #define MAX_REG_FILE_I 2047
 #define MAX_REG_FILE_B 2047
@@ -87,21 +86,12 @@
     int32_t ps_reg_file_i[MAX_REG_FILE_I * 4];
     uint8_t ps_reg_file_b[MAX_REG_FILE_B * 4];
 
-    VkDeviceMemory vertUboMemory;
-    MOJOSHADER_vkUniformBuffer **vertUboBuffers;
-    uint32_t vertUboCurrentIndex;
-
-    VkDeviceMemory fragUboMemory;
-    MOJOSHADER_vkUniformBuffer **fragUboBuffers;
-    uint32_t fragUboCurrentIndex;
-
-    uint32_t uboBufferCount;
+    MOJOSHADER_vkUniformBuffer *vertUboBuffer;
+    MOJOSHADER_vkUniformBuffer *fragUboBuffer;
 
     MOJOSHADER_vkShader *vertexShader;
     MOJOSHADER_vkShader *pixelShader;
 
-    uint32_t currentFrame;
-
     #define VULKAN_INSTANCE_FUNCTION(ret, func, params) \
         vkfntype_MOJOSHADER_##func func;
     #define VULKAN_DEVICE_FUNCTION(ret, func, params) \
@@ -143,18 +133,21 @@
     );
 } // next_highest_offset_alignment
 
-static MOJOSHADER_vkUniformBuffer *create_ubo(MOJOSHADER_vkContext *ctx,
-                                              MOJOSHADER_malloc m,
-                                              void *d
-) {
-    MOJOSHADER_vkUniformBuffer *result = (MOJOSHADER_vkUniformBuffer *) m(
+static MOJOSHADER_vkUniformBuffer *create_ubo(MOJOSHADER_vkContext *ctx)
+{
+    MOJOSHADER_vkUniformBuffer *result = (MOJOSHADER_vkUniformBuffer *) ctx->malloc_fn(
         sizeof(MOJOSHADER_vkUniformBuffer),
-        d
+        ctx->malloc_data
     );
     VkBufferCreateInfo bufferCreateInfo =
     {
         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
     };
+    VkMemoryRequirements memoryRequirements;
+    VkMemoryAllocateInfo allocateInfo =
+    {
+        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
+    };
 
     bufferCreateInfo.flags = 0;
     bufferCreateInfo.size = UBO_BUFFER_SIZE;
@@ -170,10 +163,46 @@
         &result->buffer
     );
 
+    ctx->vkGetBufferMemoryRequirements(
+        *ctx->logical_device,
+        result->buffer,
+        &memoryRequirements
+    );
+
+    allocateInfo.allocationSize = UBO_BUFFER_SIZE;
+
+    if (!find_memory_type(ctx,
+                          memoryRequirements.memoryTypeBits,
+                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+                          &allocateInfo.memoryTypeIndex))
+    {
+        set_error("failed to find suitable memory type for UBO memory");
+        return NULL;
+    } // if
+
+    ctx->vkAllocateMemory(*ctx->logical_device,
+                          &allocateInfo,
+                          NULL,
+                          &result->deviceMemory
+    );
+
+    ctx->vkBindBufferMemory(*ctx->logical_device,
+                            result->buffer,
+                            result->deviceMemory,
+                            0
+    );
+
+    ctx->vkMapMemory(*ctx->logical_device,
+                     result->deviceMemory,
+                     0,
+                     UBO_BUFFER_SIZE,
+                     0,
+                     (void**) &result->mapPointer
+    );
+
     result->bufferSize = UBO_BUFFER_SIZE;
     result->currentBlockSize = 0;
     result->dynamicOffset = 0;
-    result->full = -1;
 
     return result;
 } // create_ubo
@@ -198,9 +227,9 @@
         return VK_NULL_HANDLE;
 
     if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
-        return ctx->vertUboBuffers[ctx->vertUboCurrentIndex]->buffer;
+        return ctx->vertUboBuffer->buffer;
     else
-        return ctx->fragUboBuffers[ctx->fragUboCurrentIndex]->buffer;
+        return ctx->fragUboBuffer->buffer;
 } // get_uniform_buffer
 
 static VkDeviceSize get_uniform_offset(MOJOSHADER_vkShader *shader)
@@ -209,9 +238,9 @@
         return 0;
 
     if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
-        return ctx->vertUboBuffers[ctx->vertUboCurrentIndex]->dynamicOffset;
+        return ctx->vertUboBuffer->dynamicOffset;
     else
-        return ctx->fragUboBuffers[ctx->fragUboCurrentIndex]->dynamicOffset;
+        return ctx->fragUboBuffer->dynamicOffset;
 } // get_uniform_offset
 
 static VkDeviceSize get_uniform_size(MOJOSHADER_vkShader *shader)
@@ -220,21 +249,19 @@
         return 0;
 
     if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
-        return ctx->vertUboBuffers[ctx->vertUboCurrentIndex]->currentBlockSize;
+        return ctx->vertUboBuffer->currentBlockSize;
     else
-        return ctx->fragUboBuffers[ctx->fragUboCurrentIndex]->currentBlockSize;
+        return ctx->fragUboBuffer->currentBlockSize;
 } // get_uniform_size
 
 static void update_uniform_buffer(MOJOSHADER_vkShader *shader)
 {
     int32_t i, j;
-    void *map;
     int32_t offset;
     uint8_t *contents;
     uint32_t *contentsI;
     float *regF; int *regI; uint8_t *regB;
     MOJOSHADER_vkUniformBuffer *ubo;
-    VkDeviceMemory uboMemory;
 
     if (shader == NULL || shader->parseData->uniform_count == 0)
         return;
@@ -245,8 +272,7 @@
         regI = ctx->vs_reg_file_i;
         regB = ctx->vs_reg_file_b;
 
-        ubo = ctx->vertUboBuffers[ctx->vertUboCurrentIndex];
-        uboMemory = ctx->vertUboMemory;
+        ubo = ctx->vertUboBuffer;
     } // if
     else
     {
@@ -254,59 +280,19 @@
         regI = ctx->ps_reg_file_i;
         regB = ctx->ps_reg_file_b;
 
-        ubo = ctx->fragUboBuffers[ctx->fragUboCurrentIndex];
-        uboMemory = ctx->fragUboMemory;
+        ubo = ctx->fragUboBuffer;
     } // else
 
     ubo->dynamicOffset += ubo->currentBlockSize;
 
     ubo->currentBlockSize = next_highest_offset_alignment(uniform_data_size(shader));
 
-    // Rotate buffer if it would overrun
     if (ubo->dynamicOffset + ubo->currentBlockSize >= ubo->bufferSize)
     {
-        ubo->full = ctx->currentFrame;
-
-        if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
-        {
-            for (i = 0; i < ctx->uboBufferCount; i++)
-            {
-                ctx->vertUboCurrentIndex = (ctx->vertUboCurrentIndex + 1) % ctx->uboBufferCount;
-                if (ctx->vertUboBuffers[ctx->vertUboCurrentIndex]->full == -1)
-                    break;
-            } // for
-
-            ubo = ctx->vertUboBuffers[ctx->vertUboCurrentIndex];
-        }
-        else
-        {
-            for (int i = 0; i < ctx->uboBufferCount; i++)
-            {
-                ctx->fragUboCurrentIndex = (ctx->fragUboCurrentIndex + 1) % ctx->uboBufferCount;
-                if (ctx->fragUboBuffers[ctx->fragUboCurrentIndex]->full == -1)
-                    break;
-            } // for
-
-            ubo = ctx->fragUboBuffers[ctx->fragUboCurrentIndex];
-        } // else
-
-        ubo->dynamicOffset = 0;
-        ubo->currentBlockSize = next_highest_offset_alignment(uniform_data_size(shader));
-
-        if (ubo->full >= 0)
-            set_error("all UBO buffers are full");
+        set_error("UBO overflow!!");
     } // if
 
-    ctx->vkMapMemory(
-        *ctx->logical_device,
-        uboMemory,
-        ubo->memoryOffset,
-        ubo->bufferSize,
-        0,
-        &map
-    );
-
-    contents = ((uint8_t *) map) + ubo->dynamicOffset;
+    contents = ubo->mapPointer + ubo->dynamicOffset;
 
     offset = 0;
     for (i = 0; i < shader->parseData->uniform_count; i++)
@@ -350,10 +336,6 @@
         offset += size * 16;
     } // for
 
-    ctx->vkUnmapMemory(
-        *ctx->logical_device,
-        uboMemory
-    );
 } // update_uniform_buffer
 
 static void lookup_entry_points(MOJOSHADER_vkContext *ctx)
@@ -395,13 +377,6 @@
     MOJOSHADER_malloc m, MOJOSHADER_free f,
     void *malloc_d
 ) {
-    int32_t i;
-    int32_t uboMemoryOffset;
-    VkMemoryAllocateInfo allocate_info =
-    {
-        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
-    };
-    VkMemoryRequirements memoryRequirements;
     MOJOSHADER_vkContext* resultCtx;
 
     if (m == NULL) m = MOJOSHADER_internal_malloc;
@@ -412,7 +387,7 @@
     {
         out_of_memory();
         goto init_fail;
-    }
+    } // if
 
     memset(resultCtx, '\0', sizeof(MOJOSHADER_vkContext));
     resultCtx->malloc_fn = m;
@@ -428,111 +403,11 @@
     resultCtx->graphics_queue_family_index = graphics_queue_family_index;
     resultCtx->maxUniformBufferRange = max_uniform_buffer_range;
     resultCtx->minUniformBufferOffsetAlignment = min_uniform_buffer_offset_alignment;
-    resultCtx->currentFrame = 0;
 
     lookup_entry_points(resultCtx);
 
-    resultCtx->uboBufferCount = UBO_BUFFER_COUNT;
-
-    // Allocate vert UBO
-
-    resultCtx->vertUboCurrentIndex = 0;
-    resultCtx->vertUboBuffers = (MOJOSHADER_vkUniformBuffer**) m(
-        sizeof(MOJOSHADER_vkUniformBuffer*) * resultCtx->uboBufferCount,
-        malloc_d
-    );
-
-    for (i = 0; i < resultCtx->uboBufferCount; i++)
-        resultCtx->vertUboBuffers[i] = create_ubo(resultCtx, m, malloc_d);
-
-    resultCtx->vkGetBufferMemoryRequirements(
-        *resultCtx->logical_device,
-        resultCtx->vertUboBuffers[0]->buffer,
-        &memoryRequirements
-    );
-
-    allocate_info.allocationSize = UBO_BUFFER_SIZE * resultCtx->uboBufferCount;
-
-    if (!find_memory_type(resultCtx,
-                          memoryRequirements.memoryTypeBits,
-                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-                          &allocate_info.memoryTypeIndex))
-    {
-        set_error("failed to find suitable memory type for UBO memory");
-        return NULL;
-    } // if
-
-    resultCtx->vkAllocateMemory(
-        *resultCtx->logical_device,
-        &allocate_info,
-        NULL,
-        &resultCtx->vertUboMemory
-    );
-
-    uboMemoryOffset = 0;
-    for (i = 0; i < resultCtx->uboBufferCount; i++)
-    {
-        resultCtx->vertUboBuffers[i]->memoryOffset = uboMemoryOffset;
-
-        resultCtx->vkBindBufferMemory(
-            *resultCtx->logical_device,
-            resultCtx->vertUboBuffers[i]->buffer,
-            resultCtx->vertUboMemory,
-            uboMemoryOffset
-        );
-
-        uboMemoryOffset += UBO_BUFFER_SIZE;
-    } // for
-
-    // Allocate frag UBO
-
-    resultCtx->fragUboCurrentIndex = 0;
-    resultCtx->fragUboBuffers = (MOJOSHADER_vkUniformBuffer**) m(
-        sizeof(MOJOSHADER_vkUniformBuffer*) * resultCtx->uboBufferCount,
-        malloc_d
-    );
-
-    for (i = 0; i < resultCtx->uboBufferCount; i++)
-        resultCtx->fragUboBuffers[i] = create_ubo(resultCtx, m, malloc_d);
-
-    resultCtx->vkGetBufferMemoryRequirements(
-        *resultCtx->logical_device,
-        resultCtx->fragUboBuffers[0]->buffer,
-        &memoryRequirements
-    );
-
-    allocate_info.allocationSize = UBO_BUFFER_SIZE * resultCtx->uboBufferCount;
-
-    if (!find_memory_type(resultCtx,
-                          memoryRequirements.memoryTypeBits,
-                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-                          &allocate_info.memoryTypeIndex))
-    {
-        set_error("failed to find suitable memory type for UBO memory");
-        return NULL;
-    } // if
-
-    resultCtx->vkAllocateMemory(
-        *resultCtx->logical_device,
-        &allocate_info,
-        NULL,
-        &resultCtx->fragUboMemory
-    );
-
-    uboMemoryOffset = 0;
-    for (i = 0; i < resultCtx->uboBufferCount; i++)
-    {
-        resultCtx->fragUboBuffers[i]->memoryOffset = uboMemoryOffset;
-
-        resultCtx->vkBindBufferMemory(
-            *resultCtx->logical_device,
-            resultCtx->fragUboBuffers[i]->buffer,
-            resultCtx->fragUboMemory,
-            uboMemoryOffset
-        );
-
-        uboMemoryOffset += UBO_BUFFER_SIZE;
-    } // for
+    resultCtx->vertUboBuffer = create_ubo(resultCtx);
+    resultCtx->fragUboBuffer = create_ubo(resultCtx);
 
     return resultCtx;
 
@@ -549,40 +424,24 @@
 
 void MOJOSHADER_vkDestroyContext()
 {
-    int32_t i;
-    for (i = 0; i < ctx->uboBufferCount; i++)
-    {
-        ctx->vkDestroyBuffer(
-            *ctx->logical_device,
-            ctx->vertUboBuffers[i]->buffer,
-            NULL
-        );
+    ctx->vkDestroyBuffer(*ctx->logical_device,
+                         ctx->vertUboBuffer->buffer,
+                         NULL);
 
-        ctx->free_fn(ctx->vertUboBuffers[i], ctx->malloc_data);
-
-        ctx->vkDestroyBuffer(
-            *ctx->logical_device,
-            ctx->fragUboBuffers[i]->buffer,
-            NULL
-        );
+    ctx->vkDestroyBuffer(*ctx->logical_device,
+                         ctx->fragUboBuffer->buffer,
+                         NULL);
 
-        ctx->free_fn(ctx->fragUboBuffers[i], ctx->malloc_data);
-    } // for
-
-    ctx->free_fn(ctx->vertUboBuffers, ctx->malloc_data);
-    ctx->free_fn(ctx->fragUboBuffers, ctx->malloc_data);
+    ctx->vkFreeMemory(*ctx->logical_device,
+                      ctx->vertUboBuffer->deviceMemory,
+                      NULL);
 
-    ctx->vkFreeMemory(
-        *ctx->logical_device,
-        ctx->vertUboMemory,
-        NULL
-    );
+    ctx->vkFreeMemory(*ctx->logical_device,
+                      ctx->fragUboBuffer->deviceMemory,
+                      NULL);
 
-    ctx->vkFreeMemory(
-        *ctx->logical_device,
-        ctx->fragUboMemory,
-        NULL
-    );
+    ctx->free_fn(ctx->vertUboBuffer, ctx->malloc_data);
+    ctx->free_fn(ctx->fragUboBuffer, ctx->malloc_data);
 
     ctx->free_fn(ctx, ctx->malloc_data);
 } // MOJOSHADER_vkDestroyContext
@@ -597,7 +456,6 @@
     const unsigned int smapcount
 ) {
     VkResult result;
-    VkShaderModule shaderModule;
     VkShaderModuleCreateInfo shaderModuleCreateInfo =
     {
         VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
@@ -691,7 +549,7 @@
 void MOJOSHADER_vkBindShaders(MOJOSHADER_vkShader *vshader,
                               MOJOSHADER_vkShader *pshader)
 {
-    /* NOOP if shader is null */
+    // NOOP if shader is null
 
     if (vshader != NULL)
         ctx->vertexShader = vshader;
@@ -740,24 +598,10 @@
 
 void MOJOSHADER_vkEndFrame()
 {
-    int32_t i;
-    ctx->currentFrame = (ctx->currentFrame + 1) % ctx->frames_in_flight;
-    for (i = 0; i < ctx->uboBufferCount; i++)
-    {
-        if (ctx->vertUboBuffers[i]->full == ctx->currentFrame)
-        {
-            ctx->vertUboBuffers[i]->dynamicOffset = 0;
-            ctx->vertUboBuffers[i]->currentBlockSize = 0;
-            ctx->vertUboBuffers[i]->full = -1;
-        } // if
-
-        if (ctx->fragUboBuffers[i]->full == ctx->currentFrame)
-        {
-            ctx->fragUboBuffers[i]->dynamicOffset = 0;
-            ctx->fragUboBuffers[i]->currentBlockSize = 0;
-            ctx->fragUboBuffers[i]->full = -1;
-        } // if
-    } // for
+    ctx->vertUboBuffer->dynamicOffset = 0;
+    ctx->vertUboBuffer->currentBlockSize = 0;
+    ctx->fragUboBuffer->dynamicOffset = 0;
+    ctx->fragUboBuffer->currentBlockSize = 0;
 } // MOJOSHADER_VkEndFrame
 
 int MOJOSHADER_vkGetVertexAttribLocation(MOJOSHADER_vkShader *vert,