summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-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
4 files changed, 55 insertions, 32 deletions
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) {
SyncState();
GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()};
-
+ if (!pipeline) {
+ return;
+ }
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
pipeline->Configure(is_indexed);
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;
using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment;
using VideoCommon::GraphicsEnvironment;
+using VideoCommon::SerializePipeline;
template <typename Container>
auto MakeSpan(Container& container) {
@@ -327,10 +328,11 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
workers.QueueWork(
[this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
ctx->pools.ReleaseContents();
- auto pipeline{CreateComputePipeline(ctx->pools, key, env, false)};
-
+ auto pipeline{CreateComputePipeline(ctx->pools, key, env)};
std::lock_guard lock{state.mutex};
- compute_cache.emplace(key, std::move(pipeline));
+ if (pipeline) {
+ compute_cache.emplace(key, std::move(pipeline));
+ }
++state.built;
if (state.has_loaded) {
callback(VideoCore::LoadCallbackStage::Build, state.built, state.total);
@@ -348,10 +350,11 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
env_ptrs.push_back(&env);
}
ctx->pools.ReleaseContents();
- auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)};
-
+ auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs))};
std::lock_guard lock{state.mutex};
- graphics_cache.emplace(key, std::move(pipeline));
+ if (pipeline) {
+ graphics_cache.emplace(key, std::move(pipeline));
+ }
++state.built;
if (state.has_loaded) {
callback(VideoCore::LoadCallbackStage::Build, state.built, state.total);
@@ -419,8 +422,8 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline() {
GetGraphicsEnvironments(environments, graphics_key.unique_hashes);
main_pools.ReleaseContents();
- auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)};
- if (shader_cache_filename.empty()) {
+ auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span())};
+ if (!pipeline || shader_cache_filename.empty()) {
return pipeline;
}
boost::container::static_vector<const GenericEnvironment*, Maxwell::MaxShaderProgram> env_ptrs;
@@ -429,13 +432,13 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline() {
env_ptrs.push_back(&environments.envs[index]);
}
}
- VideoCommon::SerializePipeline(graphics_key, env_ptrs, shader_cache_filename);
+ SerializePipeline(graphics_key, env_ptrs, shader_cache_filename);
return pipeline;
}
std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
- ShaderPools& pools, const GraphicsPipelineKey& key, std::span<Shader::Environment* const> envs,
- bool build_in_parallel) {
+ ShaderPools& pools, const GraphicsPipelineKey& key,
+ std::span<Shader::Environment* const> envs) try {
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
size_t env_index{};
u32 total_storage_buffers{};
@@ -492,6 +495,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
std::move(source_program), std::move(assembly_programs), infos,
key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
+
+} catch (Shader::Exception& exception) {
+ LOG_ERROR(Render_OpenGL, "{}", exception.what());
+ return nullptr;
}
std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
@@ -502,18 +509,17 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
env.SetCachedSize(shader->size_bytes);
main_pools.ReleaseContents();
- auto pipeline{CreateComputePipeline(main_pools, key, env, true)};
- if (!shader_cache_filename.empty()) {
- VideoCommon::SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
- shader_cache_filename);
+ auto pipeline{CreateComputePipeline(main_pools, key, env)};
+ if (!pipeline || shader_cache_filename.empty()) {
+ return pipeline;
}
+ SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, shader_cache_filename);
return pipeline;
}
std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& pools,
const ComputePipelineKey& key,
- Shader::Environment& env,
- bool build_in_parallel) {
+ Shader::Environment& env) try {
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
@@ -540,6 +546,9 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools&
return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory,
kepler_compute, program_manager, program.info,
std::move(source_program), std::move(asm_program));
+} catch (Shader::Exception& exception) {
+ LOG_ERROR(Render_OpenGL, "{}", exception.what());
+ return nullptr;
}
} // 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:
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
ShaderPools& pools, const GraphicsPipelineKey& key,
- std::span<Shader::Environment* const> envs, bool build_in_parallel);
+ std::span<Shader::Environment* const> envs);
std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineKey& key,
const VideoCommon::ShaderInfo* shader);
std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderPools& pools,
const ComputePipelineKey& key,
- Shader::Environment& env,
- bool build_in_parallel);
+ Shader::Environment& env);
Core::Frontend::EmuWindow& emu_window;
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() {
if (is_new) {
pipeline = CreateGraphicsPipeline();
}
+ if (!pipeline) {
+ return nullptr;
+ }
if (current_pipeline) {
current_pipeline->AddTransition(pipeline.get());
}
@@ -362,9 +365,10 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
workers.QueueWork([this, key, env = std::move(env), &state, &callback]() mutable {
ShaderPools pools;
auto pipeline{CreateComputePipeline(pools, key, env, false)};
-
std::lock_guard lock{state.mutex};
- compute_cache.emplace(key, std::move(pipeline));
+ if (pipeline) {
+ compute_cache.emplace(key, std::move(pipeline));
+ }
++state.built;
if (state.has_loaded) {
callback(VideoCore::LoadCallbackStage::Build, state.built, state.total);
@@ -405,7 +409,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
ShaderPools& pools, const GraphicsPipelineCacheKey& key,
- std::span<Shader::Environment* const> envs, bool build_in_parallel) {
+ std::span<Shader::Environment* const> envs, bool build_in_parallel) try {
LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash());
size_t env_index{0};
std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs;
@@ -458,6 +462,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
return std::make_unique<GraphicsPipeline>(
maxwell3d, gpu_memory, scheduler, buffer_cache, texture_cache, device, descriptor_pool,
update_descriptor_queue, thread_worker, render_pass_cache, key, std::move(modules), infos);
+
+} catch (const Shader::Exception& exception) {
+ LOG_ERROR(Render_Vulkan, "{}", exception.what());
+ return nullptr;
}
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
@@ -466,7 +474,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
main_pools.ReleaseContents();
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)};
- if (pipeline_cache_filename.empty()) {
+ if (!pipeline || pipeline_cache_filename.empty()) {
return pipeline;
}
serialization_thread.QueueWork([this, key = graphics_key, envs = std::move(environments.envs)] {
@@ -477,7 +485,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
env_ptrs.push_back(&envs[index]);
}
}
- VideoCommon::SerializePipeline(key, env_ptrs, pipeline_cache_filename);
+ SerializePipeline(key, env_ptrs, pipeline_cache_filename);
});
return pipeline;
}
@@ -491,18 +499,19 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
main_pools.ReleaseContents();
auto pipeline{CreateComputePipeline(main_pools, key, env, true)};
- if (!pipeline_cache_filename.empty()) {
- serialization_thread.QueueWork([this, key, env = std::move(env)] {
- VideoCommon::SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
- pipeline_cache_filename);
- });
+ if (!pipeline || pipeline_cache_filename.empty()) {
+ return pipeline;
}
+ serialization_thread.QueueWork([this, key, env = std::move(env)] {
+ SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
+ pipeline_cache_filename);
+ });
return pipeline;
}
std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env,
- bool build_in_parallel) {
+ bool build_in_parallel) try {
LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash());
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
@@ -517,6 +526,10 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr};
return std::make_unique<ComputePipeline>(device, descriptor_pool, update_descriptor_queue,
thread_worker, program.info, std::move(spv_module));
+
+} catch (const Shader::Exception& exception) {
+ LOG_ERROR(Render_Vulkan, "{}", exception.what());
+ return nullptr;
}
} // namespace Vulkan