From 14593baebdf6a44e4f3fc01f421a848a3362182b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Apr 2019 18:22:04 +0200 Subject: [PATCH] [dxvk] Add new resolve shaders --- src/dxvk/dxvk_meta_resolve.cpp | 52 ++++++------------- src/dxvk/meson.build | 5 ++ src/dxvk/shaders/dxvk_resolve_frag_f.frag | 15 ++++++ src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag | 42 +++++++++++++++ src/dxvk/shaders/dxvk_resolve_frag_i.frag | 10 ++++ src/dxvk/shaders/dxvk_resolve_frag_u.frag | 10 ++++ 6 files changed, 99 insertions(+), 35 deletions(-) create mode 100644 src/dxvk/shaders/dxvk_resolve_frag_f.frag create mode 100644 src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag create mode 100644 src/dxvk/shaders/dxvk_resolve_frag_i.frag create mode 100644 src/dxvk/shaders/dxvk_resolve_frag_u.frag diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index dcada27df..d120b8af5 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -20,43 +20,29 @@ namespace dxvk { VkRenderPass DxvkMetaResolveRenderPass::createRenderPass() const { - std::array attachments; - attachments[0].flags = 0; - attachments[0].format = m_dstImageView->info().format; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - 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; + attachment.flags = 0; + attachment.format = m_dstImageView->info().format; + 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 dstRef; dstRef.attachment = 0; dstRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - VkAttachmentReference srcRef; - srcRef.attachment = 1; - srcRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - VkSubpassDescription subpass; subpass.flags = 0; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.inputAttachmentCount = 0; subpass.pInputAttachments = nullptr; subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &srcRef; - subpass.pResolveAttachments = &dstRef; + subpass.pColorAttachments = &dstRef; + subpass.pResolveAttachments = nullptr; subpass.pDepthStencilAttachment = nullptr; subpass.preserveAttachmentCount = 0; subpass.pPreserveAttachments = nullptr; @@ -65,8 +51,8 @@ namespace dxvk { info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; info.pNext = nullptr; info.flags = 0; - info.attachmentCount = attachments.size(); - info.pAttachments = attachments.data(); + info.attachmentCount = 1; + info.pAttachments = &attachment; info.subpassCount = 1; info.pSubpasses = &subpass; info.dependencyCount = 0; @@ -82,19 +68,15 @@ namespace dxvk { VkFramebuffer DxvkMetaResolveRenderPass::createFramebuffer() const { VkImageSubresourceRange dstSubresources = m_dstImageView->subresources(); VkExtent3D dstExtent = m_dstImageView->mipLevelExtent(0); - - std::array viewHandles = { - m_dstImageView->handle(), - m_srcImageView->handle(), - }; + VkImageView dstHandle = m_dstImageView->handle(); VkFramebufferCreateInfo fboInfo; fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fboInfo.pNext = nullptr; fboInfo.flags = 0; fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = viewHandles.size(); - fboInfo.pAttachments = viewHandles.data(); + fboInfo.attachmentCount = 1; + fboInfo.pAttachments = &dstHandle; fboInfo.width = dstExtent.width; fboInfo.height = dstExtent.height; fboInfo.layers = dstSubresources.layerCount; diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 819107cb4..0ccdbff59 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -29,6 +29,11 @@ dxvk_shaders = files([ 'shaders/dxvk_pack_d24s8.comp', 'shaders/dxvk_pack_d32s8.comp', + + 'shaders/dxvk_resolve_frag_f.frag', + 'shaders/dxvk_resolve_frag_f_amd.frag', + 'shaders/dxvk_resolve_frag_i.frag', + 'shaders/dxvk_resolve_frag_u.frag', 'shaders/dxvk_unpack_d24s8_as_d32s8.comp', 'shaders/dxvk_unpack_d24s8.comp', diff --git a/src/dxvk/shaders/dxvk_resolve_frag_f.frag b/src/dxvk/shaders/dxvk_resolve_frag_f.frag new file mode 100644 index 000000000..0823bc2de --- /dev/null +++ b/src/dxvk/shaders/dxvk_resolve_frag_f.frag @@ -0,0 +1,15 @@ +#version 450 + +layout(constant_id = 0) const int c_samples = 1; + +layout(binding = 0) uniform sampler2DMSArray s_image; + +layout(location = 0) out vec4 o_color; + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy, gl_Layer); + vec4 color = vec4(0.0f); + for (int i = 0; i < c_samples; i++) + color += texelFetch(s_image, coord, i); + o_color = color / float(c_samples); +} \ No newline at end of file diff --git a/src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag b/src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag new file mode 100644 index 000000000..180a9c25c --- /dev/null +++ b/src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag @@ -0,0 +1,42 @@ +#version 450 + +#extension GL_AMD_shader_fragment_mask: enable + +layout(constant_id = 0) const int c_samples = 1; + +layout(set = 0, binding = 0) +uniform sampler2DMSArray s_image; + +layout(location = 0) out vec4 o_color; + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy, gl_Layer); + + // get a four-bit fragment index for each sample + uint fragMask = fragmentMaskFetchAMD(s_image, coord); + + // count number of occurences of each fragment + // index in one four-bit counter for each sample + uint fragCount = 0u; + + for (int i = 0; i < 4 * c_samples; i += 4) { + uint fragIndex = bitfieldExtract(fragMask, i, 4); + fragCount += 1u << (fragIndex << 2); + } + + // perform necessary texture lookups to compute + // final fragment color + o_color = vec4(0.0f); + + while (fragCount != 0) { + int fragIndex = findLSB(fragCount) >> 2; + int fragShift = fragIndex << 2; + + o_color += fragmentFetchAMD(s_image, coord, fragIndex) + * float(bitfieldExtract(fragCount, fragShift, 4)); + + fragCount = bitfieldInsert(fragCount, 0, fragShift, 4); + } + + o_color /= float(c_samples); +} \ No newline at end of file diff --git a/src/dxvk/shaders/dxvk_resolve_frag_i.frag b/src/dxvk/shaders/dxvk_resolve_frag_i.frag new file mode 100644 index 000000000..d7cb2a87c --- /dev/null +++ b/src/dxvk/shaders/dxvk_resolve_frag_i.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(binding = 0) uniform isampler2DMSArray s_image; + +layout(location = 0) out ivec4 o_color; + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy, gl_Layer); + o_color = texelFetch(s_image, coord, 0); +} \ No newline at end of file diff --git a/src/dxvk/shaders/dxvk_resolve_frag_u.frag b/src/dxvk/shaders/dxvk_resolve_frag_u.frag new file mode 100644 index 000000000..dc6299f1f --- /dev/null +++ b/src/dxvk/shaders/dxvk_resolve_frag_u.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(binding = 0) uniform usampler2DMSArray s_image; + +layout(location = 0) out uvec4 o_color; + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy, gl_Layer); + o_color = texelFetch(s_image, coord, 0); +} \ No newline at end of file