Skip to content

Commit ef19bd9

Browse files
committed
Add intermediate resolve image for multisampled outputs
* Technically the resolve doesn't allow format conversion at all, so instead of resolving directly to the swapchain image we need a middle- man image of the same format as we use internally for the MSAA target (RGBA8_SRGB) to resolve to, then blit from that to the actual backbuffer.
1 parent a453307 commit ef19bd9

File tree

2 files changed

+75
-12
lines changed

2 files changed

+75
-12
lines changed

renderdoc/driver/vulkan/vk_replay.cpp

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ VulkanReplay::OutputWindow::OutputWindow()
5555
bbmem = VK_NULL_HANDLE;
5656
bbview = VK_NULL_HANDLE;
5757

58+
resolveimg = VK_NULL_HANDLE;
59+
resolvemem = VK_NULL_HANDLE;
60+
5861
dsimg = VK_NULL_HANDLE;
5962
dsmem = VK_NULL_HANDLE;
6063
dsview = VK_NULL_HANDLE;
@@ -151,6 +154,13 @@ void VulkanReplay::OutputWindow::Destroy(WrappedVulkan *driver, VkDevice device)
151154
vt->DestroyFramebuffer(Unwrap(device), Unwrap(fbdepth), NULL);
152155
GetResourceManager()->ReleaseWrappedResource(fbdepth);
153156

157+
vt->DestroyImage(Unwrap(device), Unwrap(resolveimg), NULL);
158+
GetResourceManager()->ReleaseWrappedResource(resolveimg);
159+
vt->FreeMemory(Unwrap(device), Unwrap(resolvemem), NULL);
160+
GetResourceManager()->ReleaseWrappedResource(resolvemem);
161+
162+
resolveimg = VK_NULL_HANDLE;
163+
resolvemem = VK_NULL_HANDLE;
154164
dsview = VK_NULL_HANDLE;
155165
dsimg = VK_NULL_HANDLE;
156166
dsmem = VK_NULL_HANDLE;
@@ -450,6 +460,30 @@ void VulkanReplay::OutputWindow::Create(WrappedVulkan *driver, VkDevice device,
450460
RDCASSERTEQUAL(vkr, VK_SUCCESS);
451461

452462
GetResourceManager()->WrapResource(Unwrap(device), dsview);
463+
464+
// create resolve target, since it must precisely match the pre-resolve format, it doesn't allow
465+
// any format conversion.
466+
imInfo.samples = VK_SAMPLE_COUNT_1_BIT;
467+
imInfo.format = imformat;
468+
imInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
469+
470+
vkr = vt->CreateImage(Unwrap(device), &imInfo, NULL, &resolveimg);
471+
RDCASSERTEQUAL(vkr, VK_SUCCESS);
472+
473+
GetResourceManager()->WrapResource(Unwrap(device), resolveimg);
474+
475+
vt->GetImageMemoryRequirements(Unwrap(device), Unwrap(resolveimg), &mrq);
476+
477+
allocInfo.allocationSize = mrq.size;
478+
allocInfo.memoryTypeIndex = driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits);
479+
480+
vkr = vt->AllocateMemory(Unwrap(device), &allocInfo, NULL, &resolvemem);
481+
RDCASSERTEQUAL(vkr, VK_SUCCESS);
482+
483+
GetResourceManager()->WrapResource(Unwrap(device), resolvemem);
484+
485+
vkr = vt->BindImageMemory(Unwrap(device), Unwrap(resolveimg), Unwrap(resolvemem), 0);
486+
RDCASSERTEQUAL(vkr, VK_SUCCESS);
453487
}
454488

455489
{
@@ -2713,22 +2747,48 @@ void VulkanReplay::FlipOutputWindow(uint64_t id)
27132747
},
27142748
};
27152749

2716-
#if ENABLED(MSAA_MESH_VIEW)
2717-
VkImageResolve resolve = {
2718-
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0},
2719-
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0},
2720-
{outw.width, outw.height, 1},
2721-
};
2750+
VkImage blitSource = outw.bb;
27222751

2752+
#if ENABLED(MSAA_MESH_VIEW)
27232753
if(outw.dsimg != VK_NULL_HANDLE)
2754+
{
2755+
VkImageResolve resolve = {
2756+
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0},
2757+
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0},
2758+
{outw.width, outw.height, 1},
2759+
};
2760+
2761+
VkImageMemoryBarrier resolveBarrier = {
2762+
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2763+
NULL,
2764+
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
2765+
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
2766+
VK_IMAGE_LAYOUT_UNDEFINED,
2767+
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2768+
VK_QUEUE_FAMILY_IGNORED,
2769+
VK_QUEUE_FAMILY_IGNORED,
2770+
Unwrap(outw.resolveimg),
2771+
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
2772+
2773+
// discard previous contents of resolve buffer and finish any work with it.
2774+
DoPipelineBarrier(cmd, 1, &resolveBarrier);
2775+
2776+
// resolve from the backbuffer to resolve buffer (identical format)
27242777
vt->CmdResolveImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2725-
Unwrap(outw.colimg[outw.curidx]), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2726-
&resolve);
2727-
else
2778+
Unwrap(outw.resolveimg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve);
2779+
2780+
// wait for resolve to finish before we blit
2781+
blitSource = outw.resolveimg;
2782+
2783+
resolveBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2784+
resolveBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
2785+
DoPipelineBarrier(cmd, 1, &resolveBarrier);
2786+
}
27282787
#endif
2729-
vt->CmdBlitImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2730-
Unwrap(outw.colimg[outw.curidx]), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2731-
&blit, VK_FILTER_NEAREST);
2788+
2789+
vt->CmdBlitImage(Unwrap(cmd), Unwrap(blitSource), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2790+
Unwrap(outw.colimg[outw.curidx]), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit,
2791+
VK_FILTER_NEAREST);
27322792

27332793
outw.bbBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
27342794
outw.bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

renderdoc/driver/vulkan/vk_replay.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ class VulkanReplay : public IReplayDriver
311311
VkRenderPass rp, rpdepth;
312312
uint32_t curidx;
313313

314+
VkImage resolveimg;
315+
VkDeviceMemory resolvemem;
316+
314317
VkImage dsimg;
315318
VkDeviceMemory dsmem;
316319
VkImageView dsview;

0 commit comments

Comments
 (0)