diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index a747394f..8d74b436 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2452,7 +2452,8 @@ namespace dxvk { void DxvkContext::setLogicOpState(const DxvkLogicOpState& lo) { m_state.gp.state.om = DxvkOmInfo( lo.enableLogicOp, - lo.logicOp); + lo.logicOp, + m_state.gp.state.om.feedbackLoop()); m_flags.set(DxvkContextFlag::GpDirtyPipelineState); } diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 86633ba1..822c4a83 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -225,6 +225,8 @@ namespace dxvk { cbInfo.logicOpEnable = state.om.enableLogicOp(); cbInfo.logicOp = state.om.logicOp(); + feedbackLoop = state.om.feedbackLoop(); + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { rtColorFormats[i] = state.rt.getColorFormat(i); @@ -321,7 +323,8 @@ namespace dxvk { && msInfo.alphaToCoverageEnable == other.msInfo.alphaToCoverageEnable && msInfo.alphaToOneEnable == other.msInfo.alphaToOneEnable && msSampleMask == other.msSampleMask - && cbUseDynamicBlendConstants == other.cbUseDynamicBlendConstants; + && cbUseDynamicBlendConstants == other.cbUseDynamicBlendConstants + && feedbackLoop == other.feedbackLoop; for (uint32_t i = 0; i < rtInfo.colorAttachmentCount && eq; i++) eq = rtColorFormats[i] == other.rtColorFormats[i]; @@ -360,6 +363,7 @@ namespace dxvk { hash.add(uint32_t(msInfo.alphaToOneEnable)); hash.add(uint32_t(msSampleMask)); hash.add(uint32_t(cbUseDynamicBlendConstants)); + hash.add(uint32_t(feedbackLoop)); for (uint32_t i = 0; i < rtInfo.colorAttachmentCount; i++) hash.add(uint32_t(rtColorFormats[i])); @@ -396,6 +400,13 @@ namespace dxvk { dyInfo.pDynamicStates = &dynamicState; } + VkPipelineCreateFlags flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + if (state.feedbackLoop & VK_IMAGE_ASPECT_COLOR_BIT) + flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + + if (state.feedbackLoop & VK_IMAGE_ASPECT_DEPTH_BIT) + flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + // pNext is non-const for some reason, but this is only an input // structure, so we should be able to safely use const_cast. VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; @@ -403,7 +414,7 @@ namespace dxvk { libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT; VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; - info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.flags = flags; info.pColorBlendState = &state.cbInfo; info.pMultisampleState = &state.msInfo; info.pDynamicState = &dyInfo; @@ -1159,6 +1170,12 @@ namespace dxvk { stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, key.shState.fsInfo), &key.scState.scInfo); } + if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_COLOR_BIT) + flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + + if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_DEPTH_BIT) + flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &key.foState.rtInfo }; info.flags = flags; info.stageCount = stageInfo.getStageCount(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index a0c0bfba..4c234f81 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -119,6 +119,8 @@ namespace dxvk { std::array cbAttachments = { }; std::array rtColorFormats = { }; + VkImageAspectFlags feedbackLoop = 0u; + bool eq(const DxvkGraphicsPipelineFragmentOutputState& other) const; size_t hash() const; diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 49f081a3..5713115c 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -433,10 +433,12 @@ namespace dxvk { DxvkOmInfo() = default; DxvkOmInfo( - VkBool32 enableLogicOp, - VkLogicOp logicOp) + VkBool32 enableLogicOp, + VkLogicOp logicOp, + VkImageAspectFlags feedbackLoop) : m_enableLogicOp (uint16_t(enableLogicOp)), m_logicOp (uint16_t(logicOp)), + m_feedbackLoop (uint16_t(feedbackLoop)), m_reserved (0) { } VkBool32 enableLogicOp() const { @@ -447,11 +449,20 @@ namespace dxvk { return VkLogicOp(m_logicOp); } + VkImageAspectFlags feedbackLoop() const { + return VkImageAspectFlags(m_feedbackLoop); + } + + void setFeedbackLoop(VkImageAspectFlags feedbackLoop) { + m_feedbackLoop = uint16_t(feedbackLoop); + } + private: uint16_t m_enableLogicOp : 1; uint16_t m_logicOp : 4; - uint16_t m_reserved : 11; + uint16_t m_feedbackLoop : 2; + uint16_t m_reserved : 9; };