continue rewrite
continuous-integration/drone/push Build is passing Details

pull/14/head
cosmonaut 2022-02-24 12:01:35 -08:00
parent 44d510892c
commit 8d41e2a64a
5 changed files with 558 additions and 141 deletions

View File

@ -553,17 +553,18 @@ typedef struct Refresh_ComputePipelineCreateInfo
Refresh_ComputePipelineLayoutCreateInfo pipelineLayoutCreateInfo;
} Refresh_ComputePipelineCreateInfo;
typedef struct Refresh_AttachmentDescription
typedef struct Refresh_ColorAttachmentDescription
{
Refresh_TextureFormat format;
Refresh_SampleCount sampleCount;
} Refresh_AttachmentDescription;
} Refresh_ColorAttachmentDescription;
typedef struct Refresh_GraphicsPipelineAttachmentInfo
{
Refresh_AttachmentDescription colorAttachmentDescriptions[4];
Refresh_ColorAttachmentDescription colorAttachmentDescriptions[4];
uint32_t colorAttachmentCount;
Refresh_AttachmentDescription *depthStencilAttachmentDescription; /* Can be NULL */
uint8_t hasDepthStencilAttachment;
Refresh_TextureFormat depthStencilFormat;
} Refresh_GraphicsPipelineAttachmentInfo;
typedef struct Refresh_GraphicsPipelineCreateInfo
@ -1113,7 +1114,7 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline(
* The area affected by the render pass.
* All load, store and resolve operations are restricted
* to the given rectangle.
* pColorAttachmentInfos:
* colorAttachmentInfos:
* A pointer to an array of Refresh_ColorAttachmentInfo structures
* that contains render targets and clear values. May be NULL.
* colorAttachmentCount: The amount of structs in the above array.
@ -1123,7 +1124,7 @@ REFRESHAPI void Refresh_BeginRenderPass(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *pColorAttachmentInfos,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
);

View File

@ -613,7 +613,7 @@ void Refresh_BeginRenderPass(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *pColorAttachmentInfos,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
) {
@ -622,7 +622,7 @@ void Refresh_BeginRenderPass(
device->driverData,
commandBuffer,
renderArea,
pColorAttachmentInfos,
colorAttachmentInfos,
colorAttachmentCount,
depthStencilAttachmentInfo
);

View File

@ -397,7 +397,7 @@ struct Refresh_Device
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *pColorAttachmentInfos,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
);

View File

@ -553,7 +553,7 @@ static void TEMPLATE_BeginRenderPass(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *pColorAttachmentInfos,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
) {

View File

@ -998,11 +998,11 @@ static inline VkRenderPass RenderPassHashArray_Fetch(
RenderPassHashArray *arr,
RenderPassHash *key
) {
int32_t i, j;
int32_t i;
for (i = 0; i < arr->count; i += 1)
{
const RenderPassHash *e = &arr->elements[i].key;
RenderPassHash *e = &arr->elements[i].key;
if (RenderPassHash_Compare(e, key))
{
@ -1029,6 +1029,116 @@ static inline void RenderPassHashArray_Insert(
arr->count += 1;
}
typedef struct FramebufferHash
{
VkImageView colorAttachmentViews[MAX_COLOR_TARGET_BINDINGS];
VkImageView colorMultiSampleAttachmentViews[MAX_COLOR_TARGET_BINDINGS];
uint32_t colorAttachmentCount;
VkImageView depthStencilAttachmentView;
uint32_t width;
uint32_t height;
} FramebufferHash;
typedef struct FramebufferHashMap
{
FramebufferHash key;
VkFramebuffer value;
} FramebufferHashMap;
typedef struct FramebufferHashArray
{
FramebufferHashMap *elements;
int32_t count;
int32_t capacity;
} FramebufferHashArray;
static inline uint8_t FramebufferHash_Compare(
FramebufferHash *a,
FramebufferHash *b
) {
uint32_t i;
if (a->colorAttachmentCount != b->colorAttachmentCount)
{
return 0;
}
for (i = 0; i < a->colorAttachmentCount; i += 1)
{
if (a->colorAttachmentViews[i] != b->colorAttachmentViews[i])
{
return 0;
}
if (a->colorMultiSampleAttachmentViews[i] != b->colorMultiSampleAttachmentViews[i])
{
return 0;
}
}
if (a->depthStencilAttachmentView != b->depthStencilAttachmentView)
{
return 0;
}
if (a->width != b->width)
{
return 0;
}
if (a->height != b->height)
{
return 0;
}
return 1;
}
static inline VkFramebuffer FramebufferHashArray_Fetch(
FramebufferHashArray *arr,
FramebufferHash *key
) {
int32_t i;
for (i = 0; i < arr->count; i += 1)
{
FramebufferHash *e = &arr->elements[i].key;
if (FramebufferHash_Compare(e, key))
{
return arr->elements[i].value;
}
}
return VK_NULL_HANDLE;
}
static inline void FramebufferHashArray_Insert(
FramebufferHashArray *arr,
FramebufferHash key,
VkFramebuffer value
) {
FramebufferHashMap map;
map.key = key;
map.value = value;
EXPAND_ELEMENTS_IF_NEEDED(arr, 4, FramebufferHashMap)
arr->elements[arr->count] = map;
arr->count += 1;
}
static inline void FramebufferHashArray_Remove(
FramebufferHashArray *arr,
uint32_t index
) {
if (index != arr->count - 1)
{
arr->elements[index] = arr->elements[arr->count - 1];
}
arr->count -= 1;
}
/* Descriptor Set Caches */
struct DescriptorSetCache
@ -1424,6 +1534,7 @@ typedef struct VulkanRenderer
GraphicsPipelineLayoutHashTable graphicsPipelineLayoutHashTable;
ComputePipelineLayoutHashTable computePipelineLayoutHashTable;
RenderPassHashArray renderPassHashArray;
FramebufferHashArray framebufferHashArray;
VkDescriptorPool defaultDescriptorPool;
@ -1454,6 +1565,8 @@ typedef struct VulkanRenderer
SDL_mutex *submitLock;
SDL_mutex *acquireFenceLock;
SDL_mutex *acquireCommandBufferLock;
SDL_mutex *renderPassFetchLock;
SDL_mutex *framebufferFetchLock;
#define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \
vkfntype_##func func;
@ -2419,11 +2532,43 @@ static void VULKAN_INTERNAL_DestroyTexture(
static void VULKAN_INTERNAL_DestroyRenderTarget(
VulkanRenderer *renderer,
VulkanRenderTarget *renderTargetTarget
VulkanRenderTarget *renderTarget
) {
int32_t i, j;
FramebufferHash *hash;
SDL_LockMutex(renderer->framebufferFetchLock);
/* Remove all associated framebuffers */
for (i = renderer->framebufferHashArray.count; i >= 0; i -= 1)
{
hash = &renderer->framebufferHashArray.elements[i].key;
for (j = 0; j < hash->colorAttachmentCount; j += 1)
{
if (hash->colorAttachmentViews[i] == renderTarget->view)
{
renderer->vkDestroyFramebuffer(
renderer->logicalDevice,
renderer->framebufferHashArray.elements[i].value,
NULL
);
FramebufferHashArray_Remove(
&renderer->framebufferHashArray,
i
);
break;
}
}
}
SDL_UnlockMutex(renderer->framebufferFetchLock);
renderer->vkDestroyImageView(
renderer->logicalDevice,
renderTargetTarget->view,
renderTarget->view,
NULL
);
@ -2431,15 +2576,15 @@ static void VULKAN_INTERNAL_DestroyRenderTarget(
* so we don't free it here
* But the multisampleTexture is!
*/
if (renderTargetTarget->multisampleTexture != NULL)
if (renderTarget->multisampleTexture != NULL)
{
VULKAN_INTERNAL_DestroyTexture(
renderer,
renderTargetTarget->multisampleTexture
renderTarget->multisampleTexture
);
}
SDL_free(renderTargetTarget);
SDL_free(renderTarget);
}
static void VULKAN_INTERNAL_DestroyBuffer(
@ -2563,17 +2708,6 @@ static void VULKAN_INTERNAL_DestroySampler(
);
}
static void VULKAN_INTERNAL_DestroyRenderPass(
VulkanRenderer *renderer,
VkRenderPass renderPass
) {
renderer->vkDestroyRenderPass(
renderer->logicalDevice,
renderPass,
NULL
);
}
static void VULKAN_INTERNAL_DestroySwapchain(
VulkanRenderer* renderer,
void *windowHandle
@ -4286,6 +4420,8 @@ static void VULKAN_DestroyDevice(
SDL_DestroyMutex(renderer->submitLock);
SDL_DestroyMutex(renderer->acquireFenceLock);
SDL_DestroyMutex(renderer->acquireCommandBufferLock);
SDL_DestroyMutex(renderer->renderPassFetchLock);
SDL_DestroyMutex(renderer->framebufferFetchLock);
renderer->vkDestroyDevice(renderer->logicalDevice, NULL);
renderer->vkDestroyInstance(renderer->instance, NULL);
@ -4531,9 +4667,7 @@ static void VULKAN_DispatchCompute(
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline;
VulkanBuffer *currentBuffer;
VkDescriptorSet descriptorSets[3];
uint32_t i;
descriptorSets[0] = vulkanCommandBuffer->bufferDescriptorSet;
descriptorSets[1] = vulkanCommandBuffer->imageDescriptorSet;
@ -4560,7 +4694,7 @@ static void VULKAN_DispatchCompute(
static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
VulkanRenderer *renderer,
Refresh_ColorAttachmentInfo *pColorAttachmentInfos,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
) {
@ -4569,7 +4703,7 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
VkAttachmentReference colorAttachmentReferences[MAX_COLOR_TARGET_BINDINGS];
VkAttachmentReference resolveReferences[MAX_COLOR_TARGET_BINDINGS + 1];
VkAttachmentReference depthStencilAttachmentReference;
VkRenderPassCreateInfo vkRenderPassCreateInfo;
VkRenderPassCreateInfo renderPassCreateInfo;
VkSubpassDescription subpass;
VkRenderPass renderPass;
uint32_t i;
@ -4584,7 +4718,7 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
for (i = 0; i < colorAttachmentCount; i += 1)
{
colorTarget = (VulkanRenderTarget*) pColorAttachmentInfos[attachmentDescriptionCount].pRenderTarget;
colorTarget = (VulkanRenderTarget*) colorAttachmentInfos[attachmentDescriptionCount].pRenderTarget;
if (colorTarget->multisampleCount > VK_SAMPLE_COUNT_1_BIT)
{
@ -4597,10 +4731,10 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
attachmentDescriptions[attachmentDescriptionCount].samples =
VK_SAMPLE_COUNT_1_BIT;
attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[
pColorAttachmentInfos[i].loadOp
colorAttachmentInfos[i].loadOp
];
attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[
pColorAttachmentInfos[i].storeOp
colorAttachmentInfos[i].storeOp
];
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp =
VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -4623,10 +4757,10 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
attachmentDescriptions[attachmentDescriptionCount].format = colorTarget->texture->format;
attachmentDescriptions[attachmentDescriptionCount].samples = colorTarget->multisampleCount;
attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[
pColorAttachmentInfos[i].loadOp
colorAttachmentInfos[i].loadOp
];
attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[
pColorAttachmentInfos[i].storeOp
colorAttachmentInfos[i].storeOp
];
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp =
VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -4652,10 +4786,10 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
attachmentDescriptions[attachmentDescriptionCount].samples =
VK_SAMPLE_COUNT_1_BIT;
attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[
pColorAttachmentInfos[i].loadOp
colorAttachmentInfos[i].loadOp
];
attachmentDescriptions[attachmentDescriptionCount].storeOp = RefreshToVK_StoreOp[
pColorAttachmentInfos[i].storeOp
colorAttachmentInfos[i].storeOp
];
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp =
VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -4666,12 +4800,12 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
attachmentDescriptions[attachmentDescriptionCount].finalLayout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptionCount += 1;
colorAttachmentReferences[colorAttachmentReferenceCount].attachment = i;
colorAttachmentReferences[colorAttachmentReferenceCount].attachment = attachmentDescriptionCount;
colorAttachmentReferences[colorAttachmentReferenceCount].layout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptionCount += 1;
colorAttachmentReferenceCount += 1;
}
}
@ -4733,32 +4867,207 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
subpass.pResolveAttachments = NULL;
}
vkRenderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
vkRenderPassCreateInfo.pNext = NULL;
vkRenderPassCreateInfo.flags = 0;
vkRenderPassCreateInfo.pAttachments = attachmentDescriptions;
vkRenderPassCreateInfo.attachmentCount = attachmentDescriptionCount;
vkRenderPassCreateInfo.subpassCount = 1;
vkRenderPassCreateInfo.pSubpasses = &subpass;
vkRenderPassCreateInfo.dependencyCount = 0;
vkRenderPassCreateInfo.pDependencies = NULL;
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.pNext = NULL;
renderPassCreateInfo.flags = 0;
renderPassCreateInfo.pAttachments = attachmentDescriptions;
renderPassCreateInfo.attachmentCount = attachmentDescriptionCount;
renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subpass;
renderPassCreateInfo.dependencyCount = 0;
renderPassCreateInfo.pDependencies = NULL;
vulkanResult = renderer->vkCreateRenderPass(
renderer->logicalDevice,
&vkRenderPassCreateInfo,
&renderPassCreateInfo,
NULL,
&renderPass
);
if (vulkanResult != VK_SUCCESS)
{
renderPass = VK_NULL_HANDLE;
LogVulkanResultAsError("vkCreateRenderPass", vulkanResult);
return VK_NULL_HANDLE;
}
return renderPass;
}
static VkRenderPass VULKAN_INTERNAL_CreateTransientRenderPass(
VulkanRenderer *renderer,
Refresh_GraphicsPipelineAttachmentInfo attachmentInfo
) {
VkAttachmentDescription attachmentDescriptions[2 * MAX_COLOR_TARGET_BINDINGS + 1];
VkAttachmentReference colorAttachmentReferences[MAX_COLOR_TARGET_BINDINGS];
VkAttachmentReference resolveReferences[MAX_COLOR_TARGET_BINDINGS + 1];
VkAttachmentReference depthStencilAttachmentReference;
Refresh_ColorAttachmentDescription attachmentDescription;
VkSubpassDescription subpass;
VkRenderPassCreateInfo renderPassCreateInfo;
VkRenderPass renderPass;
VkResult result;
uint32_t multisampling = 0;
uint32_t attachmentDescriptionCount = 0;
uint32_t colorAttachmentReferenceCount = 0;
uint32_t resolveReferenceCount = 0;
uint32_t i;
for (i = 0; i < attachmentInfo.colorAttachmentCount; i += 1)
{
attachmentDescription = attachmentInfo.colorAttachmentDescriptions[i];
if (attachmentDescription.sampleCount > REFRESH_SAMPLECOUNT_1)
{
multisampling = 1;
/* Resolve attachment and multisample attachment */
attachmentDescriptions[attachmentDescriptionCount].flags = 0;
attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[
attachmentDescription.format
];
attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
resolveReferences[resolveReferenceCount].attachment = attachmentDescriptionCount;
resolveReferences[resolveReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptionCount += 1;
resolveReferenceCount += 1;
attachmentDescriptions[attachmentDescriptionCount].flags = 0;
attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[
attachmentDescription.format
];
attachmentDescriptions[attachmentDescriptionCount].samples = VK_SAMPLE_COUNT_1_BIT;
attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorAttachmentReferences[colorAttachmentReferenceCount].attachment =
attachmentDescriptionCount;
colorAttachmentReferences[colorAttachmentReferenceCount].layout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptionCount += 1;
colorAttachmentReferenceCount += 1;
}
else
{
attachmentDescriptions[attachmentDescriptionCount].flags = 0;
attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[
attachmentDescription.format
];
attachmentDescriptions[attachmentDescriptionCount].samples =
VK_SAMPLE_COUNT_1_BIT;
attachmentDescriptions[attachmentDescriptionCount].loadOp =
VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].storeOp =
VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp =
VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp =
VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].initialLayout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptions[attachmentDescriptionCount].finalLayout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorAttachmentReferences[colorAttachmentReferenceCount].attachment = attachmentDescriptionCount;
colorAttachmentReferences[colorAttachmentReferenceCount].layout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptionCount += 1;
colorAttachmentReferenceCount += 1;
}
}
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.flags = 0;
subpass.inputAttachmentCount = 0;
subpass.pInputAttachments = NULL;
subpass.colorAttachmentCount = attachmentInfo.colorAttachmentCount;
subpass.pColorAttachments = colorAttachmentReferences;
subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = NULL;
if (attachmentInfo.hasDepthStencilAttachment)
{
attachmentDescriptions[attachmentDescriptionCount].flags = 0;
attachmentDescriptions[attachmentDescriptionCount].format = RefreshToVK_SurfaceFormat[
attachmentInfo.depthStencilFormat
];
attachmentDescriptions[attachmentDescriptionCount].samples =
VK_SAMPLE_COUNT_1_BIT; /* FIXME: do these take multisamples? */
attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].initialLayout =
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachmentDescriptions[attachmentDescriptionCount].finalLayout =
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
depthStencilAttachmentReference.attachment =
attachmentDescriptionCount;
depthStencilAttachmentReference.layout =
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
subpass.pDepthStencilAttachment =
&depthStencilAttachmentReference;
attachmentDescriptionCount += 1;
}
else
{
subpass.pDepthStencilAttachment = NULL;
}
if (multisampling)
{
subpass.pResolveAttachments = resolveReferences;
}
else
{
subpass.pResolveAttachments = NULL;
}
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.pNext = NULL;
renderPassCreateInfo.flags = 0;
renderPassCreateInfo.pAttachments = attachmentDescriptions;
renderPassCreateInfo.attachmentCount = attachmentDescriptionCount;
renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subpass;
renderPassCreateInfo.dependencyCount = 0;
renderPassCreateInfo.pDependencies = NULL;
result = renderer->vkCreateRenderPass(
renderer->logicalDevice,
&renderPassCreateInfo,
NULL,
&renderPass
);
if (result != VK_SUCCESS)
{
renderPass = VK_NULL_HANDLE;
LogVulkanResultAsError("vkCreateRenderPass", result);
}
return renderPass;
}
static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
Refresh_Renderer *driverData,
Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo
@ -4797,6 +5106,13 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
/* Create a "compatible" render pass */
VkRenderPass transientRenderPass = VULKAN_INTERNAL_CreateTransientRenderPass(
renderer,
pipelineCreateInfo->attachmentInfo
);
/* Shader stages */
shaderStageCreateInfos[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -5074,7 +5390,7 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
vkPipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo;
vkPipelineCreateInfo.pDynamicState = VK_NULL_HANDLE;
vkPipelineCreateInfo.layout = graphicsPipeline->pipelineLayout->pipelineLayout;
vkPipelineCreateInfo.renderPass = (VkRenderPass) pipelineCreateInfo->renderPass;
vkPipelineCreateInfo.renderPass = transientRenderPass;
vkPipelineCreateInfo.subpass = 0;
vkPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
vkPipelineCreateInfo.basePipelineIndex = 0;
@ -5095,6 +5411,12 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
SDL_stack_free(scissors);
SDL_stack_free(colorBlendAttachmentStates);
renderer->vkDestroyRenderPass(
renderer->logicalDevice,
transientRenderPass,
NULL
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResultAsError("vkCreateGraphicsPipelines", vulkanResult);
@ -5325,71 +5647,6 @@ static Refresh_Sampler* VULKAN_CreateSampler(
return (Refresh_Sampler*) sampler;
}
static VkFramebuffer VULKAN_INTERNAL_CreateFramebuffer(
Refresh_Renderer *driverData,
VkRenderPass renderPass,
uint32_t width,
uint32_t height,
VulkanRenderTarget **colorTargets,
uint32_t colorTargetCount,
VulkanRenderTarget *depthStencilTarget /* Can be NULL */
) {
VkResult vulkanResult;
VkFramebuffer framebuffer;
VkFramebufferCreateInfo vkFramebufferCreateInfo;
VkImageView *imageViews;
uint32_t colorAttachmentCount = colorTargetCount;
uint32_t attachmentCount = colorAttachmentCount;
uint32_t i;
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
if (depthStencilTarget != NULL)
{
attachmentCount += 1;
}
imageViews = SDL_stack_alloc(VkImageView, attachmentCount);
for (i = 0; i < colorAttachmentCount; i += 1)
{
imageViews[i] = ((VulkanRenderTarget*)colorTargets[i])->view;
}
if (depthStencilTarget != NULL)
{
imageViews[colorAttachmentCount] = ((VulkanRenderTarget*)depthStencilTarget)->view;
}
vkFramebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
vkFramebufferCreateInfo.pNext = NULL;
vkFramebufferCreateInfo.flags = 0;
vkFramebufferCreateInfo.renderPass = renderPass;
vkFramebufferCreateInfo.attachmentCount = attachmentCount;
vkFramebufferCreateInfo.pAttachments = imageViews;
vkFramebufferCreateInfo.width = width;
vkFramebufferCreateInfo.height = height;
vkFramebufferCreateInfo.layers = 1;
vulkanResult = renderer->vkCreateFramebuffer(
renderer->logicalDevice,
&vkFramebufferCreateInfo,
NULL,
&framebuffer
);
SDL_stack_free(imageViews);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResultAsError("vkCreateFramebuffer", vulkanResult);
return VK_NULL_HANDLE;
}
return framebuffer;
}
static Refresh_ShaderModule* VULKAN_CreateShaderModule(
Refresh_Renderer *driverData,
Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo
@ -7072,7 +7329,7 @@ static void VULKAN_QueueDestroyGraphicsPipeline(
static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
VulkanRenderer *renderer,
Refresh_ColorAttachmentInfo *pColorAttachmentInfos,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
) {
@ -7080,11 +7337,13 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
RenderPassHash hash;
uint32_t i;
SDL_LockMutex(renderer->renderPassFetchLock);
for (i = 0; i < colorAttachmentCount; i += 1)
{
hash.colorTargetDescriptions[i].clearColor = pColorAttachmentInfos[i].clearColor;
hash.colorTargetDescriptions[i].loadOp = pColorAttachmentInfos[i].loadOp;
hash.colorTargetDescriptions[i].storeOp = pColorAttachmentInfos[i].storeOp;
hash.colorTargetDescriptions[i].clearColor = colorAttachmentInfos[i].clearColor;
hash.colorTargetDescriptions[i].loadOp = colorAttachmentInfos[i].loadOp;
hash.colorTargetDescriptions[i].storeOp = colorAttachmentInfos[i].storeOp;
}
if (depthStencilAttachmentInfo == NULL)
@ -7109,30 +7368,170 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
if (renderPass != VK_NULL_HANDLE)
{
SDL_UnlockMutex(renderer->renderPassFetchLock);
return renderPass;
}
renderPass = VULKAN_INTERNAL_CreateRenderPass(
renderer,
pColorAttachmentInfos,
colorAttachmentInfos,
colorAttachmentCount,
depthStencilAttachmentInfo
);
RenderPassHashArray_Insert(
&renderer->renderPassHashArray,
hash,
renderPass
if (renderPass != VK_NULL_HANDLE)
{
RenderPassHashArray_Insert(
&renderer->renderPassHashArray,
hash,
renderPass
);
}
SDL_UnlockMutex(renderer->renderPassFetchLock);
return renderPass;
}
static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer(
VulkanRenderer *renderer,
VkRenderPass renderPass,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
) {
VkFramebuffer framebuffer;
VkFramebufferCreateInfo framebufferInfo;
VkResult result;
VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1];
FramebufferHash hash;
VulkanRenderTarget *renderTarget;
uint32_t attachmentCount = 0;
uint32_t i;
SDL_LockMutex(renderer->framebufferFetchLock);
for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{
hash.colorAttachmentViews[i] = VK_NULL_HANDLE;
hash.colorMultiSampleAttachmentViews[i] = VK_NULL_HANDLE;
}
hash.colorAttachmentCount = colorAttachmentCount;
for (i = 0; i < colorAttachmentCount; i += 1)
{
renderTarget = (VulkanRenderTarget*) colorAttachmentInfos[i].pRenderTarget;
hash.colorAttachmentViews[i] = (
renderTarget->view
);
hash.colorMultiSampleAttachmentViews[i] = (
renderTarget->multisampleTexture->view
);
}
if (depthStencilAttachmentInfo == NULL)
{
hash.depthStencilAttachmentView = VK_NULL_HANDLE;
}
else
{
hash.depthStencilAttachmentView = ((VulkanRenderTarget*)depthStencilAttachmentInfo->pDepthStencilTarget)->view;
}
if (colorAttachmentCount > 0)
{
renderTarget = (VulkanRenderTarget*) colorAttachmentInfos[0].pRenderTarget;
}
else
{
renderTarget = (VulkanRenderTarget*) depthStencilAttachmentInfo->pDepthStencilTarget;
}
hash.width = renderTarget->texture->dimensions.width;
hash.height = renderTarget->texture->dimensions.height;
framebuffer = FramebufferHashArray_Fetch(
&renderer->framebufferHashArray,
&hash
);
return renderPass;
if (framebuffer != VK_NULL_HANDLE)
{
SDL_UnlockMutex(renderer->framebufferFetchLock);
return framebuffer;
}
/* Create a new framebuffer */
for (i = 0; i < colorAttachmentCount; i += 1)
{
renderTarget = (VulkanRenderTarget*) colorAttachmentInfos[i].pRenderTarget;
imageViewAttachments[attachmentCount] =
renderTarget->view;
attachmentCount += 1;
if (renderTarget->multisampleCount > VK_SAMPLE_COUNT_1_BIT)
{
imageViewAttachments[attachmentCount] =
renderTarget->multisampleTexture->view;
attachmentCount += 1;
}
}
if (depthStencilAttachmentInfo != NULL)
{
renderTarget = (VulkanRenderTarget*) depthStencilAttachmentInfo->pDepthStencilTarget;
imageViewAttachments[attachmentCount] = renderTarget->view;
attachmentCount += 1;
}
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.pNext = NULL;
framebufferInfo.flags = 0;
framebufferInfo.renderPass = renderPass;
framebufferInfo.attachmentCount = attachmentCount;
framebufferInfo.pAttachments = imageViewAttachments;
framebufferInfo.width = hash.width;
framebufferInfo.height = hash.height;
framebufferInfo.layers = 1;
result = renderer->vkCreateFramebuffer(
renderer->logicalDevice,
&framebufferInfo,
NULL,
&framebuffer
);
if (result == VK_SUCCESS)
{
FramebufferHashArray_Insert(
&renderer->framebufferHashArray,
hash,
framebuffer
);
}
else
{
LogVulkanResultAsError("vkCreateFramebuffer", result);
framebuffer = VK_NULL_HANDLE;
}
SDL_UnlockMutex(renderer->framebufferFetchLock);
return framebuffer;
}
static void VULKAN_BeginRenderPass(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *pColorAttachmentInfos,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
) {
@ -7141,27 +7540,38 @@ static void VULKAN_BeginRenderPass(
VkRenderPass renderPass;
VkFramebuffer framebuffer;
VulkanRenderTarget *colorTarget;
VulkanRenderTarget *depthStencilTarget;
VkClearValue *clearValues;
uint32_t clearCount = colorAttachmentCount;
uint32_t i;
VkImageAspectFlags depthAspectFlags;
if (colorAttachmentCount == 0 && depthStencilAttachmentInfo == NULL)
{
Refresh_LogError("Render pass must have at least one render target!");
return;
}
renderPass = VULKAN_INTERNAL_FetchRenderPass(
renderer,
pColorAttachmentInfos,
colorAttachmentInfos,
colorAttachmentCount,
depthStencilAttachmentInfo
);
framebuffer = VULKAN_INTERNAL_FetchFramebuffer(renderer);
framebuffer = VULKAN_INTERNAL_FetchFramebuffer(
renderer,
renderPass,
colorAttachmentInfos,
colorAttachmentCount,
depthStencilAttachmentInfo
);
/* Layout transitions */
for (i = 0; i < colorAttachmentCount; i += 1)
{
VulkanRenderTarget *colorTarget = (VulkanRenderTarget*) pColorAttachmentInfos->pRenderTarget;
VulkanRenderTarget *colorTarget = (VulkanRenderTarget*) colorAttachmentInfos->pRenderTarget;
VULKAN_INTERNAL_ImageMemoryBarrier(
renderer,
@ -7212,10 +7622,10 @@ static void VULKAN_BeginRenderPass(
for (i = 0; i < colorAttachmentCount; i += 1)
{
clearValues[i].color.float32[0] = pColorAttachmentInfos[i].clearColor.x;
clearValues[i].color.float32[1] = pColorAttachmentInfos[i].clearColor.y;
clearValues[i].color.float32[2] = pColorAttachmentInfos[i].clearColor.z;
clearValues[i].color.float32[3] = pColorAttachmentInfos[i].clearColor.w;
clearValues[i].color.float32[0] = colorAttachmentInfos[i].clearColor.x;
clearValues[i].color.float32[1] = colorAttachmentInfos[i].clearColor.y;
clearValues[i].color.float32[2] = colorAttachmentInfos[i].clearColor.z;
clearValues[i].color.float32[3] = colorAttachmentInfos[i].clearColor.w;
}
if (depthStencilAttachmentInfo != NULL)
@ -7255,9 +7665,6 @@ static void VULKAN_EndRenderPass(
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanTexture *currentTexture;
VkImageAspectFlags depthAspectFlags;
uint32_t i;
renderer->vkCmdEndRenderPass(
vulkanCommandBuffer->commandBuffer
@ -7797,7 +8204,6 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer(
uint8_t fixed
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
uint32_t i;
SDL_threadID threadID = SDL_ThreadID();
@ -9245,6 +9651,8 @@ static Refresh_Device* VULKAN_CreateDevice(
renderer->submitLock = SDL_CreateMutex();
renderer->acquireFenceLock = SDL_CreateMutex();
renderer->acquireCommandBufferLock = SDL_CreateMutex();
renderer->renderPassFetchLock = SDL_CreateMutex();
renderer->framebufferFetchLock = SDL_CreateMutex();
/* Create fence lists */
@ -9552,6 +9960,14 @@ static Refresh_Device* VULKAN_CreateDevice(
renderer->descriptorSetLayoutHashTable.buckets[i].capacity = 0;
}
renderer->renderPassHashArray.elements = NULL;
renderer->renderPassHashArray.count = 0;
renderer->renderPassHashArray.capacity = 0;
renderer->framebufferHashArray.elements = NULL;
renderer->framebufferHashArray.count = 0;
renderer->framebufferHashArray.capacity = 0;
/* Initialize transfer buffer pool */
renderer->transferBufferPool.lock = SDL_CreateMutex();