1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +01:00

[dxvk] Support shader-based depth-stencil resolve

Requires VK_EXT_shader_stencil_export for stencil resolves.
This commit is contained in:
Philip Rebohle 2019-08-13 12:01:59 +02:00
parent a516ca5b85
commit 7e95493fba
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 131 additions and 49 deletions

View File

@ -2978,7 +2978,9 @@ namespace dxvk {
dstImage->isFullSubresource(region.dstSubresource, region.extent)); dstImage->isFullSubresource(region.dstSubresource, region.extent));
auto pipeInfo = m_common->metaResolve().getPipeline( auto pipeInfo = m_common->metaResolve().getPipeline(
format, srcImage->info().sampleCount); format, srcImage->info().sampleCount,
VK_RESOLVE_MODE_NONE_KHR,
VK_RESOLVE_MODE_NONE_KHR);
VkDescriptorImageInfo descriptorImage; VkDescriptorImageInfo descriptorImage;
descriptorImage.sampler = VK_NULL_HANDLE; descriptorImage.sampler = VK_NULL_HANDLE;

View File

@ -5,6 +5,8 @@
#include <dxvk_fullscreen_vert.h> #include <dxvk_fullscreen_vert.h>
#include <dxvk_fullscreen_layer_vert.h> #include <dxvk_fullscreen_layer_vert.h>
#include <dxvk_resolve_frag_d.h>
#include <dxvk_resolve_frag_ds.h>
#include <dxvk_resolve_frag_f.h> #include <dxvk_resolve_frag_f.h>
#include <dxvk_resolve_frag_f_amd.h> #include <dxvk_resolve_frag_f_amd.h>
#include <dxvk_resolve_frag_u.h> #include <dxvk_resolve_frag_u.h>
@ -31,35 +33,43 @@ namespace dxvk {
VkRenderPass DxvkMetaResolveRenderPass::createRenderPass(bool discard) const { VkRenderPass DxvkMetaResolveRenderPass::createRenderPass(bool discard) const {
auto formatInfo = m_dstImageView->formatInfo();
bool isColorImage = (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT);
VkAttachmentDescription attachment; VkAttachmentDescription attachment;
attachment.flags = 0; attachment.flags = 0;
attachment.format = m_dstImageView->info().format; attachment.format = m_dstImageView->info().format;
attachment.samples = VK_SAMPLE_COUNT_1_BIT; attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.initialLayout = m_dstImageView->imageInfo().layout; attachment.initialLayout = m_dstImageView->imageInfo().layout;
attachment.finalLayout = m_dstImageView->imageInfo().layout; attachment.finalLayout = m_dstImageView->imageInfo().layout;
if (discard) { if (discard) {
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
} }
VkImageLayout layout = isColorImage
? m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
: m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
VkAttachmentReference dstRef; VkAttachmentReference dstRef;
dstRef.attachment = 0; dstRef.attachment = 0;
dstRef.layout = m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); dstRef.layout = layout;
VkSubpassDescription subpass; VkSubpassDescription subpass;
subpass.flags = 0; subpass.flags = 0;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.inputAttachmentCount = 0; subpass.inputAttachmentCount = 0;
subpass.pInputAttachments = nullptr; subpass.pInputAttachments = nullptr;
subpass.colorAttachmentCount = 1; subpass.colorAttachmentCount = isColorImage ? 1 : 0;
subpass.pColorAttachments = &dstRef; subpass.pColorAttachments = isColorImage ? &dstRef : nullptr;
subpass.pResolveAttachments = nullptr; subpass.pResolveAttachments = nullptr;
subpass.pDepthStencilAttachment = nullptr; subpass.pDepthStencilAttachment = isColorImage ? nullptr : &dstRef;
subpass.preserveAttachmentCount = 0; subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr; subpass.pPreserveAttachments = nullptr;
@ -112,7 +122,11 @@ namespace dxvk {
? createShaderModule(dxvk_resolve_frag_f_amd) ? createShaderModule(dxvk_resolve_frag_f_amd)
: createShaderModule(dxvk_resolve_frag_f)), : createShaderModule(dxvk_resolve_frag_f)),
m_shaderFragU (createShaderModule(dxvk_resolve_frag_u)), m_shaderFragU (createShaderModule(dxvk_resolve_frag_u)),
m_shaderFragI (createShaderModule(dxvk_resolve_frag_i)) { m_shaderFragI (createShaderModule(dxvk_resolve_frag_i)),
m_shaderFragD (createShaderModule(dxvk_resolve_frag_d)) {
if (device->extensions().extShaderStencilExport)
m_shaderFragDS = createShaderModule(dxvk_resolve_frag_ds);
if (device->extensions().extShaderViewportIndexLayer) { if (device->extensions().extShaderViewportIndexLayer) {
m_shaderVert = createShaderModule(dxvk_fullscreen_layer_vert); m_shaderVert = createShaderModule(dxvk_fullscreen_layer_vert);
} else { } else {
@ -126,10 +140,12 @@ namespace dxvk {
for (const auto& pair : m_pipelines) { for (const auto& pair : m_pipelines) {
m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr); m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr);
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr); m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr);
m_vkd->vkDestroyDescriptorSetLayout (m_vkd->device(), pair.second.dsetLayout, nullptr); m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), pair.second.dsetLayout, nullptr);
m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second.renderPass, nullptr); m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second.renderPass, nullptr);
} }
m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragDS, nullptr);
m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragD, nullptr);
m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragF, nullptr); m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragF, nullptr);
m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragI, nullptr); m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragI, nullptr);
m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragU, nullptr); m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragU, nullptr);
@ -141,13 +157,17 @@ namespace dxvk {
DxvkMetaResolvePipeline DxvkMetaResolveObjects::getPipeline( DxvkMetaResolvePipeline DxvkMetaResolveObjects::getPipeline(
VkFormat format, VkFormat format,
VkSampleCountFlagBits samples) { VkSampleCountFlagBits samples,
VkResolveModeFlagBitsKHR depthResolveMode,
VkResolveModeFlagBitsKHR stencilResolveMode) {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
DxvkMetaResolvePipelineKey key; DxvkMetaResolvePipelineKey key;
key.format = format; key.format = format;
key.samples = samples; key.samples = samples;
key.modeD = depthResolveMode;
key.modeS = stencilResolveMode;
auto entry = m_pipelines.find(key); auto entry = m_pipelines.find(key);
if (entry != m_pipelines.end()) if (entry != m_pipelines.end())
@ -207,7 +227,7 @@ namespace dxvk {
const DxvkMetaResolvePipelineKey& key) { const DxvkMetaResolvePipelineKey& key) {
DxvkMetaResolvePipeline pipeline; DxvkMetaResolvePipeline pipeline;
pipeline.renderPass = this->createRenderPass(key); pipeline.renderPass = this->createRenderPass(key);
pipeline.dsetLayout = this->createDescriptorSetLayout(); pipeline.dsetLayout = this->createDescriptorSetLayout(key);
pipeline.pipeLayout = this->createPipelineLayout(pipeline.dsetLayout); pipeline.pipeLayout = this->createPipelineLayout(pipeline.dsetLayout);
pipeline.pipeHandle = this->createPipelineObject(key, pipeline.pipeLayout, pipeline.renderPass); pipeline.pipeHandle = this->createPipelineObject(key, pipeline.pipeLayout, pipeline.renderPass);
return pipeline; return pipeline;
@ -216,30 +236,37 @@ namespace dxvk {
VkRenderPass DxvkMetaResolveObjects::createRenderPass( VkRenderPass DxvkMetaResolveObjects::createRenderPass(
const DxvkMetaResolvePipelineKey& key) { const DxvkMetaResolvePipelineKey& key) {
auto formatInfo = imageFormatInfo(key.format);
bool isColorImage = (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT);
VkAttachmentDescription attachment; VkAttachmentDescription attachment;
attachment.flags = 0; attachment.flags = 0;
attachment.format = key.format; attachment.format = key.format;
attachment.samples = VK_SAMPLE_COUNT_1_BIT; attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.initialLayout = VK_IMAGE_LAYOUT_GENERAL; attachment.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
VkImageLayout layout = isColorImage
? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference attachmentRef; VkAttachmentReference attachmentRef;
attachmentRef.attachment = 0; attachmentRef.attachment = 0;
attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachmentRef.layout = layout;
VkSubpassDescription subpass; VkSubpassDescription subpass;
subpass.flags = 0; subpass.flags = 0;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.inputAttachmentCount = 0; subpass.inputAttachmentCount = 0;
subpass.pInputAttachments = nullptr; subpass.pInputAttachments = nullptr;
subpass.colorAttachmentCount = 1; subpass.colorAttachmentCount = isColorImage ? 1 : 0;
subpass.pColorAttachments = &attachmentRef; subpass.pColorAttachments = isColorImage ? &attachmentRef : nullptr;
subpass.pResolveAttachments = nullptr; subpass.pResolveAttachments = nullptr;
subpass.pDepthStencilAttachment = nullptr; subpass.pDepthStencilAttachment = isColorImage ? nullptr : &attachmentRef;
subpass.preserveAttachmentCount = 0; subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr; subpass.pPreserveAttachments = nullptr;
@ -261,20 +288,24 @@ namespace dxvk {
} }
VkDescriptorSetLayout DxvkMetaResolveObjects::createDescriptorSetLayout() const { VkDescriptorSetLayout DxvkMetaResolveObjects::createDescriptorSetLayout(
VkDescriptorSetLayoutBinding binding; const DxvkMetaResolvePipelineKey& key) {
binding.binding = 0; auto formatInfo = imageFormatInfo(key.format);
binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
binding.descriptorCount = 1; std::array<VkDescriptorSetLayoutBinding, 2> bindings = {{
binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &m_sampler },
binding.pImmutableSamplers = &m_sampler; { 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &m_sampler },
}};
VkDescriptorSetLayoutCreateInfo info; VkDescriptorSetLayoutCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
info.pNext = nullptr; info.pNext = nullptr;
info.flags = 0; info.flags = 0;
info.bindingCount = 1; info.bindingCount = 1;
info.pBindings = &binding; info.pBindings = bindings.data();
if ((formatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && key.modeS != VK_RESOLVE_MODE_NONE_KHR)
info.bindingCount = 2;
VkDescriptorSetLayout result = VK_NULL_HANDLE; VkDescriptorSetLayout result = VK_NULL_HANDLE;
if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS)
@ -284,7 +315,7 @@ namespace dxvk {
VkPipelineLayout DxvkMetaResolveObjects::createPipelineLayout( VkPipelineLayout DxvkMetaResolveObjects::createPipelineLayout(
VkDescriptorSetLayout descriptorSetLayout) const { VkDescriptorSetLayout descriptorSetLayout) {
VkPushConstantRange push; VkPushConstantRange push;
push.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; push.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
push.offset = 0; push.offset = 0;
@ -311,20 +342,22 @@ namespace dxvk {
VkPipelineLayout pipelineLayout, VkPipelineLayout pipelineLayout,
VkRenderPass renderPass) { VkRenderPass renderPass) {
auto formatInfo = imageFormatInfo(key.format); auto formatInfo = imageFormatInfo(key.format);
bool isColorImage = formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT;
std::array<VkPipelineShaderStageCreateInfo, 3> stages; std::array<VkPipelineShaderStageCreateInfo, 3> stages;
uint32_t stageCount = 0; uint32_t stageCount = 0;
VkSpecializationMapEntry specEntry; std::array<VkSpecializationMapEntry, 3> specEntries = {{
specEntry.constantID = 0; { 0, offsetof(DxvkMetaResolvePipelineKey, samples), sizeof(VkSampleCountFlagBits) },
specEntry.offset = 0; { 1, offsetof(DxvkMetaResolvePipelineKey, modeD), sizeof(VkResolveModeFlagBitsKHR) },
specEntry.size = sizeof(VkSampleCountFlagBits); { 2, offsetof(DxvkMetaResolvePipelineKey, modeS), sizeof(VkResolveModeFlagBitsKHR) },
}};
VkSpecializationInfo specInfo; VkSpecializationInfo specInfo;
specInfo.mapEntryCount = 1; specInfo.mapEntryCount = specEntries.size();
specInfo.pMapEntries = &specEntry; specInfo.pMapEntries = specEntries.data();
specInfo.dataSize = sizeof(VkSampleCountFlagBits); specInfo.dataSize = sizeof(key);
specInfo.pData = &key.samples; specInfo.pData = &key;
VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++]; VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++];
vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -351,14 +384,25 @@ namespace dxvk {
psStage.pNext = nullptr; psStage.pNext = nullptr;
psStage.flags = 0; psStage.flags = 0;
psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT; psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
psStage.module = m_shaderFragF; psStage.module = VK_NULL_HANDLE;
psStage.pName = "main"; psStage.pName = "main";
psStage.pSpecializationInfo = &specInfo; psStage.pSpecializationInfo = &specInfo;
if (formatInfo->flags.test(DxvkFormatFlag::SampledUInt)) if ((formatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && key.modeS != VK_RESOLVE_MODE_NONE_KHR) {
psStage.module = m_shaderFragU; if (m_shaderFragDS) {
psStage.module = m_shaderFragDS;
} else {
psStage.module = m_shaderFragD;
Logger::err("DXVK: Stencil export not supported by device, skipping stencil resolve");
}
} else if (formatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
psStage.module = m_shaderFragD;
else if (formatInfo->flags.test(DxvkFormatFlag::SampledUInt))
psStage.module = m_shaderFragU;
else if (formatInfo->flags.test(DxvkFormatFlag::SampledSInt)) else if (formatInfo->flags.test(DxvkFormatFlag::SampledSInt))
psStage.module = m_shaderFragI; psStage.module = m_shaderFragI;
else
psStage.module = m_shaderFragF;
std::array<VkDynamicState, 2> dynStates = {{ std::array<VkDynamicState, 2> dynStates = {{
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_VIEWPORT,
@ -448,6 +492,29 @@ namespace dxvk {
for (uint32_t i = 0; i < 4; i++) for (uint32_t i = 0; i < 4; i++)
cbState.blendConstants[i] = 0.0f; cbState.blendConstants[i] = 0.0f;
VkStencilOpState stencilOp;
stencilOp.failOp = VK_STENCIL_OP_REPLACE;
stencilOp.passOp = VK_STENCIL_OP_REPLACE;
stencilOp.depthFailOp = VK_STENCIL_OP_REPLACE;
stencilOp.compareOp = VK_COMPARE_OP_ALWAYS;
stencilOp.compareMask = 0xFFFFFFFF;
stencilOp.writeMask = 0xFFFFFFFF;
stencilOp.reference = 0;
VkPipelineDepthStencilStateCreateInfo dsState;
dsState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
dsState.pNext = nullptr;
dsState.flags = 0;
dsState.depthTestEnable = key.modeD != VK_RESOLVE_MODE_NONE_KHR;
dsState.depthWriteEnable = key.modeD != VK_RESOLVE_MODE_NONE_KHR;
dsState.depthCompareOp = VK_COMPARE_OP_ALWAYS;
dsState.depthBoundsTestEnable = VK_FALSE;
dsState.stencilTestEnable = key.modeS != VK_RESOLVE_MODE_NONE_KHR;
dsState.front = stencilOp;
dsState.back = stencilOp;
dsState.minDepthBounds = 0.0f;
dsState.maxDepthBounds = 1.0f;
VkGraphicsPipelineCreateInfo info; VkGraphicsPipelineCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
info.pNext = nullptr; info.pNext = nullptr;
@ -460,8 +527,8 @@ namespace dxvk {
info.pViewportState = &vpState; info.pViewportState = &vpState;
info.pRasterizationState = &rsState; info.pRasterizationState = &rsState;
info.pMultisampleState = &msState; info.pMultisampleState = &msState;
info.pColorBlendState = &cbState; info.pColorBlendState = isColorImage ? &cbState : nullptr;
info.pDepthStencilState = nullptr; info.pDepthStencilState = isColorImage ? nullptr : &dsState;
info.pDynamicState = &dynState; info.pDynamicState = &dynState;
info.layout = pipelineLayout; info.layout = pipelineLayout;
info.renderPass = renderPass; info.renderPass = renderPass;

View File

@ -31,17 +31,23 @@ namespace dxvk {
* on the copy operation they support. * on the copy operation they support.
*/ */
struct DxvkMetaResolvePipelineKey { struct DxvkMetaResolvePipelineKey {
VkFormat format; VkFormat format;
VkSampleCountFlagBits samples; VkSampleCountFlagBits samples;
VkResolveModeFlagBitsKHR modeD;
VkResolveModeFlagBitsKHR modeS;
bool eq(const DxvkMetaResolvePipelineKey& other) const { bool eq(const DxvkMetaResolvePipelineKey& other) const {
return this->format == other.format return this->format == other.format
&& this->samples == other.samples; && this->samples == other.samples
&& this->modeD == other.modeD
&& this->modeS == other.modeS;
} }
size_t hash() const { size_t hash() const {
return (uint32_t(format) << 4) return (uint32_t(format) << 4)
^ (uint32_t(samples) << 0); ^ (uint32_t(samples) << 0)
^ (uint32_t(modeD) << 12)
^ (uint32_t(modeS) << 16);
} }
}; };
@ -106,11 +112,15 @@ namespace dxvk {
* *
* \param [in] format Destination image format * \param [in] format Destination image format
* \param [in] samples Destination sample count * \param [in] samples Destination sample count
* \param [in] depthResolveMode Depth resolve mode
* \param [in] stencilResolveMode Stencil resolve mode
* \returns Compatible pipeline for the operation * \returns Compatible pipeline for the operation
*/ */
DxvkMetaResolvePipeline getPipeline( DxvkMetaResolvePipeline getPipeline(
VkFormat format, VkFormat format,
VkSampleCountFlagBits samples); VkSampleCountFlagBits samples,
VkResolveModeFlagBitsKHR depthResolveMode,
VkResolveModeFlagBitsKHR stencilResolveMode);
private: private:
@ -123,6 +133,8 @@ namespace dxvk {
VkShaderModule m_shaderFragF = VK_NULL_HANDLE; VkShaderModule m_shaderFragF = VK_NULL_HANDLE;
VkShaderModule m_shaderFragU = VK_NULL_HANDLE; VkShaderModule m_shaderFragU = VK_NULL_HANDLE;
VkShaderModule m_shaderFragI = VK_NULL_HANDLE; VkShaderModule m_shaderFragI = VK_NULL_HANDLE;
VkShaderModule m_shaderFragD = VK_NULL_HANDLE;
VkShaderModule m_shaderFragDS = VK_NULL_HANDLE;
std::mutex m_mutex; std::mutex m_mutex;
@ -142,10 +154,11 @@ namespace dxvk {
VkRenderPass createRenderPass( VkRenderPass createRenderPass(
const DxvkMetaResolvePipelineKey& key); const DxvkMetaResolvePipelineKey& key);
VkDescriptorSetLayout createDescriptorSetLayout() const; VkDescriptorSetLayout createDescriptorSetLayout(
const DxvkMetaResolvePipelineKey& key);
VkPipelineLayout createPipelineLayout( VkPipelineLayout createPipelineLayout(
VkDescriptorSetLayout descriptorSetLayout) const; VkDescriptorSetLayout descriptorSetLayout);
VkPipeline createPipelineObject( VkPipeline createPipelineObject(
const DxvkMetaResolvePipelineKey& key, const DxvkMetaResolvePipelineKey& key,