mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-27 01:02:48 +01:00
shader: Handle host exceptions
This commit is contained in:
parent
83db7abae6
commit
b7764c3a79
8 changed files with 98 additions and 45 deletions
|
@ -5,38 +5,62 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
class LogicError : public std::logic_error {
|
class Exception : public std::exception {
|
||||||
|
public:
|
||||||
|
explicit Exception(std::string message_) noexcept : message{std::move(message_)} {}
|
||||||
|
|
||||||
|
const char* what() const override {
|
||||||
|
return message.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Prepend(std::string_view prepend) {
|
||||||
|
message.insert(0, prepend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append(std::string_view append) {
|
||||||
|
message += append;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LogicError : public Exception {
|
||||||
public:
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
LogicError(const char* message, Args&&... args)
|
LogicError(const char* message, Args&&... args)
|
||||||
: std::logic_error{fmt::format(message, std::forward<Args>(args)...)} {}
|
: Exception{fmt::format(message, std::forward<Args>(args)...)} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RuntimeError : public std::runtime_error {
|
class RuntimeError : public Exception {
|
||||||
public:
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
RuntimeError(const char* message, Args&&... args)
|
RuntimeError(const char* message, Args&&... args)
|
||||||
: std::runtime_error{fmt::format(message, std::forward<Args>(args)...)} {}
|
: Exception{fmt::format(message, std::forward<Args>(args)...)} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotImplementedException : public std::logic_error {
|
class NotImplementedException : public Exception {
|
||||||
public:
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
NotImplementedException(const char* message, Args&&... args)
|
NotImplementedException(const char* message, Args&&... args)
|
||||||
: std::logic_error{fmt::format(message, std::forward<Args>(args)...)} {}
|
: Exception{fmt::format(message, std::forward<Args>(args)...)} {
|
||||||
|
Append(" is not implemented");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class InvalidArgument : public std::invalid_argument {
|
class InvalidArgument : public Exception {
|
||||||
public:
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
InvalidArgument(const char* message, Args&&... args)
|
InvalidArgument(const char* message, Args&&... args)
|
||||||
: std::invalid_argument{fmt::format(message, std::forward<Args>(args)...)} {}
|
: Exception{fmt::format(message, std::forward<Args>(args)...)} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Shader
|
} // namespace Shader
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Shader::Maxwell {
|
namespace Shader::Maxwell {
|
||||||
namespace {
|
namespace {
|
||||||
constexpr std::array NAME_TABLE{
|
constexpr std::array NAME_TABLE{
|
||||||
#define INST(name, cute, encode) #cute,
|
#define INST(name, cute, encode) cute,
|
||||||
#include "maxwell.inc"
|
#include "maxwell.inc"
|
||||||
#undef INST
|
#undef INST
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "shader_recompiler/exception.h"
|
||||||
#include "shader_recompiler/frontend/ir/basic_block.h"
|
#include "shader_recompiler/frontend/ir/basic_block.h"
|
||||||
#include "shader_recompiler/frontend/ir/post_order.h"
|
#include "shader_recompiler/frontend/ir/post_order.h"
|
||||||
#include "shader_recompiler/frontend/maxwell/program.h"
|
#include "shader_recompiler/frontend/maxwell/program.h"
|
||||||
|
|
|
@ -30,16 +30,21 @@ void Translate(Environment& env, IR::Block* block, u32 location_begin, u32 locat
|
||||||
TranslatorVisitor visitor{env, *block};
|
TranslatorVisitor visitor{env, *block};
|
||||||
for (Location pc = location_begin; pc != location_end; ++pc) {
|
for (Location pc = location_begin; pc != location_end; ++pc) {
|
||||||
const u64 insn{env.ReadInstruction(pc.Offset())};
|
const u64 insn{env.ReadInstruction(pc.Offset())};
|
||||||
const Opcode opcode{Decode(insn)};
|
try {
|
||||||
switch (opcode) {
|
const Opcode opcode{Decode(insn)};
|
||||||
|
switch (opcode) {
|
||||||
#define INST(name, cute, mask) \
|
#define INST(name, cute, mask) \
|
||||||
case Opcode::name: \
|
case Opcode::name: \
|
||||||
Invoke<&TranslatorVisitor::name>(visitor, pc, insn); \
|
Invoke<&TranslatorVisitor::name>(visitor, pc, insn); \
|
||||||
break;
|
break;
|
||||||
#include "shader_recompiler/frontend/maxwell/maxwell.inc"
|
#include "shader_recompiler/frontend/maxwell/maxwell.inc"
|
||||||
#undef OPCODE
|
#undef OPCODE
|
||||||
default:
|
default:
|
||||||
throw LogicError("Invalid opcode {}", opcode);
|
throw LogicError("Invalid opcode {}", opcode);
|
||||||
|
}
|
||||||
|
} catch (Exception& exception) {
|
||||||
|
exception.Prepend(fmt::format("Translate {}: ", Decode(insn)));
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,9 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||||
SyncState();
|
SyncState();
|
||||||
|
|
||||||
GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()};
|
GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()};
|
||||||
|
if (!pipeline) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
||||||
pipeline->Configure(is_indexed);
|
pipeline->Configure(is_indexed);
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ using VideoCommon::ComputeEnvironment;
|
||||||
using VideoCommon::FileEnvironment;
|
using VideoCommon::FileEnvironment;
|
||||||
using VideoCommon::GenericEnvironment;
|
using VideoCommon::GenericEnvironment;
|
||||||
using VideoCommon::GraphicsEnvironment;
|
using VideoCommon::GraphicsEnvironment;
|
||||||
|
using VideoCommon::SerializePipeline;
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
auto MakeSpan(Container& container) {
|
auto MakeSpan(Container& container) {
|
||||||
|
@ -327,10 +328,11 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
||||||
workers.QueueWork(
|
workers.QueueWork(
|
||||||
[this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
|
[this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
|
||||||
ctx->pools.ReleaseContents();
|
ctx->pools.ReleaseContents();
|
||||||
auto pipeline{CreateComputePipeline(ctx->pools, key, env, false)};
|
auto pipeline{CreateComputePipeline(ctx->pools, key, env)};
|
||||||
|
|
||||||
std::lock_guard lock{state.mutex};
|
std::lock_guard lock{state.mutex};
|
||||||
compute_cache.emplace(key, std::move(pipeline));
|
if (pipeline) {
|
||||||
|
compute_cache.emplace(key, std::move(pipeline));
|
||||||
|
}
|
||||||
++state.built;
|
++state.built;
|
||||||
if (state.has_loaded) {
|
if (state.has_loaded) {
|
||||||
callback(VideoCore::LoadCallbackStage::Build, state.built, state.total);
|
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);
|
env_ptrs.push_back(&env);
|
||||||
}
|
}
|
||||||
ctx->pools.ReleaseContents();
|
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};
|
std::lock_guard lock{state.mutex};
|
||||||
graphics_cache.emplace(key, std::move(pipeline));
|
if (pipeline) {
|
||||||
|
graphics_cache.emplace(key, std::move(pipeline));
|
||||||
|
}
|
||||||
++state.built;
|
++state.built;
|
||||||
if (state.has_loaded) {
|
if (state.has_loaded) {
|
||||||
callback(VideoCore::LoadCallbackStage::Build, state.built, state.total);
|
callback(VideoCore::LoadCallbackStage::Build, state.built, state.total);
|
||||||
|
@ -419,8 +422,8 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline() {
|
||||||
GetGraphicsEnvironments(environments, graphics_key.unique_hashes);
|
GetGraphicsEnvironments(environments, graphics_key.unique_hashes);
|
||||||
|
|
||||||
main_pools.ReleaseContents();
|
main_pools.ReleaseContents();
|
||||||
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)};
|
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span())};
|
||||||
if (shader_cache_filename.empty()) {
|
if (!pipeline || shader_cache_filename.empty()) {
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
boost::container::static_vector<const GenericEnvironment*, Maxwell::MaxShaderProgram> env_ptrs;
|
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]);
|
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;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
||||||
ShaderPools& pools, const GraphicsPipelineKey& key, std::span<Shader::Environment* const> envs,
|
ShaderPools& pools, const GraphicsPipelineKey& key,
|
||||||
bool build_in_parallel) {
|
std::span<Shader::Environment* const> envs) try {
|
||||||
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
|
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
|
||||||
size_t env_index{};
|
size_t env_index{};
|
||||||
u32 total_storage_buffers{};
|
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,
|
device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
|
||||||
std::move(source_program), std::move(assembly_programs), infos,
|
std::move(source_program), std::move(assembly_programs), infos,
|
||||||
key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
|
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(
|
std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
||||||
|
@ -502,18 +509,17 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
||||||
env.SetCachedSize(shader->size_bytes);
|
env.SetCachedSize(shader->size_bytes);
|
||||||
|
|
||||||
main_pools.ReleaseContents();
|
main_pools.ReleaseContents();
|
||||||
auto pipeline{CreateComputePipeline(main_pools, key, env, true)};
|
auto pipeline{CreateComputePipeline(main_pools, key, env)};
|
||||||
if (!shader_cache_filename.empty()) {
|
if (!pipeline || shader_cache_filename.empty()) {
|
||||||
VideoCommon::SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
|
return pipeline;
|
||||||
shader_cache_filename);
|
|
||||||
}
|
}
|
||||||
|
SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, shader_cache_filename);
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& pools,
|
std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& pools,
|
||||||
const ComputePipelineKey& key,
|
const ComputePipelineKey& key,
|
||||||
Shader::Environment& env,
|
Shader::Environment& env) try {
|
||||||
bool build_in_parallel) {
|
|
||||||
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
|
LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
|
||||||
|
|
||||||
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
|
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,
|
return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory,
|
||||||
kepler_compute, program_manager, program.info,
|
kepler_compute, program_manager, program.info,
|
||||||
std::move(source_program), std::move(asm_program));
|
std::move(source_program), std::move(asm_program));
|
||||||
|
} catch (Shader::Exception& exception) {
|
||||||
|
LOG_ERROR(Render_OpenGL, "{}", exception.what());
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -65,15 +65,14 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
|
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
|
||||||
ShaderPools& pools, const GraphicsPipelineKey& key,
|
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,
|
std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineKey& key,
|
||||||
const VideoCommon::ShaderInfo* shader);
|
const VideoCommon::ShaderInfo* shader);
|
||||||
|
|
||||||
std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderPools& pools,
|
std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderPools& pools,
|
||||||
const ComputePipelineKey& key,
|
const ComputePipelineKey& key,
|
||||||
Shader::Environment& env,
|
Shader::Environment& env);
|
||||||
bool build_in_parallel);
|
|
||||||
|
|
||||||
Core::Frontend::EmuWindow& emu_window;
|
Core::Frontend::EmuWindow& emu_window;
|
||||||
const Device& device;
|
const Device& device;
|
||||||
|
|
|
@ -303,6 +303,9 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() {
|
||||||
if (is_new) {
|
if (is_new) {
|
||||||
pipeline = CreateGraphicsPipeline();
|
pipeline = CreateGraphicsPipeline();
|
||||||
}
|
}
|
||||||
|
if (!pipeline) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (current_pipeline) {
|
if (current_pipeline) {
|
||||||
current_pipeline->AddTransition(pipeline.get());
|
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 {
|
workers.QueueWork([this, key, env = std::move(env), &state, &callback]() mutable {
|
||||||
ShaderPools pools;
|
ShaderPools pools;
|
||||||
auto pipeline{CreateComputePipeline(pools, key, env, false)};
|
auto pipeline{CreateComputePipeline(pools, key, env, false)};
|
||||||
|
|
||||||
std::lock_guard lock{state.mutex};
|
std::lock_guard lock{state.mutex};
|
||||||
compute_cache.emplace(key, std::move(pipeline));
|
if (pipeline) {
|
||||||
|
compute_cache.emplace(key, std::move(pipeline));
|
||||||
|
}
|
||||||
++state.built;
|
++state.built;
|
||||||
if (state.has_loaded) {
|
if (state.has_loaded) {
|
||||||
callback(VideoCore::LoadCallbackStage::Build, state.built, state.total);
|
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(
|
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||||
ShaderPools& pools, const GraphicsPipelineCacheKey& key,
|
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());
|
LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash());
|
||||||
size_t env_index{0};
|
size_t env_index{0};
|
||||||
std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs;
|
std::array<Shader::IR::Program, Maxwell::MaxShaderProgram> programs;
|
||||||
|
@ -458,6 +462,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||||
return std::make_unique<GraphicsPipeline>(
|
return std::make_unique<GraphicsPipeline>(
|
||||||
maxwell3d, gpu_memory, scheduler, buffer_cache, texture_cache, device, descriptor_pool,
|
maxwell3d, gpu_memory, scheduler, buffer_cache, texture_cache, device, descriptor_pool,
|
||||||
update_descriptor_queue, thread_worker, render_pass_cache, key, std::move(modules), infos);
|
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() {
|
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
|
||||||
|
@ -466,7 +474,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
|
||||||
|
|
||||||
main_pools.ReleaseContents();
|
main_pools.ReleaseContents();
|
||||||
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)};
|
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), true)};
|
||||||
if (pipeline_cache_filename.empty()) {
|
if (!pipeline || pipeline_cache_filename.empty()) {
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
serialization_thread.QueueWork([this, key = graphics_key, envs = std::move(environments.envs)] {
|
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]);
|
env_ptrs.push_back(&envs[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VideoCommon::SerializePipeline(key, env_ptrs, pipeline_cache_filename);
|
SerializePipeline(key, env_ptrs, pipeline_cache_filename);
|
||||||
});
|
});
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
@ -491,18 +499,19 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
||||||
|
|
||||||
main_pools.ReleaseContents();
|
main_pools.ReleaseContents();
|
||||||
auto pipeline{CreateComputePipeline(main_pools, key, env, true)};
|
auto pipeline{CreateComputePipeline(main_pools, key, env, true)};
|
||||||
if (!pipeline_cache_filename.empty()) {
|
if (!pipeline || pipeline_cache_filename.empty()) {
|
||||||
serialization_thread.QueueWork([this, key, env = std::move(env)] {
|
return pipeline;
|
||||||
VideoCommon::SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
|
|
||||||
pipeline_cache_filename);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
serialization_thread.QueueWork([this, key, env = std::move(env)] {
|
||||||
|
SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
|
||||||
|
pipeline_cache_filename);
|
||||||
|
});
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
||||||
ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env,
|
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());
|
LOG_INFO(Render_Vulkan, "0x{:016x}", key.Hash());
|
||||||
|
|
||||||
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
|
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};
|
Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr};
|
||||||
return std::make_unique<ComputePipeline>(device, descriptor_pool, update_descriptor_queue,
|
return std::make_unique<ComputePipeline>(device, descriptor_pool, update_descriptor_queue,
|
||||||
thread_worker, program.info, std::move(spv_module));
|
thread_worker, program.info, std::move(spv_module));
|
||||||
|
|
||||||
|
} catch (const Shader::Exception& exception) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "{}", exception.what());
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
Loading…
Reference in a new issue