summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-27 17:51:00 -0300
committerGravatar ameerj2021-07-22 21:51:34 -0400
commitb7764c3a796e53ac74009bc7d7cd153c64b6d743 (patch)
tree592a8be7cd43349cbabfc3d84693b443ddc0b5d8 /src
parentglasm: Use integer lod for TXQ (diff)
downloadyuzu-b7764c3a796e53ac74009bc7d7cd153c64b6d743.tar.gz
yuzu-b7764c3a796e53ac74009bc7d7cd153c64b6d743.tar.xz
yuzu-b7764c3a796e53ac74009bc7d7cd153c64b6d743.zip
shader: Handle host exceptions
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/exception.h40
-rw-r--r--src/shader_recompiler/frontend/maxwell/opcodes.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/program.cpp1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/translate.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp43
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h5
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp35
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
12namespace Shader { 14namespace Shader {
13 15
14class LogicError : public std::logic_error { 16class Exception : public std::exception {
17public:
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
32private:
33 std::string message;
34};
35
36class LogicError : public Exception {
15public: 37public:
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
21class RuntimeError : public std::runtime_error { 43class RuntimeError : public Exception {
22public: 44public:
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
28class NotImplementedException : public std::logic_error { 50class NotImplementedException : public Exception {
29public: 51public:
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
35class InvalidArgument : public std::invalid_argument { 59class InvalidArgument : public Exception {
36public: 60public:
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 @@
10namespace Shader::Maxwell { 10namespace Shader::Maxwell {
11namespace { 11namespace {
12constexpr std::array NAME_TABLE{ 12constexpr 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;
45using VideoCommon::FileEnvironment; 45using VideoCommon::FileEnvironment;
46using VideoCommon::GenericEnvironment; 46using VideoCommon::GenericEnvironment;
47using VideoCommon::GraphicsEnvironment; 47using VideoCommon::GraphicsEnvironment;
48using VideoCommon::SerializePipeline;
48 49
49template <typename Container> 50template <typename Container>
50auto MakeSpan(Container& container) { 51auto 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
436std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( 439std::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
497std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline( 504std::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
513std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& pools, 520std::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
406std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( 410std::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
463std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() { 471std::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
503std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( 512std::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