1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-13 19:29:14 +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_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;
if (m_gpActivePipeline != VK_NULL_HANDLE) {
@ -2253,6 +2254,9 @@ namespace dxvk {
? util::invertComponentMapping(attachment->info().swizzle)
: VkComponentMapping();
}
for (uint32_t i = 0; i < fb->numAttachments(); i++)
fb->getAttachment(i).view->setRtBindingFrameId(m_device->getCurrentFrameId());
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 commitComputePostBarriers();
bool checkAsyncCompilationCompat();
Rc<DxvkBuffer> getTransferBuffer(VkDeviceSize size);

View File

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

View File

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

View File

@ -386,9 +386,13 @@ namespace dxvk {
* \param [in] frameId Frame number
*/
void setRtBindingFrameId(uint32_t frameId) {
if (m_rtBindingCurrFrame != frameId) {
m_rtBindingPrevFrame = m_rtBindingCurrFrame;
m_rtBindingCurrFrame = frameId;
if (frameId != m_rtBindingFrameId) {
if (frameId == m_rtBindingFrameId + 1)
m_rtBindingFrameCount += 1;
else
m_rtBindingFrameCount = 0;
m_rtBindingFrameId = frameId;
}
}
@ -396,12 +400,12 @@ namespace dxvk {
* \brief Checks for async pipeline compatibility
*
* 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
* \returns \c true if async compilation is supported
*/
bool getRtBindingAsyncShadersCompatibility(uint32_t frameId) const {
return m_rtBindingPrevFrame == frameId - 1;
bool getRtBindingAsyncCompilationCompat() const {
return m_rtBindingFrameCount >= 5;
}
private:
@ -412,8 +416,8 @@ namespace dxvk {
DxvkImageViewCreateInfo m_info;
VkImageView m_views[ViewCount];
uint32_t m_rtBindingCurrFrame = 0;
uint32_t m_rtBindingPrevFrame = 0;
uint32_t m_rtBindingFrameId = 0;
uint32_t m_rtBindingFrameCount = 0;
void createView(VkImageViewType type, uint32_t numLayers);