Compare commits

..

2 Commits

Author SHA1 Message Date
Caleb Cornett 2f9c8aed3b add msaa support for depth textures 2023-01-30 22:48:38 -05:00
TheSpydog 6439516835 ABI break: Textures now have a sample count, not render passes (#37)
This change makes Refresh behave more like FNA and other rendering APIs, where user-side textures have a sample count instead of generating MSAA RTs on the fly.

This should theoretically reduce memory consumption since subresource views no longer generate their own MSAA textures. Instead, each texture with a sample count > 1 now has a reference to an MSAA texture baked into the root texture itself, so views can just reference that.

This also simplifies VulkanRenderTarget significantly, to the point where it's just a wrapper around VkImageView. We could probably remove the abstraction entirely at this point.

Since VkRenderPass objects still require knowing the sample count, we can use the first bound texture's sample count. This means users only have to specify sample count in two places -- the graphics pipeline, and the texture. Easy enough.

I also noticed and fixed a bug with clear values with MSAA levels > 1.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#37
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-30 18:22:16 +00:00
2 changed files with 139 additions and 138 deletions

View File

@ -463,6 +463,7 @@ typedef struct Refresh_TextureCreateInfo
uint32_t depth; uint32_t depth;
uint8_t isCube; uint8_t isCube;
uint32_t levelCount; uint32_t levelCount;
Refresh_SampleCount sampleCount;
Refresh_TextureFormat format; Refresh_TextureFormat format;
Refresh_TextureUsageFlags usageFlags; Refresh_TextureUsageFlags usageFlags;
} Refresh_TextureCreateInfo; } Refresh_TextureCreateInfo;
@ -551,7 +552,6 @@ typedef struct Refresh_ColorAttachmentInfo
uint32_t depth; uint32_t depth;
uint32_t layer; uint32_t layer;
uint32_t level; uint32_t level;
Refresh_SampleCount sampleCount;
Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */ Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */
Refresh_LoadOp loadOp; Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp; Refresh_StoreOp storeOp;

View File

@ -758,20 +758,21 @@ typedef struct VulkanTexture
uint32_t depth; uint32_t depth;
uint32_t layerCount; uint32_t layerCount;
uint32_t levelCount; uint32_t levelCount;
Refresh_SampleCount sampleCount;
VkFormat format; VkFormat format;
VulkanResourceAccessType resourceAccessType; VulkanResourceAccessType resourceAccessType;
VkImageUsageFlags usageFlags; VkImageUsageFlags usageFlags;
VkImageAspectFlags aspectFlags; VkImageAspectFlags aspectFlags;
struct VulkanTexture *msaaTex;
SDL_atomic_t referenceCount; SDL_atomic_t referenceCount;
} VulkanTexture; } VulkanTexture;
typedef struct VulkanRenderTarget typedef struct VulkanRenderTarget
{ {
VkImageView view; VkImageView view;
VulkanTexture *multisampleTexture;
VkSampleCountFlags multisampleCount;
} VulkanRenderTarget; } VulkanRenderTarget;
typedef struct VulkanFramebuffer typedef struct VulkanFramebuffer
@ -1200,11 +1201,10 @@ static inline void FramebufferHashArray_Remove(
typedef struct RenderTargetHash typedef struct RenderTargetHash
{ {
Refresh_Texture *texture; VulkanTexture *texture;
uint32_t depth; uint32_t depth;
uint32_t layer; uint32_t layer;
uint32_t level; uint32_t level;
Refresh_SampleCount sampleCount;
} RenderTargetHash; } RenderTargetHash;
typedef struct RenderTargetHashMap typedef struct RenderTargetHashMap
@ -1244,11 +1244,6 @@ static inline uint8_t RenderTargetHash_Compare(
return 0; return 0;
} }
if (a->sampleCount != b->sampleCount)
{
return 0;
}
return 1; return 1;
} }
@ -3068,6 +3063,15 @@ static void VULKAN_INTERNAL_DestroyTexture(
NULL NULL
); );
/* destroy the msaa texture, if there is one */
if (texture->msaaTex != NULL)
{
VULKAN_INTERNAL_DestroyTexture(
renderer,
texture->msaaTex
);
}
SDL_free(texture); SDL_free(texture);
} }
@ -3086,18 +3090,6 @@ static void VULKAN_INTERNAL_DestroyRenderTarget(
NULL NULL
); );
/* The texture is not owned by the RenderTarget
* so we don't free it here
* But the multisampleTexture is!
*/
if (renderTarget->multisampleTexture != NULL)
{
VULKAN_INTERNAL_DestroyTexture(
renderer,
renderTarget->multisampleTexture
);
}
SDL_free(renderTarget); SDL_free(renderTarget);
} }
@ -4605,11 +4597,13 @@ static uint8_t VULKAN_INTERNAL_CreateSwapchain(
swapchainData->textures[i].isCube = 0; swapchainData->textures[i].isCube = 0;
swapchainData->textures[i].layerCount = 1; swapchainData->textures[i].layerCount = 1;
swapchainData->textures[i].levelCount = 1; swapchainData->textures[i].levelCount = 1;
swapchainData->textures[i].sampleCount = REFRESH_SAMPLECOUNT_1;
swapchainData->textures[i].usageFlags = swapchainData->textures[i].usageFlags =
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
swapchainData->textures[i].aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; swapchainData->textures[i].aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
swapchainData->textures[i].resourceAccessType = RESOURCE_ACCESS_NONE; swapchainData->textures[i].resourceAccessType = RESOURCE_ACCESS_NONE;
swapchainData->textures[i].msaaTex = NULL;
} }
SDL_stack_free(swapchainImages); SDL_stack_free(swapchainImages);
@ -5217,8 +5211,8 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture(
uint32_t height, uint32_t height,
uint32_t depth, uint32_t depth,
uint32_t isCube, uint32_t isCube,
VkSampleCountFlagBits samples,
uint32_t levelCount, uint32_t levelCount,
Refresh_SampleCount sampleCount,
VkFormat format, VkFormat format,
VkImageAspectFlags aspectMask, VkImageAspectFlags aspectMask,
VkImageUsageFlags imageUsageFlags VkImageUsageFlags imageUsageFlags
@ -5261,7 +5255,7 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture(
imageCreateInfo.extent.depth = depth; imageCreateInfo.extent.depth = depth;
imageCreateInfo.mipLevels = levelCount; imageCreateInfo.mipLevels = levelCount;
imageCreateInfo.arrayLayers = layerCount; imageCreateInfo.arrayLayers = layerCount;
imageCreateInfo.samples = samples; imageCreateInfo.samples = RefreshToVK_SampleCount[sampleCount];
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = imageUsageFlags; imageCreateInfo.usage = imageUsageFlags;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
@ -5388,9 +5382,11 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture(
texture->format = format; texture->format = format;
texture->levelCount = levelCount; texture->levelCount = levelCount;
texture->layerCount = layerCount; texture->layerCount = layerCount;
texture->sampleCount = sampleCount;
texture->resourceAccessType = RESOURCE_ACCESS_NONE; texture->resourceAccessType = RESOURCE_ACCESS_NONE;
texture->usageFlags = imageUsageFlags; texture->usageFlags = imageUsageFlags;
texture->aspectFlags = aspectMask; texture->aspectFlags = aspectMask;
texture->msaaTex = NULL;
SDL_AtomicSet(&texture->referenceCount, 0); SDL_AtomicSet(&texture->referenceCount, 0);
@ -5399,27 +5395,22 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture(
static VulkanRenderTarget* VULKAN_INTERNAL_CreateRenderTarget( static VulkanRenderTarget* VULKAN_INTERNAL_CreateRenderTarget(
VulkanRenderer *renderer, VulkanRenderer *renderer,
Refresh_Texture *texture, VulkanTexture *texture,
uint32_t depth, uint32_t depth,
uint32_t layer, uint32_t layer,
uint32_t level, uint32_t level
Refresh_SampleCount multisampleCount
) { ) {
VkResult vulkanResult; VkResult vulkanResult;
VulkanRenderTarget *renderTarget = (VulkanRenderTarget*) SDL_malloc(sizeof(VulkanRenderTarget)); VulkanRenderTarget *renderTarget = (VulkanRenderTarget*) SDL_malloc(sizeof(VulkanRenderTarget));
VulkanTexture *vulkanTexture = (VulkanTexture*) texture;
VkImageViewCreateInfo imageViewCreateInfo; VkImageViewCreateInfo imageViewCreateInfo;
VkComponentMapping swizzle = IDENTITY_SWIZZLE; VkComponentMapping swizzle = IDENTITY_SWIZZLE;
VkImageAspectFlags aspectFlags = 0; VkImageAspectFlags aspectFlags = 0;
renderTarget->multisampleTexture = NULL; if (IsDepthFormat(texture->format))
renderTarget->multisampleCount = 1;
if (IsDepthFormat(vulkanTexture->format))
{ {
aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT; aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
if (IsStencilFormat(vulkanTexture->format)) if (IsStencilFormat(texture->format))
{ {
aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
} }
@ -5429,48 +5420,22 @@ static VulkanRenderTarget* VULKAN_INTERNAL_CreateRenderTarget(
aspectFlags |= VK_IMAGE_ASPECT_COLOR_BIT; aspectFlags |= VK_IMAGE_ASPECT_COLOR_BIT;
} }
/* create resolve target for multisample */
if (multisampleCount > REFRESH_SAMPLECOUNT_1)
{
/* Find a compatible sample count to use */
multisampleCount = VULKAN_INTERNAL_GetMaxMultiSampleCount(
renderer,
multisampleCount
);
renderTarget->multisampleTexture =
VULKAN_INTERNAL_CreateTexture(
renderer,
vulkanTexture->dimensions.width,
vulkanTexture->dimensions.height,
1,
0,
RefreshToVK_SampleCount[multisampleCount],
1,
vulkanTexture->format,
aspectFlags,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
);
renderTarget->multisampleCount = RefreshToVK_SampleCount[multisampleCount];
}
/* create framebuffer compatible views for RenderTarget */ /* create framebuffer compatible views for RenderTarget */
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.pNext = NULL; imageViewCreateInfo.pNext = NULL;
imageViewCreateInfo.flags = 0; imageViewCreateInfo.flags = 0;
imageViewCreateInfo.image = vulkanTexture->image; imageViewCreateInfo.image = texture->image;
imageViewCreateInfo.format = vulkanTexture->format; imageViewCreateInfo.format = texture->format;
imageViewCreateInfo.components = swizzle; imageViewCreateInfo.components = swizzle;
imageViewCreateInfo.subresourceRange.aspectMask = aspectFlags; imageViewCreateInfo.subresourceRange.aspectMask = aspectFlags;
imageViewCreateInfo.subresourceRange.baseMipLevel = level; imageViewCreateInfo.subresourceRange.baseMipLevel = level;
imageViewCreateInfo.subresourceRange.levelCount = 1; imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0; imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
if (vulkanTexture->is3D) if (texture->is3D)
{ {
imageViewCreateInfo.subresourceRange.baseArrayLayer = depth; imageViewCreateInfo.subresourceRange.baseArrayLayer = depth;
} }
else if (vulkanTexture->isCube) else if (texture->isCube)
{ {
imageViewCreateInfo.subresourceRange.baseArrayLayer = layer; imageViewCreateInfo.subresourceRange.baseArrayLayer = layer;
} }
@ -5499,11 +5464,10 @@ static VulkanRenderTarget* VULKAN_INTERNAL_CreateRenderTarget(
static VulkanRenderTarget* VULKAN_INTERNAL_FetchRenderTarget( static VulkanRenderTarget* VULKAN_INTERNAL_FetchRenderTarget(
VulkanRenderer *renderer, VulkanRenderer *renderer,
Refresh_Texture *texture, VulkanTexture *texture,
uint32_t depth, uint32_t depth,
uint32_t layer, uint32_t layer,
uint32_t level, uint32_t level
Refresh_SampleCount sampleCount
) { ) {
RenderTargetHash hash; RenderTargetHash hash;
VulkanRenderTarget *renderTarget; VulkanRenderTarget *renderTarget;
@ -5512,7 +5476,6 @@ static VulkanRenderTarget* VULKAN_INTERNAL_FetchRenderTarget(
hash.depth = depth; hash.depth = depth;
hash.layer = layer; hash.layer = layer;
hash.level = level; hash.level = level;
hash.sampleCount = sampleCount;
SDL_LockMutex(renderer->renderTargetFetchLock); SDL_LockMutex(renderer->renderTargetFetchLock);
@ -5528,8 +5491,7 @@ static VulkanRenderTarget* VULKAN_INTERNAL_FetchRenderTarget(
texture, texture,
depth, depth,
layer, layer,
level, level
sampleCount
); );
RenderTargetHash_Insert( RenderTargetHash_Insert(
@ -5560,31 +5522,21 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
VkSubpassDescription subpass; VkSubpassDescription subpass;
VkRenderPass renderPass; VkRenderPass renderPass;
uint32_t i; uint32_t i;
uint8_t multisampling = 0;
uint32_t attachmentDescriptionCount = 0; uint32_t attachmentDescriptionCount = 0;
uint32_t colorAttachmentReferenceCount = 0; uint32_t colorAttachmentReferenceCount = 0;
uint32_t resolveReferenceCount = 0; uint32_t resolveReferenceCount = 0;
VulkanRenderTarget *renderTarget;
VulkanTexture *texture; VulkanTexture *texture;
VulkanTexture *msaaTexture = NULL;
for (i = 0; i < colorAttachmentCount; i += 1) for (i = 0; i < colorAttachmentCount; i += 1)
{ {
texture = (VulkanTexture*) colorAttachmentInfos[i].texture; texture = (VulkanTexture*) colorAttachmentInfos[i].texture;
renderTarget = VULKAN_INTERNAL_FetchRenderTarget( if (texture->msaaTex != NULL)
renderer,
colorAttachmentInfos[i].texture,
colorAttachmentInfos[i].depth,
colorAttachmentInfos[i].layer,
colorAttachmentInfos[i].level,
colorAttachmentInfos[i].sampleCount
);
if (renderTarget->multisampleCount > VK_SAMPLE_COUNT_1_BIT)
{ {
multisampling = 1; msaaTexture = texture->msaaTex;
/* Transition the multisample attachment */ /* Transition the multisample attachment */
@ -5594,12 +5546,12 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE, RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
0, 0,
renderTarget->multisampleTexture->layerCount, msaaTexture->layerCount,
0, 0,
renderTarget->multisampleTexture->levelCount, msaaTexture->levelCount,
0, 0,
renderTarget->multisampleTexture->image, msaaTexture->image,
&renderTarget->multisampleTexture->resourceAccessType &msaaTexture->resourceAccessType
); );
/* Resolve attachment and multisample attachment */ /* Resolve attachment and multisample attachment */
@ -5631,8 +5583,10 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
resolveReferenceCount += 1; resolveReferenceCount += 1;
attachmentDescriptions[attachmentDescriptionCount].flags = 0; attachmentDescriptions[attachmentDescriptionCount].flags = 0;
attachmentDescriptions[attachmentDescriptionCount].format = texture->format; attachmentDescriptions[attachmentDescriptionCount].format = msaaTexture->format;
attachmentDescriptions[attachmentDescriptionCount].samples = renderTarget->multisampleCount; attachmentDescriptions[attachmentDescriptionCount].samples = RefreshToVK_SampleCount[
msaaTexture->sampleCount
];
attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[
colorAttachmentInfos[i].loadOp colorAttachmentInfos[i].loadOp
]; ];
@ -5701,21 +5655,13 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
} }
else else
{ {
renderTarget = VULKAN_INTERNAL_FetchRenderTarget(
renderer,
depthStencilAttachmentInfo->texture,
depthStencilAttachmentInfo->depth,
depthStencilAttachmentInfo->layer,
depthStencilAttachmentInfo->level,
REFRESH_SAMPLECOUNT_1
);
texture = (VulkanTexture*) depthStencilAttachmentInfo->texture; texture = (VulkanTexture*) depthStencilAttachmentInfo->texture;
attachmentDescriptions[attachmentDescriptionCount].flags = 0; attachmentDescriptions[attachmentDescriptionCount].flags = 0;
attachmentDescriptions[attachmentDescriptionCount].format = texture->format; attachmentDescriptions[attachmentDescriptionCount].format = texture->format;
attachmentDescriptions[attachmentDescriptionCount].samples = attachmentDescriptions[attachmentDescriptionCount].samples = RefreshToVK_SampleCount[
VK_SAMPLE_COUNT_1_BIT; texture->sampleCount
];
attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[ attachmentDescriptions[attachmentDescriptionCount].loadOp = RefreshToVK_LoadOp[
depthStencilAttachmentInfo->loadOp depthStencilAttachmentInfo->loadOp
]; ];
@ -5744,7 +5690,7 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
attachmentDescriptionCount += 1; attachmentDescriptionCount += 1;
} }
if (multisampling) if (msaaTexture != NULL)
{ {
subpass.pResolveAttachments = resolveReferences; subpass.pResolveAttachments = resolveReferences;
} }
@ -5897,8 +5843,9 @@ static VkRenderPass VULKAN_INTERNAL_CreateTransientRenderPass(
renderer, renderer,
attachmentInfo.depthStencilFormat attachmentInfo.depthStencilFormat
); );
attachmentDescriptions[attachmentDescriptionCount].samples = attachmentDescriptions[attachmentDescriptionCount].samples = RefreshToVK_SampleCount[
VK_SAMPLE_COUNT_1_BIT; /* FIXME: do these take multisamples? */ sampleCount
];
attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachmentDescriptions[attachmentDescriptionCount].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachmentDescriptions[attachmentDescriptionCount].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachmentDescriptions[attachmentDescriptionCount].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -6600,9 +6547,11 @@ static Refresh_Texture* VULKAN_CreateTexture(
VK_IMAGE_USAGE_TRANSFER_SRC_BIT VK_IMAGE_USAGE_TRANSFER_SRC_BIT
); );
VkImageAspectFlags imageAspectFlags; VkImageAspectFlags imageAspectFlags;
uint8_t isDepthFormat = IsRefreshDepthFormat(textureCreateInfo->format);
VkFormat format; VkFormat format;
VulkanTexture *result;
if (IsRefreshDepthFormat(textureCreateInfo->format)) if (isDepthFormat)
{ {
format = RefreshToVK_DepthFormat(renderer, textureCreateInfo->format); format = RefreshToVK_DepthFormat(renderer, textureCreateInfo->format);
} }
@ -6631,7 +6580,7 @@ static Refresh_Texture* VULKAN_CreateTexture(
imageUsageFlags |= VK_IMAGE_USAGE_STORAGE_BIT; imageUsageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
} }
if (IsDepthFormat(format)) if (isDepthFormat)
{ {
imageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; imageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
@ -6645,18 +6594,41 @@ static Refresh_Texture* VULKAN_CreateTexture(
imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
} }
return (Refresh_Texture*) VULKAN_INTERNAL_CreateTexture( result = VULKAN_INTERNAL_CreateTexture(
renderer, renderer,
textureCreateInfo->width, textureCreateInfo->width,
textureCreateInfo->height, textureCreateInfo->height,
textureCreateInfo->depth, textureCreateInfo->depth,
textureCreateInfo->isCube, textureCreateInfo->isCube,
VK_SAMPLE_COUNT_1_BIT,
textureCreateInfo->levelCount, textureCreateInfo->levelCount,
isDepthFormat ?
textureCreateInfo->sampleCount : /* depth textures do not have a separate msaaTex */
REFRESH_SAMPLECOUNT_1,
format, format,
imageAspectFlags, imageAspectFlags,
imageUsageFlags imageUsageFlags
); );
/* create the MSAA texture for color attachments, if needed */
if ( result != NULL &&
!isDepthFormat &&
textureCreateInfo->sampleCount > REFRESH_SAMPLECOUNT_1 )
{
result->msaaTex = VULKAN_INTERNAL_CreateTexture(
renderer,
textureCreateInfo->width,
textureCreateInfo->height,
textureCreateInfo->depth,
textureCreateInfo->isCube,
textureCreateInfo->levelCount,
textureCreateInfo->sampleCount,
format,
imageAspectFlags,
imageUsageFlags
);
}
return (Refresh_Texture*) result;
} }
static Refresh_Buffer* VULKAN_CreateBuffer( static Refresh_Buffer* VULKAN_CreateBuffer(
@ -7989,6 +7961,7 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
VkRenderPass renderPass; VkRenderPass renderPass;
RenderPassHash hash; RenderPassHash hash;
uint32_t i; uint32_t i;
VulkanTexture *texture;
SDL_LockMutex(renderer->renderPassFetchLock); SDL_LockMutex(renderer->renderPassFetchLock);
@ -8000,9 +7973,15 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
hash.colorTargetDescriptions[i].storeOp = colorAttachmentInfos[i].storeOp; hash.colorTargetDescriptions[i].storeOp = colorAttachmentInfos[i].storeOp;
} }
hash.colorAttachmentSampleCount = (colorAttachmentCount > 0) ? hash.colorAttachmentSampleCount = REFRESH_SAMPLECOUNT_1;
colorAttachmentInfos[0].sampleCount : if (colorAttachmentCount > 0)
REFRESH_SAMPLECOUNT_1; {
texture = (VulkanTexture*) colorAttachmentInfos[0].texture;
if (texture->msaaTex != NULL)
{
hash.colorAttachmentSampleCount = texture->msaaTex->sampleCount;
}
}
hash.colorAttachmentCount = colorAttachmentCount; hash.colorAttachmentCount = colorAttachmentCount;
@ -8069,6 +8048,7 @@ static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer(
VkResult result; VkResult result;
VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1]; VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1];
FramebufferHash hash; FramebufferHash hash;
VulkanTexture *texture;
VulkanRenderTarget *renderTarget; VulkanRenderTarget *renderTarget;
uint32_t attachmentCount = 0; uint32_t attachmentCount = 0;
uint32_t i; uint32_t i;
@ -8085,23 +8065,32 @@ static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer(
for (i = 0; i < colorAttachmentCount; i += 1) for (i = 0; i < colorAttachmentCount; i += 1)
{ {
texture = (VulkanTexture*) colorAttachmentInfos[i].texture;
renderTarget = VULKAN_INTERNAL_FetchRenderTarget( renderTarget = VULKAN_INTERNAL_FetchRenderTarget(
renderer, renderer,
colorAttachmentInfos[i].texture, texture,
colorAttachmentInfos[i].depth, colorAttachmentInfos[i].depth,
colorAttachmentInfos[i].layer, colorAttachmentInfos[i].layer,
colorAttachmentInfos[i].level, colorAttachmentInfos[i].level
colorAttachmentInfos[i].sampleCount
); );
hash.colorAttachmentViews[i] = ( hash.colorAttachmentViews[i] = (
renderTarget->view renderTarget->view
); );
if (renderTarget->multisampleTexture != NULL) if (texture->msaaTex != NULL)
{ {
renderTarget = VULKAN_INTERNAL_FetchRenderTarget(
renderer,
texture->msaaTex,
colorAttachmentInfos[i].depth,
colorAttachmentInfos[i].layer,
colorAttachmentInfos[i].level
);
hash.colorMultiSampleAttachmentViews[i] = ( hash.colorMultiSampleAttachmentViews[i] = (
renderTarget->multisampleTexture->view renderTarget->view
); );
} }
} }
@ -8112,13 +8101,13 @@ static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer(
} }
else else
{ {
texture = (VulkanTexture*) depthStencilAttachmentInfo->texture;
renderTarget = VULKAN_INTERNAL_FetchRenderTarget( renderTarget = VULKAN_INTERNAL_FetchRenderTarget(
renderer, renderer,
depthStencilAttachmentInfo->texture, texture,
depthStencilAttachmentInfo->depth, depthStencilAttachmentInfo->depth,
depthStencilAttachmentInfo->layer, depthStencilAttachmentInfo->layer,
depthStencilAttachmentInfo->level, depthStencilAttachmentInfo->level
REFRESH_SAMPLECOUNT_1
); );
hash.depthStencilAttachmentView = renderTarget->view; hash.depthStencilAttachmentView = renderTarget->view;
} }
@ -8145,13 +8134,14 @@ static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer(
for (i = 0; i < colorAttachmentCount; i += 1) for (i = 0; i < colorAttachmentCount; i += 1)
{ {
texture = (VulkanTexture*) colorAttachmentInfos[i].texture;
renderTarget = VULKAN_INTERNAL_FetchRenderTarget( renderTarget = VULKAN_INTERNAL_FetchRenderTarget(
renderer, renderer,
colorAttachmentInfos[i].texture, texture,
colorAttachmentInfos[i].depth, colorAttachmentInfos[i].depth,
colorAttachmentInfos[i].layer, colorAttachmentInfos[i].layer,
colorAttachmentInfos[i].level, colorAttachmentInfos[i].level
colorAttachmentInfos[i].sampleCount
); );
imageViewAttachments[attachmentCount] = imageViewAttachments[attachmentCount] =
@ -8159,10 +8149,18 @@ static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer(
attachmentCount += 1; attachmentCount += 1;
if (renderTarget->multisampleTexture != NULL) if (texture->msaaTex != NULL)
{ {
renderTarget = VULKAN_INTERNAL_FetchRenderTarget(
renderer,
texture->msaaTex,
colorAttachmentInfos[i].depth,
colorAttachmentInfos[i].layer,
colorAttachmentInfos[i].level
);
imageViewAttachments[attachmentCount] = imageViewAttachments[attachmentCount] =
renderTarget->multisampleTexture->view; renderTarget->view;
attachmentCount += 1; attachmentCount += 1;
} }
@ -8170,13 +8168,13 @@ static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer(
if (depthStencilAttachmentInfo != NULL) if (depthStencilAttachmentInfo != NULL)
{ {
texture = (VulkanTexture*) depthStencilAttachmentInfo->texture;
renderTarget = VULKAN_INTERNAL_FetchRenderTarget( renderTarget = VULKAN_INTERNAL_FetchRenderTarget(
renderer, renderer,
depthStencilAttachmentInfo->texture, texture,
depthStencilAttachmentInfo->depth, depthStencilAttachmentInfo->depth,
depthStencilAttachmentInfo->layer, depthStencilAttachmentInfo->layer,
depthStencilAttachmentInfo->level, depthStencilAttachmentInfo->level
REFRESH_SAMPLECOUNT_1
); );
imageViewAttachments[attachmentCount] = renderTarget->view; imageViewAttachments[attachmentCount] = renderTarget->view;
@ -8303,6 +8301,7 @@ static void VULKAN_BeginRenderPass(
VkClearValue *clearValues; VkClearValue *clearValues;
uint32_t clearCount = colorAttachmentCount; uint32_t clearCount = colorAttachmentCount;
uint32_t multisampleAttachmentCount = 0; uint32_t multisampleAttachmentCount = 0;
uint32_t totalColorAttachmentCount = 0;
uint32_t i; uint32_t i;
VkImageAspectFlags depthAspectFlags; VkImageAspectFlags depthAspectFlags;
Refresh_Viewport defaultViewport; Refresh_Viewport defaultViewport;
@ -8388,7 +8387,7 @@ static void VULKAN_BeginRenderPass(
&texture->resourceAccessType &texture->resourceAccessType
); );
if (colorAttachmentInfos[i].sampleCount > REFRESH_SAMPLECOUNT_1) if (texture->msaaTex != NULL)
{ {
clearCount += 1; clearCount += 1;
multisampleAttachmentCount += 1; multisampleAttachmentCount += 1;
@ -8402,9 +8401,8 @@ static void VULKAN_BeginRenderPass(
texture = (VulkanTexture*) depthStencilAttachmentInfo->texture; texture = (VulkanTexture*) depthStencilAttachmentInfo->texture;
depthAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; depthAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
if (IsStencilFormat( if (IsStencilFormat(texture->format))
texture->format {
)) {
depthAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; depthAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
} }
@ -8431,28 +8429,31 @@ static void VULKAN_BeginRenderPass(
clearValues = SDL_stack_alloc(VkClearValue, clearCount); clearValues = SDL_stack_alloc(VkClearValue, clearCount);
for (i = 0; i < colorAttachmentCount + multisampleAttachmentCount; i += 1) totalColorAttachmentCount = colorAttachmentCount + multisampleAttachmentCount;
for (i = 0; i < totalColorAttachmentCount; i += 1)
{ {
clearValues[i].color.float32[0] = colorAttachmentInfos[i].clearColor.x; clearValues[i].color.float32[0] = colorAttachmentInfos[i].clearColor.x;
clearValues[i].color.float32[1] = colorAttachmentInfos[i].clearColor.y; clearValues[i].color.float32[1] = colorAttachmentInfos[i].clearColor.y;
clearValues[i].color.float32[2] = colorAttachmentInfos[i].clearColor.z; clearValues[i].color.float32[2] = colorAttachmentInfos[i].clearColor.z;
clearValues[i].color.float32[3] = colorAttachmentInfos[i].clearColor.w; clearValues[i].color.float32[3] = colorAttachmentInfos[i].clearColor.w;
if (colorAttachmentInfos[i].sampleCount > REFRESH_SAMPLECOUNT_1) texture = (VulkanTexture*) colorAttachmentInfos[i].texture;
if (texture->msaaTex != NULL)
{ {
clearValues[i+1].color.float32[0] = colorAttachmentInfos[i].clearColor.x;
clearValues[i+1].color.float32[1] = colorAttachmentInfos[i].clearColor.y;
clearValues[i+1].color.float32[2] = colorAttachmentInfos[i].clearColor.z;
clearValues[i+1].color.float32[3] = colorAttachmentInfos[i].clearColor.w;
i += 1; i += 1;
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) if (depthStencilAttachmentInfo != NULL)
{ {
clearValues[colorAttachmentCount].depthStencil.depth = clearValues[totalColorAttachmentCount].depthStencil.depth =
depthStencilAttachmentInfo->depthStencilClearValue.depth; depthStencilAttachmentInfo->depthStencilClearValue.depth;
clearValues[colorAttachmentCount].depthStencil.stencil = clearValues[totalColorAttachmentCount].depthStencil.stencil =
depthStencilAttachmentInfo->depthStencilClearValue.stencil; depthStencilAttachmentInfo->depthStencilClearValue.stencil;
} }