diff --git a/Source/Core/VideoBackends/Metal/MTLObjectCache.mm b/Source/Core/VideoBackends/Metal/MTLObjectCache.mm index 5d29f06e88..db0e338ae5 100644 --- a/Source/Core/VideoBackends/Metal/MTLObjectCache.mm +++ b/Source/Core/VideoBackends/Metal/MTLObjectCache.mm @@ -17,6 +17,7 @@ #include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/VertexShaderGen.h" +#include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" MRCOwned> Metal::g_device; @@ -445,10 +446,66 @@ public: error:&err]; if (err) { - PanicAlertFmt("Failed to compile pipeline for {} and {}: {}", + static int counter; + std::string filename = VideoBackendBase::BadShaderFilename("pipeline", counter++); + FILE* file = fopen(filename.c_str(), "w"); + if (file) + { + fmt::println(file, "=============== Error ==============="); + fmt::println(file, "{}", [[err localizedDescription] UTF8String]); + fmt::println(file, "============== Pipeline ============="); + fmt::println(file, "VS: {}", [[[desc vertexFunction] label] UTF8String]); + fmt::println(file, "PS: {}", [[[desc fragmentFunction] label] UTF8String]); + fmt::println(file, "Color Format: {}", static_cast(fs.color_texture_format.Value())); + fmt::println(file, "Depth Format: {}", static_cast(fs.depth_texture_format.Value())); + fmt::println(file, "Sample Count: {}", fs.samples); + if (u32 cnt = fs.additional_color_attachment_count) + fmt::println(file, "Additional Color Attachments: {}", cnt); + if (bs.colorupdate && bs.alphaupdate) + fmt::println(file, "Write Color, Alpha"); + else if (bs.colorupdate) + fmt::println(file, "Write Color"); + else if (bs.alphaupdate) + fmt::println(file, "Write Alpha"); + else + fmt::println(file, "Write None"); + if (bs.blendenable) + { + auto print_blend = [file](const char* name, SrcBlendFactor src, DstBlendFactor dst, + bool subtract) { + if (subtract) + fmt::println(file, "{}: dst * {} - src * {}", name, dst, src); + else + fmt::println(file, "{}: src * {} + dst * {}", name, src, dst); + }; + print_blend("Color Blend", bs.srcfactor, bs.dstfactor, bs.subtract); + print_blend("Alpha Blend", bs.srcfactoralpha, bs.dstfactoralpha, bs.subtractAlpha); + fmt::println(file, "Blend Dual Source: {}", bs.usedualsrc ? "true" : "false"); + } + else + { + fmt::println(file, "Blend Disabled"); + } + if (const Shader* vs = static_cast(config.vertex_shader)) + { + fmt::println(file, "========= Vertex Shader MSL ========="); + fmt::println(file, "{}", vs->GetMSL()); + } + if (const Shader* ps = static_cast(config.pixel_shader)) + { + fmt::println(file, "========== Pixel Shader MSL ========="); + fmt::println(file, "{}", ps->GetMSL()); + } + fclose(file); + } + + std::string file_msg = file ? fmt::format("Details were written to {}", filename) : + "Failed to write detailed info"; + + PanicAlertFmt("Failed to compile pipeline for {} and {}: {}\n{}", [[[desc vertexFunction] label] UTF8String], [[[desc fragmentFunction] label] UTF8String], - [[err localizedDescription] UTF8String]); + [[err localizedDescription] UTF8String], file_msg); return std::make_pair(nullptr, PipelineReflection()); } diff --git a/Source/Core/VideoBackends/Metal/MTLShader.h b/Source/Core/VideoBackends/Metal/MTLShader.h index 018346bb6d..dca9d97931 100644 --- a/Source/Core/VideoBackends/Metal/MTLShader.h +++ b/Source/Core/VideoBackends/Metal/MTLShader.h @@ -19,6 +19,7 @@ public: ~Shader(); id GetShader() const { return m_shader; } + const std::string& GetMSL() const { return m_msl; } BinaryData GetBinary() const override; private: