diff options
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/exception.h | 40 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/opcodes.cpp | 2 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/program.cpp | 1 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/translate.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 43 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 35 |
8 files changed, 98 insertions, 45 deletions
diff --git a/src/shader_recompiler/exception.h b/src/shader_recompiler/exception.h index 6fe620801..013d7b1bf 100644 --- a/src/shader_recompiler/exception.h +++ b/src/shader_recompiler/exception.h | |||
| @@ -5,38 +5,62 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <stdexcept> | 7 | #include <stdexcept> |
| 8 | #include <string> | ||
| 9 | #include <string_view> | ||
| 8 | #include <utility> | 10 | #include <utility> |
| 9 | 11 | ||
| 10 | #include <fmt/format.h> | 12 | #include <fmt/format.h> |
| 11 | 13 | ||
| 12 | namespace Shader { | 14 | namespace Shader { |
| 13 | 15 | ||
| 14 | class LogicError : public std::logic_error { | 16 | class Exception : public std::exception { |
| 17 | public: | ||
| 18 | explicit Exception(std::string message_) noexcept : message{std::move(message_)} {} | ||
| 19 | |||
| 20 | const char* what() const override { | ||
| 21 | return message.c_str(); | ||
| 22 | } | ||
| 23 | |||
| 24 | void Prepend(std::string_view prepend) { | ||
| 25 | message.insert(0, prepend); | ||
| 26 | } | ||
| 27 | |||
| 28 | void Append(std::string_view append) { | ||
| 29 | message += append; | ||
| 30 | } | ||
| 31 | |||
| 32 | private: | ||
| 33 | std::string message; | ||
| 34 | }; | ||
| 35 | |||
| 36 | class LogicError : public Exception { | ||
| 15 | public: | 37 | public: |
| 16 | template <typename... Args> | 38 | template <typename... Args> |
| 17 | LogicError(const char* message, Args&&... args) | 39 | LogicError(const char* message, Args&&... args) |
| 18 | : std::logic_error{fmt::format(message, std::forward<Args>(args)...)} {} | 40 | : Exception{fmt::format(message, std::forward<Args>(args)...)} {} |
| 19 | }; | 41 | }; |
| 20 | 42 | ||
| 21 | class RuntimeError : public std::runtime_error { | 43 | class RuntimeError : public Exception { |
| 22 | public: | 44 | public: |
| 23 | template <typename... Args> | 45 | template <typename... Args> |
| 24 | RuntimeError(const char* message, Args&&... args) | 46 | RuntimeError(const char* message, Args&&... args) |
| 25 | : std::runtime_error{fmt::format(message, std::forward<Args>(args)...)} {} | 47 | : Exception{fmt::format(message, std::forward<Args>(args)...)} {} |
| 26 | }; | 48 | }; |
| 27 | 49 | ||
| 28 | class NotImplementedException : public std::logic_error { | 50 | class NotImplementedException : public Exception { |
| 29 | public: | 51 | public: |
| 30 | template <typename... Args> | 52 | template <typename... Args> |
| 31 | NotImplementedException(const char* message, Args&&... args) | 53 | NotImplementedException(const char* message, Args&&... args) |
| 32 | : std::logic_error{fmt::format(message, std::forward<Args>(args)...)} {} | 54 | : Exception{fmt::format(message, std::forward<Args>(args)...)} { |
| 55 | Append(" is not implemented"); | ||
| 56 | } | ||
| 33 | }; | 57 | }; |
| 34 | 58 | ||
| 35 | class InvalidArgument : public std::invalid_argument { | 59 | class InvalidArgument : public Exception { |
| 36 | public: | 60 | public: |
| 37 | template <typename... Args> | 61 | template <typename... Args> |
| 38 | InvalidArgument(const char* message, Args&&... args) | 62 | InvalidArgument(const char* message, Args&&... args) |
| 39 | : std::invalid_argument{fmt::format(message, std::forward<Args>(args)...)} {} | 63 | : Exception{fmt::format(message, std::forward<Args>(args)...)} {} |
| 40 | }; | 64 | }; |
| 41 | 65 | ||
| 42 | } // namespace Shader | 66 | } // namespace Shader |
diff --git a/src/shader_recompiler/frontend/maxwell/opcodes.cpp b/src/shader_recompiler/frontend/maxwell/opcodes.cpp index 12ddf2ac9..ccc40c20c 100644 --- a/src/shader_recompiler/frontend/maxwell/opcodes.cpp +++ b/src/shader_recompiler/frontend/maxwell/opcodes.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | namespace Shader::Maxwell { | 10 | namespace Shader::Maxwell { |
| 11 | namespace { | 11 | namespace { |
| 12 | constexpr std::array NAME_TABLE{ | 12 | constexpr std::array NAME_TABLE{ |
| 13 | #define INST(name, cute, encode) #cute, | 13 | #define INST(name, cute, encode) cute, |
| 14 | #include "maxwell.inc" | 14 | #include "maxwell.inc" |
| 15 | #undef INST | 15 | #undef INST |
| 16 | }; | 16 | }; |
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index ccdab1dad..900fc7ab1 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <ranges> | 7 | #include <ranges> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | 9 | ||
| 10 | #include "shader_recompiler/exception.h" | ||
| 10 | #include "shader_recompiler/frontend/ir/basic_block.h" | 11 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 11 | #include "shader_recompiler/frontend/ir/post_order.h" | 12 | #include "shader_recompiler/frontend/ir/post_order.h" |
| 12 | #include "shader_recompiler/frontend/maxwell/program.h" | 13 | #include "shader_recompiler/frontend/maxwell/program.h" |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/translate.cpp b/src/shader_recompiler/frontend/maxwell/translate/translate.cpp index 0f4e7a251..8e3c4c5d5 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/translate.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/translate.cpp | |||
| @@ -30,16 +30,21 @@ void Translate(Environment& env, IR::Block* block, u32 location_begin, u32 locat | |||
| 30 | TranslatorVisitor visitor{env, *block}; | 30 | TranslatorVisitor visitor{env, *block}; |
| 31 | for (Location pc = location_begin; pc != location_end; ++pc) { | 31 | for (Location pc = location_begin; pc != location_end; ++pc) { |
| 32 | const u64 insn{env.ReadInstruction(pc.Offset())}; | 32 | const u64 insn{env.ReadInstruction(pc.Offset())}; |
| 33 | const Opcode opcode{Decode(insn)}; | 33 | try { |
| 34 | switch (opcode) { | 34 | const Opcode opcode{Decode(insn)}; |
| 35 | switch (opcode) { | ||
| 35 | #define INST(name, cute, mask) \ | 36 | #define INST(name, cute, mask) \ |
| 36 | case Opcode::name: \ | 37 | case Opcode::name: \ |
| 37 | Invoke<&TranslatorVisitor::name>(visitor, pc, insn); \ | 38 | Invoke<&TranslatorVisitor::name>(visitor, pc, insn); \ |
| 38 | break; | 39 | break; |
| 39 | #include "shader_recompiler/frontend/maxwell/maxwell.inc" | 40 | #include "shader_recompiler/frontend/maxwell/maxwell.inc" |
| 40 | #undef OPCODE | 41 | #undef OPCODE |
| 41 | default: | 42 | default: |
| 42 | throw LogicError("Invalid opcode {}", opcode); | 43 | throw LogicError("Invalid opcode {}", opcode); |
| 44 | } | ||
| 45 | } catch (Exception& exception) { | ||
| 46 | exception.Prepend(fmt::format("Translate {}: ", Decode(insn))); | ||
| 47 | throw; | ||
| 43 | } | 48 | } |
| 44 | } | 49 | } |
| 45 | } | 50 | } |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 5d4e80364..54696d97d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -221,7 +221,9 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 221 | SyncState(); | 221 | SyncState(); |
| 222 | 222 | ||
| 223 | GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; | 223 | GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; |
| 224 | 224 | if (!pipeline) { | |
| 225 | return; | ||
| 226 | } | ||
| 225 | std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; | 227 | std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; |
| 226 | pipeline->Configure(is_indexed); | 228 | pipeline->Configure(is_indexed); |
| 227 | 229 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 287f497b5..7d2ec4efa 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -45,6 +45,7 @@ using VideoCommon::ComputeEnvironment; | |||
| 45 | using VideoCommon::FileEnvironment; | 45 | using VideoCommon::FileEnvironment; |
| 46 | using VideoCommon::GenericEnvironment; | 46 | using VideoCommon::GenericEnvironment; |
| 47 | using VideoCommon::GraphicsEnvironment; | 47 | using VideoCommon::GraphicsEnvironment; |
| 48 | using VideoCommon::SerializePipeline; | ||
| 48 | 49 | ||
| 49 | template <typename Container> | 50 | template <typename Container> |
| 50 | auto MakeSpan(Container& container) { | 51 | auto MakeSpan(Container& container) { |
| @@ -327,10 +328,11 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, | |||
| 327 | workers.QueueWork( | 328 | workers.QueueWork( |
| 328 | [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { | 329 | [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { |
| 329 | ctx->pools.ReleaseContents(); | 330 | ctx->pools.ReleaseContents(); |
| 330 | auto pipeline{CreateComputePipeline(ctx->pools, key, env, false)}; | 331 | auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; |
| 331 | |||
| 332 | std::lock_guard lock{state.mutex}; | 332 | std::lock_guard lock{state.mutex}; |
| 333 | compute_cache.emplace(key, std::move(pipeline)); | 333 | if (pipeline) { |
| 334 | compute_cache.emplace(key, std::move(pipeline)); | ||
| 335 | } | ||
| 334 | ++state.built; | 336 | ++state.built; |
| 335 | if (state.has_loaded) { | 337 | if (state.has_loaded) { |
| 336 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); | 338 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); |
| @@ -348,10 +350,11 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, | |||
| 348 | env_ptrs.push_back(&env); | 350 | env_ptrs.push_back(&env); |
| 349 | } | 351 | } |
| 350 | ctx->pools.ReleaseContents(); | 352 | ctx->pools.ReleaseContents(); |
| 351 | auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)}; | 353 | auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs))}; |
| 352 | |||
| 353 | std::lock_guard lock{state.mutex}; | 354 | std::lock_guard lock{state.mutex}; |
| 354 | graphics_cache.emplace(key, std::move(pipeline)); | 355 | if (pipeline) { |
| 356 | graphics_cache.emplace(key, std::move(pipeline)); | ||
| 357 | } | ||
| 355 | ++state.built; | 358 | ++state.built; |
| 356 | if (state.has_loaded) { | 359 | if (state.has_loaded) { |
| 357 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); | 360 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); |
| @@ -419,8 +422,8 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline() { | |||
| 419 | GetGraphicsEnvironments(environments, graphics_key.unique_hashes); | 422 | GetGraphicsEnvironments(environments, graphics_key.unique_hashes); |
| 420 | 423 | ||
| 421 | main_pools.ReleaseContents(); | 424 | main_pools.ReleaseContents(); |
| 422 | auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)}; | 425 | auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span())}; |
| 423 | if (shader_cache_filename.empty()) { | 426 | if (!pipeline || shader_cache_filename.empty()) { |
| 424 | return pipeline; | 427 | return pipeline; |
| 425 | } | 428 | } |
| 426 | boost::container::static_vector<const GenericEnvironment*, Maxwell::MaxShaderProgram> env_ptrs; | 429 | boost::container::static_vector<const GenericEnvironment*, Maxwell::MaxShaderProgram> env_ptrs; |
| @@ -429,13 +432,13 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline() { | |||
| 429 | env_ptrs.push_back(&environments.envs[index]); | 432 | env_ptrs.push_back(&environments.envs[index]); |
| 430 | } | 433 | } |
| 431 | } | 434 | } |
| 432 | VideoCommon::SerializePipeline(graphics_key, env_ptrs, shader_cache_filename); | 435 | SerializePipeline(graphics_key, env_ptrs, shader_cache_filename); |
| 433 | return pipeline; | 436 | return pipeline; |
| 434 | } | 437 | } |
| 435 | 438 | ||
| 436 | std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | 439 | std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( |
| 437 | ShaderPools& pools, const GraphicsPipelineKey& key, std::span<Shader::Environment* const> envs, | 440 | ShaderPools& pools, const GraphicsPipelineKey& key, |
| 438 | bool build_in_parallel) { | 441 | std::span<Shader::Environment* const> envs) try { |
| 439 | LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash()); | 442 | LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash()); |
| 440 | size_t env_index{}; | 443 | size_t env_index{}; |
| 441 | u32 total_storage_buffers{}; | 444 | u32 total_storage_buffers{}; |
| @@ -492,6 +495,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||
| 492 | device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker, | 495 | device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker, |
| 493 | std::move(source_program), std::move(assembly_programs), infos, | 496 | std::move(source_program), std::move(assembly_programs), infos, |
| 494 | key.xfb_enabled != 0 ? &key.xfb_state : nullptr); | 497 | key.xfb_enabled != 0 ? &key.xfb_state : nullptr); |
| 498 | |||
| 499 | } catch (Shader::Exception& exception) { | ||
| 500 | LOG_ERROR(Render_OpenGL, "{}", exception.what()); | ||
| 501 | return nullptr; | ||
| 495 | } | 502 | } |
| 496 | 503 | ||
| 497 | std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline( | 504 | std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline( |
| @@ -502,18 +509,17 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline( | |||
| 502 | env.SetCachedSize(shader->size_bytes); | 509 | env.SetCachedSize(shader->size_bytes); |
| 503 | 510 | ||
| 504 | main_pools.ReleaseContents(); | 511 | main_pools.ReleaseContents(); |
| 505 | auto pipeline{CreateComputePipeline(main_pools, key, env, true)}; | 512 | auto pipeline{CreateComputePipeline(main_pools, key, env)}; |
| 506 | if (!shader_cache_filename.empty()) { | 513 | if (!pipeline || shader_cache_filename.empty()) { |
| 507 | VideoCommon::SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, | 514 | return pipeline; |
| 508 | shader_cache_filename); | ||
| 509 | } | 515 | } |
| 516 | SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, shader_cache_filename); | ||
| 510 | return pipeline; | 517 | return pipeline; |
| 511 | } | 518 | } |
| 512 | 519 | ||
| 513 | std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& pools, | 520 | std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& pools, |
| 514 | const ComputePipelineKey& key, | 521 | const ComputePipelineKey& key, |
| 515 | Shader::Environment& env, | 522 | Shader::Environment& env) try { |
| 516 | bool build_in_parallel) { | ||
| 517 | LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash()); | 523 | LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash()); |
| 518 | 524 | ||
| 519 | Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()}; | 525 | Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()}; |
| @@ -540,6 +546,9 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& | |||
| 540 | return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory, | 546 | return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory, |
| 541 | kepler_compute, program_manager, program.info, | 547 | kepler_compute, program_manager, program.info, |
| 542 | std::move(source_program), std::move(asm_program)); | 548 | std::move(source_program), std::move(asm_program)); |
| 549 | } catch (Shader::Exception& exception) { | ||
| 550 | LOG_ERROR(Render_OpenGL, "{}", exception.what()); | ||
| 551 | return nullptr; | ||
| 543 | } | 552 | } |
| 544 | 553 | ||
| 545 | } // namespace OpenGL | 554 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 16175318b..cf74d34e4 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -65,15 +65,14 @@ private: | |||
| 65 | 65 | ||
| 66 | std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline( | 66 | std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline( |
| 67 | ShaderPools& pools, const GraphicsPipelineKey& key, | 67 | ShaderPools& pools, const GraphicsPipelineKey& key, |
| 68 | std::span<Shader::Environment* const> envs, bool build_in_parallel); | 68 | std::span<Shader::Environment* const> envs); |
| 69 | 69 | ||
| 70 | std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineKey& key, | 70 | std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineKey& key, |
| 71 | const VideoCommon::ShaderInfo* shader); | 71 | const VideoCommon::ShaderInfo* shader); |
| 72 | 72 | ||
| 73 | std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderPools& pools, | 73 | std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderPools& pools, |
| 74 | const ComputePipelineKey& key, | 74 | const ComputePipelineKey& key, |
| 75 | Shader::Environment& env, | 75 | Shader::Environment& env); |
| 76 | bool build_in_parallel); | ||
| 77 | 76 | ||
| 78 | Core::Frontend::EmuWindow& emu_window; | 77 | Core::Frontend::EmuWindow& emu_window; |
| 79 | const Device& device; | 78 | const Device& device; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index f86bf9c30..b6998e37c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -303,6 +303,9 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() { | |||
| 303 | if (is_new) { | 303 | if (is_new) { |
| 304 | pipeline = CreateGraphicsPipeline(); | 304 | pipeline = CreateGraphicsPipeline(); |
| 305 | } | 305 | } |
| 306 | if (!pipeline) { | ||
| 307 | return nullptr; | ||
| 308 | } | ||
| 306 | if (current_pipeline) { | 309 | if (current_pipeline) { |
| 307 | current_pipeline->AddTransition(pipeline.get()); | 310 | current_pipeline->AddTransition(pipeline.get()); |
| 308 | } | 311 | } |
| @@ -362,9 +365,10 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading | |||
| 362 | workers.QueueWork([this, key, env = std::move(env), &state, &callback]() mutable { | 365 | workers.QueueWork([this, key, env = std::move(env), &state, &callback]() mutable { |
| 363 | ShaderPools pools; | 366 | ShaderPools pools; |
| 364 | auto pipeline{CreateComputePipeline(pools, key, env, false)}; | 367 | auto pipeline{CreateComputePipeline(pools, key, env, false)}; |
| 365 | |||
| 366 | std::lock_guard lock{state.mutex}; | 368 | std::lock_guard lock{state.mutex}; |
| 367 | compute_cache.emplace(key, std::move(pipeline)); | 369 | if (pipeline) { |
| 370 | compute_cache.emplace(key, std::move(pipeline)); | ||
| 371 | } | ||
| 368 | ++state.built; | 372 | ++state.built; |
| 369 | if (state.has_loaded) { | 373 | if (state.has_loaded) { |
| 370 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); | 374 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); |
| @@ -405,7 +409,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading | |||
| 405 | 409 | ||
| 406 | std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | 410 | std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( |
| 407 | ShaderPools& pools, const GraphicsPipelineCacheKey& key, | 411 | ShaderPools& pools, const GraphicsPipelineCacheKey& key, |
| 408 | std::span<Shader::Environment* const> envs, bool build_in_parallel) { | 412 | std::span<Shader::Environment* const> envs, bool build_in_parallel) try { |
| 409 | LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash()); | 413 | LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash()); |
| 410 | size_t env_index{0}; | 414 | size_t env_index{0}; |
| 411 | std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs; | 415 | std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs; |
| @@ -458,6 +462,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | |||
| 458 | return std::make_unique<GraphicsPipeline>( | 462 | return std::make_unique<GraphicsPipeline>( |
| 459 | maxwell3d, gpu_memory, scheduler, buffer_cache, texture_cache, device, descriptor_pool, | 463 | maxwell3d, gpu_memory, scheduler, buffer_cache, texture_cache, device, descriptor_pool, |
| 460 | update_descriptor_queue, thread_worker, render_pass_cache, key, std::move(modules), infos); | 464 | update_descriptor_queue, thread_worker, render_pass_cache, key, std::move(modules), infos); |
| 465 | |||
| 466 | } catch (const Shader::Exception& exception) { | ||
| 467 | LOG_ERROR(Render_Vulkan, "{}", exception.what()); | ||
| 468 | return nullptr; | ||
| 461 | } | 469 | } |
| 462 | 470 | ||
| 463 | std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() { | 471 | std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() { |
| @@ -466,7 +474,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() { | |||
| 466 | 474 | ||
| 467 | main_pools.ReleaseContents(); | 475 | main_pools.ReleaseContents(); |
| 468 | auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)}; | 476 | auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)}; |
| 469 | if (pipeline_cache_filename.empty()) { | 477 | if (!pipeline || pipeline_cache_filename.empty()) { |
| 470 | return pipeline; | 478 | return pipeline; |
| 471 | } | 479 | } |
| 472 | serialization_thread.QueueWork([this, key = graphics_key, envs = std::move(environments.envs)] { | 480 | serialization_thread.QueueWork([this, key = graphics_key, envs = std::move(environments.envs)] { |
| @@ -477,7 +485,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() { | |||
| 477 | env_ptrs.push_back(&envs[index]); | 485 | env_ptrs.push_back(&envs[index]); |
| 478 | } | 486 | } |
| 479 | } | 487 | } |
| 480 | VideoCommon::SerializePipeline(key, env_ptrs, pipeline_cache_filename); | 488 | SerializePipeline(key, env_ptrs, pipeline_cache_filename); |
| 481 | }); | 489 | }); |
| 482 | return pipeline; | 490 | return pipeline; |
| 483 | } | 491 | } |
| @@ -491,18 +499,19 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( | |||
| 491 | 499 | ||
| 492 | main_pools.ReleaseContents(); | 500 | main_pools.ReleaseContents(); |
| 493 | auto pipeline{CreateComputePipeline(main_pools, key, env, true)}; | 501 | auto pipeline{CreateComputePipeline(main_pools, key, env, true)}; |
| 494 | if (!pipeline_cache_filename.empty()) { | 502 | if (!pipeline || pipeline_cache_filename.empty()) { |
| 495 | serialization_thread.QueueWork([this, key, env = std::move(env)] { | 503 | return pipeline; |
| 496 | VideoCommon::SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, | ||
| 497 | pipeline_cache_filename); | ||
| 498 | }); | ||
| 499 | } | 504 | } |
| 505 | serialization_thread.QueueWork([this, key, env = std::move(env)] { | ||
| 506 | SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, | ||
| 507 | pipeline_cache_filename); | ||
| 508 | }); | ||
| 500 | return pipeline; | 509 | return pipeline; |
| 501 | } | 510 | } |
| 502 | 511 | ||
| 503 | std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( | 512 | std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( |
| 504 | ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env, | 513 | ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env, |
| 505 | bool build_in_parallel) { | 514 | bool build_in_parallel) try { |
| 506 | LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash()); | 515 | LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash()); |
| 507 | 516 | ||
| 508 | Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()}; | 517 | Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()}; |
| @@ -517,6 +526,10 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( | |||
| 517 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; | 526 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; |
| 518 | return std::make_unique<ComputePipeline>(device, descriptor_pool, update_descriptor_queue, | 527 | return std::make_unique<ComputePipeline>(device, descriptor_pool, update_descriptor_queue, |
| 519 | thread_worker, program.info, std::move(spv_module)); | 528 | thread_worker, program.info, std::move(spv_module)); |
| 529 | |||
| 530 | } catch (const Shader::Exception& exception) { | ||
| 531 | LOG_ERROR(Render_Vulkan, "{}", exception.what()); | ||
| 532 | return nullptr; | ||
| 520 | } | 533 | } |
| 521 | 534 | ||
| 522 | } // namespace Vulkan | 535 | } // namespace Vulkan |