[Fix, Test] (ShaderTranspiler, DirectGLES): stop printing the default fragment-output colour index into ESSL

This commit is contained in:
2026-08-21 21:42:31 -04:00
parent ece9491d4b
commit f1b4a5e07f
4 changed files with 73 additions and 0 deletions
@@ -442,6 +442,23 @@ namespace MobileGL {
SPVC_CHK_RETURN
}
spvc_result SpvcSession::DropDefaultFragmentOutputColorIndex() {
if (!(usage & SessionUsageBit::Transpile)) return SPVC_ERROR_INVALID_ARGUMENT;
SPVC_CHK_INIT
const spvc_reflected_resource* list = nullptr;
size_t count = 0;
SPVC_CHK_RESULT(spvc_resources_get_resource_list_for_type(
resources, SPVC_RESOURCE_TYPE_STAGE_OUTPUT, &list, &count));
for (size_t i = 0; i < count; ++i) {
const spvc_reflected_resource& resource = list[i];
if (!spvc_compiler_has_decoration(compiler, resource.id, SpvDecorationIndex)) continue;
if (spvc_compiler_get_decoration(compiler, resource.id, SpvDecorationIndex) != 0u) continue;
spvc_compiler_unset_decoration(compiler, resource.id, SpvDecorationIndex);
}
SPVC_CHK_RETURN
}
spvc_result SpvcSession::Compile(const char** result) {
if (!(usage & SessionUsageBit::Transpile)) return SPVC_ERROR_INVALID_ARGUMENT;
SPVC_CHK_INIT
@@ -120,6 +120,25 @@ namespace MobileGL {
// `outGlBindings` is appended to, so one vector can collect a whole program's
// stages; it may repeat a binding declared by several of them.
spvc_result SetAtomicCounterBlockBindings(Int topBinding, Vector<Int>& outGlBindings);
// Drops the Index decoration from every fragment output that carries the DEFAULT
// colour index 0, so the emitted ESSL does not print `index = 0`.
//
// Index 0 is what every single-source fragment output already is, in GL and in
// ESSL alike, and SPIR-V carries the decoration only because the application
// spelled the qualifier out - `layout(location = 0, index = 0) out vec4 c;` is
// legal desktop GLSL and says nothing. Printing it back into ESSL is NOT
// harmless: GLSL ES has no `index` layout qualifier in core, so the driver
// answers "index layout qualifier requires EXT_blend_func_extended" and refuses
// the stage. The program then links nothing and every draw with it renders
// NOTHING - verified on Mesa 26.1.4 llvmpipe with no MobileGL in the process,
// and it is why KHR-GL43.shader_atomic_counters.basic-program-query read back a
// black render target.
//
// A NON-zero index is left exactly as it is: that one really does select the
// second dual-source input and cannot be expressed without the extension, so it
// must keep reaching the driver (the frontend's own glBindFragDataLocationIndexed
// path already emits only non-zero indices for the same reason).
spvc_result DropDefaultFragmentOutputColorIndex();
spvc_result Compile(const char** result);
const SpvcMetadata& GetMetadata() const;
const char* GetLastErrorString() const;