Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
47215cc
Cache clean GPU memory stamps until the next physical write
AlenHay Oct 7, 2026
a365207
Recover missing native shaders from validated additive DXIL packs
AlenHay Oct 7, 2026
ef176fc
Upload resident guest depth textures before native sampling
AlenHay Oct 7, 2026
f0822cd
Validate index ranges and upload native draw vertex windows
AlenHay Oct 7, 2026
44b9506
Define an evidence-driven native renderer regression strategy
AlenHay Oct 7, 2026
60743e5
Reject unsupported shader fetch mappings and verify compiler preparation
AlenHay Oct 7, 2026
b9fd8de
Recover shader origins through CRC lookup and bounded executable scans
AlenHay Oct 7, 2026
3f36efd
Summarize generic frame CSVs and preserve constant stage timings
AlenHay Oct 7, 2026
a42d25a
Record shader provenance limits and gameplay performance gates
AlenHay Oct 7, 2026
b6bebb1
Distinguish cadence-only frame probes from detailed timing
AlenHay Oct 7, 2026
fdf0685
Pin public Plume and validate native D3D12 dependency fixes
AlenHay Oct 7, 2026
5145a21
Validate GPU completion before retiring native resources
AlenHay Oct 7, 2026
35632b2
Add isolated renderer checkpoint regression tools
AlenHay Oct 7, 2026
4aeb3c8
Measure native frame cadence without per-draw clocks
AlenHay Oct 7, 2026
8cce273
Use the audited TU23 alpha-reference state
AlenHay Oct 7, 2026
debe406
Add opt-in native culling and bounded draw diagnostics
AlenHay Oct 7, 2026
4f251df
Add fence-gated native GPU timestamp diagnostics
AlenHay Oct 7, 2026
c4196e4
Publish prelinked shader banks transactionally
AlenHay Oct 7, 2026
b79191b
Compare GPU timestamp overhead with fixed renderer settings
AlenHay Oct 7, 2026
feb37a5
Build and fingerprint linked shader banks after their producers
AlenHay Oct 7, 2026
bcb2408
Add bounded buffer allocation diagnostics with zero disabled setup
AlenHay Oct 7, 2026
28d8337
Use RenderDoc include interface for optional native capture
AlenHay Oct 7, 2026
305e234
Pin stop-safe timers and host codegen template fixes
AlenHay Oct 7, 2026
62b361f
Test production cross-build codegen and shader producer rules
AlenHay Oct 7, 2026
cefeac1
Keep GPU-first depth sampling channels consistent and retryable
AlenHay Oct 7, 2026
b7832f8
Batch immutable draw state reads and count binding requests
AlenHay Oct 7, 2026
f40512b
Register supported GPU checks and preserve optional dependency coverage
AlenHay Oct 7, 2026
f397c01
Isolate command state cache experiments from binding diagnostics
AlenHay Oct 7, 2026
20d8988
Add verified opt-in D3D12 pipeline and root signature caching
AlenHay Oct 7, 2026
e893055
Bound memory-watch validation to the requested physical pages
AlenHay Oct 7, 2026
6247311
Pin tested SDK correctness fixes and explicit interior body owners
AlenHay Oct 7, 2026
7148d99
Record controlled renderer evidence and robust viewport source valida…
AlenHay Oct 7, 2026
050349b
Pin SDK with portable NT calendar conversions and corrected unit asse…
AlenHay Oct 7, 2026
6815e9c
Preserve TU23 viewport and scissor semantics and repair Vulkan readback
AlenHay Oct 7, 2026
a54ac14
Pin SDK with compact ordered function registration output
AlenHay Oct 7, 2026
88cf091
Pin validated registration fixture deadline
AlenHay Oct 7, 2026
38ebe53
Fix viewport clipping against promoted native tile targets
AlenHay Oct 7, 2026
99e839d
Prepare explicit coherent PM4 correctness references
AlenHay Oct 7, 2026
8f235b6
Record verified menu recovery and stopped testing handoff
AlenHay Oct 7, 2026
674975c
Publish fetchable SDK integration and focused review handoff
AlenHay Oct 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
*.wav binary
*.ttf binary
*.bin binary

# Empty unified-diff context lines require their leading space, including at EOF.
tools/gpu-aot/patches/*.patch whitespace=-blank-at-eol,-blank-at-eof
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[submodule "rexglue-sdk"]
path = rexglue-sdk
url = https://github.com/NeverCookFirst/rexglue-sdk.git
branch = toypad-ui
url = https://github.com/AlenHay/rexglue-sdk.git
branch = codex/runtime-correctness-20261007
[submodule "DimensionsModManager"]
path = DimensionsModManager
url = https://github.com/NeverCookFirst/DimensionsModLoader.git
Expand Down
2 changes: 1 addition & 1 deletion rexglue-sdk
Submodule rexglue-sdk updated 52 files
+4 −0 README.md
+6 −7 include/rex/chrono/chrono.h
+3 −0 include/rex/codegen/config.h
+6 −2 include/rex/codegen/function_graph.h
+5 −2 include/rex/codegen/function_node.h
+4 −3 include/rex/graphics/command_processor.h
+3 −2 include/rex/graphics/graphics_system.h
+1 −1 include/rex/ui/d3d12/d3d12_api.h
+29 −0 patches/README.md
+21 −0 patches/simde-native-m64-stream.patch
+18 −2 resources/templates/codegen/register_cpp.inja
+16 −1 resources/templates/init/rexglue_cmake.inja
+100 −0 scripts/prepare_simde.py
+127 −1 src/codegen/codegen_writer.cpp
+11 −3 src/codegen/config.cpp
+116 −9 src/codegen/function_graph.cpp
+50 −19 src/codegen/phase_gapfill.cpp
+2 −2 src/core/platform_win.h
+153 −13 src/core/timer_queue.cpp
+2 −2 src/graphics/command_processor.cpp
+24 −2 src/graphics/d3d12/pipeline_cache.cpp
+23 −15 src/graphics/graphics_system.cpp
+33 −6 src/graphics/vulkan/pipeline_cache.cpp
+7 −0 src/input/input_system.cpp
+1 −1 src/kernel/xboxkrnl/xboxkrnl_rtl.cpp
+3 −0 src/system/CMakeLists.txt
+6 −4 src/system/function_dispatcher.cpp
+6 −4 src/system/runtime.cpp
+3 −0 src/ui/rex_app.cpp
+59 −0 tests/CMakeLists.txt
+268 −0 tests/regression/emit_interior_entries.cpp
+160 −0 tests/regression/test_app_launch.py
+212 −0 tests/regression/test_gapfill_cleanup.py
+311 −0 tests/regression/test_graph_registration.py
+166 −0 tests/regression/test_graphics_interrupt_concurrency.py
+216 −0 tests/regression/test_graphics_shutdown.py
+192 −0 tests/regression/test_interior_entries.py
+99 −0 tests/regression/test_interrupt_tls.py
+148 −0 tests/regression/test_nt_time_fields.py
+157 −0 tests/regression/test_prepare_simde.py
+214 −0 tests/regression/test_runtime_shutdown.py
+163 −0 tests/regression/test_shader_cache_bounds.py
+84 −0 tests/regression/test_simde_stream_pi.py
+237 −0 tests/regression/test_timer_lifecycle.py
+232 −0 tests/regression/test_timer_wait.py
+152 −0 tests/regression/test_vulkan_pipeline_storage.py
+1 −0 tests/unit/CMakeLists.txt
+37 −0 tests/unit/codegen/codegen_writer_test.cpp
+2 −2 tests/unit/codegen/output_stamp_test.cpp
+31 −1 tests/unit/core/chrono_test.cpp
+5 −2 tests/unit/core/cvar_test.cpp
+1 −0 thirdparty/CMakeLists.txt
185 changes: 158 additions & 27 deletions rexlego/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ if(LEGODIMENSIONS_NATIVE_GPU)
endif()

enable_language(C)
find_package(Python3 COMPONENTS Interpreter REQUIRED)
execute_process(
COMMAND "${Python3_EXECUTABLE}"
"${CMAKE_CURRENT_SOURCE_DIR}/../tools/gpu-aot/prepare_plume.py" --check
RESULT_VARIABLE LEGO_PLUME_PREPARE_RESULT
OUTPUT_VARIABLE LEGO_PLUME_PREPARE_OUTPUT
ERROR_VARIABLE LEGO_PLUME_PREPARE_ERROR
TIMEOUT 30)
if(NOT LEGO_PLUME_PREPARE_RESULT STREQUAL "0")
message(FATAL_ERROR "Native Plume dependency needs preparation. Run python tools/gpu-aot/prepare_plume.py.\n${LEGO_PLUME_PREPARE_OUTPUT}${LEGO_PLUME_PREPARE_ERROR}")
endif()
set(PLUME_D3D12_AGILITY_SDK_ENABLED OFF CACHE BOOL "" FORCE)
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/plume"
"${CMAKE_CURRENT_BINARY_DIR}/thirdparty/plume"
Expand Down Expand Up @@ -107,7 +118,7 @@ if(LEGODIMENSIONS_NATIVE_GPU)
target_include_directories(legodimensions PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/miniz"
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/zstd")
target_link_libraries(legodimensions PRIVATE plume d3d12 dxgi rex::xxhash)
target_link_libraries(legodimensions PRIVATE plume d3d12 dxgi rex::xxhash renderdoc)

# Generated locally by tools/gpu-aot. Keeping it out of Git avoids a
# multi-megabyte generated source file while still making an enabled build
Expand Down Expand Up @@ -160,6 +171,29 @@ if(LEGODIMENSIONS_NATIVE_GPU)
"${CMAKE_CURRENT_BINARY_DIR}/generated/gpu_native/shaders")
set(LEGO_NATIVE_DXC
"${LEGO_DXC_ROOT}/bin/${LEGO_DXC_ARCH}/dxc.exe")
# Both archive prelinkers are built for the Windows target even when
# standalone host shader compilation uses a host-native DXC executable.
if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR)
message(FATAL_ERROR
"Native GPU cross-build prelinkers require CMAKE_CROSSCOMPILING_EMULATOR, including when LEGO_HOST_DXC_EXECUTABLE is set")
endif()
set(LEGO_HOST_DXC_EXECUTABLE "" CACHE FILEPATH
"Host-native DXC executable for build-time host shader compilation")
if(LEGO_HOST_DXC_EXECUTABLE)
if(NOT EXISTS "${LEGO_HOST_DXC_EXECUTABLE}")
message(FATAL_ERROR "Host DXC not found: ${LEGO_HOST_DXC_EXECUTABLE}")
endif()
set(LEGO_NATIVE_DXC "${LEGO_HOST_DXC_EXECUTABLE}")
set(LEGO_NATIVE_DXC_COMMAND "${LEGO_NATIVE_DXC}")
elseif(CMAKE_CROSSCOMPILING)
if(NOT CMAKE_CROSSCOMPILING_EMULATOR)
message(FATAL_ERROR
"Cross-building needs LEGO_HOST_DXC_EXECUTABLE or CMAKE_CROSSCOMPILING_EMULATOR for Windows DXC")
endif()
set(LEGO_NATIVE_DXC_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} "${LEGO_NATIVE_DXC}")
else()
set(LEGO_NATIVE_DXC_COMMAND "${LEGO_NATIVE_DXC}")
endif()
foreach(LEGO_HOST_SHADER IN ITEMS copy_vs copy_color_ps resolve_color_ps depth_pack_ps depth_restore_ps)
if(LEGO_HOST_SHADER STREQUAL "copy_vs")
set(LEGO_HOST_SHADER_PROFILE vs_6_6)
Expand All @@ -172,14 +206,15 @@ if(LEGODIMENSIONS_NATIVE_GPU)
OUTPUT "${LEGO_HOST_SHADER_HEADER}"
COMMAND ${CMAKE_COMMAND} -E make_directory
"${LEGO_NATIVE_GENERATED_SHADER_DIR}"
COMMAND "${LEGO_NATIVE_DXC}"
COMMAND ${LEGO_NATIVE_DXC_COMMAND}
-T ${LEGO_HOST_SHADER_PROFILE} -E main -HV 2021
-all-resources-bound -Wno-ignored-attributes
-I "${LEGO_NATIVE_HOST_SHADER_DIR}"
-Fh "${LEGO_HOST_SHADER_HEADER}"
-Vn g_${LEGO_HOST_SHADER}_dxil
"${LEGO_NATIVE_HOST_SHADER_DIR}/${LEGO_HOST_SHADER}.hlsl"
DEPENDS
"${LEGO_NATIVE_DXC}"
"${LEGO_NATIVE_HOST_SHADER_DIR}/${LEGO_HOST_SHADER}.hlsl"
"${LEGO_NATIVE_HOST_SHADER_DIR}/copy_common.hlsli"
COMMENT "Compiling ${LEGO_HOST_SHADER}.hlsl (DXIL)"
Expand Down Expand Up @@ -235,19 +270,84 @@ if(LEGODIMENSIONS_NATIVE_GPU)

add_custom_command(
OUTPUT "${LEGO_NATIVE_LINKED_SHADER_CACHE}"
COMMAND "$<TARGET_FILE:lego_gpu_prelink>"
COMMAND lego_gpu_prelink
"${LEGO_NATIVE_LINKED_SHADER_CACHE}"
DEPENDS lego_gpu_prelink
COMMENT "Pre-linking LEGO specialization-constant shader variants"
VERBATIM)
target_sources(legodimensions PRIVATE "${LEGO_NATIVE_LINKED_SHADER_CACHE}")
set_source_files_properties("${LEGO_NATIVE_LINKED_SHADER_CACHE}"
PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
add_custom_target(lego_main_linked_cache
DEPENDS "${LEGO_NATIVE_LINKED_SHADER_CACHE}")
add_dependencies(legodimensions lego_main_linked_cache)
# Large compressed banks otherwise become millions of C++ initializer
# values. Keep their metadata in C++, but embed their unchanged bytes in a
# target COFF object when host LLVM tools support the target's MSVC ABI.
find_program(LEGO_HOST_LLVM_MC NAMES llvm-mc llvm-mc-22 llvm-mc-21 llvm-mc-20
NO_CMAKE_FIND_ROOT_PATH)
set(LEGO_NATIVE_BINARY_CACHE_ARCH "")
# Windows native generators can retain the host CMAKE_SYSTEM_PROCESSOR
# when clang-cl targets another architecture. Use the compiler's proven
# architecture and pointer width; ARM64EC/X86/unknown retain C++ embedding.
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "x64")
set(LEGO_NATIVE_BINARY_CACHE_ARCH x86_64)
elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
set(LEGO_NATIVE_BINARY_CACHE_ARCH aarch64)
endif()
endif()
set(LEGO_NATIVE_BINARY_CACHE_SUPPORTED OFF)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC" AND
LEGO_NATIVE_BINARY_CACHE_ARCH AND LEGO_HOST_LLVM_MC AND
EXISTS "${LEGO_HOST_LLVM_MC}" AND NOT IS_DIRECTORY "${LEGO_HOST_LLVM_MC}" AND
Python3_Interpreter_FOUND)
set(LEGO_NATIVE_BINARY_CACHE_SUPPORTED ON)
endif()
option(LEGO_NATIVE_BINARY_CACHE
"Embed the main linked DXIL bytes as COFF instead of a C++ initializer"
${LEGO_NATIVE_BINARY_CACHE_SUPPORTED})
if(LEGO_NATIVE_BINARY_CACHE)
if(NOT LEGO_NATIVE_BINARY_CACHE_SUPPORTED)
message(FATAL_ERROR
"LEGO_NATIVE_BINARY_CACHE needs x64/ARM64 Windows Clang with the MSVC ABI, Python3, and host llvm-mc; set LEGO_NATIVE_BINARY_CACHE=OFF for C++ embedding")
endif()
set(LEGO_NATIVE_BINARY_CACHE_SCRIPT
"${CMAKE_CURRENT_SOURCE_DIR}/../tools/gpu-aot/embed_linked_bank.py")
set(LEGO_NATIVE_BINARY_CACHE_DIR
"${CMAKE_CURRENT_BINARY_DIR}/generated/gpu_native/linked-bank")
set(LEGO_NATIVE_BINARY_CACHE_METADATA
"${LEGO_NATIVE_BINARY_CACHE_DIR}/linked-bank-metadata.cpp")
set(LEGO_NATIVE_BINARY_CACHE_OBJECT
"${LEGO_NATIVE_BINARY_CACHE_DIR}/linked-bank.obj")
add_custom_command(
OUTPUT "${LEGO_NATIVE_BINARY_CACHE_METADATA}" "${LEGO_NATIVE_BINARY_CACHE_OBJECT}"
BYPRODUCTS
"${LEGO_NATIVE_BINARY_CACHE_DIR}/linked-bank.bin"
"${LEGO_NATIVE_BINARY_CACHE_DIR}/linked-bank.s"
"${LEGO_NATIVE_BINARY_CACHE_DIR}/linked-bank-manifest.json"
COMMAND "${Python3_EXECUTABLE}" "${LEGO_NATIVE_BINARY_CACHE_SCRIPT}"
"${LEGO_NATIVE_LINKED_SHADER_CACHE}" "${LEGO_NATIVE_BINARY_CACHE_DIR}"
--llvm-mc "${LEGO_HOST_LLVM_MC}"
--arch "${LEGO_NATIVE_BINARY_CACHE_ARCH}"
DEPENDS "${LEGO_NATIVE_LINKED_SHADER_CACHE}"
"${LEGO_NATIVE_BINARY_CACHE_SCRIPT}" "${LEGO_HOST_LLVM_MC}"
COMMENT "Embedding main linked DXIL bank as ${LEGO_NATIVE_BINARY_CACHE_ARCH} COFF"
VERBATIM)
target_sources(legodimensions PRIVATE
"${LEGO_NATIVE_BINARY_CACHE_METADATA}" "${LEGO_NATIVE_BINARY_CACHE_OBJECT}")
set_source_files_properties("${LEGO_NATIVE_BINARY_CACHE_METADATA}"
PROPERTIES GENERATED TRUE SKIP_PRECOMPILE_HEADERS ON)
set_source_files_properties("${LEGO_NATIVE_BINARY_CACHE_OBJECT}"
PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
else()
target_sources(legodimensions PRIVATE "${LEGO_NATIVE_LINKED_SHADER_CACHE}")
set_source_files_properties("${LEGO_NATIVE_LINKED_SHADER_CACHE}"
PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
endif()
set(LEGO_NATIVE_RUNTIME_LINKED_SHADER_CACHE
"${CMAKE_CURRENT_SOURCE_DIR}/out/native-gpu/runtime-linked-dxil-cache.cpp")
add_custom_command(
OUTPUT "${LEGO_NATIVE_RUNTIME_LINKED_SHADER_CACHE}"
COMMAND "$<TARGET_FILE:lego_gpu_prelink_runtime>"
COMMAND lego_gpu_prelink_runtime
"${LEGO_NATIVE_RUNTIME_LINKED_SHADER_CACHE}"
DEPENDS lego_gpu_prelink_runtime
COMMENT "Pre-linking LEGO runtime shader variants"
Expand All @@ -259,11 +359,15 @@ if(LEGODIMENSIONS_NATIVE_GPU)
src/gpu_native/runtime_linked_shader_cache.cpp
PROPERTIES OBJECT_DEPENDS "${LEGO_NATIVE_RUNTIME_LINKED_SHADER_CACHE}")

# Fingerprint the exact native renderer inputs. CMAKE_CONFIGURE_DEPENDS
# makes a header-only edit trigger reconfigure as well as recompilation,
# and the fingerprint printed at startup proves which executable is live.
# Fingerprint the exact native renderer inputs after generated shader banks
# exist. Hashing the linked cache during configure prevented a fresh build
# from reaching the prelink target that creates that same file.
set(LEGO_NATIVE_GPU_FINGERPRINT_INPUTS
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/plume/plume_d3d12.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/plume/plume_d3d12.h"
"${CMAKE_CURRENT_SOURCE_DIR}/../tools/gpu-aot/prepare_plume.py"
"${CMAKE_CURRENT_SOURCE_DIR}/../tools/gpu-aot/patches/plume-state-cache.patch"
"${CMAKE_CURRENT_SOURCE_DIR}/../tools/gpu-aot/patches/plume-vulkan-readback.patch"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_native/device.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_native/device.h"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_native/renderer_route.h"
Expand Down Expand Up @@ -330,26 +434,53 @@ if(LEGODIMENSIONS_NATIVE_GPU)
"${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_native/runtime_shader_cache.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_native/runtime_linked_shader_cache.cpp"
"${LEGO_NATIVE_SHADER_CACHE}"
"${LEGO_NATIVE_MICROCODE_INDEX}"
"${LEGO_NATIVE_LINKED_SHADER_CACHE}"
"${LEGO_NATIVE_RUNTIME_SHADER_CACHE}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
${LEGO_NATIVE_GPU_FINGERPRINT_INPUTS})
set(LEGO_NATIVE_GPU_FINGERPRINT_MATERIAL "")
foreach(LEGO_NATIVE_GPU_INPUT IN LISTS LEGO_NATIVE_GPU_FINGERPRINT_INPUTS)
file(SHA256 "${LEGO_NATIVE_GPU_INPUT}" LEGO_NATIVE_GPU_INPUT_HASH)
string(APPEND LEGO_NATIVE_GPU_FINGERPRINT_MATERIAL
"${LEGO_NATIVE_GPU_INPUT_HASH}")
endforeach()
string(SHA256 LEGO_NATIVE_GPU_FINGERPRINT_FULL
"${LEGO_NATIVE_GPU_FINGERPRINT_MATERIAL}")
string(SUBSTRING "${LEGO_NATIVE_GPU_FINGERPRINT_FULL}" 0 16
LEGO_NATIVE_GPU_FINGERPRINT)
configure_file(src/gpu_native/build_info.h.in
"${CMAKE_CURRENT_BINARY_DIR}/generated/native_gpu_build_info.h" @ONLY)
"${LEGO_NATIVE_RUNTIME_SHADER_CACHE}"
"${LEGO_NATIVE_RUNTIME_LINKED_SHADER_CACHE}")
# Include every native helper header so changes to upload, bounds or
# completion logic cannot retain an older executable fingerprint.
file(GLOB_RECURSE LEGO_NATIVE_GPU_LOCAL_HEADERS CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_native/*.h")
list(APPEND LEGO_NATIVE_GPU_FINGERPRINT_INPUTS ${LEGO_NATIVE_GPU_LOCAL_HEADERS})
list(REMOVE_DUPLICATES LEGO_NATIVE_GPU_FINGERPRINT_INPUTS)
set(LEGO_NATIVE_GPU_FINGERPRINT_SCRIPT
"${CMAKE_CURRENT_BINARY_DIR}/generate-native-gpu-fingerprint.cmake")
file(CONFIGURE OUTPUT "${LEGO_NATIVE_GPU_FINGERPRINT_SCRIPT}" CONTENT [=[
set(LEGO_NATIVE_GPU_FINGERPRINT_INPUTS "@LEGO_NATIVE_GPU_FINGERPRINT_INPUTS@")
set(LEGO_NATIVE_GPU_FINGERPRINT_MATERIAL "")
foreach(LEGO_NATIVE_GPU_INPUT IN LISTS LEGO_NATIVE_GPU_FINGERPRINT_INPUTS)
file(SHA256 "${LEGO_NATIVE_GPU_INPUT}" LEGO_NATIVE_GPU_INPUT_HASH)
string(APPEND LEGO_NATIVE_GPU_FINGERPRINT_MATERIAL "${LEGO_NATIVE_GPU_INPUT_HASH}")
endforeach()
string(SHA256 LEGO_NATIVE_GPU_FINGERPRINT_FULL "${LEGO_NATIVE_GPU_FINGERPRINT_MATERIAL}")
string(SUBSTRING "${LEGO_NATIVE_GPU_FINGERPRINT_FULL}" 0 16 LEGO_NATIVE_GPU_FINGERPRINT)
configure_file("@CMAKE_CURRENT_SOURCE_DIR@/src/gpu_native/build_info.h.in"
"@CMAKE_CURRENT_BINARY_DIR@/generated/native_gpu_build_info.h" @ONLY)
file(WRITE "@CMAKE_CURRENT_BINARY_DIR@/native-gpu-build.txt"
"LEGO Dimensions native GPU ${LEGO_NATIVE_GPU_FINGERPRINT}\n")
]=] @ONLY)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated/native_gpu_build_info.h"
"${CMAKE_CURRENT_BINARY_DIR}/native-gpu-build.txt"
COMMAND ${CMAKE_COMMAND} -P "${LEGO_NATIVE_GPU_FINGERPRINT_SCRIPT}"
DEPENDS ${LEGO_NATIVE_GPU_FINGERPRINT_INPUTS}
"${LEGO_NATIVE_GPU_FINGERPRINT_SCRIPT}"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gpu_native/build_info.h.in"
COMMENT "Fingerprinting native renderer sources and generated shader banks"
VERBATIM)
add_custom_target(lego_native_gpu_fingerprint
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated/native_gpu_build_info.h"
"${CMAKE_CURRENT_BINARY_DIR}/native-gpu-build.txt")
# Make generators must complete both bank producers before the fingerprint
# and metadata compilation consume their outputs through separate paths.
add_dependencies(lego_native_gpu_fingerprint
lego_main_linked_cache lego_runtime_linked_cache)
add_dependencies(legodimensions lego_native_gpu_fingerprint)
target_sources(legodimensions PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/generated/native_gpu_build_info.h")
target_include_directories(legodimensions PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/generated")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/native-gpu-build.txt"
"LEGO Dimensions native GPU ${LEGO_NATIVE_GPU_FINGERPRINT}\n")
add_custom_command(TARGET legodimensions POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/native-gpu-build.txt"
Expand Down
12 changes: 7 additions & 5 deletions rexlego/legodimensions_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,27 @@
# Same fix as the analysis-time unresolved calls: declare it as an entry point.

[functions]
# These addresses are callable interior entries. Their body owners preserve
# backward branches, live registers, and the owner's stack epilogue.
0x82D73A10 = {}
0x8307CA78 = {}
0x8307CA78 = { body = 0x8307C528 }
0x83803F18 = {}
0x82888768 = {}
0x838052D8 = {}
0x838052D8 = { body = 0x838051D0 }
0x8381BB80 = {}
0x839AAE60 = {}
0x839AAE60 = { body = 0x839AACC0 }
0x82B68438 = {}
0x83283438 = {}
0x82B6B878 = {}
0x82FD1520 = {}
0x82FD1520 = { body = 0x82FD1470 }
0x82B63298 = {}
0x8361E6E8 = {}
0x837FE708 = {}
0x83283448 = {}
0x8379EEF8 = {}
0x8379EF10 = {}
0x8379E7D0 = {}
0x82D41F28 = {}
0x82D41F28 = { body = 0x82D416A0 }
0x832A2F88 = {}
0x8361E6F8 = {}
0x8361E6D8 = {}
Expand Down
4 changes: 3 additions & 1 deletion rexlego/src/gpu_native/alpha_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ struct NativeAlphaState {
inline NativeAlphaState DecodeNativeAlphaState(std::uint32_t color_control,
float reference) {
// TU23 83FB7E00 / 83FB82C0: enable bit 3, raw Xenos compare bits 0..2.
// 83FB92B8 stores FLOAT BITS unchanged; no integer /255 or /256 mapping.
// Reference is the normalized float shadow at +10500. TU23 83FB8260
// converts the integer ALPHAREF to float and multiplies by 1/255 there.
// The separate float state written by 83FB92B8 at +10620 is not ALPHAREF.
return {(color_control & 8u) != 0, color_control & 7u, reference};
}
} // namespace legodimensions::gpu_native
46 changes: 46 additions & 0 deletions rexlego/src/gpu_native/buffer_alloc_diagnostic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once
#include <charconv>
#include <cstdint>
#include <filesystem>
#include <optional>
#include <string>
#include <string_view>
#include <utility>

namespace legodimensions::gpu_native {
// Recording-lock serialized, metadata-only diagnostic. A trigger arms the
// following frame; allocation activity during startup consumes no record budget.
class BufferAllocationDiagnostic {
public:
static std::optional<uint32_t> ParseGuest(std::string_view value) {
if (value.size() != 8) return std::nullopt;
uint32_t guest = 0;
const auto parsed = std::from_chars(value.data(), value.data() + value.size(), guest, 16);
if (parsed.ec != std::errc{} || parsed.ptr != value.data() + value.size()) return std::nullopt;
return guest;
}
BufferAllocationDiagnostic(std::optional<uint32_t> guest = {},
std::filesystem::path trigger = {}) : guest_(guest), trigger_(std::move(trigger)) {}
bool Select(uint32_t frame, uint32_t guest) {
if (!guest_ || trigger_.empty() || guest != *guest_ || records_ >= 128) return false;
if (!armed_) {
if (checked_ && checked_frame_ == frame) return false;
checked_ = true;
checked_frame_ = frame;
std::error_code error;
if (!std::filesystem::is_regular_file(trigger_, error) || error ||
!std::filesystem::remove(trigger_, error) || error) return false;
armed_ = true;
armed_frame_ = frame;
}
if (frame == armed_frame_) return false;
++records_;
return true;
}
private:
std::optional<uint32_t> guest_;
std::filesystem::path trigger_;
bool checked_ = false, armed_ = false;
uint32_t checked_frame_ = 0, armed_frame_ = 0, records_ = 0;
};
} // namespace legodimensions::gpu_native
8 changes: 8 additions & 0 deletions rexlego/src/gpu_native/buffer_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ constexpr VertexBufferWindow DrawVertexWindow(uint32_t min_index, uint32_t max_i
offset % 4 || length % 4) return {};
return {uint32_t(offset), uint32_t(length)};
}

// Nonindexed vertices form a contiguous range. Widen before adding count so
// an overflowing range cannot turn into a small apparently valid upload.
constexpr bool NonIndexedVertexRange(uint32_t start, uint32_t count, uint32_t& last) {
if (!count || uint64_t(start) + count - 1 > UINT32_MAX) return false;
last = uint32_t(uint64_t(start) + count - 1);
return true;
}
}
Loading