[dxvk] Add hazard tracking to fragment output state

We need this to set the right pipeline bits for supporting attachment feedback loops on some vendors.
This commit is contained in:
Joshua Ashton 2022-08-05 22:21:43 +00:00 committed by Joshie
parent 43f53f3c0e
commit dff514c924
4 changed files with 37 additions and 6 deletions

View File

@ -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);
}

View File

@ -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();

View File

@ -119,6 +119,8 @@ namespace dxvk {
std::array<VkPipelineColorBlendAttachmentState, MaxNumRenderTargets> cbAttachments = { };
std::array<VkFormat, MaxNumRenderTargets> rtColorFormats = { };
VkImageAspectFlags feedbackLoop = 0u;
bool eq(const DxvkGraphicsPipelineFragmentOutputState& other) const;
size_t hash() const;

View File

@ -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;
};