Skip to content

NULL: create a GpuProgramManager, so material scripts can be parsed - #590

Open
steffen-roemer wants to merge 1 commit into
OGRECave:masterfrom
orkitec:null-gpu-program-manager
Open

NULL: create a GpuProgramManager, so material scripts can be parsed#590
steffen-roemer wants to merge 1 commit into
OGRECave:masterfrom
orkitec:null-gpu-program-manager

Conversation

@steffen-roemer

Copy link
Copy Markdown
Contributor

Fixes #589. Under RenderSystem_NULL there is no GpuProgramManager, so parsing
any .material or .program script aborts:

Assertion failed: (msSingleton), function getSingleton,
  file OgreGpuProgramManager.cpp, line 52

NULLRenderSystem::_createRenderWindow creates the HardwareBuffer, Vao and
TextureGpu managers, and nothing creates a GpuProgramManager, so msSingleton
stays null for the whole process lifetime.

This is option 1 from the issue, held to the condition you set there: worth having
only if it stays small in RAM and in maintenance.

The change

NULLGpuProgramManager is created beside the other managers in
_createRenderWindow and destroyed in shutdown(). Metal and Vulkan create
theirs in initialiseFromRenderSystemCapabilities; NULL's implementation of that
hook is empty and nothing calls it, so the managers' own creation site is the
equivalent place.

It has no members. Both createImpl overloads return a NULLGpuProgram with no
branch in between, because type and syntax code only matter to a compiler and
there is none. NULLGpuProgram is the low level counterpart of the NullProgram
OgreMain already carries for high level programs in an unregistered language, and
it is the same handful of lines:

void   loadFromSource() override {}
void   unloadImpl() override {}
bool   isSupported() const override { return false; }
size_t calculateSize() const override { return 0; }
bool   setParameter( const String &, const String & ) override { return true; }

That is the entire implementation. The two new files are 62 and 97 lines
including the license header; wiring them into the render system is 7 lines.

Why it stays small

  • No state. No program factory map, no microcode, no device handle, no
    syntax registry. D3D11GpuProgramManager has exactly this shape today
    (D3D11UnsupportedGpuProgram, "D3D11 doesn't support assembly shaders").
  • Nothing to keep in sync. It holds no opinion about shader stages, root
    layouts, syntax codes or capabilities, so a change anywhere else cannot make it
    stale or wrong. There is no code path in it that a future feature has to teach.
  • RAM. One small GpuProgram per declared program, and nothing else. NULL
    advertises no shader profiles, so isSyntaxSupported() is false, the compiler
    takes the road it already takes for a program meant for another render system,
    and the program is never loaded: its source is not read from disk, and
    calculateSize() reports 0.

Nothing starts pretending to work

Each declaration is reported as unsupported by the render system, the same way a
D3D11 program is reported under GL:

Compiler error: object unsupported by render system in probe.program(1): , Shader name: ProbeVertexProgram

and a material built on such programs is honest about what it became:

WARNING: material ProbeMaterial has no supportable Techniques and will be blank. Explanation:
Pass 0: Vertex program ProbeVertexProgram cannot be used - not supported.

isSupported() is overridden rather than left to the syntax lookup, so that
answer does not depend on what the NULL capabilities happen to advertise later.

If you would rather have the honest refusal (option 2 in the issue) instead, say
so and I will send that one; which of the two to carry is your call.

Verification

macOS 15 / Apple Silicon, clang, Ninja. RenderSystem_NULL and OgreNextMain
built static in Debug from this branch, and a standalone probe linked against them
booted Root with NULLPlugin, created a render window through
Root::createRenderWindow, added a resource location holding one .program (two
asm declarations) and one .material referencing both, and called
initialiseAllResourceGroups.

Baseline master, same probe, same media:

GpuProgramManager::getSingletonPtr() = 0x0
Parsing script probe.program
Assertion failed: (msSingleton), function getSingleton, file OgreGpuProgramManager.cpp, line 52.

SIGABRT, exit 134. With this branch:

GpuProgramManager::getSingletonPtr() = 0x101a95ff0
Compiler error: object unsupported by render system in probe.program(1): , Shader name: ProbeVertexProgram
Compiler error: object unsupported by render system in probe.program(7): , Shader name: ProbeFragmentProgram
scripts parsed
ProbeVertexProgram = 0x101a9d820
  isSupported = 0, calculateSize = 0, hasCompileError = 0
ProbeMaterial = 0x101a9cf60
  supported techniques = 0
PROBE PASSED (0)

Exit 0, and the shutdown is clean.

Not covered: the Ogre-Next sample and test suites were not run, and this was built
for macOS with clang only. Nothing outside RenderSystems/NULL is touched.

Encountered while making the Ogre-Next backend of
orkige run window-less and GPU-less for CI;
the media that triggered it was the AtmosphereNpr sky's own .material/.program
pair, which the engine now skips registering when it boots deviceless.

NULLRenderSystem creates a HardwareBufferManager, a VaoManager and a
TextureGpuManager, but no GpuProgramManager, so msSingleton stays null for
the whole process lifetime and parsing any .material or .program script
aborts:

    Assertion failed: (msSingleton), function getSingleton,
      file OgreGpuProgramManager.cpp, line 52

reached from the script compiler translating a vertex_program /
fragment_program declaration.

Add NULLGpuProgramManager, created beside the other managers in
_createRenderWindow and destroyed in shutdown(), the way Metal and Vulkan
create theirs. It holds no state of its own: both createImpl overloads
return a NULLGpuProgram, the low level counterpart of OgreMain's own
NullProgram - it accepts any type and syntax code, compiles nothing,
reports isSupported() == false and calculateSize() == 0.

Nothing starts pretending to work. NULL advertises no shader profiles, so
isSyntaxSupported() stays false and the compiler takes the road it already
takes for a program meant for another render system: it reports the
program as unsupported by this render system and registers it. That leaves
the program unloaded, so a program's source is never even read from disk,
and any technique using it is dropped as unsupported.
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.

NULL render system creates no GpuProgramManager: parsing any .material/.program script asserts

1 participant