{"record":{"id":"13e25c836c1a8191","repo":"stride3d/stride","slug":"resource-resourcename-has-slot-slotstart-in-stage-but-slot","errorCode":null,"errorMessage":"Resource '{resourceName}' has slot {slotStart} in {stage} but slot {entry.SlotStart} was expected (from SDSL compiler). Cross-stage slot mismatch is not supported.","messagePattern":"Resource '(.+?)' has slot (.+?) in (.+?) but slot (.+?) was expected \\(from SDSL compiler\\)\\. Cross-stage slot mismatch is not supported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs","lineNumber":794,"sourceCode":"            // in the process.\n            // This is a convenience method to avoid unnecessary reference counting, as implicit conversions\n            // in the ComPtr<T> class will call AddRef() automatically.\n            //\n            // NOTE: This is a mirror from the ComPtrHelpers type.\n            //\n            static ComPtr<T> ToComPtr<T>(T* comPtr) where T : unmanaged, IComVtbl<T>\n            {\n                return new ComPtr<T> { Handle = comPtr };\n            }\n\n            static void UpdateResourceGroupStageFlags(Dictionary<string, (EffectResourceGroupDescription Group, int Index)> index, string resourceName, ShaderStage stage, int slotStart)\n            {\n                if (!index.TryGetValue(resourceName, out var loc))\n                    return;\n\n                var entry = loc.Group.Entries[loc.Index];\n                if (entry.SlotStart != slotStart)\n                    throw new InvalidOperationException(\n                        $\"Resource '{resourceName}' has slot {slotStart} in {stage} \" +\n                        $\"but slot {entry.SlotStart} was expected (from SDSL compiler). \" +\n                        $\"Cross-stage slot mismatch is not supported.\");\n                entry.Stages |= stage.ToFlag();\n                loc.Group.Entries[loc.Index] = entry;\n            }\n        }\n    }\n}\n\n#endif\n","sourceCodeStart":776,"sourceCodeEnd":806,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs#L776-L806","documentation":"When merging resource binding slots across shader stages into a combined binding table, ShaderCompiler.Compile checks that each resource got the same slot the SDSL compiler assigned. If a resource occupies a different slot in one stage than the recorded SlotStart, the merge is aborted with InvalidOperationException because D3D12 requires consistent register slots for a resource across all stages that use it.","triggerScenarios":"ShaderCompiler.Compile processes a stage's input binding whose resource name maps to an entry with a different SlotStart than the slot reported by that stage's reflection — e.g. the same named uniform bound to slot 2 in the pixel shader but slot 3 in the vertex shader, or reflection produced by a different toolchain than the SDSL compiler reorders resource registers.","commonSituations":"Hand-written HLSL/SPIRV mixed with SDSL shaders where explicit register() assignments disagree; shader stages generated or precompiled by different compiler versions; renaming or reordering resources so SDSL-assigned slots no longer match reflected slots; using precompiled shaders built with an older Stride compiler.","solutions":["Make the resource's register/slot identical in every shader stage that declares it (use explicit register(bN/tN/uN/sN) consistently).","Recompile all shader stages from the same SDSL source with the same Stride compiler version so slot assignment is uniform.","Remove hand-written register() or layout qualifiers that override the SDSL compiler's slot assignment.","If reflection slots come from an external toolchain, re-run it with options that preserve the declared register order (e.g. no auto-binding renumbering).","Clear the shader/effect cache and rebuild so stale per-stage bindings are not mixed with fresh ones."],"exampleFix":"// before: mismatch across stages\ncbuffer PerFrame : register(b0) { float4x4 View; };   // vs\ncbuffer PerFrame : register(b2) { float4x4 View; };   // ps -> throws\n\n// after: same slot in all stages\ncbuffer PerFrame : register(b0) { float4x4 View; };   // vs and ps","handlingStrategy":"validation","validationCode":"// pre-validate binding consistency across stages before compiling the effect\nvar slots = new Dictionary<string, int>();\nforeach (var stage in stageBindings)\n    foreach (var binding in stage.InputBindings)\n    {\n        if (slots.TryGetValue(binding.Name, out var existing) && existing != binding.SlotStart)\n            throw new InvalidOperationException($\"Resource '{binding.Name}' bound to slot {binding.SlotStart} in {stage.Stage} but slot {existing} elsewhere. Align register assignments.\");\n        slots[binding.Name] = binding.SlotStart;\n    }","typeGuard":null,"tryCatchPattern":"try\n{\n    var result = shaderCompiler.Compile(source, parameters);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Cross-stage slot mismatch\"))\n{\n    log.Error($\"Binding slot conflict: {ex.Message}. Make the resource's register identical in every stage.\");\n    throw;\n}","preventionTips":["Never override SDSL-assigned slots with hand-written register() directives in one stage only.","Declare shared resources (cbuffers, textures) once in a shared SDSL mixin and reuse it across stages.","Compile all stages from the same Stride compiler version; avoid mixing precompiled and fresh shaders.","Keep reflection toolchain options that preserve declared register order (no automatic renumbering).","Wipe the shader cache when changing resource declarations so old slot tables cannot linger."],"tags":["shaders","compilation","resource-binding","slot-mismatch","direct3d"],"backgroundTag":"internal-invariant-violation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}