1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-14 22:29:15 +01:00

[dxvk] Implement render target state tracking for async compilation

This ensures that we always render to targets which are only used once.
This commit is contained in:
Philip Rebohle 2018-09-10 18:22:09 +02:00
parent f94f5a74ba
commit 5c89a68879
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 39 additions and 14 deletions

View File

@ -1976,7 +1976,8 @@ namespace dxvk {
m_gpActivePipeline = m_state.gp.pipeline != nullptr && m_state.om.framebuffer != nullptr m_gpActivePipeline = m_state.gp.pipeline != nullptr && m_state.om.framebuffer != nullptr
? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, ? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state,
m_state.om.framebuffer->getRenderPass(), m_cmd->statCounters()) m_state.om.framebuffer->getRenderPass(), m_cmd->statCounters(),
this->checkAsyncCompilationCompat())
: VK_NULL_HANDLE; : VK_NULL_HANDLE;
if (m_gpActivePipeline != VK_NULL_HANDLE) { if (m_gpActivePipeline != VK_NULL_HANDLE) {
@ -2253,6 +2254,9 @@ namespace dxvk {
? util::invertComponentMapping(attachment->info().swizzle) ? util::invertComponentMapping(attachment->info().swizzle)
: VkComponentMapping(); : VkComponentMapping();
} }
for (uint32_t i = 0; i < fb->numAttachments(); i++)
fb->getAttachment(i).view->setRtBindingFrameId(m_device->getCurrentFrameId());
m_flags.set(DxvkContextFlag::GpDirtyPipelineState); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
} }
@ -2521,5 +2525,17 @@ namespace dxvk {
} }
} }
} }
bool DxvkContext::checkAsyncCompilationCompat() {
bool fbCompat = m_device->config().useAsyncPipeCompiler;
for (uint32_t i = 0; fbCompat && i < m_state.om.framebuffer->numAttachments(); i++) {
const auto& attachment = m_state.om.framebuffer->getAttachment(i);
fbCompat &= attachment.view->getRtBindingAsyncCompilationCompat();
}
return fbCompat;
}
} }

View File

@ -728,6 +728,8 @@ namespace dxvk {
void commitComputeInitBarriers(); void commitComputeInitBarriers();
void commitComputePostBarriers(); void commitComputePostBarriers();
bool checkAsyncCompilationCompat();
Rc<DxvkBuffer> getTransferBuffer(VkDeviceSize size); Rc<DxvkBuffer> getTransferBuffer(VkDeviceSize size);

View File

@ -102,9 +102,10 @@ namespace dxvk {
VkPipeline DxvkGraphicsPipeline::getPipelineHandle( VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass, const DxvkRenderPass& renderPass,
DxvkStatCounters& stats) { DxvkStatCounters& stats,
bool async) {
VkRenderPass renderPassHandle = renderPass.getDefaultHandle(); VkRenderPass renderPassHandle = renderPass.getDefaultHandle();
{ std::lock_guard<sync::Spinlock> lock(m_mutex); { std::lock_guard<sync::Spinlock> lock(m_mutex);
DxvkGraphicsPipelineInstance* pipeline = DxvkGraphicsPipelineInstance* pipeline =
@ -124,7 +125,7 @@ namespace dxvk {
VkPipeline newPipelineBase = m_basePipeline.load(); VkPipeline newPipelineBase = m_basePipeline.load();
VkPipeline newPipelineHandle = VK_NULL_HANDLE; VkPipeline newPipelineHandle = VK_NULL_HANDLE;
if (m_compiler == nullptr) { if (!async) {
newPipelineHandle = this->compilePipeline( newPipelineHandle = this->compilePipeline(
state, renderPassHandle, newPipelineBase); state, renderPassHandle, newPipelineBase);
} }
@ -154,7 +155,7 @@ namespace dxvk {
m_basePipeline.compare_exchange_strong(newPipelineBase, newPipelineHandle); m_basePipeline.compare_exchange_strong(newPipelineBase, newPipelineHandle);
// Compile pipeline asynchronously if requested // Compile pipeline asynchronously if requested
if (m_compiler != nullptr) if (async)
m_compiler->queueCompilation(this, newPipeline); m_compiler->queueCompilation(this, newPipeline);
return newPipelineHandle; return newPipelineHandle;

View File

@ -195,12 +195,14 @@ namespace dxvk {
* \param [in] state Pipeline state vector * \param [in] state Pipeline state vector
* \param [in] renderPass The render pass * \param [in] renderPass The render pass
* \param [in,out] stats Stat counter * \param [in,out] stats Stat counter
* \param [in] async Compile asynchronously
* \returns Pipeline handle * \returns Pipeline handle
*/ */
VkPipeline getPipelineHandle( VkPipeline getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state, const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass, const DxvkRenderPass& renderPass,
DxvkStatCounters& stats); DxvkStatCounters& stats,
bool async);
/** /**
* \brief Compiles optimized pipeline * \brief Compiles optimized pipeline

View File

@ -386,9 +386,13 @@ namespace dxvk {
* \param [in] frameId Frame number * \param [in] frameId Frame number
*/ */
void setRtBindingFrameId(uint32_t frameId) { void setRtBindingFrameId(uint32_t frameId) {
if (m_rtBindingCurrFrame != frameId) { if (frameId != m_rtBindingFrameId) {
m_rtBindingPrevFrame = m_rtBindingCurrFrame; if (frameId == m_rtBindingFrameId + 1)
m_rtBindingCurrFrame = frameId; m_rtBindingFrameCount += 1;
else
m_rtBindingFrameCount = 0;
m_rtBindingFrameId = frameId;
} }
} }
@ -396,12 +400,12 @@ namespace dxvk {
* \brief Checks for async pipeline compatibility * \brief Checks for async pipeline compatibility
* *
* Asynchronous pipeline compilation may be enabled if the * Asynchronous pipeline compilation may be enabled if the
* render target has been used during the previous frame. * render target has been drawn to in the previous frames.
* \param [in] frameId Current frame ID * \param [in] frameId Current frame ID
* \returns \c true if async compilation is supported * \returns \c true if async compilation is supported
*/ */
bool getRtBindingAsyncShadersCompatibility(uint32_t frameId) const { bool getRtBindingAsyncCompilationCompat() const {
return m_rtBindingPrevFrame == frameId - 1; return m_rtBindingFrameCount >= 5;
} }
private: private:
@ -412,8 +416,8 @@ namespace dxvk {
DxvkImageViewCreateInfo m_info; DxvkImageViewCreateInfo m_info;
VkImageView m_views[ViewCount]; VkImageView m_views[ViewCount];
uint32_t m_rtBindingCurrFrame = 0; uint32_t m_rtBindingFrameId = 0;
uint32_t m_rtBindingPrevFrame = 0; uint32_t m_rtBindingFrameCount = 0;
void createView(VkImageViewType type, uint32_t numLayers); void createView(VkImageViewType type, uint32_t numLayers);