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:
parent
f94f5a74ba
commit
5c89a68879
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -728,6 +728,8 @@ namespace dxvk {
|
||||
|
||||
void commitComputeInitBarriers();
|
||||
void commitComputePostBarriers();
|
||||
|
||||
bool checkAsyncCompilationCompat();
|
||||
|
||||
Rc<DxvkBuffer> getTransferBuffer(VkDeviceSize size);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user