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:
parent
a516ca5b85
commit
7e95493fba
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user