Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Maddie:dxvk-gplasync
dxvk-gplasync-x86-64-v3
dxvk-gplasync-2.3.1-1.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File dxvk-gplasync-2.3.1-1.patch of Package dxvk-gplasync-x86-64-v3
From fcc35246310ca077d8120b04b1c8cfd889142e1b Mon Sep 17 00:00:00 2001 From: Ph42oN <julle.ys.57@gmail.com> Date: Thu, 21 Mar 2024 12:38:27 +0200 Subject: [PATCH] release v2.3.1-1 --- meson.build | 2 +- src/dxvk/dxvk_context.cpp | 20 +++++++++++++++++--- src/dxvk/dxvk_context.h | 4 +++- src/dxvk/dxvk_graphics.cpp | 38 +++++++++++++++++++++++++++++++------- src/dxvk/dxvk_graphics.h | 9 ++++++++- src/dxvk/dxvk_image.h | 33 +++++++++++++++++++++++++++++++++ src/dxvk/dxvk_options.cpp | 10 ++++++++++ src/dxvk/dxvk_options.h | 6 ++++++ 8 files changed, 109 insertions(+), 13 deletions(-) diff --git a/meson.build b/meson.build index e35a9de0..9483be3f 100644 --- a/meson.build +++ b/meson.build @@ -174,7 +174,7 @@ glsl_generator = generator( ) dxvk_version = vcs_tag( - command: ['git', 'describe', '--dirty=+'], + command: ['git', 'describe', '--dirty=-1-gplasync'], input: 'version.h.in', output: 'version.h', ) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index dcaa7cb7..4a8f1ad3 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5045,7 +5045,8 @@ namespace dxvk { : DxvkContextFlag::GpDirtyRasterizerState); // Retrieve and bind actual Vulkan pipeline handle - auto pipelineInfo = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state); + auto pipelineInfo = m_state.gp.pipeline->getPipelineHandle( + m_state.gp.state, this->checkAsyncCompilationCompat()); if (unlikely(!pipelineInfo.first)) return false; @@ -5402,7 +5403,7 @@ namespace dxvk { } - void DxvkContext::updateFramebuffer() { + void DxvkContext::updateFramebuffer(bool isDraw) { if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) { m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer); @@ -5426,6 +5427,11 @@ namespace dxvk { m_state.gp.state.omSwizzle[i] = DxvkOmAttachmentSwizzle(mapping); } + if (isDraw) { + for (uint32_t i = 0; i < fbInfo.numAttachments(); i++) + fbInfo.getAttachment(i).view->setRtBindingFrameId(m_device->getCurrentFrameId()); + } + m_flags.set(DxvkContextFlag::GpDirtyPipelineState); } } @@ -5926,7 +5932,7 @@ namespace dxvk { } if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) - this->updateFramebuffer(); + this->updateFramebuffer(true); if (!m_flags.test(DxvkContextFlag::GpRenderPassBound)) this->startRenderPass(); @@ -6345,6 +6351,14 @@ namespace dxvk { return true; } + bool DxvkContext::checkAsyncCompilationCompat() { + bool fbCompat = true; + for (uint32_t i = 0; fbCompat && i < m_state.om.framebufferInfo.numAttachments(); i++) { + const auto& attachment = m_state.om.framebufferInfo.getAttachment(i); + fbCompat &= attachment.view->getRtBindingAsyncCompilationCompat(); + } + return fbCompat; + } DxvkGraphicsPipeline* DxvkContext::lookupGraphicsPipeline( const DxvkGraphicsPipelineShaders& shaders) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 3b61d474..e8c0c2fe 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1639,7 +1639,7 @@ namespace dxvk { DxvkFramebufferInfo makeFramebufferInfo( const DxvkRenderTargets& renderTargets); - void updateFramebuffer(); + void updateFramebuffer(bool isDraw = false); void applyRenderTargetLoadLayouts(); @@ -1722,6 +1722,8 @@ namespace dxvk { const Rc<DxvkBuffer>& buffer, VkDeviceSize copySize); + bool checkAsyncCompilationCompat(); + DxvkGraphicsPipeline* lookupGraphicsPipeline( const DxvkGraphicsPipelineShaders& shaders); diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 76df237d..2f6a241e 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -931,6 +931,7 @@ namespace dxvk { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; m_specConstantMask = this->computeSpecConstantMask(); + gplAsyncCache = m_device->config().gplAsyncCache; if (m_shaders.gs != nullptr) { if (m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) { @@ -979,7 +980,8 @@ namespace dxvk { std::pair<VkPipeline, DxvkGraphicsPipelineType> DxvkGraphicsPipeline::getPipelineHandle( - const DxvkGraphicsPipelineStateInfo& state) { + const DxvkGraphicsPipelineStateInfo& state, + bool async) { DxvkGraphicsPipelineInstance* instance = this->findInstance(state); if (unlikely(!instance)) { @@ -987,11 +989,22 @@ namespace dxvk { if (!this->validatePipelineState(state, true)) return std::make_pair(VK_NULL_HANDLE, DxvkGraphicsPipelineType::FastPipeline); - // Prevent other threads from adding new instances and check again - std::unique_lock<dxvk::mutex> lock(m_mutex); - instance = this->findInstance(state); + bool useAsync = m_device->config().enableAsync && async; + + // Prevent other threads from adding new instances and check again + std::unique_lock<dxvk::mutex> lock(useAsync ? m_asyncMutex : m_mutex); + instance = this->findInstance(state); + + if (!instance) { + if (useAsync) { + m_async = true; + lock.unlock(); + + m_workers->compileGraphicsPipeline(this, state, DxvkPipelinePriority::High); + + return std::make_pair(VK_NULL_HANDLE, DxvkGraphicsPipelineType::FastPipeline); + } else { - if (!instance) { // Keep pipeline object locked, at worst we're going to stall // a state cache worker and the current thread needs priority. bool canCreateBasePipeline = this->canCreateBasePipeline(state); @@ -1011,6 +1024,7 @@ namespace dxvk { this->writePipelineStateToCache(state); } } + } // Find a pipeline handle to use. If no optimized pipeline has // been compiled yet, use the slower base pipeline instead. @@ -1038,7 +1052,7 @@ namespace dxvk { // Do not compile if this pipeline can be fast linked. This essentially // disables the state cache for pipelines that do not benefit from it. - if (this->canCreateBasePipeline(state)) + if (!gplAsyncCache && !m_async && this->canCreateBasePipeline(state)) return; // Prevent other threads from adding new instances and check again @@ -1059,8 +1073,14 @@ namespace dxvk { instance->fastHandle.store(pipeline, std::memory_order_release); // Log pipeline state on error - if (!pipeline) + if (!pipeline) { this->logPipelineState(LogLevel::Error, state); + return; + } + + //Write pipeline to state cache + if (gplAsyncCache) + this->writePipelineStateToCache(state); } @@ -1111,6 +1131,8 @@ namespace dxvk { if (doCreateBasePipeline) baseHandle = this->getBasePipeline(state); + else if(m_async && gplAsyncCache) + baseHandle = this->getOptimizedPipeline(state); else fastHandle = this->getOptimizedPipeline(state); @@ -1279,6 +1301,8 @@ namespace dxvk { if (handle) m_fastPipelines.insert({ key, handle }); + + m_async = false; return handle; } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 435677a8..43cbac26 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -533,11 +533,14 @@ namespace dxvk { * Retrieves a pipeline handle for the given pipeline * state. If necessary, a new pipeline will be created. * \param [in] state Pipeline state vector + * \param [in] async Compile asynchronously * \returns Pipeline handle and handle type */ std::pair<VkPipeline, DxvkGraphicsPipelineType> getPipelineHandle( - const DxvkGraphicsPipelineStateInfo& state); + const DxvkGraphicsPipelineStateInfo& state, + bool async); + void asyncPipeline(const DxvkGraphicsPipelineStateInfo& state); /** * \brief Compiles a pipeline * @@ -588,6 +591,10 @@ namespace dxvk { alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; + alignas(CACHE_LINE_SIZE) + dxvk::mutex m_asyncMutex; + bool m_async = false; + bool gplAsyncCache; sync::List<DxvkGraphicsPipelineInstance> m_pipelines; uint32_t m_useCount = 0; diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 3a09302b..c9f7615d 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -548,6 +548,36 @@ namespace dxvk { this->imageSubresources(), view->imageSubresources()); } + /** + * \brief Sets render target usage frame number + * + * The image view will track internally when + * it was last used as a render target. This + * info is used for async shader compilation. + * \param [in] frameId Frame number + */ + void setRtBindingFrameId(uint32_t frameId) { + if (frameId != m_rtBindingFrameId) { + if (frameId == m_rtBindingFrameId + 1) + m_rtBindingFrameCount += 1; + else + m_rtBindingFrameCount = 0; + + m_rtBindingFrameId = frameId; + } + } + + /** + * \brief Checks for async pipeline compatibility + * + * Asynchronous pipeline compilation may be enabled if the + * 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 getRtBindingAsyncCompilationCompat() const { + return m_rtBindingFrameCount >= 5; + } private: @@ -557,6 +587,9 @@ namespace dxvk { DxvkImageViewCreateInfo m_info; VkImageView m_views[ViewCount]; + uint32_t m_rtBindingFrameId = 0; + uint32_t m_rtBindingFrameCount = 0; + void createView(VkImageViewType type, uint32_t numLayers); }; diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index 47e24492..8023851b 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -13,6 +13,16 @@ namespace dxvk { hud = config.getOption<std::string>("dxvk.hud", ""); tearFree = config.getOption<Tristate>("dxvk.tearFree", Tristate::Auto); hideIntegratedGraphics = config.getOption<bool> ("dxvk.hideIntegratedGraphics", false); + + if (env::getEnvVar("DXVK_GPLASYNCCACHE") == "1") + gplAsyncCache = true; + else + gplAsyncCache = config.getOption<bool>("dxvk.gplAsyncCache", false); + + if (env::getEnvVar("DXVK_ASYNC") == "0") + enableAsync = false; + else + enableAsync = config.getOption<bool>("dxvk.enableAsync", true); } } diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index e7e6862f..e1474ab4 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -1,6 +1,7 @@ #pragma once #include "../util/config/config.h" +#include "dxvk_include.h" namespace dxvk { @@ -24,6 +25,11 @@ namespace dxvk { /// Enables pipeline lifetime tracking Tristate trackPipelineLifetime; + // Enable async pipelines + bool enableAsync; + // Enable state cache with gpl and fixes for async + bool gplAsyncCache; + /// Shader-related options Tristate useRawSsbo; -- 2.43.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor