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
- Update the native spirv-cross binary — several combined-image-sampler bugs were fixed upstream
- Check error-callback log output preceding the throw
- Validate the SPIR-V module with spirv-val
- Confirm resource reflection succeeded (CompilerCreateShaderResources) before the GLSL branch
- 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
- Update spirv-cross for combined-sampler fixes
- Test GLSL translation of every shader in CI
- Confirm resource reflection succeeds before the GLSL branch
- Prefer separate-sampler-friendly shader layouts where possible
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
- {cross.CompilerGetCombinedImageSamplers(compiler…
- : could not compile code
- Block compression requires texture size to be a multiple of…
- Platform is not supported by TextureTool
- Pointer to DDS header cannot be null
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)