forked from MoonsideGames/Refresh
parent
f55968814f
commit
a3949528eb
|
@ -76,6 +76,7 @@ typedef struct Refresh_ShaderModule Refresh_ShaderModule;
|
||||||
typedef struct Refresh_ComputePipeline Refresh_ComputePipeline;
|
typedef struct Refresh_ComputePipeline Refresh_ComputePipeline;
|
||||||
typedef struct Refresh_GraphicsPipeline Refresh_GraphicsPipeline;
|
typedef struct Refresh_GraphicsPipeline Refresh_GraphicsPipeline;
|
||||||
typedef struct Refresh_CommandBuffer Refresh_CommandBuffer;
|
typedef struct Refresh_CommandBuffer Refresh_CommandBuffer;
|
||||||
|
typedef struct Refresh_Fence Refresh_Fence;
|
||||||
|
|
||||||
typedef enum Refresh_PresentMode
|
typedef enum Refresh_PresentMode
|
||||||
{
|
{
|
||||||
|
@ -1206,15 +1207,50 @@ REFRESHAPI Refresh_Texture* Refresh_AcquireSwapchainTexture(
|
||||||
/* Submits all of the enqueued commands. */
|
/* Submits all of the enqueued commands. */
|
||||||
REFRESHAPI void Refresh_Submit(
|
REFRESHAPI void Refresh_Submit(
|
||||||
Refresh_Device* device,
|
Refresh_Device* device,
|
||||||
uint32_t commandBufferCount,
|
Refresh_CommandBuffer *commandBuffer
|
||||||
Refresh_CommandBuffer **pCommandBuffers
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Waits for all submissions to complete. */
|
/* Submits a command buffer and acquires a fence.
|
||||||
|
* You can use the fence to check if or wait until the command buffer has finished processing.
|
||||||
|
* You are responsible for releasing this fence when you are done using it.
|
||||||
|
*/
|
||||||
|
REFRESHAPI Refresh_Fence* Refresh_SubmitAndAcquireFence(
|
||||||
|
Refresh_Device* device,
|
||||||
|
Refresh_CommandBuffer *commandBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Waits for the device to become idle. */
|
||||||
REFRESHAPI void Refresh_Wait(
|
REFRESHAPI void Refresh_Wait(
|
||||||
Refresh_Device *device
|
Refresh_Device *device
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Waits for given fences to be signaled.
|
||||||
|
*
|
||||||
|
* waitAll: If 0, waits for any fence to be signaled. If 1, waits for all fences to be signaled.
|
||||||
|
* fenceCount: The number of fences being submitted.
|
||||||
|
* pFences: An array of fences to be waited on.
|
||||||
|
*/
|
||||||
|
REFRESHAPI void Refresh_WaitForFences(
|
||||||
|
Refresh_Device *device,
|
||||||
|
uint8_t waitAll,
|
||||||
|
uint32_t fenceCount,
|
||||||
|
Refresh_Fence **pFences
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Check the status of a fence. 1 means the fence is signaled. */
|
||||||
|
REFRESHAPI int Refresh_QueryFence(
|
||||||
|
Refresh_Device *device,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Allows the fence to be reused by future command buffer submissions.
|
||||||
|
* If you do not release fences after acquiring them, you will cause unbounded resource growth.
|
||||||
|
*/
|
||||||
|
REFRESHAPI void Refresh_ReleaseFence(
|
||||||
|
Refresh_Device *device,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
|
@ -892,14 +892,23 @@ void Refresh_SetSwapchainPresentMode(
|
||||||
|
|
||||||
void Refresh_Submit(
|
void Refresh_Submit(
|
||||||
Refresh_Device *device,
|
Refresh_Device *device,
|
||||||
uint32_t commandBufferCount,
|
Refresh_CommandBuffer *commandBuffer
|
||||||
Refresh_CommandBuffer **pCommandBuffers
|
|
||||||
) {
|
) {
|
||||||
NULL_RETURN(device);
|
NULL_RETURN(device);
|
||||||
device->Submit(
|
device->Submit(
|
||||||
device->driverData,
|
device->driverData,
|
||||||
commandBufferCount,
|
commandBuffer
|
||||||
pCommandBuffers
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Refresh_Fence* Refresh_SubmitAndAcquireFence(
|
||||||
|
Refresh_Device *device,
|
||||||
|
Refresh_CommandBuffer *commandBuffer
|
||||||
|
) {
|
||||||
|
NULL_RETURN_NULL(device);
|
||||||
|
return device->SubmitAndAcquireFence(
|
||||||
|
device->driverData,
|
||||||
|
commandBuffer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,4 +921,44 @@ void Refresh_Wait(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Refresh_WaitForFences(
|
||||||
|
Refresh_Device *device,
|
||||||
|
uint8_t waitAll,
|
||||||
|
uint32_t fenceCount,
|
||||||
|
Refresh_Fence **pFences
|
||||||
|
) {
|
||||||
|
NULL_RETURN(device);
|
||||||
|
device->WaitForFences(
|
||||||
|
device->driverData,
|
||||||
|
waitAll,
|
||||||
|
fenceCount,
|
||||||
|
pFences
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Refresh_QueryFence(
|
||||||
|
Refresh_Device *device,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
) {
|
||||||
|
if (device == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device->QueryFence(
|
||||||
|
device->driverData,
|
||||||
|
fence
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Refresh_ReleaseFence(
|
||||||
|
Refresh_Device *device,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
) {
|
||||||
|
NULL_RETURN(device);
|
||||||
|
device->ReleaseFence(
|
||||||
|
device->driverData,
|
||||||
|
fence
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
|
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
|
||||||
|
|
|
@ -268,7 +268,7 @@ struct Refresh_Device
|
||||||
|
|
||||||
/* Setters */
|
/* Setters */
|
||||||
|
|
||||||
void(*SetTextureData)(
|
void (*SetTextureData)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_TextureSlice *textureSlice,
|
Refresh_TextureSlice *textureSlice,
|
||||||
|
@ -276,7 +276,7 @@ struct Refresh_Device
|
||||||
uint32_t dataLengthInBytes
|
uint32_t dataLengthInBytes
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*SetTextureDataYUV)(
|
void (*SetTextureDataYUV)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer* commandBuffer,
|
Refresh_CommandBuffer* commandBuffer,
|
||||||
Refresh_Texture *y,
|
Refresh_Texture *y,
|
||||||
|
@ -295,7 +295,7 @@ struct Refresh_Device
|
||||||
uint32_t uvStride
|
uint32_t uvStride
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*CopyTextureToTexture)(
|
void (*CopyTextureToTexture)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_TextureSlice *sourceTextureSlice,
|
Refresh_TextureSlice *sourceTextureSlice,
|
||||||
|
@ -303,14 +303,14 @@ struct Refresh_Device
|
||||||
Refresh_Filter filter
|
Refresh_Filter filter
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*CopyTextureToBuffer)(
|
void (*CopyTextureToBuffer)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_TextureSlice *textureSlice,
|
Refresh_TextureSlice *textureSlice,
|
||||||
Refresh_Buffer *buffer
|
Refresh_Buffer *buffer
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*SetBufferData)(
|
void (*SetBufferData)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Buffer *buffer,
|
Refresh_Buffer *buffer,
|
||||||
|
@ -319,14 +319,14 @@ struct Refresh_Device
|
||||||
uint32_t dataLength
|
uint32_t dataLength
|
||||||
);
|
);
|
||||||
|
|
||||||
uint32_t(*PushVertexShaderUniforms)(
|
uint32_t (*PushVertexShaderUniforms)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
void *data,
|
void *data,
|
||||||
uint32_t dataLengthInBytes
|
uint32_t dataLengthInBytes
|
||||||
);
|
);
|
||||||
|
|
||||||
uint32_t(*PushFragmentShaderUniforms)(
|
uint32_t (*PushFragmentShaderUniforms)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
void *data,
|
void *data,
|
||||||
|
@ -340,14 +340,14 @@ struct Refresh_Device
|
||||||
uint32_t dataLengthInBytes
|
uint32_t dataLengthInBytes
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindVertexSamplers)(
|
void (*BindVertexSamplers)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Texture **pTextures,
|
Refresh_Texture **pTextures,
|
||||||
Refresh_Sampler **pSamplers
|
Refresh_Sampler **pSamplers
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindFragmentSamplers)(
|
void (*BindFragmentSamplers)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Texture **pTextures,
|
Refresh_Texture **pTextures,
|
||||||
|
@ -356,7 +356,7 @@ struct Refresh_Device
|
||||||
|
|
||||||
/* Getters */
|
/* Getters */
|
||||||
|
|
||||||
void(*GetBufferData)(
|
void (*GetBufferData)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_Buffer *buffer,
|
Refresh_Buffer *buffer,
|
||||||
void *data,
|
void *data,
|
||||||
|
@ -365,39 +365,39 @@ struct Refresh_Device
|
||||||
|
|
||||||
/* Disposal */
|
/* Disposal */
|
||||||
|
|
||||||
void(*QueueDestroyTexture)(
|
void (*QueueDestroyTexture)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_Texture *texture
|
Refresh_Texture *texture
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*QueueDestroySampler)(
|
void (*QueueDestroySampler)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_Sampler *sampler
|
Refresh_Sampler *sampler
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*QueueDestroyBuffer)(
|
void (*QueueDestroyBuffer)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_Buffer *buffer
|
Refresh_Buffer *buffer
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*QueueDestroyShaderModule)(
|
void (*QueueDestroyShaderModule)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_ShaderModule *shaderModule
|
Refresh_ShaderModule *shaderModule
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*QueueDestroyComputePipeline)(
|
void (*QueueDestroyComputePipeline)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_ComputePipeline *computePipeline
|
Refresh_ComputePipeline *computePipeline
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*QueueDestroyGraphicsPipeline)(
|
void (*QueueDestroyGraphicsPipeline)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_GraphicsPipeline *graphicsPipeline
|
Refresh_GraphicsPipeline *graphicsPipeline
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Graphics State */
|
/* Graphics State */
|
||||||
|
|
||||||
void(*BeginRenderPass)(
|
void (*BeginRenderPass)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
|
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
|
||||||
|
@ -405,30 +405,30 @@ struct Refresh_Device
|
||||||
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
|
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*EndRenderPass)(
|
void (*EndRenderPass)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer
|
Refresh_CommandBuffer *commandBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*SetViewport)(
|
void (*SetViewport)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Viewport *viewport
|
Refresh_Viewport *viewport
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*SetScissor)(
|
void (*SetScissor)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Rect *scissor
|
Refresh_Rect *scissor
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindGraphicsPipeline)(
|
void (*BindGraphicsPipeline)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_GraphicsPipeline *graphicsPipeline
|
Refresh_GraphicsPipeline *graphicsPipeline
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindVertexBuffers)(
|
void (*BindVertexBuffers)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
uint32_t firstBinding,
|
uint32_t firstBinding,
|
||||||
|
@ -437,7 +437,7 @@ struct Refresh_Device
|
||||||
uint64_t *pOffsets
|
uint64_t *pOffsets
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindIndexBuffer)(
|
void (*BindIndexBuffer)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Buffer *buffer,
|
Refresh_Buffer *buffer,
|
||||||
|
@ -445,19 +445,19 @@ struct Refresh_Device
|
||||||
Refresh_IndexElementSize indexElementSize
|
Refresh_IndexElementSize indexElementSize
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindComputePipeline)(
|
void (*BindComputePipeline)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_ComputePipeline *computePipeline
|
Refresh_ComputePipeline *computePipeline
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindComputeBuffers)(
|
void (*BindComputeBuffers)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Buffer **pBuffers
|
Refresh_Buffer **pBuffers
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*BindComputeTextures)(
|
void (*BindComputeTextures)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer *commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Texture **pTextures
|
Refresh_Texture **pTextures
|
||||||
|
@ -469,7 +469,7 @@ struct Refresh_Device
|
||||||
Refresh_PresentMode presentMode
|
Refresh_PresentMode presentMode
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*UnclaimWindow)(
|
void (*UnclaimWindow)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
void *windowHandle
|
void *windowHandle
|
||||||
);
|
);
|
||||||
|
@ -497,16 +497,37 @@ struct Refresh_Device
|
||||||
Refresh_PresentMode presentMode
|
Refresh_PresentMode presentMode
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*Submit)(
|
void (*Submit)(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
uint32_t commandBufferCount,
|
Refresh_CommandBuffer *commandBuffer
|
||||||
Refresh_CommandBuffer **pCommandBuffers
|
|
||||||
);
|
);
|
||||||
|
|
||||||
void(*Wait)(
|
Refresh_Fence* (*SubmitAndAcquireFence)(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
Refresh_CommandBuffer *commandBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
void (*Wait)(
|
||||||
Refresh_Renderer *driverData
|
Refresh_Renderer *driverData
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void (*WaitForFences)(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
uint8_t waitAll,
|
||||||
|
uint32_t fenceCount,
|
||||||
|
Refresh_Fence **pFences
|
||||||
|
);
|
||||||
|
|
||||||
|
int (*QueryFence)(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
);
|
||||||
|
|
||||||
|
void (*ReleaseFence)(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
);
|
||||||
|
|
||||||
/* Opaque pointer for the Driver */
|
/* Opaque pointer for the Driver */
|
||||||
Refresh_Renderer *driverData;
|
Refresh_Renderer *driverData;
|
||||||
};
|
};
|
||||||
|
@ -560,7 +581,11 @@ struct Refresh_Device
|
||||||
ASSIGN_DRIVER_FUNC(GetSwapchainFormat, name) \
|
ASSIGN_DRIVER_FUNC(GetSwapchainFormat, name) \
|
||||||
ASSIGN_DRIVER_FUNC(SetSwapchainPresentMode, name) \
|
ASSIGN_DRIVER_FUNC(SetSwapchainPresentMode, name) \
|
||||||
ASSIGN_DRIVER_FUNC(Submit, name) \
|
ASSIGN_DRIVER_FUNC(Submit, name) \
|
||||||
ASSIGN_DRIVER_FUNC(Wait, name)
|
ASSIGN_DRIVER_FUNC(SubmitAndAcquireFence, name) \
|
||||||
|
ASSIGN_DRIVER_FUNC(Wait, name) \
|
||||||
|
ASSIGN_DRIVER_FUNC(WaitForFences, name) \
|
||||||
|
ASSIGN_DRIVER_FUNC(QueryFence, name) \
|
||||||
|
ASSIGN_DRIVER_FUNC(ReleaseFence, name)
|
||||||
|
|
||||||
typedef struct Refresh_Driver
|
typedef struct Refresh_Driver
|
||||||
{
|
{
|
||||||
|
|
|
@ -1533,6 +1533,15 @@ typedef struct VulkanTransferBufferPool
|
||||||
uint32_t availableBufferCapacity;
|
uint32_t availableBufferCapacity;
|
||||||
} VulkanTransferBufferPool;
|
} VulkanTransferBufferPool;
|
||||||
|
|
||||||
|
typedef struct VulkanFencePool
|
||||||
|
{
|
||||||
|
SDL_mutex *lock;
|
||||||
|
|
||||||
|
VkFence *availableFences;
|
||||||
|
uint32_t availableFenceCount;
|
||||||
|
uint32_t availableFenceCapacity;
|
||||||
|
} VulkanFencePool;
|
||||||
|
|
||||||
typedef struct VulkanCommandPool VulkanCommandPool;
|
typedef struct VulkanCommandPool VulkanCommandPool;
|
||||||
|
|
||||||
typedef struct VulkanCommandBuffer
|
typedef struct VulkanCommandBuffer
|
||||||
|
@ -1624,6 +1633,7 @@ typedef struct VulkanCommandBuffer
|
||||||
/* Shader modules have references tracked by pipelines */
|
/* Shader modules have references tracked by pipelines */
|
||||||
|
|
||||||
VkFence inFlightFence;
|
VkFence inFlightFence;
|
||||||
|
uint8_t autoReleaseFence;
|
||||||
} VulkanCommandBuffer;
|
} VulkanCommandBuffer;
|
||||||
|
|
||||||
struct VulkanCommandPool
|
struct VulkanCommandPool
|
||||||
|
@ -1737,6 +1747,7 @@ typedef struct VulkanRenderer
|
||||||
uint32_t submittedCommandBufferCapacity;
|
uint32_t submittedCommandBufferCapacity;
|
||||||
|
|
||||||
VulkanTransferBufferPool transferBufferPool;
|
VulkanTransferBufferPool transferBufferPool;
|
||||||
|
VulkanFencePool fencePool;
|
||||||
|
|
||||||
CommandPoolHashTable commandPoolHashTable;
|
CommandPoolHashTable commandPoolHashTable;
|
||||||
DescriptorSetLayoutHashTable descriptorSetLayoutHashTable;
|
DescriptorSetLayoutHashTable descriptorSetLayoutHashTable;
|
||||||
|
@ -1828,7 +1839,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(VulkanRenderer *renderer);
|
||||||
static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
|
static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
|
||||||
static void VULKAN_UnclaimWindow(Refresh_Renderer *driverData, void *windowHandle);
|
static void VULKAN_UnclaimWindow(Refresh_Renderer *driverData, void *windowHandle);
|
||||||
static void VULKAN_Wait(Refresh_Renderer *driverData);
|
static void VULKAN_Wait(Refresh_Renderer *driverData);
|
||||||
static void VULKAN_Submit(Refresh_Renderer *driverData, uint32_t commandBufferCount, Refresh_CommandBuffer **pCommandBuffers);
|
static void VULKAN_Submit(Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer);
|
||||||
static void VULKAN_INTERNAL_DestroyRenderTarget(VulkanRenderer *renderer, VulkanRenderTarget *renderTarget);
|
static void VULKAN_INTERNAL_DestroyRenderTarget(VulkanRenderer *renderer, VulkanRenderTarget *renderTarget);
|
||||||
|
|
||||||
/* Error Handling */
|
/* Error Handling */
|
||||||
|
@ -3589,12 +3600,6 @@ static void VULKAN_INTERNAL_DestroyCommandPool(
|
||||||
{
|
{
|
||||||
commandBuffer = commandPool->inactiveCommandBuffers[i];
|
commandBuffer = commandPool->inactiveCommandBuffers[i];
|
||||||
|
|
||||||
renderer->vkDestroyFence(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
commandBuffer->inFlightFence,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
SDL_free(commandBuffer->presentDatas);
|
SDL_free(commandBuffer->presentDatas);
|
||||||
SDL_free(commandBuffer->waitSemaphores);
|
SDL_free(commandBuffer->waitSemaphores);
|
||||||
SDL_free(commandBuffer->signalSemaphores);
|
SDL_free(commandBuffer->signalSemaphores);
|
||||||
|
@ -5158,6 +5163,14 @@ static void VULKAN_DestroyDevice(
|
||||||
SDL_free(renderer->transferBufferPool.availableBuffers);
|
SDL_free(renderer->transferBufferPool.availableBuffers);
|
||||||
SDL_DestroyMutex(renderer->transferBufferPool.lock);
|
SDL_DestroyMutex(renderer->transferBufferPool.lock);
|
||||||
|
|
||||||
|
for (i = 0; i < renderer->fencePool.availableFenceCount; i += 1)
|
||||||
|
{
|
||||||
|
renderer->vkDestroyFence(renderer->logicalDevice, renderer->fencePool.availableFences[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(renderer->fencePool.availableFences);
|
||||||
|
SDL_DestroyMutex(renderer->fencePool.lock);
|
||||||
|
|
||||||
for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1)
|
for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1)
|
||||||
{
|
{
|
||||||
commandPoolHashArray = renderer->commandPoolHashTable.buckets[i];
|
commandPoolHashArray = renderer->commandPoolHashTable.buckets[i];
|
||||||
|
@ -9362,7 +9375,6 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers(
|
||||||
uint32_t allocateCount
|
uint32_t allocateCount
|
||||||
) {
|
) {
|
||||||
VkCommandBufferAllocateInfo allocateInfo;
|
VkCommandBufferAllocateInfo allocateInfo;
|
||||||
VkFenceCreateInfo fenceCreateInfo;
|
|
||||||
VkResult vulkanResult;
|
VkResult vulkanResult;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
VkCommandBuffer *commandBuffers = SDL_stack_alloc(VkCommandBuffer, allocateCount);
|
VkCommandBuffer *commandBuffers = SDL_stack_alloc(VkCommandBuffer, allocateCount);
|
||||||
|
@ -9401,23 +9413,7 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers(
|
||||||
commandBuffer->commandPool = vulkanCommandPool;
|
commandBuffer->commandPool = vulkanCommandPool;
|
||||||
commandBuffer->commandBuffer = commandBuffers[i];
|
commandBuffer->commandBuffer = commandBuffers[i];
|
||||||
|
|
||||||
/* Create fence */
|
commandBuffer->inFlightFence = VK_NULL_HANDLE;
|
||||||
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
|
||||||
fenceCreateInfo.pNext = NULL;
|
|
||||||
fenceCreateInfo.flags = 0;
|
|
||||||
|
|
||||||
vulkanResult = renderer->vkCreateFence(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
&fenceCreateInfo,
|
|
||||||
NULL,
|
|
||||||
&commandBuffer->inFlightFence
|
|
||||||
);
|
|
||||||
|
|
||||||
if (vulkanResult != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
LogVulkanResultAsError("vkCreateFence", vulkanResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
commandBuffer->renderPassDepthTexture = NULL;
|
commandBuffer->renderPassDepthTexture = NULL;
|
||||||
|
|
||||||
/* Presentation tracking */
|
/* Presentation tracking */
|
||||||
|
@ -9650,17 +9646,6 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer(
|
||||||
LogVulkanResultAsError("vkResetCommandBuffer", result);
|
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;
|
||||||
|
@ -9949,6 +9934,77 @@ static void VULKAN_SetSwapchainPresentMode(
|
||||||
|
|
||||||
/* Submission structure */
|
/* Submission structure */
|
||||||
|
|
||||||
|
static VkFence VULKAN_INTERNAL_AcquireFenceFromPool(
|
||||||
|
VulkanRenderer *renderer
|
||||||
|
) {
|
||||||
|
VkFenceCreateInfo fenceCreateInfo;
|
||||||
|
VkFence fence;
|
||||||
|
VkResult vulkanResult;
|
||||||
|
|
||||||
|
if (renderer->fencePool.availableFenceCount == 0)
|
||||||
|
{
|
||||||
|
/* Create fence */
|
||||||
|
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
fenceCreateInfo.pNext = NULL;
|
||||||
|
fenceCreateInfo.flags = 0;
|
||||||
|
|
||||||
|
vulkanResult = renderer->vkCreateFence(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
&fenceCreateInfo,
|
||||||
|
NULL,
|
||||||
|
&fence
|
||||||
|
);
|
||||||
|
|
||||||
|
if (vulkanResult != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
LogVulkanResultAsError("vkCreateFence", vulkanResult);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fence;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LockMutex(renderer->fencePool.lock);
|
||||||
|
|
||||||
|
fence = renderer->fencePool.availableFences[renderer->fencePool.availableFenceCount - 1];
|
||||||
|
renderer->fencePool.availableFenceCount -= 1;
|
||||||
|
|
||||||
|
vulkanResult = renderer->vkResetFences(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
1,
|
||||||
|
&fence
|
||||||
|
);
|
||||||
|
|
||||||
|
if (vulkanResult != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
LogVulkanResultAsError("vkResetFences", vulkanResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_UnlockMutex(renderer->fencePool.lock);
|
||||||
|
|
||||||
|
return fence;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VULKAN_INTERNAL_ReturnFenceToPool(
|
||||||
|
VulkanRenderer *renderer,
|
||||||
|
VkFence fence
|
||||||
|
) {
|
||||||
|
SDL_LockMutex(renderer->fencePool.lock);
|
||||||
|
|
||||||
|
EXPAND_ARRAY_IF_NEEDED(
|
||||||
|
renderer->fencePool.availableFences,
|
||||||
|
VkFence,
|
||||||
|
renderer->fencePool.availableFenceCount + 1,
|
||||||
|
renderer->fencePool.availableFenceCapacity,
|
||||||
|
renderer->fencePool.availableFenceCapacity * 2
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer->fencePool.availableFences[renderer->fencePool.availableFenceCount] = fence;
|
||||||
|
renderer->fencePool.availableFenceCount += 1;
|
||||||
|
|
||||||
|
SDL_UnlockMutex(renderer->fencePool.lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void VULKAN_INTERNAL_PerformPendingDestroys(
|
static void VULKAN_INTERNAL_PerformPendingDestroys(
|
||||||
VulkanRenderer *renderer
|
VulkanRenderer *renderer
|
||||||
) {
|
) {
|
||||||
|
@ -10064,6 +10120,16 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
||||||
VulkanUniformBuffer *uniformBuffer;
|
VulkanUniformBuffer *uniformBuffer;
|
||||||
DescriptorSetData *descriptorSetData;
|
DescriptorSetData *descriptorSetData;
|
||||||
|
|
||||||
|
if (commandBuffer->autoReleaseFence)
|
||||||
|
{
|
||||||
|
VULKAN_INTERNAL_ReturnFenceToPool(
|
||||||
|
renderer,
|
||||||
|
commandBuffer->inFlightFence
|
||||||
|
);
|
||||||
|
|
||||||
|
commandBuffer->inFlightFence = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Bound uniform buffers are now available */
|
/* Bound uniform buffers are now available */
|
||||||
|
|
||||||
for (i = 0; i < commandBuffer->boundUniformBufferCount; i += 1)
|
for (i = 0; i < commandBuffer->boundUniformBufferCount; i += 1)
|
||||||
|
@ -10219,26 +10285,16 @@ static void VULKAN_Wait(
|
||||||
VkResult result;
|
VkResult result;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
SDL_LockMutex(renderer->submitLock);
|
result = renderer->vkDeviceWaitIdle(renderer->logicalDevice);
|
||||||
|
|
||||||
for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1)
|
if (result != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
commandBuffer = renderer->submittedCommandBuffers[i];
|
LogVulkanResultAsError("vkDeviceWaitIdle", result);
|
||||||
|
return;
|
||||||
result = renderer->vkWaitForFences(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
1,
|
|
||||||
&commandBuffer->inFlightFence,
|
|
||||||
VK_TRUE,
|
|
||||||
UINT64_MAX
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
LogVulkanResultAsError("vkWaitForFences", result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_LockMutex(renderer->submitLock);
|
||||||
|
|
||||||
for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1)
|
for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1)
|
||||||
{
|
{
|
||||||
commandBuffer = renderer->submittedCommandBuffers[i];
|
commandBuffer = renderer->submittedCommandBuffers[i];
|
||||||
|
@ -10250,17 +10306,30 @@ static void VULKAN_Wait(
|
||||||
SDL_UnlockMutex(renderer->submitLock);
|
SDL_UnlockMutex(renderer->submitLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Refresh_Fence* VULKAN_SubmitAndAcquireFence(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
Refresh_CommandBuffer *commandBuffer
|
||||||
|
) {
|
||||||
|
VulkanCommandBuffer *vulkanCommandBuffer;
|
||||||
|
|
||||||
|
VULKAN_Submit(driverData, commandBuffer);
|
||||||
|
|
||||||
|
vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||||
|
vulkanCommandBuffer->autoReleaseFence = 0;
|
||||||
|
|
||||||
|
return (Refresh_Fence*) vulkanCommandBuffer->inFlightFence;
|
||||||
|
}
|
||||||
|
|
||||||
static void VULKAN_Submit(
|
static void VULKAN_Submit(
|
||||||
Refresh_Renderer *driverData,
|
Refresh_Renderer *driverData,
|
||||||
uint32_t commandBufferCount,
|
Refresh_CommandBuffer *commandBuffer
|
||||||
Refresh_CommandBuffer **pCommandBuffers
|
|
||||||
) {
|
) {
|
||||||
VulkanRenderer* renderer = (VulkanRenderer*)driverData;
|
VulkanRenderer* renderer = (VulkanRenderer*)driverData;
|
||||||
VkSubmitInfo submitInfo;
|
VkSubmitInfo submitInfo;
|
||||||
VkPresentInfoKHR presentInfo;
|
VkPresentInfoKHR presentInfo;
|
||||||
VulkanPresentData *presentData;
|
VulkanPresentData *presentData;
|
||||||
VkResult vulkanResult, presentResult = VK_SUCCESS;
|
VkResult vulkanResult, presentResult = VK_SUCCESS;
|
||||||
VulkanCommandBuffer *currentCommandBuffer;
|
VulkanCommandBuffer *vulkanCommandBuffer;
|
||||||
VkPipelineStageFlags waitStages[MAX_PRESENT_COUNT];
|
VkPipelineStageFlags waitStages[MAX_PRESENT_COUNT];
|
||||||
uint32_t swapchainImageIndex;
|
uint32_t swapchainImageIndex;
|
||||||
uint8_t commandBufferCleaned = 0;
|
uint8_t commandBufferCleaned = 0;
|
||||||
|
@ -10275,99 +10344,97 @@ static void VULKAN_Submit(
|
||||||
waitStages[i] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
waitStages[i] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Submit the commands finally */
|
vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||||
|
|
||||||
for (i = 0; i < commandBufferCount; i += 1)
|
for (j = 0; j < vulkanCommandBuffer->presentDataCount; j += 1)
|
||||||
{
|
{
|
||||||
currentCommandBuffer = (VulkanCommandBuffer*)pCommandBuffers[i];
|
swapchainImageIndex = vulkanCommandBuffer->presentDatas[j].swapchainImageIndex;
|
||||||
|
|
||||||
for (j = 0; j < currentCommandBuffer->presentDataCount; j += 1)
|
VULKAN_INTERNAL_ImageMemoryBarrier(
|
||||||
{
|
renderer,
|
||||||
swapchainImageIndex = currentCommandBuffer->presentDatas[j].swapchainImageIndex;
|
vulkanCommandBuffer->commandBuffer,
|
||||||
|
RESOURCE_ACCESS_PRESENT,
|
||||||
VULKAN_INTERNAL_ImageMemoryBarrier(
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
renderer,
|
0,
|
||||||
currentCommandBuffer->commandBuffer,
|
|
||||||
RESOURCE_ACCESS_PRESENT,
|
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
currentCommandBuffer->presentDatas[j].windowData->swapchainData->textureContainers[swapchainImageIndex].vulkanTexture->image,
|
|
||||||
¤tCommandBuffer->presentDatas[j].windowData->swapchainData->textureContainers[swapchainImageIndex].vulkanTexture->resourceAccessType
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
VULKAN_INTERNAL_EndCommandBuffer(renderer, currentCommandBuffer);
|
|
||||||
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
submitInfo.pNext = NULL;
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = ¤tCommandBuffer->commandBuffer;
|
|
||||||
|
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
|
||||||
submitInfo.pWaitSemaphores = currentCommandBuffer->waitSemaphores;
|
|
||||||
submitInfo.waitSemaphoreCount = currentCommandBuffer->waitSemaphoreCount;
|
|
||||||
submitInfo.pSignalSemaphores = currentCommandBuffer->signalSemaphores;
|
|
||||||
submitInfo.signalSemaphoreCount = currentCommandBuffer->signalSemaphoreCount;
|
|
||||||
|
|
||||||
vulkanResult = renderer->vkQueueSubmit(
|
|
||||||
renderer->unifiedQueue,
|
|
||||||
1,
|
1,
|
||||||
&submitInfo,
|
0,
|
||||||
currentCommandBuffer->inFlightFence
|
1,
|
||||||
|
0,
|
||||||
|
vulkanCommandBuffer->presentDatas[j].windowData->swapchainData->textureContainers[swapchainImageIndex].vulkanTexture->image,
|
||||||
|
&vulkanCommandBuffer->presentDatas[j].windowData->swapchainData->textureContainers[swapchainImageIndex].vulkanTexture->resourceAccessType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
VULKAN_INTERNAL_EndCommandBuffer(renderer, vulkanCommandBuffer);
|
||||||
|
|
||||||
|
vulkanCommandBuffer->autoReleaseFence = 1;
|
||||||
|
vulkanCommandBuffer->inFlightFence = VULKAN_INTERNAL_AcquireFenceFromPool(renderer);
|
||||||
|
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.pNext = NULL;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &vulkanCommandBuffer->commandBuffer;
|
||||||
|
|
||||||
|
submitInfo.pWaitDstStageMask = waitStages;
|
||||||
|
submitInfo.pWaitSemaphores = vulkanCommandBuffer->waitSemaphores;
|
||||||
|
submitInfo.waitSemaphoreCount = vulkanCommandBuffer->waitSemaphoreCount;
|
||||||
|
submitInfo.pSignalSemaphores = vulkanCommandBuffer->signalSemaphores;
|
||||||
|
submitInfo.signalSemaphoreCount = vulkanCommandBuffer->signalSemaphoreCount;
|
||||||
|
|
||||||
|
vulkanResult = renderer->vkQueueSubmit(
|
||||||
|
renderer->unifiedQueue,
|
||||||
|
1,
|
||||||
|
&submitInfo,
|
||||||
|
vulkanCommandBuffer->inFlightFence
|
||||||
|
);
|
||||||
|
|
||||||
|
if (vulkanResult != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
LogVulkanResultAsError("vkQueueSubmit", vulkanResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark command buffers as submitted */
|
||||||
|
|
||||||
|
if (renderer->submittedCommandBufferCount + 1 >= renderer->submittedCommandBufferCapacity)
|
||||||
|
{
|
||||||
|
renderer->submittedCommandBufferCapacity = renderer->submittedCommandBufferCount + 1;
|
||||||
|
|
||||||
|
renderer->submittedCommandBuffers = SDL_realloc(
|
||||||
|
renderer->submittedCommandBuffers,
|
||||||
|
sizeof(VulkanCommandBuffer*) * renderer->submittedCommandBufferCapacity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = vulkanCommandBuffer;
|
||||||
|
renderer->submittedCommandBufferCount += 1;
|
||||||
|
|
||||||
|
/* Present, if applicable */
|
||||||
|
|
||||||
|
for (j = 0; j < vulkanCommandBuffer->presentDataCount; j += 1)
|
||||||
|
{
|
||||||
|
presentData = &vulkanCommandBuffer->presentDatas[j];
|
||||||
|
|
||||||
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
|
presentInfo.pNext = NULL;
|
||||||
|
presentInfo.pWaitSemaphores = &presentData->windowData->swapchainData->renderFinishedSemaphore;
|
||||||
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
|
presentInfo.pSwapchains = &presentData->windowData->swapchainData->swapchain;
|
||||||
|
presentInfo.swapchainCount = 1;
|
||||||
|
presentInfo.pImageIndices = &presentData->swapchainImageIndex;
|
||||||
|
presentInfo.pResults = NULL;
|
||||||
|
|
||||||
|
presentResult = renderer->vkQueuePresentKHR(
|
||||||
|
renderer->unifiedQueue,
|
||||||
|
&presentInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
if (vulkanResult != VK_SUCCESS)
|
if (presentResult != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
LogVulkanResultAsError("vkQueueSubmit", vulkanResult);
|
VULKAN_INTERNAL_RecreateSwapchain(
|
||||||
}
|
renderer,
|
||||||
|
presentData->windowData
|
||||||
/* Mark command buffers as submitted */
|
|
||||||
|
|
||||||
if (renderer->submittedCommandBufferCount + 1 >= renderer->submittedCommandBufferCapacity)
|
|
||||||
{
|
|
||||||
renderer->submittedCommandBufferCapacity = renderer->submittedCommandBufferCount + 1;
|
|
||||||
|
|
||||||
renderer->submittedCommandBuffers = SDL_realloc(
|
|
||||||
renderer->submittedCommandBuffers,
|
|
||||||
sizeof(VulkanCommandBuffer*) * renderer->submittedCommandBufferCapacity
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = (VulkanCommandBuffer*) pCommandBuffers[i];
|
|
||||||
renderer->submittedCommandBufferCount += 1;
|
|
||||||
|
|
||||||
/* Present, if applicable */
|
|
||||||
|
|
||||||
for (j = 0; j < currentCommandBuffer->presentDataCount; j += 1)
|
|
||||||
{
|
|
||||||
presentData = ¤tCommandBuffer->presentDatas[j];
|
|
||||||
|
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
||||||
presentInfo.pNext = NULL;
|
|
||||||
presentInfo.pWaitSemaphores = &presentData->windowData->swapchainData->renderFinishedSemaphore;
|
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
|
||||||
presentInfo.pSwapchains = &presentData->windowData->swapchainData->swapchain;
|
|
||||||
presentInfo.swapchainCount = 1;
|
|
||||||
presentInfo.pImageIndices = &presentData->swapchainImageIndex;
|
|
||||||
presentInfo.pResults = NULL;
|
|
||||||
|
|
||||||
presentResult = renderer->vkQueuePresentKHR(
|
|
||||||
renderer->unifiedQueue,
|
|
||||||
&presentInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
if (presentResult != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
VULKAN_INTERNAL_RecreateSwapchain(
|
|
||||||
renderer,
|
|
||||||
presentData->windowData
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we can perform any cleanups */
|
/* Check if we can perform any cleanups */
|
||||||
|
@ -10670,8 +10737,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
||||||
|
|
||||||
VULKAN_Submit(
|
VULKAN_Submit(
|
||||||
(Refresh_Renderer*) renderer,
|
(Refresh_Renderer*) renderer,
|
||||||
1,
|
(Refresh_CommandBuffer*) commandBuffer
|
||||||
(Refresh_CommandBuffer**) &commandBuffer
|
|
||||||
);
|
);
|
||||||
|
|
||||||
renderer->defragInProgress = 0;
|
renderer->defragInProgress = 0;
|
||||||
|
@ -10679,6 +10745,63 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void VULKAN_WaitForFences(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
uint8_t waitAll,
|
||||||
|
uint32_t fenceCount,
|
||||||
|
Refresh_Fence **pFences
|
||||||
|
) {
|
||||||
|
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
|
||||||
|
VkResult result;
|
||||||
|
|
||||||
|
result = renderer->vkWaitForFences(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
fenceCount,
|
||||||
|
(VkFence*) pFences,
|
||||||
|
waitAll,
|
||||||
|
UINT64_MAX
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
LogVulkanResultAsError("vkWaitForFences", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int VULKAN_QueryFence(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
) {
|
||||||
|
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
|
||||||
|
VkResult result;
|
||||||
|
|
||||||
|
result = renderer->vkGetFenceStatus(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
(VkFence) fence
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result == VK_SUCCESS)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (result == VK_NOT_READY)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogVulkanResultAsError("vkGetFenceStatus", result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VULKAN_ReleaseFence(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
Refresh_Fence *fence
|
||||||
|
) {
|
||||||
|
VULKAN_INTERNAL_ReturnFenceToPool((VulkanRenderer*) driverData, (VkFence) fence);
|
||||||
|
}
|
||||||
|
|
||||||
/* Device instantiation */
|
/* Device instantiation */
|
||||||
|
|
||||||
static inline uint8_t CheckDeviceExtensions(
|
static inline uint8_t CheckDeviceExtensions(
|
||||||
|
@ -11966,6 +12089,16 @@ static Refresh_Device* VULKAN_CreateDevice(
|
||||||
renderer->transferBufferPool.availableBufferCount += 1;
|
renderer->transferBufferPool.availableBufferCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize fence pool */
|
||||||
|
|
||||||
|
renderer->fencePool.lock = SDL_CreateMutex();
|
||||||
|
|
||||||
|
renderer->fencePool.availableFenceCapacity = 4;
|
||||||
|
renderer->fencePool.availableFenceCount = 0;
|
||||||
|
renderer->fencePool.availableFences = SDL_malloc(
|
||||||
|
renderer->fencePool.availableFenceCapacity * sizeof(VkFence)
|
||||||
|
);
|
||||||
|
|
||||||
/* Some drivers don't support D16, so we have to fall back to D32. */
|
/* Some drivers don't support D16, so we have to fall back to D32. */
|
||||||
|
|
||||||
vulkanResult = renderer->vkGetPhysicalDeviceImageFormatProperties(
|
vulkanResult = renderer->vkGetPhysicalDeviceImageFormatProperties(
|
||||||
|
|
Loading…
Reference in New Issue