diff --git a/src/graphics/shader/recompiler/backend/spirv/SpirvEmitter.cpp b/src/graphics/shader/recompiler/backend/spirv/SpirvEmitter.cpp index 73b9a94..8a1588d 100644 --- a/src/graphics/shader/recompiler/backend/spirv/SpirvEmitter.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/SpirvEmitter.cpp @@ -2,6 +2,7 @@ #include "graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h" #include "graphics/shader/recompiler/ir/ValueProgram.h" +#include "graphics/shader/shader.h" #include #include @@ -10,14 +11,9 @@ namespace Libs::Graphics::ShaderRecompiler::Spirv { -namespace { +using ShaderError::Fail; -bool Fail(std::string* error, const std::string& message) { - if (error != nullptr) { - *error = message; - } - return false; -} +namespace { bool ImageBinding(const IR::ImageResource& image, IR::DescriptorBindingKind& kind) { using Kind = IR::DescriptorBindingKind; diff --git a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp index 45188f4..635c1d8 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp @@ -1,4 +1,5 @@ #include "graphics/shader/recompiler/frontend/translate/Translator.h" +#include "graphics/shader/shader.h" #include #include @@ -6,14 +7,10 @@ #include namespace Libs::Graphics::ShaderRecompiler::Frontend { -namespace Detail { -bool Fail(std::string* error, const std::string& message) { - if (error != nullptr) { - *error = message; - } - return false; -} +using ShaderError::Fail; + +namespace Detail { IR::Operand Translator::OffsetOperand(const IR::Operand& operand, uint32_t offset) { if (offset == 0 || operand.kind != IR::OperandKind::Register) { @@ -808,7 +805,7 @@ bool TranslateProgram(const IR::Program& source, IR::ValueProgram& result, return block.id; })->id; if (max_id == UINT32_MAX) { - return Detail::Fail(error, "cannot allocate a typed prologue block id"); + return Fail(error, "cannot allocate a typed prologue block id"); } CFG::Terminator terminator; terminator.kind = CFG::TerminatorKind::Branch; @@ -827,7 +824,7 @@ bool TranslateProgram(const IR::Program& source, IR::ValueProgram& result, for (size_t index = 0; index < source.blocks.size(); index++) { for (const auto successor: source.blocks[index].successors) { if (successor >= source.blocks.size()) { - return Detail::Fail(error, "value IR block successor is out of range"); + return Fail(error, "value IR block successor is out of range"); } result.blocks[index + 1u]->AddBranch(result.blocks[successor + 1u]); } diff --git a/src/graphics/shader/recompiler/frontend/translate/Translator.h b/src/graphics/shader/recompiler/frontend/translate/Translator.h index f6eef90..35c4493 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translator.h +++ b/src/graphics/shader/recompiler/frontend/translate/Translator.h @@ -18,8 +18,6 @@ struct ScalarMemorySourceValues { IR::U32 offset; }; -bool Fail(std::string* error, const std::string& message); - class Translator { public: Translator(IR::ValueProgram& program, IR::Block* block, uint32_t vector_limit, diff --git a/src/graphics/shader/recompiler/ir/ValueProgram.cpp b/src/graphics/shader/recompiler/ir/ValueProgram.cpp index 8887618..15f9fdc 100644 --- a/src/graphics/shader/recompiler/ir/ValueProgram.cpp +++ b/src/graphics/shader/recompiler/ir/ValueProgram.cpp @@ -1,18 +1,16 @@ #include "graphics/shader/recompiler/ir/ValueProgram.h" +#include "graphics/shader/shader.h" + #include #include #include namespace Libs::Graphics::ShaderRecompiler::IR { -namespace { -bool Fail(std::string* error, const std::string& message) { - if (error != nullptr) { - *error = message; - } - return false; -} +using ShaderError::Fail; + +namespace { bool IsRegisterGet(ValueOpcode opcode) { switch (opcode) { diff --git a/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp b/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp index 27f21b8..877b985 100644 --- a/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp +++ b/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp @@ -2,6 +2,7 @@ #include "graphics/shader/recompiler/ir/ValueProgram.h" #include "graphics/shader/recompiler/ir/passes/SrtWalker.h" +#include "graphics/shader/shader.h" #include #include @@ -215,11 +216,9 @@ private: }; bool Fail(uint32_t pc, std::string* error, const std::string& reason) const { - if (error != nullptr) { - *error = fmt::format("shader resource tracking: hash=0x{:016x} stage={} pc=0x{:08x} {}", - m_program.shader_hash, StageName(m_program.stage), pc, reason); - } - return false; + return ShaderError::Fail( + error, fmt::format("shader resource tracking: hash=0x{:016x} stage={} pc=0x{:08x} {}", + m_program.shader_hash, StageName(m_program.stage), pc, reason)); } struct AddressPart { diff --git a/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp b/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp index 05c9d43..8aeedee 100644 --- a/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp +++ b/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp @@ -1,6 +1,7 @@ #include "graphics/shader/recompiler/ir/passes/SrtWalker.h" #include "graphics/shader/recompiler/ir/ValueProgram.h" +#include "graphics/shader/shader.h" #include #include @@ -314,10 +315,7 @@ private: }; bool Fail(uint32_t pc, std::string* error, const std::string& message) const { - if (error != nullptr) { - *error = Diagnostic(m_program, pc, message); - } - return false; + return ShaderError::Fail(error, Diagnostic(m_program, pc, message)); } bool Collect(Value value, uint32_t use_pc, std::string* error) { @@ -434,10 +432,7 @@ public: private: bool Fail(std::string* error, const std::string& message) const { - if (error != nullptr) { - *error = Diagnostic(m_program, m_use_pc, message); - } - return false; + return ShaderError::Fail(error, Diagnostic(m_program, m_use_pc, message)); } bool EvaluateWide(Value value, uint64_t& result, std::string* error) { diff --git a/src/graphics/shader/shader.h b/src/graphics/shader/shader.h index 224cf14..566a62e 100644 --- a/src/graphics/shader/shader.h +++ b/src/graphics/shader/shader.h @@ -10,10 +10,22 @@ #include #include #include +#include #include namespace Libs::Graphics { +namespace ShaderError { + +[[nodiscard]] inline bool Fail(std::string* error, std::string_view message) { + if (error != nullptr) { + error->assign(message.data(), message.size()); + } + return false; +} + +} // namespace ShaderError + namespace HW { struct VertexShaderInfo; struct PixelShaderInfo; diff --git a/src/graphics/shader/shaderVertexMetadata.cpp b/src/graphics/shader/shaderVertexMetadata.cpp index 2b81a1c..ea06fc3 100644 --- a/src/graphics/shader/shaderVertexMetadata.cpp +++ b/src/graphics/shader/shaderVertexMetadata.cpp @@ -5,21 +5,10 @@ namespace Libs::Graphics { -namespace { - -bool Fail(std::string* error, const char* message) { - if (error != nullptr) { - *error = message; - } - return false; -} - -} // namespace - bool ShaderReadVertexMetadata(const ShaderMappedData& data, uint32_t max_user_sgprs, ShaderVertexMetadata& metadata, std::string* error) { if (data.user_data == nullptr) { - return Fail(error, "missing AGC user-data header"); + return ShaderError::Fail(error, "missing AGC user-data header"); } ShaderUserData user_data {}; @@ -28,7 +17,8 @@ bool ShaderReadVertexMetadata(const ShaderMappedData& data, uint32_t max_user_sg constexpr uint32_t DirectResourceCount = static_cast(AgcDirectResourceType::Last) + 1u; if (user_data.direct_resource_count > DirectResourceCount) { - return Fail(error, "AGC direct-resource count exceeds the known resource domain"); + return ShaderError::Fail(error, + "AGC direct-resource count exceeds the known resource domain"); } std::array direct_offsets {}; @@ -36,7 +26,7 @@ bool ShaderReadVertexMetadata(const ShaderMappedData& data, uint32_t max_user_sg static_cast(user_data.direct_resource_count) * sizeof(uint16_t); if (direct_size != 0) { if (user_data.direct_resource_offset == nullptr) { - return Fail(error, "missing AGC direct-resource offsets"); + return ShaderError::Fail(error, "missing AGC direct-resource offsets"); } std::memcpy(direct_offsets.data(), user_data.direct_resource_offset, direct_size); } @@ -57,31 +47,31 @@ bool ShaderReadVertexMetadata(const ShaderMappedData& data, uint32_t max_user_sg } if (next.vertex_attrib_reg >= 0 && next.vertex_buffer_reg < 0) { - return Fail(error, "vertex attribute table requires a vertex buffer table"); + return ShaderError::Fail(error, "vertex attribute table requires a vertex buffer table"); } if (next.vertex_buffer_reg < 0) { metadata = next; return true; } if (static_cast(next.vertex_buffer_reg) + 1u >= max_user_sgprs) { - return Fail(error, "vertex table pointer exceeds the user-SGPR domain"); + return ShaderError::Fail(error, "vertex table pointer exceeds the user-SGPR domain"); } if (next.vertex_attrib_reg < 0) { metadata = next; return true; } if (static_cast(next.vertex_attrib_reg) + 1u >= max_user_sgprs) { - return Fail(error, "vertex table pointer exceeds the user-SGPR domain"); + return ShaderError::Fail(error, "vertex table pointer exceeds the user-SGPR domain"); } if (data.num_input_semantics == 0 || data.num_input_semantics > ShaderVertexInputInfo::RES_MAX) { - return Fail(error, "vertex semantic count is outside the supported domain"); + return ShaderError::Fail(error, "vertex semantic count is outside the supported domain"); } const auto semantic_size = static_cast(data.num_input_semantics) * sizeof(ShaderSemantic); if (data.input_semantics == nullptr) { - return Fail(error, "missing vertex input semantics"); + return ShaderError::Fail(error, "missing vertex input semantics"); } std::memcpy(next.input_semantics.data(), data.input_semantics, semantic_size); next.input_semantics_count = data.num_input_semantics;