Repository navigation
core/nvrhi.ts: NVRHI's interfaces called directly through @cppvtable classes - #36
Merged
Merged
Conversation
…classes core/nvrhi.ts lays tslang @cppvtable classes (pre-alpha94) over nvrhi:: IResource, IBuffer, ITexture, ICommandList and IDevice. A method call goes through the C++ object's own vtable, with no wrapper in donut_interop.cpp. Every slot is declared, because a missing one would call a different C++ method with no error. Only the methods the test calls have signatures; the other slots are placeholders named `_` + the C++ name. tools/check_nvrhi_slots.py compares the classes with the vtables MSVC builds (cl /d1reportSingleClassLayout): all 163 slots match. Swapping two methods or dropping one makes it fail. Helpers hide the MSVC hidden return pointer: createBuffer, createCommandList, executeCommandList, getNativeObject. layoutMatches() compares the tuples' sizes with the C++ structs', via the new Donut_GetNvrhiStructSize, because std::string's layout depends on the CRT. examples/nvrhi_direct.ts is a headless test of every bound method, not a sample. It uploads into one buffer and clears another, copies both into a readback buffer and checks the mapped data. It also checks the graphics API, the native device, AddRef/Release and getDesc. CTest runs it as nvrhi_direct.dx12/.vk, with the debug layers. MSVC builds only. add_tslang_example now makes an example's .ts depend on the .ts modules listed with it, so changing core/nvrhi.ts or core/paged_images.ts recompiles the examples that import them. CTest: 59/59. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds
core/nvrhi.ts, which binds NVRHI's interfaces with tslang@cppvtableclasses (TypeScriptCompiler#550, in pre-alpha94). Each method call goes through the C++ object's own vtable, so there is no wrapper per method indonut_interop.cpp:Classes and slot checking
nvrhi.IResource,IBuffer,ITexture,ICommandListandIDevicemirror the C++ hierarchy: the last four extendIResource._+ the C++ name. An overloaded method's slots are named_<name>_<slot>, because MSVC orders overloads in its own way.tools/check_nvrhi_slots.pychecks the slots. It asks MSVC for each interface's vtable (cl /d1reportSingleClassLayout<Name>) and compares it, slot by slot, with the TypeScript classes. All 163 slots match. Swappingopen/close, or dropping a slot, makes it report the exact slots. It needscl, so it isn't a CTest test; run it after changing the classes or updating NVRHI.Helpers
createBuffer,createCommandList,executeCommandListandgetNativeObjecthide MSVC's hidden return pointer, the parameter afterthisthrough which an object returned by value comes back.layoutMatches()compares the sizes of theBufferDesc(80 bytes) andCommandListParameters(48 bytes) tuples with the C++ structs. It uses a newDonut_GetNvrhiStructSize, becausestd::string's layout depends on the CRT.Test
examples/nvrhi_direct.tsis a headless test of every bound method, not a sample:clearBufferUInt.getGraphicsAPI, the native device throughgetNativeObject(annvrhi::Objectreturned by value),AddRef/Release/GetRefCount,getDesc, and the struct layouts.CTest runs it as
nvrhi_direct.dx12andnvrhi_direct.vkwith the debug layers. It is built for MSVC only: the slots and calling convention are MSVC x64's, and Android's Itanium ABI differs.The sample count (112) and the repo description are unchanged, since this isn't a sample. The README gains a "Calling NVRHI directly" section, and the screenshot script skips
nvrhi_direct(it has no window).Also: example dependencies
add_tslang_exampleused to give an example's.tsand its module.tsfiles the same dependencies, the core sources only. So editing an imported module (core/nvrhi.ts,core/paged_images.ts,core/meshlet_model.ts, ...) didn't recompile the examples that import it. The example now depends on the modules listed with it. Checked: touchingcore/nvrhi.tsandcore/paged_images.tsrebuiltnvrhi_directandmemory_management, and nothing else.Testing
nvrhi_direct.dx12/.vk.run_jit.bat examples/nvrhi_direct.ts -- -dx12|-vk -debug -testpasses.python tools/check_nvrhi_slots.pyandpython tools/check_interop_types.py --strictboth pass.🤖 Generated with Claude Code