stride3d/stride · error · Exception

: could not create shader resources

Error message

{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources

What it means

Translate throws this when CompilerCreateShaderResources fails to reflect the shader's resource bindings (cbuffers, textures, samplers, stage inputs/outputs) from the compiled IR. Reflection is required for the subsequent HLSL renaming and vertex-attribute remap steps, so translation aborts. The message includes the non-success Result code.

Solutions

  1. Validate the SPIR-V with spirv-val; recompile the shader if invalid
  2. Check the spirv-cross error-callback log lines emitted before the throw
  3. Update the native spirv-cross binary to a version matching the shader toolchain
  4. Ensure no earlier native call in the same Translate pipeline failed silently (check Result codes / logs)
  5. Isolate with a minimal known-good SPIR-V module to separate shader issues from environment issues

Example fix

// before
var hlsl = translator.Translate(Backend.Hlsl, entryPoint);
// after
try { var hlsl = translator.Translate(Backend.Hlsl, entryPoint); }
catch (Exception ex) when (ex.Message.Contains("could not create shader resources"))
{ Log.Error($"Reflection failed for shader: {ex.Message}. Verify SPIR-V with spirv-val."); throw; }
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate SPIR-V before translation so reflection has a well-formed module:
// spirv-val shader.spv  (offline) or check words[0] == 0x07230203 inline

Try / catch

try { var src = translator.Translate(backend, entryPoint); } catch (Exception ex) when (ex.Message.Contains("could not create shader resources")) { Log.Error($"Resource reflection failed: {ex.Message}"); throw; }

Prevention

When it happens

Trigger: Calling Translate when the compiler holds an IR that spirv-cross cannot reflect — corrupted/degenerate IR from a borderline-valid SPIR-V module, or an internal spirv-cross state error after prior failed calls in the same pipeline.

Common situations: Translating SPIR-V produced by newer toolchains with resource layouts spirv-cross's version doesn't understand; IR damaged by earlier failed calls; native library version bugs in reflection code.

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/551f3c8fb6f8c7aa. Report an issue: GitHub.

Appendix: source

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

            {
                cross.CompilerOptionsSetUint(compilerOptions, CompilerOption.HlslShaderModel, 50);
                cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.HlslPreserveStructuredBuffers, 1);
                // FXC rejects uninitialized loop-carried variables (from OpUndef phi inputs) with a
                // bogus "error X4555: cannot use casts on l-values" when they end up assigned in a
                // for-loop continue expression.
                cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.ForceZeroInitializedVariables, 1);
            }
            cross.CompilerInstallCompilerOptions(compiler, compilerOptions);
        }

        if (entryPoint != null)
        {
            if (cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel) != Result.Success)
                throw new Exception($"{cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel)} : could not set entry point");
        }

        if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success)
            throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources");

        // HLSL: remove type_ prefix from cbuffer (they get names from struct instead of cbuffer variable itself)
        if (backend == Backend.Hlsl)
        {

            ReflectedResource* resourcesList;
            nuint resourcesCount;
            cross.ResourcesGetResourceListForType(resources, ResourceType.UniformBuffer, &resourcesList, &resourcesCount);
            for (uint i = 0; i < resourcesCount; ++i)
            {
                var resource = resourcesList[i];
                var cbufferName = Marshal.PtrToStringAnsi((IntPtr)resource.Name)!;
                if (cbufferName.StartsWith("type."))
                {
                    cbufferName = cbufferName.Substring("type.".Length);
                    cross.CompilerSetName(compiler, resource.BaseTypeId, cbufferName);
                }
            }

View on GitHub (pinned to 96fad776d2)