Merge pull request #13104 from TellowKrinkle/MTLLogging

VideoBackends:Metal: Log file on failed pipeline compile
This commit is contained in:
JMC47 2024-10-19 13:03:52 -04:00 committed by GitHub
commit e10821a847
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 63 additions and 5 deletions

View File

@ -81,7 +81,7 @@ public:
id<MTLSamplerState> GetSampler(SamplerSelector sel)
{
if (__builtin_expect(!m_samplers[sel.value], false))
if (!m_samplers[sel.value]) [[unlikely]]
m_samplers[sel.value] = CreateSampler(sel);
return m_samplers[sel.value];
}

View File

@ -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<id<MTLDevice>> 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<u32>(fs.color_texture_format.Value()));
fmt::println(file, "Depth Format: {}", static_cast<u32>(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<const Shader*>(config.vertex_shader))
{
fmt::println(file, "========= Vertex Shader MSL =========");
fmt::println(file, "{}", vs->GetMSL());
}
if (const Shader* ps = static_cast<const Shader*>(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());
}

View File

@ -19,6 +19,7 @@ public:
~Shader();
id<MTLFunction> GetShader() const { return m_shader; }
const std::string& GetMSL() const { return m_msl; }
BinaryData GetBinary() const override;
private:

View File

@ -144,7 +144,7 @@ Metal::StateTracker::Map Metal::StateTracker::AllocateForTextureUpload(size_t am
CPUBuffer& buffer = m_texture_upload_buffer;
u64 last_draw = m_last_finished_draw.load(std::memory_order_acquire);
bool needs_new = buffer.usage.PrepareForAllocation(last_draw, amt);
if (__builtin_expect(needs_new, false))
if (needs_new) [[unlikely]]
{
// Orphan buffer
size_t newsize = std::max<size_t>(buffer.usage.Size() * 2, 4096);
@ -187,7 +187,7 @@ std::pair<void*, size_t> Metal::StateTracker::Preallocate(UploadBuffer buffer_id
}
buffer.last_upload = 0;
}
if (__builtin_expect(needs_new, false))
if (needs_new) [[unlikely]]
{
// Orphan buffer
size_t newsize = std::max<size_t>(buffer.usage.Size() * 2, 4096);