Skip to content

ShaderCompiler: preserve original sampler names colliding with HLSL/MSL keywords - #1796

Open
bkaradzic-microsoft wants to merge 1 commit into
BabylonJS:masterfrom
bkaradzic-microsoft:pr/shadercompiler-sampler-names
Open

ShaderCompiler: preserve original sampler names colliding with HLSL/MSL keywords#1796
bkaradzic-microsoft wants to merge 1 commit into
BabylonJS:masterfrom
bkaradzic-microsoft:pr/shadercompiler-sampler-names

Conversation

@bkaradzic-microsoft

Copy link
Copy Markdown
Member

Problem

SPIRV-Cross's HLSL and MSL backends rename any shader resource whose name collides with a reserved keyword of the target language, prepending an underscore. Babylon.js generates GLSL samplers named Texture2D and Texture2DArray, which are HLSL built-in object types, so they are emitted into the bgfx uniform table as _Texture2D / _Texture2DArray.

Both bgfx and Babylon.js look samplers up by their original GLSL name, so the renamed uniform never binds. There is no error — the stage just silently samples nothing and renders transparent.

Fix

AppendSamplers recovers the pre-transpile name from the parser's ParsedIR via get_name(id). The Compiler transpiles a private copy of the IR, so the parser still holds the original names. That name is emitted into the bgfx uniform table and the stage map.

  • The texture register (DecorationBinding) is untouched — only the app-facing name changes.
  • Non-colliding samplers resolve to the identical string, so they are bit-for-bit unaffected.
  • The existing OpenGL stage-assignment guard is now keyed on the recovered name so the vertex and fragment passes agree on the same identifier.

Validation

Built x64 / Release / D3D11 against this branch and ran the full Playground validation suite:

Run complete. ran=300 passed=300 failed=0 missingRef=0 skipped=420

No regressions. Because every non-colliding sampler keeps its current name, the change is a no-op for all 300 currently-enabled tests.

Scope

This is intentionally code-only — no config.json changes. The test this unblocks (MultiRenderTarget with different texture types, #XSNYAU#22) also needs a matching Babylon.js-side fix for the mixed-type MRT write path, so its un-exclusion is deliberately left for a later change once both halves are in. Verified: with only this fix applied, that test still fails, so enabling it here would red the build.

…SL keywords

SPIRV-Cross's HLSL/MSL backends rename any shader resource whose name collides with a target-language reserved keyword by prepending '_' (e.g. GLSL samplers 'Texture2D'/'Texture2DArray' become '_Texture2D'/'_Texture2DArray'). Babylon.js and bgfx look samplers up by their original GLSL name, so the renamed uniform never bound and the stage silently sampled nothing (transparent output).

AppendSamplers now recovers the original pre-transpile name from the parser's ParsedIR (get_name(id)) -- the Compiler transpiles a private copy of the IR, so the parser retains the original names -- and emits that into the bgfx uniform table and the stage map. The texture register (DecorationBinding) is unchanged; only the app-facing name is fixed. Non-colliding samplers resolve to the identical string and are unaffected.

The OpenGL stage-assignment guard is now keyed on the recovered name so the vertex and fragment passes agree on the same identifier.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 60c2ec68-6de1-445d-9fc9-b699db737eae
Copilot AI review requested due to automatic review settings July 28, 2026 02:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes sampler/uniform binding failures caused by SPIRV-Cross renaming GLSL sampler identifiers that collide with HLSL/MSL reserved keywords (e.g., Texture2D_Texture2D). It does so by emitting the original (pre-transpile) resource name into the bgfx uniform table and by using that same recovered name when maintaining the shared stage-to-texture-unit map.

Changes:

  • Extend AppendSamplers to accept the parser’s original spirv_cross::ParsedIR and recover the pre-transpile sampler name via originalIr.get_name(sampler.id).
  • Emit recovered sampler names into the bgfx shader binary uniform table (falling back to sampler.name when unavailable).
  • Key the OpenGL stage-assignment guard and stage map entries on the recovered name so vertex/fragment passes agree on the identifier.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
Plugins/ShaderCompiler/Source/ShaderCompilerCommon.h Updates AppendSamplers signature to accept the original ParsedIR for name recovery.
Plugins/ShaderCompiler/Source/ShaderCompilerCommon.cpp Recovers original sampler names from ParsedIR, writes them to the uniform table, and keys stage mapping consistently on the recovered name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants