mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxvk] Use resolve attachment for meta-resolve ops
Faster than the naive fragment shader-based solution.
This commit is contained in:
parent
209248e26d
commit
75ee1f42c2
@ -2308,7 +2308,12 @@ namespace dxvk {
|
|||||||
const Rc<DxvkImage>& srcImage,
|
const Rc<DxvkImage>& srcImage,
|
||||||
const VkImageSubresourceLayers& srcSubresources,
|
const VkImageSubresourceLayers& srcSubresources,
|
||||||
VkFormat format) {
|
VkFormat format) {
|
||||||
m_barriers.recordCommands(m_cmd);
|
auto dstSubresourceRange = vk::makeSubresourceRange(dstSubresources);
|
||||||
|
auto srcSubresourceRange = vk::makeSubresourceRange(srcSubresources);
|
||||||
|
|
||||||
|
if (m_barriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|
||||||
|
|| m_barriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write))
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
// Create image views covering the requested subresourcs
|
// Create image views covering the requested subresourcs
|
||||||
DxvkImageViewCreateInfo dstViewInfo;
|
DxvkImageViewCreateInfo dstViewInfo;
|
||||||
@ -2324,7 +2329,7 @@ namespace dxvk {
|
|||||||
DxvkImageViewCreateInfo srcViewInfo;
|
DxvkImageViewCreateInfo srcViewInfo;
|
||||||
srcViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
srcViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
srcViewInfo.format = format;
|
srcViewInfo.format = format;
|
||||||
srcViewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
srcViewInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
srcViewInfo.aspect = srcSubresources.aspectMask;
|
srcViewInfo.aspect = srcSubresources.aspectMask;
|
||||||
srcViewInfo.minLevel = srcSubresources.mipLevel;
|
srcViewInfo.minLevel = srcSubresources.mipLevel;
|
||||||
srcViewInfo.numLevels = 1;
|
srcViewInfo.numLevels = 1;
|
||||||
@ -2335,48 +2340,12 @@ namespace dxvk {
|
|||||||
Rc<DxvkImageView> srcImageView = m_device->createImageView(srcImage, srcViewInfo);
|
Rc<DxvkImageView> srcImageView = m_device->createImageView(srcImage, srcViewInfo);
|
||||||
|
|
||||||
// Create a framebuffer and pipeline for the resolve op
|
// Create a framebuffer and pipeline for the resolve op
|
||||||
DxvkMetaResolvePipeline pipeInfo = m_metaResolve->getPipeline(format);
|
|
||||||
|
|
||||||
Rc<DxvkMetaResolveRenderPass> fb = new DxvkMetaResolveRenderPass(
|
Rc<DxvkMetaResolveRenderPass> fb = new DxvkMetaResolveRenderPass(
|
||||||
m_device->vkd(), dstImageView, srcImageView);
|
m_device->vkd(), dstImageView, srcImageView);
|
||||||
|
|
||||||
// Create descriptor set pointing to the source image
|
|
||||||
VkDescriptorImageInfo descriptorImage;
|
|
||||||
descriptorImage.sampler = VK_NULL_HANDLE;
|
|
||||||
descriptorImage.imageView = srcImageView->handle();
|
|
||||||
descriptorImage.imageLayout = srcImageView->imageInfo().layout;
|
|
||||||
|
|
||||||
VkWriteDescriptorSet descriptorWrite;
|
|
||||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
||||||
descriptorWrite.pNext = nullptr;
|
|
||||||
descriptorWrite.dstBinding = 0;
|
|
||||||
descriptorWrite.dstArrayElement = 0;
|
|
||||||
descriptorWrite.descriptorCount = 1;
|
|
||||||
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
||||||
descriptorWrite.pImageInfo = &descriptorImage;
|
|
||||||
descriptorWrite.pBufferInfo = nullptr;
|
|
||||||
descriptorWrite.pTexelBufferView = nullptr;
|
|
||||||
|
|
||||||
descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout);
|
|
||||||
m_cmd->updateDescriptorSets(1, &descriptorWrite);
|
|
||||||
|
|
||||||
// Set up viewport and scissor rect
|
|
||||||
VkExtent3D passExtent = dstImageView->mipLevelExtent(0);
|
|
||||||
passExtent.depth = dstSubresources.layerCount;
|
|
||||||
|
|
||||||
VkViewport viewport;
|
|
||||||
viewport.x = 0.0f;
|
|
||||||
viewport.y = 0.0f;
|
|
||||||
viewport.width = float(passExtent.width);
|
|
||||||
viewport.height = float(passExtent.height);
|
|
||||||
viewport.minDepth = 0.0f;
|
|
||||||
viewport.maxDepth = 1.0f;
|
|
||||||
|
|
||||||
VkRect2D scissor;
|
|
||||||
scissor.offset = { 0, 0 };
|
|
||||||
scissor.extent = { passExtent.width, passExtent.height };
|
|
||||||
|
|
||||||
// Render pass info
|
// Render pass info
|
||||||
|
VkExtent3D passExtent = dstImageView->mipLevelExtent(0);
|
||||||
|
|
||||||
VkRenderPassBeginInfo info;
|
VkRenderPassBeginInfo info;
|
||||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
info.pNext = nullptr;
|
info.pNext = nullptr;
|
||||||
@ -2389,16 +2358,24 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Perform the actual resolve operation
|
// Perform the actual resolve operation
|
||||||
m_cmd->cmdBeginRenderPass(&info, VK_SUBPASS_CONTENTS_INLINE);
|
m_cmd->cmdBeginRenderPass(&info, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle);
|
|
||||||
m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
||||||
pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr);
|
|
||||||
|
|
||||||
m_cmd->cmdSetViewport(0, 1, &viewport);
|
|
||||||
m_cmd->cmdSetScissor (0, 1, &scissor);
|
|
||||||
|
|
||||||
m_cmd->cmdDraw(1, passExtent.depth, 0, 0);
|
|
||||||
m_cmd->cmdEndRenderPass();
|
m_cmd->cmdEndRenderPass();
|
||||||
|
|
||||||
|
m_barriers.accessImage(
|
||||||
|
dstImage, dstSubresourceRange,
|
||||||
|
dstImage->info().layout,
|
||||||
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0,
|
||||||
|
dstImage->info().layout,
|
||||||
|
dstImage->info().stages,
|
||||||
|
dstImage->info().access);
|
||||||
|
|
||||||
|
m_barriers.accessImage(
|
||||||
|
srcImage, srcSubresourceRange,
|
||||||
|
srcImage->info().layout,
|
||||||
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0,
|
||||||
|
srcImage->info().layout,
|
||||||
|
srcImage->info().stages,
|
||||||
|
srcImage->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource(fb);
|
m_cmd->trackResource(fb);
|
||||||
m_cmd->trackResource(dstImage);
|
m_cmd->trackResource(dstImage);
|
||||||
m_cmd->trackResource(srcImage);
|
m_cmd->trackResource(srcImage);
|
||||||
|
@ -26,32 +26,34 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
VkRenderPass DxvkMetaResolveRenderPass::createRenderPass() const {
|
VkRenderPass DxvkMetaResolveRenderPass::createRenderPass() const {
|
||||||
std::array<VkSubpassDependency, 2> subpassDeps = {{
|
std::array<VkAttachmentDescription, 2> attachments;
|
||||||
{ VK_SUBPASS_EXTERNAL, 0,
|
attachments[0].flags = 0;
|
||||||
m_dstImageView->imageInfo().stages,
|
attachments[0].format = m_dstImageView->info().format;
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0 },
|
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
{ 0, VK_SUBPASS_EXTERNAL,
|
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
m_dstImageView->imageInfo().stages,
|
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
m_dstImageView->imageInfo().access, 0 },
|
attachments[0].finalLayout = m_dstImageView->imageInfo().layout;
|
||||||
}};
|
|
||||||
|
attachments[1].flags = 0;
|
||||||
|
attachments[1].format = m_dstImageView->info().format;
|
||||||
|
attachments[1].samples = m_srcImageView->imageInfo().sampleCount;
|
||||||
|
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachments[1].initialLayout = m_srcImageView->imageInfo().layout;
|
||||||
|
attachments[1].finalLayout = m_srcImageView->imageInfo().layout;
|
||||||
|
|
||||||
VkAttachmentDescription attachment;
|
VkAttachmentReference dstRef;
|
||||||
attachment.flags = 0;
|
dstRef.attachment = 0;
|
||||||
attachment.format = m_dstImageView->info().format;
|
dstRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
attachment.finalLayout = m_dstImageView->imageInfo().layout;
|
|
||||||
|
|
||||||
VkAttachmentReference attachmentRef;
|
VkAttachmentReference srcRef;
|
||||||
attachmentRef.attachment = 0;
|
srcRef.attachment = 1;
|
||||||
attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
srcRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
VkSubpassDescription subpass;
|
VkSubpassDescription subpass;
|
||||||
subpass.flags = 0;
|
subpass.flags = 0;
|
||||||
@ -59,8 +61,8 @@ namespace dxvk {
|
|||||||
subpass.inputAttachmentCount = 0;
|
subpass.inputAttachmentCount = 0;
|
||||||
subpass.pInputAttachments = nullptr;
|
subpass.pInputAttachments = nullptr;
|
||||||
subpass.colorAttachmentCount = 1;
|
subpass.colorAttachmentCount = 1;
|
||||||
subpass.pColorAttachments = &attachmentRef;
|
subpass.pColorAttachments = &srcRef;
|
||||||
subpass.pResolveAttachments = nullptr;
|
subpass.pResolveAttachments = &dstRef;
|
||||||
subpass.pDepthStencilAttachment = nullptr;
|
subpass.pDepthStencilAttachment = nullptr;
|
||||||
subpass.preserveAttachmentCount = 0;
|
subpass.preserveAttachmentCount = 0;
|
||||||
subpass.pPreserveAttachments = nullptr;
|
subpass.pPreserveAttachments = nullptr;
|
||||||
@ -69,12 +71,12 @@ namespace dxvk {
|
|||||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
info.pNext = nullptr;
|
info.pNext = nullptr;
|
||||||
info.flags = 0;
|
info.flags = 0;
|
||||||
info.attachmentCount = 1;
|
info.attachmentCount = attachments.size();
|
||||||
info.pAttachments = &attachment;
|
info.pAttachments = attachments.data();
|
||||||
info.subpassCount = 1;
|
info.subpassCount = 1;
|
||||||
info.pSubpasses = &subpass;
|
info.pSubpasses = &subpass;
|
||||||
info.dependencyCount = subpassDeps.size();
|
info.dependencyCount = 0;
|
||||||
info.pDependencies = subpassDeps.data();
|
info.pDependencies = nullptr;
|
||||||
|
|
||||||
VkRenderPass result = VK_NULL_HANDLE;
|
VkRenderPass result = VK_NULL_HANDLE;
|
||||||
if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS)
|
if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS)
|
||||||
@ -84,17 +86,21 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
VkFramebuffer DxvkMetaResolveRenderPass::createFramebuffer() const {
|
VkFramebuffer DxvkMetaResolveRenderPass::createFramebuffer() const {
|
||||||
VkImageView dstViewHandle = m_dstImageView->handle();
|
|
||||||
VkImageSubresourceRange dstSubresources = m_dstImageView->subresources();
|
VkImageSubresourceRange dstSubresources = m_dstImageView->subresources();
|
||||||
VkExtent3D dstExtent = m_dstImageView->mipLevelExtent(0);
|
VkExtent3D dstExtent = m_dstImageView->mipLevelExtent(0);
|
||||||
|
|
||||||
|
std::array<VkImageView, 2> viewHandles = {
|
||||||
|
m_dstImageView->handle(),
|
||||||
|
m_srcImageView->handle(),
|
||||||
|
};
|
||||||
|
|
||||||
VkFramebufferCreateInfo fboInfo;
|
VkFramebufferCreateInfo fboInfo;
|
||||||
fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
fboInfo.pNext = nullptr;
|
fboInfo.pNext = nullptr;
|
||||||
fboInfo.flags = 0;
|
fboInfo.flags = 0;
|
||||||
fboInfo.renderPass = m_renderPass;
|
fboInfo.renderPass = m_renderPass;
|
||||||
fboInfo.attachmentCount = 1;
|
fboInfo.attachmentCount = viewHandles.size();
|
||||||
fboInfo.pAttachments = &dstViewHandle;
|
fboInfo.pAttachments = viewHandles.data();
|
||||||
fboInfo.width = dstExtent.width;
|
fboInfo.width = dstExtent.width;
|
||||||
fboInfo.height = dstExtent.height;
|
fboInfo.height = dstExtent.height;
|
||||||
fboInfo.layers = dstSubresources.layerCount;
|
fboInfo.layers = dstSubresources.layerCount;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user