From 9fbddf57df9c88d9ec3bea3020bf413fd6a4c83c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 29 Jan 2018 20:01:49 +0100 Subject: [PATCH] [dxvk] Emit dynamic state after binding a graphics pipeline Fixes issues with stencil references becoming undefined under certain circumstances. This issue was encountered in Heroes of the Storm. --- src/dxvk/dxvk_cmdlist.h | 3 +- src/dxvk/dxvk_context.cpp | 54 +++++++++++------------------------ src/dxvk/dxvk_context.h | 1 - src/dxvk/dxvk_context_state.h | 1 - src/util/log/log.cpp | 36 ++++++++++++----------- src/util/log/log.h | 3 ++ 6 files changed, 41 insertions(+), 57 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index cd9dedb6..aa4c79bb 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -346,8 +346,7 @@ namespace dxvk { } - void cmdSetBlendConstants( - float blendConstants[4]) { + void cmdSetBlendConstants(const float blendConstants[4]) { m_vkd->vkCmdSetBlendConstants(m_buffer, blendConstants); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 774d458a..36fe0cad 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -30,7 +30,6 @@ namespace dxvk { m_flags.set( DxvkContextFlag::GpDirtyPipeline, DxvkContextFlag::GpDirtyPipelineState, - DxvkContextFlag::GpDirtyDynamicState, DxvkContextFlag::GpDirtyResources, DxvkContextFlag::GpDirtyVertexBuffers, DxvkContextFlag::GpDirtyIndexBuffer, @@ -982,16 +981,15 @@ namespace dxvk { m_state.vp.scissorRects[i] = scissorRects[i]; } - this->updateViewports(); + m_cmd->cmdSetViewport(0, viewportCount, viewports); + m_cmd->cmdSetScissor (0, viewportCount, scissorRects); } void DxvkContext::setBlendConstants( const DxvkBlendConstants& blendConstants) { - for (uint32_t i = 0; i < 4; i++) - m_state.om.blendConstants = blendConstants; - - this->updateBlendConstants(); + m_state.om.blendConstants = blendConstants; + m_cmd->cmdSetBlendConstants(&blendConstants.r); } @@ -999,7 +997,9 @@ namespace dxvk { const uint32_t reference) { m_state.om.stencilReference = reference; - this->updateStencilReference(); + m_cmd->cmdSetStencilReference( + VK_STENCIL_FRONT_AND_BACK, + reference); } @@ -1204,6 +1204,16 @@ namespace dxvk { m_cmd->cmdBindPipeline( VK_PIPELINE_BIND_POINT_GRAPHICS, m_gpActivePipeline); + + m_cmd->cmdSetViewport(0, m_state.gp.state.rsViewportCount, m_state.vp.viewports.data()); + m_cmd->cmdSetScissor (0, m_state.gp.state.rsViewportCount, m_state.vp.scissorRects.data()); + + m_cmd->cmdSetBlendConstants( + &m_state.om.blendConstants.r); + + m_cmd->cmdSetStencilReference( + VK_STENCIL_FRONT_AND_BACK, + m_state.om.stencilReference); } } } @@ -1380,35 +1390,6 @@ namespace dxvk { } - void DxvkContext::updateDynamicState() { - if (m_flags.test(DxvkContextFlag::GpDirtyDynamicState)) { - m_flags.clr(DxvkContextFlag::GpDirtyDynamicState); - - this->updateViewports(); - this->updateBlendConstants(); - this->updateStencilReference(); - } - } - - - void DxvkContext::updateViewports() { - m_cmd->cmdSetViewport(0, m_state.gp.state.rsViewportCount, m_state.vp.viewports.data()); - m_cmd->cmdSetScissor (0, m_state.gp.state.rsViewportCount, m_state.vp.scissorRects.data()); - } - - - void DxvkContext::updateBlendConstants() { - m_cmd->cmdSetBlendConstants(&m_state.om.blendConstants.r); - } - - - void DxvkContext::updateStencilReference() { - m_cmd->cmdSetStencilReference( - VK_STENCIL_FRONT_AND_BACK, - m_state.om.stencilReference); - } - - void DxvkContext::updateIndexBufferBinding() { if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) { m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer); @@ -1460,7 +1441,6 @@ namespace dxvk { void DxvkContext::commitGraphicsState() { this->renderPassBegin(); this->updateGraphicsPipeline(); - this->updateDynamicState(); this->updateIndexBufferBinding(); this->updateVertexBufferBindings(); this->updateGraphicsShaderResources(); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 9516bbe8..d5077b3e 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -548,7 +548,6 @@ namespace dxvk { const DxvkBindingState& bindingState, const Rc& layout); - void updateDynamicState(); void updateViewports(); void updateBlendConstants(); void updateStencilReference(); diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 198514d0..ecfb4302 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -24,7 +24,6 @@ namespace dxvk { GpRenderPassBound, ///< Render pass is currently bound GpDirtyPipeline, ///< Graphics pipeline binding is out of date GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled - GpDirtyDynamicState, ///< Dynamic state needs to be reapplied GpDirtyResources, ///< Graphics pipeline resource bindings are out of date GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date GpDirtyIndexBuffer, ///< Index buffer binding are out of date diff --git a/src/util/log/log.cpp b/src/util/log/log.cpp index 47ab5af2..fc5f6ec2 100644 --- a/src/util/log/log.cpp +++ b/src/util/log/log.cpp @@ -5,21 +5,9 @@ namespace dxvk { Logger::Logger(const std::string& file_name) - : m_minLevel(getMinLogLevel()) - { - if (m_minLevel == LogLevel::None) - return; - - std::string path = env::getEnvVar(L"DXVK_LOG_PATH"); - std::string file = path; - if (!file.empty() && *file.rbegin() != '/') - file += '/'; - std::string name = env::getExeName(); - auto extp = name.find_last_of('.'); - if (extp != std::string::npos && name.substr(extp +1) == "exe") - name.erase(extp); - file += name + "_"; - m_fileStream = std::ofstream(file + file_name); + : m_minLevel(getMinLogLevel()) { + if (m_minLevel != LogLevel::None) + m_fileStream = std::ofstream(getFileName(file_name)); } @@ -61,7 +49,6 @@ namespace dxvk { const char* prefix = s_prefixes.at(static_cast(level)); std::cerr << prefix << message << std::endl; m_fileStream << prefix << message << std::endl; - m_fileStream.flush(); } } @@ -86,4 +73,21 @@ namespace dxvk { return LogLevel::Info; } + + std::string Logger::getFileName(const std::string& base) { + std::string path = env::getEnvVar(L"DXVK_LOG_PATH"); + + if (!path.empty() && *path.rbegin() != '/') + path += '/'; + + std::string exeName = env::getExeName(); + auto extp = exeName.find_last_of('.'); + + if (extp != std::string::npos && exeName.substr(extp + 1) == "exe") + exeName.erase(extp); + + path += exeName + "_" + base; + return path; + } + } diff --git a/src/util/log/log.h b/src/util/log/log.h index e298765a..09e00332 100644 --- a/src/util/log/log.h +++ b/src/util/log/log.h @@ -47,6 +47,9 @@ namespace dxvk { void log(LogLevel level, const std::string& message); static LogLevel getMinLogLevel(); + + static std::string getFileName( + const std::string& base); };