stride3d/stride · error · Exception

: Could not enable combined image samplers

Error message

{cross.CompilerBuildCombinedImageSamplers(compiler)} : Could not enable combined image samplers

What it means

Translate throws this when CompilerBuildCombinedImageSamplers fails while translating to GLSL. GLSL combines separate texture and sampler objects into combined sampler2D-style variables; this call builds that combined list and fails rarely — usually on internal spirv-cross state errors or an IR that the combination pass cannot process.

Solutions

  1. Update the native spirv-cross binary — several combined-image-sampler bugs were fixed upstream
  2. Check error-callback log output preceding the throw
  3. Validate the SPIR-V module with spirv-val
  4. Confirm resource reflection succeeded (CompilerCreateShaderResources) before the GLSL branch
  5. Fall back to Backend.Hlsl to determine if the failure is GLSL-specific

Example fix

// before
var glsl = translator.Translate(Backend.Glsl, entryPoint);
// after
try { var glsl = translator.Translate(Backend.Glsl, entryPoint); }
catch (Exception ex) when (ex.Message.Contains("combined image samplers"))
{ Log.Error($"GLSL combined-sampler pass failed: {ex.Message}"); throw; }
Defensive patterns

Strategy: fallback

Validate before calling

if (backend == Backend.Glsl) { /* ensure shader only uses features expressible with combined samplers */ }

Try / catch

try { var glsl = translator.Translate(Backend.Glsl, entryPoint); } catch (Exception ex) when (ex.Message.Contains("combined image samplers")) { Log.Warn("GLSL combined-sampler pass failed; falling back to HLSL"); var src = translator.Translate(Backend.Hlsl, entryPoint); }

Prevention

When it happens

Trigger: Calling Translate(Backend.Glsl, ...) on a module whose separate image/sampler declarations cannot be combined (degenerate IR, reflection data missing because a prior step failed, or a spirv-cross version bug in the combination pass).

Common situations: GLSL translation of SPIR-V produced by unusual toolchains; older spirv-cross builds with known combined-sampler bugs; translation attempted after a partially failed pipeline left the compiler in a bad state.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/0d9272b25c795821. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs:157

            for (uint i = 0; i < resourcesCount; ++i)
            {
                if (cross.CompilerHasDecoration(compiler, resourcesList[i].Id, Decoration.Location) != 0
                    && cross.CompilerHasDecoration(compiler, resourcesList[i].Id, Decoration.UserSemantic) != 0)
                {
                    vertexInputRemap[vertexInputRemapCount].Location = cross.CompilerGetDecoration(compiler, resourcesList[i].Id, Decoration.Location);
                    vertexInputRemap[vertexInputRemapCount].Semantic = cross.CompilerGetDecorationString(compiler, resourcesList[i].Id, Decoration.UserSemantic);
                    vertexInputRemapCount++;
                }
            }
            cross.CompilerHlslAddVertexAttributeRemap(compiler, vertexInputRemap, (nuint)vertexInputRemapCount);

            cross.CompilerHlslSetResourceBindingFlags(compiler, 0);
        }

        if (backend == Backend.Glsl)
        {
            if (cross.CompilerBuildCombinedImageSamplers(compiler) != Result.Success)
                throw new Exception($"{cross.CompilerBuildCombinedImageSamplers(compiler)} : Could not enable combined image samplers");

            nuint numSamplers = 0;
            CombinedImageSampler* combinedImageSamplers = null;
            if (cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers) != Result.Success)
                throw new Exception($"{cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers)}");

            for (uint i = 0; i < numSamplers; ++i)
            {
                var textureName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].ImageId);
                var samplerName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].SamplerId);
                cross.CompilerSetName(compiler, combinedImageSamplers[i].CombinedId, $"SPIRV_Cross_Combined{textureName}{samplerName}");
            }
        }

        if (cross.CompilerCompile(compiler, &translated) != Result.Success)
            throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code");

        translatedCode = SilkMarshal.PtrToString((nint)translated);

View on GitHub (pinned to 96fad776d2)