Compare commits

...

5 Commits

Author SHA1 Message Date
Caleb Cornett 864d381d2a Remove fixed command buffers + minor cleanup 2023-01-13 20:33:07 -05:00
cosmonaut 903192cb4c Descriptor validation fix (#32)
The validator layer was complaining about us updating bound descriptor sets, this is technically a bug in the validator layer but resetting the command buffer in Cleanup makes more sense anyway. Also changed the wait for timeout call to a fence status query to make it easier to understand.

Reviewed-on: MoonsideGames/Refresh#32
2023-01-11 02:41:30 +00:00
cosmonaut 4cdd6a497a Fix transfer buffer alignment (#31)
Reviewed-on: MoonsideGames/Refresh#31
2023-01-07 05:24:58 +00:00
cosmonaut 28b4253fdf 1.10.0 2023-01-04 11:18:37 -08:00
TheSpydog e4215efe5e Enable multiDrawIndirect feature, add indirect command struct (#30)
Fixes a validation error when attempting to draw multiple primitives via an indirect draw call. Adds some documentation for how indirect draw buffers should be set up.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#30
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-04 18:44:02 +00:00
5 changed files with 62 additions and 72 deletions

View File

@ -8,7 +8,7 @@ option(BUILD_SHARED_LIBS "Build shared library" ON)
# Version # Version
SET(LIB_MAJOR_VERSION "1") SET(LIB_MAJOR_VERSION "1")
SET(LIB_MINOR_VERSION "9") SET(LIB_MINOR_VERSION "10")
SET(LIB_REVISION "0") SET(LIB_REVISION "0")
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}") SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}")

View File

@ -55,7 +55,7 @@ extern "C" {
/* Version API */ /* Version API */
#define REFRESH_MAJOR_VERSION 1 #define REFRESH_MAJOR_VERSION 1
#define REFRESH_MINOR_VERSION 9 #define REFRESH_MINOR_VERSION 10
#define REFRESH_PATCH_VERSION 0 #define REFRESH_PATCH_VERSION 0
#define REFRESH_COMPILED_VERSION ( \ #define REFRESH_COMPILED_VERSION ( \
@ -376,6 +376,14 @@ typedef struct Refresh_TextureSlice
uint32_t level; uint32_t level;
} Refresh_TextureSlice; } Refresh_TextureSlice;
typedef struct Refresh_IndirectDrawCommand
{
uint32_t vertexCount;
uint32_t instanceCount;
uint32_t firstVertex;
uint32_t firstInstance;
} Refresh_IndirectDrawCommand;
/* State structures */ /* State structures */
typedef struct Refresh_SamplerStateCreateInfo typedef struct Refresh_SamplerStateCreateInfo
@ -666,6 +674,7 @@ REFRESHAPI void Refresh_DrawPrimitives(
); );
/* Similar to Refresh_DrawPrimitives, but draw parameters are set from a buffer. /* Similar to Refresh_DrawPrimitives, but draw parameters are set from a buffer.
* The buffer layout should match the layout of Refresh_IndirectDrawCommand.
* *
* buffer: A buffer containing draw parameters. * buffer: A buffer containing draw parameters.
* offsetInBytes: The offset to start reading from the draw buffer. * offsetInBytes: The offset to start reading from the draw buffer.
@ -1159,15 +1168,9 @@ REFRESHAPI Refresh_TextureFormat Refresh_GetSwapchainFormat(
* A command buffer may only be used on the thread that * A command buffer may only be used on the thread that
* it was acquired on. Using it on any other thread is an error. * it was acquired on. Using it on any other thread is an error.
* *
* fixed:
* If a command buffer is designated as fixed, it can be
* acquired once, have commands recorded into it, and
* be re-submitted indefinitely.
*
*/ */
REFRESHAPI Refresh_CommandBuffer* Refresh_AcquireCommandBuffer( REFRESHAPI Refresh_CommandBuffer* Refresh_AcquireCommandBuffer(
Refresh_Device *device, Refresh_Device *device
uint8_t fixed
); );
/* Acquires a texture to use for presentation. /* Acquires a texture to use for presentation.

View File

@ -789,13 +789,11 @@ void Refresh_UnclaimWindow(
} }
Refresh_CommandBuffer* Refresh_AcquireCommandBuffer( Refresh_CommandBuffer* Refresh_AcquireCommandBuffer(
Refresh_Device *device, Refresh_Device *device
uint8_t fixed
) { ) {
NULL_RETURN_NULL(device); NULL_RETURN_NULL(device);
return device->AcquireCommandBuffer( return device->AcquireCommandBuffer(
device->driverData, device->driverData
fixed
); );
} }

View File

@ -470,8 +470,7 @@ struct Refresh_Device
); );
Refresh_CommandBuffer* (*AcquireCommandBuffer)( Refresh_CommandBuffer* (*AcquireCommandBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData
uint8_t fixed
); );
Refresh_Texture* (*AcquireSwapchainTexture)( Refresh_Texture* (*AcquireSwapchainTexture)(

View File

@ -1500,10 +1500,6 @@ typedef struct VulkanCommandPool VulkanCommandPool;
typedef struct VulkanCommandBuffer typedef struct VulkanCommandBuffer
{ {
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
uint8_t fixed;
uint8_t submitted;
uint8_t renderPassInProgress;
VulkanCommandPool *commandPool; VulkanCommandPool *commandPool;
VulkanPresentData *presentDatas; VulkanPresentData *presentDatas;
@ -4662,11 +4658,7 @@ static void VULKAN_INTERNAL_BeginCommandBuffer(
beginInfo.pNext = NULL; beginInfo.pNext = NULL;
beginInfo.flags = 0; beginInfo.flags = 0;
beginInfo.pInheritanceInfo = NULL; beginInfo.pInheritanceInfo = NULL;
if (!commandBuffer->fixed)
{
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
}
result = renderer->vkBeginCommandBuffer( result = renderer->vkBeginCommandBuffer(
commandBuffer->commandBuffer, commandBuffer->commandBuffer,
@ -6734,9 +6726,11 @@ static Refresh_Buffer* VULKAN_CreateBuffer(
static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer( static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer(
VulkanRenderer *renderer, VulkanRenderer *renderer,
VulkanCommandBuffer *commandBuffer, VulkanCommandBuffer *commandBuffer,
VkDeviceSize requiredSize VkDeviceSize requiredSize,
VkDeviceSize alignment
) { ) {
VkDeviceSize size; VkDeviceSize size;
VkDeviceSize offset;
uint32_t i; uint32_t i;
VulkanTransferBuffer *transferBuffer; VulkanTransferBuffer *transferBuffer;
@ -6745,9 +6739,11 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer(
for (i = 0; i < commandBuffer->transferBufferCount; i += 1) for (i = 0; i < commandBuffer->transferBufferCount; i += 1)
{ {
transferBuffer = commandBuffer->transferBuffers[i]; transferBuffer = commandBuffer->transferBuffers[i];
offset = transferBuffer->offset + alignment - (transferBuffer->offset % alignment);
if (transferBuffer->offset + requiredSize <= transferBuffer->buffer->size) if (offset + requiredSize <= transferBuffer->buffer->size)
{ {
transferBuffer->offset = offset;
return transferBuffer; return transferBuffer;
} }
} }
@ -6759,8 +6755,9 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer(
for (i = 0; i < renderer->transferBufferPool.availableBufferCount; i += 1) for (i = 0; i < renderer->transferBufferPool.availableBufferCount; i += 1)
{ {
transferBuffer = renderer->transferBufferPool.availableBuffers[i]; transferBuffer = renderer->transferBufferPool.availableBuffers[i];
offset = transferBuffer->offset + alignment - (transferBuffer->offset % alignment);
if (transferBuffer->offset + requiredSize <= transferBuffer->buffer->size) if (offset + requiredSize <= transferBuffer->buffer->size)
{ {
if (commandBuffer->transferBufferCount == commandBuffer->transferBufferCapacity) if (commandBuffer->transferBufferCount == commandBuffer->transferBufferCapacity)
{ {
@ -6778,6 +6775,7 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer(
renderer->transferBufferPool.availableBufferCount -= 1; renderer->transferBufferPool.availableBufferCount -= 1;
SDL_UnlockMutex(renderer->transferBufferPool.lock); SDL_UnlockMutex(renderer->transferBufferPool.lock);
transferBuffer->offset = offset;
return transferBuffer; return transferBuffer;
} }
} }
@ -6847,7 +6845,8 @@ static void VULKAN_SetTextureData(
textureSlice->rectangle.w, textureSlice->rectangle.w,
textureSlice->rectangle.h, textureSlice->rectangle.h,
vulkanTexture->format vulkanTexture->format
) ),
VULKAN_INTERNAL_BytesPerPixel(vulkanTexture->format)
); );
if (transferBuffer == NULL) if (transferBuffer == NULL)
@ -6944,7 +6943,7 @@ static void VULKAN_SetTextureDataYUV(
uint32_t dataLength uint32_t dataLength
) { ) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanTexture *tex; VulkanTexture *tex = (VulkanTexture*) y;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*)commandBuffer; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*)commandBuffer;
VulkanTransferBuffer *transferBuffer; VulkanTransferBuffer *transferBuffer;
@ -6957,7 +6956,8 @@ static void VULKAN_SetTextureDataYUV(
transferBuffer = VULKAN_INTERNAL_AcquireTransferBuffer( transferBuffer = VULKAN_INTERNAL_AcquireTransferBuffer(
renderer, renderer,
vulkanCommandBuffer, vulkanCommandBuffer,
yDataLength + uvDataLength yDataLength + uvDataLength,
VULKAN_INTERNAL_BytesPerPixel(tex->format)
); );
if (transferBuffer == NULL) if (transferBuffer == NULL)
@ -6983,8 +6983,6 @@ static void VULKAN_SetTextureDataYUV(
/* Y */ /* Y */
tex = (VulkanTexture*) y;
SDL_memcpy( SDL_memcpy(
stagingBufferPointer, stagingBufferPointer,
dataPtr, dataPtr,
@ -7336,7 +7334,8 @@ static void VULKAN_SetBufferData(
transferBuffer = VULKAN_INTERNAL_AcquireTransferBuffer( transferBuffer = VULKAN_INTERNAL_AcquireTransferBuffer(
renderer, renderer,
vulkanCommandBuffer, vulkanCommandBuffer,
dataLength dataLength,
renderer->physicalDeviceProperties.properties.limits.optimalBufferCopyOffsetAlignment
); );
if (transferBuffer == NULL) if (transferBuffer == NULL)
@ -8477,8 +8476,6 @@ static void VULKAN_BeginRenderPass(
VK_SUBPASS_CONTENTS_INLINE VK_SUBPASS_CONTENTS_INLINE
); );
vulkanCommandBuffer->renderPassInProgress = 1;
SDL_stack_free(clearValues); SDL_stack_free(clearValues);
for (i = 0; i < colorAttachmentCount; i += 1) for (i = 0; i < colorAttachmentCount; i += 1)
@ -8615,7 +8612,6 @@ static void VULKAN_EndRenderPass(
vulkanCommandBuffer->renderPassDepthTexture = NULL; vulkanCommandBuffer->renderPassDepthTexture = NULL;
vulkanCommandBuffer->currentGraphicsPipeline = NULL; vulkanCommandBuffer->currentGraphicsPipeline = NULL;
vulkanCommandBuffer->renderPassInProgress = 0;
} }
static void VULKAN_BindGraphicsPipeline( static void VULKAN_BindGraphicsPipeline(
@ -9190,8 +9186,7 @@ static VulkanCommandBuffer* VULKAN_INTERNAL_GetInactiveCommandBufferFromPool(
} }
static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer(
Refresh_Renderer *driverData, Refresh_Renderer *driverData
uint8_t fixed
) { ) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData; VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VkResult result; VkResult result;
@ -9214,33 +9209,8 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer(
commandBuffer->fragmentUniformBuffer = NULL; commandBuffer->fragmentUniformBuffer = NULL;
commandBuffer->computeUniformBuffer = NULL; commandBuffer->computeUniformBuffer = NULL;
commandBuffer->fixed = fixed;
commandBuffer->submitted = 0;
commandBuffer->renderPassInProgress = 0;
commandBuffer->renderPassColorTargetCount = 0; commandBuffer->renderPassColorTargetCount = 0;
result = renderer->vkResetCommandBuffer(
commandBuffer->commandBuffer,
VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT
);
if (result != VK_SUCCESS)
{
LogVulkanResultAsError("vkResetCommandBuffer", result);
}
result = renderer->vkResetFences(
renderer->logicalDevice,
1,
&commandBuffer->inFlightFence
);
if (result != VK_SUCCESS)
{
LogVulkanResultAsError("vkResetFences", result);
}
VULKAN_INTERNAL_BeginCommandBuffer(renderer, commandBuffer); VULKAN_INTERNAL_BeginCommandBuffer(renderer, commandBuffer);
return (Refresh_CommandBuffer*) commandBuffer; return (Refresh_CommandBuffer*) commandBuffer;
@ -9644,6 +9614,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
uint32_t i; uint32_t i;
VulkanUniformBuffer *uniformBuffer; VulkanUniformBuffer *uniformBuffer;
DescriptorSetData *descriptorSetData; DescriptorSetData *descriptorSetData;
VkResult result;
/* Bound uniform buffers are now available */ /* Bound uniform buffers are now available */
@ -9773,12 +9744,35 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
SDL_UnlockMutex(renderer->acquireCommandBufferLock); SDL_UnlockMutex(renderer->acquireCommandBufferLock);
/* Resent presentation data */ /* Reset presentation data */
commandBuffer->presentDataCount = 0; commandBuffer->presentDataCount = 0;
commandBuffer->waitSemaphoreCount = 0; commandBuffer->waitSemaphoreCount = 0;
commandBuffer->signalSemaphoreCount = 0; commandBuffer->signalSemaphoreCount = 0;
/* Reset Vulkan state */
result = renderer->vkResetCommandBuffer(
commandBuffer->commandBuffer,
VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT
);
if (result != VK_SUCCESS)
{
LogVulkanResultAsError("vkResetCommandBuffer", result);
}
result = renderer->vkResetFences(
renderer->logicalDevice,
1,
&commandBuffer->inFlightFence
);
if (result != VK_SUCCESS)
{
LogVulkanResultAsError("vkResetFences", result);
}
/* Remove this command buffer from the submitted list */ /* Remove this command buffer from the submitted list */
for (i = 0; i < renderer->submittedCommandBufferCount; i += 1) for (i = 0; i < renderer->submittedCommandBufferCount; i += 1)
{ {
@ -9910,7 +9904,6 @@ static void VULKAN_Submit(
); );
} }
((VulkanCommandBuffer*)pCommandBuffers[i])->submitted = 1;
renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = (VulkanCommandBuffer*) pCommandBuffers[i]; renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = (VulkanCommandBuffer*) pCommandBuffers[i];
renderer->submittedCommandBufferCount += 1; renderer->submittedCommandBufferCount += 1;
@ -9948,13 +9941,9 @@ static void VULKAN_Submit(
for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1)
{ {
/* If we set a timeout of 0, we can query the command buffer state */ vulkanResult = renderer->vkGetFenceStatus(
vulkanResult = renderer->vkWaitForFences(
renderer->logicalDevice, renderer->logicalDevice,
1, renderer->submittedCommandBuffers[i]->inFlightFence
&renderer->submittedCommandBuffers[i]->inFlightFence,
VK_TRUE,
0
); );
if (vulkanResult == VK_SUCCESS) if (vulkanResult == VK_SUCCESS)
@ -10537,6 +10526,7 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice(
SDL_zero(deviceFeatures); SDL_zero(deviceFeatures);
deviceFeatures.fillModeNonSolid = VK_TRUE; deviceFeatures.fillModeNonSolid = VK_TRUE;
deviceFeatures.samplerAnisotropy = VK_TRUE; deviceFeatures.samplerAnisotropy = VK_TRUE;
deviceFeatures.multiDrawIndirect = VK_TRUE;
/* creating the logical device */ /* creating the logical device */