From 96646df12e00a9dff6dfc94e537f95189ced65ed Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Thu, 13 Aug 2026 01:34:57 -0400 Subject: [PATCH] [Fix] (MG_Backend/DirectVulkan): review round - failure diagnostics take MGLOG_E, the once-per-patch-size success note takes MGLOG_D, and the per-draw refusal stays latched --- .../DirectVulkan/Renderer/PipelineFactory.cpp | 11 ++++++----- .../DirectVulkan/Renderer/ProgramFactory.cpp | 14 +++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.cpp index ef1f235a..de69915f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.cpp @@ -498,14 +498,15 @@ namespace MobileGL::MG_Backend::DirectVulkan { const Bool hasTessControl = (stagesPresent & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0; const Bool hasTessEval = (stagesPresent & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0; if (hasTessControl != hasTessEval) { - // MGLOG_I, and latched: _E is compiled out of the INFO-level builds CTS and the - // shipping app run, which is exactly where this refusal is the only explanation - // for a missing draw. Latched because failures are deliberately not memoised - a - // program in this state re-enters here once per draw, every frame. + // Latched, and the latch is the point: a failed creation is deliberately never + // memoised (see GetOrCreatePipeline), so a program in this state re-enters here + // once per draw, every frame - and a refusal diagnostic that repeats per draw is + // noise, not a diagnostic. One line names the program; the draws it explains are + // all the same draw. static Bool s_warnedHalfTessellatedPipeline = false; if (!s_warnedHalfTessellatedPipeline) { s_warnedHalfTessellatedPipeline = true; - MGLOG_I("PipelineFactory::CreatePipeline: refusing a pipeline with %s tessellation stage and " + MGLOG_E("PipelineFactory::CreatePipeline: refusing a pipeline with %s tessellation stage and " "no %s stage (VUID-VkGraphicsPipelineCreateInfo-pStages-00730). programHash=0x%llx " "patchControlPoints=%u. Its draws are skipped; logged once.", hasTessEval ? "an evaluation" : "a control", diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp index ebf09c36..cfddc618 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp @@ -3346,7 +3346,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { .env = env.get()}; auto compiled = ShaderCompiler::CompileShader(shaderAttrib); if (!compiled) { - MGLOG_I("ProgramFactory: could not compile the pass-through tessellation control stage for " + MGLOG_E("ProgramFactory: could not compile the pass-through tessellation control stage for " "patchVertices=%u; a program with an evaluation stage and no control stage cannot draw. %s", patchVertices, compiled.error().log.c_str()); m_passthroughTessControlStages.emplace(patchVertices, stage); @@ -3357,7 +3357,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { programAttrib.shaders.push_back(compiled.value()); auto linked = ShaderCompiler::LinkProgram(programAttrib); if (!linked) { - MGLOG_I("ProgramFactory: could not link the pass-through tessellation control stage for " + MGLOG_E("ProgramFactory: could not link the pass-through tessellation control stage for " "patchVertices=%u. %s", patchVertices, linked.error().log.c_str()); m_passthroughTessControlStages.emplace(patchVertices, stage); return stage; @@ -3366,7 +3366,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ProgramBinaryAttrib binaryAttrib{.shaderTypes = {GL_TESS_CONTROL_SHADER}, .program = *linked.value()}; auto binary = ShaderCompiler::GetSpirvBinaryFromProgram(binaryAttrib); if (!binary || binary.value().empty() || binary.value().front().empty()) { - MGLOG_I("ProgramFactory: could not generate SPIR-V for the pass-through tessellation control stage " + MGLOG_E("ProgramFactory: could not generate SPIR-V for the pass-through tessellation control stage " "for patchVertices=%u", patchVertices); m_passthroughTessControlStages.emplace(patchVertices, stage); return stage; @@ -3387,14 +3387,14 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkShaderModule module = VK_NULL_HANDLE; const VkResult result = vkCreateShaderModule(m_device, &smci, nullptr, &module); if (result != VK_SUCCESS) { - MGLOG_I("ProgramFactory: vkCreateShaderModule failed (%d) for the pass-through tessellation control " + MGLOG_E("ProgramFactory: vkCreateShaderModule failed (%d) for the pass-through tessellation control " "stage for patchVertices=%u", static_cast(result), patchVertices); m_passthroughTessControlStages.emplace(patchVertices, stage); return stage; } stage.module = module; - MGLOG_I("ProgramFactory: built the pass-through tessellation control stage for patchVertices=%u " + MGLOG_D("ProgramFactory: built the pass-through tessellation control stage for patchVertices=%u " "(GL 4.6 11.2.2; Vulkan has no fixed-function equivalent)", patchVertices); m_passthroughTessControlStages.emplace(patchVertices, stage); return stage; @@ -3430,7 +3430,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const SpvReflectResult createResult = spvReflectCreateShaderModule(module.size() * sizeof(Uint), module.data(), &reflectModule); if (createResult != SPV_REFLECT_RESULT_SUCCESS) { - MGLOG_I("ProgramFactory::ReflectPassthroughTessControlNeed: reflection failed (result=%d); the " + MGLOG_E("ProgramFactory::ReflectPassthroughTessControlNeed: reflection failed (result=%d); the " "evaluation stage's inputs are unknown, so the pass-through is not offered", static_cast(createResult)); return; @@ -3468,7 +3468,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { for (auto* input : inputs) { if (input == nullptr) continue; if (input->location == kNoLocation) continue; - MGLOG_I("ProgramFactory: a tessellation evaluation stage with no control stage reads the " + MGLOG_E("ProgramFactory: a tessellation evaluation stage with no control stage reads the " "user-defined input '%s' at location=%u; a synthesized control stage cannot forward it, so " "this program's draws are declined rather than fed an undefined varying", input->name != nullptr ? input->name : "", input->location);