Compile pipelines in model consumer thread during boot sequence.

This commit is contained in:
Skyth 2025-01-13 20:15:58 +03:00
parent 1b5be0dfcd
commit 05deb49767

View file

@ -5057,11 +5057,29 @@ struct PipelineStateQueueItem
#ifdef ASYNC_PSO_DEBUG #ifdef ASYNC_PSO_DEBUG
std::string pipelineName; std::string pipelineName;
#endif #endif
bool precompiledPipeline{};
}; };
static moodycamel::BlockingConcurrentQueue<PipelineStateQueueItem> g_pipelineStateQueue; static moodycamel::BlockingConcurrentQueue<PipelineStateQueueItem> g_pipelineStateQueue;
static void CompilePipeline(XXH64_hash_t pipelineHash, const PipelineState& pipelineState
#ifdef ASYNC_PSO_DEBUG
, const std::string& pipelineName
#endif
)
{
auto pipeline = CreateGraphicsPipeline(pipelineState);
#ifdef ASYNC_PSO_DEBUG
pipeline->setName(pipelineName);
#endif
// Will get dropped in render thread if a different thread already managed to compile this.
RenderCommand cmd;
cmd.type = RenderCommandType::AddPipeline;
cmd.addPipeline.hash = pipelineHash;
cmd.addPipeline.pipeline = pipeline.release();
g_renderQueue.enqueue(cmd);
}
static void PipelineCompilerThread() static void PipelineCompilerThread()
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -5086,8 +5104,6 @@ static void PipelineCompilerThread()
bool loading = *reinterpret_cast<bool*>(g_memory.Translate(0x83367A4C)); bool loading = *reinterpret_cast<bool*>(g_memory.Translate(0x83367A4C));
if (loading) if (loading)
newThreadPriority = THREAD_PRIORITY_HIGHEST; newThreadPriority = THREAD_PRIORITY_HIGHEST;
else if (queueItem.precompiledPipeline)
newThreadPriority = THREAD_PRIORITY_IDLE;
else else
newThreadPriority = THREAD_PRIORITY_LOWEST; newThreadPriority = THREAD_PRIORITY_LOWEST;
@ -5098,17 +5114,11 @@ static void PipelineCompilerThread()
} }
#endif #endif
auto pipeline = CreateGraphicsPipeline(queueItem.pipelineState); CompilePipeline(queueItem.pipelineHash, queueItem.pipelineState
#ifdef ASYNC_PSO_DEBUG #ifdef ASYNC_PSO_DEBUG
pipeline->setName(queueItem.pipelineName); , queueItem.pipelineName.c_str()
#endif #endif
);
// Will get dropped in render thread if a different thread already managed to compile this.
RenderCommand cmd;
cmd.type = RenderCommandType::AddPipeline;
cmd.addPipeline.hash = queueItem.pipelineHash;
cmd.addPipeline.pipeline = pipeline.release();
g_renderQueue.enqueue(cmd);
std::this_thread::yield(); std::this_thread::yield();
} }
@ -5147,6 +5157,18 @@ static void EnqueueGraphicsPipelineCompilation(const PipelineState& pipelineStat
bool shouldCompile = g_asyncPipelines.emplace(hash, pipelineState).second; bool shouldCompile = g_asyncPipelines.emplace(hash, pipelineState).second;
if (shouldCompile) if (shouldCompile)
{
bool loading = *reinterpret_cast<bool*>(g_memory.Translate(0x83367A4C));
if (!loading && g_pendingPipelineStateCache)
{
// We can just compile here during the logos.
CompilePipeline(hash, pipelineState
#ifdef ASYNC_PSO_DEBUG
, fmt::format("CACHE {} {:X}", name, hash)
#endif
);
}
else
{ {
if (databaseDataHolderPair.counter == nullptr && databaseDataHolderPair.holder.databaseData.get() != nullptr) if (databaseDataHolderPair.counter == nullptr && databaseDataHolderPair.holder.databaseData.get() != nullptr)
databaseDataHolderPair.counter = std::make_shared<DatabaseDataHolder>(std::move(databaseDataHolderPair.holder)); databaseDataHolderPair.counter = std::make_shared<DatabaseDataHolder>(std::move(databaseDataHolderPair.holder));
@ -5158,9 +5180,9 @@ static void EnqueueGraphicsPipelineCompilation(const PipelineState& pipelineStat
#ifdef ASYNC_PSO_DEBUG #ifdef ASYNC_PSO_DEBUG
queueItem.pipelineName = fmt::format("ASYNC {} {:X}", name, hash); queueItem.pipelineName = fmt::format("ASYNC {} {:X}", name, hash);
#endif #endif
queueItem.precompiledPipeline = g_pendingPipelineStateCache;
g_pipelineStateQueue.enqueue(queueItem); g_pipelineStateQueue.enqueue(queueItem);
} }
}
} }
struct CompilationArgs struct CompilationArgs