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