diff --git a/src/render/rt64_raster_shader.cpp b/src/render/rt64_raster_shader.cpp index edaef83..69fcda5 100644 --- a/src/render/rt64_raster_shader.cpp +++ b/src/render/rt64_raster_shader.cpp @@ -531,9 +531,28 @@ namespace RT64 { } void RasterShaderUber::threadCreatePipelines(uint32_t threadIndex) { + // Delay the creation of all other pipelines until the first pipeline is created. This can help the + // driver reuse its shader cache between pipelines and achieve a much lower creation time than if + // all threads started at the same time. + if (threadIndex > 0) { + std::unique_lock lock(firstPipelineMutex); + firstPipelineCondition.wait(lock, [this]() { + return (pipelines[0] != nullptr); + }); + } + for (const PipelineCreation &creation : pipelineThreadCreations[threadIndex]) { uint32_t pipelineIndex = pipelineStateIndex(creation.zCmp, creation.zUpd, creation.cvgAdd); - pipelines[pipelineIndex] = RasterShader::createPipeline(creation); + + if (pipelineIndex == 0) { + firstPipelineMutex.lock(); + pipelines[pipelineIndex] = RasterShader::createPipeline(creation); + firstPipelineMutex.unlock(); + firstPipelineCondition.notify_all(); + } + else { + pipelines[pipelineIndex] = RasterShader::createPipeline(creation); + } } } diff --git a/src/render/rt64_raster_shader.h b/src/render/rt64_raster_shader.h index 55c5b15..804af75 100644 --- a/src/render/rt64_raster_shader.h +++ b/src/render/rt64_raster_shader.h @@ -6,6 +6,7 @@ #include "rt64_shader_common.h" +#include #include #include @@ -78,7 +79,8 @@ namespace RT64 { std::unique_ptr pipelines[8]; std::unique_ptr postBlendDitherNoiseAddPipeline; std::unique_ptr postBlendDitherNoiseSubPipeline; - std::mutex pipelinesMutex; + std::mutex firstPipelineMutex; + std::condition_variable firstPipelineCondition; bool pipelinesCreated = false; std::unique_ptr pipelineLayout; std::vector> pipelineThreadCreations; @@ -88,6 +90,7 @@ namespace RT64 { RasterShaderUber(RenderDevice *device, RenderShaderFormat shaderFormat, const RenderMultisampling &multisampling, const ShaderLibrary *shaderLibrary, uint32_t threadCount); ~RasterShaderUber(); + void threadCreatePipeline(const PipelineCreation &creation); void threadCreatePipelines(uint32_t threadIndex); void waitForPipelineCreation(); uint32_t pipelineStateIndex(bool zCmp, bool zUpd, bool cvgAdd) const;