diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08b4b6e2..b92ba2b6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,10 +4,12 @@ on: push: pull_request: - jobs: build: runs-on: windows-2025-vs2026 + strategy: + matrix: + configuration: [Debug-D3D12, Debug-Vulkan] steps: - name: Checkout repository @@ -59,40 +61,42 @@ jobs: shell: powershell run: | msbuild ./projects/modules/modules.vcxproj ` - /p:Configuration=Retail /p:Platform=x64 ` + /p:Configuration="${{ matrix.configuration }}" /p:Platform=x64 ` /pp:preprocessed.xml Select-String "_ZVcpkgCurrentInstalledDir" preprocessed.xml | Select-Object -First 5 - name: Build solution - run: msbuild ./projects/spectrum.sln /p:Configuration=Retail /p:Platform=x64 /m /v:minimal - - - name: Copy build output to workdir - shell: powershell - run: | - Copy-Item -Path ./bin/Retail/* -Destination ./workdir/ -Recurse -Force + run: msbuild ./projects/spectrum.sln /p:Configuration="${{ matrix.configuration }}" /p:Platform=x64 /m /v:minimal - - name: Upload build artifacts + - name: Upload build output uses: actions/upload-artifact@v4 if: always() with: - name: build-output - path: ./workdir/ - retention-days: 7 + name: build-${{ matrix.configuration }} + path: ./bin/Debug/ + retention-days: 1 test: runs-on: windows-2025-vs2026 needs: build + strategy: + matrix: + configuration: [Debug-D3D12, Debug-Vulkan] steps: - name: Download build output uses: actions/download-artifact@v4 with: - name: build-output - path: ./workdir + name: build-${{ matrix.configuration }} + path: ./bin/Debug - name: Run tests shell: powershell - working-directory: ./workdir + working-directory: ./bin/Debug run: | & ".\test.exe" - exit $LASTEXITCODE + if ($LASTEXITCODE -ne 0) { + Write-Error "Tests failed with exit code $LASTEXITCODE" + exit $LASTEXITCODE + } + Write-Host "All tests passed!" diff --git a/custom-overlay/directx-dxc/directx-dxc-config.cmake.in b/custom-overlay/directx-dxc/directx-dxc-config.cmake.in new file mode 100644 index 00000000..ef7fc524 --- /dev/null +++ b/custom-overlay/directx-dxc/directx-dxc-config.cmake.in @@ -0,0 +1,28 @@ +get_filename_component(_dxc_root "${CMAKE_CURRENT_LIST_DIR}" PATH) +get_filename_component(_dxc_root "${_dxc_root}" PATH) + +set(DIRECTX_DXC_TOOL "${_dxc_root}/@tool_path@" CACHE PATH "Location of the dxc tool") +mark_as_advanced(DIRECTX_DXC_TOOL) + +add_library(Microsoft::DirectXShaderCompiler SHARED IMPORTED) +set_target_properties(Microsoft::DirectXShaderCompiler PROPERTIES + IMPORTED_CONFIGURATIONS "Debug;Release" + IMPORTED_LOCATION_DEBUG "${_dxc_root}/@dll_debug_dir@/@dll_name_dxc@" + IMPORTED_LOCATION_RELEASE "${_dxc_root}/@dll_dir@/@dll_name_dxc@" + IMPORTED_IMPLIB "${_dxc_root}/lib/@lib_name@" + IMPORTED_SONAME "@lib_name@" + INTERFACE_INCLUDE_DIRECTORIES "${_dxc_root}/include/directx-dxc" + INTERFACE_LINK_LIBRARIES "Microsoft::DXIL" + IMPORTED_LINK_INTERFACE_LANGUAGES "C") + +add_library(Microsoft::DXIL SHARED IMPORTED) +set_target_properties(Microsoft::DXIL PROPERTIES + IMPORTED_CONFIGURATIONS "Debug;Release" + IMPORTED_LOCATION_DEBUG "${_dxc_root}/@dll_debug_dir@/@dll_name_dxil@" + IMPORTED_LOCATION_RELASE "${_dxc_root}/@dll_dir@/@dll_name_dxil@" + IMPORTED_IMPLIB "${_dxc_root}/lib/@lib_name@" + IMPORTED_NO_SONAME TRUE + INTERFACE_INCLUDE_DIRECTORIES "${_dxc_root}/include/directx-dxc" + IMPORTED_LINK_INTERFACE_LANGUAGES "C") + +unset(_dxc_root) diff --git a/custom-overlay/directx-dxc/portfile.cmake b/custom-overlay/directx-dxc/portfile.cmake new file mode 100644 index 00000000..6bc258b2 --- /dev/null +++ b/custom-overlay/directx-dxc/portfile.cmake @@ -0,0 +1,135 @@ +set(VCPKG_POLICY_DLLS_IN_STATIC_LIBRARY enabled) + +# DXC v1.10.2605.24 — "Shader Model 6.10 Preview" (May 2026, patch 1) +# This preview release fixes the nested-struct SPIR-V codegen bug present in +# the v1.9 stable line (OpTypeStruct ID mismatch under ResourceDescriptorHeap). +set(DIRECTX_DXC_TAG v1.10.2605.24) +set(DIRECTX_DXC_VERSION preview_2026_05_22) + +if (NOT VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic") + message(STATUS "Note: ${PORT} always requires dynamic library linkage at runtime.") +endif() + +if (VCPKG_TARGET_IS_LINUX) + vcpkg_download_distfile(ARCHIVE + URLS "https://github.com/microsoft/DirectXShaderCompiler/releases/download/${DIRECTX_DXC_TAG}/linux_dxc_${DIRECTX_DXC_VERSION}.x86_64.tar.gz" + FILENAME "linux_dxc_${DIRECTX_DXC_VERSION}.tar.gz" + SHA512 0 + ) +else() + vcpkg_download_distfile(ARCHIVE + URLS "https://github.com/microsoft/DirectXShaderCompiler/releases/download/${DIRECTX_DXC_TAG}/dxc_${DIRECTX_DXC_VERSION}.zip" + FILENAME "dxc_${DIRECTX_DXC_VERSION}.zip" + SHA512 0dce57b47a13974ab700615d883c72eb2adcf8e2e7c1b03636ae0e7c2bbcd4b62d69ea9366f47cd80dedbb9d23c0ce1d2c2e92f1a166954b8160c0e61b4116ec + ) +endif() + +vcpkg_download_distfile( + LICENSE_TXT + URLS "https://raw.githubusercontent.com/microsoft/DirectXShaderCompiler/${DIRECTX_DXC_TAG}/LICENSE.TXT" + FILENAME "LICENSE.${DIRECTX_DXC_VERSION}" + SHA512 9feaa85ca6d42d5a2d6fe773706bbab8241e78390a9d61ea9061c8f0eeb5a3e380ff07c222e02fbf61af7f2b2f6dd31c5fc87247a94dae275dc0a20cdfcc8c9d +) + +vcpkg_extract_source_archive( + PACKAGE_PATH + ARCHIVE ${ARCHIVE} + NO_REMOVE_ONE_LEVEL +) + +if (VCPKG_TARGET_IS_LINUX) + file(INSTALL + "${PACKAGE_PATH}/include/dxc/dxcapi.h" + "${PACKAGE_PATH}/include/dxc/dxcerrors.h" + "${PACKAGE_PATH}/include/dxc/dxcisense.h" + "${PACKAGE_PATH}/include/dxc/WinAdapter.h" + DESTINATION "${CURRENT_PACKAGES_DIR}/include/${PORT}") + + file(INSTALL + "${PACKAGE_PATH}/lib/libdxcompiler.so" + "${PACKAGE_PATH}/lib/libdxil.so" + DESTINATION "${CURRENT_PACKAGES_DIR}/lib") + + if(NOT DEFINED VCPKG_BUILD_TYPE) + file(INSTALL + "${PACKAGE_PATH}/lib/libdxcompiler.so" + "${PACKAGE_PATH}/lib/libdxil.so" + DESTINATION "${CURRENT_PACKAGES_DIR}/debug/lib") + endif() + + file(INSTALL + "${PACKAGE_PATH}/bin/dxc" + DESTINATION "${CURRENT_PACKAGES_DIR}/tools/${PORT}/" + FILE_PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + + set(dll_name_dxc "libdxcompiler.so") + set(dll_name_dxil "libdxil.so") + set(dll_dir "lib") + if(NOT DEFINED VCPKG_BUILD_TYPE) + set(dll_debug_dir "debug/lib") + else() + set(dll_debug_dir "lib") + endif() + set(lib_name "libdxcompiler.so") + set(tool_path "tools/${PORT}/dxc") +else() + # VCPKG_TARGET_IS_WINDOWS + if(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64") + set(DXC_ARCH arm64) + elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86") + set(DXC_ARCH x86) + else() + set(DXC_ARCH x64) + endif() + + file(INSTALL + "${PACKAGE_PATH}/inc/dxcapi.h" + "${PACKAGE_PATH}/inc/dxcerrors.h" + "${PACKAGE_PATH}/inc/dxcisense.h" + "${PACKAGE_PATH}/inc/d3d12shader.h" + DESTINATION "${CURRENT_PACKAGES_DIR}/include/${PORT}") + + file(INSTALL "${PACKAGE_PATH}/lib/${DXC_ARCH}/dxcompiler.lib" DESTINATION "${CURRENT_PACKAGES_DIR}/lib") + if(NOT DEFINED VCPKG_BUILD_TYPE) + file(INSTALL "${PACKAGE_PATH}/lib/${DXC_ARCH}/dxcompiler.lib" DESTINATION "${CURRENT_PACKAGES_DIR}/debug/lib") + endif() + + file(INSTALL + "${PACKAGE_PATH}/bin/${DXC_ARCH}/dxcompiler.dll" + "${PACKAGE_PATH}/bin/${DXC_ARCH}/dxil.dll" + DESTINATION "${CURRENT_PACKAGES_DIR}/bin") + + if(NOT DEFINED VCPKG_BUILD_TYPE) + file(INSTALL + "${PACKAGE_PATH}/bin/${DXC_ARCH}/dxcompiler.dll" + "${PACKAGE_PATH}/bin/${DXC_ARCH}/dxil.dll" + DESTINATION "${CURRENT_PACKAGES_DIR}/debug/bin") + endif() + + file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/${PORT}/") + + file(INSTALL + "${PACKAGE_PATH}/bin/${DXC_ARCH}/dxc.exe" + "${PACKAGE_PATH}/bin/${DXC_ARCH}/dxcompiler.dll" + "${PACKAGE_PATH}/bin/${DXC_ARCH}/dxil.dll" + DESTINATION "${CURRENT_PACKAGES_DIR}/tools/${PORT}/") + + set(dll_name_dxc "dxcompiler.dll") + set(dll_name_dxil "dxil.dll") + set(dll_dir "bin") + set(dll_debug_dir "bin") + set(lib_name "dxcompiler.lib") + set(tool_path "tools/${PORT}/dxc.exe") +endif() + +vcpkg_copy_tool_dependencies("${CURRENT_PACKAGES_DIR}/tools/${PORT}") + +configure_file("${CMAKE_CURRENT_LIST_DIR}/directx-dxc-config.cmake.in" + "${CURRENT_PACKAGES_DIR}/share/${PORT}/${PORT}-config.cmake" + @ONLY) + +file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}") +vcpkg_install_copyright(FILE_LIST "${LICENSE_TXT}") diff --git a/custom-overlay/directx-dxc/usage b/custom-overlay/directx-dxc/usage new file mode 100644 index 00000000..444b8ac1 --- /dev/null +++ b/custom-overlay/directx-dxc/usage @@ -0,0 +1,6 @@ +The DirectX Shader Compiler package provides CMake targets: + + find_package(directx-dxc CONFIG REQUIRED) + target_link_libraries(main PRIVATE Microsoft::DirectXShaderCompiler) + +The CMake variable DIRECTX_DXC_TOOL is also set to point to the appropriate DXC command-line tool. diff --git a/custom-overlay/directx-dxc/vcpkg.json b/custom-overlay/directx-dxc/vcpkg.json new file mode 100644 index 00000000..92af7224 --- /dev/null +++ b/custom-overlay/directx-dxc/vcpkg.json @@ -0,0 +1,24 @@ +{ + "name": "directx-dxc", + "version-date": "2026-05-27", + "port-version": 1, + "description": "DirectX Shader Compiler v1.10.2605.24 (Shader Model 6.10 Preview)", + "homepage": "https://github.com/microsoft/DirectXShaderCompiler", + "documentation": "https://github.com/microsoft/DirectXShaderCompiler/wiki", + "license": null, + "supports": "(windows & !arm32 & !uwp & !xbox) | (linux & x64)", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + { + "name": "zlib", + "platform": "linux & !static" + } + ] +} diff --git a/main.sharpmake.cs b/main.sharpmake.cs index bd454828..5a1fe2be 100644 --- a/main.sharpmake.cs +++ b/main.sharpmake.cs @@ -12,12 +12,20 @@ public enum Mode Retail = 4 } + [Fragment, Flags] + public enum Backend + { + D3D12 = 1, + Vulkan = 2 + } + public class CustomTarget : ITarget { public Platform Platform; public DevEnv DevEnv; public Optimization Optimization; public Mode Mode; + public Backend Backend; } public static class Vcpkg @@ -52,7 +60,8 @@ public Common() : base(typeof(CustomTarget)) Platform = Platform.win64, DevEnv = DevEnv.vs2026, Optimization = Optimization.Release, - Mode = Mode.Debug | Mode.Profile | Mode.Retail + Mode = Mode.Debug | Mode.Profile | Mode.Retail, + Backend = Backend.D3D12 | Backend.Vulkan }); CustomProperties.Add("VcpkgEnabled", "true"); @@ -242,6 +251,12 @@ public override void ConfigureAll(Configuration conf, CustomTarget target) conf.TargetCopyFilesToSubDirectory.Add(new KeyValuePair(Vcpkg.DebugBin + @"\D3D12Core.dll", "D3D12")); conf.TargetCopyFilesToSubDirectory.Add(new KeyValuePair(Vcpkg.DebugBin + @"\d3d12SDKLayers.dll", "D3D12")); + // Per-backend module wrappers: compile only the active backend's wrapper. + if (target.Backend == Backend.D3D12) + conf.SourceFilesBuildExcludeRegex.Add(@".*\\Modules\\vulkan\\.*"); + else // Vulkan + conf.SourceFilesBuildExcludeRegex.Add(@".*\\Modules\\d3d12\\.*"); + conf.Options.Add(new Sharpmake.Options.Vc.Compiler.DisableSpecificWarnings("5260")); // adding inline to header units } @@ -281,13 +296,38 @@ public override void ConfigureAll(Configuration conf, CustomTarget target) { base.ConfigureAll(conf, target); - conf.LibraryFiles.Add("dxgi.lib"); - conf.LibraryFiles.Add("d3d12.lib"); - conf.LibraryFiles.Add("dxguid.lib"); - conf.LibraryFiles.Add("volatileaccessu.lib"); + if (target.Backend == Backend.D3D12) + { + // D3D12 backend: include D3D12/ and DXGI/ folders, exclude Vulkan/ + conf.LibraryFiles.Add("dxgi.lib"); + conf.LibraryFiles.Add("d3d12.lib"); + conf.LibraryFiles.Add("dxguid.lib"); + conf.LibraryFiles.Add("volatileaccessu.lib"); - conf.AddPublicDependency(target); - //conf.AddPrivateDependency(target); + conf.SourceFilesBuildExcludeRegex.Add(@".*\\HAL\\API\\Vulkan\\.*"); + + conf.Defines.Add("HAL_BACKEND_D3D12"); + } + else // Vulkan + { + // Vulkan backend: include Vulkan/ folder, exclude D3D12/ and DXGI/ + conf.SourceFilesBuildExcludeRegex.Add(@".*\\HAL\\API\\D3D12\\.*"); + conf.SourceFilesBuildExcludeRegex.Add(@".*\\HAL\\DXGI\\.*"); + + conf.Defines.Add("HAL_BACKEND_VULKAN"); + + // vulkan-1.lib is generated from C:\Windows\System32\vulkan-1.dll + // (the Vulkan loader shipped with GPU drivers). It lives next to + // the Vulkan module wrapper so the project is self-contained. + // If the Vulkan SDK is later installed, replace this with the SDK lib: + // %VULKAN_SDK%\Lib\vulkan-1.lib + // conf.LibraryFiles.Add(@"[project.SharpmakeCsPath]\sources\Modules\vulkan\vulkan-1.lib"); + } + + // DXC folder is always compiled — DXC emits SPIR-V for Vulkan too. + // (No exclusion needed for DXC.) + + conf.AddPublicDependency(target); } } @@ -298,9 +338,6 @@ public RenderSystem() { SourceRootPath = @"[project.SharpmakeCsPath]\sources\RenderSystem"; AssemblyName = "RenderSystem"; - - // Exclude the legacy FW1FontWrapper directory — replaced by FreeType - SourceFilesExcludeRegex.Add(@"FW1FontWrapper"); } public override void ConfigureAll(Configuration conf, CustomTarget target) @@ -338,6 +375,35 @@ public override void ConfigureAll(Configuration conf, CustomTarget target) } + // Minimal Vulkan clear-screen test — depends only on HAL (no RenderSystem). + // Useful for validating the Vulkan backend without the full engine init path. + [Sharpmake.Generate] + public class VulkanTest : Application + { + public VulkanTest() + { + SourceRootPath = @"[project.SharpmakeCsPath]\sources\VulkanTest"; + AssemblyName = "VulkanTest"; + } + + public override void ConfigureAll(Configuration conf, CustomTarget target) + { + base.ConfigureAll(conf, target); + + conf.LibraryFiles.Add("Onecore.lib"); + conf.LibraryFiles.Add("user32.lib"); + + conf.VcxprojUserFile = new Project.Configuration.VcxprojUserFileSettings(); + conf.VcxprojUserFile.LocalDebuggerWorkingDirectory = @"[project.SharpmakeCsPath]\workdir"; + + // Window.h lives under sources/Spectrum/Platform — expose it to VulkanTest + conf.IncludePaths.Add(@"[project.SharpmakeCsPath]\sources\Spectrum"); + + conf.AddPublicDependency(target); + conf.AddPublicDependency(target); + } + } + [Sharpmake.Generate] public class Spectrum : Application { @@ -414,7 +480,8 @@ public SpectrumSolution() Platform = Platform.win64, DevEnv = DevEnv.vs2026, Optimization = Optimization.Release, - Mode = Mode.Debug | Mode.Profile | Mode.Retail + Mode = Mode.Debug | Mode.Profile | Mode.Retail, + Backend = Backend.D3D12 | Backend.Vulkan }); } @@ -424,27 +491,28 @@ public void ConfigureAll(Configuration conf, CustomTarget target) conf.SolutionFileName = "Spectrum"; conf.SolutionPath = @"[solution.SharpmakeCsPath]\projects\"; string platformName = string.Empty; -/* - switch (target.Optimization) + + switch (target.Mode) { - case Optimization.Debug: platformName += "Debug "; break; - case Optimization.Release: platformName += "Release "; break; + case Mode.Debug: platformName += "Debug"; break; + case Mode.Retail: platformName += "Retail"; break; + case Mode.Profile: platformName += "Profile"; break; default: throw new NotImplementedException(); } - */ - - switch (target.Mode) + + switch (target.Backend) { - case Mode.Debug: platformName += "Debug"; break; - case Mode.Retail: platformName += "Retail"; break; - case Mode.Profile: platformName += "Profile"; break; + case Backend.D3D12: platformName += "-D3D12"; break; + case Backend.Vulkan: platformName += "-Vulkan"; break; default: throw new NotImplementedException(); } + conf.Name = platformName; conf.AddProject(target); + conf.AddProject(target); conf.AddProject(target); conf.AddProject(target); conf.AddProject(target); diff --git a/sources/Core/Data/Data.ixx b/sources/Core/Data/Data.ixx index 7f21df87..4f9b7767 100644 --- a/sources/Core/Data/Data.ixx +++ b/sources/Core/Data/Data.ixx @@ -177,6 +177,13 @@ export { return table.size(); } + + + void clear() + { m.lock(); + table.clear(); + m.unlock(); + } Cache() = default; Cache(std::function create_func) : create_func(create_func) {} diff --git a/sources/Core/Debug/Exceptions.cpp b/sources/Core/Debug/Exceptions.cpp index 03c89200..aaa5704a 100644 --- a/sources/Core/Debug/Exceptions.cpp +++ b/sources/Core/Debug/Exceptions.cpp @@ -14,7 +14,7 @@ namespace Exceptions stack_trace get_stack_trace() { - return 1; + return std::stacktrace::current(); } } diff --git a/sources/Core/Debug/Exceptions.ixx b/sources/Core/Debug/Exceptions.ixx index 0c270852..c2cddfed 100644 --- a/sources/Core/Debug/Exceptions.ixx +++ b/sources/Core/Debug/Exceptions.ixx @@ -3,7 +3,7 @@ export module Core:Exceptions; import stl.core; export namespace Exceptions { - using stack_trace = int; + using stack_trace = std::stacktrace; class Exception : public std::exception { diff --git a/sources/Core/FileSystem/ResourceManager.ixx b/sources/Core/FileSystem/ResourceManager.ixx index e99e5aef..f3adbb72 100644 --- a/sources/Core/FileSystem/ResourceManager.ixx +++ b/sources/Core/FileSystem/ResourceManager.ixx @@ -72,6 +72,11 @@ template concept CanReload = requires (T t, T t2) { t = t2; }; + +// Resources may opt into a cache subfolder via a static cache_subfolder(). +// Used to segregate backend-specific caches (shaders/PSOs → cache//), +// while backend-agnostic resources (textures) omit it and cache in the root. +template concept HasCacheSubfolder = requires { T::cache_subfolder(); }; template class resource_manager { @@ -125,7 +130,7 @@ public: } protected: - + SERIALIZE() { ar& NVP(header); @@ -133,12 +138,22 @@ protected: } _header header; + // Cache directory for this resource type: "cache", optionally with a + // per-resource subfolder (e.g. backend name for shaders/PSOs). + static std::filesystem::path cache_directory() + { + std::filesystem::path dir("cache"); + if constexpr (HasCacheSubfolder<_resource>) + dir /= _resource::cache_subfolder(); + return dir; + } + static std::shared_ptr<_resource> create_new(const _header& header) { std::shared_ptr<_resource> result; std::string header_hash = Hasher::hash(header) + ".bin"; - std::filesystem::path cache_dir ("cache"); + std::filesystem::path cache_dir = cache_directory(); std::filesystem::path path = cache_dir / header_hash; @@ -193,7 +208,7 @@ protected: result->file_depends = file_depends; result->header = header; std::string header_hash = Hasher::hash(header) + ".bin"; - std::filesystem::path cache_dir ("cache"); + std::filesystem::path cache_dir = cache_directory(); std::filesystem::path path = cache_dir / header_hash; FileDataStorage storage(path);//Serializer::get_stream(file->load_all()); diff --git a/sources/Core/Math/Math.ixx b/sources/Core/Math/Math.ixx index e4bdeda4..dc130e95 100644 --- a/sources/Core/Math/Math.ixx +++ b/sources/Core/Math/Math.ixx @@ -5,6 +5,7 @@ export import :Math.Vectors; export import :Math.Quaternion; export import :Math.Matrices; +export import :Math.Primitive; export import :Math.AABB; export import :Math.Frustum; export import :Math.Sphere; diff --git a/sources/Core/Math/Primitives/Plane.ixx b/sources/Core/Math/Primitives/Plane.ixx index c5cbbb19..86497bdd 100644 --- a/sources/Core/Math/Primitives/Plane.ixx +++ b/sources/Core/Math/Primitives/Plane.ixx @@ -1,9 +1,9 @@ export module Core:Math.Plane; -export import :Math.Constants; -export import :Math.Vectors; -export import :Math.Quaternion; -export import :Math.Matrices; +import :Math.Constants; +import :Math.Vectors; +import :Math.Quaternion; +import :Math.Matrices; import stl.memory; import :serialization; diff --git a/sources/Core/Math/Primitives/Primitive.ixx b/sources/Core/Math/Primitives/Primitive.ixx index 0bcecf57..8b8e6c62 100644 --- a/sources/Core/Math/Primitives/Primitive.ixx +++ b/sources/Core/Math/Primitives/Primitive.ixx @@ -1,9 +1,9 @@ export module Core:Math.Primitive; -export import :Math.Constants; -export import :Math.Vectors; -export import :Math.Quaternion; -export import :Math.Matrices; +import :Math.Constants; +import :Math.Vectors; +import :Math.Quaternion; +import :Math.Matrices; import stl.memory; import :serialization; diff --git a/sources/Core/Math/Primitives/Sphere.ixx b/sources/Core/Math/Primitives/Sphere.ixx index 8bb5d3ee..f08a039f 100644 --- a/sources/Core/Math/Primitives/Sphere.ixx +++ b/sources/Core/Math/Primitives/Sphere.ixx @@ -1,10 +1,10 @@ export module Core:Math.Sphere; -export import :Math.Constants; -export import :Math.Vectors; -export import :Math.Quaternion; -export import :Math.Matrices; -export import :Math.Primitive; +import :Math.Constants; +import :Math.Vectors; +import :Math.Quaternion; +import :Math.Matrices; +import :Math.Primitive; import stl.memory; import :serialization; diff --git a/sources/Core/patterns/Singleton.ixx b/sources/Core/patterns/Singleton.ixx index 425ffb9a..9be0bdf3 100644 --- a/sources/Core/patterns/Singleton.ixx +++ b/sources/Core/patterns/Singleton.ixx @@ -51,7 +51,7 @@ public: if (instance) return instance.get(); - ASSERT(first); + //ASSERT(first); first = false; if constexpr (HasCreationFunc) { diff --git a/sources/Core/patterns/StateContext.ixx b/sources/Core/patterns/StateContext.ixx index 5e08a7e2..d750ccb0 100644 --- a/sources/Core/patterns/StateContext.ixx +++ b/sources/Core/patterns/StateContext.ixx @@ -55,6 +55,16 @@ export{ { init_func(s); } + // Also reset existing overflow-map entries (ids >= part_count). + // Without this, per-command-list CPU states with ids >= 128 retain + // stale used=true flags and dangling first_usage/last_usage pointers + // from the previous frame (usage_points.clear() frees them in + // on_execute). Accessing those dangling pointers in compile_transitions + // is UB and prevents the correct PRESENT→COLOR_ATTACHMENT barrier from + // being emitted, causing the swapchain image to render black. + std::lock_guard guard(states_lock); + for (auto& [k, v] : state_map) + init_func(v); } } }; diff --git a/sources/HAL/API/D3D12/HAL.D3D12.CommandAllocator.cpp b/sources/HAL/API/D3D12/HAL.D3D12.CommandAllocator.cpp index 61c1d6cb..3644708e 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.CommandAllocator.cpp +++ b/sources/HAL/API/D3D12/HAL.D3D12.CommandAllocator.cpp @@ -12,6 +12,8 @@ namespace HAL { device.get_native_device()->CreateCommandAllocator(t, IID_PPV_ARGS(&m_commandAllocator))); } + CommandAllocator::~CommandAllocator() {} + void CommandAllocator::reset() { m_commandAllocator->Reset(); diff --git a/sources/HAL/API/D3D12/HAL.D3D12.Device.ixx b/sources/HAL/API/D3D12/HAL.D3D12.Device.ixx index 405d9aef..fd703393 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.Device.ixx +++ b/sources/HAL/API/D3D12/HAL.D3D12.Device.ixx @@ -24,6 +24,8 @@ export namespace HAL { bool full_bindless = false; bool direct_gpu_upload_heap = false; bool work_graph = false; + // D3D12 has no alignment constraint on StructuredBuffer FirstElement offsets. + uint32_t min_storage_buffer_offset_alignment = 1; }; namespace API { diff --git a/sources/HAL/API/D3D12/HAL.D3D12.DirectXTexBridge.cpp b/sources/HAL/API/D3D12/HAL.D3D12.DirectXTexBridge.cpp new file mode 100644 index 00000000..7e2fbc5a --- /dev/null +++ b/sources/HAL/API/D3D12/HAL.D3D12.DirectXTexBridge.cpp @@ -0,0 +1,39 @@ +// Non-module TU: wrapper functions that call DirectXTex APIs accepting DXGI_FORMAT. +// Module partitions cannot call these directly because d3d12.ixx exports +// `using DXGI_FORMAT = ::DXGI_FORMAT` which module-attaches the type, making it +// incompatible with the header-based DXGI_FORMAT that DirectXTex was compiled against. +// Defining wrappers here (plain .cpp, no module) uses the real header types, +// and the module side declares + calls them — the linker connects via mangled name. +// +// Add new wrappers here for any other DirectXTex API that takes DXGI_FORMAT +// (e.g. Convert, Compress) to restore features removed due to this limitation. + +#include +#include +#include +#pragma comment(lib, "ole32.lib") + +#include +#include + +// Expand R8_UNORM pixels to RGBA8 (g,g,g,255) and encode as PNG. +std::vector hal_r8_to_png(const uint8_t* src, uint32_t width, uint32_t height) +{ + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + DirectX::ScratchImage expanded; + if (FAILED(expanded.Initialize2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1))) + return {}; + + uint8_t* dst = expanded.GetImages()[0].pixels; + for (uint32_t p = 0; p < width * height; ++p, ++src, dst += 4) + { dst[0] = *src; dst[1] = *src; dst[2] = *src; dst[3] = 0xFF; } + + DirectX::Blob blob; + if (FAILED(DirectX::SaveToWICMemory(*expanded.GetImages(), + DirectX::WIC_FLAGS_NONE, GUID_ContainerFormatPng, blob))) + return {}; + + auto* bytes = static_cast(blob.GetBufferPointer()); + return std::vector(bytes, bytes + blob.GetBufferSize()); +} diff --git a/sources/HAL/API/D3D12/HAL.D3D12.Fence.cpp b/sources/HAL/API/D3D12/HAL.D3D12.Fence.cpp index 87072cb1..7d7978d0 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.Fence.cpp +++ b/sources/HAL/API/D3D12/HAL.D3D12.Fence.cpp @@ -23,6 +23,8 @@ namespace HAL WaitForSingleObject(m_fenceEvent, INFINITE); } + Fence::~Fence() {} + Fence::Fence(Device& device) { device.native_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)); diff --git a/sources/HAL/API/D3D12/HAL.D3D12.PipelineState.cpp b/sources/HAL/API/D3D12/HAL.D3D12.PipelineState.cpp index 7113bd8e..88bdfee3 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.PipelineState.cpp +++ b/sources/HAL/API/D3D12/HAL.D3D12.PipelineState.cpp @@ -391,7 +391,7 @@ namespace HAL slots.merge(desc.amplification->slots_usage); } - ASSERT(!slots.empty()); +// ASSERT(!slots.empty()); { auto RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); RasterizerState.CullMode = to_native(desc.rasterizer.cull_mode); diff --git a/sources/HAL/API/D3D12/HAL.D3D12.Queue.cpp b/sources/HAL/API/D3D12/HAL.D3D12.Queue.cpp index 90bb55e9..ea80bf48 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.Queue.cpp +++ b/sources/HAL/API/D3D12/HAL.D3D12.Queue.cpp @@ -8,32 +8,10 @@ import HAL; namespace HAL { - Queue::Queue(CommandListType type, Device& device) : commandListCounter(device), type(type), device(device) - { - API::Queue::construct(type, &device); - m_fenceValue = 0; - del_func = [this](CommandList* list) - { - if (stop) - delete list; - else - { - std::lock_guard g(list_mutex); - lists.emplace(list, del_func); - } - }; - - del_transition = [this](TransitionCommandList* list) - { - if (stop) - delete list; - else - { - std::lock_guard g(list_mutex); - transition_lists.emplace(list, del_transition); - } - }; - } + // NOTE: the shared HAL::Queue(CommandListType, Device&) constructor is + // defined in the backend-neutral sources/HAL/HAL.Queue.cpp (it just calls + // API::Queue::construct). Do not redefine it here — doing so produces an + // LNK2005 duplicate-symbol error at executable link time. void Queue::update_tile_mappings(const update_tiling_info& infos) { diff --git a/sources/HAL/API/D3D12/HAL.D3D12.Resource.cpp b/sources/HAL/API/D3D12/HAL.D3D12.Resource.cpp index 3783d31d..1ecd6ca0 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.Resource.cpp +++ b/sources/HAL/API/D3D12/HAL.D3D12.Resource.cpp @@ -45,6 +45,14 @@ namespace HAL { GPUAddressPtr Resource::get_address() { return address; } + void* Resource::get_cpu_mapping() + { + void* ptr = nullptr; + if (native_resource) + native_resource->Map(0, nullptr, &ptr); + return ptr; + } + void Resource::init(Device& device, const ResourceDesc& _desc, const PlacementAddress& address, TextureLayout initialLayout) { auto THIS = static_cast(this); @@ -173,12 +181,14 @@ namespace HAL IID_PPV_ARGS(&native_resource))); } auto prev_flags = THIS->desc.Flags; - init(native_resource, initialLayout, device); + init(NativeImportHandle{ native_resource }, initialLayout, device); THIS->desc.Flags |= prev_flags; } - void Resource::init(D3D::Resource resource, TextureLayout layout, Device& device) + void Resource::init(const NativeImportHandle& handle, TextureLayout layout, Device& device) { + native_resource = handle.resource; + auto THIS = static_cast(this); THIS->m_device = static_cast(&device); @@ -247,9 +257,9 @@ namespace HAL init(device, desc, address, TextureLayout::UNDEFINED); } - Resource::Resource(Device& device, const D3D::Resource& resource, TextureLayout initialLayout) :state_manager(this), tiled_manager(this) + Resource::Resource(Device& device, const API::NativeImportHandle& handle, TextureLayout initialLayout) :state_manager(this), tiled_manager(this) { - native_resource = resource; + native_resource = handle.resource; m_device = &device; D3D12_HEAP_PROPERTIES HeapProperties; @@ -258,7 +268,7 @@ namespace HAL heap_type = from_native(HeapProperties.Type); - init(native_resource, initialLayout, device); + init(handle, initialLayout, device); } diff --git a/sources/HAL/API/D3D12/HAL.D3D12.Resource.ixx b/sources/HAL/API/D3D12/HAL.D3D12.Resource.ixx index 93b2b94f..c9f3a7fe 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.Resource.ixx +++ b/sources/HAL/API/D3D12/HAL.D3D12.Resource.ixx @@ -20,16 +20,29 @@ export namespace HAL namespace API { + // NativeImportHandle: wraps an externally-owned D3D12 resource + // (e.g. a swapchain back-buffer). The Vulkan backend provides its own + // version of this struct in HAL.Vulkan.Resource.ixx. + struct NativeImportHandle + { + D3D::Resource resource; + }; + class Resource { GPUAddressPtr address; public: using ptr = std::shared_ptr; void init(Device& device, const ResourceDesc& desc, const PlacementAddress& address, TextureLayout initialLayout = TextureLayout::UNDEFINED); - void init(D3D::Resource resource, TextureLayout layout, Device& device); + + // Replaces the old D3D::Resource constructor; backend-neutral. + void init(const NativeImportHandle& handle, TextureLayout layout, Device& device); GPUAddressPtr get_address(); + // CPU mapping for UPLOAD / READBACK heaps. + void* get_cpu_mapping(); + D3D::Resource native_resource; auto get_dx() const diff --git a/sources/HAL/API/D3D12/HAL.D3D12.ShaderReflection.cpp b/sources/HAL/API/D3D12/HAL.D3D12.ShaderReflection.cpp new file mode 100644 index 00000000..d3ad4518 --- /dev/null +++ b/sources/HAL/API/D3D12/HAL.D3D12.ShaderReflection.cpp @@ -0,0 +1,88 @@ +module HAL:ShaderCompiler; + +import wrl; +import Core; +import d3d12; // ID3D12ShaderReflection / ID3D12LibraryReflection +import DXCompiler; +import :Slots; // get_slot + +// D3D12 implementation of the reflect_shader() seam declared in +// DXC/DXC.ShaderCompiler.cpp. Extracts per-pass constant-buffer slot usage from +// the DXIL reflection blob. This is the only D3D12-coupled part of shader +// compilation, kept here so the DXC compile path itself stays backend-neutral. + +namespace HAL +{ + void reflect_shader(IDxcUtils* library, const DxcBuffer& reflectionBuffer, + const std::string& entry_point, CompiledShader& blob_str) + { + if (entry_point.size()) + { + blob_str.functions.emplace_back(); + auto& f = blob_str.functions.back(); + + ComPtr shaderReflection{}; + library->CreateReflection(&reflectionBuffer, IID_PPV_ARGS(&shaderReflection)); + D3D12_SHADER_DESC shaderDesc{}; + shaderReflection->GetDesc(&shaderDesc); + f.name = entry_point; + f.wname = convert(f.name); + for (uint i = 0; i < shaderDesc.ConstantBuffers; i++) + { + ID3D12ShaderReflectionConstantBuffer* cb = shaderReflection->GetConstantBufferByIndex(i); + D3D12_SHADER_BUFFER_DESC shaderBufferDesc{}; + cb->GetDesc(&shaderBufferDesc); + + std::string cb_name = shaderBufferDesc.Name; + if (cb_name.starts_with("pass_")) + { + cb_name = cb_name.substr(5); + auto slot_id = get_slot(cb_name); + if (slot_id) + f.slots.merge(slot_id.value()); + } + } + } + else + { + ComPtr libraryReflection{}; + auto hr3 = library->CreateReflection(&reflectionBuffer, IID_PPV_ARGS(&libraryReflection)); + + D3D12_LIBRARY_DESC shaderDesc{}; + libraryReflection->GetDesc(&shaderDesc); + + for (uint i = 0; i < shaderDesc.FunctionCount; i++) + { + ID3D12FunctionReflection* f = libraryReflection->GetFunctionByIndex(i); + D3D12_FUNCTION_DESC functionDesc{}; + f->GetDesc(&functionDesc); + + blob_str.functions.emplace_back(); + auto& rf = blob_str.functions.back(); + rf.name = functionDesc.Name; + rf.wname = convert(rf.name); + + for (uint i = 0; i < functionDesc.ConstantBuffers; i++) + { + ID3D12ShaderReflectionConstantBuffer* cb = f->GetConstantBufferByIndex(i); + D3D12_SHADER_BUFFER_DESC shaderBufferDesc{}; + cb->GetDesc(&shaderBufferDesc); + + std::string cb_name = shaderBufferDesc.Name; + if (cb_name.starts_with("pass_")) + { + cb_name = cb_name.substr(5); + auto slot_id = get_slot(cb_name); + rf.slots.merge(slot_id.value()); + } + } + } + } + } + + // D3D12: no extra compile flags (produces DXIL, not SPIR-V). + std::vector get_extra_compile_args(const std::string& /*target*/) + { + return {}; + } +} diff --git a/sources/HAL/API/D3D12/HAL.D3D12.TextureData.cpp b/sources/HAL/API/D3D12/HAL.D3D12.TextureData.cpp index e80597e2..46951e93 100644 --- a/sources/HAL/API/D3D12/HAL.D3D12.TextureData.cpp +++ b/sources/HAL/API/D3D12/HAL.D3D12.TextureData.cpp @@ -7,6 +7,12 @@ import :Device; import Core; import d3d12; +// Non-module bridge: DirectXTex calls that take DXGI_FORMAT can't be made +// directly from module code (DXGI_FORMAT is module-attached via import d3d12). +// These wrappers live in HAL.D3D12.DirectXTexBridge.cpp (a plain .cpp TU) +// where the header-based DXGI_FORMAT matches DirectXTex's ABI. +std::vector hal_r8_to_png(const uint8_t* src, uint32_t width, uint32_t height); + namespace HAL { @@ -224,10 +230,8 @@ namespace HAL CoInitialize(nullptr); - if (img.format != DXGI_FORMAT_R8G8B8A8_UNORM) - { - ASSERT(false); - } + if (format == Format::R8_UNORM) + return hal_r8_to_png(img.pixels, (uint32_t)img.width, (uint32_t)img.height); DirectXTex::Blob blob; if (FAILED(DirectXTex::SaveToWICMemory(*save_img, DirectXTex::WIC_FLAGS_NONE, diff --git a/sources/HAL/API/D3D12/HAL.D3D12.TiledMemoryManager.cpp b/sources/HAL/API/D3D12/HAL.D3D12.TiledMemoryManager.cpp new file mode 100644 index 00000000..3436af59 --- /dev/null +++ b/sources/HAL/API/D3D12/HAL.D3D12.TiledMemoryManager.cpp @@ -0,0 +1,81 @@ +module HAL:TiledMemoryManager; +import Core; +import d3d12; +import HAL; + +// D3D12 implementation of TiledResourceManager::init_tilings(). +// This function is excluded from the common HAL.TiledMemoryManager.cpp and +// lives here so that D3D12-specific tiling API calls stay in the D3D12/ folder. + +namespace HAL +{ + void TiledResourceManager::init_tilings() + { + UINT num_tiles = 1; + D3D12_PACKED_MIP_INFO mip_info; + D3D12_TILE_SHAPE tile_shape; + UINT num_sub_res = 20; + D3D12_SUBRESOURCE_TILING tilings[20]; + + auto desc = resource->get_desc(); + + resource->get_device().get_native_device()->GetResourceTiling( + resource->get_dx(), &num_tiles, &mip_info, &tile_shape, &num_sub_res, 0, tilings); + + packed_mip_count = mip_info.NumTilesForPackedMips; + packed_subresource_offset = mip_info.NumStandardMips; + unpacked_mip_count = mip_info.NumStandardMips; + + if (num_tiles > 0) + { + this->tile_shape = { tile_shape.WidthInTexels, + tile_shape.HeightInTexels, + tile_shape.DepthInTexels }; + + if (desc.is_buffer()) + { + tiles.resize(1); + tiles[0].resize(uint3(tilings[0].WidthInTiles, + tilings[0].HeightInTiles, + tilings[0].DepthInTiles)); + for (uint x = 0; x < tiles[0].size().x; x++) + tiles[0][{x, 0, 0}].pos = { x, 0, 0 }; + + gpu_tiles.resize(1); + gpu_tiles[0].resize(uint3(tilings[0].WidthInTiles, + tilings[0].HeightInTiles, + tilings[0].DepthInTiles)); + for (uint x = 0; x < gpu_tiles[0].size().x; x++) + gpu_tiles[0][{x, 0, 0}].pos = { x, 0, 0 }; + } + else + { + tiles.resize(mip_info.NumStandardMips); + gpu_tiles.resize(mip_info.NumStandardMips); + + packed_tiles.pos = { 0, 0, 0 }; + packed_tiles.subresource = mip_info.NumStandardMips; + + for (UINT i = 0; i < mip_info.NumStandardMips; i++) + { + tiles[i].resize(uint3(tilings[i].WidthInTiles, + tilings[i].HeightInTiles, + tilings[i].DepthInTiles)); + gpu_tiles[i].resize(uint3(tilings[i].WidthInTiles, + tilings[i].HeightInTiles, + tilings[i].DepthInTiles)); + + for (uint x = 0; x < tiles[i].size().x; x++) + for (uint y = 0; y < tiles[i].size().y; y++) + for (uint z = 0; z < tiles[i].size().z; z++) + { + tiles[i][{x, y, z}].pos = { x, y, z }; + tiles[i][{x, y, z}].subresource = i; + gpu_tiles[i][{x, y, z}].pos = { x, y, z }; + gpu_tiles[i][{x, y, z}].subresource = i; + } + } + } + } + } +} diff --git a/sources/HAL/API/D3D12/HAL.Utils.ixx b/sources/HAL/API/D3D12/HAL.Utils.ixx index 49c6be82..2e8772f3 100644 --- a/sources/HAL/API/D3D12/HAL.Utils.ixx +++ b/sources/HAL/API/D3D12/HAL.Utils.ixx @@ -9,6 +9,13 @@ import Core; using namespace HAL; +export namespace HAL +{ + // Backend identifier used to segregate per-backend caches (shaders, PSOs). + // Textures are backend-agnostic and stay in the cache root. + inline std::string get_backend_name() { return "d3d12"; } +} + static_assert(D3D12::SHADER_IDENTIFIER_SIZE_IN_BYTES == 32); export namespace D3D diff --git a/sources/HAL/API/Vulkan/HAL.Impl.cpp b/sources/HAL/API/Vulkan/HAL.Impl.cpp new file mode 100644 index 00000000..d9496926 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Impl.cpp @@ -0,0 +1,149 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:Impl; + +import stl.core; +import Core; +import :Adapter; +import :Debug; + +// ============================================================================ +// Static Vulkan instance — created once in HAL::init(), shared by +// Adapters::enumerate() and API::Device::init(). +// ============================================================================ + +namespace +{ + VkInstance g_instance = VK_NULL_HANDLE; + VkDebugUtilsMessengerEXT g_debug_messenger = VK_NULL_HANDLE; + + VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback( + VkDebugUtilsMessageSeverityFlagBitsEXT severity, + VkDebugUtilsMessageTypeFlagsEXT /*type*/, + const VkDebugUtilsMessengerCallbackDataEXT* data, + void* /*user*/) + { + if (severity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) + Log::get() << Log::LEVEL_WARNING << "[Vulkan] " << data->pMessage << Log::endl; + return VK_FALSE; + } +} + +namespace HAL +{ + VkInstance get_vk_instance() { return g_instance; } + VkDebugUtilsMessengerEXT get_vk_debug_messenger() { return g_debug_messenger; } + + void EnableGPUDebug() + { + // Validation is configured during instance creation in init(). + } + + void EnableShaderModel() + { + // No-op: SPIR-V shaders have no "shader model" negotiation. + } + + void init() + { + // ---- Application / instance info ------------------------------------ + VkApplicationInfo app_info{ VK_STRUCTURE_TYPE_APPLICATION_INFO }; + app_info.pApplicationName = "Spectrum"; + app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + app_info.pEngineName = "Spectrum"; + app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0); + app_info.apiVersion = VK_API_VERSION_1_3; + + // ---- Extensions ----------------------------------------------------- + std::vector extensions = { + VK_KHR_SURFACE_EXTENSION_NAME, + VK_KHR_WIN32_SURFACE_EXTENSION_NAME, + }; + + // ---- Probe available instance layers -------------------------------- + uint32_t layer_count = 0; + vkEnumerateInstanceLayerProperties(&layer_count, nullptr); + std::vector avail_layers(layer_count); + vkEnumerateInstanceLayerProperties(&layer_count, avail_layers.data()); + + auto layer_available = [&](const char* name) { + for (auto& l : avail_layers) + if (strcmp(l.layerName, name) == 0) return true; + return false; + }; + + // ---- Probe available instance extensions ---------------------------- + uint32_t inst_ext_count = 0; + vkEnumerateInstanceExtensionProperties(nullptr, &inst_ext_count, nullptr); + std::vector avail_inst_exts(inst_ext_count); + vkEnumerateInstanceExtensionProperties(nullptr, &inst_ext_count, avail_inst_exts.data()); + + auto inst_ext_available = [&](const char* name) { + for (auto& e : avail_inst_exts) + if (strcmp(e.extensionName, name) == 0) return true; + return false; + }; + + // ---- Layers + debug messenger --------------------------------------- + std::vector layers; + VkDebugUtilsMessengerCreateInfoEXT debug_info{ + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT }; + bool use_debug_utils = false; + + if constexpr (Debug::CheckErrors) + { + if (layer_available("VK_LAYER_KHRONOS_validation")) + layers.push_back("VK_LAYER_KHRONOS_validation"); + else + Log::get() << Log::LEVEL_WARNING + << "[Vulkan] VK_LAYER_KHRONOS_validation not found — " + "install the Vulkan SDK for validation support" << Log::endl; + + if (inst_ext_available(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) + { + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + use_debug_utils = true; + + debug_info.messageSeverity = + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + debug_info.messageType = + VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + debug_info.pfnUserCallback = debug_callback; + } + } + + // ---- Create instance ------------------------------------------------ + VkInstanceCreateInfo create_info{ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; + create_info.pApplicationInfo = &app_info; + create_info.enabledExtensionCount = static_cast(extensions.size()); + create_info.ppEnabledExtensionNames = extensions.data(); + create_info.enabledLayerCount = static_cast(layers.size()); + create_info.ppEnabledLayerNames = layers.data(); + if (use_debug_utils) + create_info.pNext = &debug_info; + + VkResult result = vkCreateInstance(&create_info, nullptr, &g_instance); + if (result != VK_SUCCESS) + { + Log::get().crash_error( + std::string("vkCreateInstance failed, VkResult=") + std::to_string(static_cast(result))); + return; + } + + // ---- Debug messenger ------------------------------------------------ + if (use_debug_utils) + { + auto fn = reinterpret_cast( + vkGetInstanceProcAddr(g_instance, "vkCreateDebugUtilsMessengerEXT")); + if (fn) + fn(g_instance, &debug_info, nullptr, &g_debug_messenger); + } + + // ---- Adapters singleton (uses g_instance for enumeration) ----------- + HAL::Adapters::create(); + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Impl.ixx b/sources/HAL/API/Vulkan/HAL.Impl.ixx new file mode 100644 index 00000000..fb29cb9b --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Impl.ixx @@ -0,0 +1,16 @@ +export module HAL:Impl; +import vulkan; +import :Debug; + +export namespace HAL +{ + void EnableGPUDebug(); // enables Vulkan validation layers + void EnableShaderModel(); // no-op in Vulkan (shader model is SPIR-V) + void init(); + + // The VkInstance is created once in HAL::init() and lives for the duration + // of the program. Both Adapters (for enumeration) and Device (for logical + // device creation) obtain it here rather than creating their own instances. + VkInstance get_vk_instance(); + VkDebugUtilsMessengerEXT get_vk_debug_messenger(); +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Adapter.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Adapter.cpp new file mode 100644 index 00000000..df1b4b88 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Adapter.cpp @@ -0,0 +1,37 @@ +module HAL:Adapter; +import stl.core; +import vulkan; +import Core; + +namespace HAL +{ + Adapter::Adapter(VkPhysicalDevice physical) : vk_physical(physical) + { + // Fill the DXGI_ADAPTER_DESC stub from VkPhysicalDeviceProperties + // so HAL::Device::create_singleton() can log the adapter name and do + // "Basic" string detection. + VkPhysicalDeviceProperties props{}; + vkGetPhysicalDeviceProperties(physical, &props); + + // Convert UTF-8 deviceName to wchar Description + const char* name = props.deviceName; + for (int i = 0; i < 127 && name[i]; ++i) + adapter_desc.Description[i] = static_cast(name[i]); + + VkPhysicalDeviceMemoryProperties mem_props{}; + vkGetPhysicalDeviceMemoryProperties(physical, &mem_props); + for (uint32_t i = 0; i < mem_props.memoryHeapCount; ++i) + { + if (mem_props.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + adapter_desc.DedicatedVideoMemory += mem_props.memoryHeaps[i].size; + } + + adapter_desc.VendorId = props.vendorID; + adapter_desc.DeviceId = props.deviceID; + } + + const DXGI_ADAPTER_DESC& Adapter::get_desc() const + { + return adapter_desc; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Adapter.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Adapter.ixx new file mode 100644 index 00000000..434d09c8 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Adapter.ixx @@ -0,0 +1,51 @@ +export module HAL:Adapter; +import :Utils; // pulls in DXGI_ADAPTER_DESC stub +import :Impl; // get_vk_instance() + +import vulkan; +import Core; + +export namespace HAL +{ + struct AdapterDesc {}; // empty common struct kept for compat + + class Adapter + { + friend class Adapters; + + protected: + VkPhysicalDevice vk_physical = VK_NULL_HANDLE; + DXGI_ADAPTER_DESC adapter_desc = {}; + + public: + using ptr = std::shared_ptr; + + explicit Adapter(VkPhysicalDevice physical); + const DXGI_ADAPTER_DESC& get_desc() const; + + // Public accessor — used by API::Device::init (cannot friend across + // the circular Adapter ↔ API.Device import dependency). + VkPhysicalDevice get_vk_physical() const { return vk_physical; } + }; + + class Adapters : public Singleton + { + friend class Singleton; + Adapters() = default; + public: + void enumerate(auto f) + { + // Instance was created in HAL::init() before this is called. + VkInstance instance = HAL::get_vk_instance(); + if (instance == VK_NULL_HANDLE) return; + + uint32_t count = 0; + vkEnumeratePhysicalDevices(instance, &count, nullptr); + std::vector devices(count); + vkEnumeratePhysicalDevices(instance, &count, devices.data()); + + for (auto pd : devices) + f(std::make_shared(pd)); + } + }; +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.CommandAllocator.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandAllocator.cpp new file mode 100644 index 00000000..2f9a3210 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandAllocator.cpp @@ -0,0 +1,45 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:API.CommandAllocator; + +import Core; +import HAL; + +namespace HAL +{ + CommandAllocator::CommandAllocator(Device& device, const CommandListType type) + : device(device), type(type) + { + auto& api_dev = static_cast(device); + if (api_dev.vk_device == VK_NULL_HANDLE) return; + + uint32_t family = api_dev.queue_families[static_cast(type)]; + if (family == static_cast(-1)) return; + + VkCommandPoolCreateInfo info{ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + // RESET_COMMAND_BUFFER_BIT lets individual buffers be reset without + // resetting the whole pool — needed since DelayedCommandList recycles + // command lists individually. + info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + info.queueFamilyIndex = family; + + vkCreateCommandPool(api_dev.vk_device, &info, nullptr, &vk_command_pool); + } + + CommandAllocator::~CommandAllocator() + { + if (vk_command_pool == VK_NULL_HANDLE) return; + auto& api_dev = static_cast(device); + if (api_dev.vk_device == VK_NULL_HANDLE) return; + vkDestroyCommandPool(api_dev.vk_device, vk_command_pool, nullptr); + vk_command_pool = VK_NULL_HANDLE; + } + + void CommandAllocator::reset() + { + if (vk_command_pool == VK_NULL_HANDLE) return; + auto& api_dev = static_cast(device); + vkResetCommandPool(api_dev.vk_device, vk_command_pool, 0); + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.CommandAllocator.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandAllocator.ixx new file mode 100644 index 00000000..66cbe242 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandAllocator.ixx @@ -0,0 +1,26 @@ +export module HAL:API.CommandAllocator; +import Core; +import vulkan; +import :Types; +import :Utils; + +export namespace HAL +{ + namespace API + { + class CommandAllocator + { + // CommandList allocates VkCommandBuffer from this pool. + friend class CommandList; + + protected: + VkCommandPool vk_command_pool = VK_NULL_HANDLE; + // VkCommandPool is not thread-safe: all vkCmd* calls and pool operations + // (allocate / reset) on any buffer from this pool must be serialized. + mutable std::mutex pool_mutex; + + public: + virtual ~CommandAllocator() = default; + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.CommandList.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandList.cpp new file mode 100644 index 00000000..154ea88a --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandList.cpp @@ -0,0 +1,923 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:API.CommandList; + +import stl.core; +import Core; +import :CommandAllocator; // full definition needed: allocator.vk_command_pool +import :RootSignature; // API::RootSignature::get_vk_pipeline_layout() +import :API.Device; // API::Device::get_native_device() +import :API.DescriptorHeap; // API::DescriptorHeap::get_vk_set() +import :API.QueryHeap; // API::QueryHeap::get_native() + +namespace HAL::API +{ + void CommandList::create(CommandListType t, Device& dev) + { + type = t; + m_device = &dev; + // VkCommandBuffer is allocated lazily in begin() from the allocator's pool. + } + + void CommandList::begin(HAL::CommandAllocator& allocator) + { + auto& api_dev = static_cast(*m_device); + auto& api_alloc = static_cast(allocator); + + // Lock the pool mutex for the entire recording session (held until end()). + _pool_mutex = &api_alloc.pool_mutex; + _pool_mutex->lock(); + + if (vk_cmd != VK_NULL_HANDLE && vk_cmd_pool == api_alloc.vk_command_pool) + { + // Same pool as before — we hold its mutex so reset is safe. + vkResetCommandBuffer(vk_cmd, 0); + } + else + { + // First use, or the compile() rotation gave us a different allocator. + // Allocate a fresh buffer from this pool. The old vk_cmd (if any) + // remains allocated from its original pool and will be freed when + // CommandAllocator::reset() is called on that pool — no explicit free + // needed here because VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT + // lets the pool reclaim its buffers on pool reset. + VkCommandBufferAllocateInfo alloc{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + alloc.commandPool = api_alloc.vk_command_pool; + alloc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + alloc.commandBufferCount = 1; + vkAllocateCommandBuffers(api_dev.get_native_device(), &alloc, &vk_cmd); + vk_cmd_pool = api_alloc.vk_command_pool; + } + + VkCommandBufferBeginInfo info{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer(vk_cmd, &info); + + // Fresh recording: clear any deferred PRESENT barriers from the previous frame. + deferred_present_barriers.clear(); + } + + void CommandList::end() + { + if (vk_cmd != VK_NULL_HANDLE) + { + end_rendering_if_active(); + + // Flush any deferred PRESENT_SRC_KHR barriers now — after all draws and + // after the render pass is closed. See the comment in the ixx for why + // these are deferred rather than emitted at the FrameGraph's normal + // non_tracked_resources transition point. + if (!deferred_present_barriers.empty()) + { + VkDependencyInfo dep{ VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + dep.imageMemoryBarrierCount = static_cast(deferred_present_barriers.size()); + dep.pImageMemoryBarriers = deferred_present_barriers.data(); + vkCmdPipelineBarrier2(vk_cmd, &dep); + deferred_present_barriers.clear(); + } + + vkEndCommandBuffer(vk_cmd); + } + // Release the pool mutex — recording is complete. + if (_pool_mutex) { _pool_mutex->unlock(); _pool_mutex = nullptr; } + } + + // ---- Dynamic rendering helpers ------------------------------------------ + + void CommandList::end_rendering_if_active() + { + if (in_render_pass) + { + vkCmdEndRendering(vk_cmd); + in_render_pass = false; + } + } + + void CommandList::begin_rendering(VkAttachmentLoadOp color_load, + VkClearValue color_clear, + VkAttachmentLoadOp depth_load, + VkClearValue depth_clear) + { + end_rendering_if_active(); + if (current_color_view == VK_NULL_HANDLE && current_depth_view == VK_NULL_HANDLE) + return; + + VkRenderingAttachmentInfo color_att{ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; + color_att.imageView = current_color_view; + color_att.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + color_att.loadOp = color_load; + color_att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + color_att.clearValue = color_clear; + + VkRenderingAttachmentInfo depth_att{ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; + depth_att.imageView = current_depth_view; + depth_att.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depth_att.loadOp = depth_load; + depth_att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + depth_att.clearValue = depth_clear; + + VkRenderingInfo ri{ VK_STRUCTURE_TYPE_RENDERING_INFO }; + ri.renderArea = { {0, 0}, current_extent }; + ri.layerCount = 1; + ri.colorAttachmentCount = current_color_view != VK_NULL_HANDLE ? 1 : 0; + ri.pColorAttachments = current_color_view != VK_NULL_HANDLE ? &color_att : nullptr; + ri.pDepthAttachment = current_depth_view != VK_NULL_HANDLE ? &depth_att : nullptr; + + vkCmdBeginRendering(vk_cmd, &ri); + in_render_pass = true; + } + + // ---- Barriers (synchronization2) ---------------------------------------- + + void CommandList::transitions(const HAL::Barriers& barriers) + { + if (vk_cmd == VK_NULL_HANDLE) return; + // Image/buffer barriers are illegal inside a dynamic rendering instance. + // End the current render pass so the barrier lands outside it. + end_rendering_if_active(); + + std::vector image_barriers; + std::vector buffer_barriers; + + for (auto& b : barriers.get_barriers()) + { + const auto* res = b.resource; + if (!res) continue; + + if (res->get_type() == ResourceType::Texture) + { + auto& api_res = static_cast(*res); + if (api_res.get_vk_image() == VK_NULL_HANDLE) continue; + + VkImageMemoryBarrier2 ib{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + ib.srcStageMask = to_native_stage(b.before.operation); + ib.srcAccessMask = to_native_access(b.before.access); + ib.dstStageMask = to_native_stage(b.after.operation); + ib.dstAccessMask = to_native_access(b.after.access); + ib.oldLayout = to_native(b.before.layout); + ib.newLayout = to_native(b.after.layout); + // D3D12 allows transitioning TO "undefined" (discard). + // Vulkan forbids VK_IMAGE_LAYOUT_UNDEFINED as newLayout — skip it. + if (ib.newLayout == VK_IMAGE_LAYOUT_UNDEFINED) continue; + ib.image = api_res.get_vk_image(); + bool is_depth = check(res->get_desc().Flags & ResFlags::DepthStencil); + ib.subresourceRange = { + static_cast( + is_depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), + 0, VK_REMAINING_MIP_LEVELS, + 0, VK_REMAINING_ARRAY_LAYERS + }; + + // Defer PRESENT_SRC_KHR transitions to end() so they always fire + // after ALL draw calls. The FrameGraph non_tracked_resources loop + // places this barrier right after set_rtv() (before draws), which + // would leave the swapchain in PRESENT_SRC_KHR when the draws run. + // D3D12 is immune (PRESENT==COMMON; implicit promotion back to RT). + // Vulkan is not → black output without this deferral. + if (ib.newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) + deferred_present_barriers.push_back(ib); + else + image_barriers.push_back(ib); + } + else + { + auto& api_res = static_cast(*res); + if (api_res.get_vk_buffer() == VK_NULL_HANDLE) continue; + + VkBufferMemoryBarrier2 bb{ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 }; + bb.srcStageMask = to_native_stage(b.before.operation); + bb.srcAccessMask = to_native_access(b.before.access); + bb.dstStageMask = to_native_stage(b.after.operation); + bb.dstAccessMask = to_native_access(b.after.access); + bb.buffer = api_res.get_vk_buffer(); + bb.offset = 0; + bb.size = VK_WHOLE_SIZE; + buffer_barriers.push_back(bb); + } + } + + if (image_barriers.empty() && buffer_barriers.empty()) return; + + VkDependencyInfo dep{ VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + dep.imageMemoryBarrierCount = static_cast(image_barriers.size()); + dep.pImageMemoryBarriers = image_barriers.data(); + dep.bufferMemoryBarrierCount = static_cast(buffer_barriers.size()); + dep.pBufferMemoryBarriers = buffer_barriers.data(); + vkCmdPipelineBarrier2(vk_cmd, &dep); + } + + // ---- Render target management ------------------------------------------- + + void CommandList::set_rtv(int /*count*/, RTVHandle rt, DSVHandle dsv) + { + if (vk_cmd == VK_NULL_HANDLE) return; + end_rendering_if_active(); + + current_color_view = VK_NULL_HANDLE; + current_depth_view = VK_NULL_HANDLE; + current_extent = {}; + + auto extract_view = [](const Handle& h, bool depth) -> std::pair + { + if (!h.is_valid()) return { VK_NULL_HANDLE, {} }; + auto& ri = h.get_resource_info(); + + std::shared_ptr res; + if (!depth) + { + auto* rtv = std::get_if(&ri.view); + if (rtv) res = rtv->Resource; + } + else + { + auto* dsv = std::get_if(&ri.view); + if (dsv) res = dsv->Resource; + } + + if (!res) return { VK_NULL_HANDLE, {} }; + auto& api = static_cast(*res); + + // get_vk_image_view() returns the swapchain view if present, + // otherwise the owned VkImageView created by Resource::init(). + return { api.get_vk_image_view(), api.get_imported_extent() }; + }; + + auto [cv, ce] = extract_view(rt, false); + auto [dv, de] = extract_view(dsv, true); + + current_color_view = cv; + current_depth_view = dv; + current_extent = (cv != VK_NULL_HANDLE) ? ce : de; + } + + // ---- Clear operations --------------------------------------------------- + + void CommandList::clear_rtv(const RTVHandle& h, vec4 color) + { + if (vk_cmd == VK_NULL_HANDLE || !h.is_valid()) return; + + auto& ri = h.get_resource_info(); + auto* rtv = std::get_if(&ri.view); + if (!rtv || !rtv->Resource) return; + + auto& api = static_cast(*rtv->Resource); + VkImageView view = api.get_vk_image_view(); + if (view == VK_NULL_HANDLE) return; + + end_rendering_if_active(); + + // Transition to COLOR_ATTACHMENT_OPTIMAL before the clear. UNDEFINED as + // oldLayout is always valid; it matches LOAD_OP_CLEAR's "discard" semantics. + { + VkImageMemoryBarrier2 b{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + b.srcStageMask = VK_PIPELINE_STAGE_2_NONE; + b.srcAccessMask = 0; + b.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + b.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + b.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + b.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + b.image = api.get_vk_image(); + b.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; + VkDependencyInfo dep{ VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + dep.imageMemoryBarrierCount = 1; + dep.pImageMemoryBarriers = &b; + vkCmdPipelineBarrier2(vk_cmd, &dep); + } + + VkClearValue cv{}; + cv.color.float32[0] = color.x; + cv.color.float32[1] = color.y; + cv.color.float32[2] = color.z; + cv.color.float32[3] = color.w; + + VkRenderingAttachmentInfo att{ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; + att.imageView = view; + att.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + att.clearValue = cv; + + VkExtent2D ext = api.get_imported_extent(); + // Fallback: if no imported extent (regular texture), use desc dimensions + if (ext.width == 0 && rtv->Resource->get_desc().is_texture()) + { + auto& td = rtv->Resource->get_desc().as_texture(); + ext = { td.Dimensions.x, td.Dimensions.y }; + } + + VkRenderingInfo rinfo{ VK_STRUCTURE_TYPE_RENDERING_INFO }; + rinfo.renderArea = { {0, 0}, ext }; + rinfo.layerCount = 1; + rinfo.colorAttachmentCount = 1; + rinfo.pColorAttachments = &att; + + vkCmdBeginRendering(vk_cmd, &rinfo); + vkCmdEndRendering(vk_cmd); + } + + void CommandList::clear_depth(const DSVHandle& dsv, float depth) + { + if (vk_cmd == VK_NULL_HANDLE || !dsv.is_valid()) return; + + auto& ri = dsv.get_resource_info(); + auto* dv = std::get_if(&ri.view); + if (!dv || !dv->Resource) return; + + auto& api = static_cast(*dv->Resource); + VkImageView view = api.get_vk_image_view(); + if (view == VK_NULL_HANDLE) return; + + end_rendering_if_active(); + + // Transition to DEPTH_STENCIL_ATTACHMENT_OPTIMAL before the clear. + { + VkImageMemoryBarrier2 b{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + b.srcStageMask = VK_PIPELINE_STAGE_2_NONE; + b.srcAccessMask = 0; + b.dstStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT; + b.dstAccessMask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + b.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + b.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + b.image = api.get_vk_image(); + b.subresourceRange = { VK_IMAGE_ASPECT_DEPTH_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; + VkDependencyInfo dep{ VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + dep.imageMemoryBarrierCount = 1; + dep.pImageMemoryBarriers = &b; + vkCmdPipelineBarrier2(vk_cmd, &dep); + } + + VkClearValue cv; + cv.depthStencil = { depth, 0 }; + + VkRenderingAttachmentInfo att{ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; + att.imageView = view; + att.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + att.clearValue = cv; + + VkExtent2D ext = api.get_imported_extent(); + if (ext.width == 0 && dv->Resource->get_desc().is_texture()) + { + auto& td = dv->Resource->get_desc().as_texture(); + ext = { td.Dimensions.x, td.Dimensions.y }; + } + + VkRenderingInfo rinfo{ VK_STRUCTURE_TYPE_RENDERING_INFO }; + rinfo.renderArea = { {0, 0}, ext }; + rinfo.layerCount = 1; + rinfo.pDepthAttachment = &att; + + vkCmdBeginRendering(vk_cmd, &rinfo); + vkCmdEndRendering(vk_cmd); + } + + void CommandList::clear_depth_stencil(const DSVHandle& dsv, bool d, bool s, float fd, UINT8 fs) + { + if (d) clear_depth(dsv, fd); + } + void CommandList::clear_stencil(const DSVHandle&, UINT8) { ASSERT(0); } + void CommandList::clear_uav(const UAVHandle& h, vec4 color) + { + if (vk_cmd == VK_NULL_HANDLE || !h.is_valid()) return; + + auto& ri = h.get_resource_info(); + auto* uav = std::get_if(&ri.view); + if (!uav || !uav->Resource) return; + + auto& api = static_cast(*uav->Resource); + VkImage img = api.get_vk_image(); + if (img == VK_NULL_HANDLE) return; + + end_rendering_if_active(); + + VkClearColorValue cv{}; + cv.float32[0] = color.x; + cv.float32[1] = color.y; + cv.float32[2] = color.z; + cv.float32[3] = color.w; + + // UAV/storage images live in GENERAL layout (the HAL transitions to + // UNORDERED_ACCESS before this call). + VkImageSubresourceRange range{ VK_IMAGE_ASPECT_COLOR_BIT, + 0, VK_REMAINING_MIP_LEVELS, + 0, VK_REMAINING_ARRAY_LAYERS }; + vkCmdClearColorImage(vk_cmd, img, VK_IMAGE_LAYOUT_GENERAL, &cv, 1, &range); + } + + // ---- Lazy render-pass start (for draw calls) ---------------------------- + + void CommandList::ensure_rendering_active() + { + if (in_render_pass) return; + if (current_color_view == VK_NULL_HANDLE && current_depth_view == VK_NULL_HANDLE) + return; + VkClearValue noop{}; + begin_rendering(VK_ATTACHMENT_LOAD_OP_LOAD, noop, VK_ATTACHMENT_LOAD_OP_LOAD, noop); + } + + // Re-bind pipeline + viewport/scissor immediately before a draw. The task-based + // recorder can place set_pipeline / set_viewports / set_scissors in a different + // command buffer than the draw, and Vulkan dynamic state + pipeline bindings do not + // carry across command buffers. Re-applying here guarantees the draw has them. + void CommandList::reapply_draw_state() + { + if (current_graphics_pipeline != VK_NULL_HANDLE) + vkCmdBindPipeline(vk_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, current_graphics_pipeline); + + if (!current_viewports.empty()) + vkCmdSetViewport(vk_cmd, 0, static_cast(current_viewports.size()), + current_viewports.data()); + else if (current_extent.width && current_extent.height) + { + // Fallback: full-target viewport (negative height = D3D12 Y orientation). + VkViewport vp{ 0.0f, (float)current_extent.height, + (float)current_extent.width, -(float)current_extent.height, 0.0f, 1.0f }; + vkCmdSetViewport(vk_cmd, 0, 1, &vp); + } + + if (has_scissor) + vkCmdSetScissor(vk_cmd, 0, 1, ¤t_scissor); + else if (current_extent.width && current_extent.height) + { + VkRect2D sc{ {0,0}, current_extent }; + vkCmdSetScissor(vk_cmd, 0, 1, &sc); + } + + // Re-set topology — dynamic topology state doesn't survive a CB split. + vkCmdSetPrimitiveTopology(vk_cmd, current_topology); + + // Re-push the staged push-constant block (carries the bindless descriptor + // indices the shader reads as _hal_push.sN). 128 bytes = the range declared + // by the root signature's VkPushConstantRange. + if (current_pipeline_layout != VK_NULL_HANDLE) + vkCmdPushConstants(vk_cmd, current_pipeline_layout, VK_SHADER_STAGE_ALL, + 0, 128, push_constants.data()); + } + + void CommandList::flush_descriptor_sets() + { + if (!descriptor_sets_dirty || current_pipeline_layout == VK_NULL_HANDLE) return; + descriptor_sets_dirty = false; + + VkDescriptorSet sets[2] = { cbv_srv_uav_set, sampler_set }; + uint32_t set_count = 0; + if (sets[0] != VK_NULL_HANDLE) set_count = 1; + if (sets[1] != VK_NULL_HANDLE) set_count = 2; + if (set_count == 0) return; + + // Bind for both graphics and compute so set is available regardless of pipeline type. + vkCmdBindDescriptorSets(vk_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + current_pipeline_layout, 0, set_count, sets, 0, nullptr); + } + + // ---- Pipeline binding --------------------------------------------------- + + void CommandList::set_pipeline(std::shared_ptr pipeline) + { + if (!pipeline || vk_cmd == VK_NULL_HANDLE) return; + if (pipeline->vk_pipeline == VK_NULL_HANDLE) return; + + VkPipelineBindPoint bind_point = pipeline->is_compute + ? VK_PIPELINE_BIND_POINT_COMPUTE + : VK_PIPELINE_BIND_POINT_GRAPHICS; + + if (!pipeline->is_compute) + { + current_graphics_pipeline = pipeline->vk_pipeline; + // Keep dynamic topology in sync with the PSO's declared topology so + // the spec requirement (same class) is always satisfied without + // requiring explicit set_topology calls at every draw site. + // current_topology = pipeline->vk_topology; + } + + vkCmdBindPipeline(vk_cmd, bind_point, pipeline->vk_pipeline); + flush_descriptor_sets(); + } + + void CommandList::set_graphics_signature(const HAL::RootSignature::ptr& sig) + { + if (!sig) return; + current_pipeline_layout = static_cast(*sig).get_vk_pipeline_layout(); + descriptor_sets_dirty = true; + } + + void CommandList::set_compute_signature(const HAL::RootSignature::ptr& sig) + { + if (!sig) return; + current_pipeline_layout = static_cast(*sig).get_vk_pipeline_layout(); + descriptor_sets_dirty = true; + } + + // ---- Descriptor heap binding ------------------------------------------- + + void CommandList::set_descriptor_heaps(DescriptorHeap* cbv, DescriptorHeap* sampler) + { + auto* api_cbv = static_cast(cbv); + auto* api_sampler = static_cast(sampler); + + cbv_srv_uav_set = api_cbv ? api_cbv->get_vk_set() : VK_NULL_HANDLE; + sampler_set = api_sampler ? api_sampler->get_vk_set() : VK_NULL_HANDLE; + descriptor_sets_dirty = true; + } + + // ---- Draw / dispatch --------------------------------------------------- + + void CommandList::draw(UINT vertex_count, UINT vertex_offset, + UINT instance_count, UINT instance_offset) + { + if (vk_cmd == VK_NULL_HANDLE) return; + ensure_rendering_active(); + if (!in_render_pass) return; // no RTV set — skip rather than crash validation + reapply_draw_state(); + flush_descriptor_sets(); + vkCmdDraw(vk_cmd, vertex_count, instance_count, vertex_offset, instance_offset); + } + + void CommandList::draw_indexed(UINT index_count, UINT index_offset, UINT vertex_offset, + UINT instance_count, UINT instance_offset) + { + if (vk_cmd == VK_NULL_HANDLE) return; + ensure_rendering_active(); + if (!in_render_pass) return; + reapply_draw_state(); + if (current_index_buffer != VK_NULL_HANDLE) + vkCmdBindIndexBuffer(vk_cmd, current_index_buffer, current_index_offset, current_index_type); + flush_descriptor_sets(); + vkCmdDrawIndexed(vk_cmd, index_count, instance_count, + index_offset, static_cast(vertex_offset), instance_offset); + } + + void CommandList::dispatch(ivec3 v) + { + if (vk_cmd == VK_NULL_HANDLE) return; + // Compute doesn't use a render pass — end any active one first. + end_rendering_if_active(); + if (current_pipeline_layout != VK_NULL_HANDLE && + (cbv_srv_uav_set != VK_NULL_HANDLE || sampler_set != VK_NULL_HANDLE)) + { + VkDescriptorSet sets[2] = { cbv_srv_uav_set, sampler_set }; + uint32_t count = (sampler_set != VK_NULL_HANDLE) ? 2 : 1; + vkCmdBindDescriptorSets(vk_cmd, VK_PIPELINE_BIND_POINT_COMPUTE, + current_pipeline_layout, 0, count, sets, 0, nullptr); + } + vkCmdDispatch(vk_cmd, static_cast(v.x), + static_cast(v.y), + static_cast(v.z)); + } + + void CommandList::dispatch_mesh(ivec3 /*v*/) + { + // VK_EXT_mesh_shader not yet requested — Phase 5. + ASSERT(0); + } + + // ---- Index buffer ------------------------------------------------------ + + void CommandList::set_index_buffer(HAL::Views::IndexBuffer index) + { + if (vk_cmd == VK_NULL_HANDLE || !index.Resource) return; + auto& api_res = static_cast(*index.Resource); + if (api_res.get_vk_buffer() == VK_NULL_HANDLE) return; + + VkIndexType idx_type = (index.Format == HAL::Format::R32_UINT) + ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16; + + current_index_buffer = api_res.get_vk_buffer(); + current_index_offset = index.OffsetInBytes; + current_index_type = idx_type; + vkCmdBindIndexBuffer(vk_cmd, api_res.get_vk_buffer(), + index.OffsetInBytes, idx_type); + } + + // ---- Viewport / scissor ------------------------------------------------ + + void CommandList::set_viewports(std::vector viewports) + { + if (vk_cmd == VK_NULL_HANDLE || viewports.empty()) return; + + std::vector vk_vps; + vk_vps.reserve(viewports.size()); + for (auto& vp : viewports) + { + // Vulkan Y-flip: use negative height trick to match D3D12 NDC + VkViewport v{}; + v.x = vp.pos.x; + v.y = vp.pos.y + vp.size.y; // start at bottom + v.width = vp.size.x; + v.height = -vp.size.y; // negative flips Y + v.minDepth = vp.depths.x; + v.maxDepth = vp.depths.y; + vk_vps.push_back(v); + } + current_viewports = vk_vps; // remember for per-draw re-apply (CB-split safe) + vkCmdSetViewport(vk_cmd, 0, static_cast(vk_vps.size()), vk_vps.data()); + } + + void CommandList::set_scissors(sizer_long rect) + { + if (vk_cmd == VK_NULL_HANDLE) return; + VkRect2D scissor{}; + scissor.offset = { static_cast(rect.left), + static_cast(rect.top) }; + scissor.extent = { static_cast(rect.right - rect.left), + static_cast(rect.bottom - rect.top) }; + current_scissor = scissor; // remember for per-draw re-apply (CB-split safe) + has_scissor = true; + vkCmdSetScissor(vk_cmd, 0, 1, &scissor); + } + + void CommandList::set_stencil_ref(UINT ref) + { + if (vk_cmd != VK_NULL_HANDLE) + vkCmdSetStencilReference(vk_cmd, VK_STENCIL_FACE_FRONT_AND_BACK, ref); + } + + // ---- Push constants --------------------------------------------------- + + void CommandList::graphics_set_constant(UINT slot, UINT offset, UINT value) + { + if (vk_cmd == VK_NULL_HANDLE || current_pipeline_layout == VK_NULL_HANDLE) return; + uint32_t byte_offset = (slot + offset) * sizeof(uint32_t); + // Stage so reapply_draw_state() can re-push before each draw — vkCmdPushConstants + // does not survive a command-buffer split; without re-pushing, the shader reads 0 + // for every bindless descriptor index (s4, …) → all bindless reads fail → black UI. + if ((slot + offset) < push_constants.size()) + push_constants[slot + offset] = value; + vkCmdPushConstants(vk_cmd, current_pipeline_layout, + VK_SHADER_STAGE_ALL, // must cover all stages in pipeline layout range + byte_offset, sizeof(uint32_t), &value); + } + + void CommandList::compute_set_constant(UINT slot, UINT offset, UINT value) + { + if (vk_cmd == VK_NULL_HANDLE || current_pipeline_layout == VK_NULL_HANDLE) return; + uint32_t byte_offset = (slot + offset) * sizeof(uint32_t); + vkCmdPushConstants(vk_cmd, current_pipeline_layout, + VK_SHADER_STAGE_ALL, // must cover all stages in pipeline layout range + byte_offset, sizeof(uint32_t), &value); + } + + // Phase 5: push descriptors for inline CBV binding + void CommandList::graphics_set_const_buffer(UINT, const ResourceAddress&) { ASSERT(0); } + void CommandList::compute_set_const_buffer(UINT, const ResourceAddress&) { ASSERT(0); } + + // ---- Copy operations --------------------------------------------------- + + void CommandList::copy_resource(HAL::Resource* dest, HAL::Resource* source) + { + if (!dest || !source || vk_cmd == VK_NULL_HANDLE) return; + auto& dst_api = static_cast(*dest); + auto& src_api = static_cast(*source); + + if (dst_api.get_vk_buffer() != VK_NULL_HANDLE && + src_api.get_vk_buffer() != VK_NULL_HANDLE) + { + VkBufferCopy region{}; + region.size = dest->get_desc().as_buffer().SizeInBytes; + vkCmdCopyBuffer(vk_cmd, src_api.get_vk_buffer(), + dst_api.get_vk_buffer(), 1, ®ion); + } + } + + void CommandList::copy_buffer(HAL::Resource* dest, uint64 dest_offset, + HAL::Resource* source, uint64 src_offset, uint64 size) + { + if (!dest || !source || vk_cmd == VK_NULL_HANDLE) return; + auto& dst_api = static_cast(*dest); + auto& src_api = static_cast(*source); + if (dst_api.get_vk_buffer() == VK_NULL_HANDLE || + src_api.get_vk_buffer() == VK_NULL_HANDLE) return; + + VkBufferCopy region{}; + region.srcOffset = src_offset; + region.dstOffset = dest_offset; + region.size = size; + vkCmdCopyBuffer(vk_cmd, src_api.get_vk_buffer(), + dst_api.get_vk_buffer(), 1, ®ion); + } + + // Build a VkBufferImageCopy from the HAL texture_layout. The staging buffer + // rows are 256-byte aligned (see Device::get_texture_layout), so bufferRowLength + // must be expressed in texels = row_stride / bytes-per-texel (NOT 0, which would + // assume tight packing and shear the image for non-aligned widths). + static VkBufferImageCopy make_buffer_image_copy(const HAL::Resource& resource, + ivec3 offset, ivec3 box, UINT sub_resource, + const ResourceAddress& address, + const texture_layout& layout) + { + if (box.y == 0) box.y = 1; + if (box.z == 0) box.z = 1; + + auto sinfo = layout.format.surface_info({ (uint)box.x, (uint)box.y }); + uint bpt = box.x ? (uint)(sinfo.rowBytes / box.x) : 4u; // bytes per texel + if (bpt == 0) bpt = 4u; + + auto& tdesc = resource.get_desc().as_texture(); + uint mips = tdesc.MipLevels ? tdesc.MipLevels : 1u; + + VkBufferImageCopy region{}; + region.bufferOffset = address.resource_offset; + region.bufferRowLength = (layout.row_stride / bpt); + region.bufferImageHeight = 0; // tight vertically: rows = imageExtent.height + region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, + sub_resource % mips, sub_resource / mips, 1 }; + region.imageOffset = { offset.x, offset.y, offset.z }; + region.imageExtent = { (uint32_t)box.x, (uint32_t)box.y, (uint32_t)box.z }; + return region; + } + + void CommandList::update_texture(HAL::Resource* resource, ivec3 offset, ivec3 box, + UINT sub_resource, ResourceAddress address, + texture_layout layout) + { + if (!resource || vk_cmd == VK_NULL_HANDLE || !address.resource) return; + auto& dst = static_cast(*resource); + auto& staging = static_cast(*address.resource); + if (dst.get_vk_image() == VK_NULL_HANDLE || staging.get_vk_buffer() == VK_NULL_HANDLE) + return; + + // The HAL transitions `resource` to COPY_DEST (→ TRANSFER_DST_OPTIMAL) before this call. + VkBufferImageCopy region = make_buffer_image_copy(*resource, offset, box, sub_resource, address, layout); + vkCmdCopyBufferToImage(vk_cmd, staging.get_vk_buffer(), dst.get_vk_image(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + } + + void CommandList::read_texture(const HAL::Resource* resource, ivec3 offset, ivec3 box, + UINT sub_resource, ResourceAddress target, + texture_layout layout) + { + if (!resource || vk_cmd == VK_NULL_HANDLE || !target.resource) return; + auto& src = static_cast(*resource); + auto& staging = static_cast(*target.resource); + if (src.get_vk_image() == VK_NULL_HANDLE || staging.get_vk_buffer() == VK_NULL_HANDLE) + return; + + // The HAL transitions `resource` to COPY_SOURCE (→ TRANSFER_SRC_OPTIMAL) before this call. + VkBufferImageCopy region = make_buffer_image_copy(*resource, offset, box, sub_resource, target, layout); + vkCmdCopyImageToBuffer(vk_cmd, src.get_vk_image(), + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, staging.get_vk_buffer(), 1, ®ion); + } + + void CommandList::copy_texture(const Resource::ptr& dest, int dest_sub, + const Resource::ptr& source, int src_sub) + { + if (!dest || !source || vk_cmd == VK_NULL_HANDLE) return; + auto& dst = static_cast(*dest); + auto& src = static_cast(*source); + if (dst.get_vk_image() == VK_NULL_HANDLE || src.get_vk_image() == VK_NULL_HANDLE) return; + + // Use imported_extent for the copy region (covers swapchain backbuffers). + // For regular textures, get_imported_extent() falls back to {0,0}; use 1 as minimum. + VkExtent2D ext = dst.get_imported_extent(); + VkImageCopy region{}; + region.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; + region.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; + region.extent = { ext.width ? ext.width : 1, + ext.height ? ext.height : 1, 1 }; + vkCmdCopyImage(vk_cmd, + src.get_vk_image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dst.get_vk_image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ®ion); + } + + void CommandList::copy_texture(const Resource::ptr& dest, ivec3 dest_pos, + const Resource::ptr& source, ivec3 src_pos, ivec3 size) + { + if (!dest || !source || vk_cmd == VK_NULL_HANDLE) return; + auto& dst = static_cast(*dest); + auto& src = static_cast(*source); + if (dst.get_vk_image() == VK_NULL_HANDLE || src.get_vk_image() == VK_NULL_HANDLE) return; + + VkImageCopy region{}; + region.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; + region.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; + region.srcOffset = { src_pos.x, src_pos.y, src_pos.z }; + region.dstOffset = { dest_pos.x, dest_pos.y, dest_pos.z }; + region.extent = { static_cast(size.x), + static_cast(size.y), + static_cast(size.z) }; + vkCmdCopyImage(vk_cmd, + src.get_vk_image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dst.get_vk_image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ®ion); + } + + // ---- Set topology ------------------------------------------------------- + // Vulkan 1.3 promotes VK_EXT_extended_dynamic_state to core, so + // VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY is always available. Mirrors D3D12's + // IASetPrimitiveTopology: the PSO has a topology TYPE (TRIANGLE/LINE), while + // this call sets the actual LIST vs STRIP mode used by the draw. + void CommandList::set_topology(HAL::PrimitiveTopologyType t, HAL::PrimitiveTopologyFeed feed, + bool, uint) + { + using T = HAL::PrimitiveTopologyType; + using F = HAL::PrimitiveTopologyFeed; + + VkPrimitiveTopology vk_topo; + if (t == T::POINT) + vk_topo = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + else if (t == T::LINE) + vk_topo = (feed == F::STRIP) ? VK_PRIMITIVE_TOPOLOGY_LINE_STRIP + : VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + else if (t == T::PATCH) + vk_topo = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + else + vk_topo = (feed == F::STRIP) ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP + : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + current_topology = vk_topo; + if (vk_cmd != VK_NULL_HANDLE) + vkCmdSetPrimitiveTopology(vk_cmd, vk_topo); + } + + // ---- Debug labels (VK_EXT_debug_utils) ---------------------------------- + + void CommandList::start_event(std::wstring_view name) + { + if (vk_cmd == VK_NULL_HANDLE) return; + auto* dev = static_cast(m_device); + if (!dev) return; + auto fn = reinterpret_cast( + vkGetDeviceProcAddr(dev->get_native_device(), "vkCmdBeginDebugUtilsLabelEXT")); + if (!fn) return; + // Narrow wstring → UTF-8 for Vulkan + std::string label(name.begin(), name.end()); + VkDebugUtilsLabelEXT info{ VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT }; + info.pLabelName = label.c_str(); + fn(vk_cmd, &info); + } + + void CommandList::end_event() + { + if (vk_cmd == VK_NULL_HANDLE) return; + auto* dev = static_cast(m_device); + if (!dev) return; + auto fn = reinterpret_cast( + vkGetDeviceProcAddr(dev->get_native_device(), "vkCmdEndDebugUtilsLabelEXT")); + if (fn) fn(vk_cmd); + } + + // ---- Indirect ----------------------------------------------------------- + void CommandList::execute_indirect(const IndirectCommand&, UINT, Resource*, UINT64, + Resource*, UINT64) { ASSERT(0); } + + // ---- Misc --------------------------------------------------------------- + void CommandList::set_name(std::wstring_view name) + { + if (vk_cmd == VK_NULL_HANDLE) return; + auto* dev = static_cast(m_device); + if (!dev) return; + auto fn = reinterpret_cast( + vkGetDeviceProcAddr(dev->get_native_device(), "vkSetDebugUtilsObjectNameEXT")); + if (!fn) return; + std::string label(name.begin(), name.end()); + VkDebugUtilsObjectNameInfoEXT info{ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT }; + info.objectType = VK_OBJECT_TYPE_COMMAND_BUFFER; + info.objectHandle = reinterpret_cast(vk_cmd); + info.pObjectName = label.c_str(); + fn(dev->get_native_device(), &info); + } + void CommandList::discard(const HAL::Resource*) + { + static bool warned = false; + if (!warned) { warned = true; Log::get() << Log::LEVEL_WARNING << "[Vulkan] CommandList::discard not implemented" << Log::endl; } + } + void CommandList::insert_time(const QueryHandle& handle, uint index) + { + if (vk_cmd == VK_NULL_HANDLE) return; + auto* heap = handle.get_heap().get(); + if (!heap) return; + auto& api_heap = static_cast(*heap); + if (api_heap.get_native() == VK_NULL_HANDLE) return; + uint32_t slot = static_cast(handle.get_offset() + index); + // In Vulkan, queries must be reset between uses (unlike D3D12 where this + // is implicit). Emit a per-slot reset command immediately before the write + // so the query is always in the "unavailable" state when written. + vkCmdResetQueryPool(vk_cmd, api_heap.get_native(), slot, 1); + vkCmdWriteTimestamp2(vk_cmd, + VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, + api_heap.get_native(), slot); + } + + void CommandList::resolve_times(const QueryHeap* heap, uint32_t count, + ResourceAddress dest) + { + if (!heap || vk_cmd == VK_NULL_HANDLE || !dest.resource) return; + + auto& api_heap = static_cast(*heap); + if (api_heap.get_native() == VK_NULL_HANDLE) return; + + auto& dst_res = static_cast(*dest.resource); + if (dst_res.get_vk_buffer() == VK_NULL_HANDLE) return; + + vkCmdCopyQueryPoolResults(vk_cmd, + api_heap.get_native(), + 0, count, + dst_res.get_vk_buffer(), + dest.resource_offset, + sizeof(uint64_t), + VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.CommandList.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandList.ixx new file mode 100644 index 00000000..9c84d5bd --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.CommandList.ixx @@ -0,0 +1,178 @@ +export module HAL:API.CommandList; +import Core; +import vulkan; +import :Types; + +import :ResourceStates; +import :Resource; +import :DescriptorHeap; +import :Fence; +import :FrameManager; +import :PipelineState; +import :RootSignature; +import :API.IndirectCommand; +import :Debug; + +export namespace HAL +{ + namespace API + { + class CommandList + { + void* debug_ptr = nullptr; + friend class HAL::Queue; + + VkCommandBuffer vk_cmd = VK_NULL_HANDLE; + // The pool that allocated vk_cmd. Tracked so begin() can detect when + // compile() rotates to a different CommandAllocator: in that case we must + // allocate a fresh buffer from the new pool rather than calling + // vkResetCommandBuffer on a buffer that belongs to a different pool — + // doing so would access the old pool without holding its mutex, which + // causes threading-validation errors when another thread uses that pool. + VkCommandPool vk_cmd_pool = VK_NULL_HANDLE; + CommandListType type; + Device* m_device = nullptr; + + // Pointer to the pool mutex; locked in begin(), unlocked in end(). + // Raw pointer (not unique_lock) so CommandList stays copy-constructible — + // generic lambdas that take (auto list) copy the list by value, which would + // fail if CommandList had a non-copyable unique_lock member. + // The copy shares the pointer but never calls end(), so double-unlock cannot + // occur. Only the canonical begin()/end() pair manages the lock. + std::mutex* _pool_mutex = nullptr; + + // Dynamic rendering state — populated by set_rtv(), consumed by draw calls. + VkImageView current_color_view = VK_NULL_HANDLE; + VkImageView current_depth_view = VK_NULL_HANDLE; + VkExtent2D current_extent = {}; + bool in_render_pass = false; + + // Pipeline state + VkPipelineLayout current_pipeline_layout = VK_NULL_HANDLE; + bool descriptor_sets_dirty = false; + // Last bound graphics pipeline — re-bound before each draw because the + // recorder may split set_pipeline and the draw across command buffers. + VkPipeline current_graphics_pipeline = VK_NULL_HANDLE; + // Last bound index buffer — re-bound before each indexed draw for the same reason. + VkBuffer current_index_buffer = VK_NULL_HANDLE; + VkDeviceSize current_index_offset = 0; + VkIndexType current_index_type = VK_INDEX_TYPE_UINT16; + // Last viewport(s) / scissor set by the engine. Dynamic state does not + // survive a command-buffer split, so these are re-applied before every draw; + // without this the draw inherits an undefined/empty scissor and is fully + // clipped → nothing renders (the classic Vulkan "black screen" here). + std::vector current_viewports; + VkRect2D current_scissor = {}; + bool has_scissor = false; + VkPrimitiveTopology current_topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + // Bound descriptor heaps (set by set_descriptor_heaps()) + VkDescriptorSet cbv_srv_uav_set = VK_NULL_HANDLE; + VkDescriptorSet sampler_set = VK_NULL_HANDLE; + + // Push constant staging (for graphics_set_constant / compute_set_constant) + std::array push_constants = {}; + + // Deferred PRESENT_SRC_KHR transitions. + // + // The FrameGraph's non_tracked_resources loop places the swapchain's + // RENDER_TARGET→PRESENT barrier immediately after set_rtv() (at P_post, + // the next usage point), which fires BEFORE the draw calls. On D3D12 + // this is harmless because PRESENT==COMMON and COMMON is implicitly + // promoted back to RENDER_TARGET on use. Vulkan has no such promotion: + // draws would see the image in PRESENT_SRC_KHR rather than + // COLOR_ATTACHMENT_OPTIMAL → black output. + // + // Fix: any barrier whose newLayout is PRESENT_SRC_KHR is held here and + // flushed at end(), after ALL draws, so the image stays in + // COLOR_ATTACHMENT_OPTIMAL throughout the render pass. + std::vector deferred_present_barriers; + + // Start/end dynamic rendering. begin_rendering uses LOAD_OP_LOAD so + // that clear_rtv (which uses its own begin/end with CLEAR) is not + // overwritten. end_rendering_if_active() is called from end() and + // set_rtv() to close any open render pass before a new one starts. + void end_rendering_if_active(); + void begin_rendering(VkAttachmentLoadOp color_load, VkClearValue color_clear, + VkAttachmentLoadOp depth_load, VkClearValue depth_clear); + void ensure_rendering_active(); // lazily start render pass for draw calls + void flush_descriptor_sets(); // bind pending descriptor sets + void reapply_draw_state(); // re-bind pipeline + viewport/scissor before a draw + + public: + VkCommandBuffer get_native() const { return vk_cmd; } + + void create(CommandListType type, Device& device); + void begin(CommandAllocator& allocator); + void end(); + + operator bool() const { return vk_cmd != VK_NULL_HANDLE; } + + // --- D3D12-only stubs (no-op in Vulkan) --- + void set_program(StateObject* id, ResourceAddress buffer, uint size, bool init) {} + void dispatch_graph(ResourceAddress addr) {} + + // --- Common recording API --- + void clear_uav(const UAVHandle& h, vec4 ClearColor); + void clear_rtv(const RTVHandle& h, vec4 ClearColor); + void clear_stencil(const DSVHandle& dsv, UINT8 stencil); + void clear_depth(const DSVHandle& dsv, float depth); + void clear_depth_stencil(const DSVHandle& dsv, bool depth, bool stencil, float fdepth, UINT8 fstencil); + void set_topology(HAL::PrimitiveTopologyType topology, + HAL::PrimitiveTopologyFeed feedType = HAL::PrimitiveTopologyFeed::LIST, + bool adjusted = false, uint controlpoints = 0); + void set_stencil_ref(UINT ref); + + // Raytracing — no-op stubs for Vulkan Phase 0 + void dispatch_rays(uint hit_size, uint miss_size, uint raygen_size, + ivec2 size, HAL::ResourceAddress hit_buffer, UINT hit_count, + HAL::ResourceAddress miss_buffer, UINT miss_count, + HAL::ResourceAddress raygen_buffer) {} + + void set_name(std::wstring_view name); + void discard(const HAL::Resource* resource); + void set_descriptor_heaps(DescriptorHeap* cbv, DescriptorHeap* sampler); + void insert_time(const QueryHandle& handle, uint offset); + void resolve_times(const QueryHeap* pQueryHeap, uint32_t NumQueries, ResourceAddress destination); + void set_graphics_signature(const HAL::RootSignature::ptr& s); + void set_compute_signature(const HAL::RootSignature::ptr& s); + void draw(UINT vertex_count, UINT vertex_offset, UINT instance_count, UINT instance_offset); + void draw_indexed(UINT index_count, UINT index_offset, UINT vertex_offset, UINT instance_count, UINT instance_offset); + void set_index_buffer(HAL::Views::IndexBuffer index); + void graphics_set_const_buffer(UINT i, const ResourceAddress& address); + void compute_set_const_buffer(UINT i, const ResourceAddress& address); + void graphics_set_constant(UINT i, UINT offset, UINT value); + void compute_set_constant(UINT i, UINT offset, UINT value); + void dispatch_mesh(ivec3 v); + void dispatch(ivec3 v); + void set_scissors(sizer_long rect); + void set_viewports(std::vector viewports); + void copy_resource(HAL::Resource* dest, HAL::Resource* source); + void copy_buffer(HAL::Resource* dest, uint64 dest_offset, + HAL::Resource* source, uint64 source_offset, uint64 size); + void set_pipeline(std::shared_ptr pipeline); + void execute_indirect(const IndirectCommand& command_types, UINT max_commands, + Resource* command_buffer, UINT64 command_offset, + Resource* counter_buffer, UINT64 counter_offset); + void set_rtv(int c, RTVHandle rt, DSVHandle h); + void start_event(std::wstring_view str); + void end_event(); + + // Raytracing acceleration structure — no-op in Vulkan Phase 0 + void build_ras(const HAL::RaytracingBuildDescStructure& build_desc, + const HAL::RaytracingBuildDescBottomInputs& bottom) {} + void build_ras(const HAL::RaytracingBuildDescStructure& build_desc, + const HAL::RaytracingBuildDescTopInputs& top) {} + + void copy_texture(const Resource::ptr& dest, int dest_subres, + const Resource::ptr& source, int source_subres); + void copy_texture(const Resource::ptr& to, ivec3 to_pos, + const Resource::ptr& from, ivec3 from_pos, ivec3 size); + void update_texture(HAL::Resource* resource, ivec3 offset, ivec3 box, + UINT sub_resource, ResourceAddress address, texture_layout layout); + void read_texture(const HAL::Resource* resource, ivec3 offset, ivec3 box, + UINT sub_resource, ResourceAddress target, texture_layout layout); + void transitions(const HAL::Barriers& barriers); + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.DescriptorHeap.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.DescriptorHeap.cpp new file mode 100644 index 00000000..9e4f97ad --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.DescriptorHeap.cpp @@ -0,0 +1,328 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:DescriptorHeap; + +import :Debug; +import :Resource; +import :Resource.Buffer; +import :API.Device; // get_native_device(), get_cbv_srv_uav_layout(), etc. + +import vulkan; +import Core; + +// Vulkan Phase 4 — real descriptor heap implementation. +// +// Descriptor model (binding numbers match DXC -fvk-b/t/u-shift flags): +// Set 0 (CBV_SRV_UAV) — 4 bindings sharing one VkDescriptorSet: +// binding 0: UNIFORM_BUFFER (CBVs, b-shift = 0) +// binding 128: SAMPLED_IMAGE (SRV textures, t-shift = 128) +// binding 256: STORAGE_IMAGE (UAV textures, u-shift = 256) +// binding 384: STORAGE_BUFFER (SRV/UAV bufs, u-shift = 256 buffers) +// Set 1 (SAMPLER) — 1 binding: +// binding 0: SAMPLER (-fvk-bind-sampler-heap 1 0) +// RTV / DSV — no VkDescriptorSet; handled by dynamic rendering. +// +// get_gpu() returns the raw descriptor slot offset as the bindless array index. +// The offset is used directly as dstArrayElement; each binding has HEAP_MAX +// elements so any flat heap position fits regardless of type. +// All bindings use UPDATE_AFTER_BIND + PARTIALLY_BOUND. + +namespace HAL +{ + // ---- Descriptor (slot within a heap) ----------------------------------- + + Descriptor::Descriptor(DescriptorHeap& heap, uint offset) : heap(heap), offset(offset) + { + // Vulkan has no CPU/GPU descriptor handles; the bindless slot index is + // carried in the stub handle value so the shared HAL::Handle interface + // (get_cpu/get_gpu) keeps working unchanged. + cpu_handle = { static_cast(offset) }; + gpu_handle = { static_cast(offset) }; + } + + void Descriptor::place(const Views::ShaderResource& v) + { + auto& api_heap = static_cast(heap); + if (!api_heap.get_vk_set() || !v.Resource) return; + + auto& api_res = static_cast(*v.Resource); + + VkWriteDescriptorSet write{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + write.dstSet = api_heap.get_vk_set(); + write.dstBinding = 0; // SAMPLED_IMAGE by default + write.dstArrayElement = offset; + write.descriptorCount = 1; + + VkDescriptorImageInfo img_info{}; + VkDescriptorBufferInfo buf_info{}; + + if (api_res.get_vk_image() != VK_NULL_HANDLE) + { + // SRV texture → binding 0 (MUTABLE → SAMPLED_IMAGE) + VkImageView view = api_res.get_vk_image_view(); + if (view == VK_NULL_HANDLE) return; + img_info.imageView = view; + // GENERAL: matches to_native(SHADER_RESOURCE) = VK_IMAGE_LAYOUT_GENERAL so + // this SRV slot never disagrees with the UAV slot for the same image. + img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + write.dstBinding = 0; + write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + write.pImageInfo = &img_info; + } + else if (api_res.get_vk_buffer() != VK_NULL_HANDLE) + { + // Buffer SRV → binding 0 (MUTABLE → STORAGE_BUFFER). + // StructuredBuffers are sub-ranges (FirstElement..NumElements) of a shared + // buffer; honour the offset/size or the shader reads the wrong elements. + buf_info.buffer = api_res.get_vk_buffer(); + buf_info.offset = 0; + buf_info.range = VK_WHOLE_SIZE; + if (auto* b = std::get_if(&v.View)) + { + const uint64_t stride = b->StructureByteStride ? b->StructureByteStride : 1u; + buf_info.offset = b->FirstElement * stride; + if (b->NumElements) + buf_info.range = static_cast(b->NumElements) * stride; + } + else + ASSERT(0); + write.dstBinding = 0; + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write.pBufferInfo = &buf_info; + } + else return; + + vkUpdateDescriptorSets(api_heap.device.get_native_device(), 1, &write, 0, nullptr); + } + + void Descriptor::place(const Views::UnorderedAccess& v) + { + auto& api_heap = static_cast(heap); + if (!api_heap.get_vk_set() || !v.Resource) return; + + auto& api_res = static_cast(*v.Resource); + + VkWriteDescriptorSet write{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + write.dstSet = api_heap.get_vk_set(); + write.dstArrayElement = offset; + write.descriptorCount = 1; + + VkDescriptorImageInfo img_info{}; + VkDescriptorBufferInfo buf_info{}; + + if (api_res.get_vk_image() != VK_NULL_HANDLE) + { + // UAV texture → binding 0 (MUTABLE → STORAGE_IMAGE). + // Vulkan requires levelCount=1 for STORAGE_IMAGE; use a per-mip view. + uint32_t mip_slice = 0, array_slice = 0; + std::visit(overloaded{ + [&](const Views::UnorderedAccess::Texture2D& t) { mip_slice = t.MipSlice; }, + [&](const Views::UnorderedAccess::Texture2DArray& t) { mip_slice = t.MipSlice; array_slice = t.FirstArraySlice; }, + [&](const Views::UnorderedAccess::Texture3D& t) { mip_slice = t.MipSlice; }, + [](auto&&) {} + }, v.View); + + VkImageView view = api_res.get_vk_mip_view( + api_heap.device.get_native_device(), mip_slice, array_slice); + if (view == VK_NULL_HANDLE) return; + img_info.imageView = view; + img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + write.dstBinding = 0; + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + write.pImageInfo = &img_info; + } + else if (api_res.get_vk_buffer() != VK_NULL_HANDLE) + { + // UAV buffer → binding 0 (MUTABLE → STORAGE_BUFFER). Honour the + // FirstElement/NumElements sub-range like the SRV path. + buf_info.buffer = api_res.get_vk_buffer(); + buf_info.offset = 0; + buf_info.range = VK_WHOLE_SIZE; + if (auto* b = std::get_if(&v.View)) + { + const uint64_t stride = b->StructureByteStride ? b->StructureByteStride : 1u; + buf_info.offset = static_cast(b->FirstElement) * stride; + if (b->NumElements) + buf_info.range = static_cast(b->NumElements) * stride; + } + write.dstBinding = 0; + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write.pBufferInfo = &buf_info; + } + else return; + + vkUpdateDescriptorSets(api_heap.device.get_native_device(), 1, &write, 0, nullptr); + } + + void Descriptor::place(const Views::ConstantBuffer& v) + { + auto& api_heap = static_cast(heap); + if (!api_heap.get_vk_set() || !v.Resource) return; + + auto& api_res = static_cast(*v.Resource); + if (api_res.get_vk_buffer() == VK_NULL_HANDLE) return; + + // CRITICAL: constant buffers are sub-allocated inside larger shared buffers + // (DataHolder::compile → place_data with resource_offset). The view carries + // OffsetInBytes/SizeInBytes; ignoring them (offset=0, range=WHOLE) points the + // descriptor at the START of the shared buffer instead of this CB's sub-region, + // so the shader reads the wrong bindless indices → garbage vertices → black UI. + VkDescriptorBufferInfo buf_info{}; + buf_info.buffer = api_res.get_vk_buffer(); + buf_info.offset = v.OffsetInBytes; + buf_info.range = v.SizeInBytes > 0 ? v.SizeInBytes : VK_WHOLE_SIZE; + + VkWriteDescriptorSet write{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + write.dstSet = api_heap.get_vk_set(); + write.dstBinding = 0; // MUTABLE → UNIFORM_BUFFER (CBV, b-shift = 0) + write.dstArrayElement = offset; + write.descriptorCount = 1; + write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write.pBufferInfo = &buf_info; + + vkUpdateDescriptorSets(api_heap.device.get_native_device(), 1, &write, 0, nullptr); + } + + void Descriptor::place(const Views::RenderTarget&) {} // handled by dynamic rendering + void Descriptor::place(const Views::DepthStencil&) {} // handled by dynamic rendering + + void Descriptor::operator=(const Descriptor& r) + { + // Copy one descriptor slot to another. For RTV/DSV heaps there are no + // Vulkan descriptor objects (dynamic rendering handles those) — the copy + // is a no-op here; HAL::Handle::place() already copies the ResourceInfo + // separately. For CBV_SRV_UAV / SAMPLER heaps use vkCopyDescriptorSets. + auto& dst_api = static_cast(heap); + auto& src_api = static_cast(r.heap); + + if (dst_api.desc.HeapType == DescriptorHeapType::RTV || + dst_api.desc.HeapType == DescriptorHeapType::DSV) + return; + + if (!dst_api.get_vk_set() || !src_api.get_vk_set()) return; + + VkCopyDescriptorSet copy{ VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET }; + copy.srcSet = src_api.get_vk_set(); + copy.srcBinding = 0; + copy.srcArrayElement = r.offset; + copy.dstSet = dst_api.get_vk_set(); + copy.dstBinding = 0; + copy.dstArrayElement = offset; + copy.descriptorCount = 1; + + vkUpdateDescriptorSets(dst_api.device.get_native_device(), 0, nullptr, 1, ©); + } + + uint DescriptorHeap::get_size() { return desc.Count; } + + namespace API + { + DescriptorHeap::DescriptorHeap(Device& dev, const DescriptorHeapDesc& d) + : device(dev), desc(d) + { + handle_size = 0; + + // RTV / DSV heaps have no Vulkan descriptor objects. + if (d.HeapType == DescriptorHeapType::RTV || + d.HeapType == DescriptorHeapType::DSV) + return; + + VkDevice vk_dev = dev.get_native_device(); + if (vk_dev == VK_NULL_HANDLE) return; + + // ---- Pool ------------------------------------------------------- + bool is_sampler = (d.HeapType == DescriptorHeapType::SAMPLER); + + std::vector pool_sizes; + if (is_sampler) + { + pool_sizes.push_back({ VK_DESCRIPTOR_TYPE_SAMPLER, d.Count }); + } + else + { + // Binding 0 is MUTABLE_EXT — one pool entry covers all resource types. + // Bindings 384-388: 5 inline static samplers (s0..s4), one per binding. + pool_sizes.push_back({ VK_DESCRIPTOR_TYPE_MUTABLE_EXT, d.Count }); + pool_sizes.push_back({ VK_DESCRIPTOR_TYPE_SAMPLER, 5u }); + } + + VkDescriptorPoolCreateInfo pool_ci{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; + pool_ci.maxSets = 1; + pool_ci.poolSizeCount = static_cast(pool_sizes.size()); + pool_ci.pPoolSizes = pool_sizes.data(); + pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT; + + if (vkCreateDescriptorPool(vk_dev, &pool_ci, nullptr, &vk_pool) != VK_SUCCESS) + return; + + // ---- Set -------------------------------------------------------- + VkDescriptorSetLayout layout = is_sampler + ? dev.get_sampler_layout() + : dev.get_cbv_srv_uav_layout(); + + if (layout == VK_NULL_HANDLE) return; + + // Variable descriptor count: use desc.Count for the last binding. + uint32_t var_count = d.Count; + VkDescriptorSetVariableDescriptorCountAllocateInfo var_info{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO }; + var_info.descriptorSetCount = 1; + var_info.pDescriptorCounts = &var_count; + + VkDescriptorSetAllocateInfo alloc_info{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; + alloc_info.descriptorPool = vk_pool; + alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = &layout; + // Only attach variable-count info if the layout actually uses it. + // The global layout uses PARTIALLY_BOUND but not VARIABLE_DESCRIPTOR_COUNT + // on the last binding (we use a fixed max count), so skip var_info here. + // alloc_info.pNext = &var_info; // reserved for per-heap variable layouts + + vkAllocateDescriptorSets(vk_dev, &alloc_info, &vk_set); + + // ---- Populate inline static samplers (s0..s4, bindings 384-388) -- + // These must be written once into every CBV_SRV_UAV set so that + // shaders using register(s0..s4) with s-shift=384 find valid samplers. + if (!is_sampler && vk_set != VK_NULL_HANDLE) + { + const VkSampler* smprs = dev.get_inline_samplers(); + constexpr uint32_t SMP_BASE = 384; + constexpr uint32_t N = 5; // s0..s4 + VkDescriptorImageInfo img_infos[N]; + VkWriteDescriptorSet writes[N]; + uint32_t write_count = 0; + for (uint32_t i = 0; i < N; ++i) + { + if (!smprs[i]) continue; + img_infos[write_count] = {}; + img_infos[write_count].sampler = smprs[i]; + writes[write_count] = {}; + writes[write_count].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes[write_count].dstSet = vk_set; + writes[write_count].dstBinding = SMP_BASE + i; + writes[write_count].dstArrayElement = 0; + writes[write_count].descriptorCount = 1; + writes[write_count].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + writes[write_count].pImageInfo = &img_infos[write_count]; + ++write_count; + } + if (write_count) + vkUpdateDescriptorSets(vk_dev, write_count, writes, 0, nullptr); + } + } + + DescriptorHeap::~DescriptorHeap() + { + VkDevice vk_dev = device.get_native_device(); + if (vk_pool != VK_NULL_HANDLE && vk_dev != VK_NULL_HANDLE) + vkDestroyDescriptorPool(vk_dev, vk_pool, nullptr); + } + + HAL::Descriptor DescriptorHeap::operator[](uint i) + { + auto THIS = static_cast(this); + return HAL::Descriptor{ *THIS, i }; + } + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.DescriptorHeap.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.DescriptorHeap.ixx new file mode 100644 index 00000000..0bed4e1c --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.DescriptorHeap.ixx @@ -0,0 +1,69 @@ +export module HAL:API.DescriptorHeap; + +import :API.Device; +export import :Utils; // Re-exported so D3D12-compat stubs are visible to HAL.DescriptorHeap.ixx +import :Types; +import :Descriptors; +import :API.Resource; + +import Core; + +export namespace HAL +{ + namespace API + { + class DescriptorHeap; + + // Vulkan equivalent of D3D12's API::Descriptor base. The shared + // HAL::Descriptor (HAL.DescriptorHeap.ixx) derives from this and the + // public HAL::Handle interface still exposes D3D12-style handles + // (stubbed in Vulkan builds); for Vulkan the handle value carries the + // bindless slot index. + class Descriptor + { + protected: + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle = {}; + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle = {}; + public: + D3D12_CPU_DESCRIPTOR_HANDLE get_cpu() const { return cpu_handle; } + D3D12_GPU_DESCRIPTOR_HANDLE get_gpu() const { return gpu_handle; } + }; + } + + struct DescriptorHeapDesc + { + uint Count; + DescriptorHeapType HeapType; + DescriptorHeapFlags Flags; + }; + + class DescriptorHeap; + class Descriptor; // shared HAL::Descriptor (HAL.DescriptorHeap.ixx) + + namespace API + { + class DescriptorHeap + { + protected: + // Vulkan descriptor objects — only valid for CBV_SRV_UAV / SAMPLER heaps. + VkDescriptorPool vk_pool = VK_NULL_HANDLE; + VkDescriptorSet vk_set = VK_NULL_HANDLE; + + public: + const DescriptorHeapDesc desc; + Device& device; // non-const: place() calls vkUpdateDescriptorSets + + uint handle_size = 0; + + friend class HAL::Descriptor; + public: + DescriptorHeap(Device& device, const DescriptorHeapDesc& desc); + virtual ~DescriptorHeap(); + + HAL::Descriptor operator[](uint i); + + // Returns the backing VkDescriptorSet so CommandList can bind it. + VkDescriptorSet get_vk_set() const noexcept { return vk_set; } + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Device.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Device.cpp new file mode 100644 index 00000000..fa518138 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Device.cpp @@ -0,0 +1,601 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +#include +module HAL:Device; + +import :Debug; +import :Utils; +import :Impl; // get_vk_instance() +import :Sampler; + +import stl.core; +import Core; + +// Vulkan native implementation of HAL::Device. +// Mirrors the partition layout of D3D12/HAL.D3D12.Device.cpp. + +namespace HAL +{ + // ---- Common HAL::Device methods ---------------------------------------- + + texture_layout Device::get_texture_layout(const ResourceDesc& rdesc, UINT sub_resource) + { + auto& desc = rdesc.as_texture(); + auto info = desc.Format.surface_info({ desc.Dimensions.x, desc.Dimensions.y }); + return { + info.numBytes, info.numRows, info.rowBytes, + static_cast(info.numBytes), 256u, desc.Format + }; + } + + texture_layout Device::get_texture_layout(const ResourceDesc& rdesc, UINT sub_resource, ivec3 box) + { + auto& desc = rdesc.as_texture(); + auto info = desc.Format.surface_info({ (uint)box.x, (uint)box.y }); + uint64 res_stride = Math::AlignUp((uint64)info.rowBytes, 256ull); + uint64 size = res_stride * info.numRows * box.z; + return { + size, info.numRows, static_cast(res_stride), + static_cast(res_stride * info.numRows), 512u, desc.Format + }; + } + + std::vector Device::compress(std::span source) + { + std::vector dest; + dest.assign(source.data(), source.data() + source.size()); + return dest; + } + + // ---- HAL::API::Device -------------------------------------------------- + + namespace API + { + void Device::queue_initial_transition(VkImage image, VkImageLayout layout, VkImageAspectFlags aspect) + { + if (image == VK_NULL_HANDLE || layout == VK_IMAGE_LAYOUT_UNDEFINED) return; + + VkImageMemoryBarrier2 b{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + b.srcStageMask = VK_PIPELINE_STAGE_2_NONE; + b.srcAccessMask = 0; + b.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + b.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT; + b.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + b.newLayout = layout; + b.image = image; + b.subresourceRange = { aspect, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; + + std::lock_guard lock(pending_init_mutex); + pending_init_barriers.push_back(b); + } + + void Device::cancel_pending_init_transition(VkImage image) + { + if (image == VK_NULL_HANDLE) return; + std::lock_guard lock(pending_init_mutex); + auto& v = pending_init_barriers; + v.erase(std::remove_if(v.begin(), v.end(), + [image](const VkImageMemoryBarrier2& b) { return b.image == image; }), + v.end()); + } + + std::vector Device::take_pending_init_transitions() + { + std::lock_guard lock(pending_init_mutex); + return std::move(pending_init_barriers); + } + + void Device::init(DeviceDesc& device_desc) + { + auto THIS = static_cast(this); + THIS->adapter = device_desc.adapter; + vk_instance = HAL::get_vk_instance(); + vk_physical = device_desc.adapter ? device_desc.adapter->get_vk_physical() : VK_NULL_HANDLE; + + if (vk_physical == VK_NULL_HANDLE) return; + + // ---- Queue families -------------------------------------------- + uint32_t qf_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(vk_physical, &qf_count, nullptr); + std::vector qf_props(qf_count); + vkGetPhysicalDeviceQueueFamilyProperties(vk_physical, &qf_count, qf_props.data()); + + uint32_t graphics_family = UINT32_MAX; + uint32_t compute_family = UINT32_MAX; + uint32_t transfer_family = UINT32_MAX; + + for (uint32_t i = 0; i < qf_count; ++i) + { + if (graphics_family == UINT32_MAX && + (qf_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) + graphics_family = i; + + if (compute_family == UINT32_MAX && + (qf_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT) && + !(qf_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) + compute_family = i; + + if (transfer_family == UINT32_MAX && + (qf_props[i].queueFlags & VK_QUEUE_TRANSFER_BIT) && + !(qf_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && + !(qf_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT)) + transfer_family = i; + } + // Fall back to graphics queue if dedicated queues not found + if (compute_family == UINT32_MAX) compute_family = graphics_family; + if (transfer_family == UINT32_MAX) transfer_family = graphics_family; + + // Store for Queue::construct() and CommandAllocator + queue_families[0] = graphics_family; // DIRECT + queue_families[1] = compute_family; // COMPUTE + queue_families[2] = transfer_family; // COPY + + // ---- Queue create infos ---------------------------------------- + const float priority = 1.0f; + std::vector queue_infos; + std::set unique_families = { graphics_family, compute_family, transfer_family }; + for (uint32_t qf : unique_families) + { + VkDeviceQueueCreateInfo qi{ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO }; + qi.queueFamilyIndex = qf; + qi.queueCount = 1; + qi.pQueuePriorities = &priority; + queue_infos.push_back(qi); + } + + // ---- Extensions: only request what the device actually supports ---- + // Many of these are promoted to Vulkan 1.2/1.3 core. Some drivers + // reject listing already-core extensions in ppEnabledExtensionNames, + // so we filter against the device's reported extension list first. + const char* wanted_extensions[] = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, + VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, + VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, + VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, + VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, + // Required for ResourceDescriptorHeap: binding 0 must accept multiple + // descriptor types (SAMPLED_IMAGE, STORAGE_IMAGE, UNIFORM_BUFFER, + // STORAGE_BUFFER) simultaneously — exactly what mutable descriptors do. + VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME, + // Required by DXC SPIRV for 'discard' in pixel shaders. + VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, + // Optional: ddx/ddy in compute shaders. + VK_KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, + // Optional: mesh/task shaders. + VK_EXT_MESH_SHADER_EXTENSION_NAME, + }; + + uint32_t avail_count = 0; + vkEnumerateDeviceExtensionProperties(vk_physical, nullptr, &avail_count, nullptr); + std::vector avail_exts(avail_count); + vkEnumerateDeviceExtensionProperties(vk_physical, nullptr, &avail_count, avail_exts.data()); + + std::vector device_extensions; + for (auto wanted : wanted_extensions) + { + for (auto& ext : avail_exts) + if (strcmp(ext.extensionName, wanted) == 0) + { device_extensions.push_back(wanted); break; } + } + + auto has_ext = [&](const char* name) { + return std::any_of(device_extensions.begin(), device_extensions.end(), + [name](const char* e) { return strcmp(e, name) == 0; }); + }; + const bool has_mesh_shader = has_ext(VK_EXT_MESH_SHADER_EXTENSION_NAME); + const bool has_cs_derivatives = has_ext(VK_KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME); + + // ---- Feature chain ---------------------------------------------- + VkPhysicalDeviceBufferDeviceAddressFeatures bda_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES }; + bda_features.bufferDeviceAddress = VK_TRUE; + + VkPhysicalDeviceTimelineSemaphoreFeatures ts_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES }; + ts_features.timelineSemaphore = VK_TRUE; + ts_features.pNext = &bda_features; + + VkPhysicalDeviceSynchronization2Features sync2_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES }; + sync2_features.synchronization2 = VK_TRUE; + sync2_features.pNext = &ts_features; + + VkPhysicalDeviceDynamicRenderingFeatures dr_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES }; + dr_features.dynamicRendering = VK_TRUE; + dr_features.pNext = &sync2_features; + + VkPhysicalDeviceDescriptorIndexingFeatures di_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES }; + di_features.runtimeDescriptorArray = VK_TRUE; + di_features.descriptorBindingPartiallyBound = VK_TRUE; + di_features.descriptorBindingVariableDescriptorCount = VK_TRUE; + di_features.shaderSampledImageArrayNonUniformIndexing = VK_TRUE; + di_features.pNext = &dr_features; + + // Mutable descriptors: binding 0 can hold SAMPLED_IMAGE, STORAGE_IMAGE, + // UNIFORM_BUFFER, STORAGE_BUFFER simultaneously (needed for ResourceDescriptorHeap). + VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutable_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT }; + mutable_features.mutableDescriptorType = VK_TRUE; + mutable_features.pNext = &di_features; + + // DemoteToHelperInvocation: 'discard' in pixel shaders uses this capability. + VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures demote_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES }; + demote_features.shaderDemoteToHelperInvocation = VK_TRUE; + demote_features.pNext = &mutable_features; + + // scalarBlockLayout: allows StructuredBuffers with strides not aligned to 16 + // (e.g. Glyph stride=28, VSLine stride=24). + VkPhysicalDeviceScalarBlockLayoutFeatures scalar_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES }; + scalar_features.scalarBlockLayout = VK_TRUE; + scalar_features.pNext = &demote_features; + + // hostQueryReset: allows vkResetQueryPool() from the CPU without a command buffer. + // Used in QueryHeap constructor to bring queries to the "unavailable" initial state. + VkPhysicalDeviceHostQueryResetFeatures host_reset_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES }; + host_reset_features.hostQueryReset = VK_TRUE; + host_reset_features.pNext = &scalar_features; + + // extendedDynamicState: required for vkCmdSetPrimitiveTopology (used by + // set_topology / reapply_draw_state). Promoted to Vulkan 1.3 core but still + // must be explicitly enabled in the device feature chain. + VkPhysicalDeviceExtendedDynamicStateFeaturesEXT eds_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT }; + eds_features.extendedDynamicState = VK_TRUE; + eds_features.pNext = &host_reset_features; + + // Optional feature structs — only inserted into the chain if the + // extension is present. Including structs for absent extensions in + // vkCreateDevice's pNext may trigger VK_ERROR_EXTENSION_NOT_PRESENT. + VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR cs_deriv_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR }; + cs_deriv_features.computeDerivativeGroupQuads = VK_TRUE; + cs_deriv_features.computeDerivativeGroupLinear = VK_TRUE; + + VkPhysicalDeviceMeshShaderFeaturesEXT mesh_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT }; + mesh_features.meshShader = VK_TRUE; + mesh_features.taskShader = VK_TRUE; + + void* feature_head = &eds_features; + if (has_cs_derivatives) { + cs_deriv_features.pNext = feature_head; + feature_head = &cs_deriv_features; + } + if (has_mesh_shader) { + mesh_features.pNext = feature_head; + feature_head = &mesh_features; + } + + VkPhysicalDeviceFeatures2 features2{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; + features2.pNext = feature_head; + vkGetPhysicalDeviceFeatures2(vk_physical, &features2); + + // ---- Create logical device -------------------------------------- + VkDeviceCreateInfo device_ci{ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; + device_ci.queueCreateInfoCount = static_cast(queue_infos.size()); + device_ci.pQueueCreateInfos = queue_infos.data(); + device_ci.enabledExtensionCount = static_cast(device_extensions.size()); + device_ci.ppEnabledExtensionNames = device_extensions.data(); + device_ci.pNext = &features2; + + VkResult result = vkCreateDevice(vk_physical, &device_ci, nullptr, &vk_device); + if (result != VK_SUCCESS) + { + Log::get().crash_error( + std::string("vkCreateDevice failed, VkResult=") + std::to_string(static_cast(result))); + return; + } + + // ---- DeviceProperties ------------------------------------------- + VkPhysicalDeviceProperties2 props2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; + vkGetPhysicalDeviceProperties2(vk_physical, &props2); + + auto& p = THIS->properties; + p.name = props2.properties.deviceName; + p.rtx = false; // Phase: VK_KHR_ray_tracing_pipeline check + p.mesh_shader = has_mesh_shader && (mesh_features.meshShader == VK_TRUE); + p.work_graph = false; // no Vulkan equivalent yet + p.min_storage_buffer_offset_alignment = + static_cast(props2.properties.limits.minStorageBufferOffsetAlignment); + // full_bindless = true whenever the Vulkan device creates successfully. + // The D3D12 version gates on shader model 6.6; on Vulkan, bindless is + // always available once descriptor indexing features are enabled, so + // we just require a working device. This is what the common + // Device::create_singleton() selection logic checks. + p.full_bindless = true; + + // ---- VMA allocator ---------------------------------------------- + VmaAllocatorCreateInfo vma_info{}; + vma_info.physicalDevice = vk_physical; + vma_info.device = vk_device; + vma_info.instance = vk_instance; + vma_info.vulkanApiVersion = VK_API_VERSION_1_3; + vma_info.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; + vmaCreateAllocator(&vma_info, &vma_allocator); + + // ---- VRAM info -------------------------------------------------- + VkPhysicalDeviceMemoryProperties mem_props{}; + vkGetPhysicalDeviceMemoryProperties(vk_physical, &mem_props); + size_t vram = 0; + for (uint32_t i = 0; i < mem_props.memoryHeapCount; ++i) + if (mem_props.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + vram += mem_props.memoryHeaps[i].size; + + // ---- Global bindless descriptor set layouts --------------------- + // DXC with -fvk-bind-resource-heap 0 0 maps the ENTIRE ResourceDescriptorHeap + // to Set 0, Binding 0 — regardless of resource type (SAMPLED_IMAGE, + // STORAGE_IMAGE, UNIFORM_BUFFER, STORAGE_BUFFER all land at binding 0). + // The b/t/u shifts (0/128/256) partition the element INDEX space: + // b-registers (CBV) → binding 0, elements [0, 127] (b-shift = 0) + // t-registers (SRV) → binding 0, elements [128, 255] (t-shift = 128) + // u-registers (UAV) → binding 0, elements [256, 383] (u-shift = 256) + // Binding 384 = SAMPLER for inline s-register declarations (s-shift = 384). + // s-registers (SMP) → set 0, binding 384+register# (s-shift = 384) + // SamplerDescriptorHeap → set 1, binding 0 (-fvk-bind-sampler-heap 1 0) + // + // Because binding 0 holds multiple descriptor types simultaneously, + // we use VK_EXT_mutable_descriptor_type (VK_DESCRIPTOR_TYPE_MUTABLE_EXT). + { + constexpr uint32_t HEAP_MAX = 65536 * 8; // matches DescriptorHeapFactory + constexpr uint32_t SMP_BASE = 384; // inline sampler binding (s-shift) + constexpr uint32_t SMP_COUNT = 128; // max inline samplers + + constexpr VkDescriptorBindingFlags bind_flags = + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT; + + // Mutable descriptor type list for binding 0. + const VkDescriptorType mutable_types[] = { + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + }; + VkMutableDescriptorTypeListEXT mutable_list{}; + mutable_list.descriptorTypeCount = 4; + mutable_list.pDescriptorTypes = mutable_types; + + // Bindings: 0 = mutable heap; 384..388 = inline static samplers s0..s4. + // Each s-register (s0..s4) maps to its own binding: sN → binding SMP_BASE+N. + // (With s-shift=384: s2 → binding 386, NOT element 2 of binding 384.) + constexpr uint32_t NUM_INLINE_SMP = 5; // s0..s4 in FrameLayout.h + // mutable heap (0) + counter heap (2) + 5 inline samplers (384-388) + constexpr uint32_t TOTAL_BINDINGS = 2 + NUM_INLINE_SMP; + + VkDescriptorSetLayoutBinding bindings[TOTAL_BINDINGS]{}; + VkDescriptorBindingFlags bflags[TOTAL_BINDINGS]{}; + + // Binding 0: mutable resource heap (CBV/SRV/UAV via ResourceDescriptorHeap) + bindings[0].binding = 0; + bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_MUTABLE_EXT; + bindings[0].descriptorCount = HEAP_MAX; + bindings[0].stageFlags = VK_SHADER_STAGE_ALL; + bflags[0] = bind_flags; + + // Binding 2: counter heap — DXC SPIR-V places AppendStructuredBuffer + // hidden counters here by default (counter.var.ResourceDescriptorHeap). + bindings[1].binding = 2; + bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + bindings[1].descriptorCount = 1; + bindings[1].stageFlags = VK_SHADER_STAGE_ALL; + bflags[1] = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT; + + for (uint32_t si = 0; si < NUM_INLINE_SMP; ++si) + { + bindings[2 + si].binding = SMP_BASE + si; // 384, 385, 386, 387, 388 + bindings[2 + si].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + bindings[2 + si].descriptorCount = 1; + bindings[2 + si].stageFlags = VK_SHADER_STAGE_ALL; + bflags[2 + si] = bind_flags; + } + + // Mutable type list: one entry per binding. + // Binding 0 = mutable; binding 2 (counter) and 384-388 (samplers) = not mutable. + VkMutableDescriptorTypeListEXT mutable_lists[TOTAL_BINDINGS]{}; + mutable_lists[0] = mutable_list; // binding 0 only + // mutable_lists[1..6] remain zero-initialised + + VkMutableDescriptorTypeCreateInfoEXT mutable_ci{ + VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT }; + mutable_ci.mutableDescriptorTypeListCount = TOTAL_BINDINGS; + mutable_ci.pMutableDescriptorTypeLists = mutable_lists; + + VkDescriptorSetLayoutBindingFlagsCreateInfo ext_info{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO }; + ext_info.bindingCount = TOTAL_BINDINGS; + ext_info.pBindingFlags = bflags; + + mutable_ci.pNext = nullptr; + ext_info.pNext = &mutable_ci; + + VkDescriptorSetLayoutCreateInfo layout_ci{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + layout_ci.bindingCount = TOTAL_BINDINGS; + layout_ci.pBindings = bindings; + layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; + layout_ci.pNext = &ext_info; + + vkCreateDescriptorSetLayout(vk_device, &layout_ci, nullptr, &cbv_srv_uav_layout); + + // ---- Set 1 layout: Sampler (dedicated) ---------------------- + VkDescriptorSetLayoutBinding samp_binding{}; + samp_binding.binding = 0; + samp_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + samp_binding.descriptorCount = 2048; + samp_binding.stageFlags = VK_SHADER_STAGE_ALL; + + VkDescriptorBindingFlags samp_flag = bind_flags; + + VkDescriptorSetLayoutBindingFlagsCreateInfo samp_ext{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO }; + samp_ext.bindingCount = 1; + samp_ext.pBindingFlags = &samp_flag; + + VkDescriptorSetLayoutCreateInfo samp_ci{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + samp_ci.bindingCount = 1; + samp_ci.pBindings = &samp_binding; + samp_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; + samp_ci.pNext = &samp_ext; + + vkCreateDescriptorSetLayout(vk_device, &samp_ci, nullptr, &sampler_layout); + } + + // ---- Inline static samplers s0..s4 (FrameLayout.h) -------------- + // These map to set 0, bindings 384-388 (s-shift = 384). + // The order must match FrameLayout.h: + // s0=linearSampler, s1=pointClampSampler, s2=linearClampSampler, + // s3=anisoBordeSampler, s4=pointBorderSampler + { + const SamplerDesc* descs[NUM_INLINE_SMP] = { + &Samplers::SamplerLinearWrapDesc, + &Samplers::SamplerPointClampDesc, + &Samplers::SamplerLinearClampDesc, + &Samplers::SamplerAnisoBorderDesc, + &Samplers::SamplerPointBorderDesc, + }; + for (uint32_t i = 0; i < NUM_INLINE_SMP; ++i) + { + auto ci = to_native_sampler_ci(*descs[i]); + vkCreateSampler(vk_device, &ci, nullptr, &inline_samplers[i]); + } + } + + Log::get() << "Vulkan device: " << p.name.c_str() + << " VRAM: " << (vram / 1024 / 1024) << " MB" << Log::endl; + } + + Device::~Device() + { + for (uint32_t i = 0; i < NUM_INLINE_SMP; ++i) + if (inline_samplers[i]) vkDestroySampler(vk_device, inline_samplers[i], nullptr); + if (cbv_srv_uav_layout) vkDestroyDescriptorSetLayout(vk_device, cbv_srv_uav_layout, nullptr); + if (sampler_layout) vkDestroyDescriptorSetLayout(vk_device, sampler_layout, nullptr); + if (vma_allocator) vmaDestroyAllocator(vma_allocator); + if (vk_device) vkDestroyDevice(vk_device, nullptr); + // Instance and debug messenger are owned by the static in HAL::init() / + // HAL.Impl.cpp — do NOT destroy them here. + } + + void Device::process_result(VkResult result, std::string_view line) const + { + if (result != VK_SUCCESS) + Log::get().crash_error(static_cast(result), line); + } + + uint Device::get_descriptor_size(DescriptorHeapType) const { return 0; } + VkDevice Device::get_native_device() const { return vk_device; } + VkResult Device::get_device_removed_reason() const { return VK_SUCCESS; } + + uint Device::Subresources(const ResourceDesc& desc) const + { + if (desc.is_buffer()) return 1; + auto t = desc.as_texture(); + return t.MipLevels * t.ArraySize; + } + + size_t Device::get_vram() + { + VkPhysicalDeviceMemoryProperties mem_props{}; + vkGetPhysicalDeviceMemoryProperties(vk_physical, &mem_props); + size_t total = 0; + for (uint32_t i = 0; i < mem_props.memoryHeapCount; ++i) + if (mem_props.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + total += mem_props.memoryHeaps[i].size; + return total / 1024 / 1024; + } + + ResourceAllocationInfo Device::get_alloc_info(const ResourceDesc& desc) + { + auto it = alloc_info.find(desc); + if (it != alloc_info.end()) return it->second; + + ResourceAllocationInfo result{}; + + if (desc.is_buffer()) + { + VkBufferCreateInfo bci{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bci.size = desc.as_buffer().SizeInBytes; + bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + + VkMemoryRequirements2 req{ VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 }; + VkDeviceBufferMemoryRequirements info{ VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS }; + info.pCreateInfo = &bci; + vkGetDeviceBufferMemoryRequirements(vk_device, &info, &req); + + result.size = req.memoryRequirements.size; + result.alignment = req.memoryRequirements.alignment; + result.flags = HeapFlags::BUFFERS_ONLY; + } + else if (desc.is_texture()) + { + auto& t = desc.as_texture(); + VkImageCreateInfo ici{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; + ici.imageType = t.is3D() ? VK_IMAGE_TYPE_3D : + t.is1D() ? VK_IMAGE_TYPE_1D : VK_IMAGE_TYPE_2D; + ici.format = to_native(t.Format); + ici.extent = { t.Dimensions.x, + t.is1D() ? 1u : t.Dimensions.y, + t.is3D() ? t.Dimensions.z : 1u }; + // MipLevels=0 means "full chain" (resolved the same way in + // Resource::init); vkGetDeviceImageMemoryRequirements requires >= 1. + ici.mipLevels = t.MipLevels; + if (ici.mipLevels == 0) + { + uint max_dim = std::max({ t.Dimensions.x, + t.is1D() ? 1u : t.Dimensions.y, + t.is3D() ? t.Dimensions.z : 1u }); + ici.mipLevels = max_dim > 0u + ? static_cast(std::floor(std::log2( + static_cast(max_dim)))) + 1u + : 1u; + } + ici.arrayLayers = t.ArraySize; + ici.samples = VK_SAMPLE_COUNT_1_BIT; + // Keep in sync with Resource::init — requirements must be queried + // for the same usage the image is actually created with. + ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT + | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + if (check(desc.Flags & ResFlags::UnorderedAccess)) + ici.usage |= VK_IMAGE_USAGE_STORAGE_BIT; + if (check(desc.Flags & ResFlags::RenderTarget)) + ici.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + if (check(desc.Flags & ResFlags::DepthStencil)) + ici.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + VkMemoryRequirements2 req{ VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 }; + VkDeviceImageMemoryRequirements info{ VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS }; + info.pCreateInfo = &ici; + vkGetDeviceImageMemoryRequirements(vk_device, &info, &req); + + result.size = req.memoryRequirements.size; + result.alignment = req.memoryRequirements.alignment; + result.flags = check(desc.Flags & (ResFlags::RenderTarget | ResFlags::DepthStencil)) + ? HeapFlags::RTDS_ONLY : HeapFlags::TEXTURES_ONLY; + } + else + { + result.size = 0; result.alignment = 256; + result.flags = HeapFlags::NONE; + } + + alloc_info[desc] = result; + return result; + } + + RaytracingPrebuildInfo Device::calculateBuffers(const RaytracingBuildDescBottomInputs&) { return {}; } + RaytracingPrebuildInfo Device::calculateBuffers(const RaytracingBuildDescTopInputs&) { return {}; } + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Device.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Device.ixx new file mode 100644 index 00000000..56091cde --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Device.ixx @@ -0,0 +1,142 @@ +export module HAL:API.Device; + +import stl.core; +import vulkan; +import Core; + +import :Types; +import :Sampler; +import :Utils; +import :Adapter; + +using namespace HAL; + +// Forward declarations for HAL-layer classes that live outside namespace API +// but must access protected API::Device fields (e.g. via static_cast). +// Full definitions live in their own partitions; only names needed here. +namespace HAL +{ + class Heap; + class SwapChain; + class CommandAllocator; +} + +export namespace HAL +{ + struct DeviceDesc + { + HAL::Adapter::ptr adapter; + }; + + struct DeviceProperties + { + std::string name; + bool rtx = false; + bool mesh_shader = false; + bool full_bindless = false; + bool direct_gpu_upload_heap = false; + bool work_graph = false; + // Vulkan: VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment. + // D3D12: 1 (no alignment constraint on StructuredBuffer FirstElement). + // Used by callers to compute lcm(sizeof(T), this) for place_data alignment. + uint32_t min_storage_buffer_offset_alignment = 1; + }; + + namespace API + { + class Device + { + std::map alloc_info; + + // API-namespace sibling classes access fields directly (same module, + // same namespace — friend grants protected access cleanly). + friend class Resource; + friend class Queue; + + // HAL-layer wrappers (namespace HAL, not API) that cast to API::Device + // and touch Vulkan internals. Forward-declared above. + friend class HAL::Heap; + friend class HAL::SwapChain; + friend class HAL::CommandAllocator; + + protected: + void init(DeviceDesc& desc); + virtual ~Device(); + + // ---- Vulkan objects (backend-internal) --------------------------- + // vk_instance is owned by HAL::init() (HAL.Impl.cpp static). + VkInstance vk_instance = VK_NULL_HANDLE; + VkPhysicalDevice vk_physical = VK_NULL_HANDLE; + VkDevice vk_device = VK_NULL_HANDLE; + VmaAllocator vma_allocator = VK_NULL_HANDLE; + + // Queue family indices: DIRECT=0, COMPUTE=1, COPY=2. + uint32_t queue_families[3] = { + static_cast(-1), + static_cast(-1), + static_cast(-1) + }; + + // Descriptor sizes — interface compat; always 0 in Vulkan. + enum_array descriptor_sizes; + + // Global bindless descriptor set layouts (created in init()). + VkDescriptorSetLayout cbv_srv_uav_layout = VK_NULL_HANDLE; + VkDescriptorSetLayout sampler_layout = VK_NULL_HANDLE; + + // Inline static samplers s0..s4 (FrameLayout.h, binding 384+N in set 0). + // Created in init(); written into every CBV_SRV_UAV DescriptorHeap set. + static constexpr uint32_t NUM_INLINE_SMP = 5; + VkSampler inline_samplers[NUM_INLINE_SMP] = {}; + + // ---- Pending initial-layout transitions -------------------------- + // D3D12 creates resources directly in their initial state; Vulkan + // images always start in UNDEFINED. The HAL state manager assumes + // the D3D12 model (resources rest in their initial layout between + // command lists), so every freshly created VkImage queues a one-time + // UNDEFINED -> initial_layout barrier here. The next Queue::execute + // flushes the batch in a small command buffer submitted ahead of the + // real work, making the state manager's assumption true. + std::mutex pending_init_mutex; + std::vector pending_init_barriers; + + public: + using ptr = std::shared_ptr; + + // ---- HAL contract (public interface) ----------------------------- + void process_result(VkResult result, std::string_view line) const; + uint get_descriptor_size(DescriptorHeapType type) const; + VkDevice get_native_device() const; // returns vk_device + VkResult get_device_removed_reason() const; + + // ---- Backend accessors (used by sibling Vulkan modules) ---------- + // Cross-partition friend declarations are not reliably enforced by + // MSVC, so we expose the Vulkan internals through thin inline getters + // rather than relying on friend access across partition boundaries. + VmaAllocator get_vma_allocator() const noexcept { return vma_allocator; } + VkPhysicalDevice get_vk_physical_dev() const noexcept { return vk_physical; } + uint32_t get_queue_family(int i) const noexcept { return queue_families[i]; } + + // ---- Global bindless descriptor set layouts ---------------------- + // Created once in init(); shared by DescriptorHeap and RootSignature. + VkDescriptorSetLayout get_cbv_srv_uav_layout() const noexcept { return cbv_srv_uav_layout; } + VkDescriptorSetLayout get_sampler_layout() const noexcept { return sampler_layout; } + const VkSampler* get_inline_samplers() const noexcept { return inline_samplers; } + + // Queue a one-time UNDEFINED -> layout transition for a new image. + // Flushed by the next Queue::execute on whichever queue submits first + // (cross-queue first use is safe: queues sharing a resource are + // already fence-synchronized by the FrameGraph). + void queue_initial_transition(VkImage image, VkImageLayout layout, VkImageAspectFlags aspect); + void cancel_pending_init_transition(VkImage image); + std::vector take_pending_init_transitions(); + + ResourceAllocationInfo get_alloc_info(const ResourceDesc& desc); + uint Subresources(const ResourceDesc& desc) const; + size_t get_vram(); + + RaytracingPrebuildInfo calculateBuffers(const RaytracingBuildDescBottomInputs& desc); + RaytracingPrebuildInfo calculateBuffers(const RaytracingBuildDescTopInputs& desc); + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Fence.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Fence.cpp new file mode 100644 index 00000000..d9ff50bd --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Fence.cpp @@ -0,0 +1,70 @@ +module HAL:Fence; + +import vulkan; +import Core; +import :Device; + +// Vulkan implementation of the HAL::Fence / HAL::Event wrappers using a +// VK_KHR_timeline_semaphore. This is inherently native code (no shared +// orchestration), so it lives per-backend — the D3D12 equivalent is +// D3D12/HAL.D3D12.Fence.cpp. + +namespace HAL +{ + // On Vulkan we synchronise via timeline semaphores (vkWaitSemaphores), + // so the Win32-event abstraction is unused — these are no-ops. + Event::Event() {} + Event::~Event() {} + void Event::wait() {} + + Fence::~Fence() + { + if (timeline_semaphore != VK_NULL_HANDLE && device != VK_NULL_HANDLE) + { + vkDestroySemaphore(device, timeline_semaphore, nullptr); + timeline_semaphore = VK_NULL_HANDLE; + } + } + + Fence::Fence(Device& device_) + { + device = device_.get_native_device(); + + VkSemaphoreTypeCreateInfo type_info{ VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; + type_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; + type_info.initialValue = 0; + + VkSemaphoreCreateInfo info{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + info.pNext = &type_info; + + vkCreateSemaphore(device, &info, nullptr, &timeline_semaphore); + } + + void Fence::signal(CounterType value) + { + // Host-side (CPU) signal of the timeline semaphore. + VkSemaphoreSignalInfo info{ VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO }; + info.semaphore = timeline_semaphore; + info.value = value; + vkSignalSemaphore(device, &info); + } + + Fence::CounterType Fence::get_completed_value() const + { + uint64_t value = 0; + vkGetSemaphoreCounterValue(device, timeline_semaphore, &value); + return value; + } + + void Fence::wait(CounterType value) const + { + if (get_completed_value() >= value) return; + + PROFILE(L"FenceWait"); + VkSemaphoreWaitInfo info{ VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO }; + info.semaphoreCount = 1; + info.pSemaphores = &timeline_semaphore; + info.pValues = &value; + vkWaitSemaphores(device, &info, std::numeric_limits::max()); + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Fence.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Fence.ixx new file mode 100644 index 00000000..3381608a --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Fence.ixx @@ -0,0 +1,35 @@ +export module HAL:API.Fence; +import vulkan; + +export namespace HAL +{ + namespace API + { + class Fence + { + // Queue signals / waits on the timeline semaphore directly. + friend class Queue; + + protected: + VkSemaphore timeline_semaphore = VK_NULL_HANDLE; + VkDevice device = VK_NULL_HANDLE; + + public: + using CounterType = uint64_t; + }; + + class Event + { + friend class Queue; + + protected: + // CPU-side wait uses a binary VkFence on Vulkan. + VkFence vk_fence = VK_NULL_HANDLE; + // Kept for interface compat with common HAL code. + HANDLE m_fenceEvent = nullptr; + + public: + virtual ~Event() = default; + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Format.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Format.cpp new file mode 100644 index 00000000..475a3039 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Format.cpp @@ -0,0 +1,330 @@ +module HAL:Format; + +import :Format; +import Core; + +// Backend-specific Format query methods. +// Mirrors D3D12/HAL.Format.cpp. These switch on the HAL::Format::Formats enum +// (whose ordering matches DXGI), so the logic is backend-portable — only the +// shader-component-mapping constant differs (it is a D3D12 concept; on Vulkan +// component swizzle is expressed per-view, so we return the same opaque value +// the rest of the HAL code treats as a token). + +namespace HAL +{ + bool Format::is_shader_visible() const + { + switch (native_format) + { + case D32_FLOAT_S8X24_UINT: + case R32_FLOAT_X8X24_TYPELESS: + case X32_TYPELESS_G8X24_UINT: + case D24_UNORM_S8_UINT: + case R24_UNORM_X8_TYPELESS: + case X24_TYPELESS_G8_UINT: + return false; + default: + return true; + } + } + + bool Format::is_srgb() const + { + switch (native_format) + { + case R8G8B8A8_UNORM_SRGB: + case BC1_UNORM_SRGB: + case BC2_UNORM_SRGB: + case BC3_UNORM_SRGB: + case B8G8R8A8_UNORM_SRGB: + case B8G8R8X8_UNORM_SRGB: + case BC7_UNORM_SRGB: + return true; + default: + return false; + } + } + + bool Format::is_blendable() const + { + switch (native_format) + { + case R32G32B32A32_FLOAT: + case R32G32B32_FLOAT: + case R16G16B16A16_FLOAT: + case R16G16B16A16_UNORM: + case R16G16B16A16_SNORM: + case R32G32_FLOAT: + case R10G10B10A2_UNORM: + case R11G11B10_FLOAT: + case R8G8B8A8_UNORM: + case R8G8B8A8_UNORM_SRGB: + case R8G8B8A8_SNORM: + case R16G16_FLOAT: + case R16G16_UNORM: + case R16G16_SNORM: + case R32_FLOAT: + case R8G8_UNORM: + case R8G8_SNORM: + case R16_FLOAT: + case R16_UNORM: + case R16_SNORM: + case R8_UNORM: + case R8_SNORM: + case A8_UNORM: + case R8G8_B8G8_UNORM: + case G8R8_G8B8_UNORM: + case B5G6R5_UNORM: + case B5G5R5A1_UNORM: + case B8G8R8A8_UNORM: + case B8G8R8X8_UNORM: + case B8G8R8A8_UNORM_SRGB: + case B8G8R8X8_UNORM_SRGB: + return true; + default: + return false; + } + } + + Format Format::to_dsv() const + { + switch (native_format) + { + case R32_TYPELESS: return D32_FLOAT; + case R16_TYPELESS: return D16_UNORM; + case R8_TYPELESS: return R8_TYPELESS; // oops! (matches D3D12 path) + default: return *this; + } + } + + Format Format::to_typeless() const + { + switch (native_format) + { + case R8G8B8A8_UNORM_SRGB: + case R8G8B8A8_UNORM: + case R8G8B8A8_UINT: + case R8G8B8A8_SNORM: + case R8G8B8A8_SINT: + return R8G8B8A8_TYPELESS; + default: + return *this; + } + } + + Format Format::to_srv() const + { + switch (native_format) + { + case R8G8B8A8_TYPELESS: return R8G8B8A8_UNORM; + case R32_TYPELESS: return R32_FLOAT; + case R16_TYPELESS: return R16_FLOAT; + case R8_TYPELESS: return R8_UNORM; + default: return *this; + } + } + + uint Format::size() const + { + switch (native_format) + { + case R32G32B32A32_TYPELESS: + case R32G32B32A32_FLOAT: + case R32G32B32A32_UINT: + case R32G32B32A32_SINT: + return 128; + + case R32G32B32_TYPELESS: + case R32G32B32_FLOAT: + case R32G32B32_UINT: + case R32G32B32_SINT: + return 96; + + case R16G16B16A16_TYPELESS: + case R16G16B16A16_FLOAT: + case R16G16B16A16_UNORM: + case R16G16B16A16_UINT: + case R16G16B16A16_SNORM: + case R16G16B16A16_SINT: + case R32G32_TYPELESS: + case R32G32_FLOAT: + case R32G32_UINT: + case R32G32_SINT: + case R32G8X24_TYPELESS: + case D32_FLOAT_S8X24_UINT: + case R32_FLOAT_X8X24_TYPELESS: + case X32_TYPELESS_G8X24_UINT: + return 64; + + case R10G10B10A2_TYPELESS: + case R10G10B10A2_UNORM: + case R10G10B10A2_UINT: + case R11G11B10_FLOAT: + case R8G8B8A8_TYPELESS: + case R8G8B8A8_UNORM: + case R8G8B8A8_UNORM_SRGB: + case R8G8B8A8_UINT: + case R8G8B8A8_SNORM: + case R8G8B8A8_SINT: + case R16G16_TYPELESS: + case R16G16_FLOAT: + case R16G16_UNORM: + case R16G16_UINT: + case R16G16_SNORM: + case R16G16_SINT: + case R32_TYPELESS: + case D32_FLOAT: + case R32_FLOAT: + case R32_UINT: + case R32_SINT: + case R24G8_TYPELESS: + case D24_UNORM_S8_UINT: + case R24_UNORM_X8_TYPELESS: + case X24_TYPELESS_G8_UINT: + case R9G9B9E5_SHAREDEXP: + case R8G8_B8G8_UNORM: + case G8R8_G8B8_UNORM: + case B8G8R8A8_UNORM: + case B8G8R8X8_UNORM: + case R10G10B10_XR_BIAS_A2_UNORM: + case B8G8R8A8_TYPELESS: + case B8G8R8A8_UNORM_SRGB: + case B8G8R8X8_TYPELESS: + case B8G8R8X8_UNORM_SRGB: + return 32; + + case R8G8_TYPELESS: + case R8G8_UNORM: + case R8G8_UINT: + case R8G8_SNORM: + case R8G8_SINT: + case R16_TYPELESS: + case R16_FLOAT: + case D16_UNORM: + case R16_UNORM: + case R16_UINT: + case R16_SNORM: + case R16_SINT: + case B5G6R5_UNORM: + case B5G5R5A1_UNORM: + return 16; + + case R8_TYPELESS: + case R8_UNORM: + case R8_UINT: + case R8_SNORM: + case R8_SINT: + case A8_UNORM: + return 8; + + case R1_UNORM: + return 1; + + case BC1_TYPELESS: + case BC1_UNORM: + case BC1_UNORM_SRGB: + return 4; + + case BC2_TYPELESS: + case BC2_UNORM: + case BC2_UNORM_SRGB: + case BC3_TYPELESS: + case BC3_UNORM: + case BC3_UNORM_SRGB: + case BC4_TYPELESS: + case BC4_UNORM: + case BC4_SNORM: + case BC5_TYPELESS: + case BC5_UNORM: + case BC5_SNORM: + case BC6H_TYPELESS: + case BC6H_UF16: + case BC6H_SF16: + case BC7_TYPELESS: + case BC7_UNORM: + case BC7_UNORM_SRGB: + return 8; + + default: + ASSERT(FALSE); + return 0; + } + } + + uint Format::get_default_mapping() const + { + // D3D12's DEFAULT_SHADER_4_COMPONENT_MAPPING literal (0x1688). On Vulkan + // component swizzle is per-view; this token is consumed by view code, + // which the Vulkan backend reinterprets in Phase 4. + return 0x1688u; + } + + SurfaceInfo Format::surface_info(uint2 size) const + { + uint64 numBytes = 0; + uint rowBytes = 0; + uint numRows = 0; + + bool bc = false; + bool packed = false; + uint bcnumBytesPerBlock = 0; + + switch (native_format) + { + case BC1_TYPELESS: + case BC1_UNORM: + case BC1_UNORM_SRGB: + case BC4_TYPELESS: + case BC4_UNORM: + case BC4_SNORM: + bc = true; bcnumBytesPerBlock = 8; break; + + case BC2_TYPELESS: + case BC2_UNORM: + case BC2_UNORM_SRGB: + case BC3_TYPELESS: + case BC3_UNORM: + case BC3_UNORM_SRGB: + case BC5_TYPELESS: + case BC5_UNORM: + case BC5_SNORM: + case BC6H_TYPELESS: + case BC6H_UF16: + case BC6H_SF16: + case BC7_TYPELESS: + case BC7_UNORM: + case BC7_UNORM_SRGB: + bc = true; bcnumBytesPerBlock = 16; break; + + case R8G8_B8G8_UNORM: + case G8R8_G8B8_UNORM: + packed = true; break; + default: + break; + } + + if (bc) + { + uint numBlocksWide = 0; + if (size.x > 0) numBlocksWide = std::max(1, (size.x + 3) / 4); + uint numBlocksHigh = 0; + if (size.y > 0) numBlocksHigh = std::max(1, (size.y + 3) / 4); + rowBytes = numBlocksWide * bcnumBytesPerBlock; + numRows = numBlocksHigh; + } + else if (packed) + { + rowBytes = ((size.x + 1) >> 1) * 4; + numRows = size.y; + } + else + { + uint bpp = this->size(); + rowBytes = (size.x * bpp + 7) / 8; + numRows = size.y; + } + + numBytes = rowBytes * numRows; + return { numBytes, rowBytes, numRows }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Heap.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Heap.cpp new file mode 100644 index 00000000..7a36eece --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Heap.cpp @@ -0,0 +1,93 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +#include +module HAL:Heap; + +import HAL; +import Core; + +namespace HAL +{ + Heap::Heap(Device& device, const HeapDesc& desc) : desc(desc) + { + auto& api_dev = static_cast(device); + + // For UPLOAD and READBACK heaps, allocate a single host-visible VMA + // buffer covering the full heap size, then persistently map it. + // The HAL::Buffer wrapper placed at offset 0 gets buffer_data directly + // from cpu_address so update_buffer / place_data work without stalls. + if (api_dev.vma_allocator && + (desc.Type == HeapType::UPLOAD || desc.Type == HeapType::READBACK)) + { + VkBufferCreateInfo bci{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bci.size = desc.Size; + // Placed sub-allocations (CBVs, vertex/index buffers, indirect args, + // texture staging) all share this single heap buffer, so it must + // declare every usage those slices can take on — matching the + // committed-buffer path in HAL.Vulkan.Resource.cpp. + bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT + | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; + + VmaAllocationCreateInfo vma_ci{}; + vma_ci.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT + | VMA_ALLOCATION_CREATE_MAPPED_BIT; + vma_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST; + + VkBuffer vk_buf = VK_NULL_HANDLE; + VmaAllocationInfo alloc_info{}; + VmaAllocation alloc = VK_NULL_HANDLE; + vmaCreateBuffer(api_dev.vma_allocator, &bci, &vma_ci, &vk_buf, &alloc, &alloc_info); + + if (alloc_info.pMappedData) + { + vma_allocation = alloc; + vma_allocator_ref = api_dev.vma_allocator; + cpu_address = static_cast(alloc_info.pMappedData); + + // Buffer device address for GPU-side access + VkBufferDeviceAddressInfo dai{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO }; + dai.buffer = vk_buf; + gpu_address = vkGetBufferDeviceAddress(api_dev.vk_device, &dai); + + // Store the VkBuffer handle via the allocation so the destructor can free it. + // We abuse vk_memory to stash the VkBuffer (both are opaque handles). + vk_memory = alloc_info.deviceMemory; + // Keep the VkBuffer alive for the heap lifetime; store in a side channel. + heap_vk_buffer = vk_buf; + } + } + + // Create the HAL::Buffer wrapper at offset 0 of this heap. + // Resource::init(PlacementAddress) will read cpu_address + gpu_address + // from this Heap object and store them as mapped_data / address on the + // resource. Buffer::init() then sets buffer_data = get_cpu_mapping(). + buffer.reset(new HAL::Buffer(device, ResourceDesc::Buffer(desc.Size), PlacementAddress{ this, 0 })); + + if (desc.Type == HeapType::UPLOAD) + buffer->set_name("Upload Heap Buffer"); + else if (desc.Type == HeapType::READBACK) + buffer->set_name("Readback Heap Buffer"); + else + buffer->set_name("GPU Heap Buffer"); + } + + std::span Heap::get_data() + { + return std::span(cpu_address, cpu_address ? desc.Size : 0); + } + + namespace API + { + Heap::~Heap() + { + if (vma_allocation && vma_allocator_ref) + vmaDestroyBuffer(vma_allocator_ref, heap_vk_buffer, vma_allocation); + } + + GPUAddressPtr Heap::get_address() const { return gpu_address; } + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Heap.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Heap.ixx new file mode 100644 index 00000000..a6868b11 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Heap.ixx @@ -0,0 +1,39 @@ +export module HAL:API.Heap; +import vulkan; +import Core; +import :Types; +import :Sampler; +import :Utils; +import :API.Device; + +export namespace HAL +{ + namespace API + { + class Heap + { + protected: + // VMA allocation backing this heap — backend-internal, not part of + // the common HAL contract. Only HAL::Heap (derived class) touches these. + VmaAllocation vma_allocation = VK_NULL_HANDLE; + VkDeviceMemory vk_memory = VK_NULL_HANDLE; + VkBuffer heap_vk_buffer = VK_NULL_HANDLE; + VmaAllocator vma_allocator_ref = VK_NULL_HANDLE; + + public: + virtual ~Heap(); + uint64_t get_address() const; + + // The single VkBuffer backing a CPU-visible (UPLOAD/READBACK) heap. + // Placed resources share it and address their slice via resource_offset. + VkBuffer get_vk_buffer() const { return heap_vk_buffer; } + + // ---- Placement interface (public) -------------------------------- + // These are read by Resource::init(PlacementAddress) to derive the + // CPU mapping and GPU address for placed resources (mirrors D3D12's + // cpu_buffer->GetGPUVirtualAddress() / Map() pattern). + std::byte* cpu_address = nullptr; + uint64_t gpu_address = 0; + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.IndirectCommand.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.IndirectCommand.cpp new file mode 100644 index 00000000..eba64f79 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.IndirectCommand.cpp @@ -0,0 +1,3 @@ +module HAL:API.IndirectCommand; +// Phase 4: implement real Vulkan indirect draw/dispatch buffer creation. +// Phase 0: all logic is inline in the header (templates). diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.IndirectCommand.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.IndirectCommand.ixx new file mode 100644 index 00000000..9979805d --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.IndirectCommand.ixx @@ -0,0 +1,66 @@ +export module HAL:API.IndirectCommand; + +import vulkan; +import :Types; +import :Utils; +import :RootSignature; +import :Slots; + +// Vulkan indirect command — VkDrawIndexedIndirectCommand / VkDispatchIndirectCommand. +// For Phase 0: stub that mirrors the D3D12 IndirectCommand interface so +// common code that creates IndirectCommands compiles unchanged. +// Phase 4: implement real vkCmdDrawIndexedIndirect / vkCmdDispatchIndirect. + +namespace HAL +{ + // Vulkan-side helpers (equivalent to D3D12's create_indirect_for chain) + // These keep the same API so HAL::IndirectCommand::create_command + // can be used without #ifdefs. +} + +export namespace HAL +{ + class IndirectCommand + { + IndirectCommand(const UsedSlots& slots) : slots(slots) {} + public: + UsedSlots slots; + + IndirectCommand() = default; + + template + static void process_one(UsedSlots& slots, uint& total_size) + { + if constexpr (HasID) + { + slots.merge(T::ID); + total_size += sizeof(uint); + } + else + total_size += sizeof(Underlying); + } + + template + static IndirectCommand create_command(Device& /*device*/, + RootSignature* /*layout*/ = nullptr) + { + UsedSlots slots; + uint total_size = 0; + (process_one(slots, total_size), ...); + // Phase 4: create real Vulkan indirect buffer layout. + return IndirectCommand(slots); + } + + template + static IndirectCommand create_command_layout(Device& device) + { + return create_command(device, nullptr); + } + + template + static IndirectCommand create_command_layout(Device& device, auto layout) + { + return create_command(device, nullptr); + } + }; +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.PipelineState.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.PipelineState.cpp new file mode 100644 index 00000000..af529558 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.PipelineState.cpp @@ -0,0 +1,411 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:PipelineState; + +import vulkan; +import Core; +import :Types; +import :Utils; +import :Device; +import :RootSignature; +import :Shader; +import :PipelineState; +import :API.Device; + +// Vulkan Phase 4 — real VkGraphicsPipeline / VkComputePipeline creation. + +namespace +{ + // ---- Conversion helpers ------------------------------------------------ + + VkPrimitiveTopology to_vk_topology(HAL::PrimitiveTopologyType t, + HAL::PrimitiveTopologyFeed feed) + { + using T = HAL::PrimitiveTopologyType; + using F = HAL::PrimitiveTopologyFeed; + if (t == T::POINT) return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + if (t == T::LINE) + return feed == F::STRIP ? VK_PRIMITIVE_TOPOLOGY_LINE_STRIP + : VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + if (t == T::PATCH) return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + // TRIANGLE (default) + return feed == F::STRIP ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP + : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + } + + VkCullModeFlagBits to_vk_cull(HAL::CullMode c) + { + switch (c) + { + case HAL::CullMode::None: return VK_CULL_MODE_NONE; + case HAL::CullMode::Front: return VK_CULL_MODE_FRONT_BIT; + default: return VK_CULL_MODE_BACK_BIT; + } + } + + VkPolygonMode to_vk_fill(HAL::FillMode f) + { + return f == HAL::FillMode::Wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL; + } + + VkBlendFactor to_vk_blend(HAL::Blend b) + { + switch (b) + { + case HAL::Blend::Zero: return VK_BLEND_FACTOR_ZERO; + case HAL::Blend::One: return VK_BLEND_FACTOR_ONE; + case HAL::Blend::SrcAlpha: return VK_BLEND_FACTOR_SRC_ALPHA; + case HAL::Blend::InvSrcAlpha: return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + case HAL::Blend::DstAlpha: return VK_BLEND_FACTOR_DST_ALPHA; + case HAL::Blend::InvDstAlpha: return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; + case HAL::Blend::SrcColor: return VK_BLEND_FACTOR_SRC_COLOR; + case HAL::Blend::InvSrcColor: return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; + case HAL::Blend::DestColor: return VK_BLEND_FACTOR_DST_COLOR; + case HAL::Blend::InvDestColor: return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; + case HAL::Blend::SrcAlphaSat: return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE; + case HAL::Blend::BlendFactor: return VK_BLEND_FACTOR_CONSTANT_COLOR; + case HAL::Blend::InvBlendFactor: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; + default: return VK_BLEND_FACTOR_ONE; + } + } + + VkCompareOp to_vk_cmp(HAL::ComparisonFunc f) + { + switch (f) + { + case HAL::ComparisonFunc::NEVER: return VK_COMPARE_OP_NEVER; + case HAL::ComparisonFunc::LESS: return VK_COMPARE_OP_LESS; + case HAL::ComparisonFunc::EQUAL: return VK_COMPARE_OP_EQUAL; + case HAL::ComparisonFunc::LESS_EQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL; + case HAL::ComparisonFunc::GREATER: return VK_COMPARE_OP_GREATER; + case HAL::ComparisonFunc::NOT_EQUAL: return VK_COMPARE_OP_NOT_EQUAL; + case HAL::ComparisonFunc::GREATER_EQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL; + default: return VK_COMPARE_OP_ALWAYS; + } + } + + VkStencilOp to_vk_stencil(HAL::StencilOp op) + { + switch (op) + { + case HAL::StencilOp::Keep: return VK_STENCIL_OP_KEEP; + case HAL::StencilOp::Zero: return VK_STENCIL_OP_ZERO; + case HAL::StencilOp::Replace: return VK_STENCIL_OP_REPLACE; + case HAL::StencilOp::IncrementSat: return VK_STENCIL_OP_INCREMENT_AND_CLAMP; + case HAL::StencilOp::DecrementSat: return VK_STENCIL_OP_DECREMENT_AND_CLAMP; + case HAL::StencilOp::Invert: return VK_STENCIL_OP_INVERT; + case HAL::StencilOp::Increment: return VK_STENCIL_OP_INCREMENT_AND_WRAP; + default: return VK_STENCIL_OP_DECREMENT_AND_WRAP; + } + } + + // Create a VkShaderModule from a SPIR-V blob. + VkShaderModule make_shader_module(VkDevice dev, const binary& blob) + { + if (blob.empty()) return VK_NULL_HANDLE; + if (blob.size() % 4 != 0) return VK_NULL_HANDLE; // SPIR-V must be 4-byte aligned + + VkShaderModuleCreateInfo ci{ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; + ci.codeSize = blob.size(); + ci.pCode = reinterpret_cast(blob.data()); + + VkShaderModule module = VK_NULL_HANDLE; + vkCreateShaderModule(dev, &ci, nullptr, &module); + return module; + } +} + +namespace HAL::API +{ + TrackedPipeline::~TrackedPipeline() + { + if (vk_pipeline != VK_NULL_HANDLE && vk_device != VK_NULL_HANDLE) + vkDestroyPipeline(vk_device, vk_pipeline, nullptr); + } +} + +namespace HAL +{ + void PipelineState::on_change() + { + tracked_info.reset(new API::TrackedPipeline()); + name = desc.name; + + // root_signature is set before on_change() is called (see HAL.PipelineState.cpp). + if (!root_signature) return; + + auto& api_dev = static_cast(root_signature->get_device()); + VkDevice vk_dev = api_dev.get_native_device(); + if (vk_dev == VK_NULL_HANDLE) return; + + VkPipelineLayout layout = static_cast(*root_signature) + .get_vk_pipeline_layout(); + if (layout == VK_NULL_HANDLE) return; + + // ---- Shader modules ------------------------------------------------- + auto make_stage = [&](VkShaderStageFlagBits stage, + const binary& blob, + const char* entry = "main") -> VkPipelineShaderStageCreateInfo + { + VkPipelineShaderStageCreateInfo si{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; + si.stage = stage; + si.module = make_shader_module(vk_dev, blob); + si.pName = entry; + return si; + }; + + std::vector stages; + std::vector modules_to_destroy; + auto add_stage = [&](VkShaderStageFlagBits stage, auto& shader_ptr) + { + if (!shader_ptr) return; + const auto& blob = shader_ptr->get_blob(); + if (blob.empty()) return; + // Use the entry point name from compilation (-E flag), e.g. "VS", "PS". + const auto& ep = shader_ptr->blob.entry_point; + const char* entry = ep.empty() ? "main" : ep.c_str(); + auto si = make_stage(stage, blob, entry); + if (si.module != VK_NULL_HANDLE) + { + stages.push_back(si); + modules_to_destroy.push_back(si.module); + } + }; + + add_stage(VK_SHADER_STAGE_VERTEX_BIT, desc.vertex); + add_stage(VK_SHADER_STAGE_FRAGMENT_BIT, desc.pixel); + add_stage(VK_SHADER_STAGE_GEOMETRY_BIT, desc.geometry); + add_stage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, desc.hull); + add_stage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, desc.domain); + add_stage(VK_SHADER_STAGE_MESH_BIT_EXT, desc.mesh); + + if (stages.empty()) return; // no compiled shaders yet + + // ---- Vertex input — vertex-pulling; no VS input attributes --------- + VkPipelineVertexInputStateCreateInfo vi{ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; + + // ---- Input assembly ------------------------------------------------- + VkPipelineInputAssemblyStateCreateInfo ia{ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + ia.topology = to_vk_topology(desc.topology, PrimitiveTopologyFeed::LIST); + + // ---- Rasterization -------------------------------------------------- + VkPipelineRasterizationStateCreateInfo raster{ + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + raster.polygonMode = to_vk_fill(desc.rasterizer.fill_mode); + raster.cullMode = to_vk_cull(desc.rasterizer.cull_mode); + // The negative-height viewport maps NDC Y-up to framebuffer Y-down, identical to + // D3D12's implicit viewport Y-flip. Both APIs then compute winding via the same + // shoelace formula in Y-down space: positive area = CW = front-facing under D3D12's + // default (FrontCounterClockwise=FALSE). VK_FRONT_FACE_CLOCKWISE also treats + // positive area as front-facing, so it is the correct match for D3D12 semantics. + raster.frontFace = VK_FRONT_FACE_CLOCKWISE; + raster.lineWidth = 1.0f; + + // Conservative rasterization (Phase 5: check extension availability) + // raster.conservativeRasterizationMode = desc.rasterizer.conservative ? + // VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; + + // ---- Multisample (1× for now) --------------------------------------- + VkPipelineMultisampleStateCreateInfo ms{ + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; + ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + // ---- Depth/stencil -------------------------------------------------- + VkPipelineDepthStencilStateCreateInfo ds{ + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + ds.depthTestEnable = desc.rtv.enable_depth ? VK_TRUE : VK_FALSE; + ds.depthWriteEnable = desc.rtv.enable_depth_write ? VK_TRUE : VK_FALSE; + ds.depthCompareOp = to_vk_cmp(desc.rtv.func); + ds.stencilTestEnable = desc.rtv.enable_stencil ? VK_TRUE : VK_FALSE; + if (ds.stencilTestEnable) + { + auto fill_stencil = [](const HAL::StencilDesc& s, uint8_t read_mask, + uint8_t write_mask) -> VkStencilOpState + { + VkStencilOpState r{}; + r.failOp = to_vk_stencil(s.StencilFailOp); + r.passOp = to_vk_stencil(s.StencilPassOp); + r.depthFailOp = to_vk_stencil(s.StencilDepthFailOp); + r.compareOp = to_vk_cmp(s.StencilFunc); + r.compareMask = read_mask; + r.writeMask = write_mask; + return r; + }; + ds.front = fill_stencil(desc.rtv.stencil_desc, + desc.rtv.stencil_read_mask, + desc.rtv.stencil_write_mask); + ds.back = ds.front; + } + + // ---- Blend ---------------------------------------------------------- + std::vector blend_attachments; + const uint32_t rt_count = static_cast(desc.rtv.rtv_formats.size()); + blend_attachments.reserve(rt_count); + for (uint32_t ri = 0; ri < rt_count; ++ri) + { + const auto& rt_blend = desc.blend.independ_blend + ? desc.blend.render_target[ri] + : desc.blend.render_target[0]; + + VkPipelineColorBlendAttachmentState att{}; + att.blendEnable = rt_blend.enabled ? VK_TRUE : VK_FALSE; + att.srcColorBlendFactor = to_vk_blend(rt_blend.source); + att.dstColorBlendFactor = to_vk_blend(rt_blend.dest); + att.colorBlendOp = VK_BLEND_OP_ADD; + att.srcAlphaBlendFactor = to_vk_blend(rt_blend.source_alpha); + att.dstAlphaBlendFactor = to_vk_blend(rt_blend.dest_alpha); + att.alphaBlendOp = VK_BLEND_OP_ADD; + att.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + blend_attachments.push_back(att); + } + + VkPipelineColorBlendStateCreateInfo blend_ci{ + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; + blend_ci.attachmentCount = static_cast(blend_attachments.size()); + blend_ci.pAttachments = blend_attachments.data(); + + // ---- Viewport (dynamic) -------------------------------------------- + VkPipelineViewportStateCreateInfo viewport{ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + viewport.viewportCount = 1; + viewport.scissorCount = 1; + + // ---- Dynamic state -------------------------------------------------- + const VkDynamicState dyn_states[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_STENCIL_REFERENCE, + // Topology is set per-draw via set_topology() (mirrors D3D12's + // IASetPrimitiveTopology: PSO has topology TYPE, draw call sets LIST/STRIP). + // Promoted to Vulkan 1.3 core via VK_EXT_extended_dynamic_state. + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, + }; + VkPipelineDynamicStateCreateInfo dyn_ci{ VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + dyn_ci.dynamicStateCount = 4; + dyn_ci.pDynamicStates = dyn_states; + + // ---- Dynamic rendering attachment formats --------------------------- + std::vector color_formats; + color_formats.reserve(rt_count); + for (auto fmt : desc.rtv.rtv_formats) + color_formats.push_back(to_native(fmt)); + + VkPipelineRenderingCreateInfoKHR rendering_ci{ + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + rendering_ci.colorAttachmentCount = static_cast(color_formats.size()); + rendering_ci.pColorAttachmentFormats = color_formats.data(); + rendering_ci.depthAttachmentFormat = desc.rtv.enable_depth + ? to_native(desc.rtv.ds_format) : VK_FORMAT_UNDEFINED; + rendering_ci.stencilAttachmentFormat = (desc.rtv.enable_stencil && desc.rtv.enable_depth) + ? to_native(desc.rtv.ds_format) : VK_FORMAT_UNDEFINED; + + // ---- Tessellation state (required when hull/domain shaders are present) --- + VkPipelineTessellationStateCreateInfo tess_ci{ + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; + // Default to 3 control points (triangle patches). The actual runtime + // value is supplied via set_topology(); for now most tessellated meshes + // use triangle patches. TODO: store patch_control_points in PSO desc. + tess_ci.patchControlPoints = 3; + const bool has_tessellation = (desc.hull != nullptr) || (desc.domain != nullptr); + + // ---- Graphics pipeline --------------------------------------------- + VkGraphicsPipelineCreateInfo gp_ci{ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; + gp_ci.stageCount = static_cast(stages.size()); + gp_ci.pStages = stages.data(); + gp_ci.pVertexInputState = &vi; + gp_ci.pInputAssemblyState = &ia; + gp_ci.pTessellationState = has_tessellation ? &tess_ci : nullptr; + gp_ci.pRasterizationState = &raster; + gp_ci.pMultisampleState = &ms; + gp_ci.pDepthStencilState = &ds; + gp_ci.pColorBlendState = &blend_ci; + gp_ci.pViewportState = &viewport; + gp_ci.pDynamicState = &dyn_ci; + gp_ci.layout = layout; + gp_ci.pNext = &rendering_ci; // dynamic rendering (no render pass) + + VkPipeline pipeline = VK_NULL_HANDLE; + VkResult r = vkCreateGraphicsPipelines(vk_dev, VK_NULL_HANDLE, 1, &gp_ci, + nullptr, &pipeline); + if (r == VK_SUCCESS) + { + tracked_info->vk_pipeline = pipeline; + tracked_info->vk_device = vk_dev; + tracked_info->vk_topology = ia.topology; + } + else + Log::get() << Log::LEVEL_WARNING << "vkCreateGraphicsPipelines failed " + << name.c_str() << " code=" << static_cast(r) << Log::endl; + + // Shader modules can be destroyed after pipeline creation. + for (auto m : modules_to_destroy) + if (m != VK_NULL_HANDLE) + vkDestroyShaderModule(vk_dev, m, nullptr); + } + + void ComputePipelineState::on_change() + { + tracked_info.reset(new API::TrackedPipeline()); + name = desc.name; + + if (!root_signature || !desc.shader) return; + + auto& api_dev = static_cast(root_signature->get_device()); + VkDevice vk_dev = api_dev.get_native_device(); + if (vk_dev == VK_NULL_HANDLE) return; + + VkPipelineLayout layout = static_cast(*root_signature) + .get_vk_pipeline_layout(); + if (layout == VK_NULL_HANDLE) return; + + const auto& blob = desc.shader->get_blob(); + if (blob.empty() || blob.size() % 4 != 0) return; + + // Use the entry point name from compilation (-E flag), e.g. "CS". + const auto& ep = desc.shader->blob.entry_point; + std::string cs_entry = ep.empty() ? "main" : ep; + + VkShaderModuleCreateInfo module_ci{ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; + module_ci.codeSize = blob.size(); + module_ci.pCode = reinterpret_cast(blob.data()); + + VkShaderModule cs_module = VK_NULL_HANDLE; + vkCreateShaderModule(vk_dev, &module_ci, nullptr, &cs_module); + if (cs_module == VK_NULL_HANDLE) return; + + VkComputePipelineCreateInfo cp_ci{ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; + cp_ci.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + cp_ci.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; + cp_ci.stage.module = cs_module; + cp_ci.stage.pName = cs_entry.c_str(); + cp_ci.layout = layout; + + VkPipeline pipeline = VK_NULL_HANDLE; + vkCreateComputePipelines(vk_dev, VK_NULL_HANDLE, 1, &cp_ci, nullptr, &pipeline); + tracked_info->vk_pipeline = pipeline; + tracked_info->vk_device = vk_dev; + tracked_info->is_compute = true; + + vkDestroyShaderModule(vk_dev, cs_module, nullptr); + } + + void StateObject::on_change() + { + tracked_info.reset(new API::TrackedPipeline()); + event_change(); + } + + HAL::shader_identifier StateObject::get_shader_id(std::wstring_view) + { + return {}; + } + + namespace API + { + std::string PipelineStateBase::get_cache() + { + return ""; + } + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.PipelineState.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.PipelineState.ixx new file mode 100644 index 00000000..edca3c80 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.PipelineState.ixx @@ -0,0 +1,38 @@ +export module HAL:API.PipelineState; +import vulkan; +import Core; +import :Types; +import :Utils; + +export namespace HAL +{ + namespace API + { + class TrackedPipeline : public TrackedObject + { + public: + VkPipeline vk_pipeline = VK_NULL_HANDLE; + VkDevice vk_device = VK_NULL_HANDLE; // for destructor cleanup + bool is_compute = false; + VkPrimitiveTopology vk_topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + virtual ~TrackedPipeline(); + }; + + class PipelineStateBase + { + public: + virtual ~PipelineStateBase() = default; + std::string get_cache(); + }; + + // StateObject: D3D12 work-graph / raytracing state object. + // Not supported on Vulkan for Phase 0; stub kept for interface compat. + class StateObject + { + public: + D3D12_PROGRAM_IDENTIFIER id{}; + uint64 buffer_size = 0; + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.QueryHeap.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.QueryHeap.cpp new file mode 100644 index 00000000..3debca97 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.QueryHeap.cpp @@ -0,0 +1,54 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:QueryHeap; + +import vulkan; +import Core; +import :API.QueryHeap; +import :API.Device; + +namespace HAL +{ + // ---- API::QueryHeap destructor ------------------------------------------ + + API::QueryHeap::~QueryHeap() + { + if (vk_query_pool != VK_NULL_HANDLE && vk_qh_device != VK_NULL_HANDLE) + { + vkDestroyQueryPool(vk_qh_device, vk_query_pool, nullptr); + vk_query_pool = VK_NULL_HANDLE; + } + } + + // ---- HAL::QueryHeap constructor ----------------------------------------- + + QueryHeap::QueryHeap(Device& device, const QueryHeapDesc& desc) : desc(desc) + { + auto& api_dev = static_cast(device); + VkDevice vk_dev = api_dev.get_native_device(); + vk_qh_device = vk_dev; + + if (vk_dev == VK_NULL_HANDLE) { read_back_data.resize(desc.Count); return; } + + // Map HAL QueryType → Vulkan query type. + VkQueryType vk_type = VK_QUERY_TYPE_TIMESTAMP; + switch (desc.type) + { + case QueryType::Timestamp: vk_type = VK_QUERY_TYPE_TIMESTAMP; break; + case QueryType::Statistics: vk_type = VK_QUERY_TYPE_PIPELINE_STATISTICS; break; + default: break; + } + + VkQueryPoolCreateInfo ci{ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO }; + ci.queryType = vk_type; + ci.queryCount = desc.Count; + vkCreateQueryPool(vk_dev, &ci, nullptr, &vk_query_pool); + + // Vulkan requires all queries to be reset before first use. + if (vk_query_pool != VK_NULL_HANDLE) + vkResetQueryPool(vk_dev, vk_query_pool, 0, desc.Count); + + read_back_data.resize(desc.Count); + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.QueryHeap.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.QueryHeap.ixx new file mode 100644 index 00000000..ba69560e --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.QueryHeap.ixx @@ -0,0 +1,24 @@ +export module HAL:API.QueryHeap; +import vulkan; +import Core; + +import :Types; +import :Sampler; +import :Utils; +import :API.Device; + +export namespace HAL +{ + namespace API + { + class QueryHeap + { + protected: + VkQueryPool vk_query_pool = VK_NULL_HANDLE; + VkDevice vk_qh_device = VK_NULL_HANDLE; // for destructor + public: + VkQueryPool get_native() const { return vk_query_pool; } + virtual ~QueryHeap(); + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Queue.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Queue.cpp new file mode 100644 index 00000000..becc525f --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Queue.cpp @@ -0,0 +1,274 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +#include +module HAL:API.Queue; + +import Core; +import HAL; +#undef THIS + +using namespace HAL; + +namespace HAL +{ + // ---- native-split members of common HAL::Queue ------------------------- + + void Queue::update_tile_mappings(const update_tiling_info&) {} + + ClockCalibrationInfo Queue::get_clock_time() const + { + // Phase: vkGetCalibratedTimestampsEXT + return { 0, 0, frequency }; + } + + // ---- HAL::DirectStorageQueue (streaming) -------------------------------- + + DirectStorageQueue::DirectStorageQueue(Device& device) : device(device), requestCounter(device) {} + DirectStorageQueue::~DirectStorageQueue() { executor.stop_and_wait(); } + void DirectStorageQueue::flush() {} + void DirectStorageQueue::stop_all() {} + + HAL::FenceWaiter DirectStorageQueue::signal() + { + auto value = ++m_fenceValue; + requestCounter.signal(value); + return FenceWaiter{ &requestCounter, value }; + } + + void DirectStorageQueue::signal_and_wait() { auto s = signal(); flush(); s.wait(); } + bool DirectStorageQueue::is_complete(UINT64 fence) { return requestCounter.get_completed_value() >= fence; } + FenceWaiter DirectStorageQueue::get_waiter() { return FenceWaiter{ &requestCounter, 0 }; } + + HAL::FenceWaiter DirectStorageQueue::execute(StorageRequest srequest) + { + // Vulkan has no DirectStorage — read the cache file and upload via a + // staging-buffer command list. The binary data was written by + // TextureResource::read(i) using get_texture_layout(desc, sub) (no-box + // version), which uses mip-0 dimensions for the row stride. We must + // use the same function here so the source row stride matches what was + // stored in the cache. update_texture() handles the mismatch between + // that stride and the 256-byte-aligned upload stride internally. + + std::ifstream file(srequest.file, std::ios::binary); + if (!file.is_open()) + return signal(); + + file.seekg(static_cast(srequest.file_offset), std::ios::beg); + std::vector data(srequest.size); + file.read(reinterpret_cast(data.data()), static_cast(srequest.size)); + if (!file) + return signal(); + + // Vulkan compress() is a no-op, so the file data is always uncompressed. + // (srequest.compressed will be false; nothing to decompress.) + + auto list = device.get_upload_list(); + + std::visit(overloaded{ + [&](const StorageRequest::Buffer&) + { + ASSERT(false); // buffer cache upload not yet implemented for Vulkan + }, + [&](const StorageRequest::Texture& texture) + { + // row stride used during save: get_texture_layout without box + auto save_layout = device.get_texture_layout( + srequest.resource->get_desc(), texture.subresource); + // mip dimensions for this subresource + auto mip_desc = srequest.resource->get_desc().as_texture(); + auto mip = mip_desc.get_mip(texture.subresource); + auto box = ivec3(mip_desc.get_size(mip)); + + list->get_copy().update_texture( + srequest.resource.get(), + ivec3(0, 0, 0), + box, + texture.subresource, + reinterpret_cast(data.data()), + save_layout.row_stride, + 0); + }, + [](auto) { ASSERT(false); } + }, srequest.operation); + + list->execute_and_wait(); + return signal(); + } + + // ---- HAL::API::Queue --------------------------------------------------- + + namespace API + { + void Queue::construct(HAL::CommandListType type, Device* device) + { + auto THIS = static_cast(this); + + auto& api_dev = *static_cast(device); + if (api_dev.get_native_device() == VK_NULL_HANDLE) return; + + m_device = &api_dev; + family_idx = api_dev.get_queue_family(static_cast(type)); + vk_device = api_dev.get_native_device(); + + if (family_idx == static_cast(-1)) return; + + vkGetDeviceQueue(vk_device, family_idx, 0, &vk_queue); + + // Query timestamp frequency (nanoseconds per tick) + VkPhysicalDeviceProperties props{}; + vkGetPhysicalDeviceProperties(api_dev.get_vk_physical_dev(), &props); + // timestampPeriod is ns/tick; we want ticks/sec for frequency + if (props.limits.timestampPeriod > 0.0f) + THIS->frequency = static_cast(1e9 / props.limits.timestampPeriod); + } + + Queue::~Queue() + { + if (init_pool != VK_NULL_HANDLE) + vkDestroyCommandPool(vk_device, init_pool, nullptr); + } + + VkCommandBuffer Queue::flush_init_transitions() + { + if (!m_device) return VK_NULL_HANDLE; + + auto barriers = m_device->take_pending_init_transitions(); + if (barriers.empty()) return VK_NULL_HANDLE; + + if (init_pool == VK_NULL_HANDLE) + { + VkCommandPoolCreateInfo pci{ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + pci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT + | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + pci.queueFamilyIndex = family_idx; + vkCreateCommandPool(vk_device, &pci, nullptr, &init_pool); + + VkCommandBufferAllocateInfo cai{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + cai.commandPool = init_pool; + cai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cai.commandBufferCount = static_cast(init_cbs.size()); + vkAllocateCommandBuffers(vk_device, &cai, init_cbs.data()); + } + + VkCommandBuffer cb = init_cbs[init_cb_index]; + init_cb_index = (init_cb_index + 1) % static_cast(init_cbs.size()); + + vkResetCommandBuffer(cb, 0); + VkCommandBufferBeginInfo bi{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + bi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer(cb, &bi); + + VkDependencyInfo dep{ VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + dep.imageMemoryBarrierCount = static_cast(barriers.size()); + dep.pImageMemoryBarriers = barriers.data(); + vkCmdPipelineBarrier2(cb, &dep); + + vkEndCommandBuffer(cb); + return cb; + } + + void Queue::execute(const API::CommandList* list) + { + if (vk_queue == VK_NULL_HANDLE || !list || list->get_native() == VK_NULL_HANDLE) + return; + + // Flush pending initial-layout transitions ahead of the real work so + // fresh images actually rest in the layout the state manager assumes. + VkCommandBufferSubmitInfo cmd_infos[2]{}; + uint32_t cmd_count = 0; + + if (VkCommandBuffer init_cb = flush_init_transitions(); init_cb != VK_NULL_HANDLE) + { + cmd_infos[cmd_count] = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + cmd_infos[cmd_count].commandBuffer = init_cb; + ++cmd_count; + } + + VkCommandBufferSubmitInfo& cmd_info = cmd_infos[cmd_count]; + cmd_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + cmd_info.commandBuffer = list->get_native(); + ++cmd_count; + + // Consume pending acquire/present semaphores (set once per frame by SwapChain). + VkSemaphoreSubmitInfo wait_info{}, sig_info{}; + uint32_t wait_count = 0, sig_count = 0; + + if (pending_wait_sem != VK_NULL_HANDLE) + { + wait_info = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + wait_info.semaphore = pending_wait_sem; + wait_info.stageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + wait_count = 1; + pending_wait_sem = VK_NULL_HANDLE; + } + if (pending_signal_sem != VK_NULL_HANDLE) + { + sig_info = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + sig_info.semaphore = pending_signal_sem; + sig_info.stageMask = VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT; + sig_count = 1; + pending_signal_sem = VK_NULL_HANDLE; + } + + VkSubmitInfo2 submit{ VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; + submit.commandBufferInfoCount = cmd_count; + submit.pCommandBufferInfos = cmd_infos; + submit.waitSemaphoreInfoCount = wait_count; + submit.pWaitSemaphoreInfos = wait_count ? &wait_info : nullptr; + submit.signalSemaphoreInfoCount = sig_count; + submit.pSignalSemaphoreInfos = sig_count ? &sig_info : nullptr; + + std::lock_guard lock(vk_queue_mutex); + vkQueueSubmit2(vk_queue, 1, &submit, VK_NULL_HANDLE); + // Note: no flush() — frame pacing is handled by timeline semaphores in signal(). + } + + void Queue::flush() + { + if (vk_queue != VK_NULL_HANDLE) + { + std::lock_guard lock(vk_queue_mutex); + vkQueueWaitIdle(vk_queue); + } + } + + void Queue::signal(Fence& fence, Fence::CounterType value) + { + if (vk_queue == VK_NULL_HANDLE || fence.timeline_semaphore == VK_NULL_HANDLE) + return; + + VkSemaphoreSubmitInfo sem{ VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + sem.semaphore = fence.timeline_semaphore; + sem.value = value; + sem.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + + VkSubmitInfo2 submit{ VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; + submit.signalSemaphoreInfoCount = 1; + submit.pSignalSemaphoreInfos = &sem; + + std::lock_guard lock(vk_queue_mutex); + vkQueueSubmit2(vk_queue, 1, &submit, VK_NULL_HANDLE); + } + + void Queue::gpu_wait(HAL::FenceWaiter waiter) + { + if (!waiter || vk_queue == VK_NULL_HANDLE) return; + if (waiter.fence->timeline_semaphore == VK_NULL_HANDLE) return; + + VkSemaphoreSubmitInfo sem{ VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + sem.semaphore = waiter.fence->timeline_semaphore; + sem.value = waiter.value; + sem.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + + VkSubmitInfo2 submit{ VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; + submit.waitSemaphoreInfoCount = 1; + submit.pWaitSemaphoreInfos = &sem; + + std::lock_guard lock(vk_queue_mutex); + vkQueueSubmit2(vk_queue, 1, &submit, VK_NULL_HANDLE); + } + + VkQueue Queue::get_native() const { return vk_queue; } + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Queue.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Queue.ixx new file mode 100644 index 00000000..5c56eb12 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Queue.ixx @@ -0,0 +1,89 @@ +export module HAL:API.Queue; +import vulkan; +import :Types; +import :Utils; +import :Fence; +import :CommandList; + +export namespace HAL +{ + namespace API + { + class Device; + + class Queue + { + protected: + VkQueue vk_queue = VK_NULL_HANDLE; + VkDevice vk_device = VK_NULL_HANDLE; + uint32_t family_idx = std::numeric_limits::max(); + Device* m_device = nullptr; + + // Transient command buffers used to flush the device's pending + // initial-layout transitions ahead of a real submit. Small ring: + // flushes are rare (only submits right after resource creation) and + // the per-frame swapchain sync guarantees a ring slot has long + // retired before it comes around again. + VkCommandPool init_pool = VK_NULL_HANDLE; + std::array init_cbs{}; + uint32_t init_cb_index = 0; + + // Records pending init barriers (if any) into a ring CB and returns + // it, or VK_NULL_HANDLE when there is nothing to flush. + VkCommandBuffer flush_init_transitions(); + + // Acquire / present semaphores consumed once on the next execute(). + // Set by SwapChain after vkAcquireNextImageKHR; cleared by execute(). + VkSemaphore pending_wait_sem = VK_NULL_HANDLE; + VkSemaphore pending_signal_sem = VK_NULL_HANDLE; + + // Protects all vkQueue* calls — VkQueue must be externally synchronized. + mutable std::mutex vk_queue_mutex; + + void execute(const API::CommandList* list); + void flush(); + void signal(Fence& fence, Fence::CounterType value); + void gpu_wait(HAL::FenceWaiter waiter); + void construct(HAL::CommandListType type, Device* device); + + public: + virtual ~Queue(); + + VkQueue get_native() const; + + // Called by SwapChain to wire the per-frame binary semaphores into + // the next command buffer submission. + void set_frame_semaphores(VkSemaphore wait, VkSemaphore signal) noexcept + { + pending_wait_sem = wait; + pending_signal_sem = signal; + } + + // Thread-safe present: takes the queue mutex so submit and present + // cannot race. Returns the VkResult from vkQueuePresentKHR. + VkResult present(VkPresentInfoKHR& pi) noexcept + { + if (vk_queue == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; + std::lock_guard lock(vk_queue_mutex); + return vkQueuePresentKHR(vk_queue, &pi); + } + + // Thread-safe raw submit used by SwapChain for its transition CB. + void submit_raw(VkSubmitInfo2& info) noexcept + { + if (vk_queue == VK_NULL_HANDLE) return; + std::lock_guard lock(vk_queue_mutex); + vkQueueSubmit2(vk_queue, 1, &info, VK_NULL_HANDLE); + } + }; + + // DirectStorage is D3D12-specific; provide an empty stub so + // HAL::DirectStorageQueue (which inherits from this) still compiles. + class DirectStorageQueue + { + protected: + public: + virtual ~DirectStorageQueue() = default; + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.Buffer.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.Buffer.cpp new file mode 100644 index 00000000..0b627673 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.Buffer.cpp @@ -0,0 +1,39 @@ +module HAL:Resource.Buffer; + +import vulkan; +import Core; + +import :FrameManager; + + +// Vulkan implementation of the backend-specific Buffer methods. +// Mirrors D3D12/HAL.D3D12.Resource.Buffer.cpp (excluded from Vulkan build). +// The backend-agnostic Buffer methods (init, read, write, constructors, +// get_size, get_resource_address) live in the common HAL.Resource.Buffer.cpp. + +namespace HAL +{ + std::span Buffer::cpu_data() const + { + return { buffer_data, buffer_data + get_size() }; + } + + Buffer::~Buffer() + { + // Phase 1: VMA-mapped memory is unmapped by vmaDestroyBuffer; if we + // hold a persistent mapping we release it here. + buffer_data = nullptr; + } + + std::byte* ResourceAddress::get_cpu_data() const + { + return resource->cpu_data().data() + resource_offset; + } +} + +// Global helper mirroring the D3D12 ::to_native(ResourceAddress) — converts a +// HAL::ResourceAddress to a raw GPU virtual address (buffer device address). +HAL::GPUAddressPtr to_native(const HAL::ResourceAddress& address) +{ + return address.resource ? (address.resource->get_address() + address.resource_offset) : 0; +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.cpp new file mode 100644 index 00000000..c440a537 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.cpp @@ -0,0 +1,422 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +#include +module HAL:Resource; + +import Core; + +import :Utils; // to_native(Format) +import :API.Resource; // API::Resource, PlacementAddress, NativeImportHandle; pulls in :Types, :API.Device +import :API.Heap; // API::Heap::cpu_address, get_address() +import :Heap; // HAL::Heap::get_type() +import :Device; // HAL::Device +import :HeapAllocators; +import :FrameManager; + +namespace HAL +{ + namespace API + { + GPUAddressPtr Resource::get_address() { return address; } + + void* Resource::get_cpu_mapping() { return mapped_data; } + + void Resource::init(Device& device, const ResourceDesc& _desc, + const PlacementAddress& placement, TextureLayout initialLayout) + { + auto THIS = static_cast(this); + THIS->m_device = static_cast(&device); + THIS->desc = _desc; + + // Resolve MipLevels=0 → full mip chain. + // D3D12 handles this natively inside CreateCommittedResource; + // Vulkan requires mipLevels >= 1 and we must compute the count + // ourselves before init_subres or vmaCreateImage sees the descriptor. + if (THIS->desc.is_texture()) + { + auto& t = THIS->desc.as_texture(); + if (t.MipLevels == 0) + { + uint max_dim = std::max({ t.Dimensions.x, + t.is1D() ? 1u : t.Dimensions.y, + t.is3D() ? t.Dimensions.z : 1u }); + t.MipLevels = max_dim > 0u + ? static_cast(std::floor(std::log2( + static_cast(max_dim)))) + 1u + : 1u; + } + } + + // heap_type priority: + // 1. If placement.heap is set, derive from that heap's type. + // 2. Otherwise, preserve what _init() already wrote. + // _init(HeapType::DEFAULT) calls init() with a null placement + // but has pre-set heap_type = DEFAULT; overwriting it to RESERVED + // was the root bug — it caused every regular non-placed resource + // to take the tiled/reserved early-return path with no VkBuffer/Image. + if (placement.heap) + THIS->heap_type = placement.heap->get_type(); + // else: keep heap_type as set by caller (_init always pre-sets it) + + // Mirror D3D12's initialLayout defaulting logic: when the caller + // passes UNDEFINED (the default), derive the initial layout from + // the resource's usage flags so the CPU state manager starts in + // the correct layout and compile_transitions() generates valid + // oldLayout values in Vulkan barriers. + if (_desc.is_texture()) + { + if (THIS->heap_type == HeapType::UPLOAD) + { + initialLayout = TextureLayout::SHADER_RESOURCE | TextureLayout::COPY_SOURCE; + } + else if (THIS->heap_type == HeapType::READBACK) + { + initialLayout = TextureLayout::COPY_DEST; + } + else if (initialLayout == TextureLayout::UNDEFINED) + { + if (check(_desc.Flags & ResFlags::ShaderResource)) + initialLayout = TextureLayout::SHADER_RESOURCE; + else if (check(_desc.Flags & ResFlags::UnorderedAccess)) + initialLayout = TextureLayout::UNORDERED_ACCESS; + else if (check(_desc.Flags & ResFlags::DepthStencil)) + initialLayout = TextureLayout::DEPTH_STENCIL_WRITE | TextureLayout::DEPTH_STENCIL_READ; + else if (check(_desc.Flags & ResFlags::RenderTarget)) + initialLayout = TextureLayout::RENDER_TARGET; + else + initialLayout = TextureLayout::COPY_DEST; + } + + if (check(_desc.Flags & ResFlags::DisableStateTracking)) + { + if (check(_desc.Flags & ResFlags::ShaderResource)) + initialLayout = TextureLayout::SHADER_RESOURCE; + else + initialLayout = TextureLayout::COPY_SOURCE; + } + } + + THIS->state_manager.init_subres(device.Subresources(THIS->get_desc()), initialLayout); + + if (THIS->heap_type == HeapType::RESERVED) + { + THIS->tiled_manager.init_tilings(); + return; + } + + // Placed resources — two cases: + // + // A) UPLOAD / READBACK heap: the heap owns a persistently-mapped VMA + // buffer. Derive cpu/gpu addresses from it (no separate allocation). + // + // B) DEFAULT heap: Vulkan has no D3D12-style placed resource without + // VK_KHR_bind_memory2 / explicit memory management. Fall through + // to create a standalone VMA allocation instead. The heap's memory + // region is intentionally ignored — the HeapType drives VMA flags. + if (placement.heap) + { + auto* api_heap = static_cast(placement.heap); + if (api_heap->cpu_address) + { + // Case A: CPU-visible heap (UPLOAD / READBACK). + // Share the heap's single VkBuffer; the slice is addressed via + // resource_offset (placement.offset) at copy/descriptor time. + // Without this, get_vk_buffer() is null for every placed staging + // buffer / CBV / vertex-index buffer, so copies and descriptor + // writes are silently skipped and the GPU reads zeroes. + mapped_data = api_heap->cpu_address + placement.offset; + address = api_heap->get_address() + placement.offset; + vk_buffer = api_heap->get_vk_buffer(); + return; + } + // Case B: DEFAULT heap — fall through to VMA allocation below. + } + + VmaAllocator allocator = device.get_vma_allocator(); + if (!allocator) return; + + VmaAllocationCreateInfo vma_ci{}; + + if (_desc.is_buffer()) + { + auto& buf = _desc.as_buffer(); + + VkBufferCreateInfo bci{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bci.size = buf.SizeInBytes; + bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT + | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; + + if (THIS->heap_type == HeapType::UPLOAD || THIS->heap_type == HeapType::READBACK) + { + vma_ci.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT + | VMA_ALLOCATION_CREATE_MAPPED_BIT; + vma_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST; + } + else + { + vma_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + } + + VmaAllocationInfo alloc_info{}; + vmaCreateBuffer(allocator, &bci, &vma_ci, &vk_buffer, &vma_alloc, &alloc_info); + + if (THIS->heap_type == HeapType::UPLOAD || THIS->heap_type == HeapType::READBACK) + mapped_data = alloc_info.pMappedData; + + if (vk_buffer != VK_NULL_HANDLE) + { + VkBufferDeviceAddressInfo dai{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO }; + dai.buffer = vk_buffer; + address = vkGetBufferDeviceAddress(device.get_native_device(), &dai); + } + } + else if (_desc.is_texture()) + { + // Read from THIS->desc, not _desc: the MipLevels=0 → full-chain + // resolution above mutated the stored copy only. vkCreateImage + // requires mipLevels >= 1, so using the raw parameter here made + // every MipLevels=0 texture silently fail creation. + auto& tex = THIS->desc.as_texture(); + + VkImageCreateInfo ici{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; + ici.imageType = tex.is3D() ? VK_IMAGE_TYPE_3D : + tex.is1D() ? VK_IMAGE_TYPE_1D : VK_IMAGE_TYPE_2D; + ici.format = to_native(tex.Format); + ici.extent = { tex.Dimensions.x, + tex.is1D() ? 1u : tex.Dimensions.y, + tex.is3D() ? tex.Dimensions.z : 1u }; + ici.mipLevels = tex.MipLevels; + ici.arrayLayers = tex.ArraySize; + ici.samples = VK_SAMPLE_COUNT_1_BIT; + ici.tiling = VK_IMAGE_TILING_OPTIMAL; + ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT + | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + + // STORAGE only on request — mirrors D3D12's ALLOW_UNORDERED_ACCESS. + // Forcing it on every image breaks formats without storage-image + // support (e.g. B8G8R8A8_UNORM on NVIDIA): vkCreateImage fails and + // the resource silently becomes a null no-op. + if (check(_desc.Flags & ResFlags::UnorderedAccess)) + ici.usage |= VK_IMAGE_USAGE_STORAGE_BIT; + if (check(_desc.Flags & ResFlags::RenderTarget)) + ici.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + if (check(_desc.Flags & ResFlags::DepthStencil)) + ici.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + vma_ci.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + + VkResult img_res = vmaCreateImage(allocator, &ici, &vma_ci, &vk_image, &vma_alloc, nullptr); + if (img_res != VK_SUCCESS) + Log::get() << "[Vulkan] vmaCreateImage failed (" << static_cast(img_res) + << ") vk_format=" << static_cast(ici.format) + << " usage=" << static_cast(ici.usage) + << " extent=" << ici.extent.width << "x" << ici.extent.height << "x" << ici.extent.depth + << " mips=" << ici.mipLevels << " layers=" << ici.arrayLayers + << " — resource will be a null no-op" << Log::endl; + + if (vk_image != VK_NULL_HANDLE) + { + // Store pixel dimensions so get_imported_extent() works for all images. + imported_extent = { ici.extent.width, ici.extent.height }; + + // Create a full-resource image view. + bool is_depth = check(_desc.Flags & ResFlags::DepthStencil); + vk_image_format = ici.format; + vk_image_aspect = is_depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + + VkImageViewCreateInfo ivci{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; + ivci.image = vk_image; + ivci.viewType = tex.is3D() ? VK_IMAGE_VIEW_TYPE_3D + : tex.is1D() ? VK_IMAGE_VIEW_TYPE_1D + : tex.ArraySize > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY + : VK_IMAGE_VIEW_TYPE_2D; + ivci.format = ici.format; + ivci.subresourceRange.aspectMask = vk_image_aspect; + ivci.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + ivci.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + vkCreateImageView(device.get_native_device(), &ivci, nullptr, &vk_image_view); + + // The state manager records `initialLayout` as the layout this + // image rests in between command lists, but a fresh VkImage is + // actually UNDEFINED. Queue the one-time transition that makes + // the assumption true (flushed before the next queue submit). + device.queue_initial_transition(vk_image, to_native(initialLayout), + is_depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT); + } + } + } + + void Resource::init(const NativeImportHandle& handle, TextureLayout layout, Device& device) + { + auto THIS = static_cast(this); + THIS->m_device = static_cast(&device); + + import_handle = handle; + vk_image = handle.image; + imported_extent = handle.extent; + + // Build a proper 2D TextureDesc so as_texture() works in common code. + // Mirrors D3D12's Resource::init(NativeImportHandle) which calls extract(). + auto fmt = from_native(handle.format); + THIS->desc = ResourceDesc::Tex2D( + fmt, + uint2(handle.extent.width, handle.extent.height), + 1, // ArraySize + 1 // MipLevels + ); + THIS->desc.Flags |= ResFlags::RenderTarget; + if (layout == TextureLayout::PRESENT) + THIS->desc.Flags |= ResFlags::Swapchain; + + THIS->state_manager.init_subres(device.Subresources(THIS->get_desc()), layout); + } + } + + void Resource::_init(Device& device, const ResourceDesc& desc, HeapType heap_type, + TextureLayout initialLayout, vec4 /*clear_value*/) + { + m_device = &device; + this->heap_type = heap_type; + alloc_info = device.get_alloc_info(desc); + + PlacementAddress address = {}; + init(device, desc, address, initialLayout); + } + + Resource::Resource(Device& device, const ResourceDesc& desc, HeapType heap_type, + TextureLayout initialLayout, vec4 clear_value) + : state_manager(this), tiled_manager(this) + { + _init(device, desc, heap_type, initialLayout, clear_value); + } + + Resource::Resource(Device& device, const ResourceDesc& desc, ResourceHandle handle, bool own) + : state_manager(this), tiled_manager(this) + { + m_device = &device; + PlacementAddress address = { handle.get_heap().get(), handle.get_offset() }; + init(device, desc, address, TextureLayout::UNDEFINED); + if (own) + alloc_handle = handle; + } + + Resource::Resource(Device& device, const ResourceDesc& desc, PlacementAddress address) + : state_manager(this), tiled_manager(this) + { + m_device = &device; + init(device, desc, address, TextureLayout::UNDEFINED); + } + + Resource::Resource(Device& device, const API::NativeImportHandle& handle, TextureLayout initialLayout) + : state_manager(this), tiled_manager(this) + { + m_device = &device; + init(handle, initialLayout, device); + } + + void Resource::set_name(std::string name) + { + if (!this->name.empty() && name.empty()) return; + this->name = name; + + if (!m_device) return; + auto& api_dev = static_cast(*m_device); + VkDevice vk_dev = api_dev.get_native_device(); + if (vk_dev == VK_NULL_HANDLE) return; + + auto fn = reinterpret_cast( + vkGetDeviceProcAddr(vk_dev, "vkSetDebugUtilsObjectNameEXT")); + if (!fn) return; + + VkDebugUtilsObjectNameInfoEXT info{ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT }; + info.pObjectName = this->name.c_str(); + + if (vk_image != VK_NULL_HANDLE) + { + info.objectType = VK_OBJECT_TYPE_IMAGE; + info.objectHandle = reinterpret_cast(vk_image); + fn(vk_dev, &info); + if (vk_image_view != VK_NULL_HANDLE) + { + info.objectType = VK_OBJECT_TYPE_IMAGE_VIEW; + info.objectHandle = reinterpret_cast(vk_image_view); + fn(vk_dev, &info); + } + } + else if (vk_buffer != VK_NULL_HANDLE) + { + info.objectType = VK_OBJECT_TYPE_BUFFER; + info.objectHandle = reinterpret_cast(vk_buffer); + fn(vk_dev, &info); + } + } + + namespace API + { + VkImageView Resource::get_vk_mip_view(VkDevice vk_dev, uint32_t mip, uint32_t layer) const noexcept + { + if (vk_image == VK_NULL_HANDLE || vk_image_format == VK_FORMAT_UNDEFINED) + return VK_NULL_HANDLE; + + uint32_t key = (layer << 16) | mip; + auto it = per_mip_views.find(key); + if (it != per_mip_views.end()) + return it->second; + + VkImageViewCreateInfo ivci{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; + ivci.image = vk_image; + ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; + ivci.format = vk_image_format; + ivci.subresourceRange.aspectMask = vk_image_aspect; + ivci.subresourceRange.baseMipLevel = mip; + ivci.subresourceRange.levelCount = 1; + ivci.subresourceRange.baseArrayLayer = layer; + ivci.subresourceRange.layerCount = 1; + + VkImageView v = VK_NULL_HANDLE; + vkCreateImageView(vk_dev, &ivci, nullptr, &v); + per_mip_views[key] = v; + return v; + } + } + + Resource::~Resource() + { + alloc_handle.Free(); + + if (vma_alloc) + { + auto& api_dev = static_cast(*m_device); + VkDevice vk_dev = api_dev.get_native_device(); + + // Cancel any pending UNDEFINED→initial transition queued at creation + // time — if the image is destroyed before Queue::execute() flushes the + // batch, the barrier would reference a freed handle and crash the driver. + api_dev.cancel_pending_init_transition(vk_image); + + // Destroy per-mip UAV views before destroying the image. + for (auto& [key, view] : per_mip_views) + if (view != VK_NULL_HANDLE) + vkDestroyImageView(vk_dev, view, nullptr); + per_mip_views.clear(); + + // Destroy the owned image view before destroying the image itself. + if (vk_image_view != VK_NULL_HANDLE && !import_handle.image) + { + vkDestroyImageView(vk_dev, vk_image_view, nullptr); + vk_image_view = VK_NULL_HANDLE; + } + + if (vk_buffer != VK_NULL_HANDLE) + vmaDestroyBuffer(api_dev.get_vma_allocator(), vk_buffer, vma_alloc); + else if (vk_image != VK_NULL_HANDLE && !import_handle.image) + vmaDestroyImage(api_dev.get_vma_allocator(), vk_image, vma_alloc); + vma_alloc = VK_NULL_HANDLE; + } + } + +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.ixx new file mode 100644 index 00000000..1e88647a --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Resource.ixx @@ -0,0 +1,109 @@ +export module HAL:API.Resource; +import vulkan; +import Core; + +import :Types; +import :Sampler; +import :Utils; +import :API.Device; +import :Heap; + +import :Format; + +export namespace HAL +{ + struct PlacementAddress + { + Heap* heap; + size_t offset; + }; + + namespace API + { + // NativeImportHandle: opaque wrapping of a backend-native resource for + // importing externally-managed images (e.g. swapchain back-buffers). + // D3D12 version wraps ComPtr; + // Vulkan version wraps VkImage + view + format. + struct NativeImportHandle + { + VkImage image = VK_NULL_HANDLE; + VkImageView image_view = VK_NULL_HANDLE; + VkFormat format = VK_FORMAT_UNDEFINED; + VkExtent2D extent = {}; // pixel dimensions of the image + }; + + class Resource + { + uint64_t address = 0; + + // CommandList needs vk_buffer/vk_image for barriers and clears. + friend class CommandList; + // Heap::Heap sets mapped_data / address on its backing buffer. + friend class Heap; + + protected: + // Vulkan resource handles — backend-internal. + VkBuffer vk_buffer = VK_NULL_HANDLE; + VkImage vk_image = VK_NULL_HANDLE; + VkImageView vk_image_view= VK_NULL_HANDLE; // owned (non-swapchain) images + VmaAllocation vma_alloc = VK_NULL_HANDLE; + + // Cached per-mip image views for UAV (storage image) descriptors. + // Keyed by (array_layer << 16 | mip_level). VkImageViews with levelCount=1 + // are required for VK_DESCRIPTOR_TYPE_STORAGE_IMAGE descriptors. + mutable std::unordered_map per_mip_views; + + // Format/aspect stored at image creation for per-mip view creation. + VkFormat vk_image_format = VK_FORMAT_UNDEFINED; + VkImageAspectFlags vk_image_aspect = 0; + + // Persistent CPU mapping (UPLOAD / READBACK heaps). + void* mapped_data = nullptr; + + // Externally-owned image handle (e.g. swapchain backbuffer). + NativeImportHandle import_handle; + + // Pixel dimensions — set for both imported and owned images. + VkExtent2D imported_extent = {}; + + public: + using ptr = std::shared_ptr; + + void init(Device& device, const ResourceDesc& desc, + const PlacementAddress& address, + TextureLayout initialLayout = TextureLayout::UNDEFINED); + void init(const NativeImportHandle& handle, + TextureLayout layout, + Device& device); + + uint64_t get_address(); + + // CPU mapping (for UPLOAD / READBACK heaps). + void* get_cpu_mapping(); + + // ---- Backend accessors (Vulkan handles for sibling modules) ------ + // Cross-partition friends are unreliable in MSVC; expose via getters. + VkImage get_vk_image() const noexcept { return vk_image; } + VkBuffer get_vk_buffer() const noexcept { return vk_buffer; } + // Primary image view: swapchain view takes priority, owned view as fallback. + VkImageView get_vk_image_view() const noexcept { + return import_handle.image_view != VK_NULL_HANDLE + ? import_handle.image_view : vk_image_view; + } + // Single-mip image view for UAV (STORAGE_IMAGE) descriptors. + // Lazily created and cached; requires levelCount=1 per Vulkan spec. + VkImageView get_vk_mip_view(VkDevice vk_dev, uint32_t mip, uint32_t layer = 0) const noexcept; + VkExtent2D get_imported_extent() const noexcept { return imported_extent; } + const NativeImportHandle& get_import_handle() const noexcept { return import_handle; } + }; + } +} + +export +{ + namespace cereal + { + template + void serialize(Archive& ar, HAL::API::Resource*& g) {} + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.RootSignature.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.RootSignature.cpp new file mode 100644 index 00000000..3f01a706 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.RootSignature.cpp @@ -0,0 +1,82 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:API.RootSignature; + +import Core; +import vulkan; +import :Types; +import :Sampler; +import :RootSignature; +import :API.Device; +import :Utils; + +// Vulkan Phase 4 — real VkPipelineLayout creation. +// +// Mapping: +// Set 0 — CBV_SRV_UAV: global bindless layout from API::Device +// Set 1 — Sampler: global bindless layout from API::Device +// Push constants: 128 bytes (ALL_STAGES) for DescriptorConstants entries + +namespace HAL +{ + RootSignature::RootSignature(Device& device, const RootSignatureDesc& desc) + : device(device) + { + this->desc = desc; + + auto& api_dev = static_cast(device); + VkDevice vk_dev = api_dev.get_native_device(); + if (vk_dev == VK_NULL_HANDLE) return; + + // ---- Descriptor set layouts ---------------------------------------- + // Set 0 = CBV_SRV_UAV, Set 1 = Sampler. + // Both come from the global layouts created by Device::init(). + VkDescriptorSetLayout set_layouts[2] = { + api_dev.get_cbv_srv_uav_layout(), + api_dev.get_sampler_layout(), + }; + + // ---- Push constant ranges ------------------------------------------ + // Gather DescriptorConstants entries and compute the total byte range. + // Each entry contributes count × 4 bytes at offset × 4 within the block. + uint32_t push_bytes = 0; + for (auto& [idx, param] : desc.parameters) + { + if (auto* c = std::get_if(¶m)) + { + uint32_t end = (c->offset + c->count) * sizeof(uint32_t); + push_bytes = std::max(push_bytes, end); + } + } + // Always allocate at least 128 bytes so common "set_constant" calls work + // even when the root signature doesn't explicitly declare them. + push_bytes = std::max(push_bytes, 128u); + // Clamp to device limit (typically 128–256 bytes). + push_bytes = std::min(push_bytes, 128u); + + VkPushConstantRange push_range{}; + push_range.stageFlags = VK_SHADER_STAGE_ALL; + push_range.offset = 0; + push_range.size = push_bytes; + + // ---- Pipeline layout ----------------------------------------------- + VkPipelineLayoutCreateInfo layout_ci{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + layout_ci.setLayoutCount = 2; + layout_ci.pSetLayouts = set_layouts; + layout_ci.pushConstantRangeCount = 1; + layout_ci.pPushConstantRanges = &push_range; + + vkCreatePipelineLayout(vk_dev, &layout_ci, nullptr, &vk_pipeline_layout); + vk_root_device = vk_dev; + } +} + +namespace HAL::API +{ + RootSignature::~RootSignature() + { + if (vk_pipeline_layout != VK_NULL_HANDLE && vk_root_device != VK_NULL_HANDLE) + vkDestroyPipelineLayout(vk_root_device, vk_pipeline_layout, nullptr); + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.RootSignature.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.RootSignature.ixx new file mode 100644 index 00000000..62137278 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.RootSignature.ixx @@ -0,0 +1,23 @@ +export module HAL:API.RootSignature; + +import vulkan; +export import :Utils; // Re-exported — same reason as DescriptorHeap. + +export namespace HAL +{ + namespace API + { + class RootSignature + { + protected: + // Vulkan: root signature maps to VkPipelineLayout + descriptor set layouts. + VkPipelineLayout vk_pipeline_layout = VK_NULL_HANDLE; + VkDevice vk_root_device = VK_NULL_HANDLE; // for destructor + + public: + virtual ~RootSignature(); + + VkPipelineLayout get_vk_pipeline_layout() const noexcept { return vk_pipeline_layout; } + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.ShaderReflection.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.ShaderReflection.cpp new file mode 100644 index 00000000..2223a9f2 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.ShaderReflection.cpp @@ -0,0 +1,82 @@ +module HAL:ShaderCompiler; + +import Core; +import DXCompiler; + +// Vulkan stub of the reflect_shader() seam declared in +// DXC/DXC.ShaderCompiler.cpp. D3D12 uses ID3D12ShaderReflection to recover +// per-pass constant-buffer slot usage from the DXIL reflection blob; on Vulkan +// (SPIR-V) reflection is deferred to Phase 4 (SPIR-V-Reflect or DXC's own +// SPIR-V reflection path). For now we record the function name only — slot +// usage stays empty, which is sufficient until pipelines/bindless land. + +namespace HAL +{ + void reflect_shader(IDxcUtils* /*library*/, const DxcBuffer& /*reflectionBuffer*/, + const std::string& entry_point, CompiledShader& blob_str) + { + if (entry_point.size()) + { + blob_str.functions.emplace_back(); + auto& f = blob_str.functions.back(); + f.name = entry_point; + f.wname = convert(f.name); + // Phase 5: populate f.slots from SPIR-V reflection. + } + } + + // Vulkan: compile HLSL to SPIR-V via DXC. + // -fvk-use-dx-layout : preserve cbuffer/structured-buffer memory layout + // -fvk-b-shift 0 all : CBVs keep their register number as the binding index + // -fvk-t-shift 128 all : SRVs start at binding 128 + // -fvk-u-shift 256 all : UAVs start at binding 256 + // -fvk-s-shift 384 all : Samplers start at binding 384 + // (Must match the VkDescriptorSetLayoutBinding layout in Device::init) + // -fvk-bind-resource-heap 0 0 : SM6.6 ResourceDescriptorHeap → set 0, binding 0 (MUTABLE) + // All types (CBV/SRV/UAV/buffer) land at binding 0. + // Shifts partition the element index range, not the binding. + // -fvk-bind-sampler-heap 1 0 : SM6.6 SamplerDescriptorHeap → set 1, binding 0 + // matches VkDescriptorSetLayout sampler_layout (set 1) + // Slot push constants: slot HLSL uses [[vk::push_constant]] ConstantBuffer<_CB_X> + // with member [[vk::offset(slot.id*4)]]. DXC places the member + // at byte slot.id*4 in the SPIRV push constant block, matching + // the HAL's vkCmdPushConstants offset = slot*4. + // [[vk::push_constant]] is silently ignored by the DXIL path. + // + // float16_tN aliases: -enable-16bit-types is intentionally suppressed for SPIRV + // (Vulkan SPIRV spec requires image sampled types to be 32-bit). Shaders that + // declare float16_tN variables/params still need the types to exist, so we + // define them as float aliases via the preprocessor — arithmetic stays correct, + // image declarations become Texture2D which is valid SPIRV. + std::vector get_extra_compile_args(const std::string& /*target*/) + { + return { + L"-spirv", + L"-fspv-target-env=vulkan1.3", + L"-fvk-use-dx-layout", + L"-fvk-b-shift", L"0", L"all", + L"-fvk-t-shift", L"128", L"all", + L"-fvk-u-shift", L"256", L"all", + L"-fvk-s-shift", L"384", L"all", + L"-fvk-bind-resource-heap", L"0", L"0", + L"-fvk-bind-sampler-heap", L"1", L"0", + // Slot ConstantBuffers use [[vk::push_constant]] + [[vk::offset(slot*4)]] in HLSL. + // No -fvk-push-constant-space needed; the offset is encoded directly in the struct. + // float16_t aliases — map 16-bit scalar/vector types to 32-bit + // so shaders compile without -enable-16bit-types (blocked for SPIRV; + // see DXC.ShaderCompiler.cpp). Texture2D → Texture2D. + L"-Dfloat16_t=float", + L"-Dfloat16_t2=float2", + L"-Dfloat16_t3=float3", + L"-Dfloat16_t4=float4", + L"-Dint16_t=int", + L"-Dint16_t2=int2", + L"-Dint16_t3=int3", + L"-Dint16_t4=int4", + L"-Duint16_t=uint", + L"-Duint16_t2=uint2", + L"-Duint16_t3=uint3", + L"-Duint16_t4=uint4", + }; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Swapchain.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Swapchain.cpp new file mode 100644 index 00000000..4ba944df --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Swapchain.cpp @@ -0,0 +1,779 @@ +module; +#define VK_USE_PLATFORM_WIN32_KHR +#include +module HAL:SwapChain; + +import Core; +import HAL; + +// ============================================================================ +// Vulkan swapchain implementation (Phase 2). +// Integrates with the existing HAL::SwapChain common wrapper: +// - frames[i].m_renderTarget — TextureResource wrapping each backbuffer +// - frames[i].fence_event — FenceWaiter for CPU-side frame pacing +// - m_frameIndex — toggles between frames in flight +// ============================================================================ + +namespace +{ + VkSemaphore make_semaphore(VkDevice dev) + { + VkSemaphoreCreateInfo info{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + VkSemaphore sem = VK_NULL_HANDLE; + vkCreateSemaphore(dev, &info, nullptr, &sem); + return sem; + } + + // Record a one-time COLOR_ATTACHMENT_OPTIMAL → PRESENT_SRC_KHR barrier into cb + // for the given swapchain image. The command buffer must already be in recording + // state. Uses SIMULTANEOUS_USE_BIT so the same CB can be in-flight while we re-submit it. + void record_present_transition(VkCommandBuffer cb, VkImage image) + { + VkImageMemoryBarrier2 barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + barrier.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + barrier.dstAccessMask = 0; + barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + barrier.image = image; + barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + + VkDependencyInfo dep{ VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + dep.imageMemoryBarrierCount = 1; + dep.pImageMemoryBarriers = &barrier; + vkCmdPipelineBarrier2(cb, &dep); + } +} + +namespace HAL +{ + // Forward declaration — defined below in present(). + static bool do_acquire(VkDevice, VkSwapchainKHR, VkSemaphore, + uint32_t& out_image, uint32_t& out_frame_index); + + // ---- VkResult diagnostics ----------------------------------------------- + static const char* vk_result_string(VkResult r) + { + switch (r) + { + case VK_SUCCESS: return "VK_SUCCESS"; + case VK_NOT_READY: return "VK_NOT_READY"; + case VK_TIMEOUT: return "VK_TIMEOUT"; + case VK_SUBOPTIMAL_KHR: return "VK_SUBOPTIMAL_KHR"; + case VK_ERROR_OUT_OF_HOST_MEMORY: return "VK_ERROR_OUT_OF_HOST_MEMORY"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + case VK_ERROR_INITIALIZATION_FAILED: return "VK_ERROR_INITIALIZATION_FAILED"; + case VK_ERROR_DEVICE_LOST: return "VK_ERROR_DEVICE_LOST"; + case VK_ERROR_SURFACE_LOST_KHR: return "VK_ERROR_SURFACE_LOST_KHR"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; + case VK_ERROR_OUT_OF_DATE_KHR: return "VK_ERROR_OUT_OF_DATE_KHR"; + case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; + case VK_ERROR_VALIDATION_FAILED_EXT: return "VK_ERROR_VALIDATION_FAILED_EXT"; + case VK_ERROR_INVALID_SHADER_NV: return "VK_ERROR_INVALID_SHADER_NV"; + case VK_ERROR_UNKNOWN: return "VK_ERROR_UNKNOWN"; + default: return ""; + } + } + + // Log a VkResult and dump the key swapchain create-info fields so the + // exact failure reason is always visible in the log. + static void log_swapchain_result(VkResult r, + const VkSwapchainCreateInfoKHR& ci, + const VkSurfaceCapabilitiesKHR& caps) + { + Log::get() << "[Vulkan swapchain] vkCreateSwapchainKHR → " + << vk_result_string(r) << " (" << static_cast(r) << ")" + << Log::endl; + if (r == VK_SUCCESS) return; + + Log::get() << " extent : " + << ci.imageExtent.width << " x " << ci.imageExtent.height << Log::endl; + Log::get() << " surface extent : " + << caps.currentExtent.width << " x " << caps.currentExtent.height + << " min=" << caps.minImageExtent.width << "x" << caps.minImageExtent.height + << " max=" << caps.maxImageExtent.width << "x" << caps.maxImageExtent.height + << Log::endl; + Log::get() << " minImageCount : " << caps.minImageCount + << " maxImageCount=" << caps.maxImageCount + << " requested=" << ci.minImageCount << Log::endl; + Log::get() << " supportedUsage : 0x" << std::hex << caps.supportedUsageFlags + << " requested=0x" << ci.imageUsage << std::dec << Log::endl; + Log::get() << " supportedAlpha : 0x" << std::hex << caps.supportedCompositeAlpha + << " requested=0x" << ci.compositeAlpha << std::dec << Log::endl; + Log::get() << " supportedTransform: 0x" << std::hex << caps.supportedTransforms + << " currentTransform=0x" << caps.currentTransform << std::dec << Log::endl; + } + + SwapChain::SwapChain(Device& device, swap_chain_desc c_desc) : device(device) + { + auto& api_dev = static_cast(device); + if (api_dev.vk_device == VK_NULL_HANDLE) return; + + VkInstance instance = api_dev.vk_instance; + + // ---- Win32 surface -------------------------------------------------- + VkWin32SurfaceCreateInfoKHR surface_ci{ + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR }; + surface_ci.hinstance = GetModuleHandle(nullptr); + surface_ci.hwnd = c_desc.window->get_hwnd(); + vkCreateWin32SurfaceKHR(instance, &surface_ci, nullptr, &vk_surface); + + // ---- Surface capabilities + format ---------------------------------- + VkSurfaceCapabilitiesKHR caps{}; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + api_dev.vk_physical, vk_surface, &caps); + + uint32_t fmt_count = 0; + vkGetPhysicalDeviceSurfaceFormatsKHR( + api_dev.vk_physical, vk_surface, &fmt_count, nullptr); + std::vector formats(fmt_count); + vkGetPhysicalDeviceSurfaceFormatsKHR( + api_dev.vk_physical, vk_surface, &fmt_count, formats.data()); + + // Pick the best available surface format. + // Priority: BGRA8_UNORM → RGBA8_UNORM → BGRA8_SRGB → RGBA8_SRGB → first. + // BGRA8_UNORM matches the D3D12/DXGI convention (DXGI promotes R8G8B8A8 to + // B8G8R8A8 anyway) and is the native Windows DWM format, so it is first. + // UI PSOs are compiled with B8G8R8A8_UNORM to match both backends. + vk_format = formats[0].format; + vk_color_space = formats[0].colorSpace; + VkColorSpaceKHR color_space = formats[0].colorSpace; + { + constexpr VkFormat preferred[] = { + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB, + VK_FORMAT_R8G8B8A8_SRGB, + }; + bool found = false; + for (VkFormat want : preferred) + { + for (auto& f : formats) + { + if (f.format == want && + f.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + { + vk_format = f.format; + vk_color_space = f.colorSpace; + color_space = f.colorSpace; + found = true; break; + } + } + if (found) break; + } + } + Log::get() << "[Vulkan swapchain] " << fmt_count << " surface formats available" + << "; selected format=" << vk_format << Log::endl; + + // Present mode: prefer MAILBOX, fall back to FIFO (always available). + uint32_t pm_count = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR( + api_dev.vk_physical, vk_surface, &pm_count, nullptr); + std::vector present_modes(pm_count); + vkGetPhysicalDeviceSurfacePresentModesKHR( + api_dev.vk_physical, vk_surface, &pm_count, present_modes.data()); + VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; + for (auto pm : present_modes) + if (pm == VK_PRESENT_MODE_MAILBOX_KHR) { present_mode = pm; break; } + + // ---- Swapchain ------------------------------------------------------ + // Request double-buffering (or what the surface supports). + uint32_t desired_images = std::max(2u, caps.minImageCount); + if (caps.maxImageCount > 0) + desired_images = std::min(desired_images, caps.maxImageCount); + + // Extent: when currentExtent is not the "app chooses" sentinel + // (0xFFFFFFFF) the compositor dictates the size — use it directly. + // Otherwise fall back to GetClientRect, clamped to surface limits. + VkExtent2D extent{}; + if (caps.currentExtent.width != UINT32_MAX && + caps.currentExtent.height != UINT32_MAX) + { + extent = caps.currentExtent; + } + else + { + RECT r{}; + GetClientRect(c_desc.window->get_hwnd(), &r); + extent = { + std::clamp(static_cast(std::max(0L, r.right - r.left)), + caps.minImageExtent.width, caps.maxImageExtent.width), + std::clamp(static_cast(std::max(0L, r.bottom - r.top)), + caps.minImageExtent.height, caps.maxImageExtent.height) + }; + } + + Log::get() << "[Vulkan swapchain] caps.currentExtent=" + << caps.currentExtent.width << "x" << caps.currentExtent.height + << " selected extent=" << extent.width << "x" << extent.height + << " minImage=" << caps.minImageCount + << " maxImage=" << caps.maxImageCount + << Log::endl; + + // If the extent is still 0 (window minimised / not yet shown), we + // cannot create a swapchain. Pre-fill `frames` with dummy slots so + // wait_for_free() / get_current_frame() don't crash on empty access. + if (extent.width == 0 || extent.height == 0) + { + Log::get() << "[Vulkan swapchain] zero-size window — deferring " + "swapchain creation; pre-allocating " << desired_images + << " dummy frames" << Log::endl; + frames.resize(desired_images); // FenceWaiter default-constructs to already-signalled + m_frameIndex = 0; + return; + } + + // Pick a supported compositeAlpha; OPAQUE is most common but not universal. + VkCompositeAlphaFlagBitsKHR composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + for (auto flag : { VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR }) + { + if (caps.supportedCompositeAlpha & flag) + { composite_alpha = flag; break; } + } + + VkSwapchainCreateInfoKHR sc_ci{ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; + sc_ci.surface = vk_surface; + sc_ci.minImageCount = desired_images; + sc_ci.imageFormat = vk_format; + sc_ci.imageColorSpace = color_space; + sc_ci.imageExtent = extent; + sc_ci.imageArrayLayers = 1; + sc_ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT; // needed for SRV in descriptor heap + sc_ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + sc_ci.preTransform = caps.currentTransform; + sc_ci.compositeAlpha = composite_alpha; + sc_ci.presentMode = present_mode; + sc_ci.clipped = VK_TRUE; + + sc_extent = extent; // store for on_change() and resize() + { + VkResult r = vkCreateSwapchainKHR(api_dev.vk_device, &sc_ci, nullptr, &vk_swapchain); + log_swapchain_result(r, sc_ci, caps); + if (r != VK_SUCCESS) return; + } + + // ---- Images + views ------------------------------------------------- + vkGetSwapchainImagesKHR(api_dev.vk_device, vk_swapchain, &image_count, nullptr); + swapchain_images.resize(image_count); + vkGetSwapchainImagesKHR( + api_dev.vk_device, vk_swapchain, &image_count, swapchain_images.data()); + + swapchain_views.resize(image_count); + for (uint32_t i = 0; i < image_count; ++i) + { + VkImageViewCreateInfo view_ci{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; + view_ci.image = swapchain_images[i]; + view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_ci.format = vk_format; + view_ci.components = { VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY }; + view_ci.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + vkCreateImageView(api_dev.vk_device, &view_ci, nullptr, &swapchain_views[i]); + } + + // ---- Sync semaphores ------------------------------------------------ + // image_available: free-running ring of (image_count + 1) — see .ixx. + // render_finished: one per swapchain image (waited by vkQueuePresentKHR). + image_available.resize(image_count + 1); + render_finished.resize(image_count); + for (auto& s : image_available) s = make_semaphore(api_dev.vk_device); + for (auto& s : render_finished) s = make_semaphore(api_dev.vk_device); + acquire_counter = 0; + + // ---- Wrap backbuffers as TextureResources --------------------------- + frames.resize(image_count); + m_frameIndex = 0; + on_change(); + + // ---- Present-transition command buffers & semaphores ---------------- + setup_present_commands(api_dev.vk_device, api_dev.get_queue_family( + static_cast(CommandListType::DIRECT))); + + // Transition all fresh images UNDEFINED → PRESENT_SRC_KHR so that + // on_change()'s TextureLayout::PRESENT assumption is valid on frame 0. + { + auto& aq = static_cast(*device.get_queue(CommandListType::DIRECT)); + init_swapchain_layouts(api_dev.vk_device, aq.get_native()); + } + + Log::get() << "Vulkan swapchain: " << image_count << " images, " + << extent.width << "x" << extent.height << Log::endl; + + // Pre-acquire the first image so m_frameIndex is valid before the + // first wait_for_free() + get_current_frame() calls. Use ring slot 0. + do_acquire(api_dev.vk_device, vk_swapchain, + image_available[acquire_counter % image_available.size()], + current_image, m_frameIndex); + + // Wire the image-available wait semaphore into the first execute() call so the + // GPU waits for the presentation engine before writing to the swapchain image. + // render_finished is signalled explicitly in present() (not via pending_signal_sem) + // so it always fires after ALL render command lists — not just the first submit. + auto& api_queue = static_cast(*device.get_queue(CommandListType::DIRECT)); + api_queue.set_frame_semaphores( + image_available[acquire_counter % image_available.size()], VK_NULL_HANDLE); + ++acquire_counter; + } + + void SwapChain::on_change() + { + // Wrap each swapchain image as a TextureResource via NativeImportHandle. + for (uint32_t i = 0; i < image_count; ++i) + { + API::NativeImportHandle handle; + handle.image = swapchain_images[i]; + handle.image_view = swapchain_views[i]; + handle.format = vk_format; + handle.extent = sc_extent; + + frames[i].m_renderTarget.reset( + // PRESENT: We explicitly transition all fresh swapchain images to + // PRESENT_SRC_KHR after creation (see init_swapchain_layouts below), so + // PRESENT is accurate here. The frame graph will emit the correct + // PRESENT_SRC_KHR→COLOR_ATTACHMENT_OPTIMAL barrier on first render. + new TextureResource(device, handle, TextureLayout::PRESENT)); + frames[i].m_renderTarget->set_name( + std::string("swapchain_") + std::to_string(i)); + } + } + + // Helper: acquire the next swapchain image and update m_frameIndex. + // Called at the end of present() (for the NEXT frame) and once in the + // constructor (for the very first frame). Mirrors D3D12's + // GetCurrentBackBufferIndex() pattern so wait_for_free() works unchanged. + static bool do_acquire(VkDevice vk_device, VkSwapchainKHR vk_swapchain, + VkSemaphore sem, + uint32_t& out_image, uint32_t& out_frame_index) + { + VkResult r = vkAcquireNextImageKHR(vk_device, vk_swapchain, + UINT64_MAX, sem, + VK_NULL_HANDLE, &out_image); + if (r == VK_SUCCESS || r == VK_SUBOPTIMAL_KHR) + { + out_frame_index = out_image; + return true; + } + return false; // VK_ERROR_OUT_OF_DATE_KHR or worse + } + + // ---- Present-transition helpers (defined in HAL::API namespace) ----------- +} // namespace HAL +namespace HAL::API +{ + void SwapChain::setup_present_commands(VkDevice vk_dev, uint32_t queue_family) + { + if (vk_dev == VK_NULL_HANDLE || image_count == 0) return; + + // Pool (not pooled with the frame-graph pools — owned exclusively by present()) + VkCommandPoolCreateInfo pool_ci{ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + pool_ci.queueFamilyIndex = queue_family; + vkCreateCommandPool(vk_dev, &pool_ci, nullptr, &present_pool); + if (present_pool == VK_NULL_HANDLE) return; + + present_cbs.resize(image_count, VK_NULL_HANDLE); + present_sems.resize(image_count, VK_NULL_HANDLE); + + VkCommandBufferAllocateInfo alloc_ci{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + alloc_ci.commandPool = present_pool; + alloc_ci.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + alloc_ci.commandBufferCount = image_count; + vkAllocateCommandBuffers(vk_dev, &alloc_ci, present_cbs.data()); + + // Allocate command buffers but do NOT pre-record them. + // They are reset and re-recorded fresh in present() each frame so the + // driver always associates the layout transition with the current + // vkAcquireNextImageKHR acquisition cycle. SIMULTANEOUS_USE_BIT is + // intentionally omitted — we guarantee no re-submission before the + // previous frame's present has completed by waiting on render_finished. + for (uint32_t i = 0; i < image_count; ++i) + present_sems[i] = make_semaphore(vk_dev); + } + + void SwapChain::init_swapchain_layouts(VkDevice vk_dev, VkQueue vk_queue) + { + // Transition every fresh swapchain image from UNDEFINED to PRESENT_SRC_KHR + // so that on_change()'s TextureLayout::PRESENT initial-state assumption holds + // on frame 0. + // + // The Vulkan spec forbids transitioning a presentable image that has not been + // acquired (VUID-vkCmdPipelineBarrier2-image-09373). We therefore loop: + // acquire → transition UNDEFINED→PRESENT_SRC_KHR → present back + // until every image index has been visited. After this function returns all + // images are in PRESENT_SRC_KHR and owned by the presentation engine; the + // caller then does one final do_acquire() to claim the first rendering image. + if (vk_dev == VK_NULL_HANDLE || vk_queue == VK_NULL_HANDLE || + vk_swapchain == VK_NULL_HANDLE || image_count == 0 || + present_pool == VK_NULL_HANDLE || present_cbs.size() < image_count) + return; + + // Allocate one acquire-semaphore and one present-semaphore per iteration. + // Upper bound: visit each image at least once; allow 4× slack for MAILBOX mode + // where the presentation engine may return the same image several times before + // handing back the others. + const uint32_t max_iters = image_count * 4; + std::vector acq_sems (max_iters, VK_NULL_HANDLE); + std::vector pres_sems(max_iters, VK_NULL_HANDLE); + for (auto& s : acq_sems ) s = make_semaphore(vk_dev); + for (auto& s : pres_sems) s = make_semaphore(vk_dev); + + std::vector done(image_count, false); + uint32_t done_count = 0; + + for (uint32_t iter = 0; iter < max_iters && done_count < image_count; ++iter) + { + VkSemaphore acq_sem = acq_sems [iter]; + VkSemaphore pres_sem = pres_sems[iter]; + + uint32_t img_idx = 0; + VkResult r = vkAcquireNextImageKHR(vk_dev, vk_swapchain, + UINT64_MAX, acq_sem, + VK_NULL_HANDLE, &img_idx); + if (r != VK_SUCCESS && r != VK_SUBOPTIMAL_KHR) break; + + // Re-use the per-image present CB slot: reset and re-record. + // For a newly-seen image record UNDEFINED→PRESENT_SRC_KHR; for an + // already-done image record an empty CB (we still need to consume + // acq_sem before presenting). + VkCommandBuffer cb = present_cbs[img_idx]; + vkResetCommandBuffer(cb, 0); + { + VkCommandBufferBeginInfo bi{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + bi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer(cb, &bi); + + if (!done[img_idx]) + { + VkImageMemoryBarrier2 barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; + barrier.srcAccessMask = 0; + barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + barrier.dstAccessMask = 0; + barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + barrier.image = swapchain_images[img_idx]; + barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + + VkDependencyInfo dep{ VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + dep.imageMemoryBarrierCount = 1; + dep.pImageMemoryBarriers = &barrier; + vkCmdPipelineBarrier2(cb, &dep); + + done[img_idx] = true; + ++done_count; + } + + vkEndCommandBuffer(cb); + } + + // Submit: wait on the acquire semaphore, signal the present semaphore. + VkSemaphoreSubmitInfo wait_si{ VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + wait_si.semaphore = acq_sem; + wait_si.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; + + VkSemaphoreSubmitInfo sig_si{ VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + sig_si.semaphore = pres_sem; + sig_si.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + + VkCommandBufferSubmitInfo cb_info{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + cb_info.commandBuffer = cb; + + VkSubmitInfo2 submit{ VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; + submit.waitSemaphoreInfoCount = 1; + submit.pWaitSemaphoreInfos = &wait_si; + submit.commandBufferInfoCount = 1; + submit.pCommandBufferInfos = &cb_info; + submit.signalSemaphoreInfoCount = 1; + submit.pSignalSemaphoreInfos = &sig_si; + vkQueueSubmit2(vk_queue, 1, &submit, VK_NULL_HANDLE); + + // Present the image back so the presentation engine can return it + // on the next acquire (necessary to cycle through all image indices). + VkPresentInfoKHR pi{ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; + pi.waitSemaphoreCount = 1; + pi.pWaitSemaphores = &pres_sem; + pi.swapchainCount = 1; + pi.pSwapchains = &vk_swapchain; + pi.pImageIndices = &img_idx; + vkQueuePresentKHR(vk_queue, &pi); + } + + // Synchronous flush: all presents above are now complete before we return. + vkQueueWaitIdle(vk_queue); + + // Destroy the temporary semaphores (safe: all GPU work has finished). + for (auto s : acq_sems ) if (s) vkDestroySemaphore(vk_dev, s, nullptr); + for (auto s : pres_sems) if (s) vkDestroySemaphore(vk_dev, s, nullptr); + } + + void SwapChain::teardown_present_commands(VkDevice vk_dev) + { + if (vk_dev == VK_NULL_HANDLE) return; + for (auto s : present_sems) + if (s) vkDestroySemaphore(vk_dev, s, nullptr); + present_sems.clear(); + present_cbs.clear(); // freed with pool + if (present_pool) { vkDestroyCommandPool(vk_dev, present_pool, nullptr); present_pool = VK_NULL_HANDLE; } + } + +} // namespace HAL::API +namespace HAL +{ + // ---- SwapChain::present() ----------------------------------------------- + + void SwapChain::present() + { + auto& api_dev = static_cast(device); + auto gfx_queue = device.get_queue(CommandListType::DIRECT); + auto& api_queue = static_cast(*gfx_queue); + + if (vk_swapchain == VK_NULL_HANDLE || image_available.empty()) + return; // zero-size / failed swapchain — nothing to present. + + // Index of the image we are about to present (still identifies this frame's + // image; the acquire below updates current_image to the NEXT frame's image). + const uint32_t presented_image = current_image; + + // =================================================================== + // CRITICAL ORDERING. + // HAL::Queue::execute() does NOT submit synchronously — it ENQUEUES the + // render command buffers onto the queue's single gpu_execute_thread (a FIFO + // worker). If we called vkQueuePresentKHR / vkAcquireNextImageKHR here on + // the *main* thread we would present and re-acquire BEFORE the render was + // even submitted: the presentation engine shows an un-rendered (black) image, + // and validation reports "image not acquired" / "semaphore not waited on". + // + // So we enqueue the ENTIRE present sequence (signal render_finished, present, + // acquire next, wire the next acquire-wait semaphore) onto that same FIFO via + // run(). It therefore executes AFTER all render submits, exactly like the + // D3D12 backend routes Present through queue->run(). Acquire and present run + // on the same thread, satisfying the swapchain's external-sync requirement, + // and pending_wait_sem is only ever touched on the worker thread (no race + // with execute_internal). A promise hands the freshly-acquired frame index + // back to the main thread before present() returns, so the next frame's + // get_current_frame()/compile() read a valid m_frameIndex. + // =================================================================== + const VkDevice vk_dev = api_dev.vk_device; + API::Queue* q = &api_queue; + auto idx_promise = std::make_shared>(); + std::future idx_future = idx_promise->get_future(); + + gfx_queue->run([this, vk_dev, q, presented_image, idx_promise]() + { + API::Queue& api_queue = *q; + // 1) Signal render_finished[presented] after all render CBs (same-thread + // FIFO guarantees those submits already happened). + if (presented_image < static_cast(render_finished.size()) && + render_finished[presented_image] != VK_NULL_HANDLE) + { + VkSemaphoreSubmitInfo rf_sig{ VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + rf_sig.semaphore = render_finished[presented_image]; + rf_sig.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + VkSubmitInfo2 rf_submit{ VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; + rf_submit.signalSemaphoreInfoCount = 1; + rf_submit.pSignalSemaphoreInfos = &rf_sig; + api_queue.submit_raw(rf_submit); + } + + // 2) Present, waiting on render_finished[presented]. The frame graph's + // non_tracked_resources loop already left the image in PRESENT_SRC_KHR. + VkSemaphore wait_sem = render_finished[presented_image]; + uint32_t img = presented_image; + VkPresentInfoKHR pi{ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; + pi.swapchainCount = 1; + pi.pSwapchains = &vk_swapchain; + pi.pImageIndices = &img; + pi.waitSemaphoreCount = (wait_sem != VK_NULL_HANDLE) ? 1u : 0u; + pi.pWaitSemaphores = (wait_sem != VK_NULL_HANDLE) ? &wait_sem : nullptr; + VkResult pr = api_queue.present(pi); + + // 3) Re-assert initial_layout=PRESENT so next frame's compile_transitions + // emits a fresh PRESENT→COLOR_ATTACHMENT barrier. + if (presented_image < static_cast(frames.size()) && + frames[presented_image].m_renderTarget) + { + frames[presented_image].m_renderTarget->get_state_manager() + .init_subres(1, TextureLayout::PRESENT); + } + + // 4) Acquire the NEXT image (free-running ring slot — NOT keyed by image + // index) and wire its wait semaphore into the next render submit. + const uint32_t sem_idx = acquire_counter % image_available.size(); + uint32_t next_image = current_image, next_idx = m_frameIndex; + if (pr != VK_ERROR_OUT_OF_DATE_KHR && + do_acquire(vk_dev, vk_swapchain, + image_available[sem_idx], next_image, next_idx)) + { + current_image = next_image; + m_frameIndex = next_idx; + api_queue.set_frame_semaphores(image_available[sem_idx], VK_NULL_HANDLE); + ++acquire_counter; + } + else + { + m_frameIndex = (m_frameIndex + 1) % image_count; + } + + idx_promise->set_value(); + }); + + // CPU fence so wait_for_free() can pace the next frame. signal() enqueues on + // the same FIFO AFTER the present task, so the ordering is correct. + frames[presented_image].fence_event = gfx_queue->signal(); + + // Block until the worker task has presented + acquired the next image and + // updated m_frameIndex / current_image. This is no more blocking than the + // previous synchronous do_acquire() (it waits on image availability), but now + // it also guarantees the render submit precedes the present on the GPU timeline. + idx_future.wait(); + } + + void SwapChain::resize(ivec2 size) + { + if (size.x < 64) size.x = 64; + if (size.y < 64) size.y = 64; + + // render() calls resize() every frame with the current window size. + // Skip the expensive teardown+recreate when nothing actually changed. + if (vk_swapchain != VK_NULL_HANDLE && + static_cast(sc_extent.width) == size.x && + static_cast(sc_extent.height) == size.y) + return; + + auto& api_dev = static_cast(device); + if (api_dev.vk_device == VK_NULL_HANDLE) return; + + // Wait for all queues idle before destroying swapchain resources. + device.get_queue(CommandListType::DIRECT)->signal_and_wait(); + device.get_queue(CommandListType::COMPUTE)->signal_and_wait(); + device.get_queue(CommandListType::COPY)->signal_and_wait(); + + // Destroy old views, semaphores, and present-transition resources. + teardown_present_commands(api_dev.vk_device); + for (uint32_t i = 0; i < image_count; ++i) + { + frames[i].m_renderTarget = nullptr; + vkDestroyImageView(api_dev.vk_device, swapchain_views[i], nullptr); + vkDestroySemaphore(api_dev.vk_device, render_finished[i], nullptr); + } + // image_available is the (image_count + 1) acquire ring — destroy all of it. + for (auto s : image_available) + if (s) vkDestroySemaphore(api_dev.vk_device, s, nullptr); + swapchain_views.clear(); + swapchain_images.clear(); + image_available.clear(); + render_finished.clear(); + + // Re-create swapchain at new size (reuse existing surface + format). + VkSurfaceCapabilitiesKHR caps{}; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(api_dev.vk_physical, vk_surface, &caps); + + VkExtent2D extent{ + std::clamp(static_cast(size.x), + caps.minImageExtent.width, caps.maxImageExtent.width), + std::clamp(static_cast(size.y), + caps.minImageExtent.height, caps.maxImageExtent.height) + }; + + VkSwapchainCreateInfoKHR sc_ci{ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; + sc_ci.surface = vk_surface; + sc_ci.minImageCount = image_count; + sc_ci.imageFormat = vk_format; + sc_ci.imageColorSpace = vk_color_space; + sc_ci.imageExtent = extent; + sc_ci.imageArrayLayers = 1; + sc_ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT; // needed for SRV in descriptor heap + sc_ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + sc_ci.preTransform = caps.currentTransform; + { + VkCompositeAlphaFlagBitsKHR ca = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + for (auto f : { VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR }) + if (caps.supportedCompositeAlpha & f) { ca = f; break; } + sc_ci.compositeAlpha = ca; + } + sc_ci.presentMode = VK_PRESENT_MODE_FIFO_KHR; + sc_ci.clipped = VK_TRUE; + sc_ci.oldSwapchain = vk_swapchain; // lets driver reuse resources + + sc_extent = extent; // update stored extent + VkSwapchainKHR new_swapchain = VK_NULL_HANDLE; + { + VkResult r = vkCreateSwapchainKHR(api_dev.vk_device, &sc_ci, nullptr, &new_swapchain); + log_swapchain_result(r, sc_ci, caps); + if (r != VK_SUCCESS) return; + } + vkDestroySwapchainKHR(api_dev.vk_device, vk_swapchain, nullptr); + vk_swapchain = new_swapchain; + + // Rebuild images / views / semaphores / wrappers. + vkGetSwapchainImagesKHR(api_dev.vk_device, vk_swapchain, &image_count, nullptr); + swapchain_images.resize(image_count); + vkGetSwapchainImagesKHR( + api_dev.vk_device, vk_swapchain, &image_count, swapchain_images.data()); + + swapchain_views.resize(image_count); + image_available.resize(image_count + 1); + render_finished.resize(image_count); + for (uint32_t i = 0; i < image_count; ++i) + { + VkImageViewCreateInfo view_ci{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; + view_ci.image = swapchain_images[i]; + view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_ci.format = vk_format; + view_ci.components = { VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY }; + view_ci.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + vkCreateImageView(api_dev.vk_device, &view_ci, nullptr, &swapchain_views[i]); + + render_finished[i] = make_semaphore(api_dev.vk_device); + } + // Acquire ring is one larger than image_count (see .ixx). + for (auto& s : image_available) s = make_semaphore(api_dev.vk_device); + acquire_counter = 0; + + frames.resize(image_count); + m_frameIndex = 0; + on_change(); + + // Rebuild present-transition resources for the new images. + setup_present_commands(api_dev.vk_device, + api_dev.get_queue_family(static_cast(CommandListType::DIRECT))); + + // Transition fresh images UNDEFINED → PRESENT_SRC_KHR. + { + auto& aq = static_cast(*device.get_queue(CommandListType::DIRECT)); + init_swapchain_layouts(api_dev.vk_device, aq.get_native()); + } + + // Null out the stale semaphore handles the queue is holding before we + // re-acquire, so a racing execute() sees VK_NULL_HANDLE rather than + // a destroyed semaphore. + auto& api_queue = static_cast(*device.get_queue(CommandListType::DIRECT)); + api_queue.set_frame_semaphores(VK_NULL_HANDLE, VK_NULL_HANDLE); + + // Re-acquire the first image post-resize using ring slot 0, then advance + // the counter so present() rotates through the rest of the ring. + do_acquire(api_dev.vk_device, vk_swapchain, + image_available[acquire_counter % image_available.size()], + current_image, m_frameIndex); + // Wire only the wait side; render_finished is signalled explicitly in present(). + api_queue.set_frame_semaphores( + image_available[acquire_counter % image_available.size()], VK_NULL_HANDLE); + ++acquire_counter; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Swapchain.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Swapchain.ixx new file mode 100644 index 00000000..989f6e02 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Swapchain.ixx @@ -0,0 +1,70 @@ +export module HAL:API.SwapChain; +import vulkan; +import Core; +import :Types; + +export +{ + namespace HAL + { + namespace API + { + class SwapChain + { + protected: + VkSurfaceKHR vk_surface = VK_NULL_HANDLE; + VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE; + VkFormat vk_format = VK_FORMAT_R8G8B8A8_UNORM; + VkColorSpaceKHR vk_color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + VkExtent2D sc_extent = {}; + uint32_t image_count = 0; + uint32_t current_image = 0; // index into swapchain_images[], set by vkAcquireNextImageKHR + + std::vector swapchain_images; + std::vector swapchain_views; + + // Sync objects. + // image_available is a FREE-RUNNING RING indexed by acquire_counter, + // NOT by image index. vkAcquireNextImageKHR can return the same image + // index on consecutive frames (always true under MAILBOX, possible under + // any mode), so tying the acquire semaphore to the image index would reuse + // a semaphore whose previous wait has not yet completed → VUID-01779 + // "Semaphore must not have any pending operations" → GPU hang → device lost. + // Ring size = image_count + 1; per-image fence pacing (wait_for_free) bounds + // frames-in-flight to <= image_count, so the slot acquire_counter reuses is + // always fully drained. render_finished stays per-image (waited by present). + std::vector image_available; // ring of (image_count + 1) + std::vector render_finished; // one per swapchain image + uint32_t acquire_counter = 0; + + // Set during acquire_next_frame(); consumed by present(). + VkSemaphore current_image_available = VK_NULL_HANDLE; + + // Present-time transition infrastructure. + // create_transition_list() in the common HAL is stubbed out, so the + // RENDER_TARGET→PRESENT layout transition never fires from the frame graph. + // We inject it here: one pre-recorded command buffer per swapchain image + // (COLOR_ATTACHMENT_OPTIMAL → PRESENT_SRC_KHR) plus one "image ready for + // present" semaphore per image. The chain in present() is: + // execute() → signals render_finished[I] + // transition_submit waits render_finished[I], signals present_sem[I] + // vkQueuePresentKHR waits present_sem[I] + VkCommandPool present_pool = VK_NULL_HANDLE; + std::vector present_cbs; // COLOR_ATTACHMENT→PRESENT_SRC_KHR + std::vector present_sems; // signalled when transition done + + // Build / destroy the present-transition command buffers and semaphores. + void setup_present_commands(VkDevice vk_dev, uint32_t queue_family); + void teardown_present_commands(VkDevice vk_dev); + + // One-time submit: transition all fresh swapchain images + // UNDEFINED → PRESENT_SRC_KHR so on_change()'s TextureLayout::PRESENT + // initial-state assumption holds true from the very first frame. + void init_swapchain_layouts(VkDevice vk_dev, VkQueue vk_queue); + + public: + virtual ~SwapChain() = default; + }; + } + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.TextureData.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.TextureData.cpp new file mode 100644 index 00000000..948516f9 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.TextureData.cpp @@ -0,0 +1,236 @@ +module; +// PNG encode/decode via the Windows Imaging Component. WIC is portable across +// graphics backends (it is not a D3D/Vulkan dependency), so it gives the Vulkan +// backend the same golden-image PNG support the D3D12 backend gets through +// DirectXTex — without needing `import d3d12`. +#include +#include +#pragma comment(lib, "windowscodecs.lib") +#pragma comment(lib, "ole32.lib") +module HAL:TextureData; + +import Core; +import :Utils; +import :Types; +import :Device; + +// Vulkan implementation of HAL::texture_data. +// Mirrors D3D12/HAL.D3D12.TextureData.cpp. The size/layout math is portable +// (uses Format::surface_info), so the constructors are identical. The file +// loaders use DirectXTex on D3D12; on Vulkan they are stubbed for now (Phase +// 4+: replace with a portable image loader or reuse DirectXTex which is +// API-agnostic for decode and only needs a format table). + +namespace HAL +{ + texture_mip_data::texture_mip_data(UINT w, UINT h, UINT d, Format format) + { + width = w; + height = h; + depth = d; + auto info = format.surface_info({ w, h }); + width_stride = info.rowBytes; + slice_stride = static_cast(info.numBytes); + num_rows = info.numRows; + data.resize(slice_stride * d); + } + + mip::mip(uint32_t count, uint32_t width, uint32_t height, uint32_t depth, Format format) + { + mips.reserve(count); + for (uint32_t i = 0; i < count; i++) + { + mips.emplace_back(std::make_shared(width, height, depth, format)); + width /= 2; if (width < 1) width = 1; + height /= 2; if (height < 1) height = 1; + depth /= 2; if (depth < 1) depth = 1; + } + } + + texture_data::texture_data(uint32_t array_count, uint32_t num_mips, uint32_t width, + uint32_t height, uint32_t depth, Format format) + { + array_size = array_count; + this->depth = depth; + this->format = format; + this->height = height; + this->mip_maps = num_mips; + this->width = width; + array.reserve(array_count); + for (uint32_t i = 0; i < array_count; i++) + array.emplace_back(std::make_shared(num_mips, width, height, depth, format)); + } + + texture_data::ptr texture_data::compress(texture_data::ptr orig) + { + // Phase 4+: BC compression via a portable encoder. For now return the + // original uncompressed data. + return orig; + } + + texture_data::ptr texture_data::load_texture(std::shared_ptr file, int /*flags*/) + { + // WIC's stream decoder auto-detects the container (JPEG/PNG/BMP/…), so + // from_png() handles any of them — decode straight from the file bytes. + if (!file) return nullptr; + auto bytes = file->load_all(); + return from_png(bytes.data(), bytes.size()); + } + + // Build from GPU readback data: strips row padding (layout.row_stride → + // width_stride). Portable — no graphics-API dependency. Identical to the + // D3D12 backend implementation. + texture_data::ptr texture_data::from_readback(uint width, uint height, Format fmt, + std::span gpu_data, + const texture_layout& layout) + { + auto result = std::make_shared(1, 1, width, height, 1, fmt); + auto& mip = result->array[0]->mips[0]; + + uint row_bytes = mip->width_stride; + for (uint row = 0; row < mip->num_rows; ++row) + { + auto src = reinterpret_cast(gpu_data.data()) + row * layout.row_stride; + auto dst = mip->data.data() + row * row_bytes; + std::memcpy(dst, src, row_bytes); + } + return result; + } + + // Encode mip[0] as PNG bytes via WIC. + // Supported formats: R8G8B8A8_UNORM, B8G8R8A8_UNORM/SRGB, R8_UNORM (grayscale). + std::vector texture_data::to_png() const + { + using Microsoft::WRL::ComPtr; + + if (array.empty() || array[0]->mips.empty()) + return {}; + auto& mip = array[0]->mips[0]; + + CoInitializeEx(nullptr, COINIT_MULTITHREADED); // S_FALSE if already inited — fine + + ComPtr factory; + if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, nullptr, + CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory)))) + return {}; + + ComPtr stream; + if (FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream))) + return {}; + + ComPtr encoder; + if (FAILED(factory->CreateEncoder(GUID_ContainerFormatPng, nullptr, &encoder))) + return {}; + encoder->Initialize(stream.Get(), WICBitmapEncoderNoCache); + + ComPtr frame; + ComPtr props; + encoder->CreateNewFrame(&frame, &props); + frame->Initialize(props.Get()); + frame->SetSize(mip->width, mip->height); + + // Pick the WIC pixel format that matches the raw byte layout of mip->data. + WICPixelFormatGUID src_fmt; + WICPixelFormatGUID dst_fmt; + if (format == Format::R8_UNORM) + { + src_fmt = GUID_WICPixelFormat8bppGray; + dst_fmt = GUID_WICPixelFormat8bppGray; + } + else if (format == Format::B8G8R8A8_UNORM || format == Format::B8G8R8A8_UNORM_SRGB) + { + src_fmt = GUID_WICPixelFormat32bppBGRA; + dst_fmt = GUID_WICPixelFormat32bppRGBA; + } + else + { + src_fmt = GUID_WICPixelFormat32bppRGBA; + dst_fmt = GUID_WICPixelFormat32bppRGBA; + } + + WICPixelFormatGUID fmt = dst_fmt; + frame->SetPixelFormat(&fmt); + + const UINT stride = mip->width_stride; + const UINT buf_size = stride * mip->height; + + // Wrap the readback bytes in a WIC bitmap tagged with their real channel + // order, then WriteSource — WIC converts to whatever format the PNG frame + // actually chose. (WritePixels would blindly reinterpret the bytes as the + // frame's native format, swapping R<->B when WIC falls back to BGRA.) + ComPtr bitmap; + if (FAILED(factory->CreateBitmapFromMemory(mip->width, mip->height, + src_fmt, stride, buf_size, + reinterpret_cast(const_cast(mip->data.data())), + &bitmap))) + return {}; + + if (FAILED(frame->WriteSource(bitmap.Get(), nullptr))) + return {}; + frame->Commit(); + encoder->Commit(); + + STATSTG stat{}; + if (FAILED(stream->Stat(&stat, STATFLAG_NONAME))) + return {}; + const ULONG size = static_cast(stat.cbSize.QuadPart); + + std::vector out(size); + LARGE_INTEGER zero{}; + stream->Seek(zero, STREAM_SEEK_SET, nullptr); + ULONG read = 0; + stream->Read(out.data(), size, &read); + out.resize(read); + return out; + } + + // Decode PNG bytes into an R8G8B8A8_UNORM texture_data via WIC. + texture_data::ptr texture_data::from_png(const void* data, size_t size) + { + using Microsoft::WRL::ComPtr; + + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + ComPtr factory; + if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, nullptr, + CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory)))) + return nullptr; + + ComPtr stream; + if (FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream))) + return nullptr; + ULONG written = 0; + stream->Write(data, static_cast(size), &written); + LARGE_INTEGER zero{}; + stream->Seek(zero, STREAM_SEEK_SET, nullptr); + + ComPtr decoder; + if (FAILED(factory->CreateDecoderFromStream(stream.Get(), nullptr, + WICDecodeMetadataCacheOnDemand, &decoder))) + return nullptr; + + ComPtr frame; + if (FAILED(decoder->GetFrame(0, &frame))) + return nullptr; + + UINT w = 0, h = 0; + frame->GetSize(&w, &h); + + // Convert whatever the PNG is to straight 32bpp RGBA. + ComPtr converter; + factory->CreateFormatConverter(&converter); + if (FAILED(converter->Initialize(frame.Get(), GUID_WICPixelFormat32bppRGBA, + WICBitmapDitherTypeNone, nullptr, 0.0, WICBitmapPaletteTypeCustom))) + return nullptr; + + auto result = std::make_shared(1, 1, w, h, 1, Format::R8G8B8A8_UNORM); + auto& mip = result->array[0]->mips[0]; + + const UINT stride = w * 4; + const UINT buf_size = stride * h; + if (FAILED(converter->CopyPixels(nullptr, stride, buf_size, mip->data.data()))) + return nullptr; + + return result; + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.TiledMemoryManager.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.TiledMemoryManager.cpp new file mode 100644 index 00000000..2c5203e9 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.TiledMemoryManager.cpp @@ -0,0 +1,94 @@ +module HAL:TiledMemoryManager; +import Core; +import HAL; + +// Vulkan stub for TiledResourceManager::init_tilings(). +// +// Real Vulkan sparse resources (VK_KHR_sparse_resources) are a post-Phase-0 +// feature. However, we must populate the CPU-side `tiles` grid so that the +// common streaming code (load_tile, zero_tile, etc.) doesn't crash on +// out-of-bounds access — it always indexes tiles[subres][pos] without +// re-checking is_tiled() first. +// +// The tile mappings are never sent to the GPU (Queue::update_tile_mappings +// is a no-op), so RESERVED resources in Vulkan are simply invisible to +// shaders. That is acceptable for Phase 0. + +namespace HAL +{ + static constexpr uint TILE_SIZE = 64 * 1024; // 64 KB — standard Vulkan sparse tile + + void TiledResourceManager::init_tilings() + { + auto desc = resource->get_desc(); + + if (desc.is_buffer()) + { + // Buffers: a flat 1-D array of 64 KB tiles. + const size_t bytes = desc.as_buffer().SizeInBytes; + const uint num_tiles = std::max(1u, static_cast( + (bytes + TILE_SIZE - 1) / TILE_SIZE)); + + tile_shape = { TILE_SIZE, 1, 1 }; + packed_mip_count = 0; + unpacked_mip_count = 0; + packed_subresource_offset = 0; + + tiles.resize(1); + tiles[0].resize(uint3{ num_tiles, 1, 1 }); + for (uint x = 0; x < num_tiles; ++x) + tiles[0][{x, 0, 0}].pos = { x, 0, 0 }; + + gpu_tiles.resize(1); + gpu_tiles[0].resize(uint3{ num_tiles, 1, 1 }); + for (uint x = 0; x < num_tiles; ++x) + gpu_tiles[0][{x, 0, 0}].pos = { x, 0, 0 }; + } + else if (desc.is_texture()) + { + auto& tex = desc.as_texture(); + + // Simple tile shape: 128 x 128 texels (works for most formats at 32 bpp). + // Vulkan sparse block sizes are format-dependent; this approximation is + // sufficient to keep the CPU tile grid alive without crashing. + const uint tile_w = 128u; + const uint tile_h = 128u; + const uint tile_d = 1u; + + tile_shape = { tile_w, tile_h, tile_d }; + + // Standard mip layout: all mips get a tile grid; no packed mips stub. + const uint mips = std::max(1u, tex.MipLevels); + packed_mip_count = 0; + unpacked_mip_count = mips; + packed_subresource_offset = mips; + + tiles.resize(mips); + gpu_tiles.resize(mips); + + for (uint m = 0; m < mips; ++m) + { + uint3 mip_dim = uint3::max({ 1, 1, 1 }, + tex.Dimensions / (uint)std::pow(2, m)); + + uint xt = std::max(1u, (mip_dim.x + tile_w - 1) / tile_w); + uint yt = std::max(1u, (mip_dim.y + tile_h - 1) / tile_h); + uint zt = std::max(1u, tex.is3D() + ? (mip_dim.z + tile_d - 1) / tile_d : 1u); + + tiles[m].resize(uint3(xt, yt, zt)); + gpu_tiles[m].resize(uint3(xt, yt, zt)); + + for (uint x = 0; x < xt; ++x) + for (uint y = 0; y < yt; ++y) + for (uint z = 0; z < zt; ++z) + { + tiles[m][{x,y,z}].pos = { x, y, z }; + tiles[m][{x,y,z}].subresource = m; + gpu_tiles[m][{x,y,z}].pos = { x, y, z }; + gpu_tiles[m][{x,y,z}].subresource = m; + } + } + } + } +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Utils.cpp b/sources/HAL/API/Vulkan/HAL.Vulkan.Utils.cpp new file mode 100644 index 00000000..3dfdceed --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Utils.cpp @@ -0,0 +1,401 @@ +module; +// Global module fragment: include Vulkan headers directly so that +// `static const VkPipelineStageFlagBits2` / `VkAccessFlagBits2` values +// (VK_PIPELINE_STAGE_2_*, VK_ACCESS_2_*) are visible as file-scope names. +// MSVC does not export `static const` namespace-scope variables from header +// units, so `import vulkan;` alone is not enough for these types. +#define VK_USE_PLATFORM_WIN32_KHR +#include +#include +module HAL:Utils; +import stl.core; +import Core; + +// Vulkan conversion helpers: HAL abstract types → Vulkan native types. +// These mirror the to_native() / from_native() functions provided by the +// D3D12 Utils for D3D12 types. Only the conversions needed through Phase 3 +// (clear screen) are implemented here; pipeline/sampler conversions arrive +// in Phase 4. +// +// Defined at global scope with `using namespace HAL` to match the D3D12 Utils +// convention and the declarations in HAL.Vulkan.Utils.ixx. + +using namespace HAL; + +// ============================================================================ +// Format +// ============================================================================ + +VkFormat to_native(Format format) +{ + switch (format) + { + // ---- 8-bit --------------------------------------------------------------- + case Format::R8_UNORM: return VK_FORMAT_R8_UNORM; + case Format::R8_UINT: return VK_FORMAT_R8_UINT; + case Format::R8_SNORM: return VK_FORMAT_R8_SNORM; + case Format::R8_SINT: return VK_FORMAT_R8_SINT; + case Format::R8G8_UNORM: return VK_FORMAT_R8G8_UNORM; + case Format::R8G8_UINT: return VK_FORMAT_R8G8_UINT; + case Format::R8G8_SNORM: return VK_FORMAT_R8G8_SNORM; + case Format::R8G8_SINT: return VK_FORMAT_R8G8_SINT; + case Format::R8G8B8A8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM; + case Format::R8G8B8A8_UNORM_SRGB: return VK_FORMAT_R8G8B8A8_SRGB; + case Format::R8G8B8A8_UINT: return VK_FORMAT_R8G8B8A8_UINT; + case Format::R8G8B8A8_SNORM: return VK_FORMAT_R8G8B8A8_SNORM; + case Format::R8G8B8A8_SINT: return VK_FORMAT_R8G8B8A8_SINT; + case Format::B8G8R8A8_UNORM: return VK_FORMAT_B8G8R8A8_UNORM; + case Format::B8G8R8A8_UNORM_SRGB: return VK_FORMAT_B8G8R8A8_SRGB; + // ---- 16-bit -------------------------------------------------------------- + case Format::R16_FLOAT: return VK_FORMAT_R16_SFLOAT; + case Format::R16_UNORM: return VK_FORMAT_R16_UNORM; + case Format::R16_UINT: return VK_FORMAT_R16_UINT; + case Format::R16_SNORM: return VK_FORMAT_R16_SNORM; + case Format::R16_SINT: return VK_FORMAT_R16_SINT; + case Format::R16G16_FLOAT: return VK_FORMAT_R16G16_SFLOAT; + case Format::R16G16_UNORM: return VK_FORMAT_R16G16_UNORM; + case Format::R16G16_UINT: return VK_FORMAT_R16G16_UINT; + case Format::R16G16_SNORM: return VK_FORMAT_R16G16_SNORM; + case Format::R16G16_SINT: return VK_FORMAT_R16G16_SINT; + case Format::R16G16B16A16_FLOAT: return VK_FORMAT_R16G16B16A16_SFLOAT; + case Format::R16G16B16A16_UNORM: return VK_FORMAT_R16G16B16A16_UNORM; + case Format::R16G16B16A16_UINT: return VK_FORMAT_R16G16B16A16_UINT; + case Format::R16G16B16A16_SNORM: return VK_FORMAT_R16G16B16A16_SNORM; + case Format::R16G16B16A16_SINT: return VK_FORMAT_R16G16B16A16_SINT; + // ---- 32-bit -------------------------------------------------------------- + case Format::R32_FLOAT: return VK_FORMAT_R32_SFLOAT; + case Format::R32_UINT: return VK_FORMAT_R32_UINT; + case Format::R32_SINT: return VK_FORMAT_R32_SINT; + case Format::R32G32_FLOAT: return VK_FORMAT_R32G32_SFLOAT; + case Format::R32G32_UINT: return VK_FORMAT_R32G32_UINT; + case Format::R32G32_SINT: return VK_FORMAT_R32G32_SINT; + case Format::R32G32B32_FLOAT: return VK_FORMAT_R32G32B32_SFLOAT; + case Format::R32G32B32_UINT: return VK_FORMAT_R32G32B32_UINT; + case Format::R32G32B32_SINT: return VK_FORMAT_R32G32B32_SINT; + case Format::R32G32B32A32_FLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT; + case Format::R32G32B32A32_UINT: return VK_FORMAT_R32G32B32A32_UINT; + case Format::R32G32B32A32_SINT: return VK_FORMAT_R32G32B32A32_SINT; + // ---- packed -------------------------------------------------------------- + case Format::R10G10B10A2_UNORM: return VK_FORMAT_A2B10G10R10_UNORM_PACK32; + case Format::R10G10B10A2_UINT: return VK_FORMAT_A2B10G10R10_UINT_PACK32; + case Format::R11G11B10_FLOAT: return VK_FORMAT_B10G11R11_UFLOAT_PACK32; + case Format::R9G9B9E5_SHAREDEXP: return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32; + case Format::B5G6R5_UNORM: return VK_FORMAT_R5G6B5_UNORM_PACK16; + case Format::B5G5R5A1_UNORM: return VK_FORMAT_A1R5G5B5_UNORM_PACK16; + // ---- depth/stencil ------------------------------------------------------- + case Format::D16_UNORM: return VK_FORMAT_D16_UNORM; + case Format::D24_UNORM_S8_UINT: return VK_FORMAT_D24_UNORM_S8_UINT; + case Format::D32_FLOAT: return VK_FORMAT_D32_SFLOAT; + case Format::D32_FLOAT_S8X24_UINT: return VK_FORMAT_D32_SFLOAT_S8_UINT; + // ---- block-compressed ---------------------------------------------------- + case Format::BC1_UNORM: return VK_FORMAT_BC1_RGBA_UNORM_BLOCK; + case Format::BC1_UNORM_SRGB: return VK_FORMAT_BC1_RGBA_SRGB_BLOCK; + case Format::BC2_UNORM: return VK_FORMAT_BC2_UNORM_BLOCK; + case Format::BC2_UNORM_SRGB: return VK_FORMAT_BC2_SRGB_BLOCK; + case Format::BC3_UNORM: return VK_FORMAT_BC3_UNORM_BLOCK; + case Format::BC3_UNORM_SRGB: return VK_FORMAT_BC3_SRGB_BLOCK; + case Format::BC4_UNORM: return VK_FORMAT_BC4_UNORM_BLOCK; + case Format::BC4_SNORM: return VK_FORMAT_BC4_SNORM_BLOCK; + case Format::BC5_UNORM: return VK_FORMAT_BC5_UNORM_BLOCK; + case Format::BC5_SNORM: return VK_FORMAT_BC5_SNORM_BLOCK; + case Format::BC6H_UF16: return VK_FORMAT_BC6H_UFLOAT_BLOCK; + case Format::BC6H_SF16: return VK_FORMAT_BC6H_SFLOAT_BLOCK; + case Format::BC7_UNORM: return VK_FORMAT_BC7_UNORM_BLOCK; + case Format::BC7_UNORM_SRGB: return VK_FORMAT_BC7_SRGB_BLOCK; + // ---- TYPELESS → concrete ------------------------------------------------- + // Vulkan has no typeless formats; a typeless D3D12 resource maps to the + // natural typed format and is reinterpreted per-view (images that need it + // are created with VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT). + case Format::R32G32B32A32_TYPELESS: return VK_FORMAT_R32G32B32A32_SFLOAT; + case Format::R32G32B32_TYPELESS: return VK_FORMAT_R32G32B32_SFLOAT; + case Format::R16G16B16A16_TYPELESS: return VK_FORMAT_R16G16B16A16_SFLOAT; + case Format::R32G32_TYPELESS: return VK_FORMAT_R32G32_SFLOAT; + case Format::R10G10B10A2_TYPELESS: return VK_FORMAT_A2B10G10R10_UNORM_PACK32; + case Format::R8G8B8A8_TYPELESS: return VK_FORMAT_R8G8B8A8_UNORM; + case Format::B8G8R8A8_TYPELESS: return VK_FORMAT_B8G8R8A8_UNORM; + case Format::R16G16_TYPELESS: return VK_FORMAT_R16G16_SFLOAT; + case Format::R32_TYPELESS: return VK_FORMAT_R32_SFLOAT; + case Format::R8G8_TYPELESS: return VK_FORMAT_R8G8_UNORM; + case Format::R16_TYPELESS: return VK_FORMAT_R16_SFLOAT; + case Format::R8_TYPELESS: return VK_FORMAT_R8_UNORM; + case Format::R24G8_TYPELESS: return VK_FORMAT_D24_UNORM_S8_UINT; + case Format::R32G8X24_TYPELESS: return VK_FORMAT_D32_SFLOAT_S8_UINT; + case Format::BC1_TYPELESS: return VK_FORMAT_BC1_RGBA_UNORM_BLOCK; + case Format::BC2_TYPELESS: return VK_FORMAT_BC2_UNORM_BLOCK; + case Format::BC3_TYPELESS: return VK_FORMAT_BC3_UNORM_BLOCK; + case Format::BC4_TYPELESS: return VK_FORMAT_BC4_UNORM_BLOCK; + case Format::BC5_TYPELESS: return VK_FORMAT_BC5_UNORM_BLOCK; + case Format::BC6H_TYPELESS: return VK_FORMAT_BC6H_UFLOAT_BLOCK; + case Format::BC7_TYPELESS: return VK_FORMAT_BC7_UNORM_BLOCK; + // ---- formats with no direct Vulkan equivalent ---------------------------- + // TYPELESS formats have no Vulkan analogue; callers should resolve to a + // typed format before calling to_native(). + // A8_UNORM, R1_UNORM, subsampled YUV formats, etc. are also unsupported. + default: + Log::get() << "[Vulkan] to_native(Format): unhandled HAL format " + << static_cast(static_cast(format)) + << " — returning VK_FORMAT_UNDEFINED" << Log::endl; + ASSERT(false && "to_native(Format): unhandled format — see log"); + return VK_FORMAT_UNDEFINED; + } +} + +Format from_native(VkFormat format) +{ + switch (format) + { + case VK_FORMAT_R8_UNORM: return Format::R8_UNORM; + case VK_FORMAT_R8_UINT: return Format::R8_UINT; + case VK_FORMAT_R8_SNORM: return Format::R8_SNORM; + case VK_FORMAT_R8_SINT: return Format::R8_SINT; + case VK_FORMAT_R8G8_UNORM: return Format::R8G8_UNORM; + case VK_FORMAT_R8G8_UINT: return Format::R8G8_UINT; + case VK_FORMAT_R8G8_SNORM: return Format::R8G8_SNORM; + case VK_FORMAT_R8G8_SINT: return Format::R8G8_SINT; + case VK_FORMAT_R8G8B8A8_UNORM: return Format::R8G8B8A8_UNORM; + case VK_FORMAT_R8G8B8A8_SRGB: return Format::R8G8B8A8_UNORM_SRGB; + case VK_FORMAT_R8G8B8A8_UINT: return Format::R8G8B8A8_UINT; + case VK_FORMAT_R8G8B8A8_SNORM: return Format::R8G8B8A8_SNORM; + case VK_FORMAT_R8G8B8A8_SINT: return Format::R8G8B8A8_SINT; + case VK_FORMAT_B8G8R8A8_UNORM: return Format::B8G8R8A8_UNORM; + case VK_FORMAT_B8G8R8A8_SRGB: return Format::B8G8R8A8_UNORM_SRGB; + case VK_FORMAT_R16_SFLOAT: return Format::R16_FLOAT; + case VK_FORMAT_R16_UNORM: return Format::R16_UNORM; + case VK_FORMAT_R16_UINT: return Format::R16_UINT; + case VK_FORMAT_R16_SNORM: return Format::R16_SNORM; + case VK_FORMAT_R16_SINT: return Format::R16_SINT; + case VK_FORMAT_R16G16_SFLOAT: return Format::R16G16_FLOAT; + case VK_FORMAT_R16G16_UNORM: return Format::R16G16_UNORM; + case VK_FORMAT_R16G16_UINT: return Format::R16G16_UINT; + case VK_FORMAT_R16G16_SNORM: return Format::R16G16_SNORM; + case VK_FORMAT_R16G16_SINT: return Format::R16G16_SINT; + case VK_FORMAT_R16G16B16A16_SFLOAT: return Format::R16G16B16A16_FLOAT; + case VK_FORMAT_R16G16B16A16_UNORM: return Format::R16G16B16A16_UNORM; + case VK_FORMAT_R16G16B16A16_UINT: return Format::R16G16B16A16_UINT; + case VK_FORMAT_R16G16B16A16_SNORM: return Format::R16G16B16A16_SNORM; + case VK_FORMAT_R16G16B16A16_SINT: return Format::R16G16B16A16_SINT; + case VK_FORMAT_R32_SFLOAT: return Format::R32_FLOAT; + case VK_FORMAT_R32_UINT: return Format::R32_UINT; + case VK_FORMAT_R32_SINT: return Format::R32_SINT; + case VK_FORMAT_R32G32_SFLOAT: return Format::R32G32_FLOAT; + case VK_FORMAT_R32G32_UINT: return Format::R32G32_UINT; + case VK_FORMAT_R32G32_SINT: return Format::R32G32_SINT; + case VK_FORMAT_R32G32B32_SFLOAT: return Format::R32G32B32_FLOAT; + case VK_FORMAT_R32G32B32_UINT: return Format::R32G32B32_UINT; + case VK_FORMAT_R32G32B32_SINT: return Format::R32G32B32_SINT; + case VK_FORMAT_R32G32B32A32_SFLOAT: return Format::R32G32B32A32_FLOAT; + case VK_FORMAT_R32G32B32A32_UINT: return Format::R32G32B32A32_UINT; + case VK_FORMAT_R32G32B32A32_SINT: return Format::R32G32B32A32_SINT; + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return Format::R10G10B10A2_UNORM; + case VK_FORMAT_A2B10G10R10_UINT_PACK32: return Format::R10G10B10A2_UINT; + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: return Format::R11G11B10_FLOAT; + case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: return Format::R9G9B9E5_SHAREDEXP; + case VK_FORMAT_R5G6B5_UNORM_PACK16: return Format::B5G6R5_UNORM; + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: return Format::B5G5R5A1_UNORM; + case VK_FORMAT_D16_UNORM: return Format::D16_UNORM; + case VK_FORMAT_D32_SFLOAT: return Format::D32_FLOAT; + case VK_FORMAT_D24_UNORM_S8_UINT: return Format::D24_UNORM_S8_UINT; + case VK_FORMAT_D32_SFLOAT_S8_UINT: return Format::D32_FLOAT_S8X24_UINT; + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return Format::BC1_UNORM; + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: return Format::BC1_UNORM_SRGB; + case VK_FORMAT_BC2_UNORM_BLOCK: return Format::BC2_UNORM; + case VK_FORMAT_BC2_SRGB_BLOCK: return Format::BC2_UNORM_SRGB; + case VK_FORMAT_BC3_UNORM_BLOCK: return Format::BC3_UNORM; + case VK_FORMAT_BC3_SRGB_BLOCK: return Format::BC3_UNORM_SRGB; + case VK_FORMAT_BC4_UNORM_BLOCK: return Format::BC4_UNORM; + case VK_FORMAT_BC4_SNORM_BLOCK: return Format::BC4_SNORM; + case VK_FORMAT_BC5_UNORM_BLOCK: return Format::BC5_UNORM; + case VK_FORMAT_BC5_SNORM_BLOCK: return Format::BC5_SNORM; + case VK_FORMAT_BC6H_UFLOAT_BLOCK: return Format::BC6H_UF16; + case VK_FORMAT_BC6H_SFLOAT_BLOCK: return Format::BC6H_SF16; + case VK_FORMAT_BC7_UNORM_BLOCK: return Format::BC7_UNORM; + case VK_FORMAT_BC7_SRGB_BLOCK: return Format::BC7_UNORM_SRGB; + default: + Log::get() << "[Vulkan] from_native(VkFormat): unhandled VkFormat " + << static_cast(format) + << " — returning Format::UNKNOWN" << Log::endl; + ASSERT(false && "from_native(VkFormat): unhandled format — see log"); + return Format::UNKNOWN; + } +} + +// ============================================================================ +// TextureLayout → VkImageLayout +// NOTE: TextureLayout is a sequential enum (not bit flags), so use a switch. +// ============================================================================ + +VkImageLayout to_native(TextureLayout layout) +{ + switch (layout) + { + case TextureLayout::UNDEFINED: return VK_IMAGE_LAYOUT_UNDEFINED; + case TextureLayout::PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; // == COMMON + // case TextureLayout::GENERIC_READ: return VK_IMAGE_LAYOUT_GENERAL; + case TextureLayout::RENDER_TARGET: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + case TextureLayout::UNORDERED_ACCESS: return VK_IMAGE_LAYOUT_GENERAL; + case TextureLayout::DEPTH_STENCIL_WRITE: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + case TextureLayout::DEPTH_STENCIL_READ: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + // GENERAL instead of SHADER_READ_ONLY_OPTIMAL: D3D12 descriptors carry no + // embedded layout, so the same slot is validly used as both SRV and UAV + // without ever becoming "stale." Vulkan's VkDescriptorImageInfo embeds a + // layout, causing Warning 529 when a bindless STORAGE_IMAGE slot still + // says GENERAL while the image has been transitioned back to + // SHADER_READ_ONLY. By keeping ALL shader-accessible images in GENERAL we + // match D3D12 semantics: one stable layout for any shader access. + // (GENERAL is a valid layout for VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE per spec.) + case TextureLayout::SHADER_RESOURCE: return VK_IMAGE_LAYOUT_GENERAL; + case TextureLayout::COPY_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case TextureLayout::COPY_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + // case TextureLayout::RESOLVE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + // case TextureLayout::RESOLVE_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + default: return VK_IMAGE_LAYOUT_GENERAL; + } +} + +// ============================================================================ +// BarrierSync → VkPipelineStageFlags2 (synchronization2) +// ============================================================================ + +VkPipelineStageFlags2 to_native_stage(BarrierSync sync) +{ + if (sync == BarrierSync::NONE) return VK_PIPELINE_STAGE_2_NONE; + //if (check(sync & BarrierSync::ALL)) return VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + + VkPipelineStageFlags2 result = VK_PIPELINE_STAGE_2_NONE; + if (check(sync & BarrierSync::DRAW)) result |= VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT; + //if (check(sync & BarrierSync::INPUT_ASSEMBLER)) result |= VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT; + if (check(sync & BarrierSync::VERTEX_SHADING)) result |= VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT; + if (check(sync & BarrierSync::PIXEL_SHADING)) result |= VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; + if (check(sync & BarrierSync::DEPTH_STENCIL)) result |= VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT; + if (check(sync & BarrierSync::RENDER_TARGET)) result |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + if (check(sync & BarrierSync::COMPUTE_SHADING)) result |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + if (check(sync & BarrierSync::RAYTRACING)) result |= VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR; + if (check(sync & BarrierSync::COPY)) result |= VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT; + if (check(sync & BarrierSync::RESOLVE)) result |= VK_PIPELINE_STAGE_2_RESOLVE_BIT; + if (check(sync & BarrierSync::EXECUTE_INDIRECT)) result |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT; + if (check(sync & BarrierSync::ALL_SHADING)) result |= VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + if (check(sync & BarrierSync::BUILD_RAYTRACING_ACCELERATION_STRUCTURE)) result |= VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR; + return result; +} + +// ============================================================================ +// BarrierAccess → VkAccessFlags2 +// ============================================================================ + +VkAccessFlags2 to_native_access(BarrierAccess access) +{ + if (check(access & BarrierAccess::NO_ACCESS)) return VK_ACCESS_2_NONE; + + VkAccessFlags2 result = VK_ACCESS_2_NONE; + if (check(access & BarrierAccess::VERTEX_BUFFER)) result |= VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT; + if (check(access & BarrierAccess::CONSTANT_BUFFER)) result |= VK_ACCESS_2_UNIFORM_READ_BIT; + if (check(access & BarrierAccess::INDEX_BUFFER)) result |= VK_ACCESS_2_INDEX_READ_BIT; + if (check(access & BarrierAccess::RENDER_TARGET)) result |= VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + if (check(access & BarrierAccess::UNORDERED_ACCESS)) result |= VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT; + if (check(access & BarrierAccess::DEPTH_STENCIL_WRITE)) result |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + if (check(access & BarrierAccess::DEPTH_STENCIL_READ)) result |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + if (check(access & BarrierAccess::SHADER_RESOURCE)) result |= VK_ACCESS_2_SHADER_READ_BIT; + if (check(access & BarrierAccess::INDIRECT_ARGUMENT)) result |= VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT; + if (check(access & BarrierAccess::COPY_DEST)) result |= VK_ACCESS_2_TRANSFER_WRITE_BIT; + if (check(access & BarrierAccess::COPY_SOURCE)) result |= VK_ACCESS_2_TRANSFER_READ_BIT; + if (check(access & BarrierAccess::RESOLVE_DEST)) result |= VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + if (check(access & BarrierAccess::RESOLVE_SOURCE)) result |= VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT; + if (check(access & BarrierAccess::RAYTRACING_ACCELERATION_STRUCTURE_READ)) result |= VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR; + if (check(access & BarrierAccess::RAYTRACING_ACCELERATION_STRUCTURE_WRITE)) result |= VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR; + return result; +} + +// ============================================================================ +// CommandListType → Vulkan queue family flags +// ============================================================================ + +VkQueueFlagBits to_native_queue(CommandListType type) +{ + switch (type) + { + case CommandListType::DIRECT: return VK_QUEUE_GRAPHICS_BIT; + case CommandListType::COMPUTE: return VK_QUEUE_COMPUTE_BIT; + case CommandListType::COPY: return VK_QUEUE_TRANSFER_BIT; + default: return VK_QUEUE_GRAPHICS_BIT; + } +} + +// ============================================================================ +// Sampler conversion helpers +// ============================================================================ + +VkFilter to_native_filter(Filter f) +{ + switch (f) + { + case Filter::POINT: return VK_FILTER_NEAREST; + case Filter::ANISOTROPIC: return VK_FILTER_LINEAR; + default: return VK_FILTER_LINEAR; + } +} + +VkSamplerMipmapMode to_native_mipmap(Filter f) +{ + return (f == Filter::POINT) ? VK_SAMPLER_MIPMAP_MODE_NEAREST + : VK_SAMPLER_MIPMAP_MODE_LINEAR; +} + +VkSamplerAddressMode to_native(TextureAddressMode mode) +{ + switch (mode) + { + case TextureAddressMode::WRAP: return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case TextureAddressMode::MIRROR: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case TextureAddressMode::CLAMP: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case TextureAddressMode::BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + case TextureAddressMode::MIRROR_ONCE: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; + default: return VK_SAMPLER_ADDRESS_MODE_REPEAT; + } +} + +VkCompareOp to_native(ComparisonFunc func) +{ + switch (func) + { + case ComparisonFunc::NONE: return VK_COMPARE_OP_ALWAYS; + case ComparisonFunc::NEVER: return VK_COMPARE_OP_NEVER; + case ComparisonFunc::LESS: return VK_COMPARE_OP_LESS; + case ComparisonFunc::EQUAL: return VK_COMPARE_OP_EQUAL; + case ComparisonFunc::LESS_EQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL; + case ComparisonFunc::GREATER: return VK_COMPARE_OP_GREATER; + case ComparisonFunc::NOT_EQUAL: return VK_COMPARE_OP_NOT_EQUAL; + case ComparisonFunc::GREATER_EQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL; + case ComparisonFunc::ALWAYS: return VK_COMPARE_OP_ALWAYS; + default: return VK_COMPARE_OP_ALWAYS; + } +} + +VkSamplerCreateInfo to_native_sampler_ci(const SamplerDesc& desc) +{ + VkSamplerCreateInfo ci{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; + ci.magFilter = to_native_filter(desc.MagFilter); + ci.minFilter = to_native_filter(desc.MinFilter); + ci.mipmapMode = to_native_mipmap(desc.MipFilter); + ci.addressModeU = to_native(desc.AddressU); + ci.addressModeV = to_native(desc.AddressV); + ci.addressModeW = to_native(desc.AddressW); + ci.mipLodBias = desc.MipLODBias; + ci.anisotropyEnable = (desc.MinFilter == Filter::ANISOTROPIC || + desc.MagFilter == Filter::ANISOTROPIC) ? VK_TRUE : VK_FALSE; + ci.maxAnisotropy = static_cast(desc.MaxAnisotropy); + ci.compareEnable = (desc.ComparisonFunc != ComparisonFunc::NONE) ? VK_TRUE : VK_FALSE; + ci.compareOp = to_native(desc.ComparisonFunc); + ci.minLod = desc.MinLOD; + ci.maxLod = desc.MaxLOD; + // Border color: Vulkan only supports a fixed set. + // All HAL SamplerDesc border colors are (1,1,1,1) → opaque white. + const auto& bc = desc.BorderColor; + if (bc.x == 0.f && bc.y == 0.f && bc.z == 0.f && bc.w == 0.f) + ci.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + else if (bc.x == 0.f && bc.y == 0.f && bc.z == 0.f) + ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; + else + ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; + ci.unnormalizedCoordinates = VK_FALSE; + return ci; +} diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.Utils.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.Utils.ixx new file mode 100644 index 00000000..6c21adc5 --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.Utils.ixx @@ -0,0 +1,240 @@ +export module HAL:Utils; + +import stl.core; +import vulkan; +import Core; + +import :Types; +import :Sampler; +using namespace HAL; + +export namespace HAL +{ + // Backend identifier used to segregate per-backend caches (shaders, PSOs). + // Textures are backend-agnostic and stay in the cache root. + inline std::string get_backend_name() { return "vulkan"; } +} + +// ============================================================================ +// Compatibility stubs for D3D12 types used in common HAL files. +// In D3D12 builds, these come from d3d12.h/dxgi.h via the D3D12 Utils +// partition. In Vulkan builds, we supply minimal-compatible definitions that +// share the same field names so common code compiles without any #ifdefs. +// ============================================================================ + +export +{ + // --- D3D12 descriptor handle stubs --- + // Used by HAL::Handle::get_cpu() / get_gpu() in HAL.DescriptorHeap.ixx. + struct D3D12_CPU_DESCRIPTOR_HANDLE { size_t ptr = 0; }; + struct D3D12_GPU_DESCRIPTOR_HANDLE { uint64_t ptr = 0; }; + + // --- DXGI adapter description stub --- + // Used by HAL::Device::create_singleton() in HAL.Device.cpp. + struct DXGI_ADAPTER_DESC + { + wchar_t Description[128] = {}; + unsigned VendorId = 0; + unsigned DeviceId = 0; + unsigned SubSysId = 0; + unsigned Revision = 0; + size_t DedicatedVideoMemory = 0; + size_t DedicatedSystemMemory = 0; + size_t SharedSystemMemory = 0; + }; + + // --- D3D12 dispatch / draw argument stubs --- + // Used by IndirectCommand template machinery. + struct D3D12_DISPATCH_ARGUMENTS + { + unsigned ThreadGroupCountX = 0; + unsigned ThreadGroupCountY = 0; + unsigned ThreadGroupCountZ = 0; + }; + struct D3D12_DRAW_INDEXED_ARGUMENTS + { + unsigned IndexCountPerInstance = 0; + unsigned InstanceCount = 0; + unsigned StartIndexLocation = 0; + int BaseVertexLocation = 0; + unsigned StartInstanceLocation = 0; + }; + // D3D12_DISPATCH_MESH_ARGUMENTS — used in IndirectCommand stubs + struct D3D12_DISPATCH_MESH_ARGUMENTS + { + unsigned ThreadGroupCountX = 0; + unsigned ThreadGroupCountY = 0; + unsigned ThreadGroupCountZ = 0; + }; + + // --- D3D12_PROGRAM_IDENTIFIER stub (used by API::StateObject) --- + struct D3D12_PROGRAM_IDENTIFIER + { + uint64_t OpaqueData[4] = {}; + }; + + // --- D3D12CalcSubresource stub --- + // Utility from d3dx12.h: computes a flat subresource index from + // (MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize). + // Used in RenderSystem/Font/TextSystem.cpp. + // TODO (REFACTOR_TODO §2): replace call-site with + // TextureDesc::CalcSubresource() which already exists in HAL::TextureDesc. + inline constexpr unsigned D3D12CalcSubresource( + unsigned MipSlice, unsigned ArraySlice, unsigned PlaneSlice, + unsigned MipLevels, unsigned ArraySize) noexcept + { + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; + } + + // --- D3D_PRIMITIVE_TOPOLOGY stub --- + // Used by RenderSystem (universal_material.ixx return type, Canvas.cpp, + // FlowGraph) as a topology token. Values match d3dcommon.h exactly so + // that any serialized/cached topology tokens remain compatible. + // TODO (REFACTOR_TODO §2): replace with HAL::PrimitiveTopologyType usage + // throughout the RenderSystem. + enum D3D_PRIMITIVE_TOPOLOGY : int + { + D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1, + D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5, + D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13, + D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33, + D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34, + D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35, + D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36, + D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = 37, + D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = 38, + D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = 39, + D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = 40, + D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = 41, + D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = 42, + D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64, + }; + + // --- Raytracing instance descriptor stub --- + // Used by RenderSystem/Scene/Scene.ixx and MeshAsset as a gpu_buffer element + // type. The real struct is in d3d12.h; for Vulkan it maps to + // VkAccelerationStructureInstanceKHR (same binary layout by design, but the + // type name appears in template arguments so a stub is needed to compile). + // TODO (REFACTOR_TODO §2): replace usages with HAL::InstanceDesc once the + // RenderSystem is decoupled from D3D12 types. + struct D3D12_RAYTRACING_INSTANCE_DESC + { + float Transform[3][4] = {}; + unsigned InstanceID : 24 = 0; + unsigned InstanceMask : 8 = 0; + unsigned InstanceContributionToHitGroupIndex : 24 = 0; + unsigned Flags : 8 = 0; + uint64_t AccelerationStructure = 0; + }; + + namespace cereal + { + // Empty serialization — matches the D3D12 Utils stub exactly. + // Cereal requires a serialize() to be findable for any type it touches. + template + void serialize(Archive& /*ar*/, D3D12_RAYTRACING_INSTANCE_DESC& /*g*/) {} + } + + // --- IndirectCommand / Work-Graph stubs --- + // Used by DataHolder::create_indirect() and EntryPoints::compile() in + // SIG/Slots.ixx. The functions are never actually called in the Vulkan + // backend (IndirectCommand is stubbed), but the types must exist for + // the common template code to compile. + + enum D3D12_INDIRECT_ARGUMENT_TYPE : unsigned + { + D3D12_INDIRECT_ARGUMENT_TYPE_DRAW = 0, + D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED = 1, + D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH = 2, + D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT = 5, + D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH = 10, + }; + + struct D3D12_INDIRECT_ARGUMENT_DESC + { + D3D12_INDIRECT_ARGUMENT_TYPE Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH; + struct { unsigned RootParameterIndex = 0; unsigned DestOffsetIn32BitValues = 0; unsigned Num32BitValuesToSet = 0; } Constant; + }; + + // Work-graph node input types (D3D12 work-graphs, post-MVP on Vulkan). + struct D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE + { + uint64_t StartAddress = 0; + uint64_t StrideInBytes = 0; + }; + + struct D3D12_NODE_GPU_INPUT + { + unsigned EntrypointIndex = 0; + unsigned NumRecords = 0; + D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE Records; + }; + + struct D3D12_MULTI_NODE_GPU_INPUT + { + unsigned NumNodeInputs = 0; + D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE NodeInputs; + }; + + // --- HANDLE stub (Win32 HANDLE used by API::Fence Event) --- + // In Vulkan builds the Windows headers are still included (for HWND etc.), + // so HANDLE is already defined. No stub needed here. + + // ======================================================================== + // Vulkan backend namespace aliases (mirrors the D3D:: / DXGI:: aliases + // the D3D12 Utils exports so that backend-specific code has a uniform + // convention, though common code must not use these). + // ======================================================================== + namespace VK + { + // Placeholder — populated by backend implementation files. + } + + // ======================================================================== + // Conversion helpers: HAL abstract types → Vulkan native types. + // The D3D12 Utils exports to_native() for every HAL enum. We mirror the + // same function names so any code (currently none in common files) that + // calls to_native() still compiles. + // ======================================================================== + + VkFormat to_native(Format format); + Format from_native(VkFormat format); + + VkImageLayout to_native(TextureLayout layout); + VkPipelineStageFlags2 to_native_stage(BarrierSync sync); + VkAccessFlags2 to_native_access(BarrierAccess access); + + VkFilter to_native_filter(Filter f); + VkSamplerAddressMode to_native(TextureAddressMode mode); + VkCompareOp to_native(ComparisonFunc func); + VkSamplerCreateInfo to_native_sampler_ci(const SamplerDesc& desc); + VkPrimitiveTopology to_native_topology(PrimitiveTopologyType t); + VkCullModeFlagBits to_native(CullMode mode); + VkPolygonMode to_native(FillMode mode); + VkBlendFactor to_native(Blend b); + VkStencilOp to_native(StencilOp op); + VkStencilOpState to_native(StencilDesc desc); + VkImageType to_native(ResourceType t); + + VkCommandBufferLevel to_native(CommandListType type); + VkQueueFlagBits to_native_queue(CommandListType type); + + // Raytracing stubs — declared but not used in Vulkan for Phase 0. + struct RaytracingDescNative {}; + RaytracingDescNative to_native(const RaytracingBuildDescBottomInputs& inputs); + VkAccelerationStructureBuildGeometryInfoKHR + to_native(const RaytracingBuildDescTopInputs& inputs); + + // ResourceAddress → raw GPU virtual address. + // Mirrors the global ::to_native(ResourceAddress) in the D3D12 Utils. + // Defined in HAL.Vulkan.Resource.Buffer.cpp. + GPUAddressPtr to_native(const HAL::ResourceAddress& address); + +} // export diff --git a/sources/HAL/API/Vulkan/HAL.Vulkan.ixx b/sources/HAL/API/Vulkan/HAL.Vulkan.ixx new file mode 100644 index 00000000..449a719b --- /dev/null +++ b/sources/HAL/API/Vulkan/HAL.Vulkan.ixx @@ -0,0 +1,9 @@ +export module HAL:API; + +export import :API.DescriptorHeap; +export import :API.Device; +export import :API.Fence; +export import :API.Heap; +export import :API.IndirectCommand; +export import :API.Resource; +export import :API.RootSignature; diff --git a/sources/HAL/API/Vulkan/REFACTOR_TODO.md b/sources/HAL/API/Vulkan/REFACTOR_TODO.md new file mode 100644 index 00000000..b1779ac3 --- /dev/null +++ b/sources/HAL/API/Vulkan/REFACTOR_TODO.md @@ -0,0 +1,290 @@ +# Vulkan Backend — Clean-Refactor TODO + +This file records the work deferred while taking the **fast stub path** to get a +compiling Vulkan backend (C++20 module partition swap, no `#ifdef`s). The goal +of this document is so the "do it properly" pass can be done later without +re-deriving the analysis. + +--- + +## 0. Architecture recap + +`sources/HAL/D3D12/` and `sources/HAL/Vulkan/` both export the **same** module +partition names (`HAL:API.Device`, `HAL:API.Resource`, `HAL:Device`, +`HAL:Resource`, `HAL:Format`, …). Sharpmake compiles exactly one folder per +build via `target.Backend` (see `main.sharpmake.cs`, `HAL::ConfigureAll`). +Common files in `sources/HAL/*.cpp` compile in **both** backends and only call +into the `HAL::API::*` seam. + +Partition ownership map (who defines what), discovered during scaffolding: + +| Partition | Common file (both) | D3D12-only file | Vulkan-only file | +|---|---|---|---| +| `HAL:Device` | `HAL.Device.cpp` (singleton/managers) | `D3D12/HAL.D3D12.Device.cpp` (API::Device + get_texture_layout/compress) | `Vulkan/HAL.Vulkan.Device.cpp` | +| `HAL:Resource` | `HAL.Resource.cpp` (create_resource, getters) | `D3D12/HAL.D3D12.Resource.cpp` | `Vulkan/HAL.Vulkan.Resource.cpp` | +| `HAL:Resource.Buffer` | `HAL.Resource.Buffer.cpp` (init/read/write/ctors) | `D3D12/...Resource.Buffer.cpp` (cpu_data, dtor, to_native addr) | `Vulkan/...Resource.Buffer.cpp` | +| `HAL:DescriptorHeap` | `HAL.DescriptorHeap.cpp` (Handle/Storage/Factory) | `D3D12/...DescriptorHeap.cpp` (Descriptor::place, get_cpu/gpu) | `Vulkan/...DescriptorHeap.cpp` | +| `HAL:Heap` | `HAL.Heap.cpp` (get_type/size/as_buffer) | `D3D12/...Heap.cpp` (ctor, API::Heap) | `Vulkan/...Heap.cpp` | +| `HAL:Format` | `HAL.Format.cpp` (ctor/basic) | `D3D12/HAL.Format.cpp` (size, surface_info, …) | `Vulkan/HAL.Vulkan.Format.cpp` | +| `HAL:Queue` | `HAL.Queue.cpp` (orchestration) | `D3D12/...Queue.cpp` (API::Queue, DirectStorageQueue, tile maps) | `Vulkan/...Queue.cpp` | +| `HAL:CommandList` | `HAL.CommandList.cpp` + `HAL.CommandListRecorder.cpp` (ALL wrapper orchestration: GraphicsContext, ComputeContext, CopyContext, Transitions, Eventer, DelayedCommandList) | — | — | +| `HAL:API.CommandList` | — | `D3D12/...CommandList.cpp` | `Vulkan/...CommandList.cpp` | +| `HAL:PipelineState` | `HAL.PipelineState.cpp` (cache/desc) | `D3D12/...PipelineState.cpp` (on_change builders) | `Vulkan/...PipelineState.cpp` | +| `HAL:TextureData` | — | `D3D12/...TextureData.cpp` | `Vulkan/...TextureData.cpp` | +| `HAL:TiledMemoryManager` | `HAL.TiledMemoryManager.cpp` (tile logic) | `D3D12/...TiledMemoryManager.cpp` (init_tilings) | `Vulkan/...TiledMemoryManager.cpp` | +| `HAL:SwapChain` | `HAL.Swapchain.cpp` (getters/wait) | `DXGI/HAL.DXGI.Swapchain.cpp` (ctor/present/resize) | `Vulkan/...Swapchain.cpp` | +| `HAL:Adapter` | — | `DXGI/HAL.Adapter.cpp` | `Vulkan/...Adapter.cpp` | +| `HAL:Utils` | — | `D3D12/HAL.Utils.cpp` | `Vulkan/HAL.Vulkan.Utils.cpp` | +| `HAL:Impl` | — | `D3D12/HAL.Impl.cpp` | `Vulkan/HAL.Impl.cpp` | + +**Key takeaway:** the entire CommandList *wrapper* layer is already +backend-agnostic — it records lambdas into `DelayedCommandList` and replays them +against `API::CommandList`. So Vulkan only ever needs to implement the +`API::CommandList` method bodies. No duplication of GraphicsContext/Transitions. + +--- + +## 1. Stubs that still need real implementations (functional gaps) + +These compile but do nothing yet. Ordered by milestone. + +### Phase 1 — Device + adapter ✅ DONE +- ✅ `vkCreateInstance` with optional `VK_LAYER_KHRONOS_validation` (probes + availability first — graceful fallback when SDK not installed) +- ✅ `VK_EXT_debug_utils` messenger +- ✅ `vkCreateDevice` with extension filtering against device capabilities +- ✅ `vmaCreateAllocator`, `DeviceProperties` filled +- ✅ Physical device enumeration via `Adapters::enumerate()` +- ✅ `get_alloc_info`: real `vkGetDeviceBufferMemoryRequirements` / + `vkGetDeviceImageMemoryRequirements` + +### Phase 2 — Swapchain ✅ DONE +- ✅ Win32 surface, swapchain, image views, format/present-mode selection +- ✅ Backbuffer wrap via `NativeImportHandle{ image, view, format, extent }` +- ✅ `NativeImportHandle` now also sets a proper `TextureDesc` on the resource + so `as_texture()` works in common code +- ✅ Pre-acquire pattern: acquire at end of `present()` / constructor so + `wait_for_free()` + `get_current_frame()` work unchanged (mirrors D3D12) +- ✅ `resize()` reconstructs swapchain at new extent + +### Phase 3 — Command + clear ✅ DONE +- ✅ `begin`/`end` — real `VkCommandBuffer` allocation from pool +- ✅ `transitions()` → `vkCmdPipelineBarrier2` (sync2) +- ✅ `set_rtv` / `clear_rtv` / `clear_depth` via `vkCmdBeginRendering` + + clear load-op + `vkCmdEndRendering` (dynamic rendering) +- ✅ `Queue::construct` — `vkGetDeviceQueue` +- ✅ `Queue::execute` — `vkQueueSubmit2` +- ✅ `Queue::flush` — `vkQueueWaitIdle` +- ✅ `CommandAllocator` — `vkCreateCommandPool` / `vkResetCommandPool` +- ✅ **VulkanTest project** — standalone minimal app, clears window to solid + colour each frame, validates the full acquire→record→present pipeline +- ⚠️ Present sync: Phase 3 uses `vkQueueWaitIdle` instead of semaphores. + Phase 4 should wire `image_available` / `render_finished` through + `Queue::execute` for proper overlap. + +### Phase 1+ — Resources / memory ✅ DONE +- ✅ `vmaCreateBuffer` / `vmaCreateImage` for standalone resources +- ✅ `vkGetBufferDeviceAddress` for GPU-side buffer addresses +- ✅ Heap VMA allocation with persistent CPU map for UPLOAD/READBACK +- ✅ Placed-buffer pattern: `Resource::init(PlacementAddress)` derives + `heap_type` + `mapped_data` from the heap's `cpu_address` +- ⏳ `QueryHeap`: `vkCreateQueryPool(TIMESTAMP)` — deferred to Phase 4 + +### Phase 4 — Descriptors / pipelines / shaders + +### Phase 4 — Descriptors / pipelines / shaders +- `Vulkan/HAL.Vulkan.DescriptorHeap.cpp`: `VkDescriptorPool` / sets; + `Descriptor::place(*)` writes; **bindless** via `VK_EXT_descriptor_indexing`. +- `Vulkan/HAL.Vulkan.RootSignature.cpp`: `VkDescriptorSetLayout`(s) + + push constants → `vkCreatePipelineLayout`. +- `Vulkan/HAL.Vulkan.PipelineState.cpp`: `vkCreateGraphicsPipelines` / + `vkCreateComputePipelines`; `VkPipelineCache` for `get_cache()`. +- HLSL → SPIR-V: DXC already in the project; add `-spirv` path (the DXC/ + folder compiles in **both** backends). +- `Vulkan/HAL.Vulkan.IndirectCommand.cpp`: real indirect buffer layout + + `vkCmdDrawIndexedIndirect` / `vkCmdDispatchIndirect`. +- `Vulkan/HAL.Vulkan.TextureData.cpp`: real image decode (DirectXTex decode is + API-agnostic and can be reused) + BC compression. + +### Phase 3.5 — API surface audit & visibility tightening +The Vulkan `API::*` ixx files currently expose all Vulkan handles as `public`. +They should be `protected` (accessible to the owning `HAL::*` class via +inheritance) or `private` with `friend` declarations for the sibling API +classes that legitimately need them. No new public methods should be added to +the common `HAL::SwapChain` / `HAL::Queue` / etc. interfaces for Vulkan-only +purposes. + +Audit checklist (per ixx file): +- `HAL.Vulkan.Device.ixx` — `vk_instance`, `vk_physical`, `vk_device`, + `vma_allocator`, `queue_families` → `protected`; add `friend` for + `API::Resource`, `API::Heap`, `API::Queue`, `API::CommandAllocator`. +- `HAL.Vulkan.Resource.ixx` — `vk_buffer`, `vk_image`, `vma_alloc`, + `mapped_data`, `import_handle`, `imported_extent` → `protected`; add + `friend API::CommandList`. +- `HAL.Vulkan.Heap.ixx` — `vma_allocation`, `vk_memory`, `heap_vk_buffer`, + `cpu_address`, `gpu_address` → `protected`; `friend API::Resource`. +- `HAL.Vulkan.CommandAllocator.ixx` — `vk_command_pool` → `protected`; + `friend API::CommandList`. +- `HAL.Vulkan.Fence.ixx` — `timeline_semaphore`, `vk_fence` → `protected`; + `friend API::Queue`. +- `HAL.Vulkan.Adapter.ixx` — `vk_physical` → `protected`; `friend API::Device`. +- `HAL.Vulkan.Queue.ixx` — `vk_queue`, `vk_device` → `protected` (already); + verify no unnecessary public accessors. +- Validate: no `Vk*` / `Vma*` type appears in a `public:` section of any + `API::*` class unless it is a deliberate cross-backend accessor + (e.g. `Queue::get_native()` used by `SwapChain::present()`). + +### Autogen / SIG codegen issues for SPIRV + +- **`float4[2]` array in `ColorRect` / `(float2[4])` reinterpret — `gui/rect.hlsl`**: + `ColorRect` originally had `float4 pos[2]`. Accessing it via `ResourceDescriptorHeap` + caused DXC to emit two `OpTypeArray` definitions with different IDs, crashing + `OpAccessChain`. Fixed by splitting into `float4 pos_a; float4 pos_b;` (same binary + layout) and replacing `(float2[4])GetColorRect().pos` with explicit swizzles in + `rect.hlsl`. **Note:** the SIG template (`templates/hlsl/table.jinja`) will + regenerate `float4 pos[2]` if `ui.sig` is re-parsed — the template needs the same + fix as `gather_pipeline` (emit individual fields instead of packed arrays, or use + scalar layout). The shader change in `rect.hlsl` must also be re-applied after + any regeneration. + +- **`(uint[8])uint4[2]` reinterpret cast — `gather_pipeline.hlsl`**: + `GatherPipeline.table.ixx` (and the HLSL it generates) stores pipeline IDs as + `uint4 pip_ids[2]` to avoid DX cbuffer padding (bare `uint[8]` in a cbuffer + is padded to 128 bytes under DX rules; `uint4[2]` stays 32 bytes). The shader + then reinterprets with `(uint[8])pipi.pip_ids` to get individual uint IDs. + DXC's SPIRV backend generates a broken `OpCompositeExtract` for this cast: + the result type is `uint4[2]` (the whole array) instead of `uint4` (one + element), which SPIRV validation rejects. + **No compiler flag can fix this — it is a DXC codegen bug on uint4[]-to-uint[] + array reinterpret casts.** + Proper fixes (pick one): + 1. Compile the table as a `StructuredBuffer` instead of + `ConstantBuffer<>` — structured buffers use tight packing so `uint[8]` + stays 32 bytes and no reinterpret cast is needed. + 2. Change the Jinja table template (`templates/hlsl/table.jinja`) to emit a + flat `uint pip_ids[8]` **and** switch to scalar layout + (`-fvk-use-scalar-layout`) so the Vulkan GLSL/SPIRV packing matches. + 3. Have the SIG emit an accessor helper `uint GetPip_ids_flat(int i)` that + expands to `pip_ids[i/4][i%4]` — avoids the cast entirely; shader just + needs to call the helper. + +--- + +### Shader compilation — known workarounds + +- **FP16 image types suppressed for SPIRV** (`DXC.ShaderCompiler.cpp`): + `-enable-16bit-types` is intentionally skipped when compiling to SPIR-V. + Vulkan SPIRV spec (VUID-StandaloneSpirv-OpTypeImage-04656) requires image + sampled types to be 32-bit — `OpTypeImage %half` is rejected regardless of + extensions. Without the flag, `half`/`min16float` in image declarations + silently promote to `float32`. To keep `float16_tN` types available for arithmetic (groupshared memory, + function parameters, etc.) without triggering the image type issue, + `get_extra_compile_args` injects `-Dfloat16_t=float` / `-Dfloat16_t2=float2` + etc. so all 16-bit types silently become 32-bit aliases via the preprocessor. + **Proper fix:** audit shaders that use half-precision textures; for those that + genuinely need FP16 sampling, route them through a `float32` image + explicit + `f16tof32` / `f32tof16` in the shader body, or wait for + `VK_EXT_shader_float16_int8` image-fetch support to land in the SPIRV spec. + +- **`ResourceDescriptorHeap` requires DXC 1.9+** (`HAL.Vulkan.ShaderReflection.cpp`): + SM6.6 bindless heap access compiled via `-fvk-bind-resource-heap 0 0` / + `-fvk-bind-sampler-heap 0 1`. These flags did not exist in DXC ≤ 1.8.2407; + the project was pinned to DXC `2026-02-20` (v1.9.2602) in `vcpkg.json` + overrides to unlock them. If DXC is ever rolled back, bindless shaders will + fail with "HLSL object ResourceDescriptorHeap not yet supported with -spirv". + +### Post-MVP +- Tiled/sparse: `Vulkan/HAL.Vulkan.TiledMemoryManager.cpp` `init_tilings` + + `Queue::update_tile_mappings` via `vkQueueBindSparse`. +- Raytracing: `StateObject` / `dispatch_rays` / `build_ras` via + `VK_KHR_acceleration_structure` + `VK_KHR_ray_tracing_pipeline`. +- Work graphs: no direct Vulkan equivalent — emulate or leave disabled. +- DirectStorage streaming (`DirectStorageQueue::execute`): replace with a + Vulkan staging-buffer uploader (+ optional GDeflate). + +--- + +## 2. Compatibility shims that should be removed in the clean version + +The fast path introduced D3D12-named stand-ins so common files compile +unchanged. The *clean* refactor should replace these with backend-neutral +names in the common headers and drop the shims. + +- `HAL.Vulkan.Utils.ixx` defines stubs for D3D12/DXGI types used in common code: + `D3D12_CPU_DESCRIPTOR_HANDLE`, `D3D12_GPU_DESCRIPTOR_HANDLE`, + `DXGI_ADAPTER_DESC`, `D3D12_DISPATCH_ARGUMENTS`, `D3D12_DRAW_INDEXED_ARGUMENTS`, + `D3D12_DISPATCH_MESH_ARGUMENTS`, `D3D12_PROGRAM_IDENTIFIER`, + `D3D12_INDIRECT_ARGUMENT_TYPE`, `D3D12_INDIRECT_ARGUMENT_DESC`, + `D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE`, `D3D12_NODE_GPU_INPUT`, + `D3D12_MULTI_NODE_GPU_INPUT`, `D3D12_RAYTRACING_INSTANCE_DESC`, + **`D3D_PRIMITIVE_TOPOLOGY`**. + - Source leaks to fix in **common** code so the shims can die: + - `HAL.DescriptorHeap.ixx` — `Handle::get_cpu()/get_gpu()` return + `D3D12_CPU/GPU_DESCRIPTOR_HANDLE`. Introduce a neutral + `HAL::DescriptorPointer { uint64 cpu; uint64 gpu; }` (or opaque) and + change the common signature; each backend fills it. + - `HAL.Device.cpp` — logs `adapter->get_desc().Description`. Introduce a + neutral `HAL::AdapterInfo { std::wstring name; uint vendor, device; size_t vram; }` + returned by `Adapter::get_info()`, and switch the log + the "Basic" + device-selection heuristic to it. + - `API::StateObject::id` is `D3D12_PROGRAM_IDENTIFIER` (work-graph only) — + gate behind a neutral type once work-graphs are abstracted. + - **`RenderSystem/Scene/Scene.ixx` and `MeshAsset.ixx`** use + `D3D12_RAYTRACING_INSTANCE_DESC` as a `virtual_gpu_buffer` element type + and as a field type. The proper fix is to introduce a backend-neutral + `HAL::RaytracingInstanceDesc` (identical binary layout to both the D3D12 + struct and `VkAccelerationStructureInstanceKHR`) and use it everywhere. + The common `HAL::InstanceDesc` already exists in Types.ixx as a partial + mirror — unify them and migrate the RenderSystem. + +- `to_native(const ResourceAddress&)` is declared in `HAL.Vulkan.Utils.ixx` + and defined in `HAL.Vulkan.Resource.Buffer.cpp` to mirror the D3D12 global. + In the clean version, make `ResourceAddress::get_native()` (or similar) a + first-class HAL method instead of a free `to_native`. + +--- + +## 3. Open design points + +- **Adapter/instance ownership.** D3D12 has a global `DXGI::Factory` in the + `Adapters` singleton that can enumerate before any device. Vulkan needs a + `VkInstance` first. Options: (a) `Adapters` creates its own lightweight + instance for enumeration; (b) Device creates the instance and pushes it to + `Adapters::set_instance()` before enumerating. Current scaffold leans toward + (b) but `Device::create_singleton()` (common) calls + `Adapters::get().enumerate()` *before* constructing a Device — so (a) is + probably required. **Resolve before Phase 1.** + +- **`HAL::init()`** (`HAL.Impl.cpp`): D3D12 enables the debug layer globally + before device creation; Vulkan validation is per-instance. The Vulkan + `init()` currently just creates the `Adapters` singleton. Decide where the + instance is born (ties into the point above). + +- **Backend-neutral barrier types already exist** (`BarrierSync`, + `BarrierAccess`, `TextureLayout`) and map cleanly to sync2 — no shim needed, + this is the clean seam to imitate elsewhere. + +--- + +## 4. Build-system notes (`main.sharpmake.cs`) + +- `Backend` fragment added (`D3D12 | Vulkan`); solution configs are + `Debug-D3D12`, `Debug-Vulkan`, etc. +- `HAL::ConfigureAll` excludes the other backend folder via + `SourceFilesBuildExcludeRegex`; DXC/ stays in both. +- `Modules::ConfigureAll` excludes the other backend's module wrapper + (`Modules/d3d12/` vs `Modules/vulkan/`). +- `vcpkg.json` adds `vulkan-memory-allocator` + `vulkan-headers`. +- Vulkan build defines `HAL_BACKEND_VULKAN` (currently unused by source — keep + it ifdef-free; it exists only for tooling/diagnostics). + +--- + +## 5. When doing the clean version + +1. Introduce the neutral types in §2 in the **common** headers. +2. Update the handful of common call sites (DescriptorHeap handle, Device log). +3. Delete the D3D12-named shims from both `HAL.Vulkan.Utils.ixx` and the D3D12 + Utils (replace with the neutral types there too). +4. Keep the partition-swap file layout — it is the correct long-term structure; + only the *contents* of the stubs change. diff --git a/sources/HAL/DXC/DXC.ShaderCompiler.cpp b/sources/HAL/DXC/DXC.ShaderCompiler.cpp index f660fa0c..85effbe7 100644 --- a/sources/HAL/DXC/DXC.ShaderCompiler.cpp +++ b/sources/HAL/DXC/DXC.ShaderCompiler.cpp @@ -3,9 +3,27 @@ module HAL:ShaderCompiler; import wrl; import Core; -import d3d12; +import windows; // COM base types (IUnknown, INoMarshal), MessageBoxA, LPCWSTR import DXCompiler; +// Shader reflection is the only D3D12-coupled part of compilation (it uses the +// ID3D12ShaderReflection / ID3D12LibraryReflection interfaces). It is split out +// behind this seam so the common compile path stays backend-neutral: +// * D3D12 build: D3D12/HAL.D3D12.ShaderReflection.cpp (real reflection) +// * Vulkan build: Vulkan/HAL.Vulkan.ShaderReflection.cpp (stub for now) +// Both are implementation units of `module HAL:ShaderCompiler`, so this +// declaration has module linkage and is visible to whichever one is compiled. +namespace HAL +{ + void reflect_shader(IDxcUtils* library, const DxcBuffer& reflectionBuffer, + const std::string& entry_point, CompiledShader& out); + + // Backend-specific extra DXC compilation flags. + // D3D12 backend: returns {} (no-op). + // Vulkan backend: returns { L"-spirv", L"-fvk-use-dx-layout", ... }. + std::vector get_extra_compile_args(const std::string& target); +} + #define DXC_MICROCOM_REF_FIELD(m_dwRef) \ volatile std::atomic_int m_dwRef = {0}; #define DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \ @@ -181,9 +199,24 @@ namespace HAL compilationArguments.emplace_back(L"-no-warnings"); compilationArguments.emplace_back(L"-O3"); - if (check(options & ShaderOptions::FP16)) + // Backend-specific extra flags (e.g. "-spirv" for Vulkan). + // Defined in D3D12/HAL.D3D12.ShaderReflection.cpp (returns {}) + // and Vulkan/HAL.Vulkan.ShaderReflection.cpp (returns SPIR-V flags). + for (auto& extra : get_extra_compile_args(target)) + compilationArguments.push_back(extra); + { - compilationArguments.push_back(L"-enable-16bit-types"); + // -enable-16bit-types makes `half` a native 16-bit type in DXIL instead of a + // min-precision alias. Without it, the DXIL validator rejects bitcast operations + // on `half` (e.g. in FFX denoiser shaders that use asuint(half)). + // For SPIRV targets we must NOT set this flag: DXC would emit native + // OpTypeImage %half which violates VUID-StandaloneSpirv-OpTypeImage-04656 + // (sampled-image component type must be 32-bit). The Vulkan shaders instead + // handle float16 via explicit #ifdef __spirv__ + float16_t aliases. + bool is_spirv = std::any_of(compilationArguments.begin(), compilationArguments.end(), + [](const std::wstring& a) { return a == L"-spirv"; }); + if (!is_spirv) + compilationArguments.push_back(L"-enable-16bit-types"); } for (auto& m : defines) @@ -225,6 +258,7 @@ namespace HAL errorMsg += file_name + "\n"; errorMsg.append((infoLog)); Log::get() << Log::LEVEL_ERROR << errorMsg << Log::endl; + MessageBoxA(nullptr, errorMsg.c_str(), "Error!", MB_OK); return {}; } @@ -235,7 +269,7 @@ namespace HAL blob_str.blob.assign(static_cast(resultBlob->GetBufferPointer()), static_cast(resultBlob->GetBufferPointer()) + resultBlob->GetBufferSize()); - ComPtr reflectionBlob{}; + /*omPtr reflectionBlob{}; compiledShaderBuffer->GetOutput(DXC_OUT_REFLECTION, IID_PPV_ARGS(&reflectionBlob), nullptr); const DxcBuffer reflectionBuffer @@ -244,90 +278,12 @@ namespace HAL .Size = reflectionBlob->GetBufferSize() }; - - if (entry_point.size()) - { - - blob_str.functions.emplace_back(); - auto& f = blob_str.functions.back(); - - ComPtr shaderReflection{}; - library->CreateReflection(&reflectionBuffer, IID_PPV_ARGS(&shaderReflection)); - D3D12_SHADER_DESC shaderDesc{}; - shaderReflection->GetDesc(&shaderDesc); - f.name = entry_point; - f.wname = convert(f.name); - for (uint i = 0; i < shaderDesc.ConstantBuffers; i++) - { - ID3D12ShaderReflectionConstantBuffer* cb = shaderReflection->GetConstantBufferByIndex(i); - D3D12_SHADER_BUFFER_DESC shaderBufferDesc{}; - cb->GetDesc(&shaderBufferDesc); - - std::string cb_name = shaderBufferDesc.Name; - - if (cb_name.starts_with("pass_")) - { - cb_name = cb_name.substr(5); - auto slot_id = get_slot(cb_name); - - if(slot_id) - f.slots.merge(slot_id.value()); - } - - //Log::get() << shaderBufferDesc.Name << Log::endl; - - } - - } else - { - ComPtr libraryReflection{}; - auto hr3 = library->CreateReflection(&reflectionBuffer, IID_PPV_ARGS(&libraryReflection)); - - - D3D12_LIBRARY_DESC shaderDesc{}; - libraryReflection->GetDesc(&shaderDesc); - - - for (uint i = 0; i < shaderDesc.FunctionCount; i++) - { - ID3D12FunctionReflection* f = libraryReflection->GetFunctionByIndex(i); - D3D12_FUNCTION_DESC functionDesc{}; - f->GetDesc(&functionDesc); - // Log::get() << "FUNCTION "<< functionDesc.Name << Log::endl; - - blob_str.functions.emplace_back(); - auto& rf = blob_str.functions.back(); - rf.name = functionDesc.Name ; - rf.wname = convert(rf.name); - - - for (uint i = 0; i < functionDesc.ConstantBuffers; i++) - { - ID3D12ShaderReflectionConstantBuffer* cb = f->GetConstantBufferByIndex(i); - D3D12_SHADER_BUFFER_DESC shaderBufferDesc{}; - cb->GetDesc(&shaderBufferDesc); - - std::string cb_name = shaderBufferDesc.Name; - - - if (cb_name.starts_with("pass_")) - { - cb_name = cb_name.substr(5); - - auto slot_id = get_slot(cb_name); - - rf.slots.merge(slot_id.value()); - } - // Log::get() << shaderBufferDesc.Name << Log::endl; - - } - } - - - } - - - + // Backend-specific: D3D12 uses ID3D12ShaderReflection to extract per-pass + // constant-buffer slot usage; Vulkan stubs this for now (Phase 4 will use + // SPIR-V reflection). See reflect_shader() seam at top of this TU. + reflect_shader(library, reflectionBuffer, entry_point, blob_str); + */ + blob_str.entry_point = entry_point; // store so pipeline creation can use it return std::move(blob_str); } diff --git a/sources/HAL/DXGI/HAL.DXGI.Swapchain.cpp b/sources/HAL/DXGI/HAL.DXGI.Swapchain.cpp index 6d70be8f..9e01bfa3 100644 --- a/sources/HAL/DXGI/HAL.DXGI.Swapchain.cpp +++ b/sources/HAL/DXGI/HAL.DXGI.Swapchain.cpp @@ -7,7 +7,7 @@ import HAL; import d3d12; -#undef THIS + namespace HAL { SwapChain::SwapChain(Device& device, swap_chain_desc c_desc) :device(device) @@ -77,7 +77,7 @@ namespace HAL { D3D::Resource render_target; m_swapChain->GetBuffer(n, IID_PPV_ARGS(&render_target)); - frames[n].m_renderTarget.reset(new TextureResource(device, render_target, TextureLayout::PRESENT)); + frames[n].m_renderTarget.reset(new TextureResource(device, API::NativeImportHandle{render_target}, TextureLayout::PRESENT)); frames[n].m_renderTarget->set_name(std::string("swap_chain_") + std::to_string(n)); } diff --git a/sources/HAL/Formats.h b/sources/HAL/Formats.h index 22a27bea..5906ee98 100644 --- a/sources/HAL/Formats.h +++ b/sources/HAL/Formats.h @@ -8,9 +8,10 @@ HAL::Format::R32G32B32A32_FLOAT, \ HAL::Format::R32G32B32A32_UINT, \ HAL::Format::R32G32B32A32_SINT, \ - HAL::Format::R32G32B32_FLOAT, \ - HAL::Format::R32G32B32_UINT, \ - HAL::Format::R32G32B32_SINT, \ + /* R32G32B32_* omitted: Vulkan COLOR_ATTACHMENT_BIT support is optional for 3-component R32 formats */ \ + /*HAL::Format::R32G32B32_FLOAT,*/ \ + /*HAL::Format::R32G32B32_UINT,*/ \ + /*HAL::Format::R32G32B32_SINT,*/ \ HAL::Format::R16G16B16A16_FLOAT, \ HAL::Format::R16G16B16A16_UNORM, \ HAL::Format::R16G16B16A16_UINT, \ @@ -48,16 +49,19 @@ HAL::Format::R8_UINT, \ HAL::Format::R8_SNORM, \ HAL::Format::R8_SINT, \ - HAL::Format::A8_UNORM, \ + /* A8_UNORM omitted: no VK_FORMAT_A8_UNORM in core Vulkan */ \ + /*HAL::Format::A8_UNORM,*/ \ /*HAL::Format::R1_UNORM,*/ \ - HAL::Format::R8G8_B8G8_UNORM, \ - HAL::Format::G8R8_G8B8_UNORM, \ + /* R8G8_B8G8 / G8R8_G8B8 omitted: D3D12 subsampled YUV-packed formats, no Vulkan RT equivalent */ \ + /*HAL::Format::R8G8_B8G8_UNORM,*/ \ + /*HAL::Format::G8R8_G8B8_UNORM,*/ \ HAL::Format::B5G6R5_UNORM, \ HAL::Format::B5G5R5A1_UNORM, \ HAL::Format::B8G8R8A8_UNORM, \ - HAL::Format::B8G8R8X8_UNORM, \ - HAL::Format::B8G8R8A8_UNORM_SRGB, \ - HAL::Format::B8G8R8X8_UNORM_SRGB + /* B8G8R8X8 omitted: no dedicated VkFormat; Vulkan uses B8G8R8A8 (no X/ignored-alpha variant) */ \ + /*HAL::Format::B8G8R8X8_UNORM,*/ \ + HAL::Format::B8G8R8A8_UNORM_SRGB \ + /*HAL::Format::B8G8R8X8_UNORM_SRGB*/ #endif #ifndef ALL_RT_BLENDING_FORMATS @@ -83,12 +87,14 @@ HAL::Format::R16_SNORM, \ HAL::Format::R8_UNORM, \ HAL::Format::R8_SNORM, \ - HAL::Format::A8_UNORM, \ + /* A8_UNORM omitted: no VK_FORMAT_A8_UNORM in core Vulkan */ \ + /*HAL::Format::A8_UNORM,*/ \ /*HAL::Format::R1_UNORM,*/ \ HAL::Format::B5G6R5_UNORM, \ HAL::Format::B5G5R5A1_UNORM, \ HAL::Format::B8G8R8A8_UNORM, \ - HAL::Format::B8G8R8X8_UNORM, \ - HAL::Format::B8G8R8A8_UNORM_SRGB, \ - HAL::Format::B8G8R8X8_UNORM_SRGB + /* B8G8R8X8 omitted: no dedicated VkFormat */ \ + /*HAL::Format::B8G8R8X8_UNORM,*/ \ + HAL::Format::B8G8R8A8_UNORM_SRGB \ + /*HAL::Format::B8G8R8X8_UNORM_SRGB*/ #endif diff --git a/sources/HAL/HAL.CommandAllocator.ixx b/sources/HAL/HAL.CommandAllocator.ixx index 71990cf4..5d658f5b 100644 --- a/sources/HAL/HAL.CommandAllocator.ixx +++ b/sources/HAL/HAL.CommandAllocator.ixx @@ -16,6 +16,7 @@ export{ CommandListType type; public: CommandAllocator(Device& device, CommandListType type); + ~CommandAllocator(); void reset(); CommandListType get_type() const; }; diff --git a/sources/HAL/HAL.CommandList.cpp b/sources/HAL/HAL.CommandList.cpp index fa39c415..f5cc50ec 100644 --- a/sources/HAL/HAL.CommandList.cpp +++ b/sources/HAL/HAL.CommandList.cpp @@ -1595,7 +1595,7 @@ namespace HAL void TransitionCommandList::create_transition_list(FrameResources& frame, const HAL::Barriers& transitions) { - + /* ASSERT(false); device.context_generator.generate(this); @@ -1629,7 +1629,7 @@ namespace HAL compiler.compile(*ca); end(); - frame.free_ca(ca); + frame.free_ca(ca);*/ } diff --git a/sources/HAL/HAL.CommandList.ixx b/sources/HAL/HAL.CommandList.ixx index 649c5eb2..0c0c80ed 100644 --- a/sources/HAL/HAL.CommandList.ixx +++ b/sources/HAL/HAL.CommandList.ixx @@ -214,7 +214,7 @@ export{ class SignatureDataSetter; - class CommandList : public Transitions, public Eventer, public Sendable, public SharedObject + class CommandList : public Transitions, public Eventer, public Sendable, public SharedObject, public TypedObject { public: diff --git a/sources/HAL/HAL.Debug.ixx b/sources/HAL/HAL.Debug.ixx index 0a7e0a72..ad0a1317 100644 --- a/sources/HAL/HAL.Debug.ixx +++ b/sources/HAL/HAL.Debug.ixx @@ -3,7 +3,6 @@ export module HAL:Debug; import Core; import :Types; - class CommandList; export namespace HAL { diff --git a/sources/HAL/HAL.DescriptorHeap.cpp b/sources/HAL/HAL.DescriptorHeap.cpp index c243f1af..4df69e78 100644 --- a/sources/HAL/HAL.DescriptorHeap.cpp +++ b/sources/HAL/HAL.DescriptorHeap.cpp @@ -355,7 +355,7 @@ f(view.Resource, ALL_SUBRESOURCES); bool Handle::is_valid() const { - return storage && (offset != std::numeric_limits::max()); + return storage && (offset != std::numeric_limits::max()) && storage->get_heap() != nullptr; } bool Handle::operator!=(const Handle& r) diff --git a/sources/HAL/HAL.Device.cpp b/sources/HAL/HAL.Device.cpp index d50dcbec..391a31a6 100644 --- a/sources/HAL/HAL.Device.cpp +++ b/sources/HAL/HAL.Device.cpp @@ -52,11 +52,10 @@ namespace HAL const auto& props = device->get_properties(); - if (result==nullptr && props.mesh_shader && props.full_bindless&&(std::wstring(adapter_desc.Description).find(L"Basic")==std::wstring::npos) ) { - Log::get() << "Selecting adapter: " << adapter_desc.Description << Log::endl; + // Log::get() << "Selecting adapter: " << adapter_desc.Description << Log::endl; result = device; }else if(props.full_bindless) { @@ -73,7 +72,12 @@ namespace HAL Log::get().crash_error("Cant find proper device"); } else - result->init_managers(); + { + + Log::get() << "Selected device : " << result->get_properties().name << Log::endl; + result->init_managers(); + } + return result; } diff --git a/sources/HAL/HAL.Fence.ixx b/sources/HAL/HAL.Fence.ixx index bb6b388c..8e5c4d73 100644 --- a/sources/HAL/HAL.Fence.ixx +++ b/sources/HAL/HAL.Fence.ixx @@ -20,6 +20,7 @@ export namespace HAL public: using CounterType = API::Fence::CounterType; Fence(Device& device); + ~Fence(); void signal(CounterType value); CounterType get_completed_value() const; diff --git a/sources/HAL/HAL.PipelineState.cpp b/sources/HAL/HAL.PipelineState.cpp index 6a61b25c..15c3f792 100644 --- a/sources/HAL/HAL.PipelineState.cpp +++ b/sources/HAL/HAL.PipelineState.cpp @@ -3,6 +3,7 @@ import Core; import :Device; import :Shader; import :PSO; +import :Utils; // get_backend_name() for per-backend PSO cache namespace HAL { @@ -39,7 +40,7 @@ namespace HAL { std::lock_guard g(m); - FileDataStorage storage(L"cache/pso.bin"); + FileDataStorage storage(std::filesystem::path("cache") / get_backend_name() / "pso.bin"); storage.start_save(); storage.put("cache", binary_cache); storage.save(); @@ -90,7 +91,7 @@ namespace HAL - FileDataStorage storage(L"cache/pso.bin"); + FileDataStorage storage(std::filesystem::path("cache") / get_backend_name() / "pso.bin"); storage.get("cache",binary_cache); } diff --git a/sources/HAL/HAL.Queue.cpp b/sources/HAL/HAL.Queue.cpp index 9ed400ec..50ef7b20 100644 --- a/sources/HAL/HAL.Queue.cpp +++ b/sources/HAL/HAL.Queue.cpp @@ -4,7 +4,7 @@ module HAL:Queue; import Core; import HAL; -#undef THIS + using namespace HAL; namespace HAL @@ -23,6 +23,33 @@ namespace HAL } + Queue::Queue(CommandListType type, Device& device) : commandListCounter(device), type(type), device(device) + { + API::Queue::construct(type, &device); + m_fenceValue = 0; + del_func = [this](CommandList* list) + { + if (stop) + delete list; + else + { + std::lock_guard g(list_mutex); + lists.emplace(list, del_func); + } + }; + + del_transition = [this](TransitionCommandList* list) + { + if (stop) + delete list; + else + { + std::lock_guard g(list_mutex); + transition_lists.emplace(list, del_transition); + } + }; + } + /* FenceWaiter Queue::signal_internal() { diff --git a/sources/HAL/HAL.Resource.Buffer.cpp b/sources/HAL/HAL.Resource.Buffer.cpp index 74c9ab2a..1be99c0d 100644 --- a/sources/HAL/HAL.Resource.Buffer.cpp +++ b/sources/HAL/HAL.Resource.Buffer.cpp @@ -53,7 +53,7 @@ namespace HAL if (heap_type == HeapType::UPLOAD || heap_type == HeapType::READBACK) { ASSERT(buffer_data == nullptr); - get_dx()->Map(0, nullptr, reinterpret_cast(&buffer_data)); + buffer_data = static_cast(get_cpu_mapping()); } gpu_address = ResourceAddress{ this, 0 }; diff --git a/sources/HAL/HAL.Resource.Texture.cpp b/sources/HAL/HAL.Resource.Texture.cpp index ba0f246e..c2958007 100644 --- a/sources/HAL/HAL.Resource.Texture.cpp +++ b/sources/HAL/HAL.Resource.Texture.cpp @@ -57,8 +57,8 @@ namespace HAL init(); } - TextureResource::TextureResource(Device& device, const D3D::Resource& resouce, TextureLayout initialLayout) - : Resource(device, resouce, initialLayout) + TextureResource::TextureResource(Device& device, const API::NativeImportHandle& handle, TextureLayout initialLayout) + : Resource(device, handle, initialLayout) { init(); } diff --git a/sources/HAL/HAL.Resource.Texture.ixx b/sources/HAL/HAL.Resource.Texture.ixx index f20e4425..d613c932 100644 --- a/sources/HAL/HAL.Resource.Texture.ixx +++ b/sources/HAL/HAL.Resource.Texture.ixx @@ -28,7 +28,7 @@ export{ TextureResource(Device& device, const ResourceDesc& desc, HeapType heap_type, TextureLayout initialLayout = TextureLayout::UNDEFINED, vec4 clear_value = vec4(0, 0, 0, 0)); TextureResource(Device& device, const ResourceDesc& desc, PlacementAddress handle); TextureResource(Device& device, const ResourceDesc& desc, ResourceHandle handle, bool own = false); - TextureResource(Device& device, const D3D::Resource& resouce, TextureLayout initialLayout); + TextureResource(Device& device, const API::NativeImportHandle& handle, TextureLayout initialLayout); virtual ~TextureResource() {} private: diff --git a/sources/HAL/HAL.Resource.cpp b/sources/HAL/HAL.Resource.cpp index 9f9cb430..8f5a19b6 100644 --- a/sources/HAL/HAL.Resource.cpp +++ b/sources/HAL/HAL.Resource.cpp @@ -18,14 +18,11 @@ import Core; namespace HAL { - Resource::ptr create_resource(Device& device, const HAL::ResourceDesc& desc, ResourceHandle handle) - { - PROFILE(L"create_resource handle"); + // NOTE: create_resource(Device&, ResourceDesc&, ResourceHandle) is intentionally + // NOT defined here. It is an inline in HAL.Resource.ixx to avoid the MSVC + // $$_A/$$_B module-type-tag mismatch for template arguments (HeapHandle). + // The inline forwards to _create_resource_placed_impl below. - if (desc.is_buffer()) - return std::make_shared(device, desc, handle); - return std::make_shared(device, desc, handle); - } Resource::ptr create_resource(Device& device, const HAL::ResourceDesc& desc, HeapType heap_type) { @@ -107,11 +104,32 @@ namespace HAL desc.Flags |= ResFlags::DisableStateTracking; } + void Resource::enable_state_tracking() + { + desc.Flags &= ~ResFlags::DisableStateTracking; + } + HeapType Resource::get_heap_type() const { return heap_type; } -} + // ---- Forwarding helper for the ResourceHandle overload -------------------- + // void* + size_t parameters carry no cross-partition template-argument type + // tags, so the symbol is identical from inside the module ($$_B context) and + // from external callers ($$_A context). + // Resource in the return type is from THIS partition — always [HAL], no mismatch. + Resource::ptr _create_resource_placed_impl(Device& device, + const ResourceDesc& desc, + void* heap_raw, size_t offset) + { + auto* heap = static_cast(heap_raw); + PlacementAddress placement{ heap, offset }; + if (desc.is_buffer()) + return std::make_shared(device, desc, placement); + return std::make_shared(device, desc, placement); + } + +} // namespace HAL diff --git a/sources/HAL/HAL.Resource.ixx b/sources/HAL/HAL.Resource.ixx index 3e198d3d..e4645a99 100644 --- a/sources/HAL/HAL.Resource.ixx +++ b/sources/HAL/HAL.Resource.ixx @@ -140,7 +140,7 @@ export{ bool serialize_from_derived = false; protected: friend class API::Resource; - HeapType heap_type; + HeapType heap_type = HeapType::RESERVED; // safe sentinel; _init() always overwrites ResourceDesc desc; Device* m_device = nullptr; @@ -170,6 +170,7 @@ export{ std::shared_ptr get_tracked(); void disable_state_tracking(); + void enable_state_tracking(); ResourceAllocationInfo alloc_info; std::string name; void set_name(std::string name); @@ -178,7 +179,7 @@ export{ using ptr = std::shared_ptr; protected: Resource(Device& device, const ResourceDesc& desc, HeapType heap_type, TextureLayout initialLayout = TextureLayout::UNDEFINED, vec4 clear_value = vec4(0, 0, 0, 0)); - Resource(Device& device, const D3D::Resource& resouce, TextureLayout initialLayout); + Resource(Device& device, const API::NativeImportHandle& handle, TextureLayout initialLayout); Resource(Device& device, const ResourceDesc& desc, PlacementAddress handle); Resource(Device& device, const ResourceDesc& desc, ResourceHandle handle, bool own = false); @@ -227,12 +228,37 @@ export{ - Resource::ptr create_resource(Device& device, const HAL::ResourceDesc& desc, HeapType heap_type); - - Resource::ptr create_resource(Device& device, const HAL::ResourceDesc& desc, ResourceHandle addr); + Resource::ptr create_resource(Device& device, const HAL::ResourceDesc& desc, HeapType heap_type); + + // MSVC C++20 module $$_A/$$_B fix for the ResourceHandle overload. + // + // Problem: MSVC mangles cross-partition template arguments differently + // inside a module ($$_B / [!HAL]) vs outside via `import HAL;` ($$_A / + // [HAL]). ResourceHandle = HeapHandle has HAL::Heap from the + // :Heap partition, so the function defined in HAL.Resource.cpp (a module + // implementation unit) gets the $$_B mangling that FrameGraph never finds. + // + // Fix A: declare the real work as _create_resource_placed_impl with only + // primitive/non-template parameters (void*, size_t) — no cross-partition + // template arguments → symbol is stable from inside and outside the module. + // Fix B: make create_resource(ResourceHandle) inline here in the *interface* + // unit. Inline bodies are compiled in each caller's context, so + // addr.get_heap().get() uses the caller's $$_A view of HAL::Heap. + // The call to _create_resource_placed_impl uses only void*/size_t — no + // mismatch. And Resource in the return type is from THIS same partition + // interface, so it's always [HAL] on both sides. + Resource::ptr _create_resource_placed_impl(Device& device, + const ResourceDesc& desc, + void* heap_raw, size_t offset); + + inline Resource::ptr create_resource(Device& device, const HAL::ResourceDesc& desc, ResourceHandle addr) + { + return _create_resource_placed_impl(device, desc, + static_cast(addr.get_heap().get()), + addr.get_offset()); + } } - } diff --git a/sources/HAL/HAL.ResourceStates.cpp b/sources/HAL/HAL.ResourceStates.cpp index a39691c4..72ce495f 100644 --- a/sources/HAL/HAL.ResourceStates.cpp +++ b/sources/HAL/HAL.ResourceStates.cpp @@ -379,9 +379,16 @@ namespace HAL for (auto& e : gpu_state.subres) e.layout = layout; + // Reset every per-command-list CPU state so that set_cpu_state_first() on + // the next barrier-compilation pass sees "never used" and falls back to the + // GPU state we just reset above, rather than overwriting it with a stale + // layout from a previous frame (e.g. COLOR_ATTACHMENT_OPTIMAL after present). states.set_init_func([count](SubResourcesCPU& state) { + state.used = false; state.subres.resize(count); + for (auto& e : state.subres) + e.used = false; // prevents set_cpu_state_first from using stale layout }); } diff --git a/sources/HAL/HAL.Shader.ixx b/sources/HAL/HAL.Shader.ixx index aa3c1ffd..9872f12d 100644 --- a/sources/HAL/HAL.Shader.ixx +++ b/sources/HAL/HAL.Shader.ixx @@ -4,6 +4,7 @@ import :ShaderCompiler; import Core; import :Enums; import :Slots; +import :Utils; // get_backend_name() for per-backend shader cache std::optional get_slot(std::string_view slot_name); export { @@ -143,6 +144,11 @@ export this->id = shader_ids[blob_hash]; } public: + // Per-backend shader cache: a SPIR-V (Vulkan) blob and a DXIL (D3D12) + // blob hash to the same source but must never share a cache slot. + // → cache//.bin + static std::string cache_subfolder() { return get_backend_name(); } + static Cache shader_ids; CompiledShader blob; diff --git a/sources/HAL/HAL.ShaderCompiler.ixx b/sources/HAL/HAL.ShaderCompiler.ixx index 58def5f1..a49fc0bf 100644 --- a/sources/HAL/HAL.ShaderCompiler.ixx +++ b/sources/HAL/HAL.ShaderCompiler.ixx @@ -29,11 +29,13 @@ export namespace HAL { std::vector functions; binary blob; - + std::string entry_point; // name passed to -E (e.g. "CS", "VS", "PS") + SERIALIZE() { ar& NVP(functions); ar& NVP(blob); + ar& NVP(entry_point); } }; diff --git a/sources/HAL/HAL.TiledMemoryManager.cpp b/sources/HAL/HAL.TiledMemoryManager.cpp index 6c16e84d..97233189 100644 --- a/sources/HAL/HAL.TiledMemoryManager.cpp +++ b/sources/HAL/HAL.TiledMemoryManager.cpp @@ -223,71 +223,9 @@ namespace HAL { { return tile_shape; } - void TiledResourceManager::init_tilings() - { - UINT num_tiles = 1; - D3D12_PACKED_MIP_INFO mip_info; - D3D12_TILE_SHAPE tile_shape; - UINT num_sub_res = 20; - // UINT first_sub_res; - D3D12_SUBRESOURCE_TILING tilings[20]; - - - auto desc = (resource)->get_desc(); - - resource->get_device().get_native_device()->GetResourceTiling((resource)->get_dx(), &num_tiles, &mip_info, &tile_shape, &num_sub_res, 0, tilings); - packed_mip_count = mip_info.NumTilesForPackedMips; - packed_subresource_offset = mip_info.NumStandardMips; - unpacked_mip_count = mip_info.NumStandardMips; - if (num_tiles > 0) - { - - this->tile_shape = { tile_shape.WidthInTexels,tile_shape.HeightInTexels,tile_shape.DepthInTexels }; - - if (desc.is_buffer()) - { - tiles.resize(1); - tiles[0].resize(uint3(tilings[0].WidthInTiles, tilings[0].HeightInTiles, tilings[0].DepthInTiles)); - for (uint x = 0; x < tiles[0].size().x; x++) - tiles[0][{x, 0, 0}].pos = { x,0,0 }; - - gpu_tiles.resize(1); - gpu_tiles[0].resize(uint3(tilings[0].WidthInTiles, tilings[0].HeightInTiles, tilings[0].DepthInTiles)); - for (uint x = 0; x < gpu_tiles[0].size().x; x++) - gpu_tiles[0][{x, 0, 0}].pos = { x,0,0 }; - - } - else - { - tiles.resize(mip_info.NumStandardMips); - gpu_tiles.resize(mip_info.NumStandardMips); - - packed_tiles.pos = { 0,0,0 }; - packed_tiles.subresource = mip_info.NumStandardMips; - - - for (UINT i = 0; i < mip_info.NumStandardMips; i++) - { - tiles[i].resize(uint3(tilings[i].WidthInTiles, tilings[i].HeightInTiles, tilings[i].DepthInTiles)); - gpu_tiles[i].resize(uint3(tilings[i].WidthInTiles, tilings[i].HeightInTiles, tilings[i].DepthInTiles)); - - for (uint x = 0; x < tiles[i].size().x; x++) - for (uint y = 0; y < tiles[i].size().y; y++) - for (uint z = 0; z < tiles[i].size().z; z++) - - { - tiles[i][{x, y, z}].pos = { x,y,z }; - tiles[i][{x, y, z}].subresource = i; - - gpu_tiles[i][{x, y, z}].pos = { x,y,z }; - gpu_tiles[i][{x, y, z}].subresource = i;; - } - } - } - - } - } - + // init_tilings() is implemented in the backend-specific files: + // D3D12/HAL.D3D12.TiledMemoryManager.cpp — real D3D12 implementation + // Vulkan/HAL.Vulkan.TiledMemoryManager.cpp — no-op stub void TiledResourceManager::load_packed(CommandList& list) { diff --git a/sources/HAL/HAL.ixx b/sources/HAL/HAL.ixx index f742bf39..2463bb86 100644 --- a/sources/HAL/HAL.ixx +++ b/sources/HAL/HAL.ixx @@ -6,7 +6,7 @@ export import :Types; export import :Sampler; // TODO: Should be private -//export import :Utils; +export import :Utils; export import :Device; export import :Queue; diff --git a/sources/HAL/SIG/Layout.ixx b/sources/HAL/SIG/Layout.ixx index f107fc2c..46d6d466 100644 --- a/sources/HAL/SIG/Layout.ixx +++ b/sources/HAL/SIG/Layout.ixx @@ -18,7 +18,7 @@ export template void process_one() { - desc[T::ID] = HAL::DescriptorConstants(2, 1, HAL::ShaderVisibility::ALL, T::ID); + desc[T::ID] = HAL::DescriptorConstants(T::ID, 1, HAL::ShaderVisibility::ALL, T::ID); // b-register = slot.id for push constant offset alignment } template< class ...A> diff --git a/sources/HAL/SIG/Slots.ixx b/sources/HAL/SIG/Slots.ixx index 316cc3b3..05c2bb0f 100644 --- a/sources/HAL/SIG/Slots.ixx +++ b/sources/HAL/SIG/Slots.ixx @@ -6,7 +6,7 @@ import :DescriptorHeap; import :Enums; //import :Buffer; import :SIG; - + import :Utils; struct placement_info { uint offset; @@ -242,7 +242,7 @@ export { return compiled; } - + #ifdef HAL_BACKEND_D3D12 static D3D12_INDIRECT_ARGUMENT_DESC create_indirect() { @@ -254,6 +254,7 @@ export { return desc; } +#endif }; class UsedSlots @@ -354,7 +355,7 @@ export { HAL::ResourceAddress compile() const { - +#ifdef HAL_BACKEND_D3D12 if(records.empty()) return HAL::ResourceAddress{}; @@ -422,6 +423,10 @@ export { // std::memcpy(info3.get_cpu_data(), &t, sizeof(t)); //} return res; +#else + + return HAL::ResourceAddress{}; +#endif } }; template diff --git a/sources/HAL/autogen/autogen.cpp b/sources/HAL/autogen/autogen.cpp index 4d56db57..f9ea86e0 100644 --- a/sources/HAL/autogen/autogen.cpp +++ b/sources/HAL/autogen/autogen.cpp @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - module HAL; import HAL; diff --git a/sources/HAL/autogen/autogen.ixx b/sources/HAL/autogen/autogen.ixx index 2944e361..2c7b7763 100644 --- a/sources/HAL/autogen/autogen.ixx +++ b/sources/HAL/autogen/autogen.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen; diff --git a/sources/HAL/autogen/enums.ixx b/sources/HAL/autogen/enums.ixx index 19955a0e..54e4b489 100644 --- a/sources/HAL/autogen/enums.ixx +++ b/sources/HAL/autogen/enums.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Enums; import Core; diff --git a/sources/HAL/autogen/layout/DefaultLayout.layout.ixx b/sources/HAL/autogen/layout/DefaultLayout.layout.ixx index 28dbaf46..0d3ec1be 100644 --- a/sources/HAL/autogen/layout/DefaultLayout.layout.ixx +++ b/sources/HAL/autogen/layout/DefaultLayout.layout.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Layouts.DefaultLayout; import Core; import :Autogen.Layouts.FrameLayout; diff --git a/sources/HAL/autogen/layout/FrameLayout.layout.ixx b/sources/HAL/autogen/layout/FrameLayout.layout.ixx index 54c53982..c8ce6309 100644 --- a/sources/HAL/autogen/layout/FrameLayout.layout.ixx +++ b/sources/HAL/autogen/layout/FrameLayout.layout.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Layouts.FrameLayout; import Core; import :Types; diff --git a/sources/HAL/autogen/layout/NoneLayout.layout.ixx b/sources/HAL/autogen/layout/NoneLayout.layout.ixx index c3931cbf..2b31e20b 100644 --- a/sources/HAL/autogen/layout/NoneLayout.layout.ixx +++ b/sources/HAL/autogen/layout/NoneLayout.layout.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Layouts.NoneLayout; import Core; import :Types; diff --git a/sources/HAL/autogen/pso.cpp b/sources/HAL/autogen/pso.cpp index b22fa525..f4a99d4b 100644 --- a/sources/HAL/autogen/pso.cpp +++ b/sources/HAL/autogen/pso.cpp @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - module HAL; import Core; import HAL; @@ -29,6 +28,8 @@ void init_indirect_commands(HAL::Device& device, enum_array& pso) { std::vector> tasks; + + tasks.emplace_back(PSOBase::create(device, pso[PSO::BlueNoise])); tasks.emplace_back(PSOBase::create(device, pso[PSO::BRDF])); tasks.emplace_back(PSOBase::create(device, pso[PSO::DenoiserReflectionReproject])); @@ -62,6 +63,8 @@ void init_pso(HAL::Device& device, enum_array& pso) tasks.emplace_back(PSOBase::create(device, pso[PSO::FrameClassification])); tasks.emplace_back(PSOBase::create(device, pso[PSO::FrameClassificationInitDispatch])); tasks.emplace_back(PSOBase::create(device, pso[PSO::ReflectionCombine])); + + tasks.emplace_back(PSOBase::create(device, pso[PSO::FontRender])); tasks.emplace_back(PSOBase::create(device, pso[PSO::RenderBoxes])); tasks.emplace_back(PSOBase::create(device, pso[PSO::RenderToDS])); @@ -97,7 +100,18 @@ void init_pso(HAL::Device& device, enum_array& pso) tasks.emplace_back(PSOBase::create(device, pso[PSO::VoxelIndirectUpsample])); tasks.emplace_back(PSOBase::create(device, pso[PSO::VoxelDebug])); tasks.emplace_back(PSOBase::create(device, pso[PSO::DenoiserDownsample])); + + + +#ifndef HAL_BACKEND_VULKAN + + + tasks.emplace_back(PSOBase::create(device, pso[PSO::WorkGR])); + + +#endif // !HAL_BACKEND_VULKAN + when_all(begin(tasks), end(tasks)).wait(); } diff --git a/sources/HAL/autogen/pso/BRDF.pso.ixx b/sources/HAL/autogen/pso/BRDF.pso.ixx index 3a549dae..6c90a9af 100644 --- a/sources/HAL/autogen/pso/BRDF.pso.ixx +++ b/sources/HAL/autogen/pso/BRDF.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.BRDF; import Core; diff --git a/sources/HAL/autogen/pso/BlendWeight.pso.ixx b/sources/HAL/autogen/pso/BlendWeight.pso.ixx index 3ff271a3..3385b8a3 100644 --- a/sources/HAL/autogen/pso/BlendWeight.pso.ixx +++ b/sources/HAL/autogen/pso/BlendWeight.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.BlendWeight; import Core; diff --git a/sources/HAL/autogen/pso/Blending.pso.ixx b/sources/HAL/autogen/pso/Blending.pso.ixx index ca840f33..83d50bb3 100644 --- a/sources/HAL/autogen/pso/Blending.pso.ixx +++ b/sources/HAL/autogen/pso/Blending.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.Blending; import Core; diff --git a/sources/HAL/autogen/pso/BlueNoise.pso.ixx b/sources/HAL/autogen/pso/BlueNoise.pso.ixx index 978620df..21f5cdc3 100644 --- a/sources/HAL/autogen/pso/BlueNoise.pso.ixx +++ b/sources/HAL/autogen/pso/BlueNoise.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.BlueNoise; import Core; diff --git a/sources/HAL/autogen/pso/CanvasBack.pso.ixx b/sources/HAL/autogen/pso/CanvasBack.pso.ixx index aca8eb8d..56bc190a 100644 --- a/sources/HAL/autogen/pso/CanvasBack.pso.ixx +++ b/sources/HAL/autogen/pso/CanvasBack.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.CanvasBack; import Core; @@ -46,7 +45,7 @@ export namespace PSOS mpso.pixel.flags = HAL::ShaderOptions::None; - mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.rtv_formats = { HAL::Format::B8G8R8A8_UNORM }; mpso.blend = { HAL::Blends::AlphaBlend }; mpso.enable_depth =false; diff --git a/sources/HAL/autogen/pso/CanvasLines.pso.ixx b/sources/HAL/autogen/pso/CanvasLines.pso.ixx index b5e62ff7..1d7fd63c 100644 --- a/sources/HAL/autogen/pso/CanvasLines.pso.ixx +++ b/sources/HAL/autogen/pso/CanvasLines.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.CanvasLines; import Core; @@ -58,7 +57,7 @@ export namespace PSOS mpso.hull.flags = HAL::ShaderOptions::None; - mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.rtv_formats = { HAL::Format::B8G8R8A8_UNORM }; mpso.blend = { HAL::Blends::AlphaBlend }; mpso.enable_depth =false; diff --git a/sources/HAL/autogen/pso/CopyTexture.pso.ixx b/sources/HAL/autogen/pso/CopyTexture.pso.ixx index df005d04..7866b5f6 100644 --- a/sources/HAL/autogen/pso/CopyTexture.pso.ixx +++ b/sources/HAL/autogen/pso/CopyTexture.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.CopyTexture; import Core; diff --git a/sources/HAL/autogen/pso/CubemapENV.pso.ixx b/sources/HAL/autogen/pso/CubemapENV.pso.ixx index a254cf97..276c1bf1 100644 --- a/sources/HAL/autogen/pso/CubemapENV.pso.ixx +++ b/sources/HAL/autogen/pso/CubemapENV.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.CubemapENV; import Core; diff --git a/sources/HAL/autogen/pso/CubemapENVDiffuse.pso.ixx b/sources/HAL/autogen/pso/CubemapENVDiffuse.pso.ixx index ddca2fa9..9c2ac961 100644 --- a/sources/HAL/autogen/pso/CubemapENVDiffuse.pso.ixx +++ b/sources/HAL/autogen/pso/CubemapENVDiffuse.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.CubemapENVDiffuse; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserDownsample.pso.ixx b/sources/HAL/autogen/pso/DenoiserDownsample.pso.ixx index 2ccd7ffe..d6b4c143 100644 --- a/sources/HAL/autogen/pso/DenoiserDownsample.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserDownsample.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserDownsample; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserHistoryFix.pso.ixx b/sources/HAL/autogen/pso/DenoiserHistoryFix.pso.ixx index 5f725d82..2a4bb873 100644 --- a/sources/HAL/autogen/pso/DenoiserHistoryFix.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserHistoryFix.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserHistoryFix; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserReflectionPrefilter.pso.ixx b/sources/HAL/autogen/pso/DenoiserReflectionPrefilter.pso.ixx index 9252c72c..48554a1f 100644 --- a/sources/HAL/autogen/pso/DenoiserReflectionPrefilter.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserReflectionPrefilter.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserReflectionPrefilter; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserReflectionReproject.pso.ixx b/sources/HAL/autogen/pso/DenoiserReflectionReproject.pso.ixx index 314808eb..aa7550af 100644 --- a/sources/HAL/autogen/pso/DenoiserReflectionReproject.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserReflectionReproject.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserReflectionReproject; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserReflectionResolve.pso.ixx b/sources/HAL/autogen/pso/DenoiserReflectionResolve.pso.ixx index a15d2867..9e7bbd26 100644 --- a/sources/HAL/autogen/pso/DenoiserReflectionResolve.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserReflectionResolve.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserReflectionResolve; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserShadow_Filter.pso.ixx b/sources/HAL/autogen/pso/DenoiserShadow_Filter.pso.ixx index cfceca00..afd2f261 100644 --- a/sources/HAL/autogen/pso/DenoiserShadow_Filter.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserShadow_Filter.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserShadow_Filter; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserShadow_Prepare.pso.ixx b/sources/HAL/autogen/pso/DenoiserShadow_Prepare.pso.ixx index 28f29f3e..2c544f63 100644 --- a/sources/HAL/autogen/pso/DenoiserShadow_Prepare.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserShadow_Prepare.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserShadow_Prepare; import Core; diff --git a/sources/HAL/autogen/pso/DenoiserShadow_TileClassification.pso.ixx b/sources/HAL/autogen/pso/DenoiserShadow_TileClassification.pso.ixx index 0660c870..8455b877 100644 --- a/sources/HAL/autogen/pso/DenoiserShadow_TileClassification.pso.ixx +++ b/sources/HAL/autogen/pso/DenoiserShadow_TileClassification.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DenoiserShadow_TileClassification; import Core; diff --git a/sources/HAL/autogen/pso/DepthDraw.pso.ixx b/sources/HAL/autogen/pso/DepthDraw.pso.ixx index a1651573..33506e6d 100644 --- a/sources/HAL/autogen/pso/DepthDraw.pso.ixx +++ b/sources/HAL/autogen/pso/DepthDraw.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DepthDraw; import Core; diff --git a/sources/HAL/autogen/pso/DownsampleDepth.pso.ixx b/sources/HAL/autogen/pso/DownsampleDepth.pso.ixx index ce4f0358..6b6a3456 100644 --- a/sources/HAL/autogen/pso/DownsampleDepth.pso.ixx +++ b/sources/HAL/autogen/pso/DownsampleDepth.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DownsampleDepth; import Core; diff --git a/sources/HAL/autogen/pso/DrawAxis.pso.ixx b/sources/HAL/autogen/pso/DrawAxis.pso.ixx index df98086c..55e77e94 100644 --- a/sources/HAL/autogen/pso/DrawAxis.pso.ixx +++ b/sources/HAL/autogen/pso/DrawAxis.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DrawAxis; import Core; diff --git a/sources/HAL/autogen/pso/DrawBox.pso.ixx b/sources/HAL/autogen/pso/DrawBox.pso.ixx index 1482a848..62b5db48 100644 --- a/sources/HAL/autogen/pso/DrawBox.pso.ixx +++ b/sources/HAL/autogen/pso/DrawBox.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DrawBox; import Core; diff --git a/sources/HAL/autogen/pso/DrawSelected.pso.ixx b/sources/HAL/autogen/pso/DrawSelected.pso.ixx index 34bc6ce6..46a089f8 100644 --- a/sources/HAL/autogen/pso/DrawSelected.pso.ixx +++ b/sources/HAL/autogen/pso/DrawSelected.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DrawSelected; import Core; diff --git a/sources/HAL/autogen/pso/DrawStencil.pso.ixx b/sources/HAL/autogen/pso/DrawStencil.pso.ixx index f0c4945c..70402491 100644 --- a/sources/HAL/autogen/pso/DrawStencil.pso.ixx +++ b/sources/HAL/autogen/pso/DrawStencil.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.DrawStencil; import Core; diff --git a/sources/HAL/autogen/pso/EdgeDetect.pso.ixx b/sources/HAL/autogen/pso/EdgeDetect.pso.ixx index 92e63a1a..e0ba2735 100644 --- a/sources/HAL/autogen/pso/EdgeDetect.pso.ixx +++ b/sources/HAL/autogen/pso/EdgeDetect.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.EdgeDetect; import Core; diff --git a/sources/HAL/autogen/pso/FSR.pso.ixx b/sources/HAL/autogen/pso/FSR.pso.ixx index b6501e78..fab9fd11 100644 --- a/sources/HAL/autogen/pso/FSR.pso.ixx +++ b/sources/HAL/autogen/pso/FSR.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FSR; import Core; diff --git a/sources/HAL/autogen/pso/FontRender.pso.ixx b/sources/HAL/autogen/pso/FontRender.pso.ixx index 237ac795..a1bb6d74 100644 --- a/sources/HAL/autogen/pso/FontRender.pso.ixx +++ b/sources/HAL/autogen/pso/FontRender.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FontRender; import Core; @@ -60,6 +59,7 @@ export namespace PSOS mpso.topology =HAL::PrimitiveTopologyType::POINT; mpso.enable_depth =false; + mpso.cull =HAL::CullMode::None; return mpso; } diff --git a/sources/HAL/autogen/pso/FrameClassification.pso.ixx b/sources/HAL/autogen/pso/FrameClassification.pso.ixx index eface915..3f5bfe17 100644 --- a/sources/HAL/autogen/pso/FrameClassification.pso.ixx +++ b/sources/HAL/autogen/pso/FrameClassification.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FrameClassification; import Core; diff --git a/sources/HAL/autogen/pso/FrameClassificationInitDispatch.pso.ixx b/sources/HAL/autogen/pso/FrameClassificationInitDispatch.pso.ixx index 0b48c101..df6f0ac8 100644 --- a/sources/HAL/autogen/pso/FrameClassificationInitDispatch.pso.ixx +++ b/sources/HAL/autogen/pso/FrameClassificationInitDispatch.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FrameClassificationInitDispatch; import Core; diff --git a/sources/HAL/autogen/pso/FrameGraph_Debug_NotImplemented.pso.ixx b/sources/HAL/autogen/pso/FrameGraph_Debug_NotImplemented.pso.ixx index 664063ad..1e0a97fa 100644 --- a/sources/HAL/autogen/pso/FrameGraph_Debug_NotImplemented.pso.ixx +++ b/sources/HAL/autogen/pso/FrameGraph_Debug_NotImplemented.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FrameGraph_Debug_NotImplemented; import Core; diff --git a/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2D.pso.ixx b/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2D.pso.ixx index 7438997d..64ded86d 100644 --- a/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2D.pso.ixx +++ b/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2D.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FrameGraph_Debug_Texture2D; import Core; diff --git a/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2DArray.pso.ixx b/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2DArray.pso.ixx index a5ce77b5..380f56bb 100644 --- a/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2DArray.pso.ixx +++ b/sources/HAL/autogen/pso/FrameGraph_Debug_Texture2DArray.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FrameGraph_Debug_Texture2DArray; import Core; diff --git a/sources/HAL/autogen/pso/FrameGraph_Debug_Texture3D.pso.ixx b/sources/HAL/autogen/pso/FrameGraph_Debug_Texture3D.pso.ixx index 44d0c9b6..eb8d0ac7 100644 --- a/sources/HAL/autogen/pso/FrameGraph_Debug_Texture3D.pso.ixx +++ b/sources/HAL/autogen/pso/FrameGraph_Debug_Texture3D.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FrameGraph_Debug_Texture3D; import Core; diff --git a/sources/HAL/autogen/pso/FrameGraph_Debug_TextureCube.pso.ixx b/sources/HAL/autogen/pso/FrameGraph_Debug_TextureCube.pso.ixx index da297dee..0182fa00 100644 --- a/sources/HAL/autogen/pso/FrameGraph_Debug_TextureCube.pso.ixx +++ b/sources/HAL/autogen/pso/FrameGraph_Debug_TextureCube.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.FrameGraph_Debug_TextureCube; import Core; diff --git a/sources/HAL/autogen/pso/GBufferDownsample.pso.ixx b/sources/HAL/autogen/pso/GBufferDownsample.pso.ixx index 58535b69..85fdec26 100644 --- a/sources/HAL/autogen/pso/GBufferDownsample.pso.ixx +++ b/sources/HAL/autogen/pso/GBufferDownsample.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.GBufferDownsample; import Core; diff --git a/sources/HAL/autogen/pso/GBufferDraw.pso.ixx b/sources/HAL/autogen/pso/GBufferDraw.pso.ixx index 501e0ae2..12bf1ceb 100644 --- a/sources/HAL/autogen/pso/GBufferDraw.pso.ixx +++ b/sources/HAL/autogen/pso/GBufferDraw.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.GBufferDraw; import Core; diff --git a/sources/HAL/autogen/pso/GatherBoxes.pso.ixx b/sources/HAL/autogen/pso/GatherBoxes.pso.ixx index 320f8eff..7818d217 100644 --- a/sources/HAL/autogen/pso/GatherBoxes.pso.ixx +++ b/sources/HAL/autogen/pso/GatherBoxes.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.GatherBoxes; import Core; diff --git a/sources/HAL/autogen/pso/GatherMeshes.pso.ixx b/sources/HAL/autogen/pso/GatherMeshes.pso.ixx index 44fd1e49..2f4a670d 100644 --- a/sources/HAL/autogen/pso/GatherMeshes.pso.ixx +++ b/sources/HAL/autogen/pso/GatherMeshes.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.GatherMeshes; import Core; diff --git a/sources/HAL/autogen/pso/GatherPipeline.pso.ixx b/sources/HAL/autogen/pso/GatherPipeline.pso.ixx index 4b27afa9..932d4a82 100644 --- a/sources/HAL/autogen/pso/GatherPipeline.pso.ixx +++ b/sources/HAL/autogen/pso/GatherPipeline.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.GatherPipeline; import Core; diff --git a/sources/HAL/autogen/pso/InitDispatch.pso.ixx b/sources/HAL/autogen/pso/InitDispatch.pso.ixx index 23c21ae6..dc4474fd 100644 --- a/sources/HAL/autogen/pso/InitDispatch.pso.ixx +++ b/sources/HAL/autogen/pso/InitDispatch.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.InitDispatch; import Core; diff --git a/sources/HAL/autogen/pso/Lighting.pso.ixx b/sources/HAL/autogen/pso/Lighting.pso.ixx index b7406ee3..4082ee56 100644 --- a/sources/HAL/autogen/pso/Lighting.pso.ixx +++ b/sources/HAL/autogen/pso/Lighting.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.Lighting; import Core; diff --git a/sources/HAL/autogen/pso/MipMapping.pso.ixx b/sources/HAL/autogen/pso/MipMapping.pso.ixx index faf8a90f..123ac8e8 100644 --- a/sources/HAL/autogen/pso/MipMapping.pso.ixx +++ b/sources/HAL/autogen/pso/MipMapping.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.MipMapping; import Core; diff --git a/sources/HAL/autogen/pso/NinePatch.pso.ixx b/sources/HAL/autogen/pso/NinePatch.pso.ixx index 4be39084..e944ed86 100644 --- a/sources/HAL/autogen/pso/NinePatch.pso.ixx +++ b/sources/HAL/autogen/pso/NinePatch.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.NinePatch; import Core; @@ -46,9 +45,10 @@ export namespace PSOS mpso.pixel.flags = HAL::ShaderOptions::None; - mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.rtv_formats = { HAL::Format::B8G8R8A8_UNORM }; mpso.blend = { HAL::Blends::AlphaBlend }; + mpso.cull =HAL::CullMode::None; return mpso; } diff --git a/sources/HAL/autogen/pso/PSSMApply.pso.ixx b/sources/HAL/autogen/pso/PSSMApply.pso.ixx index 12315087..4df513ff 100644 --- a/sources/HAL/autogen/pso/PSSMApply.pso.ixx +++ b/sources/HAL/autogen/pso/PSSMApply.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.PSSMApply; import Core; diff --git a/sources/HAL/autogen/pso/PSSMMask.pso.ixx b/sources/HAL/autogen/pso/PSSMMask.pso.ixx index ca603061..9d5bce2d 100644 --- a/sources/HAL/autogen/pso/PSSMMask.pso.ixx +++ b/sources/HAL/autogen/pso/PSSMMask.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.PSSMMask; import Core; diff --git a/sources/HAL/autogen/pso/QualityColor.pso.ixx b/sources/HAL/autogen/pso/QualityColor.pso.ixx index 9ab7ca39..28e64273 100644 --- a/sources/HAL/autogen/pso/QualityColor.pso.ixx +++ b/sources/HAL/autogen/pso/QualityColor.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.QualityColor; import Core; diff --git a/sources/HAL/autogen/pso/QualityToStencil.pso.ixx b/sources/HAL/autogen/pso/QualityToStencil.pso.ixx index 7becf630..6c4b349c 100644 --- a/sources/HAL/autogen/pso/QualityToStencil.pso.ixx +++ b/sources/HAL/autogen/pso/QualityToStencil.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.QualityToStencil; import Core; diff --git a/sources/HAL/autogen/pso/QualityToStencilREfl.pso.ixx b/sources/HAL/autogen/pso/QualityToStencilREfl.pso.ixx index a579e525..7295ca1b 100644 --- a/sources/HAL/autogen/pso/QualityToStencilREfl.pso.ixx +++ b/sources/HAL/autogen/pso/QualityToStencilREfl.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.QualityToStencilREfl; import Core; diff --git a/sources/HAL/autogen/pso/RCAS.pso.ixx b/sources/HAL/autogen/pso/RCAS.pso.ixx index 704c4dc4..50df8da9 100644 --- a/sources/HAL/autogen/pso/RCAS.pso.ixx +++ b/sources/HAL/autogen/pso/RCAS.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.RCAS; import Core; diff --git a/sources/HAL/autogen/pso/ReflectionCombine.pso.ixx b/sources/HAL/autogen/pso/ReflectionCombine.pso.ixx index acb15da9..ef946b29 100644 --- a/sources/HAL/autogen/pso/ReflectionCombine.pso.ixx +++ b/sources/HAL/autogen/pso/ReflectionCombine.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.ReflectionCombine; import Core; diff --git a/sources/HAL/autogen/pso/RenderBoxes.pso.ixx b/sources/HAL/autogen/pso/RenderBoxes.pso.ixx index 25f9bf18..69bb05f2 100644 --- a/sources/HAL/autogen/pso/RenderBoxes.pso.ixx +++ b/sources/HAL/autogen/pso/RenderBoxes.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.RenderBoxes; import Core; diff --git a/sources/HAL/autogen/pso/RenderToDS.pso.ixx b/sources/HAL/autogen/pso/RenderToDS.pso.ixx index 921ea8c8..5643924d 100644 --- a/sources/HAL/autogen/pso/RenderToDS.pso.ixx +++ b/sources/HAL/autogen/pso/RenderToDS.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.RenderToDS; import Core; diff --git a/sources/HAL/autogen/pso/SS_Shadow.pso.ixx b/sources/HAL/autogen/pso/SS_Shadow.pso.ixx index 49a7ae85..9bc284fb 100644 --- a/sources/HAL/autogen/pso/SS_Shadow.pso.ixx +++ b/sources/HAL/autogen/pso/SS_Shadow.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.SS_Shadow; import Core; diff --git a/sources/HAL/autogen/pso/SimpleRect.pso.ixx b/sources/HAL/autogen/pso/SimpleRect.pso.ixx index 9dfd1ac1..665e7aef 100644 --- a/sources/HAL/autogen/pso/SimpleRect.pso.ixx +++ b/sources/HAL/autogen/pso/SimpleRect.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.SimpleRect; import Core; @@ -46,7 +45,7 @@ export namespace PSOS mpso.pixel.flags = HAL::ShaderOptions::None; - mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.rtv_formats = { HAL::Format::B8G8R8A8_UNORM }; mpso.blend = { HAL::Blends::AlphaBlend }; mpso.cull =HAL::CullMode::None; diff --git a/sources/HAL/autogen/pso/Sky.pso.ixx b/sources/HAL/autogen/pso/Sky.pso.ixx index e5d5a880..157f399b 100644 --- a/sources/HAL/autogen/pso/Sky.pso.ixx +++ b/sources/HAL/autogen/pso/Sky.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.Sky; import Core; diff --git a/sources/HAL/autogen/pso/SkyCube.pso.ixx b/sources/HAL/autogen/pso/SkyCube.pso.ixx index 1d71252e..31c902e9 100644 --- a/sources/HAL/autogen/pso/SkyCube.pso.ixx +++ b/sources/HAL/autogen/pso/SkyCube.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.SkyCube; import Core; diff --git a/sources/HAL/autogen/pso/StencilerLast.pso.ixx b/sources/HAL/autogen/pso/StencilerLast.pso.ixx index 4dad6db3..3a2e4824 100644 --- a/sources/HAL/autogen/pso/StencilerLast.pso.ixx +++ b/sources/HAL/autogen/pso/StencilerLast.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.StencilerLast; import Core; diff --git a/sources/HAL/autogen/pso/VoxelCopy.pso.ixx b/sources/HAL/autogen/pso/VoxelCopy.pso.ixx index ce76d904..ba31e971 100644 --- a/sources/HAL/autogen/pso/VoxelCopy.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelCopy.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelCopy; import Core; diff --git a/sources/HAL/autogen/pso/VoxelDebug.pso.ixx b/sources/HAL/autogen/pso/VoxelDebug.pso.ixx index 08ab3a5c..3aae7fd5 100644 --- a/sources/HAL/autogen/pso/VoxelDebug.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelDebug.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelDebug; import Core; diff --git a/sources/HAL/autogen/pso/VoxelDownsample.pso.ixx b/sources/HAL/autogen/pso/VoxelDownsample.pso.ixx index b13030f7..b427eddb 100644 --- a/sources/HAL/autogen/pso/VoxelDownsample.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelDownsample.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelDownsample; import Core; diff --git a/sources/HAL/autogen/pso/VoxelIndirectFilter.pso.ixx b/sources/HAL/autogen/pso/VoxelIndirectFilter.pso.ixx index 0cae006c..ce92b60d 100644 --- a/sources/HAL/autogen/pso/VoxelIndirectFilter.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelIndirectFilter.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelIndirectFilter; import Core; diff --git a/sources/HAL/autogen/pso/VoxelIndirectHi.pso.ixx b/sources/HAL/autogen/pso/VoxelIndirectHi.pso.ixx index deeb9179..22c05b98 100644 --- a/sources/HAL/autogen/pso/VoxelIndirectHi.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelIndirectHi.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelIndirectHi; import Core; diff --git a/sources/HAL/autogen/pso/VoxelIndirectLow.pso.ixx b/sources/HAL/autogen/pso/VoxelIndirectLow.pso.ixx index a27b07a2..39ed59d3 100644 --- a/sources/HAL/autogen/pso/VoxelIndirectLow.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelIndirectLow.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelIndirectLow; import Core; diff --git a/sources/HAL/autogen/pso/VoxelIndirectUpsample.pso.ixx b/sources/HAL/autogen/pso/VoxelIndirectUpsample.pso.ixx index 1e6a6415..5de1f97d 100644 --- a/sources/HAL/autogen/pso/VoxelIndirectUpsample.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelIndirectUpsample.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelIndirectUpsample; import Core; diff --git a/sources/HAL/autogen/pso/VoxelReflectionHi.pso.ixx b/sources/HAL/autogen/pso/VoxelReflectionHi.pso.ixx index 5d2a382f..dab1e5d6 100644 --- a/sources/HAL/autogen/pso/VoxelReflectionHi.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelReflectionHi.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelReflectionHi; import Core; diff --git a/sources/HAL/autogen/pso/VoxelReflectionUpsample.pso.ixx b/sources/HAL/autogen/pso/VoxelReflectionUpsample.pso.ixx index 17b5d249..01452a08 100644 --- a/sources/HAL/autogen/pso/VoxelReflectionUpsample.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelReflectionUpsample.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelReflectionUpsample; import Core; diff --git a/sources/HAL/autogen/pso/VoxelVisibility.pso.ixx b/sources/HAL/autogen/pso/VoxelVisibility.pso.ixx index ae1bbaea..7389bcc5 100644 --- a/sources/HAL/autogen/pso/VoxelVisibility.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelVisibility.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelVisibility; import Core; diff --git a/sources/HAL/autogen/pso/VoxelZero.pso.ixx b/sources/HAL/autogen/pso/VoxelZero.pso.ixx index 7aedbcc0..c46bfd09 100644 --- a/sources/HAL/autogen/pso/VoxelZero.pso.ixx +++ b/sources/HAL/autogen/pso/VoxelZero.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.VoxelZero; import Core; diff --git a/sources/HAL/autogen/pso/Voxelization.pso.ixx b/sources/HAL/autogen/pso/Voxelization.pso.ixx index 2e945e63..d2cc165b 100644 --- a/sources/HAL/autogen/pso/Voxelization.pso.ixx +++ b/sources/HAL/autogen/pso/Voxelization.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.Voxelization; import Core; diff --git a/sources/HAL/autogen/pso/WorkGR.pso.ixx b/sources/HAL/autogen/pso/WorkGR.pso.ixx index 77f692d7..2731dea3 100644 --- a/sources/HAL/autogen/pso/WorkGR.pso.ixx +++ b/sources/HAL/autogen/pso/WorkGR.pso.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.PSO.WorkGR; import Core; diff --git a/sources/HAL/autogen/rt/DepthOnly.rt.ixx b/sources/HAL/autogen/rt/DepthOnly.rt.ixx index e578e032..de58e69d 100644 --- a/sources/HAL/autogen/rt/DepthOnly.rt.ixx +++ b/sources/HAL/autogen/rt/DepthOnly.rt.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.RT.DepthOnly; import Core; diff --git a/sources/HAL/autogen/rt/GBuffer.rt.ixx b/sources/HAL/autogen/rt/GBuffer.rt.ixx index 8a8bfa04..42d97057 100644 --- a/sources/HAL/autogen/rt/GBuffer.rt.ixx +++ b/sources/HAL/autogen/rt/GBuffer.rt.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.RT.GBuffer; import Core; diff --git a/sources/HAL/autogen/rt/GBufferDownsampleRT.rt.ixx b/sources/HAL/autogen/rt/GBufferDownsampleRT.rt.ixx index 785777f9..11995617 100644 --- a/sources/HAL/autogen/rt/GBufferDownsampleRT.rt.ixx +++ b/sources/HAL/autogen/rt/GBufferDownsampleRT.rt.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.RT.GBufferDownsampleRT; import Core; diff --git a/sources/HAL/autogen/rt/NoOutput.rt.ixx b/sources/HAL/autogen/rt/NoOutput.rt.ixx index 5b4d7d74..8f56fa3a 100644 --- a/sources/HAL/autogen/rt/NoOutput.rt.ixx +++ b/sources/HAL/autogen/rt/NoOutput.rt.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.RT.NoOutput; import Core; diff --git a/sources/HAL/autogen/rt/SingleColor.rt.ixx b/sources/HAL/autogen/rt/SingleColor.rt.ixx index 8c47cca1..2e700d79 100644 --- a/sources/HAL/autogen/rt/SingleColor.rt.ixx +++ b/sources/HAL/autogen/rt/SingleColor.rt.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.RT.SingleColor; import Core; diff --git a/sources/HAL/autogen/rt/SingleColorDepth.rt.ixx b/sources/HAL/autogen/rt/SingleColorDepth.rt.ixx index 43e7ddf7..0b66389e 100644 --- a/sources/HAL/autogen/rt/SingleColorDepth.rt.ixx +++ b/sources/HAL/autogen/rt/SingleColorDepth.rt.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.RT.SingleColorDepth; import Core; diff --git a/sources/HAL/autogen/rtx/ColorPass.h b/sources/HAL/autogen/rtx/ColorPass.h index 2749887b..2bb38fd3 100644 --- a/sources/HAL/autogen/rtx/ColorPass.h +++ b/sources/HAL/autogen/rtx/ColorPass.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct ColorPass: public RaytracePass diff --git a/sources/HAL/autogen/rtx/Indirect.h b/sources/HAL/autogen/rtx/Indirect.h index 93567e4d..da8eb027 100644 --- a/sources/HAL/autogen/rtx/Indirect.h +++ b/sources/HAL/autogen/rtx/Indirect.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct Indirect: public RaytraceRaygen diff --git a/sources/HAL/autogen/rtx/MainRTX.rtx.ixx b/sources/HAL/autogen/rtx/MainRTX.rtx.ixx index 4d358271..2834c2d0 100644 --- a/sources/HAL/autogen/rtx/MainRTX.rtx.ixx +++ b/sources/HAL/autogen/rtx/MainRTX.rtx.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.RTX.MainRTX; import Core; diff --git a/sources/HAL/autogen/rtx/Reflection.h b/sources/HAL/autogen/rtx/Reflection.h index c37a250c..5a1dc25a 100644 --- a/sources/HAL/autogen/rtx/Reflection.h +++ b/sources/HAL/autogen/rtx/Reflection.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct Reflection: public RaytraceRaygen diff --git a/sources/HAL/autogen/rtx/Shadow.h b/sources/HAL/autogen/rtx/Shadow.h index 3b19c8f3..2516752f 100644 --- a/sources/HAL/autogen/rtx/Shadow.h +++ b/sources/HAL/autogen/rtx/Shadow.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct Shadow: public RaytraceRaygen diff --git a/sources/HAL/autogen/rtx/ShadowPass.h b/sources/HAL/autogen/rtx/ShadowPass.h index d3967acc..04674ff0 100644 --- a/sources/HAL/autogen/rtx/ShadowPass.h +++ b/sources/HAL/autogen/rtx/ShadowPass.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct ShadowPass: public RaytracePass diff --git a/sources/HAL/autogen/tables/AABB.table.ixx b/sources/HAL/autogen/tables/AABB.table.ixx index 5a55d17d..81816cce 100644 --- a/sources/HAL/autogen/tables/AABB.table.ixx +++ b/sources/HAL/autogen/tables/AABB.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.AABB; import Core; diff --git a/sources/HAL/autogen/tables/BRDF.table.ixx b/sources/HAL/autogen/tables/BRDF.table.ixx index 45f0c137..33138717 100644 --- a/sources/HAL/autogen/tables/BRDF.table.ixx +++ b/sources/HAL/autogen/tables/BRDF.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.BRDF; import Core; diff --git a/sources/HAL/autogen/tables/BlueNoise.table.ixx b/sources/HAL/autogen/tables/BlueNoise.table.ixx index c7ae9b07..f82dbf04 100644 --- a/sources/HAL/autogen/tables/BlueNoise.table.ixx +++ b/sources/HAL/autogen/tables/BlueNoise.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.BlueNoise; import Core; diff --git a/sources/HAL/autogen/tables/BoxInfo.table.ixx b/sources/HAL/autogen/tables/BoxInfo.table.ixx index 1fd6163e..455ef8ab 100644 --- a/sources/HAL/autogen/tables/BoxInfo.table.ixx +++ b/sources/HAL/autogen/tables/BoxInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.BoxInfo; import Core; diff --git a/sources/HAL/autogen/tables/Camera.table.ixx b/sources/HAL/autogen/tables/Camera.table.ixx index 4957e2e4..6435cca6 100644 --- a/sources/HAL/autogen/tables/Camera.table.ixx +++ b/sources/HAL/autogen/tables/Camera.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Camera; import Core; diff --git a/sources/HAL/autogen/tables/Color.table.ixx b/sources/HAL/autogen/tables/Color.table.ixx index 42b037c1..52551ad3 100644 --- a/sources/HAL/autogen/tables/Color.table.ixx +++ b/sources/HAL/autogen/tables/Color.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Color; import Core; diff --git a/sources/HAL/autogen/tables/ColorRect.table.ixx b/sources/HAL/autogen/tables/ColorRect.table.ixx index c99966aa..22e5fec7 100644 --- a/sources/HAL/autogen/tables/ColorRect.table.ixx +++ b/sources/HAL/autogen/tables/ColorRect.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.ColorRect; import Core; diff --git a/sources/HAL/autogen/tables/CommandData.table.ixx b/sources/HAL/autogen/tables/CommandData.table.ixx index 93000089..e66c41c4 100644 --- a/sources/HAL/autogen/tables/CommandData.table.ixx +++ b/sources/HAL/autogen/tables/CommandData.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.CommandData; import Core; diff --git a/sources/HAL/autogen/tables/CopyTexture.table.ixx b/sources/HAL/autogen/tables/CopyTexture.table.ixx index 7441c34e..8b688b45 100644 --- a/sources/HAL/autogen/tables/CopyTexture.table.ixx +++ b/sources/HAL/autogen/tables/CopyTexture.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.CopyTexture; import Core; diff --git a/sources/HAL/autogen/tables/Countour.table.ixx b/sources/HAL/autogen/tables/Countour.table.ixx index f573edc0..0b1f2d85 100644 --- a/sources/HAL/autogen/tables/Countour.table.ixx +++ b/sources/HAL/autogen/tables/Countour.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Countour; import Core; diff --git a/sources/HAL/autogen/tables/DebugInfo.table.ixx b/sources/HAL/autogen/tables/DebugInfo.table.ixx index 914173bc..1a8513d7 100644 --- a/sources/HAL/autogen/tables/DebugInfo.table.ixx +++ b/sources/HAL/autogen/tables/DebugInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DebugInfo; import Core; diff --git a/sources/HAL/autogen/tables/DebugStruct.table.ixx b/sources/HAL/autogen/tables/DebugStruct.table.ixx index 175a3a61..ad9a3ffe 100644 --- a/sources/HAL/autogen/tables/DebugStruct.table.ixx +++ b/sources/HAL/autogen/tables/DebugStruct.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DebugStruct; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserDownsample.table.ixx b/sources/HAL/autogen/tables/DenoiserDownsample.table.ixx index 02930fda..66f43523 100644 --- a/sources/HAL/autogen/tables/DenoiserDownsample.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserDownsample.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserDownsample; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserHistoryFix.table.ixx b/sources/HAL/autogen/tables/DenoiserHistoryFix.table.ixx index f9e62fbe..880f149c 100644 --- a/sources/HAL/autogen/tables/DenoiserHistoryFix.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserHistoryFix.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserHistoryFix; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserReflectionCommon.table.ixx b/sources/HAL/autogen/tables/DenoiserReflectionCommon.table.ixx index 3255e0ba..58557337 100644 --- a/sources/HAL/autogen/tables/DenoiserReflectionCommon.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserReflectionCommon.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserReflectionCommon; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserReflectionPrefilter.table.ixx b/sources/HAL/autogen/tables/DenoiserReflectionPrefilter.table.ixx index eec0c513..4c93ab51 100644 --- a/sources/HAL/autogen/tables/DenoiserReflectionPrefilter.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserReflectionPrefilter.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserReflectionPrefilter; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserReflectionReproject.table.ixx b/sources/HAL/autogen/tables/DenoiserReflectionReproject.table.ixx index dab55545..01115c83 100644 --- a/sources/HAL/autogen/tables/DenoiserReflectionReproject.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserReflectionReproject.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserReflectionReproject; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserReflectionResolve.table.ixx b/sources/HAL/autogen/tables/DenoiserReflectionResolve.table.ixx index c9010c6e..ec80a1d7 100644 --- a/sources/HAL/autogen/tables/DenoiserReflectionResolve.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserReflectionResolve.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserReflectionResolve; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserShadow_Filter.table.ixx b/sources/HAL/autogen/tables/DenoiserShadow_Filter.table.ixx index c5a4d801..cba3061f 100644 --- a/sources/HAL/autogen/tables/DenoiserShadow_Filter.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserShadow_Filter.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserShadow_Filter; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserShadow_FilterLast.table.ixx b/sources/HAL/autogen/tables/DenoiserShadow_FilterLast.table.ixx index a3cf0ec7..9ca199bd 100644 --- a/sources/HAL/autogen/tables/DenoiserShadow_FilterLast.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserShadow_FilterLast.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserShadow_FilterLast; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserShadow_FilterLocal.table.ixx b/sources/HAL/autogen/tables/DenoiserShadow_FilterLocal.table.ixx index dadebb42..e7a1cbc9 100644 --- a/sources/HAL/autogen/tables/DenoiserShadow_FilterLocal.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserShadow_FilterLocal.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserShadow_FilterLocal; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserShadow_Prepare.table.ixx b/sources/HAL/autogen/tables/DenoiserShadow_Prepare.table.ixx index 0eb37839..6d68e240 100644 --- a/sources/HAL/autogen/tables/DenoiserShadow_Prepare.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserShadow_Prepare.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserShadow_Prepare; import Core; diff --git a/sources/HAL/autogen/tables/DenoiserShadow_TileClassification.table.ixx b/sources/HAL/autogen/tables/DenoiserShadow_TileClassification.table.ixx index 4a0c33bc..58000aff 100644 --- a/sources/HAL/autogen/tables/DenoiserShadow_TileClassification.table.ixx +++ b/sources/HAL/autogen/tables/DenoiserShadow_TileClassification.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DenoiserShadow_TileClassification; import Core; diff --git a/sources/HAL/autogen/tables/DepthOnly.table.ixx b/sources/HAL/autogen/tables/DepthOnly.table.ixx index 96148068..3c61c217 100644 --- a/sources/HAL/autogen/tables/DepthOnly.table.ixx +++ b/sources/HAL/autogen/tables/DepthOnly.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DepthOnly; import Core; diff --git a/sources/HAL/autogen/tables/DispatchParameters.table.ixx b/sources/HAL/autogen/tables/DispatchParameters.table.ixx index 33fdfea5..a0217476 100644 --- a/sources/HAL/autogen/tables/DispatchParameters.table.ixx +++ b/sources/HAL/autogen/tables/DispatchParameters.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DispatchParameters; import Core; @@ -22,14 +21,14 @@ export namespace Table float SurfaceThickness = 0.005; float BilinearThreshold = 0.02; float ShadowContrast = 4; - bool IgnoreEdgePixels = false; - bool UsePrecisionOffset = false; - bool BilinearSamplingOffsetMode = false; - bool DebugOutputEdgeMask = false; - bool DebugOutputThreadIndex = false; - bool DebugOutputWaveIndex = false; + uint IgnoreEdgePixels = false; + uint UsePrecisionOffset = false; + uint BilinearSamplingOffsetMode = false; + uint DebugOutputEdgeMask = false; + uint DebugOutputThreadIndex = false; + uint DebugOutputWaveIndex = false; float2 DepthBounds = float2(0,1); - bool UseEarlyOut = false; + uint UseEarlyOut = false; float4 LightCoordinate; int2 WaveOffset; float FarDepthValue; @@ -40,14 +39,14 @@ export namespace Table float& GetSurfaceThickness() { return SurfaceThickness; } float& GetBilinearThreshold() { return BilinearThreshold; } float& GetShadowContrast() { return ShadowContrast; } - bool& GetIgnoreEdgePixels() { return IgnoreEdgePixels; } - bool& GetUsePrecisionOffset() { return UsePrecisionOffset; } - bool& GetBilinearSamplingOffsetMode() { return BilinearSamplingOffsetMode; } - bool& GetDebugOutputEdgeMask() { return DebugOutputEdgeMask; } - bool& GetDebugOutputThreadIndex() { return DebugOutputThreadIndex; } - bool& GetDebugOutputWaveIndex() { return DebugOutputWaveIndex; } + uint& GetIgnoreEdgePixels() { return IgnoreEdgePixels; } + uint& GetUsePrecisionOffset() { return UsePrecisionOffset; } + uint& GetBilinearSamplingOffsetMode() { return BilinearSamplingOffsetMode; } + uint& GetDebugOutputEdgeMask() { return DebugOutputEdgeMask; } + uint& GetDebugOutputThreadIndex() { return DebugOutputThreadIndex; } + uint& GetDebugOutputWaveIndex() { return DebugOutputWaveIndex; } float2& GetDepthBounds() { return DepthBounds; } - bool& GetUseEarlyOut() { return UseEarlyOut; } + uint& GetUseEarlyOut() { return UseEarlyOut; } float4& GetLightCoordinate() { return LightCoordinate; } int2& GetWaveOffset() { return WaveOffset; } float& GetFarDepthValue() { return FarDepthValue; } @@ -83,14 +82,14 @@ export namespace Table float SurfaceThickness; // float float BilinearThreshold; // float float ShadowContrast; // float - bool IgnoreEdgePixels; // bool - bool UsePrecisionOffset; // bool - bool BilinearSamplingOffsetMode; // bool - bool DebugOutputEdgeMask; // bool - bool DebugOutputThreadIndex; // bool - bool DebugOutputWaveIndex; // bool + uint IgnoreEdgePixels; // uint + uint UsePrecisionOffset; // uint + uint BilinearSamplingOffsetMode; // uint + uint DebugOutputEdgeMask; // uint + uint DebugOutputThreadIndex; // uint + uint DebugOutputWaveIndex; // uint float2 DepthBounds; // float2 - bool UseEarlyOut; // bool + uint UseEarlyOut; // uint float4 LightCoordinate; // float4 int2 WaveOffset; // int2 float FarDepthValue; // float diff --git a/sources/HAL/autogen/tables/DownsampleDepth.table.ixx b/sources/HAL/autogen/tables/DownsampleDepth.table.ixx index c62a24bd..188e1b16 100644 --- a/sources/HAL/autogen/tables/DownsampleDepth.table.ixx +++ b/sources/HAL/autogen/tables/DownsampleDepth.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DownsampleDepth; import Core; diff --git a/sources/HAL/autogen/tables/DrawBoxes.table.ixx b/sources/HAL/autogen/tables/DrawBoxes.table.ixx index 504ebf03..ff7f9eff 100644 --- a/sources/HAL/autogen/tables/DrawBoxes.table.ixx +++ b/sources/HAL/autogen/tables/DrawBoxes.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DrawBoxes; import Core; diff --git a/sources/HAL/autogen/tables/DrawStencil.table.ixx b/sources/HAL/autogen/tables/DrawStencil.table.ixx index e2140c62..2156c552 100644 --- a/sources/HAL/autogen/tables/DrawStencil.table.ixx +++ b/sources/HAL/autogen/tables/DrawStencil.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.DrawStencil; import Core; diff --git a/sources/HAL/autogen/tables/EnvFilter.table.ixx b/sources/HAL/autogen/tables/EnvFilter.table.ixx index 5c18e591..f46c07a4 100644 --- a/sources/HAL/autogen/tables/EnvFilter.table.ixx +++ b/sources/HAL/autogen/tables/EnvFilter.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.EnvFilter; import Core; diff --git a/sources/HAL/autogen/tables/EnvSource.table.ixx b/sources/HAL/autogen/tables/EnvSource.table.ixx index 92924b5e..a5670346 100644 --- a/sources/HAL/autogen/tables/EnvSource.table.ixx +++ b/sources/HAL/autogen/tables/EnvSource.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.EnvSource; import Core; diff --git a/sources/HAL/autogen/tables/FSR.table.ixx b/sources/HAL/autogen/tables/FSR.table.ixx index fe3a8b7a..28a497ca 100644 --- a/sources/HAL/autogen/tables/FSR.table.ixx +++ b/sources/HAL/autogen/tables/FSR.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FSR; import Core; diff --git a/sources/HAL/autogen/tables/FSRConstants.table.ixx b/sources/HAL/autogen/tables/FSRConstants.table.ixx index c0fae675..003a4b44 100644 --- a/sources/HAL/autogen/tables/FSRConstants.table.ixx +++ b/sources/HAL/autogen/tables/FSRConstants.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FSRConstants; import Core; diff --git a/sources/HAL/autogen/tables/FlowGraph.table.ixx b/sources/HAL/autogen/tables/FlowGraph.table.ixx index ce2a086b..b8c604a3 100644 --- a/sources/HAL/autogen/tables/FlowGraph.table.ixx +++ b/sources/HAL/autogen/tables/FlowGraph.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FlowGraph; import Core; diff --git a/sources/HAL/autogen/tables/FontRendering.table.ixx b/sources/HAL/autogen/tables/FontRendering.table.ixx index dad5ab64..fdd9f813 100644 --- a/sources/HAL/autogen/tables/FontRendering.table.ixx +++ b/sources/HAL/autogen/tables/FontRendering.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FontRendering; import Core; @@ -20,9 +19,9 @@ export namespace Table { static constexpr SlotID ID = SlotID::FontRendering; HLSL::Texture2D tex0; - HLSL::Buffer positions; + HLSL::StructuredBuffer positions; HLSL::Texture2D& GetTex0() { return tex0; } - HLSL::Buffer& GetPositions() { return positions; } + HLSL::StructuredBuffer& GetPositions() { return positions; } static constexpr SIG_TYPE TYPE = SIG_TYPE::Table; template void compile(Compiler& compiler) const @@ -33,7 +32,7 @@ export namespace Table struct Compiled { uint tex0; // Texture2D - uint positions; // Buffer + uint positions; // StructuredBuffer private: diff --git a/sources/HAL/autogen/tables/FontRenderingConstants.table.ixx b/sources/HAL/autogen/tables/FontRenderingConstants.table.ixx index 71aa2db4..7ba23538 100644 --- a/sources/HAL/autogen/tables/FontRenderingConstants.table.ixx +++ b/sources/HAL/autogen/tables/FontRenderingConstants.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FontRenderingConstants; import Core; diff --git a/sources/HAL/autogen/tables/FontRenderingGlyphs.table.ixx b/sources/HAL/autogen/tables/FontRenderingGlyphs.table.ixx index 1c46b43c..b0c8ae93 100644 --- a/sources/HAL/autogen/tables/FontRenderingGlyphs.table.ixx +++ b/sources/HAL/autogen/tables/FontRenderingGlyphs.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FontRenderingGlyphs; import Core; diff --git a/sources/HAL/autogen/tables/FrameClassification.table.ixx b/sources/HAL/autogen/tables/FrameClassification.table.ixx index 49580a82..bf5a5ab5 100644 --- a/sources/HAL/autogen/tables/FrameClassification.table.ixx +++ b/sources/HAL/autogen/tables/FrameClassification.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameClassification; import Core; diff --git a/sources/HAL/autogen/tables/FrameClassificationInitDispatch.table.ixx b/sources/HAL/autogen/tables/FrameClassificationInitDispatch.table.ixx index 1e094d23..98c1c897 100644 --- a/sources/HAL/autogen/tables/FrameClassificationInitDispatch.table.ixx +++ b/sources/HAL/autogen/tables/FrameClassificationInitDispatch.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameClassificationInitDispatch; import Core; diff --git a/sources/HAL/autogen/tables/FrameGraph_Debug_Common.table.ixx b/sources/HAL/autogen/tables/FrameGraph_Debug_Common.table.ixx index ed2d86b6..f9900298 100644 --- a/sources/HAL/autogen/tables/FrameGraph_Debug_Common.table.ixx +++ b/sources/HAL/autogen/tables/FrameGraph_Debug_Common.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameGraph_Debug_Common; import Core; diff --git a/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2D.table.ixx b/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2D.table.ixx index bf6169f2..46cbfe84 100644 --- a/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2D.table.ixx +++ b/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2D.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameGraph_Debug_Texture2D; import Core; diff --git a/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2DArray.table.ixx b/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2DArray.table.ixx index 42128b1a..63610261 100644 --- a/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2DArray.table.ixx +++ b/sources/HAL/autogen/tables/FrameGraph_Debug_Texture2DArray.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameGraph_Debug_Texture2DArray; import Core; diff --git a/sources/HAL/autogen/tables/FrameGraph_Debug_Texture3D.table.ixx b/sources/HAL/autogen/tables/FrameGraph_Debug_Texture3D.table.ixx index 517d5115..ad5b31a1 100644 --- a/sources/HAL/autogen/tables/FrameGraph_Debug_Texture3D.table.ixx +++ b/sources/HAL/autogen/tables/FrameGraph_Debug_Texture3D.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameGraph_Debug_Texture3D; import Core; diff --git a/sources/HAL/autogen/tables/FrameGraph_Debug_TextureCube.table.ixx b/sources/HAL/autogen/tables/FrameGraph_Debug_TextureCube.table.ixx index 4c952d24..b4255007 100644 --- a/sources/HAL/autogen/tables/FrameGraph_Debug_TextureCube.table.ixx +++ b/sources/HAL/autogen/tables/FrameGraph_Debug_TextureCube.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameGraph_Debug_TextureCube; import Core; diff --git a/sources/HAL/autogen/tables/FrameInfo.table.ixx b/sources/HAL/autogen/tables/FrameInfo.table.ixx index 470557e8..19a8e67d 100644 --- a/sources/HAL/autogen/tables/FrameInfo.table.ixx +++ b/sources/HAL/autogen/tables/FrameInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.FrameInfo; import Core; diff --git a/sources/HAL/autogen/tables/Frustum.table.ixx b/sources/HAL/autogen/tables/Frustum.table.ixx index f4ffe654..b47d22c8 100644 --- a/sources/HAL/autogen/tables/Frustum.table.ixx +++ b/sources/HAL/autogen/tables/Frustum.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Frustum; import Core; diff --git a/sources/HAL/autogen/tables/GBuffer.table.ixx b/sources/HAL/autogen/tables/GBuffer.table.ixx index 63f52159..599f5380 100644 --- a/sources/HAL/autogen/tables/GBuffer.table.ixx +++ b/sources/HAL/autogen/tables/GBuffer.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GBuffer; import Core; diff --git a/sources/HAL/autogen/tables/GBufferDownsample.table.ixx b/sources/HAL/autogen/tables/GBufferDownsample.table.ixx index 92b334e3..9f99416e 100644 --- a/sources/HAL/autogen/tables/GBufferDownsample.table.ixx +++ b/sources/HAL/autogen/tables/GBufferDownsample.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GBufferDownsample; import Core; diff --git a/sources/HAL/autogen/tables/GBufferDownsampleRT.table.ixx b/sources/HAL/autogen/tables/GBufferDownsampleRT.table.ixx index 4ba29009..3b8861d9 100644 --- a/sources/HAL/autogen/tables/GBufferDownsampleRT.table.ixx +++ b/sources/HAL/autogen/tables/GBufferDownsampleRT.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GBufferDownsampleRT; import Core; diff --git a/sources/HAL/autogen/tables/GBufferQuality.table.ixx b/sources/HAL/autogen/tables/GBufferQuality.table.ixx index 6d034898..d2814259 100644 --- a/sources/HAL/autogen/tables/GBufferQuality.table.ixx +++ b/sources/HAL/autogen/tables/GBufferQuality.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GBufferQuality; import Core; diff --git a/sources/HAL/autogen/tables/GatherBoxes.table.ixx b/sources/HAL/autogen/tables/GatherBoxes.table.ixx index 2ad74eb7..8e111c1e 100644 --- a/sources/HAL/autogen/tables/GatherBoxes.table.ixx +++ b/sources/HAL/autogen/tables/GatherBoxes.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GatherBoxes; import Core; diff --git a/sources/HAL/autogen/tables/GatherMeshesBoxes.table.ixx b/sources/HAL/autogen/tables/GatherMeshesBoxes.table.ixx index bcdf6437..9e7f898d 100644 --- a/sources/HAL/autogen/tables/GatherMeshesBoxes.table.ixx +++ b/sources/HAL/autogen/tables/GatherMeshesBoxes.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GatherMeshesBoxes; import Core; diff --git a/sources/HAL/autogen/tables/GatherPipeline.table.ixx b/sources/HAL/autogen/tables/GatherPipeline.table.ixx index 05704a0e..69e2b269 100644 --- a/sources/HAL/autogen/tables/GatherPipeline.table.ixx +++ b/sources/HAL/autogen/tables/GatherPipeline.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GatherPipeline; import Core; diff --git a/sources/HAL/autogen/tables/GatherPipelineGlobal.table.ixx b/sources/HAL/autogen/tables/GatherPipelineGlobal.table.ixx index f7552905..92327534 100644 --- a/sources/HAL/autogen/tables/GatherPipelineGlobal.table.ixx +++ b/sources/HAL/autogen/tables/GatherPipelineGlobal.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GatherPipelineGlobal; import Core; diff --git a/sources/HAL/autogen/tables/Glyph.table.ixx b/sources/HAL/autogen/tables/Glyph.table.ixx index 2d23b3bb..be401ad0 100644 --- a/sources/HAL/autogen/tables/Glyph.table.ixx +++ b/sources/HAL/autogen/tables/Glyph.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Glyph; import Core; diff --git a/sources/HAL/autogen/tables/GraphInput.table.ixx b/sources/HAL/autogen/tables/GraphInput.table.ixx index aad65f6b..5fecb526 100644 --- a/sources/HAL/autogen/tables/GraphInput.table.ixx +++ b/sources/HAL/autogen/tables/GraphInput.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.GraphInput; import Core; diff --git a/sources/HAL/autogen/tables/InitDispatch.table.ixx b/sources/HAL/autogen/tables/InitDispatch.table.ixx index f46fc3a7..b49775f9 100644 --- a/sources/HAL/autogen/tables/InitDispatch.table.ixx +++ b/sources/HAL/autogen/tables/InitDispatch.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.InitDispatch; import Core; diff --git a/sources/HAL/autogen/tables/Instance.table.ixx b/sources/HAL/autogen/tables/Instance.table.ixx index 8a1239c5..bf1a1518 100644 --- a/sources/HAL/autogen/tables/Instance.table.ixx +++ b/sources/HAL/autogen/tables/Instance.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Instance; import Core; diff --git a/sources/HAL/autogen/tables/LineRender.table.ixx b/sources/HAL/autogen/tables/LineRender.table.ixx index 803ccb45..26f490ce 100644 --- a/sources/HAL/autogen/tables/LineRender.table.ixx +++ b/sources/HAL/autogen/tables/LineRender.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.LineRender; import Core; diff --git a/sources/HAL/autogen/tables/MaterialCommandData.table.ixx b/sources/HAL/autogen/tables/MaterialCommandData.table.ixx index 3d30a7d6..08169681 100644 --- a/sources/HAL/autogen/tables/MaterialCommandData.table.ixx +++ b/sources/HAL/autogen/tables/MaterialCommandData.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MaterialCommandData; import Core; diff --git a/sources/HAL/autogen/tables/MaterialInfo.table.ixx b/sources/HAL/autogen/tables/MaterialInfo.table.ixx index 484a46b4..eb620516 100644 --- a/sources/HAL/autogen/tables/MaterialInfo.table.ixx +++ b/sources/HAL/autogen/tables/MaterialInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MaterialInfo; import Core; diff --git a/sources/HAL/autogen/tables/MeshCommandData.table.ixx b/sources/HAL/autogen/tables/MeshCommandData.table.ixx index daf62240..31ec0da3 100644 --- a/sources/HAL/autogen/tables/MeshCommandData.table.ixx +++ b/sources/HAL/autogen/tables/MeshCommandData.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MeshCommandData; import Core; diff --git a/sources/HAL/autogen/tables/MeshInfo.table.ixx b/sources/HAL/autogen/tables/MeshInfo.table.ixx index 6cf20768..d6c689d4 100644 --- a/sources/HAL/autogen/tables/MeshInfo.table.ixx +++ b/sources/HAL/autogen/tables/MeshInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MeshInfo; import Core; diff --git a/sources/HAL/autogen/tables/MeshInstance.table.ixx b/sources/HAL/autogen/tables/MeshInstance.table.ixx index 262f56b8..7ee16736 100644 --- a/sources/HAL/autogen/tables/MeshInstance.table.ixx +++ b/sources/HAL/autogen/tables/MeshInstance.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MeshInstance; import Core; diff --git a/sources/HAL/autogen/tables/MeshInstanceInfo.table.ixx b/sources/HAL/autogen/tables/MeshInstanceInfo.table.ixx index 80197fb4..f63d8e35 100644 --- a/sources/HAL/autogen/tables/MeshInstanceInfo.table.ixx +++ b/sources/HAL/autogen/tables/MeshInstanceInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MeshInstanceInfo; import Core; diff --git a/sources/HAL/autogen/tables/Meshlet.table.ixx b/sources/HAL/autogen/tables/Meshlet.table.ixx index ddc6612d..24ad7445 100644 --- a/sources/HAL/autogen/tables/Meshlet.table.ixx +++ b/sources/HAL/autogen/tables/Meshlet.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Meshlet; import Core; diff --git a/sources/HAL/autogen/tables/MeshletCullData.table.ixx b/sources/HAL/autogen/tables/MeshletCullData.table.ixx index 9130f2d5..6c3e062c 100644 --- a/sources/HAL/autogen/tables/MeshletCullData.table.ixx +++ b/sources/HAL/autogen/tables/MeshletCullData.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MeshletCullData; import Core; diff --git a/sources/HAL/autogen/tables/MipMapping.table.ixx b/sources/HAL/autogen/tables/MipMapping.table.ixx index c2ef5b30..1ccda9a4 100644 --- a/sources/HAL/autogen/tables/MipMapping.table.ixx +++ b/sources/HAL/autogen/tables/MipMapping.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.MipMapping; import Core; diff --git a/sources/HAL/autogen/tables/NinePatch.table.ixx b/sources/HAL/autogen/tables/NinePatch.table.ixx index 34969a61..71dd2617 100644 --- a/sources/HAL/autogen/tables/NinePatch.table.ixx +++ b/sources/HAL/autogen/tables/NinePatch.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.NinePatch; import Core; diff --git a/sources/HAL/autogen/tables/NoOutput.table.ixx b/sources/HAL/autogen/tables/NoOutput.table.ixx index ad24159b..e80b368f 100644 --- a/sources/HAL/autogen/tables/NoOutput.table.ixx +++ b/sources/HAL/autogen/tables/NoOutput.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.NoOutput; import Core; diff --git a/sources/HAL/autogen/tables/PSSMConstants.table.ixx b/sources/HAL/autogen/tables/PSSMConstants.table.ixx index 7532000c..244a713b 100644 --- a/sources/HAL/autogen/tables/PSSMConstants.table.ixx +++ b/sources/HAL/autogen/tables/PSSMConstants.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.PSSMConstants; import Core; diff --git a/sources/HAL/autogen/tables/PSSMData.table.ixx b/sources/HAL/autogen/tables/PSSMData.table.ixx index d86287e5..8f14efb2 100644 --- a/sources/HAL/autogen/tables/PSSMData.table.ixx +++ b/sources/HAL/autogen/tables/PSSMData.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.PSSMData; import Core; diff --git a/sources/HAL/autogen/tables/PSSMDataGlobal.table.ixx b/sources/HAL/autogen/tables/PSSMDataGlobal.table.ixx index 9dd10243..412f0ecf 100644 --- a/sources/HAL/autogen/tables/PSSMDataGlobal.table.ixx +++ b/sources/HAL/autogen/tables/PSSMDataGlobal.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.PSSMDataGlobal; import Core; diff --git a/sources/HAL/autogen/tables/PSSMLighting.table.ixx b/sources/HAL/autogen/tables/PSSMLighting.table.ixx index f226252d..7b651587 100644 --- a/sources/HAL/autogen/tables/PSSMLighting.table.ixx +++ b/sources/HAL/autogen/tables/PSSMLighting.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.PSSMLighting; import Core; diff --git a/sources/HAL/autogen/tables/PickerBuffer.table.ixx b/sources/HAL/autogen/tables/PickerBuffer.table.ixx index fdddc046..c0ebeba4 100644 --- a/sources/HAL/autogen/tables/PickerBuffer.table.ixx +++ b/sources/HAL/autogen/tables/PickerBuffer.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.PickerBuffer; import Core; diff --git a/sources/HAL/autogen/tables/RayCone.table.ixx b/sources/HAL/autogen/tables/RayCone.table.ixx index fb66c520..a8e88ac3 100644 --- a/sources/HAL/autogen/tables/RayCone.table.ixx +++ b/sources/HAL/autogen/tables/RayCone.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.RayCone; import Core; diff --git a/sources/HAL/autogen/tables/RayPayload.table.ixx b/sources/HAL/autogen/tables/RayPayload.table.ixx index aa9cc58f..d158f27a 100644 --- a/sources/HAL/autogen/tables/RayPayload.table.ixx +++ b/sources/HAL/autogen/tables/RayPayload.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.RayPayload; import Core; diff --git a/sources/HAL/autogen/tables/RaytraceInstanceInfo.table.ixx b/sources/HAL/autogen/tables/RaytraceInstanceInfo.table.ixx index 4d37ae22..13bf954f 100644 --- a/sources/HAL/autogen/tables/RaytraceInstanceInfo.table.ixx +++ b/sources/HAL/autogen/tables/RaytraceInstanceInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.RaytraceInstanceInfo; import Core; diff --git a/sources/HAL/autogen/tables/Raytracing.table.ixx b/sources/HAL/autogen/tables/Raytracing.table.ixx index e7beada6..fa1a55ad 100644 --- a/sources/HAL/autogen/tables/Raytracing.table.ixx +++ b/sources/HAL/autogen/tables/Raytracing.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Raytracing; import Core; diff --git a/sources/HAL/autogen/tables/RaytracingRays.table.ixx b/sources/HAL/autogen/tables/RaytracingRays.table.ixx index f03a8fa7..59d7b4bd 100644 --- a/sources/HAL/autogen/tables/RaytracingRays.table.ixx +++ b/sources/HAL/autogen/tables/RaytracingRays.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.RaytracingRays; import Core; diff --git a/sources/HAL/autogen/tables/ReflectionCombine.table.ixx b/sources/HAL/autogen/tables/ReflectionCombine.table.ixx index fcfb6fd6..28845bdc 100644 --- a/sources/HAL/autogen/tables/ReflectionCombine.table.ixx +++ b/sources/HAL/autogen/tables/ReflectionCombine.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.ReflectionCombine; import Core; diff --git a/sources/HAL/autogen/tables/SMAA_Blend.table.ixx b/sources/HAL/autogen/tables/SMAA_Blend.table.ixx index a072699f..26b93791 100644 --- a/sources/HAL/autogen/tables/SMAA_Blend.table.ixx +++ b/sources/HAL/autogen/tables/SMAA_Blend.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SMAA_Blend; import Core; diff --git a/sources/HAL/autogen/tables/SMAA_Global.table.ixx b/sources/HAL/autogen/tables/SMAA_Global.table.ixx index b108a039..6a312da7 100644 --- a/sources/HAL/autogen/tables/SMAA_Global.table.ixx +++ b/sources/HAL/autogen/tables/SMAA_Global.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SMAA_Global; import Core; diff --git a/sources/HAL/autogen/tables/SMAA_Weights.table.ixx b/sources/HAL/autogen/tables/SMAA_Weights.table.ixx index 3bb3370a..642d8144 100644 --- a/sources/HAL/autogen/tables/SMAA_Weights.table.ixx +++ b/sources/HAL/autogen/tables/SMAA_Weights.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SMAA_Weights; import Core; diff --git a/sources/HAL/autogen/tables/SceneData.table.ixx b/sources/HAL/autogen/tables/SceneData.table.ixx index 8a6fe19d..84242499 100644 --- a/sources/HAL/autogen/tables/SceneData.table.ixx +++ b/sources/HAL/autogen/tables/SceneData.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SceneData; import Core; diff --git a/sources/HAL/autogen/tables/ShadowPayload.table.ixx b/sources/HAL/autogen/tables/ShadowPayload.table.ixx index c27cef7a..86eac04a 100644 --- a/sources/HAL/autogen/tables/ShadowPayload.table.ixx +++ b/sources/HAL/autogen/tables/ShadowPayload.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.ShadowPayload; import Core; diff --git a/sources/HAL/autogen/tables/SingleColor.table.ixx b/sources/HAL/autogen/tables/SingleColor.table.ixx index b4f4a12e..7c95eb3f 100644 --- a/sources/HAL/autogen/tables/SingleColor.table.ixx +++ b/sources/HAL/autogen/tables/SingleColor.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SingleColor; import Core; diff --git a/sources/HAL/autogen/tables/SingleColorDepth.table.ixx b/sources/HAL/autogen/tables/SingleColorDepth.table.ixx index 908546f9..1d7c9cfc 100644 --- a/sources/HAL/autogen/tables/SingleColorDepth.table.ixx +++ b/sources/HAL/autogen/tables/SingleColorDepth.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SingleColorDepth; import Core; diff --git a/sources/HAL/autogen/tables/SkyData.table.ixx b/sources/HAL/autogen/tables/SkyData.table.ixx index 6cd2d2c8..4721d30b 100644 --- a/sources/HAL/autogen/tables/SkyData.table.ixx +++ b/sources/HAL/autogen/tables/SkyData.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SkyData; import Core; diff --git a/sources/HAL/autogen/tables/SkyFace.table.ixx b/sources/HAL/autogen/tables/SkyFace.table.ixx index 20ec9ae2..ab2b6766 100644 --- a/sources/HAL/autogen/tables/SkyFace.table.ixx +++ b/sources/HAL/autogen/tables/SkyFace.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.SkyFace; import Core; diff --git a/sources/HAL/autogen/tables/Test.table.ixx b/sources/HAL/autogen/tables/Test.table.ixx index d1ef7a9b..d83ed994 100644 --- a/sources/HAL/autogen/tables/Test.table.ixx +++ b/sources/HAL/autogen/tables/Test.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Test; import Core; diff --git a/sources/HAL/autogen/tables/TextureRenderer.table.ixx b/sources/HAL/autogen/tables/TextureRenderer.table.ixx index 6ba47eda..d1472f27 100644 --- a/sources/HAL/autogen/tables/TextureRenderer.table.ixx +++ b/sources/HAL/autogen/tables/TextureRenderer.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.TextureRenderer; import Core; diff --git a/sources/HAL/autogen/tables/TilingParams.table.ixx b/sources/HAL/autogen/tables/TilingParams.table.ixx index bf30fa07..1d2473d9 100644 --- a/sources/HAL/autogen/tables/TilingParams.table.ixx +++ b/sources/HAL/autogen/tables/TilingParams.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.TilingParams; import Core; diff --git a/sources/HAL/autogen/tables/TilingPostprocess.table.ixx b/sources/HAL/autogen/tables/TilingPostprocess.table.ixx index 8c61bec7..dbc6779d 100644 --- a/sources/HAL/autogen/tables/TilingPostprocess.table.ixx +++ b/sources/HAL/autogen/tables/TilingPostprocess.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.TilingPostprocess; import Core; diff --git a/sources/HAL/autogen/tables/Triangle.table.ixx b/sources/HAL/autogen/tables/Triangle.table.ixx index a82535ba..0418fce9 100644 --- a/sources/HAL/autogen/tables/Triangle.table.ixx +++ b/sources/HAL/autogen/tables/Triangle.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Triangle; import Core; diff --git a/sources/HAL/autogen/tables/VSLine.table.ixx b/sources/HAL/autogen/tables/VSLine.table.ixx index 95117cb7..5c9c0db4 100644 --- a/sources/HAL/autogen/tables/VSLine.table.ixx +++ b/sources/HAL/autogen/tables/VSLine.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VSLine; import Core; diff --git a/sources/HAL/autogen/tables/VoxelBlur.table.ixx b/sources/HAL/autogen/tables/VoxelBlur.table.ixx index ea48aa82..5b1082a9 100644 --- a/sources/HAL/autogen/tables/VoxelBlur.table.ixx +++ b/sources/HAL/autogen/tables/VoxelBlur.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelBlur; import Core; diff --git a/sources/HAL/autogen/tables/VoxelCopy.table.ixx b/sources/HAL/autogen/tables/VoxelCopy.table.ixx index 06084d01..9fa23eca 100644 --- a/sources/HAL/autogen/tables/VoxelCopy.table.ixx +++ b/sources/HAL/autogen/tables/VoxelCopy.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelCopy; import Core; diff --git a/sources/HAL/autogen/tables/VoxelDebug.table.ixx b/sources/HAL/autogen/tables/VoxelDebug.table.ixx index 8dce77c6..84934aaf 100644 --- a/sources/HAL/autogen/tables/VoxelDebug.table.ixx +++ b/sources/HAL/autogen/tables/VoxelDebug.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelDebug; import Core; diff --git a/sources/HAL/autogen/tables/VoxelInfo.table.ixx b/sources/HAL/autogen/tables/VoxelInfo.table.ixx index 255d55b1..27080d64 100644 --- a/sources/HAL/autogen/tables/VoxelInfo.table.ixx +++ b/sources/HAL/autogen/tables/VoxelInfo.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelInfo; import Core; diff --git a/sources/HAL/autogen/tables/VoxelLighting.table.ixx b/sources/HAL/autogen/tables/VoxelLighting.table.ixx index 143f212a..0aeaa4a1 100644 --- a/sources/HAL/autogen/tables/VoxelLighting.table.ixx +++ b/sources/HAL/autogen/tables/VoxelLighting.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelLighting; import Core; diff --git a/sources/HAL/autogen/tables/VoxelMipMap.table.ixx b/sources/HAL/autogen/tables/VoxelMipMap.table.ixx index 5f201d4b..3d9bff98 100644 --- a/sources/HAL/autogen/tables/VoxelMipMap.table.ixx +++ b/sources/HAL/autogen/tables/VoxelMipMap.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelMipMap; import Core; diff --git a/sources/HAL/autogen/tables/VoxelOutput.table.ixx b/sources/HAL/autogen/tables/VoxelOutput.table.ixx index 15976552..fe610cba 100644 --- a/sources/HAL/autogen/tables/VoxelOutput.table.ixx +++ b/sources/HAL/autogen/tables/VoxelOutput.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelOutput; import Core; diff --git a/sources/HAL/autogen/tables/VoxelScreen.table.ixx b/sources/HAL/autogen/tables/VoxelScreen.table.ixx index 2f1ffddf..7dce9020 100644 --- a/sources/HAL/autogen/tables/VoxelScreen.table.ixx +++ b/sources/HAL/autogen/tables/VoxelScreen.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelScreen; import Core; diff --git a/sources/HAL/autogen/tables/VoxelTilingParams.table.ixx b/sources/HAL/autogen/tables/VoxelTilingParams.table.ixx index 0daa7968..29c4d6cf 100644 --- a/sources/HAL/autogen/tables/VoxelTilingParams.table.ixx +++ b/sources/HAL/autogen/tables/VoxelTilingParams.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelTilingParams; import Core; diff --git a/sources/HAL/autogen/tables/VoxelUpscale.table.ixx b/sources/HAL/autogen/tables/VoxelUpscale.table.ixx index 2d57633a..98e8dd01 100644 --- a/sources/HAL/autogen/tables/VoxelUpscale.table.ixx +++ b/sources/HAL/autogen/tables/VoxelUpscale.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelUpscale; import Core; diff --git a/sources/HAL/autogen/tables/VoxelVisibility.table.ixx b/sources/HAL/autogen/tables/VoxelVisibility.table.ixx index de5cdb42..22892b75 100644 --- a/sources/HAL/autogen/tables/VoxelVisibility.table.ixx +++ b/sources/HAL/autogen/tables/VoxelVisibility.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelVisibility; import Core; diff --git a/sources/HAL/autogen/tables/VoxelZero.table.ixx b/sources/HAL/autogen/tables/VoxelZero.table.ixx index a1ab086e..1d0454ee 100644 --- a/sources/HAL/autogen/tables/VoxelZero.table.ixx +++ b/sources/HAL/autogen/tables/VoxelZero.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.VoxelZero; import Core; diff --git a/sources/HAL/autogen/tables/Voxelization.table.ixx b/sources/HAL/autogen/tables/Voxelization.table.ixx index 52b30df9..f0610cb2 100644 --- a/sources/HAL/autogen/tables/Voxelization.table.ixx +++ b/sources/HAL/autogen/tables/Voxelization.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.Voxelization; import Core; diff --git a/sources/HAL/autogen/tables/WorkGraphTest.table.ixx b/sources/HAL/autogen/tables/WorkGraphTest.table.ixx index 9a635d0d..45d204e9 100644 --- a/sources/HAL/autogen/tables/WorkGraphTest.table.ixx +++ b/sources/HAL/autogen/tables/WorkGraphTest.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.WorkGraphTest; import Core; diff --git a/sources/HAL/autogen/tables/mesh_vertex_input.table.ixx b/sources/HAL/autogen/tables/mesh_vertex_input.table.ixx index b151da05..46ac719d 100644 --- a/sources/HAL/autogen/tables/mesh_vertex_input.table.ixx +++ b/sources/HAL/autogen/tables/mesh_vertex_input.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.mesh_vertex_input; import Core; diff --git a/sources/HAL/autogen/tables/node_data.table.ixx b/sources/HAL/autogen/tables/node_data.table.ixx index e9784f8e..1ba5c526 100644 --- a/sources/HAL/autogen/tables/node_data.table.ixx +++ b/sources/HAL/autogen/tables/node_data.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.node_data; import Core; diff --git a/sources/HAL/autogen/tables/vertex_input.table.ixx b/sources/HAL/autogen/tables/vertex_input.table.ixx index 95d091bf..7c480da4 100644 --- a/sources/HAL/autogen/tables/vertex_input.table.ixx +++ b/sources/HAL/autogen/tables/vertex_input.table.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module HAL:Autogen.Tables.vertex_input; import Core; diff --git a/sources/Modules/d3d12/d3d12.ixx b/sources/Modules/d3d12/d3d12.ixx index fbbf302b..c59a4035 100644 --- a/sources/Modules/d3d12/d3d12.ixx +++ b/sources/Modules/d3d12/d3d12.ixx @@ -268,9 +268,9 @@ export namespace DirectXTex // ------------------------------------------------------------------------- inline HRESULT GetMetadataFromTGAFile(const wchar_t* szFile, DirectX::TexMetadata& metadata) noexcept { return DirectX::GetMetadataFromTGAFile(szFile, metadata); } inline HRESULT GetMetadataFromWICFile(const wchar_t* szFile, DirectX::WIC_FLAGS flags, DirectX::TexMetadata& metadata) noexcept { return DirectX::GetMetadataFromWICFile(szFile, flags, metadata); } - inline HRESULT LoadFromTGAMemory(const void* pSource, size_t size, DirectX::TexMetadata* metadata, DirectX::ScratchImage& image) noexcept { return DirectX::LoadFromTGAMemory(pSource, size, metadata, image); } - inline HRESULT LoadFromDDSMemory(const void* pSource, size_t size, DirectX::DDS_FLAGS flags, DirectX::TexMetadata* metadata, DirectX::ScratchImage& image) noexcept { return DirectX::LoadFromDDSMemory(pSource, size, flags, metadata, image); } - inline HRESULT LoadFromWICMemory(const void* pSource, size_t size, DirectX::WIC_FLAGS flags, DirectX::TexMetadata* metadata, DirectX::ScratchImage& image) noexcept { return DirectX::LoadFromWICMemory(pSource, size, flags, metadata, image); } + inline HRESULT LoadFromTGAMemory(const void* pSource, size_t size, DirectX::TexMetadata* metadata, DirectX::ScratchImage& image) noexcept { return DirectX::LoadFromTGAMemory(static_cast(pSource), size, metadata, image); } + inline HRESULT LoadFromDDSMemory(const void* pSource, size_t size, DirectX::DDS_FLAGS flags, DirectX::TexMetadata* metadata, DirectX::ScratchImage& image) noexcept { return DirectX::LoadFromDDSMemory(static_cast(pSource), size, flags, metadata, image); } + inline HRESULT LoadFromWICMemory(const void* pSource, size_t size, DirectX::WIC_FLAGS flags, DirectX::TexMetadata* metadata, DirectX::ScratchImage& image) noexcept { return DirectX::LoadFromWICMemory(static_cast(pSource), size, flags, metadata, image); } inline HRESULT GenerateMipMaps(const DirectX::Image* srcImages, size_t nimages, const DirectX::TexMetadata& metadata, DirectX::TEX_FILTER_FLAGS filter, size_t levels, DirectX::ScratchImage& mipChain) noexcept { return DirectX::GenerateMipMaps(srcImages, nimages, metadata, filter, levels, mipChain); } inline HRESULT SaveToWICMemory(const DirectX::Image& image, DirectX::WIC_FLAGS flags, REFGUID guidContainerFormat, DirectX::Blob& blob) noexcept { return DirectX::SaveToWICMemory(image, flags, guidContainerFormat, blob); } } diff --git a/sources/Modules/dxc/dxc.h b/sources/Modules/dxc/dxc.h index 636e053f..acfc5267 100644 --- a/sources/Modules/dxc/dxc.h +++ b/sources/Modules/dxc/dxc.h @@ -1,4 +1,3 @@ -import d3d12; import windows; import stl.core; import ; diff --git a/sources/Modules/stl/core.h b/sources/Modules/stl/core.h index deb2b99d..ca23bd12 100644 --- a/sources/Modules/stl/core.h +++ b/sources/Modules/stl/core.h @@ -64,3 +64,4 @@ // memory (formerly stl/memory.h) #include + #include \ No newline at end of file diff --git a/sources/Modules/vulkan/vulkan-1.def b/sources/Modules/vulkan/vulkan-1.def new file mode 100644 index 00000000..e56bb0e5 --- /dev/null +++ b/sources/Modules/vulkan/vulkan-1.def @@ -0,0 +1,267 @@ +LIBRARY vulkan-1 +EXPORTS + vkAcquireNextImage2KHR + vkAcquireNextImageKHR + vkAllocateCommandBuffers + vkAllocateDescriptorSets + vkAllocateMemory + vkBeginCommandBuffer + vkBindBufferMemory + vkBindBufferMemory2 + vkBindImageMemory + vkBindImageMemory2 + vkCmdBeginQuery + vkCmdBeginRenderPass + vkCmdBeginRenderPass2 + vkCmdBeginRendering + vkCmdBindDescriptorSets + vkCmdBindDescriptorSets2 + vkCmdBindIndexBuffer + vkCmdBindIndexBuffer2 + vkCmdBindPipeline + vkCmdBindVertexBuffers + vkCmdBindVertexBuffers2 + vkCmdBlitImage + vkCmdBlitImage2 + vkCmdClearAttachments + vkCmdClearColorImage + vkCmdClearDepthStencilImage + vkCmdCopyBuffer + vkCmdCopyBuffer2 + vkCmdCopyBufferToImage + vkCmdCopyBufferToImage2 + vkCmdCopyImage + vkCmdCopyImage2 + vkCmdCopyImageToBuffer + vkCmdCopyImageToBuffer2 + vkCmdCopyQueryPoolResults + vkCmdDispatch + vkCmdDispatchBase + vkCmdDispatchIndirect + vkCmdDraw + vkCmdDrawIndexed + vkCmdDrawIndexedIndirect + vkCmdDrawIndexedIndirectCount + vkCmdDrawIndirect + vkCmdDrawIndirectCount + vkCmdEndQuery + vkCmdEndRenderPass + vkCmdEndRenderPass2 + vkCmdEndRendering + vkCmdExecuteCommands + vkCmdFillBuffer + vkCmdNextSubpass + vkCmdNextSubpass2 + vkCmdPipelineBarrier + vkCmdPipelineBarrier2 + vkCmdPushConstants + vkCmdPushConstants2 + vkCmdPushDescriptorSet + vkCmdPushDescriptorSet2 + vkCmdPushDescriptorSetWithTemplate + vkCmdPushDescriptorSetWithTemplate2 + vkCmdResetEvent + vkCmdResetEvent2 + vkCmdResetQueryPool + vkCmdResolveImage + vkCmdResolveImage2 + vkCmdSetBlendConstants + vkCmdSetCullMode + vkCmdSetDepthBias + vkCmdSetDepthBiasEnable + vkCmdSetDepthBounds + vkCmdSetDepthBoundsTestEnable + vkCmdSetDepthCompareOp + vkCmdSetDepthTestEnable + vkCmdSetDepthWriteEnable + vkCmdSetDeviceMask + vkCmdSetEvent + vkCmdSetEvent2 + vkCmdSetFrontFace + vkCmdSetLineStipple + vkCmdSetLineWidth + vkCmdSetPrimitiveRestartEnable + vkCmdSetPrimitiveTopology + vkCmdSetRasterizerDiscardEnable + vkCmdSetRenderingAttachmentLocations + vkCmdSetRenderingInputAttachmentIndices + vkCmdSetScissor + vkCmdSetScissorWithCount + vkCmdSetStencilCompareMask + vkCmdSetStencilOp + vkCmdSetStencilReference + vkCmdSetStencilTestEnable + vkCmdSetStencilWriteMask + vkCmdSetViewport + vkCmdSetViewportWithCount + vkCmdUpdateBuffer + vkCmdWaitEvents + vkCmdWaitEvents2 + vkCmdWriteTimestamp + vkCmdWriteTimestamp2 + vkCopyImageToImage + vkCopyImageToMemory + vkCopyMemoryToImage + vkCreateBuffer + vkCreateBufferView + vkCreateCommandPool + vkCreateComputePipelines + vkCreateDescriptorPool + vkCreateDescriptorSetLayout + vkCreateDescriptorUpdateTemplate + vkCreateDevice + vkCreateDisplayModeKHR + vkCreateDisplayPlaneSurfaceKHR + vkCreateEvent + vkCreateFence + vkCreateFramebuffer + vkCreateGraphicsPipelines + vkCreateHeadlessSurfaceEXT + vkCreateImage + vkCreateImageView + vkCreateInstance + vkCreatePipelineCache + vkCreatePipelineLayout + vkCreatePrivateDataSlot + vkCreateQueryPool + vkCreateRenderPass + vkCreateRenderPass2 + vkCreateSampler + vkCreateSamplerYcbcrConversion + vkCreateSemaphore + vkCreateShaderModule + vkCreateSharedSwapchainsKHR + vkCreateSwapchainKHR + vkCreateWin32SurfaceKHR + vkDestroyBuffer + vkDestroyBufferView + vkDestroyCommandPool + vkDestroyDescriptorPool + vkDestroyDescriptorSetLayout + vkDestroyDescriptorUpdateTemplate + vkDestroyDevice + vkDestroyEvent + vkDestroyFence + vkDestroyFramebuffer + vkDestroyImage + vkDestroyImageView + vkDestroyInstance + vkDestroyPipeline + vkDestroyPipelineCache + vkDestroyPipelineLayout + vkDestroyPrivateDataSlot + vkDestroyQueryPool + vkDestroyRenderPass + vkDestroySampler + vkDestroySamplerYcbcrConversion + vkDestroySemaphore + vkDestroyShaderModule + vkDestroySurfaceKHR + vkDestroySwapchainKHR + vkDeviceWaitIdle + vkEndCommandBuffer + vkEnumerateDeviceExtensionProperties + vkEnumerateDeviceLayerProperties + vkEnumerateInstanceExtensionProperties + vkEnumerateInstanceLayerProperties + vkEnumerateInstanceVersion + vkEnumeratePhysicalDeviceGroups + vkEnumeratePhysicalDevices + vkFlushMappedMemoryRanges + vkFreeCommandBuffers + vkFreeDescriptorSets + vkFreeMemory + vkGetBufferDeviceAddress + vkGetBufferMemoryRequirements + vkGetBufferMemoryRequirements2 + vkGetBufferOpaqueCaptureAddress + vkGetDescriptorSetLayoutSupport + vkGetDeviceBufferMemoryRequirements + vkGetDeviceGroupPeerMemoryFeatures + vkGetDeviceGroupPresentCapabilitiesKHR + vkGetDeviceGroupSurfacePresentModesKHR + vkGetDeviceImageMemoryRequirements + vkGetDeviceImageSparseMemoryRequirements + vkGetDeviceImageSubresourceLayout + vkGetDeviceMemoryCommitment + vkGetDeviceMemoryOpaqueCaptureAddress + vkGetDeviceProcAddr + vkGetDeviceQueue + vkGetDeviceQueue2 + vkGetDisplayModeProperties2KHR + vkGetDisplayModePropertiesKHR + vkGetDisplayPlaneCapabilities2KHR + vkGetDisplayPlaneCapabilitiesKHR + vkGetDisplayPlaneSupportedDisplaysKHR + vkGetEventStatus + vkGetFenceStatus + vkGetImageMemoryRequirements + vkGetImageMemoryRequirements2 + vkGetImageSparseMemoryRequirements + vkGetImageSparseMemoryRequirements2 + vkGetImageSubresourceLayout + vkGetImageSubresourceLayout2 + vkGetInstanceProcAddr + vkGetPhysicalDeviceDisplayPlaneProperties2KHR + vkGetPhysicalDeviceDisplayPlanePropertiesKHR + vkGetPhysicalDeviceDisplayProperties2KHR + vkGetPhysicalDeviceDisplayPropertiesKHR + vkGetPhysicalDeviceExternalBufferProperties + vkGetPhysicalDeviceExternalFenceProperties + vkGetPhysicalDeviceExternalSemaphoreProperties + vkGetPhysicalDeviceFeatures + vkGetPhysicalDeviceFeatures2 + vkGetPhysicalDeviceFormatProperties + vkGetPhysicalDeviceFormatProperties2 + vkGetPhysicalDeviceImageFormatProperties + vkGetPhysicalDeviceImageFormatProperties2 + vkGetPhysicalDeviceMemoryProperties + vkGetPhysicalDeviceMemoryProperties2 + vkGetPhysicalDevicePresentRectanglesKHR + vkGetPhysicalDeviceProperties + vkGetPhysicalDeviceProperties2 + vkGetPhysicalDeviceQueueFamilyProperties + vkGetPhysicalDeviceQueueFamilyProperties2 + vkGetPhysicalDeviceSparseImageFormatProperties + vkGetPhysicalDeviceSparseImageFormatProperties2 + vkGetPhysicalDeviceSurfaceCapabilities2KHR + vkGetPhysicalDeviceSurfaceCapabilitiesKHR + vkGetPhysicalDeviceSurfaceFormats2KHR + vkGetPhysicalDeviceSurfaceFormatsKHR + vkGetPhysicalDeviceSurfacePresentModesKHR + vkGetPhysicalDeviceSurfaceSupportKHR + vkGetPhysicalDeviceToolProperties + vkGetPhysicalDeviceWin32PresentationSupportKHR + vkGetPipelineCacheData + vkGetPrivateData + vkGetQueryPoolResults + vkGetRenderAreaGranularity + vkGetRenderingAreaGranularity + vkGetSemaphoreCounterValue + vkGetSwapchainImagesKHR + vkInvalidateMappedMemoryRanges + vkMapMemory + vkMapMemory2 + vkMergePipelineCaches + vkQueueBindSparse + vkQueuePresentKHR + vkQueueSubmit + vkQueueSubmit2 + vkQueueWaitIdle + vkResetCommandBuffer + vkResetCommandPool + vkResetDescriptorPool + vkResetEvent + vkResetFences + vkResetQueryPool + vkSetEvent + vkSetPrivateData + vkSignalSemaphore + vkTransitionImageLayout + vkTrimCommandPool + vkUnmapMemory + vkUnmapMemory2 + vkUpdateDescriptorSetWithTemplate + vkUpdateDescriptorSets + vkWaitForFences + vkWaitSemaphores diff --git a/sources/Modules/vulkan/vulkan-1.exp b/sources/Modules/vulkan/vulkan-1.exp new file mode 100644 index 00000000..b6ba37fa Binary files /dev/null and b/sources/Modules/vulkan/vulkan-1.exp differ diff --git a/sources/Modules/vulkan/vulkan-1.lib b/sources/Modules/vulkan/vulkan-1.lib new file mode 100644 index 00000000..92429d0a Binary files /dev/null and b/sources/Modules/vulkan/vulkan-1.lib differ diff --git a/sources/Modules/vulkan/vulkan.cpp b/sources/Modules/vulkan/vulkan.cpp new file mode 100644 index 00000000..dc9da8d9 --- /dev/null +++ b/sources/Modules/vulkan/vulkan.cpp @@ -0,0 +1,12 @@ +module; +// Global module fragment — provide the VMA implementation translation unit. +// VMA is a single-header library; exactly one TU must define VMA_IMPLEMENTATION +// before including the header. The header unit in vulkan.ixx provides the +// declarations; this TU provides the definitions. +#pragma warning(push, 0) +#define VMA_IMPLEMENTATION +#define VK_USE_PLATFORM_WIN32_KHR +#include +#include +#pragma warning(pop) +module vulkan; diff --git a/sources/Modules/vulkan/vulkan.ixx b/sources/Modules/vulkan/vulkan.ixx new file mode 100644 index 00000000..0a257428 --- /dev/null +++ b/sources/Modules/vulkan/vulkan.ixx @@ -0,0 +1,2 @@ +export module vulkan; +export import "vulkan_includes.h"; diff --git a/sources/Modules/vulkan/vulkan_includes.h b/sources/Modules/vulkan/vulkan_includes.h new file mode 100644 index 00000000..2d261bf5 --- /dev/null +++ b/sources/Modules/vulkan/vulkan_includes.h @@ -0,0 +1,37 @@ +#pragma once +// vulkan_includes.h — Vulkan API declarations for use as a C++20 header unit. +// Included by vulkan.ixx via export import "vulkan_includes.h". +// Provides VkXxx types, vulkan_win32 surface extension, and VMA declarations. +// VMA_IMPLEMENTATION is defined in vulkan.cpp (global module fragment) so the +// implementation symbols are compiled exactly once. + +#define VK_USE_PLATFORM_WIN32_KHR +#include +#include +// vcpkg installs VMA under the vma/ subdirectory. +#include + +// ---- Macro re-exports --------------------------------------------------- +// C++20 named modules cannot export preprocessor macros, so any Vulkan macro +// used as a value in module code must be re-exported as a real C++ entity +// (same approach as Modules/d3d12/d3d12_includes.h for IID_PPV_ARGS / DXGI +// error codes). +// +// VK_NULL_HANDLE is `#define VK_NULL_HANDLE 0`. We re-export it as `nullptr` +// rather than an integer constant: on x64 (VK_USE_64_BIT_PTR_DEFINES) every +// Vulkan handle is a pointer type, and only a null-pointer constant — not a +// constexpr int 0 — is assignable to a pointer. All inline header code that +// needs the macro (e.g. VMA) was already parsed above with the macro active, +// so undefining it here is safe. +#undef VK_NULL_HANDLE +export inline constexpr decltype(nullptr) VK_NULL_HANDLE = nullptr; + +// Sentinel values used in subresource ranges and buffer sizes. +#undef VK_REMAINING_MIP_LEVELS +export inline constexpr uint32_t VK_REMAINING_MIP_LEVELS = (~0U); + +#undef VK_REMAINING_ARRAY_LAYERS +export inline constexpr uint32_t VK_REMAINING_ARRAY_LAYERS = (~0U); + +#undef VK_WHOLE_SIZE +export inline constexpr uint64_t VK_WHOLE_SIZE = (~0ULL); diff --git a/sources/RenderSystem/Assets/Asset.cpp b/sources/RenderSystem/Assets/Asset.cpp index 33ea7e5f..4be5b19d 100644 --- a/sources/RenderSystem/Assets/Asset.cpp +++ b/sources/RenderSystem/Assets/Asset.cpp @@ -2,6 +2,8 @@ module Graphics:Asset; import Core; import ppl; import windows; + +import :AssetRenderer; using namespace concurrency; @@ -70,6 +72,8 @@ void AssetManager::add_func(std::function f) void AssetManager::add_preview(Asset::ptr asset) { + if (!AssetRenderer::is_good()) return; // no preview renderer on Vulkan + std::lock_guard g(update_preview_mutex); diff --git a/sources/RenderSystem/Font/TextSystem.cpp b/sources/RenderSystem/Font/TextSystem.cpp index 80d765ec..1f0111c6 100644 --- a/sources/RenderSystem/Font/TextSystem.cpp +++ b/sources/RenderSystem/Font/TextSystem.cpp @@ -64,9 +64,13 @@ struct GlyphCacheKey } }; +} // anonymous namespace + // --------------------------------------------------------------------------- -// FontAtlas — single R8_UNORM texture + coord buffer shared by all fonts +// FontAtlas — defined in namespace Fonts so it can be a FontSystem member // --------------------------------------------------------------------------- +namespace Fonts { + class FontAtlas { public: @@ -79,7 +83,9 @@ class FontAtlas m_texture->resource->set_name("FontAtlas::texture"); m_coord_buf = - HAL::StructuredBufferView(HAL::Device::get(), MAX_GLYPHS); + HAL::StructuredBufferView(HAL::Device::get(), MAX_GLYPHS, + HAL::counterType::NONE, HAL::ResFlags::ShaderResource, + HAL::HeapType::UPLOAD); m_cpu.resize(ATLAS_W * ATLAS_H, 0u); m_entries.reserve(MAX_GLYPHS); @@ -183,6 +189,20 @@ class FontAtlas std::lock_guard lk(m_mtx); if (!m_dirty) return; + // On first upload, clear the entire GPU texture to zero so undefined + // texels outside the dirty rect don't produce garbage samples. + if (m_first_flush) + { + m_first_flush = false; + list->get_copy().update_texture( + m_texture->resource, + ivec3(0, 0, 0), + ivec3(static_cast(ATLAS_W), static_cast(ATLAS_H), 1), + HAL::calc_subresource(0, 0, 0, 1, 1), + reinterpret_cast(m_cpu.data()), + static_cast(ATLAS_W)); + } + // Upload dirty region of the atlas texture if (m_dirty_r > m_dirty_l && m_dirty_b > m_dirty_t) { @@ -197,11 +217,13 @@ class FontAtlas static_cast(ATLAS_W)); } - // Upload updated coord buffer entries + // Write coord buffer entries directly into the UPLOAD-heap mapped memory. + // UPLOAD heap is always host-coherent; no copy command or barrier needed. if (!m_entries.empty()) { - list->get_copy().update(m_coord_buf, 0, - std::span{m_entries.data(), m_entries.size()}); + auto* dst = reinterpret_cast(m_coord_buf.resource->buffer_data); + if (dst) + std::memcpy(dst, m_entries.data(), m_entries.size() * sizeof(GlyphAtlasEntry)); } // Reset dirty state @@ -212,6 +234,8 @@ class FontAtlas m_dirty_b = 0; } + HAL::TextureResource* get_texture_resource() const { return m_texture->resource.get(); } + // Bind the atlas texture and coord buffer to the FontRendering slot void bind(HAL::CommandList::ptr& list) { @@ -219,8 +243,8 @@ class FontAtlas rendering.GetTex0() = m_texture->texture_2d().texture2D; rendering.GetPositions() = m_coord_buf.resource->create_view< - HAL::FormattedBufferView>(*list) - .buffer; + HAL::StructuredBufferView>(*list) + .structuredBuffer; list->get_graphics().set(rendering); } @@ -240,22 +264,22 @@ class FontAtlas uint32_t m_dirty_l = ATLAS_W, m_dirty_t = ATLAS_H; uint32_t m_dirty_r = 0, m_dirty_b = 0; bool m_dirty = false; + bool m_first_flush = true; std::mutex m_mtx; }; +} // namespace Fonts + +namespace +{ + using Fonts::FontAtlas; + // --------------------------------------------------------------------------- -// Module-level singletons (created lazily) +// FreeType library singleton (created lazily, cleaned up by FontSystem dtor) // --------------------------------------------------------------------------- -static FontAtlas* s_atlas = nullptr; static FT_Library s_ft_lib = nullptr; -static FontAtlas& get_atlas() -{ - if (!s_atlas) s_atlas = new FontAtlas(); - return *s_atlas; -} - static FT_Library get_ft_library() { if (!s_ft_lib) FT_Init_FreeType(&s_ft_lib); @@ -447,16 +471,15 @@ static_assert(sizeof(ShaderConstants) == sizeof(Table::FontRenderingConstants)); // draw_vertices — uploads vertices and issues the draw call // --------------------------------------------------------------------------- static void draw_vertices( - HAL::CommandList::ptr& list, + HAL::CommandList::ptr& list, const std::vector& verts, - const sizer* clip_rect, - const float* transform_matrix, - unsigned int /*flags*/) + const sizer* clip_rect, + const float* transform_matrix, + unsigned int /*flags*/, + FontAtlas& atlas) { if (verts.empty()) return; - FontAtlas& atlas = get_atlas(); - // 1. Flush any newly rasterised glyphs to the GPU atlas.flush(list); @@ -470,6 +493,11 @@ static void draw_vertices( PSOS::FontRender::Format(formats[0])); list->get_graphics().set_topology(HAL::PrimitiveTopologyType::POINT, HAL::PrimitiveTopologyFeed::LIST); + { + auto pipeline = HAL::Device::get().get_engine_pso_holder().GetPSO( + PSOS::FontRender::Format(formats[0])); + + } // 4. Shader constants (transform + clip rect) ShaderConstants sc{}; @@ -515,8 +543,14 @@ static void draw_vertices( list->get_graphics().set(gpu_consts); // 5. Upload glyph vertex buffer (transient placement) + // Alignment must satisfy both the struct stride AND Vulkan's + // minStorageBufferOffsetAlignment so buf_info.offset in the Vulkan descriptor + // is legal. lcm(stride, device_limit) is the minimal safe alignment. uint32_t count = static_cast(verts.size()); - auto placed = list->place_data(sizeof(Table::Glyph) * count, sizeof(Table::Glyph)); + const uint32_t stride_align = sizeof(Table::Glyph); + const uint32_t vk_align = HAL::Device::get().get_properties().min_storage_buffer_offset_alignment; + const uint32_t buf_align = std::lcm(stride_align, vk_align); + auto placed = list->place_data(sizeof(Table::Glyph) * count, buf_align); list->write(placed, std::span{verts.data(), count}); auto view = placed.resource->create_view>( @@ -611,8 +645,9 @@ void Font::draw(HAL::CommandList::ptr& list, { if (!m_data || !m_data->face) return; - auto verts = layout_text(m_data->face, str, size, area, color, flags, get_atlas()); - draw_vertices(list, verts, &clip_rect, nullptr, flags | FW1_CLIPRECT); + FontAtlas& atlas = FontSystem::get_atlas(); + auto verts = layout_text(m_data->face, str, size, area, color, flags, atlas); + draw_vertices(list, verts, &clip_rect, nullptr, flags | FW1_CLIPRECT, atlas); } vec2 Font::measure(std::string str, float size, unsigned int flags) @@ -675,6 +710,10 @@ void Font::set_states(HAL::CommandList::ptr& list) FontSystem::FontSystem() { + ASSERT(m_atlas == nullptr); + m_atlas = new FontAtlas(); + ASSERT(m_atlas != nullptr); + fonts.create_func = [](const std::string& name) -> Font::ptr { std::string path = resolve_font_path(name); @@ -693,6 +732,28 @@ FontSystem::FontSystem() }; } +FontSystem::~FontSystem() +{ + fonts.clear(); + delete m_atlas; + m_atlas = nullptr; + if (s_ft_lib) + { + FT_Done_FreeType(s_ft_lib); + s_ft_lib = nullptr; + } +} + +FontAtlas& FontSystem::get_atlas() +{ + return *FontSystem::get().m_atlas; +} + +HAL::TextureResource* FontSystem::get_atlas_texture() +{ + return FontSystem::get_atlas().get_texture_resource(); +} + Font::ptr FontSystem::get_font(std::string font_name) { return fonts[font_name]; @@ -738,7 +799,7 @@ void FontGeometry::set(HAL::CommandList::ptr& /*list*/, if (!font || !font->m_data || !font->m_data->face) return; m_impl->verts = layout_text(font->m_data->face, str, size, - area, color, flags, get_atlas()); + area, color, flags, FontSystem::get_atlas()); } sizer FontGeometry::add(HAL::CommandList::ptr& /*list*/, @@ -753,7 +814,7 @@ sizer FontGeometry::add(HAL::CommandList::ptr& /*list*/, if (!font || !font->m_data || !font->m_data->face) return area; auto new_verts = layout_text(font->m_data->face, str, size, - area, color, flags, get_atlas()); + area, color, flags, FontSystem::get_atlas()); for (auto& v : new_verts) m_impl->verts.push_back(v); @@ -790,7 +851,8 @@ void FontGeometry::draw(HAL::CommandList::ptr& list, mtx[10] = 1.f; mtx[15] = 1.f; - draw_vertices(list, m_impl->verts, &clip_rect, mtx, flags | FW1_CLIPRECT); + draw_vertices(list, m_impl->verts, &clip_rect, mtx, flags | FW1_CLIPRECT, + FontSystem::get_atlas()); } float FontGeometry::get_size() diff --git a/sources/RenderSystem/Font/TextSystem.ixx b/sources/RenderSystem/Font/TextSystem.ixx index 00271422..a94a54ca 100644 --- a/sources/RenderSystem/Font/TextSystem.ixx +++ b/sources/RenderSystem/Font/TextSystem.ixx @@ -31,6 +31,8 @@ export enum FW1_TEXT_FLAG : unsigned int FW1_UNUSED = 0xffffffff }; +namespace Fonts { class FontAtlas; } + export namespace Fonts { class FontSystem; @@ -78,10 +80,15 @@ export namespace Fonts friend class FontGeometry; Cache fonts; + FontAtlas* m_atlas = nullptr; + FontSystem(); + ~FontSystem(); public: Font::ptr get_font(std::string font_name); + static FontAtlas& get_atlas(); + static HAL::TextureResource* get_atlas_texture(); }; // ----------------------------------------------------------------------- diff --git a/sources/RenderSystem/FrameGraph/FrameGraph.cpp b/sources/RenderSystem/FrameGraph/FrameGraph.cpp index fe965dbc..ef0c5ac7 100644 --- a/sources/RenderSystem/FrameGraph/FrameGraph.cpp +++ b/sources/RenderSystem/FrameGraph/FrameGraph.cpp @@ -801,7 +801,7 @@ namespace FrameGraph for (auto& pair : builder.alloc_resources) { auto info = &pair.second; - if (!check(info->flags & ResourceFlags::Static)) + if (!check(info->flags & ResourceFlags::Static)&&!info->passed) { info->resource = nullptr; // info->view = nullptr; diff --git a/sources/RenderSystem/FrameGraph/PassDefaults.cpp b/sources/RenderSystem/FrameGraph/PassDefaults.cpp new file mode 100644 index 00000000..62ed3ec7 --- /dev/null +++ b/sources/RenderSystem/FrameGraph/PassDefaults.cpp @@ -0,0 +1,74 @@ +module Graphics; + +import :FrameGraphContext; +import FrameGraph; +import HAL; + +using namespace FrameGraph; + +// ---- ResultCreation --------------------------------------------------------- + +bool PassDefault::setup( + Passes::ResultCreation::Context& data, FrameGraph::TaskBuilder& builder) +{ + auto& frame = builder.graph->get_context(); + builder.create(data.ResultTexture, + { uint3(frame.frame_size, 0), HAL::Format::R16G16B16A16_FLOAT, 1, 1 }, + FrameGraph::ResourceFlags::RenderTarget); + return false; +} + +void PassDefault::render( + Passes::ResultCreation::Context&, FrameGraph::FrameContext&) {} + + +// ---- CopyPrev --------------------------------------------------------------- + +bool PassDefault::setup( + Passes::CopyPrev::Context& data, FrameGraph::TaskBuilder& builder) +{ + builder.need(data.gbuffer.GBuffer_NormalsPrev, FrameGraph::ResourceFlags::CopyDest); + builder.need(data.gbuffer.GBuffer_SpecularPrev, FrameGraph::ResourceFlags::CopyDest); + builder.need(data.gbuffer.GBuffer_Normals, FrameGraph::ResourceFlags::CopySource); + builder.need(data.gbuffer.GBuffer_Specular, FrameGraph::ResourceFlags::CopySource); + builder.need(data.gbuffer.GBuffer_DepthPrev, FrameGraph::ResourceFlags::CopyDest); + builder.need(data.gbuffer.GBuffer_DepthMips, FrameGraph::ResourceFlags::CopySource); + return true; +} + +void PassDefault::render( + Passes::CopyPrev::Context& data, FrameGraph::FrameContext& context) +{ + auto& copy = context.get_list()->get_copy(); + + copy.copy_resource(data.gbuffer.GBuffer_NormalsPrev->resource, + data.gbuffer.GBuffer_Normals->resource); + copy.copy_resource(data.gbuffer.GBuffer_SpecularPrev->resource, + data.gbuffer.GBuffer_Specular->resource); + copy.copy_texture(data.gbuffer.GBuffer_DepthPrev->resource, 0, + data.gbuffer.GBuffer_DepthMips->resource, 0); +} + + +// ---- Profiler --------------------------------------------------------------- + +bool PassDefault::setup( + Passes::Profiler::Context& data, FrameGraph::TaskBuilder& builder) +{ + builder.need(data.swapchain, + FrameGraph::ResourceFlags::Required | FrameGraph::ResourceFlags::RenderTarget); + return false; +} + +void PassDefault::render( + Passes::Profiler::Context&, FrameGraph::FrameContext&) {} + + +// ---- RTXPass ---------------------------------------------------------------- +// Not yet implemented; always disabled so the pass is skipped at runtime. + +bool PassDefault::setup( + Passes::RTXPass::Context&, FrameGraph::TaskBuilder&) { return false; } + +void PassDefault::render( + Passes::RTXPass::Context&, FrameGraph::FrameContext&) {} diff --git a/sources/RenderSystem/FrameGraph/autogen/enums.h b/sources/RenderSystem/FrameGraph/autogen/enums.h index 7862aea4..14eb4061 100644 --- a/sources/RenderSystem/FrameGraph/autogen/enums.h +++ b/sources/RenderSystem/FrameGraph/autogen/enums.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module FrameGraphAutogen:Passes.; import FrameGraph; diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/AssetGBuffer.h b/sources/RenderSystem/FrameGraph/autogen/pass/AssetGBuffer.h index 46cffdbd..a7262e32 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/AssetGBuffer.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/AssetGBuffer.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/AssetMip.h b/sources/RenderSystem/FrameGraph/autogen/pass/AssetMip.h index 5621e959..6dda6d23 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/AssetMip.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/AssetMip.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/AssetPipeline.pipeline.h b/sources/RenderSystem/FrameGraph/autogen/pass/AssetPipeline.pipeline.h index 5cdfcd81..df2b941c 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/AssetPipeline.pipeline.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/AssetPipeline.pipeline.h @@ -5,7 +5,6 @@ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #include "ResultCreation.h" #include "PreScene.h" #include "BlueNoise.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/BlueNoise.h b/sources/RenderSystem/FrameGraph/autogen/pass/BlueNoise.h index ec6fc45c..f4cfef2f 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/BlueNoise.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/BlueNoise.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/CopyPrev.h b/sources/RenderSystem/FrameGraph/autogen/pass/CopyPrev.h index 5fe79dac..d5e5a573 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/CopyPrev.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/CopyPrev.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapDownsample.h b/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapDownsample.h index 90801ed8..ade16962 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapDownsample.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapDownsample.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapEnviromentProcessor.h b/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapEnviromentProcessor.h index 52265649..fe8aa4e1 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapEnviromentProcessor.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/CubeMapEnviromentProcessor.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/CubeSky.h b/sources/RenderSystem/FrameGraph/autogen/pass/CubeSky.h index 657a72d0..d0499b7d 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/CubeSky.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/CubeSky.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/FSR.h b/sources/RenderSystem/FrameGraph/autogen/pass/FSR.h index 9d8bb6d4..c1d97cee 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/FSR.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/FSR.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/GBuffer.h b/sources/RenderSystem/FrameGraph/autogen/pass/GBuffer.h index 682ca5de..9d5c2d2f 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/GBuffer.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/GBuffer.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/GBufferDownsampler.h b/sources/RenderSystem/FrameGraph/autogen/pass/GBufferDownsampler.h index 577729fd..1eef447a 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/GBufferDownsampler.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/GBufferDownsampler.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/Lighting.h b/sources/RenderSystem/FrameGraph/autogen/pass/Lighting.h index 1d778fda..d433c9dc 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/Lighting.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/Lighting.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/MainPipeline.pipeline.h b/sources/RenderSystem/FrameGraph/autogen/pass/MainPipeline.pipeline.h index c7eb76e9..00b2e038 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/MainPipeline.pipeline.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/MainPipeline.pipeline.h @@ -5,7 +5,6 @@ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #include "PreScene.h" #include "BlueNoise.h" #include "Voxelize.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/Mipmapping.h b/sources/RenderSystem/FrameGraph/autogen/pass/Mipmapping.h index 6cf2e645..dd329767 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/Mipmapping.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/Mipmapping.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Cascade.h b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Cascade.h index 9e0c2ac3..fae3fc04 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Cascade.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Cascade.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Combine.h b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Combine.h index 5977150c..61ac5c52 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Combine.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Combine.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_GenerateMask.h b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_GenerateMask.h index ecb21976..a172cead 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_GenerateMask.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_GenerateMask.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Global.h b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Global.h index dcfbce4c..14753785 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Global.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/PSSM_Global.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/PreScene.h b/sources/RenderSystem/FrameGraph/autogen/pass/PreScene.h index 39e81550..f29b3f80 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/PreScene.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/PreScene.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/Profiler.h b/sources/RenderSystem/FrameGraph/autogen/pass/Profiler.h index c6f48bea..c3521065 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/Profiler.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/Profiler.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/RTXPass.h b/sources/RenderSystem/FrameGraph/autogen/pass/RTXPass.h index 465db3b0..207eb7e8 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/RTXPass.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/RTXPass.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/ReflCombine.h b/sources/RenderSystem/FrameGraph/autogen/pass/ReflCombine.h index e3b98f26..5b7c0895 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/ReflCombine.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/ReflCombine.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/ReflectionDenoiser_Reproject.h b/sources/RenderSystem/FrameGraph/autogen/pass/ReflectionDenoiser_Reproject.h index 6b44a6f4..0b573c91 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/ReflectionDenoiser_Reproject.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/ReflectionDenoiser_Reproject.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/ResultCreation.h b/sources/RenderSystem/FrameGraph/autogen/pass/ResultCreation.h index b95d8b53..13284c9a 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/ResultCreation.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/ResultCreation.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/SMAA.h b/sources/RenderSystem/FrameGraph/autogen/pass/SMAA.h index f9f42b85..a13ddbd8 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/SMAA.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/SMAA.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/Scene.h b/sources/RenderSystem/FrameGraph/autogen/pass/Scene.h index 1f56b62c..c1b114b4 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/Scene.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/Scene.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/ScreenReflection.h b/sources/RenderSystem/FrameGraph/autogen/pass/ScreenReflection.h index 658f2a51..55c0e16f 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/ScreenReflection.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/ScreenReflection.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Filter.h b/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Filter.h index 2d2f7ec6..f0f2db47 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Filter.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Filter.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Prepare.h b/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Prepare.h index f5f2e755..354d8556 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Prepare.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_Prepare.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_TileClassification.h b/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_TileClassification.h index 77450598..64cd7e14 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_TileClassification.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/ShadowDenoiser_TileClassification.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/Sky.h b/sources/RenderSystem/FrameGraph/autogen/pass/Sky.h index bd4b7392..69f41a48 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/Sky.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/Sky.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/UIPipeline.pipeline.h b/sources/RenderSystem/FrameGraph/autogen/pass/UIPipeline.pipeline.h index c9e72ccb..2bd75e9a 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/UIPipeline.pipeline.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/UIPipeline.pipeline.h @@ -5,7 +5,6 @@ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #include "Profiler.h" #include "UI_Render.h" #include "../pass_defaults.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/UI_Render.h b/sources/RenderSystem/FrameGraph/autogen/pass/UI_Render.h index 121ee788..b8b8c514 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/UI_Render.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/UI_Render.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/VoxelCombine.h b/sources/RenderSystem/FrameGraph/autogen/pass/VoxelCombine.h index d010599b..f04a2012 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/VoxelCombine.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/VoxelCombine.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/VoxelDebug.h b/sources/RenderSystem/FrameGraph/autogen/pass/VoxelDebug.h index 440e49d3..c5fd29e2 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/VoxelDebug.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/VoxelDebug.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/VoxelScreen.h b/sources/RenderSystem/FrameGraph/autogen/pass/VoxelScreen.h index cb9d72af..f604a370 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/VoxelScreen.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/VoxelScreen.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" #include "GBuffer.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/Voxelize.h b/sources/RenderSystem/FrameGraph/autogen/pass/Voxelize.h index cc1e33e8..01a92104 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/Voxelize.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/Voxelize.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_after.h b/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_after.h index f2febfcf..fe4faedb 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_after.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_after.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_before.h b/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_before.h index 8fd4c01b..faccd448 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_before.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass/stencil_renderer_before.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "../PassNodeBase.h" diff --git a/sources/RenderSystem/FrameGraph/autogen/pass_defaults.h b/sources/RenderSystem/FrameGraph/autogen/pass_defaults.h index 04261c23..42b0a5f2 100644 --- a/sources/RenderSystem/FrameGraph/autogen/pass_defaults.h +++ b/sources/RenderSystem/FrameGraph/autogen/pass_defaults.h @@ -4,11 +4,9 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ -// // PassDefault provides the setup/render implementations for passes whose // logic is fully self-contained (no external wiring needed). Bodies are // defined out-of-line in main.cpp. - #pragma once extern "C++" diff --git a/sources/RenderSystem/FrameGraph/autogen/passes.ixx b/sources/RenderSystem/FrameGraph/autogen/passes.ixx index 7d990b85..86e28e99 100644 --- a/sources/RenderSystem/FrameGraph/autogen/passes.ixx +++ b/sources/RenderSystem/FrameGraph/autogen/passes.ixx @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - export module FrameGraph:Passes; import :Base; diff --git a/sources/RenderSystem/GUI/Elements/Label.cpp b/sources/RenderSystem/GUI/Elements/Label.cpp index b0910338..34a05235 100644 --- a/sources/RenderSystem/GUI/Elements/Label.cpp +++ b/sources/RenderSystem/GUI/Elements/Label.cpp @@ -47,7 +47,7 @@ namespace GUI if ((intersected.top < intersected.bottom && intersected.left < intersected.right)) { // if(GetAsyncKeyState('U')) - + ASSERT(cache.texture.texture2D && "label::draw: cache texture not initialized — recalculate not called?"); c.renderer->draw(c, cache, p); // else // geomerty->draw(c.command_list, c.ui_clipping, 0, p.pos); diff --git a/sources/RenderSystem/GUI/Renderer/NinePatch.cpp b/sources/RenderSystem/GUI/Renderer/NinePatch.cpp index 61b05dfd..34940aa3 100644 --- a/sources/RenderSystem/GUI/Renderer/NinePatch.cpp +++ b/sources/RenderSystem/GUI/Renderer/NinePatch.cpp @@ -1,12 +1,19 @@ import GUI; import HAL; + import Core; using namespace HAL; namespace GUI { - HAL::IndexBuffer NinePatch::index_buffer; + //HAL::IndexBuffer NinePatch::index_buffer; + void NinePatch::reset() + { + + // index_buffer.resource = nullptr; + + } NinePatch::NinePatch() { if(!index_buffer) @@ -50,13 +57,13 @@ if(!index_buffer) added = true; textures_handles.emplace_back(item.texture.texture2D); } - if (!added && current_state == HAL::Device::get().get_engine_pso_holder().GetPSO()) { return; } if(!added) { +// ASSERT(false && "NinePatch::draw: null texture2D handle — item.texture was never set (cache_resource not created?)"); textures_handles.emplace_back(HAL::Texture2DView{}.texture2D); } @@ -72,7 +79,7 @@ if(!index_buffer) float tl = 0, tt = 0, tr = 0, tb = 0; - if (item.texture) + if (item.texture.resource) { tl = static_cast(item.padding.left) / item.texture.get_desc().as_texture().Dimensions.x; tt = static_cast(item.padding.top) / item.texture.get_desc().as_texture().Dimensions.y; @@ -279,7 +286,7 @@ if(!index_buffer) void NinePatch::flush(base::Context& c) { if (vertexes.empty()) return; - + auto& graphics = c.command_list->get_graphics(); graphics.set_topology(HAL::PrimitiveTopologyType::TRIANGLE, HAL::PrimitiveTopologyFeed::LIST); graphics.set_index_buffer(index_buffer.get_index_buffer_view()); diff --git a/sources/RenderSystem/GUI/Renderer/Renderer.ixx b/sources/RenderSystem/GUI/Renderer/Renderer.ixx index 39a6e358..907c0dd6 100644 --- a/sources/RenderSystem/GUI/Renderer/Renderer.ixx +++ b/sources/RenderSystem/GUI/Renderer/Renderer.ixx @@ -17,7 +17,7 @@ export namespace GUI HAL::PipelineState::ptr current_state; public: - static HAL::IndexBuffer index_buffer; + HAL::IndexBuffer index_buffer; int counter = 0; using ptr = s_ptr; NinePatch(); @@ -25,6 +25,8 @@ export namespace GUI void draw(base::Context& c, GUI::Texture& item, rect r); void draw(base::Context& c, GUI::Texture& item, rect r, HAL::PipelineState::ptr pipeline_state); void flush(base::Context& c); + + static void reset(); }; class SimpleRect diff --git a/sources/RenderSystem/Materials/universal_material.cpp b/sources/RenderSystem/Materials/universal_material.cpp index 244a5280..91338a51 100644 --- a/sources/RenderSystem/Materials/universal_material.cpp +++ b/sources/RenderSystem/Materials/universal_material.cpp @@ -199,6 +199,9 @@ DynamicData generate_data(std::vector& un) void materials::universal_material::update() { +#ifdef HAL_BACKEND_VULKAN + return; // material pipeline not active on Vulkan yet +#endif //std::lock_guard g(m); PROFILE(L"universal_material"); if (need_regenerate_material) @@ -321,6 +324,12 @@ void materials::universal_material::generate_texture_handles() void materials::universal_material::generate_material() { +#ifdef HAL_BACKEND_VULKAN + // Material PSO compilation requires the 3D pipeline (GBufferDraw, Voxelization, + // raytracing libs, etc.) which is not yet active on Vulkan. Skip generation + // silently — materials will be re-generated when the 3D pipeline is enabled. + return; +#endif // std::lock_guard g(m); if (!context) context.reset(new MaterialContext); diff --git a/sources/RenderSystem/Mesh/AssimpLoader.cpp b/sources/RenderSystem/Mesh/AssimpLoader.cpp index 69063d76..c21f2679 100644 --- a/sources/RenderSystem/Mesh/AssimpLoader.cpp +++ b/sources/RenderSystem/Mesh/AssimpLoader.cpp @@ -4,6 +4,10 @@ #define AI_MATKEY_COLOR_DIFFUSE "$clr.diffuse", 0, 0 #define AI_MATKEY_SHININESS "$mat.shininess", 0, 0 #define AI_MATKEY_REFLECTIVITY "$mat.reflectivity", 0, 0 +// material.h defines aiGetMaterialFloat as static inline; static functions from +// exported headers don't cross the module boundary into this TU, so include it +// explicitly in the global module fragment to keep the definition reachable. +#include module Graphics; import Core; diff --git a/sources/RenderSystem/Scene/Scene.cpp b/sources/RenderSystem/Scene/Scene.cpp index 5a66cab8..ddbecc03 100644 --- a/sources/RenderSystem/Scene/Scene.cpp +++ b/sources/RenderSystem/Scene/Scene.cpp @@ -124,7 +124,7 @@ void Scene::update(HAL::FrameResources& frame) sceneData.GetMaterials() = universal_material_info_part_manager::get().buffer; sceneData.GetMeshes() = scene->mesh_infos->buffer; sceneData.GetRaytraceInstanceInfo() = universal_rtx_manager::get().buffer; -sceneData.GetScene() = raytrace_scene->raytracing_handle; +//sceneData.GetScene() = raytrace_scene->raytracing_handle; compiledScene = sceneData.compile(frame); } diff --git a/sources/SIGParser/.antlr/SIG.interp b/sources/SIGParser/.antlr/SIG.interp index 0bf9cde4..05644263 100644 --- a/sources/SIGParser/.antlr/SIG.interp +++ b/sources/SIGParser/.antlr/SIG.interp @@ -253,4 +253,4 @@ bool_type atn: -[4, 1, 86, 669, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 160, 8, 0, 10, 0, 12, 0, 163, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 170, 8, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 3, 3, 179, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 185, 8, 4, 10, 4, 12, 4, 188, 9, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 3, 6, 196, 8, 6, 1, 6, 1, 6, 1, 7, 5, 7, 201, 8, 7, 10, 7, 12, 7, 204, 9, 7, 1, 7, 1, 7, 1, 7, 3, 7, 209, 8, 7, 1, 7, 1, 7, 3, 7, 213, 8, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 5, 10, 228, 8, 10, 10, 10, 12, 10, 231, 9, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 237, 8, 10, 1, 10, 1, 10, 1, 11, 5, 11, 242, 8, 11, 10, 11, 12, 11, 245, 9, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 5, 12, 253, 8, 12, 10, 12, 12, 12, 256, 9, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 5, 14, 266, 8, 14, 10, 14, 12, 14, 269, 9, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 5, 16, 281, 8, 16, 10, 16, 12, 16, 284, 9, 16, 1, 16, 3, 16, 287, 8, 16, 1, 16, 3, 16, 290, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 3, 22, 305, 8, 22, 1, 22, 1, 22, 5, 22, 309, 8, 22, 10, 22, 12, 22, 312, 9, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 323, 8, 23, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 329, 8, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 5, 27, 337, 8, 27, 10, 27, 12, 27, 340, 9, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 5, 28, 348, 8, 28, 10, 28, 12, 28, 351, 9, 28, 1, 29, 1, 29, 1, 29, 3, 29, 356, 8, 29, 1, 30, 5, 30, 359, 8, 30, 10, 30, 12, 30, 362, 9, 30, 1, 31, 1, 31, 1, 31, 3, 31, 367, 8, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 3, 32, 376, 8, 32, 1, 33, 5, 33, 379, 8, 33, 10, 33, 12, 33, 382, 9, 33, 1, 34, 5, 34, 385, 8, 34, 10, 34, 12, 34, 388, 9, 34, 1, 34, 1, 34, 1, 34, 3, 34, 393, 8, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 3, 37, 410, 8, 37, 1, 38, 5, 38, 413, 8, 38, 10, 38, 12, 38, 416, 9, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 5, 41, 430, 8, 41, 10, 41, 12, 41, 433, 9, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 5, 43, 443, 8, 43, 10, 43, 12, 43, 446, 9, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 457, 8, 44, 1, 45, 5, 45, 460, 8, 45, 10, 45, 12, 45, 463, 9, 45, 1, 46, 1, 46, 1, 46, 3, 46, 468, 8, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 3, 47, 481, 8, 47, 1, 48, 5, 48, 484, 8, 48, 10, 48, 12, 48, 487, 9, 48, 1, 49, 5, 49, 490, 8, 49, 10, 49, 12, 49, 493, 9, 49, 1, 49, 1, 49, 1, 49, 3, 49, 498, 8, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 3, 50, 506, 8, 50, 1, 51, 5, 51, 509, 8, 51, 10, 51, 12, 51, 512, 9, 51, 1, 52, 1, 52, 1, 52, 3, 52, 517, 8, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 527, 8, 53, 1, 54, 5, 54, 530, 8, 54, 10, 54, 12, 54, 533, 9, 54, 1, 55, 1, 55, 1, 55, 3, 55, 538, 8, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 3, 56, 547, 8, 56, 1, 57, 5, 57, 550, 8, 57, 10, 57, 12, 57, 553, 9, 57, 1, 58, 5, 58, 556, 8, 58, 10, 58, 12, 58, 559, 9, 58, 1, 58, 1, 58, 1, 58, 3, 58, 564, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 3, 59, 572, 8, 59, 1, 60, 5, 60, 575, 8, 60, 10, 60, 12, 60, 578, 9, 60, 1, 61, 5, 61, 581, 8, 61, 10, 61, 12, 61, 584, 9, 61, 1, 61, 1, 61, 1, 61, 3, 61, 589, 8, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 5, 62, 596, 8, 62, 10, 62, 12, 62, 599, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 3, 63, 607, 8, 63, 1, 64, 5, 64, 610, 8, 64, 10, 64, 12, 64, 613, 9, 64, 1, 65, 5, 65, 616, 8, 65, 10, 65, 12, 65, 619, 9, 65, 1, 65, 1, 65, 1, 65, 3, 65, 624, 8, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 5, 66, 631, 8, 66, 10, 66, 12, 66, 634, 9, 66, 1, 66, 1, 66, 1, 66, 3, 66, 639, 8, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 649, 8, 67, 1, 68, 5, 68, 652, 8, 68, 10, 68, 12, 68, 655, 9, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 15, 202, 229, 243, 254, 267, 338, 349, 386, 444, 491, 557, 582, 597, 617, 632, 0, 73, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 0, 3, 1, 0, 8, 19, 1, 0, 20, 35, 1, 0, 58, 59, 690, 0, 161, 1, 0, 0, 0, 2, 169, 1, 0, 0, 0, 4, 173, 1, 0, 0, 0, 6, 176, 1, 0, 0, 0, 8, 180, 1, 0, 0, 0, 10, 191, 1, 0, 0, 0, 12, 193, 1, 0, 0, 0, 14, 202, 1, 0, 0, 0, 16, 216, 1, 0, 0, 0, 18, 220, 1, 0, 0, 0, 20, 229, 1, 0, 0, 0, 22, 243, 1, 0, 0, 0, 24, 254, 1, 0, 0, 0, 26, 262, 1, 0, 0, 0, 28, 267, 1, 0, 0, 0, 30, 275, 1, 0, 0, 0, 32, 277, 1, 0, 0, 0, 34, 291, 1, 0, 0, 0, 36, 293, 1, 0, 0, 0, 38, 295, 1, 0, 0, 0, 40, 297, 1, 0, 0, 0, 42, 299, 1, 0, 0, 0, 44, 301, 1, 0, 0, 0, 46, 322, 1, 0, 0, 0, 48, 328, 1, 0, 0, 0, 50, 330, 1, 0, 0, 0, 52, 332, 1, 0, 0, 0, 54, 338, 1, 0, 0, 0, 56, 343, 1, 0, 0, 0, 58, 355, 1, 0, 0, 0, 60, 360, 1, 0, 0, 0, 62, 363, 1, 0, 0, 0, 64, 375, 1, 0, 0, 0, 66, 380, 1, 0, 0, 0, 68, 386, 1, 0, 0, 0, 70, 398, 1, 0, 0, 0, 72, 402, 1, 0, 0, 0, 74, 409, 1, 0, 0, 0, 76, 414, 1, 0, 0, 0, 78, 417, 1, 0, 0, 0, 80, 423, 1, 0, 0, 0, 82, 425, 1, 0, 0, 0, 84, 436, 1, 0, 0, 0, 86, 444, 1, 0, 0, 0, 88, 456, 1, 0, 0, 0, 90, 461, 1, 0, 0, 0, 92, 464, 1, 0, 0, 0, 94, 480, 1, 0, 0, 0, 96, 485, 1, 0, 0, 0, 98, 491, 1, 0, 0, 0, 100, 505, 1, 0, 0, 0, 102, 510, 1, 0, 0, 0, 104, 513, 1, 0, 0, 0, 106, 526, 1, 0, 0, 0, 108, 531, 1, 0, 0, 0, 110, 534, 1, 0, 0, 0, 112, 546, 1, 0, 0, 0, 114, 551, 1, 0, 0, 0, 116, 557, 1, 0, 0, 0, 118, 571, 1, 0, 0, 0, 120, 576, 1, 0, 0, 0, 122, 582, 1, 0, 0, 0, 124, 597, 1, 0, 0, 0, 126, 606, 1, 0, 0, 0, 128, 611, 1, 0, 0, 0, 130, 617, 1, 0, 0, 0, 132, 632, 1, 0, 0, 0, 134, 648, 1, 0, 0, 0, 136, 653, 1, 0, 0, 0, 138, 656, 1, 0, 0, 0, 140, 662, 1, 0, 0, 0, 142, 664, 1, 0, 0, 0, 144, 666, 1, 0, 0, 0, 146, 160, 3, 62, 31, 0, 147, 160, 3, 68, 34, 0, 148, 160, 3, 78, 39, 0, 149, 160, 3, 110, 55, 0, 150, 160, 3, 92, 46, 0, 151, 160, 3, 98, 49, 0, 152, 160, 3, 104, 52, 0, 153, 160, 3, 116, 58, 0, 154, 160, 3, 122, 61, 0, 155, 160, 3, 132, 66, 0, 156, 160, 3, 130, 65, 0, 157, 160, 3, 138, 69, 0, 158, 160, 5, 81, 0, 0, 159, 146, 1, 0, 0, 0, 159, 147, 1, 0, 0, 0, 159, 148, 1, 0, 0, 0, 159, 149, 1, 0, 0, 0, 159, 150, 1, 0, 0, 0, 159, 151, 1, 0, 0, 0, 159, 152, 1, 0, 0, 0, 159, 153, 1, 0, 0, 0, 159, 154, 1, 0, 0, 0, 159, 155, 1, 0, 0, 0, 159, 156, 1, 0, 0, 0, 159, 157, 1, 0, 0, 0, 159, 158, 1, 0, 0, 0, 160, 163, 1, 0, 0, 0, 161, 159, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 164, 1, 0, 0, 0, 163, 161, 1, 0, 0, 0, 164, 165, 5, 0, 0, 1, 165, 1, 1, 0, 0, 0, 166, 167, 3, 40, 20, 0, 167, 168, 5, 1, 0, 0, 168, 170, 1, 0, 0, 0, 169, 166, 1, 0, 0, 0, 169, 170, 1, 0, 0, 0, 170, 171, 1, 0, 0, 0, 171, 172, 3, 46, 23, 0, 172, 3, 1, 0, 0, 0, 173, 174, 5, 51, 0, 0, 174, 175, 3, 2, 1, 0, 175, 5, 1, 0, 0, 0, 176, 178, 3, 36, 18, 0, 177, 179, 3, 4, 2, 0, 178, 177, 1, 0, 0, 0, 178, 179, 1, 0, 0, 0, 179, 7, 1, 0, 0, 0, 180, 181, 5, 56, 0, 0, 181, 186, 3, 6, 3, 0, 182, 183, 5, 2, 0, 0, 183, 185, 3, 6, 3, 0, 184, 182, 1, 0, 0, 0, 185, 188, 1, 0, 0, 0, 186, 184, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 189, 1, 0, 0, 0, 188, 186, 1, 0, 0, 0, 189, 190, 5, 57, 0, 0, 190, 9, 1, 0, 0, 0, 191, 192, 5, 78, 0, 0, 192, 11, 1, 0, 0, 0, 193, 195, 5, 56, 0, 0, 194, 196, 3, 10, 5, 0, 195, 194, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 197, 1, 0, 0, 0, 197, 198, 5, 57, 0, 0, 198, 13, 1, 0, 0, 0, 199, 201, 3, 8, 4, 0, 200, 199, 1, 0, 0, 0, 201, 204, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, 203, 205, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 206, 3, 50, 25, 0, 206, 208, 3, 36, 18, 0, 207, 209, 3, 12, 6, 0, 208, 207, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 212, 1, 0, 0, 0, 210, 211, 5, 51, 0, 0, 211, 213, 3, 46, 23, 0, 212, 210, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 50, 0, 0, 215, 15, 1, 0, 0, 0, 216, 217, 5, 72, 0, 0, 217, 218, 3, 36, 18, 0, 218, 219, 5, 50, 0, 0, 219, 17, 1, 0, 0, 0, 220, 221, 5, 3, 0, 0, 221, 222, 3, 36, 18, 0, 222, 223, 5, 51, 0, 0, 223, 224, 3, 46, 23, 0, 224, 225, 5, 50, 0, 0, 225, 19, 1, 0, 0, 0, 226, 228, 3, 8, 4, 0, 227, 226, 1, 0, 0, 0, 228, 231, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 230, 232, 1, 0, 0, 0, 231, 229, 1, 0, 0, 0, 232, 233, 5, 4, 0, 0, 233, 236, 3, 36, 18, 0, 234, 235, 5, 51, 0, 0, 235, 237, 3, 82, 41, 0, 236, 234, 1, 0, 0, 0, 236, 237, 1, 0, 0, 0, 237, 238, 1, 0, 0, 0, 238, 239, 5, 50, 0, 0, 239, 21, 1, 0, 0, 0, 240, 242, 3, 8, 4, 0, 241, 240, 1, 0, 0, 0, 242, 245, 1, 0, 0, 0, 243, 244, 1, 0, 0, 0, 243, 241, 1, 0, 0, 0, 244, 246, 1, 0, 0, 0, 245, 243, 1, 0, 0, 0, 246, 247, 5, 5, 0, 0, 247, 248, 5, 51, 0, 0, 248, 249, 3, 82, 41, 0, 249, 250, 5, 50, 0, 0, 250, 23, 1, 0, 0, 0, 251, 253, 3, 8, 4, 0, 252, 251, 1, 0, 0, 0, 253, 256, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 255, 257, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 258, 5, 6, 0, 0, 258, 259, 5, 51, 0, 0, 259, 260, 3, 82, 41, 0, 260, 261, 5, 50, 0, 0, 261, 25, 1, 0, 0, 0, 262, 263, 5, 83, 0, 0, 263, 27, 1, 0, 0, 0, 264, 266, 3, 8, 4, 0, 265, 264, 1, 0, 0, 0, 266, 269, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 267, 265, 1, 0, 0, 0, 268, 270, 1, 0, 0, 0, 269, 267, 1, 0, 0, 0, 270, 271, 3, 142, 71, 0, 271, 272, 5, 51, 0, 0, 272, 273, 3, 46, 23, 0, 273, 274, 5, 50, 0, 0, 274, 29, 1, 0, 0, 0, 275, 276, 5, 77, 0, 0, 276, 31, 1, 0, 0, 0, 277, 286, 3, 30, 15, 0, 278, 282, 5, 41, 0, 0, 279, 281, 3, 42, 21, 0, 280, 279, 1, 0, 0, 0, 281, 284, 1, 0, 0, 0, 282, 280, 1, 0, 0, 0, 282, 283, 1, 0, 0, 0, 283, 285, 1, 0, 0, 0, 284, 282, 1, 0, 0, 0, 285, 287, 5, 40, 0, 0, 286, 278, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 289, 1, 0, 0, 0, 288, 290, 3, 26, 13, 0, 289, 288, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 33, 1, 0, 0, 0, 291, 292, 5, 77, 0, 0, 292, 35, 1, 0, 0, 0, 293, 294, 5, 77, 0, 0, 294, 37, 1, 0, 0, 0, 295, 296, 5, 77, 0, 0, 296, 39, 1, 0, 0, 0, 297, 298, 5, 77, 0, 0, 298, 41, 1, 0, 0, 0, 299, 300, 5, 77, 0, 0, 300, 43, 1, 0, 0, 0, 301, 302, 5, 77, 0, 0, 302, 304, 5, 52, 0, 0, 303, 305, 3, 48, 24, 0, 304, 303, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 310, 1, 0, 0, 0, 306, 307, 5, 2, 0, 0, 307, 309, 3, 48, 24, 0, 308, 306, 1, 0, 0, 0, 309, 312, 1, 0, 0, 0, 310, 308, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 313, 1, 0, 0, 0, 312, 310, 1, 0, 0, 0, 313, 314, 5, 53, 0, 0, 314, 45, 1, 0, 0, 0, 315, 323, 3, 140, 70, 0, 316, 323, 5, 77, 0, 0, 317, 323, 5, 78, 0, 0, 318, 323, 5, 79, 0, 0, 319, 323, 3, 144, 72, 0, 320, 323, 3, 44, 22, 0, 321, 323, 3, 82, 41, 0, 322, 315, 1, 0, 0, 0, 322, 316, 1, 0, 0, 0, 322, 317, 1, 0, 0, 0, 322, 318, 1, 0, 0, 0, 322, 319, 1, 0, 0, 0, 322, 320, 1, 0, 0, 0, 322, 321, 1, 0, 0, 0, 323, 47, 1, 0, 0, 0, 324, 329, 5, 77, 0, 0, 325, 329, 5, 78, 0, 0, 326, 329, 5, 79, 0, 0, 327, 329, 3, 144, 72, 0, 328, 324, 1, 0, 0, 0, 328, 325, 1, 0, 0, 0, 328, 326, 1, 0, 0, 0, 328, 327, 1, 0, 0, 0, 329, 49, 1, 0, 0, 0, 330, 331, 3, 32, 16, 0, 331, 51, 1, 0, 0, 0, 332, 333, 5, 86, 0, 0, 333, 53, 1, 0, 0, 0, 334, 335, 5, 77, 0, 0, 335, 337, 5, 46, 0, 0, 336, 334, 1, 0, 0, 0, 337, 340, 1, 0, 0, 0, 338, 339, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 339, 341, 1, 0, 0, 0, 340, 338, 1, 0, 0, 0, 341, 342, 5, 77, 0, 0, 342, 55, 1, 0, 0, 0, 343, 344, 5, 7, 0, 0, 344, 349, 3, 34, 17, 0, 345, 346, 5, 2, 0, 0, 346, 348, 3, 34, 17, 0, 347, 345, 1, 0, 0, 0, 348, 351, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 350, 57, 1, 0, 0, 0, 351, 349, 1, 0, 0, 0, 352, 356, 3, 16, 8, 0, 353, 356, 3, 18, 9, 0, 354, 356, 5, 81, 0, 0, 355, 352, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 355, 354, 1, 0, 0, 0, 356, 59, 1, 0, 0, 0, 357, 359, 3, 58, 29, 0, 358, 357, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 61, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 363, 364, 5, 61, 0, 0, 364, 366, 3, 36, 18, 0, 365, 367, 3, 56, 28, 0, 366, 365, 1, 0, 0, 0, 366, 367, 1, 0, 0, 0, 367, 368, 1, 0, 0, 0, 368, 369, 5, 54, 0, 0, 369, 370, 3, 60, 30, 0, 370, 371, 5, 55, 0, 0, 371, 63, 1, 0, 0, 0, 372, 376, 3, 14, 7, 0, 373, 376, 3, 52, 26, 0, 374, 376, 5, 81, 0, 0, 375, 372, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 375, 374, 1, 0, 0, 0, 376, 65, 1, 0, 0, 0, 377, 379, 3, 64, 32, 0, 378, 377, 1, 0, 0, 0, 379, 382, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 380, 381, 1, 0, 0, 0, 381, 67, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 383, 385, 3, 8, 4, 0, 384, 383, 1, 0, 0, 0, 385, 388, 1, 0, 0, 0, 386, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 389, 1, 0, 0, 0, 388, 386, 1, 0, 0, 0, 389, 390, 5, 62, 0, 0, 390, 392, 3, 36, 18, 0, 391, 393, 3, 56, 28, 0, 392, 391, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 394, 1, 0, 0, 0, 394, 395, 5, 54, 0, 0, 395, 396, 3, 66, 33, 0, 396, 397, 5, 55, 0, 0, 397, 69, 1, 0, 0, 0, 398, 399, 3, 50, 25, 0, 399, 400, 3, 36, 18, 0, 400, 401, 5, 50, 0, 0, 401, 71, 1, 0, 0, 0, 402, 403, 5, 75, 0, 0, 403, 404, 3, 36, 18, 0, 404, 405, 5, 50, 0, 0, 405, 73, 1, 0, 0, 0, 406, 410, 3, 70, 35, 0, 407, 410, 3, 72, 36, 0, 408, 410, 5, 81, 0, 0, 409, 406, 1, 0, 0, 0, 409, 407, 1, 0, 0, 0, 409, 408, 1, 0, 0, 0, 410, 75, 1, 0, 0, 0, 411, 413, 3, 74, 37, 0, 412, 411, 1, 0, 0, 0, 413, 416, 1, 0, 0, 0, 414, 412, 1, 0, 0, 0, 414, 415, 1, 0, 0, 0, 415, 77, 1, 0, 0, 0, 416, 414, 1, 0, 0, 0, 417, 418, 5, 73, 0, 0, 418, 419, 3, 36, 18, 0, 419, 420, 5, 54, 0, 0, 420, 421, 3, 76, 38, 0, 421, 422, 5, 55, 0, 0, 422, 79, 1, 0, 0, 0, 423, 424, 3, 46, 23, 0, 424, 81, 1, 0, 0, 0, 425, 426, 5, 54, 0, 0, 426, 431, 3, 80, 40, 0, 427, 428, 5, 2, 0, 0, 428, 430, 3, 80, 40, 0, 429, 427, 1, 0, 0, 0, 430, 433, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 434, 1, 0, 0, 0, 433, 431, 1, 0, 0, 0, 434, 435, 5, 55, 0, 0, 435, 83, 1, 0, 0, 0, 436, 437, 5, 76, 0, 0, 437, 438, 5, 51, 0, 0, 438, 439, 3, 36, 18, 0, 439, 440, 5, 50, 0, 0, 440, 85, 1, 0, 0, 0, 441, 443, 3, 8, 4, 0, 442, 441, 1, 0, 0, 0, 443, 446, 1, 0, 0, 0, 444, 445, 1, 0, 0, 0, 444, 442, 1, 0, 0, 0, 445, 447, 1, 0, 0, 0, 446, 444, 1, 0, 0, 0, 447, 448, 3, 140, 70, 0, 448, 449, 5, 51, 0, 0, 449, 450, 3, 54, 27, 0, 450, 451, 5, 50, 0, 0, 451, 87, 1, 0, 0, 0, 452, 457, 3, 84, 42, 0, 453, 457, 3, 86, 43, 0, 454, 457, 3, 20, 10, 0, 455, 457, 5, 81, 0, 0, 456, 452, 1, 0, 0, 0, 456, 453, 1, 0, 0, 0, 456, 454, 1, 0, 0, 0, 456, 455, 1, 0, 0, 0, 457, 89, 1, 0, 0, 0, 458, 460, 3, 88, 44, 0, 459, 458, 1, 0, 0, 0, 460, 463, 1, 0, 0, 0, 461, 459, 1, 0, 0, 0, 461, 462, 1, 0, 0, 0, 462, 91, 1, 0, 0, 0, 463, 461, 1, 0, 0, 0, 464, 465, 5, 63, 0, 0, 465, 467, 3, 36, 18, 0, 466, 468, 3, 56, 28, 0, 467, 466, 1, 0, 0, 0, 467, 468, 1, 0, 0, 0, 468, 469, 1, 0, 0, 0, 469, 470, 5, 54, 0, 0, 470, 471, 3, 90, 45, 0, 471, 472, 5, 55, 0, 0, 472, 93, 1, 0, 0, 0, 473, 481, 3, 84, 42, 0, 474, 481, 3, 86, 43, 0, 475, 481, 3, 20, 10, 0, 476, 481, 3, 22, 11, 0, 477, 481, 3, 24, 12, 0, 478, 481, 3, 28, 14, 0, 479, 481, 5, 81, 0, 0, 480, 473, 1, 0, 0, 0, 480, 474, 1, 0, 0, 0, 480, 475, 1, 0, 0, 0, 480, 476, 1, 0, 0, 0, 480, 477, 1, 0, 0, 0, 480, 478, 1, 0, 0, 0, 480, 479, 1, 0, 0, 0, 481, 95, 1, 0, 0, 0, 482, 484, 3, 94, 47, 0, 483, 482, 1, 0, 0, 0, 484, 487, 1, 0, 0, 0, 485, 483, 1, 0, 0, 0, 485, 486, 1, 0, 0, 0, 486, 97, 1, 0, 0, 0, 487, 485, 1, 0, 0, 0, 488, 490, 3, 8, 4, 0, 489, 488, 1, 0, 0, 0, 490, 493, 1, 0, 0, 0, 491, 492, 1, 0, 0, 0, 491, 489, 1, 0, 0, 0, 492, 494, 1, 0, 0, 0, 493, 491, 1, 0, 0, 0, 494, 495, 5, 64, 0, 0, 495, 497, 3, 36, 18, 0, 496, 498, 3, 56, 28, 0, 497, 496, 1, 0, 0, 0, 497, 498, 1, 0, 0, 0, 498, 499, 1, 0, 0, 0, 499, 500, 5, 54, 0, 0, 500, 501, 3, 96, 48, 0, 501, 502, 5, 55, 0, 0, 502, 99, 1, 0, 0, 0, 503, 506, 3, 84, 42, 0, 504, 506, 5, 81, 0, 0, 505, 503, 1, 0, 0, 0, 505, 504, 1, 0, 0, 0, 506, 101, 1, 0, 0, 0, 507, 509, 3, 100, 50, 0, 508, 507, 1, 0, 0, 0, 509, 512, 1, 0, 0, 0, 510, 508, 1, 0, 0, 0, 510, 511, 1, 0, 0, 0, 511, 103, 1, 0, 0, 0, 512, 510, 1, 0, 0, 0, 513, 514, 5, 65, 0, 0, 514, 516, 3, 36, 18, 0, 515, 517, 3, 56, 28, 0, 516, 515, 1, 0, 0, 0, 516, 517, 1, 0, 0, 0, 517, 518, 1, 0, 0, 0, 518, 519, 5, 54, 0, 0, 519, 520, 3, 102, 51, 0, 520, 521, 5, 55, 0, 0, 521, 105, 1, 0, 0, 0, 522, 527, 3, 84, 42, 0, 523, 527, 3, 86, 43, 0, 524, 527, 3, 20, 10, 0, 525, 527, 5, 81, 0, 0, 526, 522, 1, 0, 0, 0, 526, 523, 1, 0, 0, 0, 526, 524, 1, 0, 0, 0, 526, 525, 1, 0, 0, 0, 527, 107, 1, 0, 0, 0, 528, 530, 3, 106, 53, 0, 529, 528, 1, 0, 0, 0, 530, 533, 1, 0, 0, 0, 531, 529, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 109, 1, 0, 0, 0, 533, 531, 1, 0, 0, 0, 534, 535, 5, 66, 0, 0, 535, 537, 3, 36, 18, 0, 536, 538, 3, 56, 28, 0, 537, 536, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 539, 1, 0, 0, 0, 539, 540, 5, 54, 0, 0, 540, 541, 3, 108, 54, 0, 541, 542, 5, 55, 0, 0, 542, 111, 1, 0, 0, 0, 543, 547, 3, 86, 43, 0, 544, 547, 5, 81, 0, 0, 545, 547, 3, 28, 14, 0, 546, 543, 1, 0, 0, 0, 546, 544, 1, 0, 0, 0, 546, 545, 1, 0, 0, 0, 547, 113, 1, 0, 0, 0, 548, 550, 3, 112, 56, 0, 549, 548, 1, 0, 0, 0, 550, 553, 1, 0, 0, 0, 551, 549, 1, 0, 0, 0, 551, 552, 1, 0, 0, 0, 552, 115, 1, 0, 0, 0, 553, 551, 1, 0, 0, 0, 554, 556, 3, 8, 4, 0, 555, 554, 1, 0, 0, 0, 556, 559, 1, 0, 0, 0, 557, 558, 1, 0, 0, 0, 557, 555, 1, 0, 0, 0, 558, 560, 1, 0, 0, 0, 559, 557, 1, 0, 0, 0, 560, 561, 5, 68, 0, 0, 561, 563, 3, 36, 18, 0, 562, 564, 3, 56, 28, 0, 563, 562, 1, 0, 0, 0, 563, 564, 1, 0, 0, 0, 564, 565, 1, 0, 0, 0, 565, 566, 5, 54, 0, 0, 566, 567, 3, 114, 57, 0, 567, 568, 5, 55, 0, 0, 568, 117, 1, 0, 0, 0, 569, 572, 3, 86, 43, 0, 570, 572, 5, 81, 0, 0, 571, 569, 1, 0, 0, 0, 571, 570, 1, 0, 0, 0, 572, 119, 1, 0, 0, 0, 573, 575, 3, 118, 59, 0, 574, 573, 1, 0, 0, 0, 575, 578, 1, 0, 0, 0, 576, 574, 1, 0, 0, 0, 576, 577, 1, 0, 0, 0, 577, 121, 1, 0, 0, 0, 578, 576, 1, 0, 0, 0, 579, 581, 3, 8, 4, 0, 580, 579, 1, 0, 0, 0, 581, 584, 1, 0, 0, 0, 582, 583, 1, 0, 0, 0, 582, 580, 1, 0, 0, 0, 583, 585, 1, 0, 0, 0, 584, 582, 1, 0, 0, 0, 585, 586, 5, 67, 0, 0, 586, 588, 3, 36, 18, 0, 587, 589, 3, 56, 28, 0, 588, 587, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 590, 1, 0, 0, 0, 590, 591, 5, 54, 0, 0, 591, 592, 3, 120, 60, 0, 592, 593, 5, 55, 0, 0, 593, 123, 1, 0, 0, 0, 594, 596, 3, 8, 4, 0, 595, 594, 1, 0, 0, 0, 596, 599, 1, 0, 0, 0, 597, 598, 1, 0, 0, 0, 597, 595, 1, 0, 0, 0, 598, 600, 1, 0, 0, 0, 599, 597, 1, 0, 0, 0, 600, 601, 3, 50, 25, 0, 601, 602, 3, 36, 18, 0, 602, 603, 5, 50, 0, 0, 603, 125, 1, 0, 0, 0, 604, 607, 3, 124, 62, 0, 605, 607, 5, 81, 0, 0, 606, 604, 1, 0, 0, 0, 606, 605, 1, 0, 0, 0, 607, 127, 1, 0, 0, 0, 608, 610, 3, 126, 63, 0, 609, 608, 1, 0, 0, 0, 610, 613, 1, 0, 0, 0, 611, 609, 1, 0, 0, 0, 611, 612, 1, 0, 0, 0, 612, 129, 1, 0, 0, 0, 613, 611, 1, 0, 0, 0, 614, 616, 3, 8, 4, 0, 615, 614, 1, 0, 0, 0, 616, 619, 1, 0, 0, 0, 617, 618, 1, 0, 0, 0, 617, 615, 1, 0, 0, 0, 618, 620, 1, 0, 0, 0, 619, 617, 1, 0, 0, 0, 620, 621, 5, 70, 0, 0, 621, 623, 3, 36, 18, 0, 622, 624, 3, 56, 28, 0, 623, 622, 1, 0, 0, 0, 623, 624, 1, 0, 0, 0, 624, 625, 1, 0, 0, 0, 625, 626, 5, 54, 0, 0, 626, 627, 3, 128, 64, 0, 627, 628, 5, 55, 0, 0, 628, 131, 1, 0, 0, 0, 629, 631, 3, 8, 4, 0, 630, 629, 1, 0, 0, 0, 631, 634, 1, 0, 0, 0, 632, 633, 1, 0, 0, 0, 632, 630, 1, 0, 0, 0, 633, 635, 1, 0, 0, 0, 634, 632, 1, 0, 0, 0, 635, 636, 5, 69, 0, 0, 636, 638, 3, 36, 18, 0, 637, 639, 3, 56, 28, 0, 638, 637, 1, 0, 0, 0, 638, 639, 1, 0, 0, 0, 639, 640, 1, 0, 0, 0, 640, 641, 5, 54, 0, 0, 641, 642, 3, 128, 64, 0, 642, 643, 5, 55, 0, 0, 643, 133, 1, 0, 0, 0, 644, 645, 3, 36, 18, 0, 645, 646, 5, 50, 0, 0, 646, 649, 1, 0, 0, 0, 647, 649, 5, 81, 0, 0, 648, 644, 1, 0, 0, 0, 648, 647, 1, 0, 0, 0, 649, 135, 1, 0, 0, 0, 650, 652, 3, 134, 67, 0, 651, 650, 1, 0, 0, 0, 652, 655, 1, 0, 0, 0, 653, 651, 1, 0, 0, 0, 653, 654, 1, 0, 0, 0, 654, 137, 1, 0, 0, 0, 655, 653, 1, 0, 0, 0, 656, 657, 5, 71, 0, 0, 657, 658, 3, 36, 18, 0, 658, 659, 5, 54, 0, 0, 659, 660, 3, 136, 68, 0, 660, 661, 5, 55, 0, 0, 661, 139, 1, 0, 0, 0, 662, 663, 7, 0, 0, 0, 663, 141, 1, 0, 0, 0, 664, 665, 7, 1, 0, 0, 665, 143, 1, 0, 0, 0, 666, 667, 7, 2, 0, 0, 667, 145, 1, 0, 0, 0, 64, 159, 161, 169, 178, 186, 195, 202, 208, 212, 229, 236, 243, 254, 267, 282, 286, 289, 304, 310, 322, 328, 338, 349, 355, 360, 366, 375, 380, 386, 392, 409, 414, 431, 444, 456, 461, 467, 480, 485, 491, 497, 505, 510, 516, 526, 531, 537, 546, 551, 557, 563, 571, 576, 582, 588, 597, 606, 611, 617, 623, 632, 638, 648, 653] \ No newline at end of file +[4, 1, 86, 681, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 160, 8, 0, 10, 0, 12, 0, 163, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 170, 8, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 3, 3, 179, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 185, 8, 4, 10, 4, 12, 4, 188, 9, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 3, 6, 196, 8, 6, 1, 6, 1, 6, 1, 7, 5, 7, 201, 8, 7, 10, 7, 12, 7, 204, 9, 7, 1, 7, 1, 7, 1, 7, 3, 7, 209, 8, 7, 1, 7, 1, 7, 3, 7, 213, 8, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 5, 10, 228, 8, 10, 10, 10, 12, 10, 231, 9, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 237, 8, 10, 1, 10, 1, 10, 1, 11, 5, 11, 242, 8, 11, 10, 11, 12, 11, 245, 9, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 5, 12, 253, 8, 12, 10, 12, 12, 12, 256, 9, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 5, 14, 266, 8, 14, 10, 14, 12, 14, 269, 9, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 5, 16, 281, 8, 16, 10, 16, 12, 16, 284, 9, 16, 1, 16, 3, 16, 287, 8, 16, 1, 16, 3, 16, 290, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 3, 22, 305, 8, 22, 1, 22, 1, 22, 5, 22, 309, 8, 22, 10, 22, 12, 22, 312, 9, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 323, 8, 23, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 329, 8, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 5, 27, 337, 8, 27, 10, 27, 12, 27, 340, 9, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 5, 28, 348, 8, 28, 10, 28, 12, 28, 351, 9, 28, 1, 29, 1, 29, 1, 29, 3, 29, 356, 8, 29, 1, 30, 5, 30, 359, 8, 30, 10, 30, 12, 30, 362, 9, 30, 1, 31, 1, 31, 1, 31, 3, 31, 367, 8, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 3, 32, 376, 8, 32, 1, 33, 5, 33, 379, 8, 33, 10, 33, 12, 33, 382, 9, 33, 1, 34, 5, 34, 385, 8, 34, 10, 34, 12, 34, 388, 9, 34, 1, 34, 1, 34, 1, 34, 3, 34, 393, 8, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 3, 37, 410, 8, 37, 1, 38, 5, 38, 413, 8, 38, 10, 38, 12, 38, 416, 9, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 5, 41, 430, 8, 41, 10, 41, 12, 41, 433, 9, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 5, 43, 443, 8, 43, 10, 43, 12, 43, 446, 9, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 457, 8, 44, 1, 45, 5, 45, 460, 8, 45, 10, 45, 12, 45, 463, 9, 45, 1, 46, 5, 46, 466, 8, 46, 10, 46, 12, 46, 469, 9, 46, 1, 46, 1, 46, 1, 46, 3, 46, 474, 8, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 3, 47, 487, 8, 47, 1, 48, 5, 48, 490, 8, 48, 10, 48, 12, 48, 493, 9, 48, 1, 49, 5, 49, 496, 8, 49, 10, 49, 12, 49, 499, 9, 49, 1, 49, 1, 49, 1, 49, 3, 49, 504, 8, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 3, 50, 512, 8, 50, 1, 51, 5, 51, 515, 8, 51, 10, 51, 12, 51, 518, 9, 51, 1, 52, 1, 52, 1, 52, 3, 52, 523, 8, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 533, 8, 53, 1, 54, 5, 54, 536, 8, 54, 10, 54, 12, 54, 539, 9, 54, 1, 55, 5, 55, 542, 8, 55, 10, 55, 12, 55, 545, 9, 55, 1, 55, 1, 55, 1, 55, 3, 55, 550, 8, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 3, 56, 559, 8, 56, 1, 57, 5, 57, 562, 8, 57, 10, 57, 12, 57, 565, 9, 57, 1, 58, 5, 58, 568, 8, 58, 10, 58, 12, 58, 571, 9, 58, 1, 58, 1, 58, 1, 58, 3, 58, 576, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 3, 59, 584, 8, 59, 1, 60, 5, 60, 587, 8, 60, 10, 60, 12, 60, 590, 9, 60, 1, 61, 5, 61, 593, 8, 61, 10, 61, 12, 61, 596, 9, 61, 1, 61, 1, 61, 1, 61, 3, 61, 601, 8, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 5, 62, 608, 8, 62, 10, 62, 12, 62, 611, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 3, 63, 619, 8, 63, 1, 64, 5, 64, 622, 8, 64, 10, 64, 12, 64, 625, 9, 64, 1, 65, 5, 65, 628, 8, 65, 10, 65, 12, 65, 631, 9, 65, 1, 65, 1, 65, 1, 65, 3, 65, 636, 8, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 5, 66, 643, 8, 66, 10, 66, 12, 66, 646, 9, 66, 1, 66, 1, 66, 1, 66, 3, 66, 651, 8, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 661, 8, 67, 1, 68, 5, 68, 664, 8, 68, 10, 68, 12, 68, 667, 9, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 17, 202, 229, 243, 254, 267, 338, 349, 386, 444, 467, 497, 543, 569, 594, 609, 629, 644, 0, 73, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 0, 3, 1, 0, 8, 19, 1, 0, 20, 35, 1, 0, 58, 59, 704, 0, 161, 1, 0, 0, 0, 2, 169, 1, 0, 0, 0, 4, 173, 1, 0, 0, 0, 6, 176, 1, 0, 0, 0, 8, 180, 1, 0, 0, 0, 10, 191, 1, 0, 0, 0, 12, 193, 1, 0, 0, 0, 14, 202, 1, 0, 0, 0, 16, 216, 1, 0, 0, 0, 18, 220, 1, 0, 0, 0, 20, 229, 1, 0, 0, 0, 22, 243, 1, 0, 0, 0, 24, 254, 1, 0, 0, 0, 26, 262, 1, 0, 0, 0, 28, 267, 1, 0, 0, 0, 30, 275, 1, 0, 0, 0, 32, 277, 1, 0, 0, 0, 34, 291, 1, 0, 0, 0, 36, 293, 1, 0, 0, 0, 38, 295, 1, 0, 0, 0, 40, 297, 1, 0, 0, 0, 42, 299, 1, 0, 0, 0, 44, 301, 1, 0, 0, 0, 46, 322, 1, 0, 0, 0, 48, 328, 1, 0, 0, 0, 50, 330, 1, 0, 0, 0, 52, 332, 1, 0, 0, 0, 54, 338, 1, 0, 0, 0, 56, 343, 1, 0, 0, 0, 58, 355, 1, 0, 0, 0, 60, 360, 1, 0, 0, 0, 62, 363, 1, 0, 0, 0, 64, 375, 1, 0, 0, 0, 66, 380, 1, 0, 0, 0, 68, 386, 1, 0, 0, 0, 70, 398, 1, 0, 0, 0, 72, 402, 1, 0, 0, 0, 74, 409, 1, 0, 0, 0, 76, 414, 1, 0, 0, 0, 78, 417, 1, 0, 0, 0, 80, 423, 1, 0, 0, 0, 82, 425, 1, 0, 0, 0, 84, 436, 1, 0, 0, 0, 86, 444, 1, 0, 0, 0, 88, 456, 1, 0, 0, 0, 90, 461, 1, 0, 0, 0, 92, 467, 1, 0, 0, 0, 94, 486, 1, 0, 0, 0, 96, 491, 1, 0, 0, 0, 98, 497, 1, 0, 0, 0, 100, 511, 1, 0, 0, 0, 102, 516, 1, 0, 0, 0, 104, 519, 1, 0, 0, 0, 106, 532, 1, 0, 0, 0, 108, 537, 1, 0, 0, 0, 110, 543, 1, 0, 0, 0, 112, 558, 1, 0, 0, 0, 114, 563, 1, 0, 0, 0, 116, 569, 1, 0, 0, 0, 118, 583, 1, 0, 0, 0, 120, 588, 1, 0, 0, 0, 122, 594, 1, 0, 0, 0, 124, 609, 1, 0, 0, 0, 126, 618, 1, 0, 0, 0, 128, 623, 1, 0, 0, 0, 130, 629, 1, 0, 0, 0, 132, 644, 1, 0, 0, 0, 134, 660, 1, 0, 0, 0, 136, 665, 1, 0, 0, 0, 138, 668, 1, 0, 0, 0, 140, 674, 1, 0, 0, 0, 142, 676, 1, 0, 0, 0, 144, 678, 1, 0, 0, 0, 146, 160, 3, 62, 31, 0, 147, 160, 3, 68, 34, 0, 148, 160, 3, 78, 39, 0, 149, 160, 3, 110, 55, 0, 150, 160, 3, 92, 46, 0, 151, 160, 3, 98, 49, 0, 152, 160, 3, 104, 52, 0, 153, 160, 3, 116, 58, 0, 154, 160, 3, 122, 61, 0, 155, 160, 3, 132, 66, 0, 156, 160, 3, 130, 65, 0, 157, 160, 3, 138, 69, 0, 158, 160, 5, 81, 0, 0, 159, 146, 1, 0, 0, 0, 159, 147, 1, 0, 0, 0, 159, 148, 1, 0, 0, 0, 159, 149, 1, 0, 0, 0, 159, 150, 1, 0, 0, 0, 159, 151, 1, 0, 0, 0, 159, 152, 1, 0, 0, 0, 159, 153, 1, 0, 0, 0, 159, 154, 1, 0, 0, 0, 159, 155, 1, 0, 0, 0, 159, 156, 1, 0, 0, 0, 159, 157, 1, 0, 0, 0, 159, 158, 1, 0, 0, 0, 160, 163, 1, 0, 0, 0, 161, 159, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 164, 1, 0, 0, 0, 163, 161, 1, 0, 0, 0, 164, 165, 5, 0, 0, 1, 165, 1, 1, 0, 0, 0, 166, 167, 3, 40, 20, 0, 167, 168, 5, 1, 0, 0, 168, 170, 1, 0, 0, 0, 169, 166, 1, 0, 0, 0, 169, 170, 1, 0, 0, 0, 170, 171, 1, 0, 0, 0, 171, 172, 3, 46, 23, 0, 172, 3, 1, 0, 0, 0, 173, 174, 5, 51, 0, 0, 174, 175, 3, 2, 1, 0, 175, 5, 1, 0, 0, 0, 176, 178, 3, 36, 18, 0, 177, 179, 3, 4, 2, 0, 178, 177, 1, 0, 0, 0, 178, 179, 1, 0, 0, 0, 179, 7, 1, 0, 0, 0, 180, 181, 5, 56, 0, 0, 181, 186, 3, 6, 3, 0, 182, 183, 5, 2, 0, 0, 183, 185, 3, 6, 3, 0, 184, 182, 1, 0, 0, 0, 185, 188, 1, 0, 0, 0, 186, 184, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 189, 1, 0, 0, 0, 188, 186, 1, 0, 0, 0, 189, 190, 5, 57, 0, 0, 190, 9, 1, 0, 0, 0, 191, 192, 5, 78, 0, 0, 192, 11, 1, 0, 0, 0, 193, 195, 5, 56, 0, 0, 194, 196, 3, 10, 5, 0, 195, 194, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 197, 1, 0, 0, 0, 197, 198, 5, 57, 0, 0, 198, 13, 1, 0, 0, 0, 199, 201, 3, 8, 4, 0, 200, 199, 1, 0, 0, 0, 201, 204, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, 203, 205, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 206, 3, 50, 25, 0, 206, 208, 3, 36, 18, 0, 207, 209, 3, 12, 6, 0, 208, 207, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 212, 1, 0, 0, 0, 210, 211, 5, 51, 0, 0, 211, 213, 3, 46, 23, 0, 212, 210, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 50, 0, 0, 215, 15, 1, 0, 0, 0, 216, 217, 5, 72, 0, 0, 217, 218, 3, 36, 18, 0, 218, 219, 5, 50, 0, 0, 219, 17, 1, 0, 0, 0, 220, 221, 5, 3, 0, 0, 221, 222, 3, 36, 18, 0, 222, 223, 5, 51, 0, 0, 223, 224, 3, 46, 23, 0, 224, 225, 5, 50, 0, 0, 225, 19, 1, 0, 0, 0, 226, 228, 3, 8, 4, 0, 227, 226, 1, 0, 0, 0, 228, 231, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 230, 232, 1, 0, 0, 0, 231, 229, 1, 0, 0, 0, 232, 233, 5, 4, 0, 0, 233, 236, 3, 36, 18, 0, 234, 235, 5, 51, 0, 0, 235, 237, 3, 82, 41, 0, 236, 234, 1, 0, 0, 0, 236, 237, 1, 0, 0, 0, 237, 238, 1, 0, 0, 0, 238, 239, 5, 50, 0, 0, 239, 21, 1, 0, 0, 0, 240, 242, 3, 8, 4, 0, 241, 240, 1, 0, 0, 0, 242, 245, 1, 0, 0, 0, 243, 244, 1, 0, 0, 0, 243, 241, 1, 0, 0, 0, 244, 246, 1, 0, 0, 0, 245, 243, 1, 0, 0, 0, 246, 247, 5, 5, 0, 0, 247, 248, 5, 51, 0, 0, 248, 249, 3, 82, 41, 0, 249, 250, 5, 50, 0, 0, 250, 23, 1, 0, 0, 0, 251, 253, 3, 8, 4, 0, 252, 251, 1, 0, 0, 0, 253, 256, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 255, 257, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 258, 5, 6, 0, 0, 258, 259, 5, 51, 0, 0, 259, 260, 3, 82, 41, 0, 260, 261, 5, 50, 0, 0, 261, 25, 1, 0, 0, 0, 262, 263, 5, 83, 0, 0, 263, 27, 1, 0, 0, 0, 264, 266, 3, 8, 4, 0, 265, 264, 1, 0, 0, 0, 266, 269, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 267, 265, 1, 0, 0, 0, 268, 270, 1, 0, 0, 0, 269, 267, 1, 0, 0, 0, 270, 271, 3, 142, 71, 0, 271, 272, 5, 51, 0, 0, 272, 273, 3, 46, 23, 0, 273, 274, 5, 50, 0, 0, 274, 29, 1, 0, 0, 0, 275, 276, 5, 77, 0, 0, 276, 31, 1, 0, 0, 0, 277, 286, 3, 30, 15, 0, 278, 282, 5, 41, 0, 0, 279, 281, 3, 42, 21, 0, 280, 279, 1, 0, 0, 0, 281, 284, 1, 0, 0, 0, 282, 280, 1, 0, 0, 0, 282, 283, 1, 0, 0, 0, 283, 285, 1, 0, 0, 0, 284, 282, 1, 0, 0, 0, 285, 287, 5, 40, 0, 0, 286, 278, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 289, 1, 0, 0, 0, 288, 290, 3, 26, 13, 0, 289, 288, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 33, 1, 0, 0, 0, 291, 292, 5, 77, 0, 0, 292, 35, 1, 0, 0, 0, 293, 294, 5, 77, 0, 0, 294, 37, 1, 0, 0, 0, 295, 296, 5, 77, 0, 0, 296, 39, 1, 0, 0, 0, 297, 298, 5, 77, 0, 0, 298, 41, 1, 0, 0, 0, 299, 300, 5, 77, 0, 0, 300, 43, 1, 0, 0, 0, 301, 302, 5, 77, 0, 0, 302, 304, 5, 52, 0, 0, 303, 305, 3, 48, 24, 0, 304, 303, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 310, 1, 0, 0, 0, 306, 307, 5, 2, 0, 0, 307, 309, 3, 48, 24, 0, 308, 306, 1, 0, 0, 0, 309, 312, 1, 0, 0, 0, 310, 308, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 313, 1, 0, 0, 0, 312, 310, 1, 0, 0, 0, 313, 314, 5, 53, 0, 0, 314, 45, 1, 0, 0, 0, 315, 323, 3, 140, 70, 0, 316, 323, 5, 77, 0, 0, 317, 323, 5, 78, 0, 0, 318, 323, 5, 79, 0, 0, 319, 323, 3, 144, 72, 0, 320, 323, 3, 44, 22, 0, 321, 323, 3, 82, 41, 0, 322, 315, 1, 0, 0, 0, 322, 316, 1, 0, 0, 0, 322, 317, 1, 0, 0, 0, 322, 318, 1, 0, 0, 0, 322, 319, 1, 0, 0, 0, 322, 320, 1, 0, 0, 0, 322, 321, 1, 0, 0, 0, 323, 47, 1, 0, 0, 0, 324, 329, 5, 77, 0, 0, 325, 329, 5, 78, 0, 0, 326, 329, 5, 79, 0, 0, 327, 329, 3, 144, 72, 0, 328, 324, 1, 0, 0, 0, 328, 325, 1, 0, 0, 0, 328, 326, 1, 0, 0, 0, 328, 327, 1, 0, 0, 0, 329, 49, 1, 0, 0, 0, 330, 331, 3, 32, 16, 0, 331, 51, 1, 0, 0, 0, 332, 333, 5, 86, 0, 0, 333, 53, 1, 0, 0, 0, 334, 335, 5, 77, 0, 0, 335, 337, 5, 46, 0, 0, 336, 334, 1, 0, 0, 0, 337, 340, 1, 0, 0, 0, 338, 339, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 339, 341, 1, 0, 0, 0, 340, 338, 1, 0, 0, 0, 341, 342, 5, 77, 0, 0, 342, 55, 1, 0, 0, 0, 343, 344, 5, 7, 0, 0, 344, 349, 3, 34, 17, 0, 345, 346, 5, 2, 0, 0, 346, 348, 3, 34, 17, 0, 347, 345, 1, 0, 0, 0, 348, 351, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 350, 57, 1, 0, 0, 0, 351, 349, 1, 0, 0, 0, 352, 356, 3, 16, 8, 0, 353, 356, 3, 18, 9, 0, 354, 356, 5, 81, 0, 0, 355, 352, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 355, 354, 1, 0, 0, 0, 356, 59, 1, 0, 0, 0, 357, 359, 3, 58, 29, 0, 358, 357, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 61, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 363, 364, 5, 61, 0, 0, 364, 366, 3, 36, 18, 0, 365, 367, 3, 56, 28, 0, 366, 365, 1, 0, 0, 0, 366, 367, 1, 0, 0, 0, 367, 368, 1, 0, 0, 0, 368, 369, 5, 54, 0, 0, 369, 370, 3, 60, 30, 0, 370, 371, 5, 55, 0, 0, 371, 63, 1, 0, 0, 0, 372, 376, 3, 14, 7, 0, 373, 376, 3, 52, 26, 0, 374, 376, 5, 81, 0, 0, 375, 372, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 375, 374, 1, 0, 0, 0, 376, 65, 1, 0, 0, 0, 377, 379, 3, 64, 32, 0, 378, 377, 1, 0, 0, 0, 379, 382, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 380, 381, 1, 0, 0, 0, 381, 67, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 383, 385, 3, 8, 4, 0, 384, 383, 1, 0, 0, 0, 385, 388, 1, 0, 0, 0, 386, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 389, 1, 0, 0, 0, 388, 386, 1, 0, 0, 0, 389, 390, 5, 62, 0, 0, 390, 392, 3, 36, 18, 0, 391, 393, 3, 56, 28, 0, 392, 391, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 394, 1, 0, 0, 0, 394, 395, 5, 54, 0, 0, 395, 396, 3, 66, 33, 0, 396, 397, 5, 55, 0, 0, 397, 69, 1, 0, 0, 0, 398, 399, 3, 50, 25, 0, 399, 400, 3, 36, 18, 0, 400, 401, 5, 50, 0, 0, 401, 71, 1, 0, 0, 0, 402, 403, 5, 75, 0, 0, 403, 404, 3, 36, 18, 0, 404, 405, 5, 50, 0, 0, 405, 73, 1, 0, 0, 0, 406, 410, 3, 70, 35, 0, 407, 410, 3, 72, 36, 0, 408, 410, 5, 81, 0, 0, 409, 406, 1, 0, 0, 0, 409, 407, 1, 0, 0, 0, 409, 408, 1, 0, 0, 0, 410, 75, 1, 0, 0, 0, 411, 413, 3, 74, 37, 0, 412, 411, 1, 0, 0, 0, 413, 416, 1, 0, 0, 0, 414, 412, 1, 0, 0, 0, 414, 415, 1, 0, 0, 0, 415, 77, 1, 0, 0, 0, 416, 414, 1, 0, 0, 0, 417, 418, 5, 73, 0, 0, 418, 419, 3, 36, 18, 0, 419, 420, 5, 54, 0, 0, 420, 421, 3, 76, 38, 0, 421, 422, 5, 55, 0, 0, 422, 79, 1, 0, 0, 0, 423, 424, 3, 46, 23, 0, 424, 81, 1, 0, 0, 0, 425, 426, 5, 54, 0, 0, 426, 431, 3, 80, 40, 0, 427, 428, 5, 2, 0, 0, 428, 430, 3, 80, 40, 0, 429, 427, 1, 0, 0, 0, 430, 433, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 434, 1, 0, 0, 0, 433, 431, 1, 0, 0, 0, 434, 435, 5, 55, 0, 0, 435, 83, 1, 0, 0, 0, 436, 437, 5, 76, 0, 0, 437, 438, 5, 51, 0, 0, 438, 439, 3, 36, 18, 0, 439, 440, 5, 50, 0, 0, 440, 85, 1, 0, 0, 0, 441, 443, 3, 8, 4, 0, 442, 441, 1, 0, 0, 0, 443, 446, 1, 0, 0, 0, 444, 445, 1, 0, 0, 0, 444, 442, 1, 0, 0, 0, 445, 447, 1, 0, 0, 0, 446, 444, 1, 0, 0, 0, 447, 448, 3, 140, 70, 0, 448, 449, 5, 51, 0, 0, 449, 450, 3, 54, 27, 0, 450, 451, 5, 50, 0, 0, 451, 87, 1, 0, 0, 0, 452, 457, 3, 84, 42, 0, 453, 457, 3, 86, 43, 0, 454, 457, 3, 20, 10, 0, 455, 457, 5, 81, 0, 0, 456, 452, 1, 0, 0, 0, 456, 453, 1, 0, 0, 0, 456, 454, 1, 0, 0, 0, 456, 455, 1, 0, 0, 0, 457, 89, 1, 0, 0, 0, 458, 460, 3, 88, 44, 0, 459, 458, 1, 0, 0, 0, 460, 463, 1, 0, 0, 0, 461, 459, 1, 0, 0, 0, 461, 462, 1, 0, 0, 0, 462, 91, 1, 0, 0, 0, 463, 461, 1, 0, 0, 0, 464, 466, 3, 8, 4, 0, 465, 464, 1, 0, 0, 0, 466, 469, 1, 0, 0, 0, 467, 468, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 468, 470, 1, 0, 0, 0, 469, 467, 1, 0, 0, 0, 470, 471, 5, 63, 0, 0, 471, 473, 3, 36, 18, 0, 472, 474, 3, 56, 28, 0, 473, 472, 1, 0, 0, 0, 473, 474, 1, 0, 0, 0, 474, 475, 1, 0, 0, 0, 475, 476, 5, 54, 0, 0, 476, 477, 3, 90, 45, 0, 477, 478, 5, 55, 0, 0, 478, 93, 1, 0, 0, 0, 479, 487, 3, 84, 42, 0, 480, 487, 3, 86, 43, 0, 481, 487, 3, 20, 10, 0, 482, 487, 3, 22, 11, 0, 483, 487, 3, 24, 12, 0, 484, 487, 3, 28, 14, 0, 485, 487, 5, 81, 0, 0, 486, 479, 1, 0, 0, 0, 486, 480, 1, 0, 0, 0, 486, 481, 1, 0, 0, 0, 486, 482, 1, 0, 0, 0, 486, 483, 1, 0, 0, 0, 486, 484, 1, 0, 0, 0, 486, 485, 1, 0, 0, 0, 487, 95, 1, 0, 0, 0, 488, 490, 3, 94, 47, 0, 489, 488, 1, 0, 0, 0, 490, 493, 1, 0, 0, 0, 491, 489, 1, 0, 0, 0, 491, 492, 1, 0, 0, 0, 492, 97, 1, 0, 0, 0, 493, 491, 1, 0, 0, 0, 494, 496, 3, 8, 4, 0, 495, 494, 1, 0, 0, 0, 496, 499, 1, 0, 0, 0, 497, 498, 1, 0, 0, 0, 497, 495, 1, 0, 0, 0, 498, 500, 1, 0, 0, 0, 499, 497, 1, 0, 0, 0, 500, 501, 5, 64, 0, 0, 501, 503, 3, 36, 18, 0, 502, 504, 3, 56, 28, 0, 503, 502, 1, 0, 0, 0, 503, 504, 1, 0, 0, 0, 504, 505, 1, 0, 0, 0, 505, 506, 5, 54, 0, 0, 506, 507, 3, 96, 48, 0, 507, 508, 5, 55, 0, 0, 508, 99, 1, 0, 0, 0, 509, 512, 3, 84, 42, 0, 510, 512, 5, 81, 0, 0, 511, 509, 1, 0, 0, 0, 511, 510, 1, 0, 0, 0, 512, 101, 1, 0, 0, 0, 513, 515, 3, 100, 50, 0, 514, 513, 1, 0, 0, 0, 515, 518, 1, 0, 0, 0, 516, 514, 1, 0, 0, 0, 516, 517, 1, 0, 0, 0, 517, 103, 1, 0, 0, 0, 518, 516, 1, 0, 0, 0, 519, 520, 5, 65, 0, 0, 520, 522, 3, 36, 18, 0, 521, 523, 3, 56, 28, 0, 522, 521, 1, 0, 0, 0, 522, 523, 1, 0, 0, 0, 523, 524, 1, 0, 0, 0, 524, 525, 5, 54, 0, 0, 525, 526, 3, 102, 51, 0, 526, 527, 5, 55, 0, 0, 527, 105, 1, 0, 0, 0, 528, 533, 3, 84, 42, 0, 529, 533, 3, 86, 43, 0, 530, 533, 3, 20, 10, 0, 531, 533, 5, 81, 0, 0, 532, 528, 1, 0, 0, 0, 532, 529, 1, 0, 0, 0, 532, 530, 1, 0, 0, 0, 532, 531, 1, 0, 0, 0, 533, 107, 1, 0, 0, 0, 534, 536, 3, 106, 53, 0, 535, 534, 1, 0, 0, 0, 536, 539, 1, 0, 0, 0, 537, 535, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 109, 1, 0, 0, 0, 539, 537, 1, 0, 0, 0, 540, 542, 3, 8, 4, 0, 541, 540, 1, 0, 0, 0, 542, 545, 1, 0, 0, 0, 543, 544, 1, 0, 0, 0, 543, 541, 1, 0, 0, 0, 544, 546, 1, 0, 0, 0, 545, 543, 1, 0, 0, 0, 546, 547, 5, 66, 0, 0, 547, 549, 3, 36, 18, 0, 548, 550, 3, 56, 28, 0, 549, 548, 1, 0, 0, 0, 549, 550, 1, 0, 0, 0, 550, 551, 1, 0, 0, 0, 551, 552, 5, 54, 0, 0, 552, 553, 3, 108, 54, 0, 553, 554, 5, 55, 0, 0, 554, 111, 1, 0, 0, 0, 555, 559, 3, 86, 43, 0, 556, 559, 5, 81, 0, 0, 557, 559, 3, 28, 14, 0, 558, 555, 1, 0, 0, 0, 558, 556, 1, 0, 0, 0, 558, 557, 1, 0, 0, 0, 559, 113, 1, 0, 0, 0, 560, 562, 3, 112, 56, 0, 561, 560, 1, 0, 0, 0, 562, 565, 1, 0, 0, 0, 563, 561, 1, 0, 0, 0, 563, 564, 1, 0, 0, 0, 564, 115, 1, 0, 0, 0, 565, 563, 1, 0, 0, 0, 566, 568, 3, 8, 4, 0, 567, 566, 1, 0, 0, 0, 568, 571, 1, 0, 0, 0, 569, 570, 1, 0, 0, 0, 569, 567, 1, 0, 0, 0, 570, 572, 1, 0, 0, 0, 571, 569, 1, 0, 0, 0, 572, 573, 5, 68, 0, 0, 573, 575, 3, 36, 18, 0, 574, 576, 3, 56, 28, 0, 575, 574, 1, 0, 0, 0, 575, 576, 1, 0, 0, 0, 576, 577, 1, 0, 0, 0, 577, 578, 5, 54, 0, 0, 578, 579, 3, 114, 57, 0, 579, 580, 5, 55, 0, 0, 580, 117, 1, 0, 0, 0, 581, 584, 3, 86, 43, 0, 582, 584, 5, 81, 0, 0, 583, 581, 1, 0, 0, 0, 583, 582, 1, 0, 0, 0, 584, 119, 1, 0, 0, 0, 585, 587, 3, 118, 59, 0, 586, 585, 1, 0, 0, 0, 587, 590, 1, 0, 0, 0, 588, 586, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 121, 1, 0, 0, 0, 590, 588, 1, 0, 0, 0, 591, 593, 3, 8, 4, 0, 592, 591, 1, 0, 0, 0, 593, 596, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 594, 592, 1, 0, 0, 0, 595, 597, 1, 0, 0, 0, 596, 594, 1, 0, 0, 0, 597, 598, 5, 67, 0, 0, 598, 600, 3, 36, 18, 0, 599, 601, 3, 56, 28, 0, 600, 599, 1, 0, 0, 0, 600, 601, 1, 0, 0, 0, 601, 602, 1, 0, 0, 0, 602, 603, 5, 54, 0, 0, 603, 604, 3, 120, 60, 0, 604, 605, 5, 55, 0, 0, 605, 123, 1, 0, 0, 0, 606, 608, 3, 8, 4, 0, 607, 606, 1, 0, 0, 0, 608, 611, 1, 0, 0, 0, 609, 610, 1, 0, 0, 0, 609, 607, 1, 0, 0, 0, 610, 612, 1, 0, 0, 0, 611, 609, 1, 0, 0, 0, 612, 613, 3, 50, 25, 0, 613, 614, 3, 36, 18, 0, 614, 615, 5, 50, 0, 0, 615, 125, 1, 0, 0, 0, 616, 619, 3, 124, 62, 0, 617, 619, 5, 81, 0, 0, 618, 616, 1, 0, 0, 0, 618, 617, 1, 0, 0, 0, 619, 127, 1, 0, 0, 0, 620, 622, 3, 126, 63, 0, 621, 620, 1, 0, 0, 0, 622, 625, 1, 0, 0, 0, 623, 621, 1, 0, 0, 0, 623, 624, 1, 0, 0, 0, 624, 129, 1, 0, 0, 0, 625, 623, 1, 0, 0, 0, 626, 628, 3, 8, 4, 0, 627, 626, 1, 0, 0, 0, 628, 631, 1, 0, 0, 0, 629, 630, 1, 0, 0, 0, 629, 627, 1, 0, 0, 0, 630, 632, 1, 0, 0, 0, 631, 629, 1, 0, 0, 0, 632, 633, 5, 70, 0, 0, 633, 635, 3, 36, 18, 0, 634, 636, 3, 56, 28, 0, 635, 634, 1, 0, 0, 0, 635, 636, 1, 0, 0, 0, 636, 637, 1, 0, 0, 0, 637, 638, 5, 54, 0, 0, 638, 639, 3, 128, 64, 0, 639, 640, 5, 55, 0, 0, 640, 131, 1, 0, 0, 0, 641, 643, 3, 8, 4, 0, 642, 641, 1, 0, 0, 0, 643, 646, 1, 0, 0, 0, 644, 645, 1, 0, 0, 0, 644, 642, 1, 0, 0, 0, 645, 647, 1, 0, 0, 0, 646, 644, 1, 0, 0, 0, 647, 648, 5, 69, 0, 0, 648, 650, 3, 36, 18, 0, 649, 651, 3, 56, 28, 0, 650, 649, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 652, 1, 0, 0, 0, 652, 653, 5, 54, 0, 0, 653, 654, 3, 128, 64, 0, 654, 655, 5, 55, 0, 0, 655, 133, 1, 0, 0, 0, 656, 657, 3, 36, 18, 0, 657, 658, 5, 50, 0, 0, 658, 661, 1, 0, 0, 0, 659, 661, 5, 81, 0, 0, 660, 656, 1, 0, 0, 0, 660, 659, 1, 0, 0, 0, 661, 135, 1, 0, 0, 0, 662, 664, 3, 134, 67, 0, 663, 662, 1, 0, 0, 0, 664, 667, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0, 665, 666, 1, 0, 0, 0, 666, 137, 1, 0, 0, 0, 667, 665, 1, 0, 0, 0, 668, 669, 5, 71, 0, 0, 669, 670, 3, 36, 18, 0, 670, 671, 5, 54, 0, 0, 671, 672, 3, 136, 68, 0, 672, 673, 5, 55, 0, 0, 673, 139, 1, 0, 0, 0, 674, 675, 7, 0, 0, 0, 675, 141, 1, 0, 0, 0, 676, 677, 7, 1, 0, 0, 677, 143, 1, 0, 0, 0, 678, 679, 7, 2, 0, 0, 679, 145, 1, 0, 0, 0, 66, 159, 161, 169, 178, 186, 195, 202, 208, 212, 229, 236, 243, 254, 267, 282, 286, 289, 304, 310, 322, 328, 338, 349, 355, 360, 366, 375, 380, 386, 392, 409, 414, 431, 444, 456, 461, 467, 473, 486, 491, 497, 503, 511, 516, 522, 532, 537, 543, 549, 558, 563, 569, 575, 583, 588, 594, 600, 609, 618, 623, 629, 635, 644, 650, 660, 665] \ No newline at end of file diff --git a/sources/SIGParser/.antlr/SIGBaseListener.cpp b/sources/SIGParser/.antlr/SIGBaseListener.cpp index 5aecba05..f686ac49 100644 --- a/sources/SIGParser/.antlr/SIGBaseListener.cpp +++ b/sources/SIGParser/.antlr/SIGBaseListener.cpp @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #include "SIGBaseListener.h" diff --git a/sources/SIGParser/.antlr/SIGBaseListener.h b/sources/SIGParser/.antlr/SIGBaseListener.h index 6ea559ed..84d9dbc7 100644 --- a/sources/SIGParser/.antlr/SIGBaseListener.h +++ b/sources/SIGParser/.antlr/SIGBaseListener.h @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #pragma once diff --git a/sources/SIGParser/.antlr/SIGLexer.cpp b/sources/SIGParser/.antlr/SIGLexer.cpp index 661ad626..8e653e77 100644 --- a/sources/SIGParser/.antlr/SIGLexer.cpp +++ b/sources/SIGParser/.antlr/SIGLexer.cpp @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #include "SIGLexer.h" @@ -42,19 +42,10 @@ struct SIGLexerStaticData final { }; ::antlr4::internal::OnceFlag siglexerLexerOnceFlag; -#if ANTLR4_USE_THREAD_LOCAL_CACHE -static thread_local -#endif SIGLexerStaticData *siglexerLexerStaticData = nullptr; void siglexerLexerInitialize() { -#if ANTLR4_USE_THREAD_LOCAL_CACHE - if (siglexerLexerStaticData != nullptr) { - return; - } -#else assert(siglexerLexerStaticData == nullptr); -#endif auto staticData = std::make_unique( std::vector{ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", @@ -412,9 +403,5 @@ const atn::ATN& SIGLexer::getATN() const { void SIGLexer::initialize() { -#if ANTLR4_USE_THREAD_LOCAL_CACHE - siglexerLexerInitialize(); -#else ::antlr4::internal::call_once(siglexerLexerOnceFlag, siglexerLexerInitialize); -#endif } diff --git a/sources/SIGParser/.antlr/SIGLexer.h b/sources/SIGParser/.antlr/SIGLexer.h index 7ce321f5..0dbc917b 100644 --- a/sources/SIGParser/.antlr/SIGLexer.h +++ b/sources/SIGParser/.antlr/SIGLexer.h @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #pragma once diff --git a/sources/SIGParser/.antlr/SIGListener.cpp b/sources/SIGParser/.antlr/SIGListener.cpp index 8311cbfb..8cb5e150 100644 --- a/sources/SIGParser/.antlr/SIGListener.cpp +++ b/sources/SIGParser/.antlr/SIGListener.cpp @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #include "SIGListener.h" diff --git a/sources/SIGParser/.antlr/SIGListener.h b/sources/SIGParser/.antlr/SIGListener.h index 18c6b8e9..05746919 100644 --- a/sources/SIGParser/.antlr/SIGListener.h +++ b/sources/SIGParser/.antlr/SIGListener.h @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #pragma once diff --git a/sources/SIGParser/.antlr/SIGParser.cpp b/sources/SIGParser/.antlr/SIGParser.cpp index f4a6eea2..6cf829ab 100644 --- a/sources/SIGParser/.antlr/SIGParser.cpp +++ b/sources/SIGParser/.antlr/SIGParser.cpp @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #include "SIGListener.h" @@ -37,19 +37,10 @@ struct SIGParserStaticData final { }; ::antlr4::internal::OnceFlag sigParserOnceFlag; -#if ANTLR4_USE_THREAD_LOCAL_CACHE -static thread_local -#endif SIGParserStaticData *sigParserStaticData = nullptr; void sigParserInitialize() { -#if ANTLR4_USE_THREAD_LOCAL_CACHE - if (sigParserStaticData != nullptr) { - return; - } -#else assert(sigParserStaticData == nullptr); -#endif auto staticData = std::make_unique( std::vector{ "parse", "bind_option", "options_assign", "option", "option_block", @@ -101,7 +92,7 @@ void sigParserInitialize() { } ); static const int32_t serializedATNSegment[] = { - 4,1,86,669,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2, + 4,1,86,681,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2, 7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,7, 14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7, 21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26,2,27,7,27,2,28,7, @@ -136,194 +127,199 @@ void sigParserInitialize() { 1,39,1,39,1,40,1,40,1,41,1,41,1,41,1,41,5,41,430,8,41,10,41,12,41,433, 9,41,1,41,1,41,1,42,1,42,1,42,1,42,1,42,1,43,5,43,443,8,43,10,43,12,43, 446,9,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44,1,44,3,44,457,8,44,1, - 45,5,45,460,8,45,10,45,12,45,463,9,45,1,46,1,46,1,46,3,46,468,8,46,1, - 46,1,46,1,46,1,46,1,47,1,47,1,47,1,47,1,47,1,47,1,47,3,47,481,8,47,1, - 48,5,48,484,8,48,10,48,12,48,487,9,48,1,49,5,49,490,8,49,10,49,12,49, - 493,9,49,1,49,1,49,1,49,3,49,498,8,49,1,49,1,49,1,49,1,49,1,50,1,50,3, - 50,506,8,50,1,51,5,51,509,8,51,10,51,12,51,512,9,51,1,52,1,52,1,52,3, - 52,517,8,52,1,52,1,52,1,52,1,52,1,53,1,53,1,53,1,53,3,53,527,8,53,1,54, - 5,54,530,8,54,10,54,12,54,533,9,54,1,55,1,55,1,55,3,55,538,8,55,1,55, - 1,55,1,55,1,55,1,56,1,56,1,56,3,56,547,8,56,1,57,5,57,550,8,57,10,57, - 12,57,553,9,57,1,58,5,58,556,8,58,10,58,12,58,559,9,58,1,58,1,58,1,58, - 3,58,564,8,58,1,58,1,58,1,58,1,58,1,59,1,59,3,59,572,8,59,1,60,5,60,575, - 8,60,10,60,12,60,578,9,60,1,61,5,61,581,8,61,10,61,12,61,584,9,61,1,61, - 1,61,1,61,3,61,589,8,61,1,61,1,61,1,61,1,61,1,62,5,62,596,8,62,10,62, - 12,62,599,9,62,1,62,1,62,1,62,1,62,1,63,1,63,3,63,607,8,63,1,64,5,64, - 610,8,64,10,64,12,64,613,9,64,1,65,5,65,616,8,65,10,65,12,65,619,9,65, - 1,65,1,65,1,65,3,65,624,8,65,1,65,1,65,1,65,1,65,1,66,5,66,631,8,66,10, - 66,12,66,634,9,66,1,66,1,66,1,66,3,66,639,8,66,1,66,1,66,1,66,1,66,1, - 67,1,67,1,67,1,67,3,67,649,8,67,1,68,5,68,652,8,68,10,68,12,68,655,9, - 68,1,69,1,69,1,69,1,69,1,69,1,69,1,70,1,70,1,71,1,71,1,72,1,72,1,72,15, - 202,229,243,254,267,338,349,386,444,491,557,582,597,617,632,0,73,0,2, - 4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50, - 52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96, - 98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132, - 134,136,138,140,142,144,0,3,1,0,8,19,1,0,20,35,1,0,58,59,690,0,161,1, - 0,0,0,2,169,1,0,0,0,4,173,1,0,0,0,6,176,1,0,0,0,8,180,1,0,0,0,10,191, - 1,0,0,0,12,193,1,0,0,0,14,202,1,0,0,0,16,216,1,0,0,0,18,220,1,0,0,0,20, - 229,1,0,0,0,22,243,1,0,0,0,24,254,1,0,0,0,26,262,1,0,0,0,28,267,1,0,0, - 0,30,275,1,0,0,0,32,277,1,0,0,0,34,291,1,0,0,0,36,293,1,0,0,0,38,295, - 1,0,0,0,40,297,1,0,0,0,42,299,1,0,0,0,44,301,1,0,0,0,46,322,1,0,0,0,48, - 328,1,0,0,0,50,330,1,0,0,0,52,332,1,0,0,0,54,338,1,0,0,0,56,343,1,0,0, - 0,58,355,1,0,0,0,60,360,1,0,0,0,62,363,1,0,0,0,64,375,1,0,0,0,66,380, - 1,0,0,0,68,386,1,0,0,0,70,398,1,0,0,0,72,402,1,0,0,0,74,409,1,0,0,0,76, - 414,1,0,0,0,78,417,1,0,0,0,80,423,1,0,0,0,82,425,1,0,0,0,84,436,1,0,0, - 0,86,444,1,0,0,0,88,456,1,0,0,0,90,461,1,0,0,0,92,464,1,0,0,0,94,480, - 1,0,0,0,96,485,1,0,0,0,98,491,1,0,0,0,100,505,1,0,0,0,102,510,1,0,0,0, - 104,513,1,0,0,0,106,526,1,0,0,0,108,531,1,0,0,0,110,534,1,0,0,0,112,546, - 1,0,0,0,114,551,1,0,0,0,116,557,1,0,0,0,118,571,1,0,0,0,120,576,1,0,0, - 0,122,582,1,0,0,0,124,597,1,0,0,0,126,606,1,0,0,0,128,611,1,0,0,0,130, - 617,1,0,0,0,132,632,1,0,0,0,134,648,1,0,0,0,136,653,1,0,0,0,138,656,1, - 0,0,0,140,662,1,0,0,0,142,664,1,0,0,0,144,666,1,0,0,0,146,160,3,62,31, - 0,147,160,3,68,34,0,148,160,3,78,39,0,149,160,3,110,55,0,150,160,3,92, - 46,0,151,160,3,98,49,0,152,160,3,104,52,0,153,160,3,116,58,0,154,160, - 3,122,61,0,155,160,3,132,66,0,156,160,3,130,65,0,157,160,3,138,69,0,158, - 160,5,81,0,0,159,146,1,0,0,0,159,147,1,0,0,0,159,148,1,0,0,0,159,149, - 1,0,0,0,159,150,1,0,0,0,159,151,1,0,0,0,159,152,1,0,0,0,159,153,1,0,0, - 0,159,154,1,0,0,0,159,155,1,0,0,0,159,156,1,0,0,0,159,157,1,0,0,0,159, - 158,1,0,0,0,160,163,1,0,0,0,161,159,1,0,0,0,161,162,1,0,0,0,162,164,1, - 0,0,0,163,161,1,0,0,0,164,165,5,0,0,1,165,1,1,0,0,0,166,167,3,40,20,0, - 167,168,5,1,0,0,168,170,1,0,0,0,169,166,1,0,0,0,169,170,1,0,0,0,170,171, - 1,0,0,0,171,172,3,46,23,0,172,3,1,0,0,0,173,174,5,51,0,0,174,175,3,2, - 1,0,175,5,1,0,0,0,176,178,3,36,18,0,177,179,3,4,2,0,178,177,1,0,0,0,178, - 179,1,0,0,0,179,7,1,0,0,0,180,181,5,56,0,0,181,186,3,6,3,0,182,183,5, - 2,0,0,183,185,3,6,3,0,184,182,1,0,0,0,185,188,1,0,0,0,186,184,1,0,0,0, - 186,187,1,0,0,0,187,189,1,0,0,0,188,186,1,0,0,0,189,190,5,57,0,0,190, - 9,1,0,0,0,191,192,5,78,0,0,192,11,1,0,0,0,193,195,5,56,0,0,194,196,3, - 10,5,0,195,194,1,0,0,0,195,196,1,0,0,0,196,197,1,0,0,0,197,198,5,57,0, - 0,198,13,1,0,0,0,199,201,3,8,4,0,200,199,1,0,0,0,201,204,1,0,0,0,202, - 203,1,0,0,0,202,200,1,0,0,0,203,205,1,0,0,0,204,202,1,0,0,0,205,206,3, - 50,25,0,206,208,3,36,18,0,207,209,3,12,6,0,208,207,1,0,0,0,208,209,1, - 0,0,0,209,212,1,0,0,0,210,211,5,51,0,0,211,213,3,46,23,0,212,210,1,0, - 0,0,212,213,1,0,0,0,213,214,1,0,0,0,214,215,5,50,0,0,215,15,1,0,0,0,216, - 217,5,72,0,0,217,218,3,36,18,0,218,219,5,50,0,0,219,17,1,0,0,0,220,221, - 5,3,0,0,221,222,3,36,18,0,222,223,5,51,0,0,223,224,3,46,23,0,224,225, - 5,50,0,0,225,19,1,0,0,0,226,228,3,8,4,0,227,226,1,0,0,0,228,231,1,0,0, - 0,229,230,1,0,0,0,229,227,1,0,0,0,230,232,1,0,0,0,231,229,1,0,0,0,232, - 233,5,4,0,0,233,236,3,36,18,0,234,235,5,51,0,0,235,237,3,82,41,0,236, - 234,1,0,0,0,236,237,1,0,0,0,237,238,1,0,0,0,238,239,5,50,0,0,239,21,1, - 0,0,0,240,242,3,8,4,0,241,240,1,0,0,0,242,245,1,0,0,0,243,244,1,0,0,0, - 243,241,1,0,0,0,244,246,1,0,0,0,245,243,1,0,0,0,246,247,5,5,0,0,247,248, - 5,51,0,0,248,249,3,82,41,0,249,250,5,50,0,0,250,23,1,0,0,0,251,253,3, - 8,4,0,252,251,1,0,0,0,253,256,1,0,0,0,254,255,1,0,0,0,254,252,1,0,0,0, - 255,257,1,0,0,0,256,254,1,0,0,0,257,258,5,6,0,0,258,259,5,51,0,0,259, - 260,3,82,41,0,260,261,5,50,0,0,261,25,1,0,0,0,262,263,5,83,0,0,263,27, - 1,0,0,0,264,266,3,8,4,0,265,264,1,0,0,0,266,269,1,0,0,0,267,268,1,0,0, - 0,267,265,1,0,0,0,268,270,1,0,0,0,269,267,1,0,0,0,270,271,3,142,71,0, - 271,272,5,51,0,0,272,273,3,46,23,0,273,274,5,50,0,0,274,29,1,0,0,0,275, - 276,5,77,0,0,276,31,1,0,0,0,277,286,3,30,15,0,278,282,5,41,0,0,279,281, - 3,42,21,0,280,279,1,0,0,0,281,284,1,0,0,0,282,280,1,0,0,0,282,283,1,0, - 0,0,283,285,1,0,0,0,284,282,1,0,0,0,285,287,5,40,0,0,286,278,1,0,0,0, - 286,287,1,0,0,0,287,289,1,0,0,0,288,290,3,26,13,0,289,288,1,0,0,0,289, - 290,1,0,0,0,290,33,1,0,0,0,291,292,5,77,0,0,292,35,1,0,0,0,293,294,5, - 77,0,0,294,37,1,0,0,0,295,296,5,77,0,0,296,39,1,0,0,0,297,298,5,77,0, - 0,298,41,1,0,0,0,299,300,5,77,0,0,300,43,1,0,0,0,301,302,5,77,0,0,302, - 304,5,52,0,0,303,305,3,48,24,0,304,303,1,0,0,0,304,305,1,0,0,0,305,310, - 1,0,0,0,306,307,5,2,0,0,307,309,3,48,24,0,308,306,1,0,0,0,309,312,1,0, - 0,0,310,308,1,0,0,0,310,311,1,0,0,0,311,313,1,0,0,0,312,310,1,0,0,0,313, - 314,5,53,0,0,314,45,1,0,0,0,315,323,3,140,70,0,316,323,5,77,0,0,317,323, - 5,78,0,0,318,323,5,79,0,0,319,323,3,144,72,0,320,323,3,44,22,0,321,323, - 3,82,41,0,322,315,1,0,0,0,322,316,1,0,0,0,322,317,1,0,0,0,322,318,1,0, - 0,0,322,319,1,0,0,0,322,320,1,0,0,0,322,321,1,0,0,0,323,47,1,0,0,0,324, - 329,5,77,0,0,325,329,5,78,0,0,326,329,5,79,0,0,327,329,3,144,72,0,328, - 324,1,0,0,0,328,325,1,0,0,0,328,326,1,0,0,0,328,327,1,0,0,0,329,49,1, - 0,0,0,330,331,3,32,16,0,331,51,1,0,0,0,332,333,5,86,0,0,333,53,1,0,0, - 0,334,335,5,77,0,0,335,337,5,46,0,0,336,334,1,0,0,0,337,340,1,0,0,0,338, - 339,1,0,0,0,338,336,1,0,0,0,339,341,1,0,0,0,340,338,1,0,0,0,341,342,5, - 77,0,0,342,55,1,0,0,0,343,344,5,7,0,0,344,349,3,34,17,0,345,346,5,2,0, - 0,346,348,3,34,17,0,347,345,1,0,0,0,348,351,1,0,0,0,349,350,1,0,0,0,349, - 347,1,0,0,0,350,57,1,0,0,0,351,349,1,0,0,0,352,356,3,16,8,0,353,356,3, - 18,9,0,354,356,5,81,0,0,355,352,1,0,0,0,355,353,1,0,0,0,355,354,1,0,0, - 0,356,59,1,0,0,0,357,359,3,58,29,0,358,357,1,0,0,0,359,362,1,0,0,0,360, - 358,1,0,0,0,360,361,1,0,0,0,361,61,1,0,0,0,362,360,1,0,0,0,363,364,5, - 61,0,0,364,366,3,36,18,0,365,367,3,56,28,0,366,365,1,0,0,0,366,367,1, - 0,0,0,367,368,1,0,0,0,368,369,5,54,0,0,369,370,3,60,30,0,370,371,5,55, - 0,0,371,63,1,0,0,0,372,376,3,14,7,0,373,376,3,52,26,0,374,376,5,81,0, - 0,375,372,1,0,0,0,375,373,1,0,0,0,375,374,1,0,0,0,376,65,1,0,0,0,377, - 379,3,64,32,0,378,377,1,0,0,0,379,382,1,0,0,0,380,378,1,0,0,0,380,381, - 1,0,0,0,381,67,1,0,0,0,382,380,1,0,0,0,383,385,3,8,4,0,384,383,1,0,0, - 0,385,388,1,0,0,0,386,387,1,0,0,0,386,384,1,0,0,0,387,389,1,0,0,0,388, - 386,1,0,0,0,389,390,5,62,0,0,390,392,3,36,18,0,391,393,3,56,28,0,392, - 391,1,0,0,0,392,393,1,0,0,0,393,394,1,0,0,0,394,395,5,54,0,0,395,396, - 3,66,33,0,396,397,5,55,0,0,397,69,1,0,0,0,398,399,3,50,25,0,399,400,3, - 36,18,0,400,401,5,50,0,0,401,71,1,0,0,0,402,403,5,75,0,0,403,404,3,36, - 18,0,404,405,5,50,0,0,405,73,1,0,0,0,406,410,3,70,35,0,407,410,3,72,36, - 0,408,410,5,81,0,0,409,406,1,0,0,0,409,407,1,0,0,0,409,408,1,0,0,0,410, - 75,1,0,0,0,411,413,3,74,37,0,412,411,1,0,0,0,413,416,1,0,0,0,414,412, - 1,0,0,0,414,415,1,0,0,0,415,77,1,0,0,0,416,414,1,0,0,0,417,418,5,73,0, - 0,418,419,3,36,18,0,419,420,5,54,0,0,420,421,3,76,38,0,421,422,5,55,0, - 0,422,79,1,0,0,0,423,424,3,46,23,0,424,81,1,0,0,0,425,426,5,54,0,0,426, - 431,3,80,40,0,427,428,5,2,0,0,428,430,3,80,40,0,429,427,1,0,0,0,430,433, - 1,0,0,0,431,429,1,0,0,0,431,432,1,0,0,0,432,434,1,0,0,0,433,431,1,0,0, - 0,434,435,5,55,0,0,435,83,1,0,0,0,436,437,5,76,0,0,437,438,5,51,0,0,438, - 439,3,36,18,0,439,440,5,50,0,0,440,85,1,0,0,0,441,443,3,8,4,0,442,441, - 1,0,0,0,443,446,1,0,0,0,444,445,1,0,0,0,444,442,1,0,0,0,445,447,1,0,0, - 0,446,444,1,0,0,0,447,448,3,140,70,0,448,449,5,51,0,0,449,450,3,54,27, - 0,450,451,5,50,0,0,451,87,1,0,0,0,452,457,3,84,42,0,453,457,3,86,43,0, - 454,457,3,20,10,0,455,457,5,81,0,0,456,452,1,0,0,0,456,453,1,0,0,0,456, - 454,1,0,0,0,456,455,1,0,0,0,457,89,1,0,0,0,458,460,3,88,44,0,459,458, - 1,0,0,0,460,463,1,0,0,0,461,459,1,0,0,0,461,462,1,0,0,0,462,91,1,0,0, - 0,463,461,1,0,0,0,464,465,5,63,0,0,465,467,3,36,18,0,466,468,3,56,28, - 0,467,466,1,0,0,0,467,468,1,0,0,0,468,469,1,0,0,0,469,470,5,54,0,0,470, - 471,3,90,45,0,471,472,5,55,0,0,472,93,1,0,0,0,473,481,3,84,42,0,474,481, - 3,86,43,0,475,481,3,20,10,0,476,481,3,22,11,0,477,481,3,24,12,0,478,481, - 3,28,14,0,479,481,5,81,0,0,480,473,1,0,0,0,480,474,1,0,0,0,480,475,1, - 0,0,0,480,476,1,0,0,0,480,477,1,0,0,0,480,478,1,0,0,0,480,479,1,0,0,0, - 481,95,1,0,0,0,482,484,3,94,47,0,483,482,1,0,0,0,484,487,1,0,0,0,485, - 483,1,0,0,0,485,486,1,0,0,0,486,97,1,0,0,0,487,485,1,0,0,0,488,490,3, - 8,4,0,489,488,1,0,0,0,490,493,1,0,0,0,491,492,1,0,0,0,491,489,1,0,0,0, - 492,494,1,0,0,0,493,491,1,0,0,0,494,495,5,64,0,0,495,497,3,36,18,0,496, - 498,3,56,28,0,497,496,1,0,0,0,497,498,1,0,0,0,498,499,1,0,0,0,499,500, - 5,54,0,0,500,501,3,96,48,0,501,502,5,55,0,0,502,99,1,0,0,0,503,506,3, - 84,42,0,504,506,5,81,0,0,505,503,1,0,0,0,505,504,1,0,0,0,506,101,1,0, - 0,0,507,509,3,100,50,0,508,507,1,0,0,0,509,512,1,0,0,0,510,508,1,0,0, - 0,510,511,1,0,0,0,511,103,1,0,0,0,512,510,1,0,0,0,513,514,5,65,0,0,514, - 516,3,36,18,0,515,517,3,56,28,0,516,515,1,0,0,0,516,517,1,0,0,0,517,518, - 1,0,0,0,518,519,5,54,0,0,519,520,3,102,51,0,520,521,5,55,0,0,521,105, - 1,0,0,0,522,527,3,84,42,0,523,527,3,86,43,0,524,527,3,20,10,0,525,527, - 5,81,0,0,526,522,1,0,0,0,526,523,1,0,0,0,526,524,1,0,0,0,526,525,1,0, - 0,0,527,107,1,0,0,0,528,530,3,106,53,0,529,528,1,0,0,0,530,533,1,0,0, - 0,531,529,1,0,0,0,531,532,1,0,0,0,532,109,1,0,0,0,533,531,1,0,0,0,534, - 535,5,66,0,0,535,537,3,36,18,0,536,538,3,56,28,0,537,536,1,0,0,0,537, - 538,1,0,0,0,538,539,1,0,0,0,539,540,5,54,0,0,540,541,3,108,54,0,541,542, - 5,55,0,0,542,111,1,0,0,0,543,547,3,86,43,0,544,547,5,81,0,0,545,547,3, - 28,14,0,546,543,1,0,0,0,546,544,1,0,0,0,546,545,1,0,0,0,547,113,1,0,0, - 0,548,550,3,112,56,0,549,548,1,0,0,0,550,553,1,0,0,0,551,549,1,0,0,0, - 551,552,1,0,0,0,552,115,1,0,0,0,553,551,1,0,0,0,554,556,3,8,4,0,555,554, - 1,0,0,0,556,559,1,0,0,0,557,558,1,0,0,0,557,555,1,0,0,0,558,560,1,0,0, - 0,559,557,1,0,0,0,560,561,5,68,0,0,561,563,3,36,18,0,562,564,3,56,28, - 0,563,562,1,0,0,0,563,564,1,0,0,0,564,565,1,0,0,0,565,566,5,54,0,0,566, - 567,3,114,57,0,567,568,5,55,0,0,568,117,1,0,0,0,569,572,3,86,43,0,570, - 572,5,81,0,0,571,569,1,0,0,0,571,570,1,0,0,0,572,119,1,0,0,0,573,575, - 3,118,59,0,574,573,1,0,0,0,575,578,1,0,0,0,576,574,1,0,0,0,576,577,1, - 0,0,0,577,121,1,0,0,0,578,576,1,0,0,0,579,581,3,8,4,0,580,579,1,0,0,0, - 581,584,1,0,0,0,582,583,1,0,0,0,582,580,1,0,0,0,583,585,1,0,0,0,584,582, - 1,0,0,0,585,586,5,67,0,0,586,588,3,36,18,0,587,589,3,56,28,0,588,587, - 1,0,0,0,588,589,1,0,0,0,589,590,1,0,0,0,590,591,5,54,0,0,591,592,3,120, - 60,0,592,593,5,55,0,0,593,123,1,0,0,0,594,596,3,8,4,0,595,594,1,0,0,0, - 596,599,1,0,0,0,597,598,1,0,0,0,597,595,1,0,0,0,598,600,1,0,0,0,599,597, - 1,0,0,0,600,601,3,50,25,0,601,602,3,36,18,0,602,603,5,50,0,0,603,125, - 1,0,0,0,604,607,3,124,62,0,605,607,5,81,0,0,606,604,1,0,0,0,606,605,1, - 0,0,0,607,127,1,0,0,0,608,610,3,126,63,0,609,608,1,0,0,0,610,613,1,0, - 0,0,611,609,1,0,0,0,611,612,1,0,0,0,612,129,1,0,0,0,613,611,1,0,0,0,614, - 616,3,8,4,0,615,614,1,0,0,0,616,619,1,0,0,0,617,618,1,0,0,0,617,615,1, - 0,0,0,618,620,1,0,0,0,619,617,1,0,0,0,620,621,5,70,0,0,621,623,3,36,18, - 0,622,624,3,56,28,0,623,622,1,0,0,0,623,624,1,0,0,0,624,625,1,0,0,0,625, - 626,5,54,0,0,626,627,3,128,64,0,627,628,5,55,0,0,628,131,1,0,0,0,629, - 631,3,8,4,0,630,629,1,0,0,0,631,634,1,0,0,0,632,633,1,0,0,0,632,630,1, - 0,0,0,633,635,1,0,0,0,634,632,1,0,0,0,635,636,5,69,0,0,636,638,3,36,18, - 0,637,639,3,56,28,0,638,637,1,0,0,0,638,639,1,0,0,0,639,640,1,0,0,0,640, - 641,5,54,0,0,641,642,3,128,64,0,642,643,5,55,0,0,643,133,1,0,0,0,644, - 645,3,36,18,0,645,646,5,50,0,0,646,649,1,0,0,0,647,649,5,81,0,0,648,644, - 1,0,0,0,648,647,1,0,0,0,649,135,1,0,0,0,650,652,3,134,67,0,651,650,1, - 0,0,0,652,655,1,0,0,0,653,651,1,0,0,0,653,654,1,0,0,0,654,137,1,0,0,0, - 655,653,1,0,0,0,656,657,5,71,0,0,657,658,3,36,18,0,658,659,5,54,0,0,659, - 660,3,136,68,0,660,661,5,55,0,0,661,139,1,0,0,0,662,663,7,0,0,0,663,141, - 1,0,0,0,664,665,7,1,0,0,665,143,1,0,0,0,666,667,7,2,0,0,667,145,1,0,0, - 0,64,159,161,169,178,186,195,202,208,212,229,236,243,254,267,282,286, - 289,304,310,322,328,338,349,355,360,366,375,380,386,392,409,414,431,444, - 456,461,467,480,485,491,497,505,510,516,526,531,537,546,551,557,563,571, - 576,582,588,597,606,611,617,623,632,638,648,653 + 45,5,45,460,8,45,10,45,12,45,463,9,45,1,46,5,46,466,8,46,10,46,12,46, + 469,9,46,1,46,1,46,1,46,3,46,474,8,46,1,46,1,46,1,46,1,46,1,47,1,47,1, + 47,1,47,1,47,1,47,1,47,3,47,487,8,47,1,48,5,48,490,8,48,10,48,12,48,493, + 9,48,1,49,5,49,496,8,49,10,49,12,49,499,9,49,1,49,1,49,1,49,3,49,504, + 8,49,1,49,1,49,1,49,1,49,1,50,1,50,3,50,512,8,50,1,51,5,51,515,8,51,10, + 51,12,51,518,9,51,1,52,1,52,1,52,3,52,523,8,52,1,52,1,52,1,52,1,52,1, + 53,1,53,1,53,1,53,3,53,533,8,53,1,54,5,54,536,8,54,10,54,12,54,539,9, + 54,1,55,5,55,542,8,55,10,55,12,55,545,9,55,1,55,1,55,1,55,3,55,550,8, + 55,1,55,1,55,1,55,1,55,1,56,1,56,1,56,3,56,559,8,56,1,57,5,57,562,8,57, + 10,57,12,57,565,9,57,1,58,5,58,568,8,58,10,58,12,58,571,9,58,1,58,1,58, + 1,58,3,58,576,8,58,1,58,1,58,1,58,1,58,1,59,1,59,3,59,584,8,59,1,60,5, + 60,587,8,60,10,60,12,60,590,9,60,1,61,5,61,593,8,61,10,61,12,61,596,9, + 61,1,61,1,61,1,61,3,61,601,8,61,1,61,1,61,1,61,1,61,1,62,5,62,608,8,62, + 10,62,12,62,611,9,62,1,62,1,62,1,62,1,62,1,63,1,63,3,63,619,8,63,1,64, + 5,64,622,8,64,10,64,12,64,625,9,64,1,65,5,65,628,8,65,10,65,12,65,631, + 9,65,1,65,1,65,1,65,3,65,636,8,65,1,65,1,65,1,65,1,65,1,66,5,66,643,8, + 66,10,66,12,66,646,9,66,1,66,1,66,1,66,3,66,651,8,66,1,66,1,66,1,66,1, + 66,1,67,1,67,1,67,1,67,3,67,661,8,67,1,68,5,68,664,8,68,10,68,12,68,667, + 9,68,1,69,1,69,1,69,1,69,1,69,1,69,1,70,1,70,1,71,1,71,1,72,1,72,1,72, + 17,202,229,243,254,267,338,349,386,444,467,497,543,569,594,609,629,644, + 0,73,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44, + 46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90, + 92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128, + 130,132,134,136,138,140,142,144,0,3,1,0,8,19,1,0,20,35,1,0,58,59,704, + 0,161,1,0,0,0,2,169,1,0,0,0,4,173,1,0,0,0,6,176,1,0,0,0,8,180,1,0,0,0, + 10,191,1,0,0,0,12,193,1,0,0,0,14,202,1,0,0,0,16,216,1,0,0,0,18,220,1, + 0,0,0,20,229,1,0,0,0,22,243,1,0,0,0,24,254,1,0,0,0,26,262,1,0,0,0,28, + 267,1,0,0,0,30,275,1,0,0,0,32,277,1,0,0,0,34,291,1,0,0,0,36,293,1,0,0, + 0,38,295,1,0,0,0,40,297,1,0,0,0,42,299,1,0,0,0,44,301,1,0,0,0,46,322, + 1,0,0,0,48,328,1,0,0,0,50,330,1,0,0,0,52,332,1,0,0,0,54,338,1,0,0,0,56, + 343,1,0,0,0,58,355,1,0,0,0,60,360,1,0,0,0,62,363,1,0,0,0,64,375,1,0,0, + 0,66,380,1,0,0,0,68,386,1,0,0,0,70,398,1,0,0,0,72,402,1,0,0,0,74,409, + 1,0,0,0,76,414,1,0,0,0,78,417,1,0,0,0,80,423,1,0,0,0,82,425,1,0,0,0,84, + 436,1,0,0,0,86,444,1,0,0,0,88,456,1,0,0,0,90,461,1,0,0,0,92,467,1,0,0, + 0,94,486,1,0,0,0,96,491,1,0,0,0,98,497,1,0,0,0,100,511,1,0,0,0,102,516, + 1,0,0,0,104,519,1,0,0,0,106,532,1,0,0,0,108,537,1,0,0,0,110,543,1,0,0, + 0,112,558,1,0,0,0,114,563,1,0,0,0,116,569,1,0,0,0,118,583,1,0,0,0,120, + 588,1,0,0,0,122,594,1,0,0,0,124,609,1,0,0,0,126,618,1,0,0,0,128,623,1, + 0,0,0,130,629,1,0,0,0,132,644,1,0,0,0,134,660,1,0,0,0,136,665,1,0,0,0, + 138,668,1,0,0,0,140,674,1,0,0,0,142,676,1,0,0,0,144,678,1,0,0,0,146,160, + 3,62,31,0,147,160,3,68,34,0,148,160,3,78,39,0,149,160,3,110,55,0,150, + 160,3,92,46,0,151,160,3,98,49,0,152,160,3,104,52,0,153,160,3,116,58,0, + 154,160,3,122,61,0,155,160,3,132,66,0,156,160,3,130,65,0,157,160,3,138, + 69,0,158,160,5,81,0,0,159,146,1,0,0,0,159,147,1,0,0,0,159,148,1,0,0,0, + 159,149,1,0,0,0,159,150,1,0,0,0,159,151,1,0,0,0,159,152,1,0,0,0,159,153, + 1,0,0,0,159,154,1,0,0,0,159,155,1,0,0,0,159,156,1,0,0,0,159,157,1,0,0, + 0,159,158,1,0,0,0,160,163,1,0,0,0,161,159,1,0,0,0,161,162,1,0,0,0,162, + 164,1,0,0,0,163,161,1,0,0,0,164,165,5,0,0,1,165,1,1,0,0,0,166,167,3,40, + 20,0,167,168,5,1,0,0,168,170,1,0,0,0,169,166,1,0,0,0,169,170,1,0,0,0, + 170,171,1,0,0,0,171,172,3,46,23,0,172,3,1,0,0,0,173,174,5,51,0,0,174, + 175,3,2,1,0,175,5,1,0,0,0,176,178,3,36,18,0,177,179,3,4,2,0,178,177,1, + 0,0,0,178,179,1,0,0,0,179,7,1,0,0,0,180,181,5,56,0,0,181,186,3,6,3,0, + 182,183,5,2,0,0,183,185,3,6,3,0,184,182,1,0,0,0,185,188,1,0,0,0,186,184, + 1,0,0,0,186,187,1,0,0,0,187,189,1,0,0,0,188,186,1,0,0,0,189,190,5,57, + 0,0,190,9,1,0,0,0,191,192,5,78,0,0,192,11,1,0,0,0,193,195,5,56,0,0,194, + 196,3,10,5,0,195,194,1,0,0,0,195,196,1,0,0,0,196,197,1,0,0,0,197,198, + 5,57,0,0,198,13,1,0,0,0,199,201,3,8,4,0,200,199,1,0,0,0,201,204,1,0,0, + 0,202,203,1,0,0,0,202,200,1,0,0,0,203,205,1,0,0,0,204,202,1,0,0,0,205, + 206,3,50,25,0,206,208,3,36,18,0,207,209,3,12,6,0,208,207,1,0,0,0,208, + 209,1,0,0,0,209,212,1,0,0,0,210,211,5,51,0,0,211,213,3,46,23,0,212,210, + 1,0,0,0,212,213,1,0,0,0,213,214,1,0,0,0,214,215,5,50,0,0,215,15,1,0,0, + 0,216,217,5,72,0,0,217,218,3,36,18,0,218,219,5,50,0,0,219,17,1,0,0,0, + 220,221,5,3,0,0,221,222,3,36,18,0,222,223,5,51,0,0,223,224,3,46,23,0, + 224,225,5,50,0,0,225,19,1,0,0,0,226,228,3,8,4,0,227,226,1,0,0,0,228,231, + 1,0,0,0,229,230,1,0,0,0,229,227,1,0,0,0,230,232,1,0,0,0,231,229,1,0,0, + 0,232,233,5,4,0,0,233,236,3,36,18,0,234,235,5,51,0,0,235,237,3,82,41, + 0,236,234,1,0,0,0,236,237,1,0,0,0,237,238,1,0,0,0,238,239,5,50,0,0,239, + 21,1,0,0,0,240,242,3,8,4,0,241,240,1,0,0,0,242,245,1,0,0,0,243,244,1, + 0,0,0,243,241,1,0,0,0,244,246,1,0,0,0,245,243,1,0,0,0,246,247,5,5,0,0, + 247,248,5,51,0,0,248,249,3,82,41,0,249,250,5,50,0,0,250,23,1,0,0,0,251, + 253,3,8,4,0,252,251,1,0,0,0,253,256,1,0,0,0,254,255,1,0,0,0,254,252,1, + 0,0,0,255,257,1,0,0,0,256,254,1,0,0,0,257,258,5,6,0,0,258,259,5,51,0, + 0,259,260,3,82,41,0,260,261,5,50,0,0,261,25,1,0,0,0,262,263,5,83,0,0, + 263,27,1,0,0,0,264,266,3,8,4,0,265,264,1,0,0,0,266,269,1,0,0,0,267,268, + 1,0,0,0,267,265,1,0,0,0,268,270,1,0,0,0,269,267,1,0,0,0,270,271,3,142, + 71,0,271,272,5,51,0,0,272,273,3,46,23,0,273,274,5,50,0,0,274,29,1,0,0, + 0,275,276,5,77,0,0,276,31,1,0,0,0,277,286,3,30,15,0,278,282,5,41,0,0, + 279,281,3,42,21,0,280,279,1,0,0,0,281,284,1,0,0,0,282,280,1,0,0,0,282, + 283,1,0,0,0,283,285,1,0,0,0,284,282,1,0,0,0,285,287,5,40,0,0,286,278, + 1,0,0,0,286,287,1,0,0,0,287,289,1,0,0,0,288,290,3,26,13,0,289,288,1,0, + 0,0,289,290,1,0,0,0,290,33,1,0,0,0,291,292,5,77,0,0,292,35,1,0,0,0,293, + 294,5,77,0,0,294,37,1,0,0,0,295,296,5,77,0,0,296,39,1,0,0,0,297,298,5, + 77,0,0,298,41,1,0,0,0,299,300,5,77,0,0,300,43,1,0,0,0,301,302,5,77,0, + 0,302,304,5,52,0,0,303,305,3,48,24,0,304,303,1,0,0,0,304,305,1,0,0,0, + 305,310,1,0,0,0,306,307,5,2,0,0,307,309,3,48,24,0,308,306,1,0,0,0,309, + 312,1,0,0,0,310,308,1,0,0,0,310,311,1,0,0,0,311,313,1,0,0,0,312,310,1, + 0,0,0,313,314,5,53,0,0,314,45,1,0,0,0,315,323,3,140,70,0,316,323,5,77, + 0,0,317,323,5,78,0,0,318,323,5,79,0,0,319,323,3,144,72,0,320,323,3,44, + 22,0,321,323,3,82,41,0,322,315,1,0,0,0,322,316,1,0,0,0,322,317,1,0,0, + 0,322,318,1,0,0,0,322,319,1,0,0,0,322,320,1,0,0,0,322,321,1,0,0,0,323, + 47,1,0,0,0,324,329,5,77,0,0,325,329,5,78,0,0,326,329,5,79,0,0,327,329, + 3,144,72,0,328,324,1,0,0,0,328,325,1,0,0,0,328,326,1,0,0,0,328,327,1, + 0,0,0,329,49,1,0,0,0,330,331,3,32,16,0,331,51,1,0,0,0,332,333,5,86,0, + 0,333,53,1,0,0,0,334,335,5,77,0,0,335,337,5,46,0,0,336,334,1,0,0,0,337, + 340,1,0,0,0,338,339,1,0,0,0,338,336,1,0,0,0,339,341,1,0,0,0,340,338,1, + 0,0,0,341,342,5,77,0,0,342,55,1,0,0,0,343,344,5,7,0,0,344,349,3,34,17, + 0,345,346,5,2,0,0,346,348,3,34,17,0,347,345,1,0,0,0,348,351,1,0,0,0,349, + 350,1,0,0,0,349,347,1,0,0,0,350,57,1,0,0,0,351,349,1,0,0,0,352,356,3, + 16,8,0,353,356,3,18,9,0,354,356,5,81,0,0,355,352,1,0,0,0,355,353,1,0, + 0,0,355,354,1,0,0,0,356,59,1,0,0,0,357,359,3,58,29,0,358,357,1,0,0,0, + 359,362,1,0,0,0,360,358,1,0,0,0,360,361,1,0,0,0,361,61,1,0,0,0,362,360, + 1,0,0,0,363,364,5,61,0,0,364,366,3,36,18,0,365,367,3,56,28,0,366,365, + 1,0,0,0,366,367,1,0,0,0,367,368,1,0,0,0,368,369,5,54,0,0,369,370,3,60, + 30,0,370,371,5,55,0,0,371,63,1,0,0,0,372,376,3,14,7,0,373,376,3,52,26, + 0,374,376,5,81,0,0,375,372,1,0,0,0,375,373,1,0,0,0,375,374,1,0,0,0,376, + 65,1,0,0,0,377,379,3,64,32,0,378,377,1,0,0,0,379,382,1,0,0,0,380,378, + 1,0,0,0,380,381,1,0,0,0,381,67,1,0,0,0,382,380,1,0,0,0,383,385,3,8,4, + 0,384,383,1,0,0,0,385,388,1,0,0,0,386,387,1,0,0,0,386,384,1,0,0,0,387, + 389,1,0,0,0,388,386,1,0,0,0,389,390,5,62,0,0,390,392,3,36,18,0,391,393, + 3,56,28,0,392,391,1,0,0,0,392,393,1,0,0,0,393,394,1,0,0,0,394,395,5,54, + 0,0,395,396,3,66,33,0,396,397,5,55,0,0,397,69,1,0,0,0,398,399,3,50,25, + 0,399,400,3,36,18,0,400,401,5,50,0,0,401,71,1,0,0,0,402,403,5,75,0,0, + 403,404,3,36,18,0,404,405,5,50,0,0,405,73,1,0,0,0,406,410,3,70,35,0,407, + 410,3,72,36,0,408,410,5,81,0,0,409,406,1,0,0,0,409,407,1,0,0,0,409,408, + 1,0,0,0,410,75,1,0,0,0,411,413,3,74,37,0,412,411,1,0,0,0,413,416,1,0, + 0,0,414,412,1,0,0,0,414,415,1,0,0,0,415,77,1,0,0,0,416,414,1,0,0,0,417, + 418,5,73,0,0,418,419,3,36,18,0,419,420,5,54,0,0,420,421,3,76,38,0,421, + 422,5,55,0,0,422,79,1,0,0,0,423,424,3,46,23,0,424,81,1,0,0,0,425,426, + 5,54,0,0,426,431,3,80,40,0,427,428,5,2,0,0,428,430,3,80,40,0,429,427, + 1,0,0,0,430,433,1,0,0,0,431,429,1,0,0,0,431,432,1,0,0,0,432,434,1,0,0, + 0,433,431,1,0,0,0,434,435,5,55,0,0,435,83,1,0,0,0,436,437,5,76,0,0,437, + 438,5,51,0,0,438,439,3,36,18,0,439,440,5,50,0,0,440,85,1,0,0,0,441,443, + 3,8,4,0,442,441,1,0,0,0,443,446,1,0,0,0,444,445,1,0,0,0,444,442,1,0,0, + 0,445,447,1,0,0,0,446,444,1,0,0,0,447,448,3,140,70,0,448,449,5,51,0,0, + 449,450,3,54,27,0,450,451,5,50,0,0,451,87,1,0,0,0,452,457,3,84,42,0,453, + 457,3,86,43,0,454,457,3,20,10,0,455,457,5,81,0,0,456,452,1,0,0,0,456, + 453,1,0,0,0,456,454,1,0,0,0,456,455,1,0,0,0,457,89,1,0,0,0,458,460,3, + 88,44,0,459,458,1,0,0,0,460,463,1,0,0,0,461,459,1,0,0,0,461,462,1,0,0, + 0,462,91,1,0,0,0,463,461,1,0,0,0,464,466,3,8,4,0,465,464,1,0,0,0,466, + 469,1,0,0,0,467,468,1,0,0,0,467,465,1,0,0,0,468,470,1,0,0,0,469,467,1, + 0,0,0,470,471,5,63,0,0,471,473,3,36,18,0,472,474,3,56,28,0,473,472,1, + 0,0,0,473,474,1,0,0,0,474,475,1,0,0,0,475,476,5,54,0,0,476,477,3,90,45, + 0,477,478,5,55,0,0,478,93,1,0,0,0,479,487,3,84,42,0,480,487,3,86,43,0, + 481,487,3,20,10,0,482,487,3,22,11,0,483,487,3,24,12,0,484,487,3,28,14, + 0,485,487,5,81,0,0,486,479,1,0,0,0,486,480,1,0,0,0,486,481,1,0,0,0,486, + 482,1,0,0,0,486,483,1,0,0,0,486,484,1,0,0,0,486,485,1,0,0,0,487,95,1, + 0,0,0,488,490,3,94,47,0,489,488,1,0,0,0,490,493,1,0,0,0,491,489,1,0,0, + 0,491,492,1,0,0,0,492,97,1,0,0,0,493,491,1,0,0,0,494,496,3,8,4,0,495, + 494,1,0,0,0,496,499,1,0,0,0,497,498,1,0,0,0,497,495,1,0,0,0,498,500,1, + 0,0,0,499,497,1,0,0,0,500,501,5,64,0,0,501,503,3,36,18,0,502,504,3,56, + 28,0,503,502,1,0,0,0,503,504,1,0,0,0,504,505,1,0,0,0,505,506,5,54,0,0, + 506,507,3,96,48,0,507,508,5,55,0,0,508,99,1,0,0,0,509,512,3,84,42,0,510, + 512,5,81,0,0,511,509,1,0,0,0,511,510,1,0,0,0,512,101,1,0,0,0,513,515, + 3,100,50,0,514,513,1,0,0,0,515,518,1,0,0,0,516,514,1,0,0,0,516,517,1, + 0,0,0,517,103,1,0,0,0,518,516,1,0,0,0,519,520,5,65,0,0,520,522,3,36,18, + 0,521,523,3,56,28,0,522,521,1,0,0,0,522,523,1,0,0,0,523,524,1,0,0,0,524, + 525,5,54,0,0,525,526,3,102,51,0,526,527,5,55,0,0,527,105,1,0,0,0,528, + 533,3,84,42,0,529,533,3,86,43,0,530,533,3,20,10,0,531,533,5,81,0,0,532, + 528,1,0,0,0,532,529,1,0,0,0,532,530,1,0,0,0,532,531,1,0,0,0,533,107,1, + 0,0,0,534,536,3,106,53,0,535,534,1,0,0,0,536,539,1,0,0,0,537,535,1,0, + 0,0,537,538,1,0,0,0,538,109,1,0,0,0,539,537,1,0,0,0,540,542,3,8,4,0,541, + 540,1,0,0,0,542,545,1,0,0,0,543,544,1,0,0,0,543,541,1,0,0,0,544,546,1, + 0,0,0,545,543,1,0,0,0,546,547,5,66,0,0,547,549,3,36,18,0,548,550,3,56, + 28,0,549,548,1,0,0,0,549,550,1,0,0,0,550,551,1,0,0,0,551,552,5,54,0,0, + 552,553,3,108,54,0,553,554,5,55,0,0,554,111,1,0,0,0,555,559,3,86,43,0, + 556,559,5,81,0,0,557,559,3,28,14,0,558,555,1,0,0,0,558,556,1,0,0,0,558, + 557,1,0,0,0,559,113,1,0,0,0,560,562,3,112,56,0,561,560,1,0,0,0,562,565, + 1,0,0,0,563,561,1,0,0,0,563,564,1,0,0,0,564,115,1,0,0,0,565,563,1,0,0, + 0,566,568,3,8,4,0,567,566,1,0,0,0,568,571,1,0,0,0,569,570,1,0,0,0,569, + 567,1,0,0,0,570,572,1,0,0,0,571,569,1,0,0,0,572,573,5,68,0,0,573,575, + 3,36,18,0,574,576,3,56,28,0,575,574,1,0,0,0,575,576,1,0,0,0,576,577,1, + 0,0,0,577,578,5,54,0,0,578,579,3,114,57,0,579,580,5,55,0,0,580,117,1, + 0,0,0,581,584,3,86,43,0,582,584,5,81,0,0,583,581,1,0,0,0,583,582,1,0, + 0,0,584,119,1,0,0,0,585,587,3,118,59,0,586,585,1,0,0,0,587,590,1,0,0, + 0,588,586,1,0,0,0,588,589,1,0,0,0,589,121,1,0,0,0,590,588,1,0,0,0,591, + 593,3,8,4,0,592,591,1,0,0,0,593,596,1,0,0,0,594,595,1,0,0,0,594,592,1, + 0,0,0,595,597,1,0,0,0,596,594,1,0,0,0,597,598,5,67,0,0,598,600,3,36,18, + 0,599,601,3,56,28,0,600,599,1,0,0,0,600,601,1,0,0,0,601,602,1,0,0,0,602, + 603,5,54,0,0,603,604,3,120,60,0,604,605,5,55,0,0,605,123,1,0,0,0,606, + 608,3,8,4,0,607,606,1,0,0,0,608,611,1,0,0,0,609,610,1,0,0,0,609,607,1, + 0,0,0,610,612,1,0,0,0,611,609,1,0,0,0,612,613,3,50,25,0,613,614,3,36, + 18,0,614,615,5,50,0,0,615,125,1,0,0,0,616,619,3,124,62,0,617,619,5,81, + 0,0,618,616,1,0,0,0,618,617,1,0,0,0,619,127,1,0,0,0,620,622,3,126,63, + 0,621,620,1,0,0,0,622,625,1,0,0,0,623,621,1,0,0,0,623,624,1,0,0,0,624, + 129,1,0,0,0,625,623,1,0,0,0,626,628,3,8,4,0,627,626,1,0,0,0,628,631,1, + 0,0,0,629,630,1,0,0,0,629,627,1,0,0,0,630,632,1,0,0,0,631,629,1,0,0,0, + 632,633,5,70,0,0,633,635,3,36,18,0,634,636,3,56,28,0,635,634,1,0,0,0, + 635,636,1,0,0,0,636,637,1,0,0,0,637,638,5,54,0,0,638,639,3,128,64,0,639, + 640,5,55,0,0,640,131,1,0,0,0,641,643,3,8,4,0,642,641,1,0,0,0,643,646, + 1,0,0,0,644,645,1,0,0,0,644,642,1,0,0,0,645,647,1,0,0,0,646,644,1,0,0, + 0,647,648,5,69,0,0,648,650,3,36,18,0,649,651,3,56,28,0,650,649,1,0,0, + 0,650,651,1,0,0,0,651,652,1,0,0,0,652,653,5,54,0,0,653,654,3,128,64,0, + 654,655,5,55,0,0,655,133,1,0,0,0,656,657,3,36,18,0,657,658,5,50,0,0,658, + 661,1,0,0,0,659,661,5,81,0,0,660,656,1,0,0,0,660,659,1,0,0,0,661,135, + 1,0,0,0,662,664,3,134,67,0,663,662,1,0,0,0,664,667,1,0,0,0,665,663,1, + 0,0,0,665,666,1,0,0,0,666,137,1,0,0,0,667,665,1,0,0,0,668,669,5,71,0, + 0,669,670,3,36,18,0,670,671,5,54,0,0,671,672,3,136,68,0,672,673,5,55, + 0,0,673,139,1,0,0,0,674,675,7,0,0,0,675,141,1,0,0,0,676,677,7,1,0,0,677, + 143,1,0,0,0,678,679,7,2,0,0,679,145,1,0,0,0,66,159,161,169,178,186,195, + 202,208,212,229,236,243,254,267,282,286,289,304,310,322,328,338,349,355, + 360,366,375,380,386,392,409,414,431,444,456,461,467,473,486,491,497,503, + 511,516,522,532,537,543,549,558,563,569,575,583,588,594,600,609,618,623, + 629,635,644,650,660,665 }; staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0])); @@ -520,8 +516,8 @@ SIGParser::ParseContext* SIGParser::parse() { setState(161); _errHandler->sync(this); _la = _input->LA(1); - while (((((_la - 56) & ~ 0x3fULL) == 0) && - ((1ULL << (_la - 56)) & 33751009) != 0)) { + while ((((_la - 56) & ~ 0x3fULL) == 0) && + ((1ULL << (_la - 56)) & 33751009) != 0) { setState(159); _errHandler->sync(this); switch (getInterpreter()->adaptivePredict(_input, 0, _ctx)) { @@ -2189,8 +2185,8 @@ SIGParser::Function_idContext* SIGParser::function_id() { _errHandler->sync(this); _la = _input->LA(1); - if (((((_la - 58) & ~ 0x3fULL) == 0) && - ((1ULL << (_la - 58)) & 3670019) != 0)) { + if ((((_la - 58) & ~ 0x3fULL) == 0) && + ((1ULL << (_la - 58)) & 3670019) != 0) { setState(303); value_id_ignore(); } @@ -3082,8 +3078,8 @@ SIGParser::Table_blockContext* SIGParser::table_block() { setState(380); _errHandler->sync(this); _la = _input->LA(1); - while (((((_la - 56) & ~ 0x3fULL) == 0) && - ((1ULL << (_la - 56)) & 1109393409) != 0)) { + while ((((_la - 56) & ~ 0x3fULL) == 0) && + ((1ULL << (_la - 56)) & 1109393409) != 0) { setState(377); table_stat(); setState(382); @@ -3475,8 +3471,8 @@ SIGParser::Rt_blockContext* SIGParser::rt_block() { setState(414); _errHandler->sync(this); _la = _input->LA(1); - while (((((_la - 75) & ~ 0x3fULL) == 0) && - ((1ULL << (_la - 75)) & 69) != 0)) { + while ((((_la - 75) & ~ 0x3fULL) == 0) && + ((1ULL << (_la - 75)) & 69) != 0) { setState(411); rt_stat(); setState(416); @@ -4013,8 +4009,8 @@ SIGParser::Compute_pso_blockContext* SIGParser::compute_pso_block() { setState(461); _errHandler->sync(this); _la = _input->LA(1); - while ((((_la & ~ 0x3fULL) == 0) && - ((1ULL << _la) & 72057594038976272) != 0) || _la == SIGParser::ROOTSIG + while (((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 72057594038976272) != 0 || _la == SIGParser::ROOTSIG || _la == SIGParser::COMMENT) { setState(458); @@ -4060,6 +4056,14 @@ tree::TerminalNode* SIGParser::Compute_pso_definitionContext::CBRACE() { return getToken(SIGParser::CBRACE, 0); } +std::vector SIGParser::Compute_pso_definitionContext::option_block() { + return getRuleContexts(); +} + +SIGParser::Option_blockContext* SIGParser::Compute_pso_definitionContext::option_block(size_t i) { + return getRuleContext(i); +} + SIGParser::InheritContext* SIGParser::Compute_pso_definitionContext::inherit() { return getRuleContext(0); } @@ -4094,24 +4098,37 @@ SIGParser::Compute_pso_definitionContext* SIGParser::compute_pso_definition() { exitRule(); }); try { + size_t alt; enterOuterAlt(_localctx, 1); - setState(464); + setState(467); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 36, _ctx); + while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1 + 1) { + setState(464); + option_block(); + } + setState(469); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 36, _ctx); + } + setState(470); match(SIGParser::COMPUTE_PSO); - setState(465); + setState(471); name_id(); - setState(467); + setState(473); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(466); + setState(472); inherit(); } - setState(469); + setState(475); match(SIGParser::OBRACE); - setState(470); + setState(476); compute_pso_block(); - setState(471); + setState(477); match(SIGParser::CBRACE); } @@ -4187,54 +4204,54 @@ SIGParser::Graphics_pso_statContext* SIGParser::graphics_pso_stat() { exitRule(); }); try { - setState(480); + setState(486); _errHandler->sync(this); - switch (getInterpreter()->adaptivePredict(_input, 37, _ctx)) { + switch (getInterpreter()->adaptivePredict(_input, 38, _ctx)) { case 1: { enterOuterAlt(_localctx, 1); - setState(473); + setState(479); root_sig(); break; } case 2: { enterOuterAlt(_localctx, 2); - setState(474); + setState(480); shader(); break; } case 3: { enterOuterAlt(_localctx, 3); - setState(475); + setState(481); define_declaration(); break; } case 4: { enterOuterAlt(_localctx, 4); - setState(476); + setState(482); rtv_formats_declaration(); break; } case 5: { enterOuterAlt(_localctx, 5); - setState(477); + setState(483); blends_declaration(); break; } case 6: { enterOuterAlt(_localctx, 6); - setState(478); + setState(484); pso_param(); break; } case 7: { enterOuterAlt(_localctx, 7); - setState(479); + setState(485); match(SIGParser::COMMENT); break; } @@ -4298,16 +4315,16 @@ SIGParser::Graphics_pso_blockContext* SIGParser::graphics_pso_block() { }); try { enterOuterAlt(_localctx, 1); - setState(485); + setState(491); _errHandler->sync(this); _la = _input->LA(1); - while ((((_la & ~ 0x3fULL) == 0) && - ((1ULL << _la) & 72057662757404528) != 0) || _la == SIGParser::ROOTSIG + while (((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 72057662757404528) != 0 || _la == SIGParser::ROOTSIG || _la == SIGParser::COMMENT) { - setState(482); + setState(488); graphics_pso_stat(); - setState(487); + setState(493); _errHandler->sync(this); _la = _input->LA(1); } @@ -4392,35 +4409,35 @@ SIGParser::Graphics_pso_definitionContext* SIGParser::graphics_pso_definition() try { size_t alt; enterOuterAlt(_localctx, 1); - setState(491); + setState(497); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 39, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 40, _ctx); while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { if (alt == 1 + 1) { - setState(488); + setState(494); option_block(); } - setState(493); + setState(499); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 39, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 40, _ctx); } - setState(494); + setState(500); match(SIGParser::GRAPHICS_PSO); - setState(495); + setState(501); name_id(); - setState(497); + setState(503); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(496); + setState(502); inherit(); } - setState(499); + setState(505); match(SIGParser::OBRACE); - setState(500); + setState(506); graphics_pso_block(); - setState(501); + setState(507); match(SIGParser::CBRACE); } @@ -4476,19 +4493,19 @@ SIGParser::Rtx_pso_statContext* SIGParser::rtx_pso_stat() { exitRule(); }); try { - setState(505); + setState(511); _errHandler->sync(this); switch (_input->LA(1)) { case SIGParser::ROOTSIG: { enterOuterAlt(_localctx, 1); - setState(503); + setState(509); root_sig(); break; } case SIGParser::COMMENT: { enterOuterAlt(_localctx, 2); - setState(504); + setState(510); match(SIGParser::COMMENT); break; } @@ -4552,15 +4569,15 @@ SIGParser::Rtx_pso_blockContext* SIGParser::rtx_pso_block() { }); try { enterOuterAlt(_localctx, 1); - setState(510); + setState(516); _errHandler->sync(this); _la = _input->LA(1); while (_la == SIGParser::ROOTSIG || _la == SIGParser::COMMENT) { - setState(507); + setState(513); rtx_pso_stat(); - setState(512); + setState(518); _errHandler->sync(this); _la = _input->LA(1); } @@ -4636,23 +4653,23 @@ SIGParser::Rtx_pso_definitionContext* SIGParser::rtx_pso_definition() { }); try { enterOuterAlt(_localctx, 1); - setState(513); + setState(519); match(SIGParser::RAYTRACE_PSO); - setState(514); + setState(520); name_id(); - setState(516); + setState(522); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(515); + setState(521); inherit(); } - setState(518); + setState(524); match(SIGParser::OBRACE); - setState(519); + setState(525); rtx_pso_block(); - setState(520); + setState(526); match(SIGParser::CBRACE); } @@ -4716,33 +4733,33 @@ SIGParser::Workgraph_pso_statContext* SIGParser::workgraph_pso_stat() { exitRule(); }); try { - setState(526); + setState(532); _errHandler->sync(this); - switch (getInterpreter()->adaptivePredict(_input, 44, _ctx)) { + switch (getInterpreter()->adaptivePredict(_input, 45, _ctx)) { case 1: { enterOuterAlt(_localctx, 1); - setState(522); + setState(528); root_sig(); break; } case 2: { enterOuterAlt(_localctx, 2); - setState(523); + setState(529); shader(); break; } case 3: { enterOuterAlt(_localctx, 3); - setState(524); + setState(530); define_declaration(); break; } case 4: { enterOuterAlt(_localctx, 4); - setState(525); + setState(531); match(SIGParser::COMMENT); break; } @@ -4806,16 +4823,16 @@ SIGParser::Workgraph_pso_blockContext* SIGParser::workgraph_pso_block() { }); try { enterOuterAlt(_localctx, 1); - setState(531); + setState(537); _errHandler->sync(this); _la = _input->LA(1); - while ((((_la & ~ 0x3fULL) == 0) && - ((1ULL << _la) & 72057594038976272) != 0) || _la == SIGParser::ROOTSIG + while (((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 72057594038976272) != 0 || _la == SIGParser::ROOTSIG || _la == SIGParser::COMMENT) { - setState(528); + setState(534); workgraph_pso_stat(); - setState(533); + setState(539); _errHandler->sync(this); _la = _input->LA(1); } @@ -4856,6 +4873,14 @@ tree::TerminalNode* SIGParser::Workgraph_pso_definitionContext::CBRACE() { return getToken(SIGParser::CBRACE, 0); } +std::vector SIGParser::Workgraph_pso_definitionContext::option_block() { + return getRuleContexts(); +} + +SIGParser::Option_blockContext* SIGParser::Workgraph_pso_definitionContext::option_block(size_t i) { + return getRuleContext(i); +} + SIGParser::InheritContext* SIGParser::Workgraph_pso_definitionContext::inherit() { return getRuleContext(0); } @@ -4890,24 +4915,37 @@ SIGParser::Workgraph_pso_definitionContext* SIGParser::workgraph_pso_definition( exitRule(); }); try { + size_t alt; enterOuterAlt(_localctx, 1); - setState(534); + setState(543); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 47, _ctx); + while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1 + 1) { + setState(540); + option_block(); + } + setState(545); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 47, _ctx); + } + setState(546); match(SIGParser::WORKGRAPH_PSO); - setState(535); + setState(547); name_id(); - setState(537); + setState(549); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(536); + setState(548); inherit(); } - setState(539); + setState(551); match(SIGParser::OBRACE); - setState(540); + setState(552); workgraph_pso_block(); - setState(541); + setState(553); match(SIGParser::CBRACE); } @@ -4967,26 +5005,26 @@ SIGParser::Rtx_pass_statContext* SIGParser::rtx_pass_stat() { exitRule(); }); try { - setState(546); + setState(558); _errHandler->sync(this); - switch (getInterpreter()->adaptivePredict(_input, 47, _ctx)) { + switch (getInterpreter()->adaptivePredict(_input, 49, _ctx)) { case 1: { enterOuterAlt(_localctx, 1); - setState(543); + setState(555); shader(); break; } case 2: { enterOuterAlt(_localctx, 2); - setState(544); + setState(556); match(SIGParser::COMMENT); break; } case 3: { enterOuterAlt(_localctx, 3); - setState(545); + setState(557); pso_param(); break; } @@ -5050,14 +5088,14 @@ SIGParser::Rtx_pass_blockContext* SIGParser::rtx_pass_block() { }); try { enterOuterAlt(_localctx, 1); - setState(551); + setState(563); _errHandler->sync(this); _la = _input->LA(1); - while ((((_la & ~ 0x3fULL) == 0) && - ((1ULL << _la) & 72057662757404416) != 0) || _la == SIGParser::COMMENT) { - setState(548); + while (((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 72057662757404416) != 0 || _la == SIGParser::COMMENT) { + setState(560); rtx_pass_stat(); - setState(553); + setState(565); _errHandler->sync(this); _la = _input->LA(1); } @@ -5142,35 +5180,35 @@ SIGParser::Rtx_pass_definitionContext* SIGParser::rtx_pass_definition() { try { size_t alt; enterOuterAlt(_localctx, 1); - setState(557); + setState(569); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 49, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 51, _ctx); while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { if (alt == 1 + 1) { - setState(554); + setState(566); option_block(); } - setState(559); + setState(571); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 49, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 51, _ctx); } - setState(560); + setState(572); match(SIGParser::RAYTRACE_PASS); - setState(561); + setState(573); name_id(); - setState(563); + setState(575); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(562); + setState(574); inherit(); } - setState(565); + setState(577); match(SIGParser::OBRACE); - setState(566); + setState(578); rtx_pass_block(); - setState(567); + setState(579); match(SIGParser::CBRACE); } @@ -5226,7 +5264,7 @@ SIGParser::Rtx_raygen_statContext* SIGParser::rtx_raygen_stat() { exitRule(); }); try { - setState(571); + setState(583); _errHandler->sync(this); switch (_input->LA(1)) { case SIGParser::T__7: @@ -5243,14 +5281,14 @@ SIGParser::Rtx_raygen_statContext* SIGParser::rtx_raygen_stat() { case SIGParser::T__18: case SIGParser::OSBRACE: { enterOuterAlt(_localctx, 1); - setState(569); + setState(581); shader(); break; } case SIGParser::COMMENT: { enterOuterAlt(_localctx, 2); - setState(570); + setState(582); match(SIGParser::COMMENT); break; } @@ -5314,14 +5352,14 @@ SIGParser::Rtx_raygen_blockContext* SIGParser::rtx_raygen_block() { }); try { enterOuterAlt(_localctx, 1); - setState(576); + setState(588); _errHandler->sync(this); _la = _input->LA(1); - while ((((_la & ~ 0x3fULL) == 0) && - ((1ULL << _la) & 72057594038976256) != 0) || _la == SIGParser::COMMENT) { - setState(573); + while (((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 72057594038976256) != 0 || _la == SIGParser::COMMENT) { + setState(585); rtx_raygen_stat(); - setState(578); + setState(590); _errHandler->sync(this); _la = _input->LA(1); } @@ -5406,35 +5444,35 @@ SIGParser::Rtx_raygen_definitionContext* SIGParser::rtx_raygen_definition() { try { size_t alt; enterOuterAlt(_localctx, 1); - setState(582); + setState(594); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 53, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 55, _ctx); while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { if (alt == 1 + 1) { - setState(579); + setState(591); option_block(); } - setState(584); + setState(596); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 53, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 55, _ctx); } - setState(585); + setState(597); match(SIGParser::RAYTRACE_RAYGEN); - setState(586); + setState(598); name_id(); - setState(588); + setState(600); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(587); + setState(599); inherit(); } - setState(590); + setState(602); match(SIGParser::OBRACE); - setState(591); + setState(603); rtx_raygen_block(); - setState(592); + setState(604); match(SIGParser::CBRACE); } @@ -5504,23 +5542,23 @@ SIGParser::View_declarationContext* SIGParser::view_declaration() { try { size_t alt; enterOuterAlt(_localctx, 1); - setState(597); + setState(609); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 55, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 57, _ctx); while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { if (alt == 1 + 1) { - setState(594); + setState(606); option_block(); } - setState(599); + setState(611); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 55, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 57, _ctx); } - setState(600); + setState(612); type_id(); - setState(601); + setState(613); name_id(); - setState(602); + setState(614); match(SIGParser::SCOL); } @@ -5576,20 +5614,20 @@ SIGParser::View_statContext* SIGParser::view_stat() { exitRule(); }); try { - setState(606); + setState(618); _errHandler->sync(this); switch (_input->LA(1)) { case SIGParser::OSBRACE: case SIGParser::ID: { enterOuterAlt(_localctx, 1); - setState(604); + setState(616); view_declaration(); break; } case SIGParser::COMMENT: { enterOuterAlt(_localctx, 2); - setState(605); + setState(617); match(SIGParser::COMMENT); break; } @@ -5653,14 +5691,14 @@ SIGParser::View_blockContext* SIGParser::view_block() { }); try { enterOuterAlt(_localctx, 1); - setState(611); + setState(623); _errHandler->sync(this); _la = _input->LA(1); - while (((((_la - 56) & ~ 0x3fULL) == 0) && - ((1ULL << (_la - 56)) & 35651585) != 0)) { - setState(608); + while ((((_la - 56) & ~ 0x3fULL) == 0) && + ((1ULL << (_la - 56)) & 35651585) != 0) { + setState(620); view_stat(); - setState(613); + setState(625); _errHandler->sync(this); _la = _input->LA(1); } @@ -5745,35 +5783,35 @@ SIGParser::View_definitionContext* SIGParser::view_definition() { try { size_t alt; enterOuterAlt(_localctx, 1); - setState(617); + setState(629); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 58, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 60, _ctx); while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { if (alt == 1 + 1) { - setState(614); + setState(626); option_block(); } - setState(619); + setState(631); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 58, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 60, _ctx); } - setState(620); + setState(632); match(SIGParser::VIEW); - setState(621); + setState(633); name_id(); - setState(623); + setState(635); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(622); + setState(634); inherit(); } - setState(625); + setState(637); match(SIGParser::OBRACE); - setState(626); + setState(638); view_block(); - setState(627); + setState(639); match(SIGParser::CBRACE); } @@ -5856,35 +5894,35 @@ SIGParser::Pass_definitionContext* SIGParser::pass_definition() { try { size_t alt; enterOuterAlt(_localctx, 1); - setState(632); + setState(644); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 60, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 62, _ctx); while (alt != 1 && alt != atn::ATN::INVALID_ALT_NUMBER) { if (alt == 1 + 1) { - setState(629); + setState(641); option_block(); } - setState(634); + setState(646); _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 60, _ctx); + alt = getInterpreter()->adaptivePredict(_input, 62, _ctx); } - setState(635); + setState(647); match(SIGParser::PASS); - setState(636); + setState(648); name_id(); - setState(638); + setState(650); _errHandler->sync(this); _la = _input->LA(1); if (_la == SIGParser::T__6) { - setState(637); + setState(649); inherit(); } - setState(640); + setState(652); match(SIGParser::OBRACE); - setState(641); + setState(653); view_block(); - setState(642); + setState(654); match(SIGParser::CBRACE); } @@ -5944,21 +5982,21 @@ SIGParser::Pipeline_statContext* SIGParser::pipeline_stat() { exitRule(); }); try { - setState(648); + setState(660); _errHandler->sync(this); switch (_input->LA(1)) { case SIGParser::ID: { enterOuterAlt(_localctx, 1); - setState(644); + setState(656); name_id(); - setState(645); + setState(657); match(SIGParser::SCOL); break; } case SIGParser::COMMENT: { enterOuterAlt(_localctx, 2); - setState(647); + setState(659); match(SIGParser::COMMENT); break; } @@ -6022,15 +6060,15 @@ SIGParser::Pipeline_blockContext* SIGParser::pipeline_block() { }); try { enterOuterAlt(_localctx, 1); - setState(653); + setState(665); _errHandler->sync(this); _la = _input->LA(1); while (_la == SIGParser::ID || _la == SIGParser::COMMENT) { - setState(650); + setState(662); pipeline_stat(); - setState(655); + setState(667); _errHandler->sync(this); _la = _input->LA(1); } @@ -6101,15 +6139,15 @@ SIGParser::Pipeline_definitionContext* SIGParser::pipeline_definition() { }); try { enterOuterAlt(_localctx, 1); - setState(656); + setState(668); match(SIGParser::PIPELINE); - setState(657); + setState(669); name_id(); - setState(658); + setState(670); match(SIGParser::OBRACE); - setState(659); + setState(671); pipeline_block(); - setState(660); + setState(672); match(SIGParser::CBRACE); } @@ -6159,10 +6197,10 @@ SIGParser::Shader_typeContext* SIGParser::shader_type() { }); try { enterOuterAlt(_localctx, 1); - setState(662); + setState(674); _la = _input->LA(1); - if (!((((_la & ~ 0x3fULL) == 0) && - ((1ULL << _la) & 1048320) != 0))) { + if (!(((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 1048320) != 0)) { _errHandler->recoverInline(this); } else { @@ -6217,10 +6255,10 @@ SIGParser::Pso_param_idContext* SIGParser::pso_param_id() { }); try { enterOuterAlt(_localctx, 1); - setState(664); + setState(676); _la = _input->LA(1); - if (!((((_la & ~ 0x3fULL) == 0) && - ((1ULL << _la) & 68718428160) != 0))) { + if (!(((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 68718428160) != 0)) { _errHandler->recoverInline(this); } else { @@ -6283,7 +6321,7 @@ SIGParser::Bool_typeContext* SIGParser::bool_type() { }); try { enterOuterAlt(_localctx, 1); - setState(666); + setState(678); _la = _input->LA(1); if (!(_la == SIGParser::TRUE @@ -6306,9 +6344,5 @@ SIGParser::Bool_typeContext* SIGParser::bool_type() { } void SIGParser::initialize() { -#if ANTLR4_USE_THREAD_LOCAL_CACHE - sigParserInitialize(); -#else ::antlr4::internal::call_once(sigParserOnceFlag, sigParserInitialize); -#endif } diff --git a/sources/SIGParser/.antlr/SIGParser.h b/sources/SIGParser/.antlr/SIGParser.h index a48d9763..d0062c01 100644 --- a/sources/SIGParser/.antlr/SIGParser.h +++ b/sources/SIGParser/.antlr/SIGParser.h @@ -1,5 +1,5 @@ -// Generated from c:/Users/Bohdan/Documents/GitHub/Spectrum/sources/SIGParser/SIG.g4 by ANTLR 4.13.1 +// Generated from SIG.g4 by ANTLR 4.11.1 #pragma once @@ -882,6 +882,8 @@ class SIGParser : public antlr4::Parser { antlr4::tree::TerminalNode *OBRACE(); Compute_pso_blockContext *compute_pso_block(); antlr4::tree::TerminalNode *CBRACE(); + std::vector option_block(); + Option_blockContext* option_block(size_t i); InheritContext *inherit(); virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override; @@ -1029,6 +1031,8 @@ class SIGParser : public antlr4::Parser { antlr4::tree::TerminalNode *OBRACE(); Workgraph_pso_blockContext *workgraph_pso_block(); antlr4::tree::TerminalNode *CBRACE(); + std::vector option_block(); + Option_blockContext* option_block(size_t i); InheritContext *inherit(); virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override; diff --git a/sources/SIGParser/Main.cpp b/sources/SIGParser/Main.cpp index 2775a2eb..3e22d530 100644 --- a/sources/SIGParser/Main.cpp +++ b/sources/SIGParser/Main.cpp @@ -114,6 +114,25 @@ int main() { auto p = parse(filename); + // Stamp every top-level named item with its source .sig path so + // templates can emit an autogenerated-from comment in the output. + std::string sig_path = "sources/SIGParser/" + + std::filesystem::path(filename).generic_string(); + auto tag = [&](auto& container) + { + for (auto& item : container) + item.source_file = sig_path; + }; + tag(p.tables); + tag(p.layouts); + tag(p.compute_pso); + tag(p.graphics_pso); + tag(p.workgraph_pso); + tag(p.raytrace_pso); + tag(p.rt); + tag(p.views); + tag(p.passes); + parsed.merge(p); }); diff --git a/sources/SIGParser/Parsed.h b/sources/SIGParser/Parsed.h index 5c4c803a..e2f84bed 100644 --- a/sources/SIGParser/Parsed.h +++ b/sources/SIGParser/Parsed.h @@ -46,6 +46,7 @@ struct parsed_type struct have_name : public virtual parsed_type { std::string name; + std::string source_file; // path of the .sig file that defined this item ~have_name() override = default; @@ -53,6 +54,7 @@ struct have_name : public virtual parsed_type SERIALIZE() { ar& NVP(name); + ar& NVP(source_file); } }; diff --git a/sources/SIGParser/SIG.g4 b/sources/SIGParser/SIG.g4 index 717f2740..a81c2d12 100644 --- a/sources/SIGParser/SIG.g4 +++ b/sources/SIGParser/SIG.g4 @@ -148,7 +148,7 @@ compute_pso_stat | COMMENT ; compute_pso_block: compute_pso_stat*; -compute_pso_definition: COMPUTE_PSO name_id inherit? OBRACE compute_pso_block CBRACE; +compute_pso_definition: option_block*? COMPUTE_PSO name_id inherit? OBRACE compute_pso_block CBRACE; graphics_pso_stat @@ -180,7 +180,7 @@ workgraph_pso_stat | COMMENT ; workgraph_pso_block: workgraph_pso_stat*; -workgraph_pso_definition: WORKGRAPH_PSO name_id inherit? OBRACE workgraph_pso_block CBRACE; +workgraph_pso_definition: option_block*? WORKGRAPH_PSO name_id inherit? OBRACE workgraph_pso_block CBRACE; diff --git a/sources/SIGParser/sigs/MipMapping.sig b/sources/SIGParser/sigs/MipMapping.sig index 6738d6c3..d36113b8 100644 --- a/sources/SIGParser/sigs/MipMapping.sig +++ b/sources/SIGParser/sigs/MipMapping.sig @@ -6,6 +6,10 @@ struct MipMapping float2 TexelSize; + # Split from OutMip[4] — fixed-size arrays in CBV structs accessed via + # ResourceDescriptorHeap cause DXC to emit duplicate OpTypeArray IDs in SPIR-V. + # Four individual fields have identical binary layout and avoid the issue. + # See REFACTOR_TODO.md for root cause and the proper template fix. RWTexture2D OutMip[4]; Texture2D SrcMip; diff --git a/sources/SIGParser/sigs/SS_Shadow.sig b/sources/SIGParser/sigs/SS_Shadow.sig index b2a0a0b0..3ecb798f 100644 --- a/sources/SIGParser/sigs/SS_Shadow.sig +++ b/sources/SIGParser/sigs/SS_Shadow.sig @@ -18,16 +18,16 @@ struct DispatchParameters float ShadowContrast = 4; # A contrast boost is applied to the transition in/out of shadow. # Recommended starting value: 2 or 4. Values >= 1 are valid. - bool IgnoreEdgePixels = false; # If an edge is detected, the edge pixel will not contribute to the shadow. + uint IgnoreEdgePixels = false; # If an edge is detected, the edge pixel will not contribute to the shadow. # If a very flat surface is being lit and rendered at an grazing angles, the edge detect may incorrectly detect multiple 'edge' pixels along that flat surface. # In these cases, the grazing angle of the light may subsequently produce aliasing artefacts in the shadow where these incorrect edges were detected. # Setting this value to true would mean that those pixels would not cast a shadow, however it can also thin out otherwise valid shadows, especially on foliage edges. # Recommended starting value: false, unless typical scenes have numerous large flat surfaces, in which case true. - bool UsePrecisionOffset = false; # A small offset is applied to account for an imprecise depth buffer (recommend off) + uint UsePrecisionOffset = false; # A small offset is applied to account for an imprecise depth buffer (recommend off) - bool BilinearSamplingOffsetMode = false;# There are two modes to compute bilinear samples for shadow depth: + uint BilinearSamplingOffsetMode = false;# There are two modes to compute bilinear samples for shadow depth: # true = sampling points for pixels are offset to the wavefront shared ray, shadow depths and starting depths are the same. Can project more jagged/aliased shadow lines in some cases. # false = sampling points for pixels are not offset and start from pixel centers. Shadow depths are biased based on depth gradient across the current pixel bilinear sample. Has more issues in back-face / grazing areas. # Both modes have subtle visual differences, which may / may not exaggerate depth buffer aliasing that gets projected in to the shadow. @@ -35,14 +35,14 @@ struct DispatchParameters # Recommended starting value: false # Debug views - bool DebugOutputEdgeMask = false; # Use this to visualize edges, for tuning the 'BilinearThreshold' value. - bool DebugOutputThreadIndex = false; # Debug output to visualize layout of compute threads - bool DebugOutputWaveIndex = false; # Debug output to visualize layout of compute wavefronts, useful to sanity check the Light Coordinate is being computed correctly. + uint DebugOutputEdgeMask = false; # Use this to visualize edges, for tuning the 'BilinearThreshold' value. + uint DebugOutputThreadIndex = false; # Debug output to visualize layout of compute threads + uint DebugOutputWaveIndex = false; # Debug output to visualize layout of compute wavefronts, useful to sanity check the Light Coordinate is being computed correctly. # Culling / Early out: float2 DepthBounds = float2(0,1); # Depth Bounds (min, max) for the on-screen volume of the light. Typically (0,1) for directional lights. Only used when 'UseEarlyOut' is true. - bool UseEarlyOut = false; # Set to true to early-out when depth values are not within [DepthBounds] - otherwise DepthBounds is unused + uint UseEarlyOut = false; # Set to true to early-out when depth values are not within [DepthBounds] - otherwise DepthBounds is unused # [Optionally customize the 'EarlyOutPixel()' function to perform your own early-out logic, e.g. skipping pixels that a shadow map indicates are already fully occluded] # This can dramatically reduce cost when only a small portion of the pixels need a shadow term (e.g., cull out sky pixels), however it does have some overhead (~15%) in worst-case where nothing early-outs # Note; Early-out is most efficient when WAVE_SIZE matches the hardware wavefront size - otherwise cross wave communication is required. diff --git a/sources/SIGParser/sigs/WorkGraph.sig b/sources/SIGParser/sigs/WorkGraph.sig index f44ca70b..60dec2db 100644 --- a/sources/SIGParser/sigs/WorkGraph.sig +++ b/sources/SIGParser/sigs/WorkGraph.sig @@ -18,7 +18,7 @@ struct GraphInput } -WorkgraphPSO WorkGR +[ExcludeVulkan] WorkgraphPSO WorkGR { root = DefaultLayout; diff --git a/sources/SIGParser/sigs/defaultlayout.sig b/sources/SIGParser/sigs/defaultlayout.sig index 3b3b4a7c..44f5986b 100644 --- a/sources/SIGParser/sigs/defaultlayout.sig +++ b/sources/SIGParser/sigs/defaultlayout.sig @@ -48,7 +48,7 @@ struct DebugInfo debug.v = v; - uav.debug[id] = debug; + GetDebug()[id] = debug; } }% diff --git a/sources/SIGParser/sigs/font_render.sig b/sources/SIGParser/sigs/font_render.sig index 17b68c02..00d127ac 100644 --- a/sources/SIGParser/sigs/font_render.sig +++ b/sources/SIGParser/sigs/font_render.sig @@ -3,7 +3,7 @@ struct FontRendering { Texture2D tex0; - Buffer positions; + StructuredBuffer positions; } [Bind = DefaultLayout::Instance1] @@ -48,5 +48,6 @@ GraphicsPSO FontRender rtv = { Format }; enable_depth = false; + cull = None; # blend = { AlphaBlend }; } \ No newline at end of file diff --git a/sources/SIGParser/sigs/test.sig b/sources/SIGParser/sigs/test.sig index 357b0ada..0963c364 100644 --- a/sources/SIGParser/sigs/test.sig +++ b/sources/SIGParser/sigs/test.sig @@ -8,7 +8,6 @@ struct Test StructuredBuffer instances[]; } - Pipeline MainPipeline { # scene prep diff --git a/sources/SIGParser/sigs/ui.sig b/sources/SIGParser/sigs/ui.sig index 795fe517..d09ab7b2 100644 --- a/sources/SIGParser/sigs/ui.sig +++ b/sources/SIGParser/sigs/ui.sig @@ -41,8 +41,10 @@ GraphicsPSO NinePatch [EntryPoint = PS] pixel = gui/ninepatch; - rtv = { R8G8B8A8_UNORM }; + rtv = { B8G8R8A8_UNORM }; blend = { AlphaBlend }; + + cull = None; } @@ -56,7 +58,7 @@ GraphicsPSO SimpleRect [EntryPoint = PS_COLOR] pixel = gui/rect; - rtv = { R8G8B8A8_UNORM }; + rtv = { B8G8R8A8_UNORM }; blend = { AlphaBlend }; cull = None; } @@ -75,7 +77,7 @@ GraphicsPSO CanvasBack cull = None; topology = TRIANGLE; - rtv = { R8G8B8A8_UNORM }; + rtv = { B8G8R8A8_UNORM }; blend = { AlphaBlend }; } @@ -115,7 +117,7 @@ GraphicsPSO CanvasLines cull = None; topology = PATCH; - rtv = { R8G8B8A8_UNORM }; + rtv = { B8G8R8A8_UNORM }; blend = { AlphaBlend }; } diff --git a/sources/SIGParser/templates/cpp/psos.jinja b/sources/SIGParser/templates/cpp/psos.jinja index 70f1b423..237b6bd0 100644 --- a/sources/SIGParser/templates/cpp/psos.jinja +++ b/sources/SIGParser/templates/cpp/psos.jinja @@ -34,20 +34,51 @@ void init_indirect_commands(HAL::Device& device, enum_array& pso) { std::vector> tasks; + {% for v in parsed.compute_pso -%} -{%- set t = parsed.compute_pso[v] -%} +{%- set t = parsed.compute_pso[v] -%} +{%- if t.options.ExcludeVulkan is undefined %} tasks.emplace_back(PSOBase::create(device, pso[PSO::{{t.name}}])); -{% endfor -%} +{%- endif %} +{%- endfor %} -{%- for v in parsed.graphics_pso -%} -{%- set t = parsed.graphics_pso[v] -%} +{% for v in parsed.graphics_pso -%} +{%- set t = parsed.graphics_pso[v] -%} +{%- if t.options.ExcludeVulkan is undefined %} tasks.emplace_back(PSOBase::create(device, pso[PSO::{{t.name}}])); -{% endfor -%} +{%- endif %} +{%- endfor %} -{%- for v in parsed.workgraph_pso -%} -{%- set t = parsed.workgraph_pso[v] -%} +{% for v in parsed.workgraph_pso -%} +{%- set t = parsed.workgraph_pso[v] -%} +{%- if t.options.ExcludeVulkan is undefined %} tasks.emplace_back(PSOBase::create(device, pso[PSO::{{t.name}}])); -{% endfor -%} +{%- endif %} +{%- endfor %} + +#ifndef HAL_BACKEND_VULKAN +{% for v in parsed.compute_pso -%} +{%- set t = parsed.compute_pso[v] -%} +{%- if t.options.ExcludeVulkan is defined %} + tasks.emplace_back(PSOBase::create(device, pso[PSO::{{t.name}}])); +{%- endif %} +{%- endfor %} + +{% for v in parsed.graphics_pso -%} +{%- set t = parsed.graphics_pso[v] -%} +{%- if t.options.ExcludeVulkan is defined %} + tasks.emplace_back(PSOBase::create(device, pso[PSO::{{t.name}}])); +{%- endif %} +{%- endfor %} + +{% for v in parsed.workgraph_pso -%} +{%- set t = parsed.workgraph_pso[v] -%} +{%- if t.options.ExcludeVulkan is defined %} + tasks.emplace_back(PSOBase::create(device, pso[PSO::{{t.name}}])); +{%- endif %} +{%- endfor %} +#endif // !HAL_BACKEND_VULKAN + when_all(begin(tasks), end(tasks)).wait(); } diff --git a/sources/SIGParser/templates/hlsl/layout.jinja b/sources/SIGParser/templates/hlsl/layout.jinja index 4d3f4fcd..93f0a3b0 100644 --- a/sources/SIGParser/templates/hlsl/layout.jinja +++ b/sources/SIGParser/templates/hlsl/layout.jinja @@ -13,3 +13,19 @@ {%- for s in layout.samplers %} SamplerState {{s.name}}:register(s{{loop.index0}}); {%- endfor-%} + +{%- if layout.parent is undefined %} +#ifdef __spirv__ +struct _HALPush { + uint s0; uint s1; uint s2; uint s3; + uint s4; uint s5; uint s6; uint s7; + uint s8; uint s9; uint s10; uint s11; + uint s12; uint s13; uint s14; uint s15; + uint s16; uint s17; uint s18; uint s19; + uint s20; uint s21; uint s22; uint s23; + uint s24; uint s25; uint s26; uint s27; + uint s28; uint s29; uint s30; uint s31; +}; +[[vk::push_constant]] ConstantBuffer<_HALPush> _hal_push; +#endif +{%- endif %} diff --git a/sources/SIGParser/templates/hlsl/slot.jinja b/sources/SIGParser/templates/hlsl/slot.jinja index a55920e9..0c72b675 100644 --- a/sources/SIGParser/templates/hlsl/slot.jinja +++ b/sources/SIGParser/templates/hlsl/slot.jinja @@ -19,7 +19,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_{{table.name}}: register( b2, space{{slot.id}}); +#ifdef __spirv__ +struct _CB_{{table.name}} { uint offset; }; +static _CB_{{table.name}} pass_{{table.name}} = { _hal_push.s{{slot.id}} }; +#else +ConstantBuffer pass_{{table.name}}: register(b{{slot.id}}, space{{slot.id}}); +#endif ConstantBuffer<{{table.name}}> Create{{table.name}}() { @@ -27,6 +32,6 @@ ConstantBuffer<{{table.name}}> Create{{table.name}}() } #ifndef NO_GLOBAL -static const {{table.name}} {{lowerize(table.name) }}_global = Create{{table.name}}(); -const {{table.name}} Get{{table.name|title}}(){ return {{lowerize(table.name)}}_global; } +static const ConstantBuffer<{{table.name}}> {{lowerize(table.name) }}_global = Create{{table.name}}(); +ConstantBuffer<{{table.name}}> Get{{table.name|title}}(){ return {{lowerize(table.name)}}_global; } #endif \ No newline at end of file diff --git a/sources/SIGParser/templates/hlsl/table.jinja b/sources/SIGParser/templates/hlsl/table.jinja index 4fc05a44..6f2240a9 100644 --- a/sources/SIGParser/templates/hlsl/table.jinja +++ b/sources/SIGParser/templates/hlsl/table.jinja @@ -14,6 +14,7 @@ {%- endfor -%} + {%- macro declare_func(type) -%} {%- for v in (table.values|unique|selectattr('value_type','==', type)) -%} {%- if (not v.pointer and (v.value_type == ValueType.CB or v.value_type == ValueType.STRUCT)) %} @@ -34,7 +35,15 @@ struct {{"[raypayload]" if table.options.raypayload is defined}}{{table.name}} {%- for v in (table.values|unique|list) -%} {%- if v.value_type == ValueType.CB or v.value_type == ValueType.STRUCT %} + {%- if v.as_array and v.array_count > 1 %} + {{v.type if not v.pointer else "uint"}} Get{{v.name|camel}}(int i) { return {{v.name}}[i]; } + {%- else %} + {%- if v.value_type == ValueType.STRUCT and not v.pointer and not v.as_array %} + {{v.type}} Get{{v.name|camel}}() { return {{v.name}}; } + {%- else %} {{v.type if not v.pointer else "uint"}} Get{{v.name|camel}}({{"int i" if v.as_array}}) { return {{v.name}}{{"[i]" if v.as_array}}; } + {%- endif %} + {%- endif %} {%-endif-%} {%-endfor-%} @@ -42,12 +51,14 @@ struct {{"[raypayload]" if table.options.raypayload is defined}}{{table.name}} {%- if v.value_type != ValueType.CB and v.value_type != ValueType.STRUCT -%} {%- set type = v.type | replace_start("RenderTarget", "Texture2D") | replace_start("DepthStencil", "Texture2D")-%} {%if v.as_array and v.bindless %} - {{type}} Get{{v.name|camel}}(int i) + {{type}} Get{{v.name|camel}}(int i) { - StructuredBuffer indirection = ResourceDescriptorHeap[{{v.name}}]; + StructuredBuffer indirection = ResourceDescriptorHeap[{{v.name}}]; uint id = indirection.Load(i); - return ResourceDescriptorHeap[id]; + return ResourceDescriptorHeap[id]; } +{%elif v.as_array and v.array_count > 1 %} + {{type}} Get{{v.name|camel}}(int i) { return ResourceDescriptorHeap[{{v.name}}[i]]; } {%else%} {{type}} Get{{v.name|camel}}({{"int i" if v.as_array}}) { return ResourceDescriptorHeap[{{v.name}}{{"[i]" if v.as_array}}]; } {%-endif-%} diff --git a/sources/Spectrum/RTXPassSystem.ixx b/sources/Spectrum/RTXPassSystem.ixx deleted file mode 100644 index 0513cffd..00000000 --- a/sources/Spectrum/RTXPassSystem.ixx +++ /dev/null @@ -1,115 +0,0 @@ -export module Graphics:RTXPassSystem; - - -import :FrameGraphContext; -import :Context; -import :MeshRenderer; -import FrameGraph; -import HAL; - -#define A_CPU -#include "bend_sss_cpu.h" - -#include "../RenderSystem/FrameGraph/autogen/pass_defaults.h" - -using namespace FrameGraph; - -bool PassDefault::setup( - Passes::RTXPass::Context& data, FrameGraph::TaskBuilder& builder) -{ - auto& frame = builder.graph->get_context(); - auto work_pso = HAL::Device::get().get_engine_pso_holder().GetPSO(); - auto size = frame.frame_size; - - builder.need(data.gbuffer.GBuffer_Albedo, ResourceFlags::PixelRead | ResourceFlags::ComputeRead); - builder.need(data.gbuffer.GBuffer_Normals, ResourceFlags::PixelRead | ResourceFlags::ComputeRead); - builder.need(data.gbuffer.GBuffer_Depth, ResourceFlags::PixelRead | ResourceFlags::ComputeRead); - builder.need(data.gbuffer.GBuffer_Specular, ResourceFlags::PixelRead | ResourceFlags::ComputeRead); - builder.need(data.gbuffer.GBuffer_Speed, ResourceFlags::PixelRead | ResourceFlags::ComputeRead); - builder.need(data.gbuffer.GBuffer_DepthPrev, ResourceFlags::PixelRead | ResourceFlags::ComputeRead); - builder.need(data.gbuffer.GBuffer_DepthMips, ResourceFlags::None); - - builder.create(data.RTXDebug, - { ivec3(size, 0), HAL::Format::R16G16B16A16_FLOAT, 1 }, - ResourceFlags::UnorderedAccess); - builder.create(data.WorkGraphBuffer, { work_pso->buffer_size }, - ResourceFlags::UnorderedAccess); - - return true; -} - -void PassDefault::render( - Passes::RTXPass::Context& data, FrameGraph::FrameContext& context) -{ - auto& scene_ctx = context.graph->get_context(); - auto& camera_ctx = context.graph->get_context(); - auto& sky_ctx = context.graph->get_context(); - - auto& compute = context.get_list()->get_compute(); - - if (data.RTXDebug.is_new()) - context.get_list()->clear_uav(data.RTXDebug->rwTexture2D, vec4(0, 0, 0, 0)); - - auto& backingBuffer = data.WorkGraphBuffer->resource; - auto work_pso = HAL::Device::get().get_engine_pso_holder().GetPSO(); - - compute.set_program(work_pso.get(), - backingBuffer->get_resource_address(), - uint(work_pso->buffer_size), - data.WorkGraphBuffer.is_new()); - - context.graph->set_slot(SlotID::VoxelInfo, compute); - context.graph->set_slot(SlotID::FrameInfo, compute); - context.graph->set_slot(SlotID::SceneData, compute); - - GBuffer gbuffer=GBufferViewDesc::actualize(data.gbuffer); - - - { - Slots::Raytracing rtx; - rtx.GetScene() = scene_ctx.scene->raytrace_scene->raytracing_handle; - compute.set(rtx); - } - { - Slots::VoxelScreen voxelScreen; - gbuffer.SetTable(voxelScreen.GetGbuffer()); - voxelScreen.GetPrev_depth() = gbuffer.depth_prev_mips; - compute.set(voxelScreen); - } - - auto light = float4(sky_ctx.sunDir, 0) * camera_ctx.cam->get_view_proj(); - - Bend::DispatchList res = Bend::BuildDispatchList( - { light.x, light.y, light.z, light.w }, - { data.RTXDebug->get_size().x, data.RTXDebug->get_size().y }, - { 0, 0 }, - { data.RTXDebug->get_size().x, data.RTXDebug->get_size().y }, - false, 64); - - Slots::DispatchParameters dispatchParameters; - dispatchParameters.GetDepthTexture() = gbuffer.depth.texture2D; - dispatchParameters.GetOutputTexture() = data.RTXDebug->rwTexture2D; - dispatchParameters.GetLightCoordinate() = float4( - res.LightCoordinate_Shader[0], res.LightCoordinate_Shader[1], - res.LightCoordinate_Shader[2], res.LightCoordinate_Shader[3]); - dispatchParameters.FarDepthValue = 0; - dispatchParameters.NearDepthValue = 1; - dispatchParameters.InvDepthTextureSize = float2( - 1.0f / data.RTXDebug->get_size().x, - 1.0f / data.RTXDebug->get_size().y); - compute.set(dispatchParameters); - - auto ep = create_entry(compute); - for (auto i = 0; i < res.DispatchCount; i++) - { - auto& e = res.Dispatch[i]; - { - Slots::GraphInput input; - input.GetDispatch_grid() = vec3(e.WaveCount[0], e.WaveCount[1], e.WaveCount[2]); - input.GetWaveOffset() = int2(e.WaveOffset_Shader[0], e.WaveOffset_Shader[1]); - ep.add(0, input); - } - } - if (res.DispatchCount) - compute.dispatch_graph(ep.compile()); -} diff --git a/sources/Spectrum/main.cpp b/sources/Spectrum/main.cpp index 363aa1f8..54eee687 100644 --- a/sources/Spectrum/main.cpp +++ b/sources/Spectrum/main.cpp @@ -25,67 +25,6 @@ using namespace FrameGraph; using namespace HAL; -// ============================================================ -// PassDefault implementations -// ============================================================ - -// ---- ResultCreation ------------------------------------------------ - -bool PassDefault::setup( - Passes::ResultCreation::Context& data, FrameGraph::TaskBuilder& builder) -{ - auto& frame = builder.graph->get_context(); - builder.create(data.ResultTexture, - { uint3(frame.frame_size, 0), HAL::Format::R16G16B16A16_FLOAT, 1, 1 }, - FrameGraph::ResourceFlags::RenderTarget); - return false; -} - -void PassDefault::render( - Passes::ResultCreation::Context&, FrameGraph::FrameContext&) {} - - -// ---- CopyPrev ------------------------------------------------------ - -bool PassDefault::setup( - Passes::CopyPrev::Context& data, FrameGraph::TaskBuilder& builder) -{ - builder.need(data.gbuffer.GBuffer_NormalsPrev, FrameGraph::ResourceFlags::CopyDest); - builder.need(data.gbuffer.GBuffer_SpecularPrev, FrameGraph::ResourceFlags::CopyDest); - builder.need(data.gbuffer.GBuffer_Normals, FrameGraph::ResourceFlags::CopySource); - builder.need(data.gbuffer.GBuffer_Specular, FrameGraph::ResourceFlags::CopySource); - builder.need(data.gbuffer.GBuffer_DepthPrev, FrameGraph::ResourceFlags::CopyDest); - builder.need(data.gbuffer.GBuffer_DepthMips, FrameGraph::ResourceFlags::CopySource); - return true; -} - -void PassDefault::render( - Passes::CopyPrev::Context& data, FrameGraph::FrameContext& context) -{ - auto& copy = context.get_list()->get_copy(); - - copy.copy_resource(data.gbuffer.GBuffer_NormalsPrev->resource, - data.gbuffer.GBuffer_Normals->resource); - copy.copy_resource(data.gbuffer.GBuffer_SpecularPrev->resource, - data.gbuffer.GBuffer_Specular->resource); - copy.copy_texture(data.gbuffer.GBuffer_DepthPrev->resource, 0, - data.gbuffer.GBuffer_DepthMips->resource, 0); -} - - -// ---- Profiler ------------------------------------------------------ - -bool PassDefault::setup( - Passes::Profiler::Context& data, FrameGraph::TaskBuilder& builder) -{ - builder.need(data.swapchain, - FrameGraph::ResourceFlags::Required | FrameGraph::ResourceFlags::RenderTarget); - return false; -} - -void PassDefault::render( - Passes::Profiler::Context&, FrameGraph::FrameContext&) {} - class tick_timer { @@ -515,6 +454,7 @@ namespace GUI } + class GraphRender : public Window, public GUI::user_interface { HAL::SwapChain::ptr swap_chain; @@ -579,6 +519,8 @@ class GraphRender : public Window, public GUI::user_interface } Profiler::get().on_frame(frame_counter++); + if (frame_counter <= 5) + Log::get() << "[Render] frame " << frame_counter << Log::endl; { PROFILE(L"GarbageCollect"); Device::get().get_heap_factory().GarbageCollect(); @@ -620,12 +562,69 @@ class GraphRender : public Window, public GUI::user_interface auto fence = graph.commit_command_lists(); + + // ---- One-shot debug screenshot ---------------------------------------- + // Fires on the first rendered frame. Uses HAL::texture_data::from_readback + // + to_png() (same pattern as Test.HAL.TextureUtils) to write screenshot.png + // in the working directory. Lets us verify GPU pixel output independently + // of any swapchain-presentation issues. + { + static int screenshot_countdown = 1; + if (screenshot_countdown > 0 && --screenshot_countdown == 0) + { + Log::get() << "[Screenshot] Starting readback on frame " << frame_counter << Log::endl; + fence.wait(); // ensure GPU finished rendering + PRESENT transition + + const auto& sc_res = swap_chain->get_current_frame(); + const auto& tex_desc = sc_res->get_desc().as_texture(); + const uint32_t w = tex_desc.Dimensions.x; + const uint32_t h = tex_desc.Dimensions.y ? tex_desc.Dimensions.y : 1; + const HAL::Format fmt = tex_desc.Format; + + HAL::texture_data::ptr result; + auto ss_list = HAL::Device::get().get_upload_list(); + auto fut = ss_list->get_copy().read_texture( + sc_res.get(), 0, + [&](std::span data, HAL::texture_layout layout) + { + result = HAL::texture_data::from_readback(w, h, fmt, data, layout); + }); + // Restore swapchain to PRESENT layout so present() works correctly. + // On Vulkan this barrier is deferred to end() so it always fires + // after the copy regardless of recording order. + ss_list->transition_present(sc_res.get()); + ss_list->execute_and_wait(); + fut.wait(); + + if (result) + { + auto png = result->to_png(); + if (!png.empty()) + { + std::string png_str(reinterpret_cast(png.data()), png.size()); + FileSystem::get().save_data("screenshot.png", png_str); + Log::get() << "[Screenshot] Saved screenshot.png " + << w << "x" << h << Log::endl; + } + else + Log::get() << "[Screenshot] to_png() returned empty" << Log::endl; + } + else + Log::get() << "[Screenshot] from_readback() returned null" << Log::endl; + } + } + // ----------------------------------------------------------------------- + { PROFILE(L"reset"); graph.reset(); } + if (frame_counter <= 5) + Log::get() << "[Render] calling present frame " << frame_counter << Log::endl; swap_chain->present(); + if (frame_counter <= 5) + Log::get() << "[Render] present returned frame " << frame_counter << Log::endl; } @@ -826,6 +825,7 @@ class GraphRender : public Window, public GUI::user_interface auto d = std::make_shared(); docker = d; d->docking = GUI::dock::FILL; +#ifndef HAL_BACKEND_VULKAN { EVENT("Start Drawer"); drawer.reset(new triangle_drawer()); @@ -834,6 +834,7 @@ class GraphRender : public Window, public GUI::user_interface d->get_tabs()->add_page("Game", drawer); EVENT("End Drawer"); } +#endif { // auto text = std::make_shared(); @@ -913,6 +914,7 @@ class GraphRender : public Window, public GUI::user_interface { add_task([this]() { + if (!drawer) return; drawer->scene->remove_all(); }); }; @@ -920,6 +922,7 @@ class GraphRender : public Window, public GUI::user_interface { add_task([this]() { + if (!drawer) return; try { auto f = FileSystem::get().get_file(to_path(L"scene.dat"))->load_all(); @@ -935,6 +938,7 @@ class GraphRender : public Window, public GUI::user_interface }; file->add_item("Save")->on_click = [this](GUI::Elements::menu_list_element::ptr elem) { + if (!drawer) return; auto data = Serializer::serialize(*drawer->scene); FileSystem::get().save_data(to_path(L"scene.dat"), data); }; @@ -1072,7 +1076,9 @@ class RenderApplication : public Application RTX::create(); EVENT("AssetManager"); +#ifndef HAL_BACKEND_VULKAN AssetRenderer::create(); +#endif AssetManager::create(); EVENT("WindowRender"); @@ -1111,21 +1117,18 @@ class RenderApplication : public Application /// main_window2 = nullptr; Fonts::FontSystem::reset(); RTX::reset(); +#ifndef HAL_BACKEND_VULKAN AssetRenderer::reset(); TextureAssetRenderer::reset(); +#endif AssetManager::reset(); materials::PipelineManager::reset(); universal_nodes_manager::reset(); universal_mesh_instance_manager::reset(); - // universal_mesh_info_part_manager::get().prepare(command_list); universal_material_info_part_manager::reset(); universal_rtx_manager::reset(); - //HAL::PipelineLibrary::reset(); - GUI::NinePatch::index_buffer = StructuredBufferView(); - HAL::Device::reset(); - // HAL::Device::reset(); } diff --git a/sources/Test/Defines.h b/sources/Test/Defines.h index 6c0bb3f8..a8c90d04 100644 --- a/sources/Test/Defines.h +++ b/sources/Test/Defines.h @@ -9,10 +9,18 @@ #define CONCAT(a, b) a##b #define CONCAT_IMPL(a, b) CONCAT(a, b) +// Each test file must define TEST_MODULE_ID with a unique per-file token before +// using TEST(). The generated function names become test_{MODULE}_{LINE}, which +// are globally unique across all test modules. Combined with `inline`, this +// prevents LNK2005 errors when MSVC copies function bodies across import boundaries. +// +// Example (at file scope, before any TEST use): +// #define TEST_MODULE_ID HALRendering + #define TEST(category, name) \ - void CONCAT_IMPL(test_, __LINE__)(); \ - Test::TestRegistrator CONCAT_IMPL(registrator_, __LINE__)(#category, #name, CONCAT_IMPL(test_, __LINE__), __FILE__, __LINE__); \ - void CONCAT_IMPL(test_, __LINE__)() + inline void CONCAT_IMPL(CONCAT_IMPL(test_, TEST_MODULE_ID), CONCAT_IMPL(_, __LINE__))(); \ + inline ::Test::TestRegistrator CONCAT_IMPL(CONCAT_IMPL(registrator_, TEST_MODULE_ID), CONCAT_IMPL(_, __LINE__))(#category, #name, CONCAT_IMPL(CONCAT_IMPL(test_, TEST_MODULE_ID), CONCAT_IMPL(_, __LINE__)), __FILE__, __LINE__); \ + inline void CONCAT_IMPL(CONCAT_IMPL(test_, TEST_MODULE_ID), CONCAT_IMPL(_, __LINE__))() #define ASSERT_TRUE(condition) \ Test::AssertTrue(condition, #condition, __FILE__, __LINE__) diff --git a/sources/Test/TestFramework/Test.Framework.ixx b/sources/Test/TestFramework/Test.Framework.ixx index d01abeb7..62f86e3a 100644 --- a/sources/Test/TestFramework/Test.Framework.ixx +++ b/sources/Test/TestFramework/Test.Framework.ixx @@ -6,6 +6,8 @@ module; #include #include #include +#include +#include export module Test.Framework; @@ -67,13 +69,27 @@ export namespace Test skipped_categories[category] = reason; } - std::vector RunAll() + std::vector RunAll(std::string_view filter = {}) { std::vector results; std::set ranSetups; + auto matches = [&](const Test& t) -> bool { + if (filter.empty()) return true; + std::string full = t.category.empty() ? t.name : t.category + "::" + t.name; + std::string lf(filter), lful(full); + std::transform(lf.begin(), lf.end(), lf.begin(), [](unsigned char c){ return std::tolower(c); }); + std::transform(lful.begin(), lful.end(), lful.begin(), [](unsigned char c){ return std::tolower(c); }); + return lful.find(lf) != std::string::npos; + }; + + auto matchCount = std::count_if(tests.begin(), tests.end(), matches); + Log::get() << Log::LEVEL_INFO << "========== Starting Tests ==========" << Log::endl; - Log::get() << Log::LEVEL_INFO << "Running " << tests.size() << " test(s)..." << Log::endl; + if (!filter.empty()) + Log::get() << Log::LEVEL_INFO << "Filter: \"" << std::string(filter) << "\" (" << matchCount << " of " << tests.size() << " test(s) selected)" << Log::endl; + else + Log::get() << Log::LEVEL_INFO << "Running " << tests.size() << " test(s)..." << Log::endl; auto runTeardown = [&](const std::string& category) { @@ -90,6 +106,8 @@ export namespace Test for (const auto& test : tests) { + if (!matches(test)) continue; + if (test.category != currentCategory) { runTeardown(currentCategory); diff --git a/sources/Test/Tests/Test.Core.ixx b/sources/Test/Tests/Test.Core.ixx index 394c73ab..22577757 100644 --- a/sources/Test/Tests/Test.Core.ixx +++ b/sources/Test/Tests/Test.Core.ixx @@ -2,6 +2,8 @@ module; export module Test.Core; +#define TEST_MODULE_ID CoreTests + export import Test.Framework; import Core; diff --git a/sources/Test/Tests/Test.Events.ixx b/sources/Test/Tests/Test.Events.ixx index 24b7e302..397e7708 100644 --- a/sources/Test/Tests/Test.Events.ixx +++ b/sources/Test/Tests/Test.Events.ixx @@ -1,5 +1,7 @@ export module Test.Events; +#define TEST_MODULE_ID Events + export import Test.Framework; import Core; diff --git a/sources/Test/Tests/Test.FileSystem.ixx b/sources/Test/Tests/Test.FileSystem.ixx index 7e1bdd02..5e4f3c19 100644 --- a/sources/Test/Tests/Test.FileSystem.ixx +++ b/sources/Test/Tests/Test.FileSystem.ixx @@ -1,5 +1,7 @@ export module Test.FileSystem; +#define TEST_MODULE_ID FileSystem + export import Test.Framework; import Core; diff --git a/sources/Test/Tests/Test.FrameGraph.ixx b/sources/Test/Tests/Test.FrameGraph.ixx new file mode 100644 index 00000000..1bf1c34f --- /dev/null +++ b/sources/Test/Tests/Test.FrameGraph.ixx @@ -0,0 +1,89 @@ +export module Test.FrameGraph; + +#define TEST_MODULE_ID FG + +export import Test.Framework; +export import Test.HAL.TextureUtils; + +import Core; +import HAL; +import GUI; +import FrameGraph; + +// PassDefault specialisation declarations — bodies live in RenderSystem. +// Must be included AFTER the module imports so Passes::* and FrameGraph::* +// types are already in scope (mirrors how VulkanTest/main.cpp does it). +#include "RenderSystem/FrameGraph/autogen/pass_defaults.h" + +export namespace Test +{ + // Exercises the complete UIPipeline path end-to-end: + // GUI::user_interface layout → UIPipeline::add_passes (Profiler + 16×UI_Render) + // → create_graph → Graph::setup/compile/render/commit → golden image comparison. + // + // UI: dark background fill, a 64px red top band, and a green fill area. + // Rendered into a 512×256 B8G8R8A8_UNORM off-screen texture. + TEST(Core.HAL, FrameGraph_UIPipeline) + { + THREAD_SCOPE(GUI); + auto& device = HAL::Device::get(); + constexpr uint W = 512, H = 256; + + auto rt = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {W, H}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + // ---- Build the UI hierarchy ------------------------------------------- + GUI::user_interface ui; + ui.size = vec2((float)W, (float)H); + + // Full-screen dark-blue background (dock NONE, MATCH_PARENT) + { + auto bg = std::make_shared(); + bg->color = float4(0.10f, 0.15f, 0.25f, 1.0f); + bg->width_size = GUI::size_type::MATCH_PARENT; + bg->height_size = GUI::size_type::MATCH_PARENT; + ui.add_child(bg); + } + // Red top band, 64px tall + { + auto top = std::make_shared(); + top->color = float4(0.70f, 0.15f, 0.10f, 1.0f); + top->docking = GUI::dock::TOP; + top->height_size = GUI::size_type::FIXED; + top->width_size = GUI::size_type::MATCH_PARENT; + top->size = vec2(0.0f, 64.0f); + ui.add_child(top); + } + // Green fill area (remaining space after the top band) + { + auto fill = std::make_shared(); + fill->color = float4(0.10f, 0.55f, 0.25f, 1.0f); + fill->docking = GUI::dock::FILL; + ui.add_child(fill); + } + + ui.process_ui(0.0f); + + // ---- Drive the FrameGraph -------------------------------------------- + FrameGraph::Graph graph; + Pipelines::UIPipeline pipeline; + + graph.start_new_frame(); + graph.builder.pass_texture("swapchain", rt); + + pipeline.add_passes(graph); + ui.create_graph(graph); // populates UIContext::draw_infos + + graph.setup(); + graph.compile(0); + graph.render(); + auto fence = graph.commit_command_lists(); + fence.wait(); + + ASSERT_TEXTURE(rt.get(), "fg_uipipeline"); + + graph.reset(); + } +} diff --git a/sources/Test/Tests/Test.GUI.ixx b/sources/Test/Tests/Test.GUI.ixx new file mode 100644 index 00000000..2b079479 --- /dev/null +++ b/sources/Test/Tests/Test.GUI.ixx @@ -0,0 +1,763 @@ +export module Test.GUI; + +#define TEST_MODULE_ID GUI + +export import Test.Framework; +export import Test.HAL.TextureUtils; + +import Core; +import HAL; +import GUI; +import FrameGraph; +import TextSystem; + +// ----------------------------------------------------------------------- +// Clipping/culling helpers shared by the NinePatch clip tests. +// +// Source: 32x32 with 8px corners (RED corners, GREEN h-edges, +// BLUE v-edges, WHITE center). Padding 8px on all sides. +// Patch: 160x80 placed at (48,24) inside a 256x128 RT. +// Corner X boundaries in screen space: 48, 56, 200, 208 +// Corner Y boundaries in screen space: 24, 32, 96, 104 +// ----------------------------------------------------------------------- +namespace +{ + std::shared_ptr make_ninepatch_src(HAL::Device& device) + { + constexpr uint TEX_W = 32, TEX_H = 32, CORNER = 8; + auto src = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::R8G8B8A8_UNORM, {TEX_W, TEX_H}, 1, 1), + HAL::HeapType::DEFAULT); + + std::vector px(TEX_W * TEX_H * 4); + for (uint y = 0; y < TEX_H; ++y) + for (uint x = 0; x < TEX_W; ++x) + { + bool cx = (x < CORNER || x >= TEX_W - CORNER); + bool cy = (y < CORNER || y >= TEX_H - CORNER); + uint8_t r, g, b; + if ( cx && cy) { r=255; g=0; b=0; } + else if (!cx && cy) { r=0; g=255; b=0; } + else if ( cx && !cy) { r=0; g=0; b=255; } + else { r=255; g=255; b=255; } + size_t i = ((size_t)y * TEX_W + x) * 4; + px[i]=r; px[i+1]=g; px[i+2]=b; px[i+3]=255; + } + + auto upload = device.get_upload_list(); + upload->get_copy().update_texture(src.get(), ivec3(0,0,0), ivec3(TEX_W,TEX_H,1), 0, + reinterpret_cast(px.data()), TEX_W * 4); + upload->execute_and_wait(); + return src; + } + + std::shared_ptr run_clip_test( + HAL::Device& device, sizer_long clip, const wchar_t* label) + { + constexpr uint RT_W = 256, RT_H = 128; + auto src = make_ninepatch_src(device); + + auto rt = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {RT_W, RT_H}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + auto list = device.get_queue(HAL::CommandListType::DIRECT)->get_free_list(); + list->begin(label); + + HAL::Texture2DView src_view(src, *list); + HAL::Texture2DView rt_view(rt, *list); + + HAL::CompiledRT compiled; + compiled.table_rtv = rt_view.renderTarget; + list->get_graphics().set_rtv(compiled, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.05f, 0.05f, 0.1f, 1.0f)); + + sizer_long full_vp{ 0, 0, (long)RT_W, (long)RT_H }; + list->get_graphics().set_scissors(full_vp); + + GUIInfo c; + c.renderer = nullptr; + c.command_list = list; + c.window_size = vec2((float)RT_W, (float)RT_H); + c.offset = vec2(0.0f, 0.0f); + c.ui_clipping = clip; + c.scissors = full_vp; + c.scale = 1.0f; + c.delta_time = 0.0f; + + GUI::Texture item; + item = src_view; + item.padding = sizer(8.0f, 8.0f, 8.0f, 8.0f); + + GUI::NinePatch nine_patch; + nine_patch.draw(c, item, rect{ vec2(48.0f, 24.0f), vec2(160.0f, 80.0f) }); + nine_patch.flush(c); + + list->execute_and_wait(); + return rt; + } +} + +export namespace Test +{ + // Verifies that process_ui() propagates render_bounds to a fill-docked child. + // Pure layout check — no GPU work required. + TEST(Core.HAL, GUILayout_Fill) + { + THREAD_SCOPE(GUI); + GUI::user_interface ui; + ui.size = vec2(256.0f, 256.0f); + + auto cr = std::make_shared(); + cr->color = float4(1.0f, 0.0f, 0.0f, 1.0f); + cr->docking = GUI::dock::FILL; + ui.add_child(cr); + ui.process_ui(0.0f); + + rect b = cr->get_render_bounds(); + ASSERT_TRUE(b.x == 0.0f); + ASSERT_TRUE(b.y == 0.0f); + ASSERT_TRUE(b.w == 256.0f); + ASSERT_TRUE(b.h == 256.0f); + } + + // Verifies that dock::TOP elements consume space from the top and dock::FILL + // elements get the remaining area — non-overlapping horizontal bands. + TEST(Core.HAL, GUILayout_DockedBands) + { + THREAD_SCOPE(GUI); + GUI::user_interface ui; + ui.size = vec2(256.0f, 256.0f); + + auto top_rect = std::make_shared(); + top_rect->color = float4(1.0f, 0.0f, 0.0f, 1.0f); + top_rect->docking = GUI::dock::TOP; + top_rect->size = vec2(256.0f, 80.0f); + top_rect->width_size = GUI::size_type::MATCH_PARENT; + top_rect->height_size = GUI::size_type::FIXED; + + auto fill_rect = std::make_shared(); + fill_rect->color = float4(0.0f, 1.0f, 0.0f, 1.0f); + fill_rect->docking = GUI::dock::FILL; + + ui.add_child(top_rect); + ui.add_child(fill_rect); + ui.process_ui(0.0f); + + rect tb = top_rect->get_render_bounds(); + rect fb = fill_rect->get_render_bounds(); + + ASSERT_TRUE(tb.y == 0.0f); + ASSERT_TRUE(tb.h == 80.0f); + ASSERT_TRUE(fb.y == 80.0f); + ASSERT_TRUE(fb.h == 176.0f); + } + + // Tests GUI::Renderer::draw_color: renders a centered rect in pixel space and + // verifies the result via golden image comparison. Pixel (64,64)→(192,192) in + // a 256×256 window maps to clip ±0.5 — the inner half of the screen. + TEST(Core.HAL, GUIRenderer_DrawColor) + { + THREAD_SCOPE(GUI); + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 256, HEIGHT = 256; + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"GUIRenderer_DrawColor"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled_rt; + compiled_rt.table_rtv = view.renderTarget; + list->get_graphics().set_rtv(compiled_rt, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.1f, 0.1f, 0.2f, 1.0f)); + + sizer_long full_vp; + full_vp.left = 0; + full_vp.top = 0; + full_vp.right = (long)WIDTH; + full_vp.bottom = (long)HEIGHT; + + GUI::Renderer renderer; + GUIInfo c; + c.renderer = &renderer; + c.command_list = list; + c.window_size = vec2((float)WIDTH, (float)HEIGHT); + c.offset = vec2(0.0f, 0.0f); + c.ui_clipping = full_vp; + c.scissors = full_vp; + c.scale = 1.0f; + c.delta_time = 0.0f; + + renderer.draw_color(c, float4(0.8f, 0.3f, 0.1f, 1.0f), + rect{ vec2(64.0f, 64.0f), vec2(128.0f, 128.0f) }); + renderer.flush(c); + + list->execute_and_wait(); + ASSERT_TEXTURE(tex.get(), "gui_renderer_draw_color"); + } + + // Tests colored_rect::draw through the full element dispatch path: + // user_interface layout → colored_rect::draw → Renderer::draw_color → PSOS::SimpleRect. + TEST(Core.HAL, GUIElement_ColoredRect) + { + THREAD_SCOPE(GUI); + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 256, HEIGHT = 256; + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + GUI::user_interface ui; + ui.size = vec2((float)WIDTH, (float)HEIGHT); + + auto cr = std::make_shared(); + cr->color = float4(0.2f, 0.7f, 0.4f, 1.0f); + cr->docking = GUI::dock::FILL; + ui.add_child(cr); + ui.process_ui(0.0f); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"GUIElement_ColoredRect"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled_rt; + compiled_rt.table_rtv = view.renderTarget; + list->get_graphics().set_rtv(compiled_rt, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.1f, 0.1f, 0.2f, 1.0f)); + + sizer_long full_vp; + full_vp.left = 0; + full_vp.top = 0; + full_vp.right = (long)WIDTH; + full_vp.bottom = (long)HEIGHT; + + GUI::Renderer renderer; + GUIInfo c; + c.renderer = &renderer; + c.command_list = list; + c.window_size = vec2((float)WIDTH, (float)HEIGHT); + c.offset = vec2(0.0f, 0.0f); + c.ui_clipping = full_vp; + c.scissors = full_vp; + c.scale = 1.0f; + c.delta_time = 0.0f; + + cr->draw(c); + renderer.flush(c); + + list->execute_and_wait(); + ASSERT_TEXTURE(tex.get(), "gui_element_colored_rect"); + } + + // Tests that three docked bands render as distinct horizontal stripes with + // correct pixel boundaries, verifying both layout and rendering together. + TEST(Core.HAL, GUIElement_ThreeBands) + { + THREAD_SCOPE(GUI); + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 256, HEIGHT = 240; + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + GUI::user_interface ui; + ui.size = vec2((float)WIDTH, (float)HEIGHT); + + struct Band { float4 color; float height; }; + constexpr Band bands[] = { + { float4(0.85f, 0.15f, 0.15f, 1.0f), 80.0f }, + { float4(0.15f, 0.80f, 0.15f, 1.0f), 80.0f }, + { float4(0.15f, 0.15f, 0.85f, 1.0f), 80.0f }, + }; + + std::vector> rects; + for (auto& b : bands) + { + auto r = std::make_shared(); + r->color = b.color; + r->docking = GUI::dock::TOP; + r->size = vec2((float)WIDTH, b.height); + r->width_size = GUI::size_type::MATCH_PARENT; + r->height_size = GUI::size_type::FIXED; + ui.add_child(r); + rects.push_back(r); + } + ui.process_ui(0.0f); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"GUIElement_ThreeBands"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled_rt; + compiled_rt.table_rtv = view.renderTarget; + list->get_graphics().set_rtv(compiled_rt, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.05f, 0.05f, 0.1f, 1.0f)); + + sizer_long full_vp; + full_vp.left = 0; + full_vp.top = 0; + full_vp.right = (long)WIDTH; + full_vp.bottom = (long)HEIGHT; + + GUI::Renderer renderer; + GUIInfo c; + c.renderer = &renderer; + c.command_list = list; + c.window_size = vec2((float)WIDTH, (float)HEIGHT); + c.offset = vec2(0.0f, 0.0f); + c.ui_clipping = full_vp; + c.scissors = full_vp; + c.scale = 1.0f; + c.delta_time = 0.0f; + + for (auto& r : rects) + r->draw(c); + renderer.flush(c); + + list->execute_and_wait(); + ASSERT_TEXTURE(tex.get(), "gui_element_three_bands"); + } + + // Single label "Hello Label" docked FILL in a 256x64 render target. + // Exercises the full label path: recalculate → pre_draw (glyph raster) → + // draw via UIContext.draw_infos loop. + TEST(Core.HAL, GUIElement_Label) + { + THREAD_SCOPE(GUI); + + constexpr uint W = 256, H = 64; + auto& device = HAL::Device::get(); + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {W, H}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + GUI::user_interface ui; + ui.size = vec2((float)W, (float)H); + + auto lbl = std::make_shared(); + lbl->text = "Hello Label"; + lbl->docking = GUI::dock::FILL; + ui.add_child(lbl); + + ui.process_ui(0.0f); + + FrameGraph::Graph graph; + ui.create_graph(graph); + device.get_queue(HAL::CommandListType::DIRECT)->signal_and_wait(); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"GUIElement_Label"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled_rt; + compiled_rt.table_rtv = view.renderTarget; + list->get_graphics().set_rtv(compiled_rt, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.05f, 0.05f, 0.1f, 1.0f)); + + sizer_long full_vp{ 0, 0, (long)W, (long)H }; + list->get_graphics().set_scissors(full_vp); + + GUI::Renderer renderer; + GUIInfo c; + c.renderer = &renderer; + c.command_list = list; + c.window_size = vec2((float)W, (float)H); + c.offset = vec2(0.0f, 0.0f); + c.ui_clipping = full_vp; + c.scissors = full_vp; + c.scale = 1.0f; + c.delta_time = 0.0f; + + auto& ui_ctx = graph.get_context(); + for (auto& e : ui_ctx.draw_infos) + { + if (c.scissors != e.scissors) + { + renderer.flush(c); + list->get_graphics().set_scissors(e.scissors); + } + c.scale = e.scale; + c.ui_clipping = e.clip; + c.offset = e.offset; + c.scissors = e.scissors; + c.window_size = ui_ctx.scaled_size; + + if (e.before) + e.elem->draw(c); + else + e.elem->draw_after(c); + } + renderer.flush(c); + + list->execute_and_wait(); + + ASSERT_TEXTURE(Fonts::FontSystem::get_atlas_texture(), "font_atlas"); + ASSERT_TEXTURE(tex.get(), "gui_element_label"); + } + + // Renders a realistic multi-widget UI into an 800x600 texture. + // Exercises: colored_rect background, label, button row, check_box_text + // panel, status_bar. Uses create_graph to pre-render label glyphs via + // the production path, then iterates UIContext.draw_infos exactly as + // PassDefault::render does. + TEST(Core.HAL, GUIFullScreen) + { + THREAD_SCOPE(GUI); + + constexpr uint W = 800, H = 600; + auto& device = HAL::Device::get(); + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {W, H}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + GUI::user_interface ui; + ui.size = vec2((float)W, (float)H); + + // Full-screen background (dock::NONE + MATCH_PARENT — layer 0) + { + auto bg = std::make_shared(); + bg->color = float4(0.11f, 0.13f, 0.19f, 1.0f); + bg->width_size = GUI::size_type::MATCH_PARENT; + bg->height_size = GUI::size_type::MATCH_PARENT; + ui.add_child(bg); + } + + // Title bar (dock TOP, 36px) + { + auto panel = std::make_shared(); + panel->docking = GUI::dock::TOP; + panel->height_size = GUI::size_type::FIXED; + panel->size = vec2(0.0f, 36.0f); + + auto lbl = std::make_shared(); + lbl->text = "Spectrum UI Test"; + lbl->docking = GUI::dock::FILL; + panel->add_child(lbl); + ui.add_child(panel); + } + + // Button row (dock TOP, 40px) + { + auto row = std::make_shared(); + row->docking = GUI::dock::TOP; + row->height_size = GUI::size_type::FIXED; + row->size = vec2(0.0f, 40.0f); + + for (const char* name : {"File", "Edit", "View"}) + { + auto btn = std::make_shared(); + btn->get_label()->text = name; + btn->docking = GUI::dock::LEFT; + btn->width_size = GUI::size_type::FIXED; + btn->size = vec2(80.0f, 0.0f); + row->add_child(btn); + } + ui.add_child(row); + } + + // Status bar (dock BOTTOM) + { + auto bar = std::make_shared(); + auto lbl = std::make_shared(); + lbl->text = "Ready"; + bar->add_child(lbl); + ui.add_child(bar); + } + + // Left options panel (dock LEFT, 180px) + { + auto panel = std::make_shared(); + panel->docking = GUI::dock::LEFT; + panel->width_size = GUI::size_type::FIXED; + panel->size = vec2(180.0f, 0.0f); + + auto hdr = std::make_shared(); + hdr->text = "Options"; + hdr->docking = GUI::dock::TOP; + hdr->height_size = GUI::size_type::FIXED; + hdr->size = vec2(0.0f, 28.0f); + panel->add_child(hdr); + + for (const char* opt : {"Shadows", "Reflections", "Voxel GI"}) + { + auto cbt = std::make_shared(); + cbt->get_label()->text = opt; + cbt->docking = GUI::dock::TOP; + cbt->height_size = GUI::size_type::FIXED; + cbt->size = vec2(0.0f, 28.0f); + panel->add_child(cbt); + } + ui.add_child(panel); + } + + // Fill area (dock FILL) — blue-tinted content area + { + auto fill = std::make_shared(); + fill->color = float4(0.12f, 0.20f, 0.36f, 1.0f); + fill->docking = GUI::dock::FILL; + ui.add_child(fill); + } + + // Layout pass + ui.process_ui(0.0f); + + // Populate UIContext.draw_infos + async pre-render of label glyphs + FrameGraph::Graph graph; + ui.create_graph(graph); + device.get_queue(HAL::CommandListType::DIRECT)->signal_and_wait(); + + // GPU render pass + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"GUIFullScreen"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled_rt; + compiled_rt.table_rtv = view.renderTarget; + list->get_graphics().set_rtv(compiled_rt, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.05f, 0.05f, 0.1f, 1.0f)); + + sizer_long full_vp; + full_vp.left = 0; + full_vp.top = 0; + full_vp.right = (long)W; + full_vp.bottom = (long)H; + list->get_graphics().set_scissors(full_vp); + + GUI::Renderer renderer; + GUIInfo c; + c.renderer = &renderer; + c.command_list = list; + c.window_size = vec2((float)W, (float)H); + c.offset = vec2(0.0f, 0.0f); + c.ui_clipping = full_vp; + c.scissors = full_vp; + c.scale = 1.0f; + c.delta_time = 0.0f; + + auto& ui_ctx = graph.get_context(); + for (auto& e : ui_ctx.draw_infos) + { + if (c.scissors != e.scissors) + { + renderer.flush(c); + list->get_graphics().set_scissors(e.scissors); + } + c.scale = e.scale; + c.ui_clipping = e.clip; + c.offset = e.offset; + c.scissors = e.scissors; + c.window_size = ui_ctx.scaled_size; + + if (e.before) + e.elem->draw(c); + else + e.elem->draw_after(c); + } + renderer.flush(c); + + list->execute_and_wait(); + ASSERT_TEXTURE(tex.get(), "gui_full_screen"); + } + + // Renders a 32x32 nine-patch source texture into a 256x128 target at three + // different rect sizes to verify that corners stay fixed (8px) while the + // edges and center stretch correctly. + // Source color layout: RED 8x8 corners, GREEN top/bottom edges, + // BLUE left/right edges, WHITE center (R8G8B8A8_UNORM). + TEST(Core.HAL, GUINinePatch_Stretch) + { + THREAD_SCOPE(GUI); + auto& device = HAL::Device::get(); + constexpr uint RT_W = 256, RT_H = 128; + constexpr uint TEX_W = 32, TEX_H = 32; + constexpr uint CORNER = 8; + + // Build 32x32 source texture: RED corners, GREEN top/bottom edges, + // BLUE left/right edges, WHITE center. + auto src_tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::R8G8B8A8_UNORM, {TEX_W, TEX_H}, 1, 1), + HAL::HeapType::DEFAULT); + + constexpr uint ROW_STRIDE = TEX_W * 4; + std::vector pixels(TEX_W * TEX_H * 4); + for (uint y = 0; y < TEX_H; ++y) + { + for (uint x = 0; x < TEX_W; ++x) + { + bool cx = (x < CORNER || x >= TEX_W - CORNER); + bool cy = (y < CORNER || y >= TEX_H - CORNER); + uint8_t r, g, b; + if (cx && cy) { r=255; g=0; b=0; } // RED corners + else if (!cx && cy) { r=0; g=255; b=0; } // GREEN top/bottom edges + else if (cx && !cy) { r=0; g=0; b=255; } // BLUE left/right edges + else { r=255; g=255; b=255; } // WHITE center + size_t idx = ((size_t)y * TEX_W + x) * 4; + pixels[idx+0]=r; pixels[idx+1]=g; pixels[idx+2]=b; pixels[idx+3]=255; + } + } + { + auto upload = device.get_upload_list(); + upload->get_copy().update_texture(src_tex.get(), ivec3(0,0,0), ivec3(TEX_W,TEX_H,1), 0, + reinterpret_cast(pixels.data()), ROW_STRIDE); + upload->execute_and_wait(); + } + + auto rt = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {RT_W, RT_H}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"GUINinePatch_Stretch"); + + HAL::Texture2DView src_view(src_tex, *list); + HAL::Texture2DView rt_view(rt, *list); + + HAL::CompiledRT compiled_rt; + compiled_rt.table_rtv = rt_view.renderTarget; + list->get_graphics().set_rtv(compiled_rt, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.05f, 0.05f, 0.1f, 1.0f)); + + sizer_long full_vp; + full_vp.left = 0; + full_vp.top = 0; + full_vp.right = (long)RT_W; + full_vp.bottom = (long)RT_H; + list->get_graphics().set_scissors(full_vp); + + GUIInfo c; + c.renderer = nullptr; + c.command_list = list; + c.window_size = vec2((float)RT_W, (float)RT_H); + c.offset = vec2(0.0f, 0.0f); + c.ui_clipping = full_vp; + c.scissors = full_vp; + c.scale = 1.0f; + c.delta_time = 0.0f; + + GUI::Texture item; + item = src_view; + item.padding = sizer(8.0f, 8.0f, 8.0f, 8.0f); + + GUI::NinePatch nine_patch; + // Small (40x40): corners should occupy most of the patch + nine_patch.draw(c, item, rect{ vec2(4.0f, 4.0f), vec2(40.0f, 40.0f) }); + // Medium (120x60): balanced stretch + nine_patch.draw(c, item, rect{ vec2(52.0f, 4.0f), vec2(120.0f, 60.0f) }); + // Wide (240x48): heavy horizontal stretch + nine_patch.draw(c, item, rect{ vec2(4.0f, 72.0f), vec2(240.0f, 48.0f) }); + nine_patch.flush(c); + + list->execute_and_wait(); + ASSERT_TEXTURE(rt.get(), "gui_nine_patch_stretch"); + } + + // Each test clips the 160x80 patch at (48,24) from a different side, + // landing inside the 8px corner region to exercise the corner clipping path. + + // Clip cuts 8px into the left corner (corner ends at x=56, clip starts at x=52). + TEST(Core.HAL, GUINinePatch_ClipLeft) + { + THREAD_SCOPE(GUI); + sizer_long clip{ 52, 0, 256, 128 }; + auto rt = run_clip_test(HAL::Device::get(), clip, L"GUINinePatch_ClipLeft"); + ASSERT_TEXTURE(rt.get(), "gui_nine_patch_clip_left"); + } + + // Clip cuts 8px into the right corner (corner starts at x=200, clip ends at x=204). + TEST(Core.HAL, GUINinePatch_ClipRight) + { + THREAD_SCOPE(GUI); + sizer_long clip{ 0, 0, 204, 128 }; + auto rt = run_clip_test(HAL::Device::get(), clip, L"GUINinePatch_ClipRight"); + ASSERT_TEXTURE(rt.get(), "gui_nine_patch_clip_right"); + } + + // Clip cuts 8px into the top corner (corner ends at y=32, clip starts at y=28). + TEST(Core.HAL, GUINinePatch_ClipTop) + { + THREAD_SCOPE(GUI); + sizer_long clip{ 0, 28, 256, 128 }; + auto rt = run_clip_test(HAL::Device::get(), clip, L"GUINinePatch_ClipTop"); + ASSERT_TEXTURE(rt.get(), "gui_nine_patch_clip_top"); + } + + // Clip cuts 8px into the bottom corner (corner starts at y=96, clip ends at y=100). + TEST(Core.HAL, GUINinePatch_ClipBottom) + { + THREAD_SCOPE(GUI); + sizer_long clip{ 0, 0, 256, 100 }; + auto rt = run_clip_test(HAL::Device::get(), clip, L"GUINinePatch_ClipBottom"); + ASSERT_TEXTURE(rt.get(), "gui_nine_patch_clip_bottom"); + } + + // All four sides clipped simultaneously — only the white center is visible. + TEST(Core.HAL, GUINinePatch_ClipCenter) + { + THREAD_SCOPE(GUI); + sizer_long clip{ 60, 36, 196, 92 }; + auto rt = run_clip_test(HAL::Device::get(), clip, L"GUINinePatch_ClipCenter"); + ASSERT_TEXTURE(rt.get(), "gui_nine_patch_clip_center"); + } + + // Raw Font::draw() directly on a command list — no label element, no FrameGraph. + // Exercises the draw_vertices path in isolation: glyph raster → atlas flush → + // vertex upload → point-list GS draw, all driven from the immediate Font API. + TEST(Core.HAL, FontDirect_Draw) + { + THREAD_SCOPE(GUI); + + constexpr uint W = 256, H = 64; + auto& device = HAL::Device::get(); + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {W, H}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"FontDirect_Draw"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled; + compiled.table_rtv = view.renderTarget; + list->get_graphics().set_rtv(compiled, + HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.05f, 0.05f, 0.1f, 1.0f)); + + auto font = Fonts::FontSystem::get().get_font("Segoe UI Light"); + font->draw(list, std::string("Hello Direct"), 20.0f, vec2(8.0f, 10.0f), + float4(1.0f, 1.0f, 1.0f, 1.0f)); + + list->execute_and_wait(); + ASSERT_TEXTURE(tex.get(), "font_direct_draw"); + } +} diff --git a/sources/Test/Tests/Test.HAL.Rendering.ixx b/sources/Test/Tests/Test.HAL.Rendering.ixx index 83985e09..bd8fbb65 100644 --- a/sources/Test/Tests/Test.HAL.Rendering.ixx +++ b/sources/Test/Tests/Test.HAL.Rendering.ixx @@ -1,11 +1,75 @@ export module Test.HAL.Rendering; +#define TEST_MODULE_ID HALRendering + export import Test.Framework; export import Test.HAL.TextureUtils; import Core; import HAL; +namespace { + // Left triangle — CCW in NDC (signed area > 0) = front face = GREEN + // Right triangle — CW in NDC (signed area < 0) = back face = RED + // With BackCull: only GREEN visible. + // With FrontCull: only RED visible. + // With NoCull: both visible. + static constexpr const char* kCullHLSL = R"hlsl( +static const float2 kPos[6] = { + float2(-0.7,-0.5), float2(-0.1,-0.5), float2(-0.4, 0.5), // CCW = front face + float2( 0.1,-0.5), float2( 0.4, 0.5), float2( 0.7,-0.5), // CW = back face +}; +static const float4 kColor[2] = { + float4(0.0,1.0,0.0,1.0), // GREEN = front face + float4(1.0,0.0,0.0,1.0), // RED = back face +}; +struct VSOut { float4 pos : SV_Position; float4 col : COLOR0; }; +VSOut VS(uint vid : SV_VertexID) +{ + VSOut o; + o.pos = float4(kPos[vid], 0.0, 1.0); + o.col = kColor[vid / 3]; + return o; +} +float4 PS(VSOut i) : SV_Target { return i.col; } +)hlsl"; + + std::shared_ptr run_cull_test(HAL::Device& device, HAL::CullMode mode, const wchar_t* label) + { + constexpr uint W = 256, H = 256; + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::R8G8B8A8_UNORM, {W, H}, 1, 1, HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + SimpleGraphicsPSO mpso("TestCull"); + mpso.root_signature = Layouts::NoneLayout; + mpso.vertex = { kCullHLSL, "VS", HAL::ShaderOptions::None, {}, true }; + mpso.pixel = { kCullHLSL, "PS", HAL::ShaderOptions::None, {}, true }; + mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.enable_depth = false; + mpso.cull = mode; + mpso.topology = HAL::PrimitiveTopologyType::TRIANGLE; + auto pso = mpso.create(device); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(label); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled; + compiled.table_rtv = view.renderTarget; + + auto& gfx = list->get_graphics(); + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); + gfx.set_pipeline(pso); + gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE); + gfx.draw(6); + + list->execute_and_wait(); + return tex; + } +} + export namespace Test { TEST(Core.HAL, RenderTriangle) @@ -55,7 +119,9 @@ float4 PS() : SV_Target compiled.table_rtv = view.renderTarget; auto& gfx = list->get_graphics(); - gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0, 0, 0, 1)); + // Non-zero clear color so the test actually validates clearing — a black + // (zero) background is indistinguishable from zeroed/uninitialized memory. + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); gfx.set_pipeline(pso); gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE); @@ -124,7 +190,9 @@ float4 PS(VSOut i) : SV_Target { return i.col; } compiled.table_rtv = view.renderTarget; auto& gfx = list->get_graphics(); - gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0, 0, 0, 1)); + // Non-zero clear color so the test actually validates clearing — a black + // (zero) background is indistinguishable from zeroed/uninitialized memory. + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); gfx.set_pipeline(pso); gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE); @@ -247,4 +315,91 @@ float4 PS(VSOut i) : SV_Target { return i.col; } ASSERT_TEXTURE(color_tex.get(), "cube"); } + + // Left = GREEN (CCW in NDC = front face), Right = RED (CW in NDC = back face). + // NoCull: both triangles visible. + TEST(Core.HAL, RenderCull_None) + { + auto rt = run_cull_test(HAL::Device::get(), HAL::CullMode::None, L"RenderCull_None"); + ASSERT_TEXTURE(rt.get(), "cull_none"); + } + + // BackCull: back face (CW in NDC, RED right triangle) discarded — only GREEN left triangle visible. + TEST(Core.HAL, RenderCull_Back) + { + auto rt = run_cull_test(HAL::Device::get(), HAL::CullMode::Back, L"RenderCull_Back"); + ASSERT_TEXTURE(rt.get(), "cull_back"); + } + + // FrontCull: front face (CCW in NDC, GREEN left triangle) discarded — only RED right triangle visible. + TEST(Core.HAL, RenderCull_Front) + { + auto rt = run_cull_test(HAL::Device::get(), HAL::CullMode::Front, L"RenderCull_Front"); + ASSERT_TEXTURE(rt.get(), "cull_front"); + } + + // Geometry shader: VS emits one point at the origin; GS expands it into a + // full-screen orange triangle. Verifies the GS stage is invoked and produces + // visible output — a regression target for geometry shader pipeline breakage. + TEST(Core.HAL, RenderGeometryShader) + { + auto& device = HAL::Device::get(); + constexpr uint W = 256, H = 256; + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::R8G8B8A8_UNORM, {W, H}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + static constexpr const char* kGsHLSL = R"hlsl( +struct GSIn { float4 pos : SV_Position; }; +struct GSOut { float4 pos : SV_Position; float4 col : COLOR0; }; + +// VS: emit a single point — position is irrelevant, GS ignores it. +GSIn VS() { GSIn o; o.pos = float4(0,0,0,1); return o; } + +// GS: one point in → one triangle out covering most of the screen. +[maxvertexcount(3)] +void GS(point GSIn input[1], inout TriangleStream stream) +{ + float4 orange = float4(1.0, 0.5, 0.0, 1.0); + GSOut v; + v.col = orange; + v.pos = float4(-0.9, -0.9, 0, 1); stream.Append(v); + v.pos = float4( 0.0, 0.9, 0, 1); stream.Append(v); + v.pos = float4( 0.9, -0.9, 0, 1); stream.Append(v); +} + +float4 PS(GSOut i) : SV_Target { return i.col; } +)hlsl"; + + SimpleGraphicsPSO mpso("TestGeometryShader"); + mpso.root_signature = Layouts::NoneLayout; + mpso.vertex = { kGsHLSL, "VS", HAL::ShaderOptions::None, {}, true }; + mpso.geometry = { kGsHLSL, "GS", HAL::ShaderOptions::None, {}, true }; + mpso.pixel = { kGsHLSL, "PS", HAL::ShaderOptions::None, {}, true }; + mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.enable_depth = false; + mpso.cull = HAL::CullMode::None; + mpso.topology = HAL::PrimitiveTopologyType::POINT; + auto pso = mpso.create(device); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"RenderGeometryShader"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled; + compiled.table_rtv = view.renderTarget; + + auto& gfx = list->get_graphics(); + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, + vec4(0.05f, 0.05f, 0.1f, 1.0f)); + gfx.set_pipeline(pso); + gfx.set_topology(HAL::PrimitiveTopologyType::POINT, HAL::PrimitiveTopologyFeed::LIST); + gfx.draw(1); // one point → GS expands to one triangle + + list->execute_and_wait(); + ASSERT_TEXTURE(tex.get(), "geometry_shader"); + } } diff --git a/sources/Test/Tests/Test.HAL.SIG.ixx b/sources/Test/Tests/Test.HAL.SIG.ixx new file mode 100644 index 00000000..6fe88fef --- /dev/null +++ b/sources/Test/Tests/Test.HAL.SIG.ixx @@ -0,0 +1,190 @@ +export module Test.HAL.SIG; + +#define TEST_MODULE_ID HALSIG + +export import Test.Framework; +export import Test.HAL.TextureUtils; + +import Core; +import HAL; + +export namespace Test +{ + // Verifies that Slots::Color (a plain float4 CBV) round-trips through the + // DefaultLayout SIG pipeline: compile the slot via the graphics context, bind + // it, draw a full-screen triangle that reads the CBV and writes the color to + // the render target, and compare the result against the golden image. + TEST(Core.HAL, SIGColor) + { + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 64, HEIGHT = 64; + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::R8G8B8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + // Full-screen triangle that reads the Color CBV and outputs it. + // Uses the same indirect-CBV boilerplate as the autogen Color.h header + // so the binding matches DefaultLayout::Instance0 (slot ID 4). + static constexpr const char* kSigColorHLSL = R"hlsl( +struct CB { uint offset; }; +struct Color { float4 color; }; +#ifdef __spirv__ +#ifndef HAL_PUSH_DEFINED +#define HAL_PUSH_DEFINED +struct _HALPush { uint s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15; }; +[[vk::push_constant]] ConstantBuffer<_HALPush> _hal_push; +#endif +struct _CB_Color { uint offset; }; +static _CB_Color pass_Color = { _hal_push.s4 }; +#else +ConstantBuffer pass_Color : register(b4, space4); +#endif +ConstantBuffer CreateColor() { return ResourceDescriptorHeap[pass_Color.offset]; } + +float4 VS(uint vid : SV_VertexID) : SV_Position +{ + float2 uv = float2((vid & 1) * 2.0, (vid >> 1) * 2.0); + return float4(uv * 2.0 - 1.0, 0.0, 1.0); +} +float4 PS() : SV_Target +{ + Color c = CreateColor(); + return c.color; +} +)hlsl"; + + SimpleGraphicsPSO mpso("TestSIGColor"); + mpso.root_signature = Layouts::DefaultLayout; + mpso.vertex = { kSigColorHLSL, "VS", HAL::ShaderOptions::None, {}, true }; + mpso.pixel = { kSigColorHLSL, "PS", HAL::ShaderOptions::None, {}, true }; + mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.enable_depth = false; + mpso.cull = HAL::CullMode::None; + mpso.topology = HAL::PrimitiveTopologyType::TRIANGLE; + auto pso = mpso.create(device); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"SIGColor"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled; + compiled.table_rtv = view.renderTarget; + + Slots::Color color_slot; + color_slot.GetColor() = float4(0.4f, 0.2f, 0.8f, 1.0f); + + auto& gfx = list->get_graphics(); + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); + gfx.set_pipeline(pso); + gfx.set(color_slot); + gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE); + gfx.draw(3); + + list->execute_and_wait(); + + ASSERT_TEXTURE(tex.get(), "sig_color"); + } + + // Verifies the SRV (Texture2D) path of the SIG system: upload a solid-color + // source texture, bind it via Slots::CopyTexture, render a full-screen quad + // that loads each texel by pixel position, and compare the copy output. + TEST(Core.HAL, SIGCopyTexture) + { + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 64, HEIGHT = 64; + + // Source texture: ShaderResource (default flags), filled with solid orange. + auto src_tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::R8G8B8A8_UNORM, {WIDTH, HEIGHT}, 1, 1), + HAL::HeapType::DEFAULT); + + { + constexpr uint ROW_STRIDE = WIDTH * 4; + std::vector pixels(WIDTH * HEIGHT * 4); + for (size_t i = 0; i < pixels.size(); i += 4) + { + pixels[i + 0] = 255; + pixels[i + 1] = 128; + pixels[i + 2] = 0; + pixels[i + 3] = 255; + } + auto upload = device.get_upload_list(); + upload->get_copy().update_texture(src_tex.get(), + ivec3(0, 0, 0), ivec3(WIDTH, HEIGHT, 1), 0, + reinterpret_cast(pixels.data()), ROW_STRIDE); + upload->execute_and_wait(); + } + + auto dst_tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::R8G8B8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + // Full-screen triangle that reads each pixel from srcTex via Slots::CopyTexture. + // The indirect-CBV boilerplate mirrors autogen/CopyTexture.h. + static constexpr const char* kSigCopyHLSL = R"hlsl( +struct CB { uint offset; }; +struct CopyTexture { uint srcTex; }; +#ifdef __spirv__ +#ifndef HAL_PUSH_DEFINED +#define HAL_PUSH_DEFINED +struct _HALPush { uint s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15; }; +[[vk::push_constant]] ConstantBuffer<_HALPush> _hal_push; +#endif +struct _CB_CopyTexture { uint offset; }; +static _CB_CopyTexture pass_CopyTexture = { _hal_push.s4 }; +#else +ConstantBuffer pass_CopyTexture : register(b4, space4); +#endif +ConstantBuffer CreateCopyTexture() { return ResourceDescriptorHeap[pass_CopyTexture.offset]; } + +float4 VS(uint vid : SV_VertexID) : SV_Position +{ + float2 uv = float2((vid & 1) * 2.0, (vid >> 1) * 2.0); + return float4(uv * 2.0 - 1.0, 0.0, 1.0); +} +float4 PS(float4 pos : SV_Position) : SV_Target +{ + CopyTexture ct = CreateCopyTexture(); + Texture2D srcTex = ResourceDescriptorHeap[ct.srcTex]; + return srcTex.Load(int3((int)pos.x, (int)pos.y, 0)); +} +)hlsl"; + + SimpleGraphicsPSO mpso("TestSIGCopy"); + mpso.root_signature = Layouts::DefaultLayout; + mpso.vertex = { kSigCopyHLSL, "VS", HAL::ShaderOptions::None, {}, true }; + mpso.pixel = { kSigCopyHLSL, "PS", HAL::ShaderOptions::None, {}, true }; + mpso.rtv_formats = { HAL::Format::R8G8B8A8_UNORM }; + mpso.enable_depth = false; + mpso.cull = HAL::CullMode::None; + mpso.topology = HAL::PrimitiveTopologyType::TRIANGLE; + auto pso = mpso.create(device); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"SIGCopyTexture"); + + HAL::Texture2DView src_view(src_tex, *list); + HAL::Texture2DView dst_view(dst_tex, *list); + HAL::CompiledRT compiled_rt; + compiled_rt.table_rtv = dst_view.renderTarget; + + Slots::CopyTexture copy_slot; + copy_slot.GetSrcTex() = src_view.texture2D; + + auto& gfx = list->get_graphics(); + gfx.set_rtv(compiled_rt, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); + gfx.set_pipeline(pso); + gfx.set(copy_slot); + gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE); + gfx.draw(3); + + list->execute_and_wait(); + + ASSERT_TEXTURE(dst_tex.get(), "sig_copy_texture"); + } +} diff --git a/sources/Test/Tests/Test.HAL.TextureUtils.cpp b/sources/Test/Tests/Test.HAL.TextureUtils.cpp index b432b74b..9455f1ed 100644 --- a/sources/Test/Tests/Test.HAL.TextureUtils.cpp +++ b/sources/Test/Tests/Test.HAL.TextureUtils.cpp @@ -83,14 +83,21 @@ namespace Test auto& diff_data = diff_td->array[0]->mips[0]->data; size_t pixel_count = (size_t)actual_rgba->width * actual_rgba->height; + // Bytes per pixel may differ: e.g. actual is RGBA8 (4) but an old reference + // was saved as greyscale R8 (1). Use separate strides per side and compare + // only the channels present on both (capped at 3 to skip alpha). + size_t bpp_act = act_data.size() / pixel_count; + size_t bpp_ref = ref_data.size() / pixel_count; + size_t ch = std::min({ bpp_act, bpp_ref, (size_t)3 }); + for (size_t p = 0; p < pixel_count; ++p) { int max_diff = 0; bool pixel_mismatch = false; - for (int c = 0; c < 3; ++c) + for (size_t c = 0; c < ch; ++c) { - size_t i = p * 4 + c; - int d = std::abs((int)(uint8_t)act_data[i] - (int)(uint8_t)ref_data[i]); + int d = std::abs((int)(uint8_t)act_data[p * bpp_act + c] + - (int)(uint8_t)ref_data[p * bpp_ref + c]); if (d > max_diff) max_diff = d; if (d > (int)tolerance) pixel_mismatch = true; diff --git a/sources/Test/Tests/Test.HAL.TextureUtils.ixx b/sources/Test/Tests/Test.HAL.TextureUtils.ixx index 03e83889..a7ce9047 100644 --- a/sources/Test/Tests/Test.HAL.TextureUtils.ixx +++ b/sources/Test/Tests/Test.HAL.TextureUtils.ixx @@ -13,7 +13,12 @@ export namespace Test HAL::TextureResource* tex, const std::string& name, uint sub_resource = 0, - uint tolerance = 0, + // Allow a 1-LSB difference per channel: golden references and actuals can + // be encoded by different PNG libraries (DirectXTex on D3D12 vs WIC on + // Vulkan) which round exact boundary values (e.g. 0.5*255) differently, + // and GPUs may differ by a unit in the last place. 2 stays well below + // any perceptible / real rendering error. + uint tolerance = 2, const std::filesystem::path& reference_dir = "test_references", const std::filesystem::path& results_dir = "test_results"); } diff --git a/sources/Test/Tests/Test.HAL.UI.ixx b/sources/Test/Tests/Test.HAL.UI.ixx new file mode 100644 index 00000000..694e0cd9 --- /dev/null +++ b/sources/Test/Tests/Test.HAL.UI.ixx @@ -0,0 +1,169 @@ +export module Test.HAL.UI; + +#define TEST_MODULE_ID HALUI + +export import Test.Framework; +export import Test.HAL.TextureUtils; + +import Core; +import HAL; + +export namespace Test +{ + // Render a single centered rectangle via the production SimpleRect PSO and + // Slots::ColorRect. Positions are clip-space float2 pairs packed into + // float4[2]: pos[0] = (v0.x, v0.y, v1.x, v1.y), pos[1] = (v2.x, v2.y, v3.x, v3.y). + // Draw(4) with TRIANGLE_STRIP forms two triangles that cover the quad. + TEST(Core.HAL, UIRect_Solid) + { + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 256, HEIGHT = 256; + + // SimpleRect PSO requires B8G8R8A8_UNORM + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"UIRect_Solid"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled; + compiled.table_rtv = view.renderTarget; + + // A centered 50%-of-screen green rectangle (clip-space ±0.5) + Slots::ColorRect rect_slot; + auto* p = rect_slot.GetPos(); + p[0] = float4(-0.5f, 0.5f, 0.5f, 0.5f); // v0=TL, v1=TR + p[1] = float4(-0.5f, -0.5f, 0.5f, -0.5f); // v2=BL, v3=BR + rect_slot.GetColor() = float4(0.2f, 0.8f, 0.2f, 1.0f); + + auto& gfx = list->get_graphics(); + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); + gfx.set_pipeline(); + gfx.set(rect_slot); + gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE, HAL::PrimitiveTopologyFeed::STRIP); + gfx.draw(4); + + list->execute_and_wait(); + + ASSERT_TEXTURE(tex.get(), "ui_rect_solid"); + } + + + // Render two overlapping rectangles to verify alpha blending. + // Pass 1: full-screen opaque blue (0,0,1,1) — establishes the base color. + // Pass 2: right-half semi-transparent red (1,0,0,0.6) — blends over it. + // Expected result: left half = pure blue, right half = (0.6, 0, 0.4, 1.0). + TEST(Core.HAL, UIRect_AlphaBlend) + { + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 256, HEIGHT = 256; + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"UIRect_AlphaBlend"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled; + compiled.table_rtv = view.renderTarget; + + auto& gfx = list->get_graphics(); + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); + gfx.set_pipeline(); + gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE, HAL::PrimitiveTopologyFeed::STRIP); + + // Pass 1: opaque blue full-screen quad + { + Slots::ColorRect blue; + auto* p = blue.GetPos(); + p[0] = float4(-1.0f, 1.0f, 1.0f, 1.0f); + p[1] = float4(-1.0f, -1.0f, 1.0f, -1.0f); + blue.GetColor() = float4(0.0f, 0.0f, 1.0f, 1.0f); + gfx.set(blue); + gfx.draw(4); + } + + // Pass 2: semi-transparent red over the right half + { + Slots::ColorRect red; + auto* p = red.GetPos(); + p[0] = float4(0.0f, 1.0f, 1.0f, 1.0f); + p[1] = float4(0.0f, -1.0f, 1.0f, -1.0f); + red.GetColor() = float4(1.0f, 0.0f, 0.0f, 0.6f); + gfx.set(red); + gfx.draw(4); + } + + list->execute_and_wait(); + + ASSERT_TEXTURE(tex.get(), "ui_rect_alpha_blend"); + } + + // Render three non-overlapping rectangles in different positions to verify + // that clip-space coordinates map to the correct screen regions. + TEST(Core.HAL, UIRect_Layout) + { + auto& device = HAL::Device::get(); + constexpr uint WIDTH = 256, HEIGHT = 256; + + auto tex = std::make_shared(device, + HAL::ResourceDesc::Tex2D(HAL::Format::B8G8R8A8_UNORM, {WIDTH, HEIGHT}, 1, 1, + HAL::ResFlags::RenderTarget), + HAL::HeapType::DEFAULT); + + auto& queue = device.get_queue(HAL::CommandListType::DIRECT); + auto list = queue->get_free_list(); + list->begin(L"UIRect_Layout"); + + HAL::Texture2DView view(tex, *list); + HAL::CompiledRT compiled; + compiled.table_rtv = view.renderTarget; + + auto& gfx = list->get_graphics(); + gfx.set_rtv(compiled, HAL::RTOptions::Default | HAL::RTOptions::ClearColor, 0, 0, vec4(0.05f, 0.05f, 0.1f, 1.0f)); + gfx.set_pipeline(); + gfx.set_topology(HAL::PrimitiveTopologyType::TRIANGLE, HAL::PrimitiveTopologyFeed::STRIP); + + // Left-third red + { + Slots::ColorRect r; + auto* p = r.GetPos(); + p[0] = float4(-1.0f, 0.8f, -0.35f, 0.8f); + p[1] = float4(-1.0f, -0.8f, -0.35f, -0.8f); + r.GetColor() = float4(0.9f, 0.2f, 0.2f, 1.0f); + gfx.set(r); gfx.draw(4); + } + + // Center green + { + Slots::ColorRect r; + auto* p = r.GetPos(); + p[0] = float4(-0.3f, 0.8f, 0.3f, 0.8f); + p[1] = float4(-0.3f, -0.8f, 0.3f, -0.8f); + r.GetColor() = float4(0.2f, 0.9f, 0.2f, 1.0f); + gfx.set(r); gfx.draw(4); + } + + // Right-third blue + { + Slots::ColorRect r; + auto* p = r.GetPos(); + p[0] = float4(0.35f, 0.8f, 1.0f, 0.8f); + p[1] = float4(0.35f, -0.8f, 1.0f, -0.8f); + r.GetColor() = float4(0.2f, 0.2f, 0.9f, 1.0f); + gfx.set(r); gfx.draw(4); + } + + list->execute_and_wait(); + + ASSERT_TEXTURE(tex.get(), "ui_rect_layout"); + } +} diff --git a/sources/Test/Tests/Test.HAL.ixx b/sources/Test/Tests/Test.HAL.ixx index 57432dfe..df61f4fd 100644 --- a/sources/Test/Tests/Test.HAL.ixx +++ b/sources/Test/Tests/Test.HAL.ixx @@ -1,19 +1,56 @@ export module Test.HAL; +#define TEST_MODULE_ID HAL + export import Test.Framework; export import Test.HAL.TextureUtils; -export import Test.HAL.Rendering; +import Test.HAL.Rendering; +import Test.HAL.SIG; +import Test.HAL.UI; +import Test.GUI; +import Test.FrameGraph; import Core; import HAL; - +import Graphics; +import GUI; +import TextSystem; SETUP_CATEGORY(Core.HAL, []() { - auto device = HAL::Device::create_singleton(); + auto device = HAL::Device::create(); + if (!device) Test::TestRegistry::Instance().SkipCategory("Core.HAL", "no suitable GPU device found"); + else + AssetManager::create(); }); TEARDOWN_CATEGORY(Core.HAL, []() { + GUI::NinePatch::reset(); + HAL::Device::get().stop_all(); + Skin::reset(); + HAL::Texture::reset_manager(); + HAL::pixel_shader::reset_manager(); + HAL::vertex_shader::reset_manager(); + HAL::domain_shader::reset_manager(); + HAL::hull_shader::reset_manager(); + HAL::geometry_shader::reset_manager(); + HAL::compute_shader::reset_manager(); + GUI::Elements::FlowGraph::manager::reset(); + Profiler::reset(); + /// main_window2 = nullptr; + Fonts::FontSystem::reset(); + RTX::reset(); +//#ifndef HAL_BACKEND_VULKAN + AssetRenderer::reset(); + TextureAssetRenderer::reset(); +//#endif + AssetManager::reset(); + materials::PipelineManager::reset(); + universal_nodes_manager::reset(); + + universal_mesh_instance_manager::reset(); + universal_material_info_part_manager::reset(); + universal_rtx_manager::reset(); HAL::Device::reset(); }); diff --git a/sources/Test/Tests/Test.Math.Extended.ixx b/sources/Test/Tests/Test.Math.Extended.ixx index fa32496f..d9765c7c 100644 --- a/sources/Test/Tests/Test.Math.Extended.ixx +++ b/sources/Test/Tests/Test.Math.Extended.ixx @@ -4,6 +4,8 @@ module; export module Test.Math.Extended; +#define TEST_MODULE_ID MathExtended + export import Test.Framework; import Core; diff --git a/sources/Test/Tests/Test.Math.ixx b/sources/Test/Tests/Test.Math.ixx index 67c5a8ae..dcbe6efb 100644 --- a/sources/Test/Tests/Test.Math.ixx +++ b/sources/Test/Tests/Test.Math.ixx @@ -4,6 +4,8 @@ module; export module Test.Math; +#define TEST_MODULE_ID Math + export import Test.Framework; import stl.core; diff --git a/sources/Test/Tests/Test.Profiling.ixx b/sources/Test/Tests/Test.Profiling.ixx index a1796075..8ade8591 100644 --- a/sources/Test/Tests/Test.Profiling.ixx +++ b/sources/Test/Tests/Test.Profiling.ixx @@ -1,5 +1,7 @@ export module Test.Profiling; +#define TEST_MODULE_ID Profiling + export import Test.Framework; import Core; diff --git a/sources/Test/Tests/Test.Serialization.ixx b/sources/Test/Tests/Test.Serialization.ixx index 5c29635d..e017ba51 100644 --- a/sources/Test/Tests/Test.Serialization.ixx +++ b/sources/Test/Tests/Test.Serialization.ixx @@ -1,5 +1,7 @@ export module Test.Serialization; +#define TEST_MODULE_ID Serialization + import Test.Framework; import Core; diff --git a/sources/Test/Tests/Test.Threading.ixx b/sources/Test/Tests/Test.Threading.ixx index dee5f7ab..0fcd3686 100644 --- a/sources/Test/Tests/Test.Threading.ixx +++ b/sources/Test/Tests/Test.Threading.ixx @@ -1,5 +1,7 @@ export module Test.Threading; +#define TEST_MODULE_ID Threading + export import Test.Framework; import Core; diff --git a/sources/Test/main.cpp b/sources/Test/main.cpp index 0b5aa421..f95992c5 100644 --- a/sources/Test/main.cpp +++ b/sources/Test/main.cpp @@ -19,11 +19,23 @@ void SetupLogging() Log::get().set_logging_level(Log::LEVEL_ALL); } -int main() +int main(int argc, char** argv) { SetupLogging(); - auto results = Test::TestRegistry::Instance().RunAll(); + std::string filter; + for (int i = 1; i < argc; ++i) + { + std::string arg(argv[i]); + if (arg.rfind("--filter=", 0) == 0) + filter = arg.substr(9); + else if ((arg == "--filter" || arg == "-k") && i + 1 < argc) + filter = argv[++i]; + else if (arg[0] != '-') + filter = arg; + } + + auto results = Test::TestRegistry::Instance().RunAll(filter); Test::TestRegistry::Instance().PrintResults(results); bool any_failed = std::any_of(results.begin(), results.end(), diff --git a/sources/VulkanTest/Defines.h b/sources/VulkanTest/Defines.h new file mode 100644 index 00000000..41f19ae2 --- /dev/null +++ b/sources/VulkanTest/Defines.h @@ -0,0 +1,2 @@ +#pragma once +#include "../RenderSystem/Defines.h" diff --git a/sources/VulkanTest/Platform/Window.cpp b/sources/VulkanTest/Platform/Window.cpp new file mode 100644 index 00000000..f578faca --- /dev/null +++ b/sources/VulkanTest/Platform/Window.cpp @@ -0,0 +1,197 @@ +#include "Platform/Window.h" + +import windows; + +void TrackMouse(HWND hwnd) +{ + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + tme.dwHoverTime = 0; + tme.hwndTrack = hwnd; + TrackMouseEvent(&tme); +} + +LRESULT CALLBACK MyWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + Window* winptr = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (winptr == NULL) + return DefWindowProc(hwnd, message, wParam, lParam); + + MSG msg; + msg.hwnd = hwnd; + msg.message = message; + msg.wParam = wParam; + msg.lParam = lParam; + return winptr->MsgProc(msg); +} + +void Window::InitWindow(int width, int height, LPCTSTR name) +{ + WNDCLASSEX wc = { 0 }; + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC)MyWndProc; + wc.hInstance = GetModuleHandle(NULL); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.lpszClassName = name; + RegisterClassEx(&wc); + HWND hWindow = CreateWindowEx(WS_EX_WINDOWEDGE, name, name, + WS_OVERLAPPEDWINDOW, -1, -1, width, height, + NULL, NULL, GetModuleHandle(NULL), NULL); + SetWindowLongPtr(hWindow, GWLP_USERDATA, (LONG_PTR)this); + hwnd = hWindow; + ShowWindow(hWindow, SW_SHOWNORMAL); + UpdateWindow(hWindow); +} + +Window::Window(ivec2 size, std::string name) +{ + sizing = false; + MinWindowSize = { 200, 100 }; + InitWindow(size.x, size.y, name.c_str()); +} + +Window::~Window() +{ + if (hwnd) on_destroy(); +} + +void Window::on_destroy() +{ + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)0); + ::DestroyWindow(hwnd); + hwnd = 0; +} + +void Window::on_size_begin() { sizing = true; } +void Window::on_size_end() { sizing = false; } +void Window::on_paint() {} +void Window::on_resize(vec2) {} + +LRESULT Window::MsgProc(MSG msg) +{ + switch (msg.message) + { + case WM_SIZE: + size = { GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam) }; + on_resize(size); + break; + case WM_MOUSEMOVE: + { + vec2 p = { GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam) }; + if (input_handler) input_handler->mouse_move_event(p); + TrackMouse(hwnd); + break; + } + case WM_MOUSELEAVE: + { + if (!GetCapture()) { + vec2 p = { GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam) }; + if (input_handler) input_handler->mouse_action_event(mouse_action::CANCEL, mouse_button::LEFT, p); + if (input_handler) input_handler->mouse_action_event(mouse_action::CANCEL, mouse_button::RIGHT, p); + if (input_handler) input_handler->mouse_action_event(mouse_action::CANCEL, mouse_button::MIDDLE, p); + } + break; + } + case WM_LBUTTONDOWN: { vec2 p={GET_X_LPARAM(msg.lParam),GET_Y_LPARAM(msg.lParam)}; if(input_handler)input_handler->mouse_action_event(mouse_action::DOWN,mouse_button::LEFT, p); break; } + case WM_LBUTTONUP: { vec2 p={GET_X_LPARAM(msg.lParam),GET_Y_LPARAM(msg.lParam)}; if(input_handler)input_handler->mouse_action_event(mouse_action::UP, mouse_button::LEFT, p); break; } + case WM_MBUTTONDOWN: { vec2 p={GET_X_LPARAM(msg.lParam),GET_Y_LPARAM(msg.lParam)}; if(input_handler)input_handler->mouse_action_event(mouse_action::DOWN,mouse_button::MIDDLE,p); break; } + case WM_MBUTTONUP: { vec2 p={GET_X_LPARAM(msg.lParam),GET_Y_LPARAM(msg.lParam)}; if(input_handler)input_handler->mouse_action_event(mouse_action::UP, mouse_button::MIDDLE,p); break; } + case WM_RBUTTONDOWN: { vec2 p={GET_X_LPARAM(msg.lParam),GET_Y_LPARAM(msg.lParam)}; if(input_handler)input_handler->mouse_action_event(mouse_action::DOWN,mouse_button::RIGHT, p); break; } + case WM_RBUTTONUP: { vec2 p={GET_X_LPARAM(msg.lParam),GET_Y_LPARAM(msg.lParam)}; if(input_handler)input_handler->mouse_action_event(mouse_action::UP, mouse_button::RIGHT, p); break; } + case WM_MOUSEWHEEL: + { + POINT pos = { GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam) }; + ScreenToClient(hwnd, &pos); + if (input_handler) + input_handler->mouse_wheel_event(mouse_wheel::VERTICAL, + static_cast(GET_WHEEL_DELTA_WPARAM(msg.wParam)) / WHEEL_DELTA, + vec2(pos.x, pos.y)); + break; + } + case WM_KEYDOWN: + if (input_handler) input_handler->key_action_event((long)msg.wParam); + break; + case WM_ERASEBKGND: + return true; + case WM_ENTERSIZEMOVE: on_size_begin(); break; + case WM_EXITSIZEMOVE: on_size_end(); break; + case WM_PAINT: on_paint(); break; + case WM_CLOSE: + on_destroy(); + return 0; + case WM_SETCURSOR: + return DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); + case WM_GETMINMAXINFO: + { + LPMINMAXINFO p = (LPMINMAXINFO)msg.lParam; + if (p) p->ptMinTrackSize = MinWindowSize; + break; + } + } + return DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); +} + +void Window::process_messages() +{ + MSG msg; + while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +void Window::redraw() +{ + if (!sizing) on_paint(); +} + +ivec2 Window::get_size() const { return size; } + +std::vector Window::file_open( + const std::string& Name, const std::string& StartPath, const std::string& Extension) +{ + std::vector result; + char Filestring[256] = {}; + char FilterBuffer[512] = {}; + std::memcpy(FilterBuffer, Extension.c_str(), std::min(Extension.size(), (size_t)512)); + for (int i = 0; i < 512; i++) + if (FilterBuffer[i] == '|') FilterBuffer[i] = 0; + + OPENFILENAMEA opf = { 0 }; + opf.hwndOwner = 0; + opf.lpstrFilter = FilterBuffer; + opf.lpstrFile = Filestring; + opf.nMaxFile = 256; + opf.lpstrInitialDir = StartPath.c_str(); + opf.lpstrTitle = Name.c_str(); + opf.lpstrDefExt = "*.*"; + opf.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_PATHMUSTEXIST + | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT; + opf.lStructSize = sizeof(OPENFILENAME); + + if (GetOpenFileNameA(&opf)) + { + if (opf.nFileExtension) + { + result.push_back(opf.lpstrFile); + } + else + { + char* start = opf.lpstrFile; + std::string dir = start; + start += dir.size() + 1; + dir += "\\"; + while (*start) + { + std::string file = start; + start += file.size() + 1; + result.push_back(dir + file); + } + } + } + return result; +} diff --git a/sources/VulkanTest/main.cpp b/sources/VulkanTest/main.cpp new file mode 100644 index 00000000..d809bdb8 --- /dev/null +++ b/sources/VulkanTest/main.cpp @@ -0,0 +1,244 @@ +// VulkanTest — Vulkan backend smoke-test with a live GUI. +// Exercises the full UI stack (FrameGraph, GUI::user_interface, Skin, Font) +// without any 3D rendering. Acts as the reference app while 3D PSOs are being +// brought up on Vulkan. + +import GUI; +import Graphics; // AssetManager, EngineAssets, Skin +import FrameGraph; +import HAL; +import Core; + +#include "Platform/Window.h" + +// pass_defaults.h declares the PassDefault specialisations (bodies are +// out-of-line so each app provides its own implementations). +// Profiler.h / UI_Render.h / UIPipeline are NOT re-included here — they are +// already exported by `import FrameGraph;` and re-including them in this TU +// would cause class-redefinition errors (module types vs. header types are +// different entities from MSVC's perspective). +#include "../RenderSystem/FrameGraph/autogen/pass_defaults.h" +using namespace FrameGraph; + +// ============================================================================ +// Helpers +// ============================================================================ + +class tick_timer +{ + std::chrono::time_point last_tick; +public: + tick_timer() { last_tick = std::chrono::system_clock::now(); } + double tick() + { + auto now = std::chrono::system_clock::now(); + std::chrono::duration dt = now - last_tick; + last_tick = now; + return dt.count(); + } +}; + +class count_meter +{ + double time = 0; + tick_timer t; + unsigned int ticks = 0; + double average = 0; +public: + bool tick() + { + time += t.tick(); + ticks++; + if (time > 1.0) + { + average = ticks / time; + ticks = 0; time = 0; + return true; + } + return false; + } + float get() const { return (float)average; } +}; + +// ============================================================================ +// VulkanTestApp — window + UI + frame-graph +// ============================================================================ + +class VulkanTestApp : public Window, public GUI::user_interface +{ + HAL::SwapChain::ptr swap_chain; + FrameGraph::Graph graph; + Pipelines::UIPipeline pipeline; + + tick_timer frame_timer; + count_meter fps_meter; + ivec2 new_size; + + // UI widgets + GUI::Elements::label::ptr label_fps; + GUI::Elements::label::ptr label_backend; + + int frame_counter = 0; + +public: + VulkanTestApp() + : Window({ 1280, 720 }, "Vulkan UI Test") + { + THREAD_SCOPE(GUI); + + Window::input_handler = this; + + HAL::swap_chain_desc sc_desc; + sc_desc.window = this; + sc_desc.format = HAL::Format::B8G8R8A8_UNORM; + swap_chain = std::make_shared(HAL::Device::get(), sc_desc); + + new_size = get_size(); + GUI::user_interface::size = new_size; + + // ---- Build UI tree -------------------------------------------------- + + // Background fill + { + auto back = std::make_shared(); + back->texture = Skin::get().Fill; + back->texture.tiled = true; + back->width_size = GUI::size_type::MATCH_PARENT; + back->height_size = GUI::size_type::MATCH_PARENT; + add_child(back); + } + + // Top info panel + { + auto panel = std::make_shared(); + panel->docking = GUI::dock::TOP; + panel->height_size = GUI::size_type::FIXED; + panel->size = {0,40}; + + label_backend = std::make_shared(); + label_backend->text = "Vulkan Backend — UI Test"; + label_backend->docking = GUI::dock::FILL; + panel->add_child(label_backend); + add_child(panel); + } + + // Adapter info (filled after device is up) + { + auto& props = HAL::Device::get().get_properties(); + label_backend->text = std::string("Vulkan: ") + (props.name); + } + + // Status bar at bottom + { + auto bar = std::make_shared(); + label_fps = std::make_shared(); + label_fps->text = "fps: --"; + bar->add_child(label_fps); + add_child(bar); + } + } + + // ---- Render one frame --------------------------------------------------- + void render() + { + ++frame_counter; + if (frame_counter <= 5) + Log::get() << "[Render] frame " << frame_counter << Log::endl; + + swap_chain->resize(new_size); + swap_chain->wait_for_free(); + + + + if (fps_meter.tick()) + label_fps->text = std::to_string((int)fps_meter.get()) + " fps | " + + std::to_string(HAL::Device::get().get_vram()) + " MB VRAM"; + + GUI::user_interface::size = new_size; + process_ui((float)frame_timer.tick()); + + graph.start_new_frame(); + // Render into our off-screen texture (passed as "swapchain" so the + // UI pipeline writes to it). The real swapchain is still cycled via + // wait_for_free()/present() but won't have any rendered content. + graph.builder.pass_texture("swapchain", swap_chain->get_current_frame()); + + pipeline.add_passes(graph); + create_graph(graph); // injects UI_Render pass slots + + graph.setup(); + graph.compile(swap_chain->m_frameIndex); + graph.render(); + auto fence = graph.commit_command_lists(); + + + // ----------------------------------------------------------------------- + + graph.reset(); + + if (frame_counter <= 5) + Log::get() << "[Render] calling present frame " << frame_counter << Log::endl; + swap_chain->present(); + if (frame_counter <= 5) + Log::get() << "[Render] present returned frame " << frame_counter << Log::endl; + } + + void on_resize(vec2 sz) override + { + new_size = vec2::max(sz, { 64, 64 }); + GUI::user_interface::on_size_changed(new_size); + } + + void on_destroy() override + { + Application::get().shutdown(); + } +}; + +// ============================================================================ +// WinMain +// ============================================================================ + +int APIENTRY WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) +{ + CoInitialize(nullptr); + + // Logging + Log::create(); + VSOutputLogger::create(); + FileTXTLogger::create(); + Log::get().set_logging_level(Log::LEVEL_ALL); + + FileSystem::get().register_provider(std::make_shared()); + + // Device + HAL::Device::create(); + + // Asset manager — needed for Skin textures and font glyphs + AssetManager::create(); + Application::create(); + // App window + UI + auto app = std::make_shared(); + + // Message + render loop + bool running = true; + while (running) + { + Window::process_messages(); + if (!Application::is_good()) break; + app->render(); + } + + // Cleanup + HAL::Device::get().stop_all(); + Skin::reset(); + Fonts::FontSystem::reset(); + AssetManager::reset(); + HAL::pixel_shader::reset_manager(); + HAL::vertex_shader::reset_manager(); + HAL::compute_shader::reset_manager(); + HAL::Device::reset(); + + CoUninitialize(); + return 0; +} diff --git a/sources/VulkanTest/pass_defaults_stubs.cpp b/sources/VulkanTest/pass_defaults_stubs.cpp new file mode 100644 index 00000000..98a4f941 --- /dev/null +++ b/sources/VulkanTest/pass_defaults_stubs.cpp @@ -0,0 +1,8 @@ +// VulkanTest — stub definitions for every PassDefault body that MainPipeline +// references. MainPipeline::add_passes is compiled into rendersystem.lib; +// VulkanTest never calls it, but the linker still requires every symbol it +// touches to be present. +// +// Spectrum's main.cpp provides the real implementations. Here we provide +// no-op stubs so VulkanTest can link without the full Spectrum app code. + diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json index e8e8bb1a..f7ca46fd 100644 --- a/vcpkg-configuration.json +++ b/vcpkg-configuration.json @@ -1,7 +1,7 @@ { "default-registry": { "kind": "git", - "baseline": "91f002cae2281636da5155efc5a11d67efa72415", + "baseline": "2a5ea1e58fc6776ede8fd1470db0aea26ae320c4", "repository": "https://github.com/microsoft/vcpkg" }, "registries": [ diff --git a/vcpkg.json b/vcpkg.json index 17d89a52..6aabd82c 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -13,16 +13,24 @@ "cereal", "dstorage", "jinja2cpp", - {"name" :"directx-dxc", "version>=":"2026-02-20"}, + {"name" :"directx-dxc", "version>=":"2026-05-27"}, {"name" :"directx12-agility", "version>=":"1.619.3"}, {"name" :"directx-headers", "version>=":"1.619.1"}, - "bshoshany-thread-pool" - + "bshoshany-thread-pool", + "vulkan-headers", + "vulkan-loader", + "vulkan-memory-allocator" ], - "builtin-baseline": "a76e5d9e1c62a23b9e92353e5e25d8c34cda2b74", + "builtin-baseline": "2a5ea1e58fc6776ede8fd1470db0aea26ae320c4", "overrides": [ - { - "name": "fmt", + { + "name": "fmt", "version": "10.1.1" - }] + }, + { + "name": "directx-dxc", + "version-date": "2026-05-27", + "port-version": 1 + } + ] } diff --git a/workdir/screenshot.png b/workdir/screenshot.png new file mode 100644 index 00000000..096b7ca3 Binary files /dev/null and b/workdir/screenshot.png differ diff --git a/workdir/shaders/FSR.i b/workdir/shaders/FSR.i new file mode 100644 index 00000000..f6ea2ce6 --- /dev/null +++ b/workdir/shaders/FSR.i @@ -0,0 +1,893 @@ +#line 1 "C:\\github\\Spectrum\\workdir\\shaders\\FSR.hlsl" +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/autogen/FSR.h" +#line 13 "C:\\github\\Spectrum\\workdir\\shaders/autogen/FSR.h" +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/autogen/layout/DefaultLayout.h" + + + + + + + +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/autogen/layout/FrameLayout.h" + + + + + + + +SamplerState linearSampler:register(s0); +SamplerState pointClampSampler:register(s1); +SamplerState linearClampSampler:register(s2); +SamplerState anisoBordeSampler:register(s3); +SamplerState pointBorderSampler:register(s4); +#line 8 "C:\\github\\Spectrum\\workdir\\shaders/autogen/layout/DefaultLayout.h" +#line 14 "C:\\github\\Spectrum\\workdir\\shaders/autogen/FSR.h" +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/autogen/tables/FSR.h" + + + + + + + +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/sig_hlsl.hlsl" +#line 8 "C:\\github\\Spectrum\\workdir\\shaders/autogen/tables/FSR.h" + +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/autogen/tables/FSRConstants.h" +#line 12 "C:\\github\\Spectrum\\workdir\\shaders/autogen/tables/FSRConstants.h" +struct FSRConstants +{ + uint4 Const0; + uint4 Const1; + uint4 Const2; + uint4 Const3; + uint4 Sample; + uint4 GetConst0() { return Const0; } + uint4 GetConst1() { return Const1; } + uint4 GetConst2() { return Const2; } + uint4 GetConst3() { return Const3; } + uint4 GetSample() { return Sample; } +}; +#line 9 "C:\\github\\Spectrum\\workdir\\shaders/autogen/tables/FSR.h" + + + + +struct FSR +{ + uint source; + uint target; + FSRConstants constants; + FSRConstants GetConstants() { return constants; } + Texture2D GetSource() { return ResourceDescriptorHeap[source]; } + RWTexture2D GetTarget() { return ResourceDescriptorHeap[target]; } +}; +#line 15 "C:\\github\\Spectrum\\workdir\\shaders/autogen/FSR.h" + + + +struct CB { uint offset; }; + + + + + + +ConstantBuffer pass_FSR: register(b4, space4); + + +ConstantBuffer CreateFSR() +{ + return ResourceDescriptorHeap[pass_FSR.offset]; +} + + +static const ConstantBuffer fSR_global = CreateFSR(); +ConstantBuffer GetFSR(){ return fSR_global; } +#line 1 "C:\\github\\Spectrum\\workdir\\shaders\\FSR.hlsl" + + +static Texture2D InputTexture = GetFSR().GetSource(); +static RWTexture2D OutputTexture = GetFSR().GetTarget(); +static const uint4 Const0 = GetFSR().GetConstants().GetConst0(); +static const uint4 Const1 = GetFSR().GetConstants().GetConst1(); +static const uint4 Const2 = GetFSR().GetConstants().GetConst2(); +static const uint4 Const3 = GetFSR().GetConstants().GetConst3(); +#line 17 "C:\\github\\Spectrum\\workdir\\shaders\\FSR.hlsl" +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" +#line 1089 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + uint AU1_AH1_AF1_x(float a){return f32tof16(a);} + + + uint AU1_AH2_AF2_x(float2 a){return f32tof16(a.x)|(f32tof16(a.y)<<16);} + + + + float2 AF2_AH2_AU1_x(uint x){return float2(f16tof32(x&0xFFFF),f16tof32(x>>16));} + + + float AF1_x(float a){return float(a);} + float2 AF2_x(float a){return float2(a,a);} + float3 AF3_x(float a){return float3(a,a,a);} + float4 AF4_x(float a){return float4(a,a,a,a);} + + + + + + uint AU1_x(uint a){return uint(a);} + uint2 AU2_x(uint a){return uint2(a,a);} + uint3 AU3_x(uint a){return uint3(a,a,a);} + uint4 AU4_x(uint a){return uint4(a,a,a,a);} + + + + + + uint AAbsSU1(uint a){return uint(abs(int(a)));} + uint2 AAbsSU2(uint2 a){return uint2(abs(int2(a)));} + uint3 AAbsSU3(uint3 a){return uint3(abs(int3(a)));} + uint4 AAbsSU4(uint4 a){return uint4(abs(int4(a)));} + + uint ABfe(uint src,uint off,uint bits){uint mask=(1u<>off)&mask;} + uint ABfi(uint src,uint ins,uint mask){return (ins&mask)|(src&(~mask));} + uint ABfiM(uint src,uint ins,uint bits){uint mask=(1u<>int(b));} + uint2 AShrSU2(uint2 a,uint2 b){return uint2(int2(a)>>int2(b));} + uint3 AShrSU3(uint3 a,uint3 b){return uint3(int3(a)>>int3(b));} + uint4 AShrSU4(uint4 a,uint4 b){return uint4(int4(a)>>int4(b));} +#line 1481 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + float ACpySgnF1(float d,float s){return asfloat(uint(asuint(float(d))|(asuint(float(s))&AU1_x(uint(0x80000000u)))));} + float2 ACpySgnF2(float2 d,float2 s){return asfloat(uint2(asuint(float2(d))|(asuint(float2(s))&AU2_x(uint(0x80000000u)))));} + float3 ACpySgnF3(float3 d,float3 s){return asfloat(uint3(asuint(float3(d))|(asuint(float3(s))&AU3_x(uint(0x80000000u)))));} + float4 ACpySgnF4(float4 d,float4 s){return asfloat(uint4(asuint(float4(d))|(asuint(float4(s))&AU4_x(uint(0x80000000u)))));} +#line 1494 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + float ASignedF1(float m){return ASatF1(m*AF1_x(float(asfloat(uint(0xff800000u)))));} + float2 ASignedF2(float2 m){return ASatF2(m*AF2_x(float(asfloat(uint(0xff800000u)))));} + float3 ASignedF3(float3 m){return ASatF3(m*AF3_x(float(asfloat(uint(0xff800000u)))));} + float4 ASignedF4(float4 m){return ASatF4(m*AF4_x(float(asfloat(uint(0xff800000u)))));} + + float AGtZeroF1(float m){return ASatF1(m*AF1_x(float(asfloat(uint(0x7f800000u)))));} + float2 AGtZeroF2(float2 m){return ASatF2(m*AF2_x(float(asfloat(uint(0x7f800000u)))));} + float3 AGtZeroF3(float3 m){return ASatF3(m*AF3_x(float(asfloat(uint(0x7f800000u)))));} + float4 AGtZeroF4(float4 m){return ASatF4(m*AF4_x(float(asfloat(uint(0x7f800000u)))));} +#line 1546 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + uint AFisToU1(uint x){return x^(( AShrSU1(x,AU1_x(uint(31))))|AU1_x(uint(0x80000000)));} + uint AFisFromU1(uint x){return x^((~AShrSU1(x,AU1_x(uint(31))))|AU1_x(uint(0x80000000)));} + + + uint AFisToHiU1(uint x){return x^(( AShrSU1(x,AU1_x(uint(15))))|AU1_x(uint(0x80000000)));} + uint AFisFromHiU1(uint x){return x^((~AShrSU1(x,AU1_x(uint(15))))|AU1_x(uint(0x80000000)));} +#line 1660 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + uint ABuc0ToU1(uint d,float i){return (d&0xffffff00u)|((min(uint(i),255u) )&(0x000000ffu));} + uint ABuc1ToU1(uint d,float i){return (d&0xffff00ffu)|((min(uint(i),255u)<< 8)&(0x0000ff00u));} + uint ABuc2ToU1(uint d,float i){return (d&0xff00ffffu)|((min(uint(i),255u)<<16)&(0x00ff0000u));} + uint ABuc3ToU1(uint d,float i){return (d&0x00ffffffu)|((min(uint(i),255u)<<24)&(0xff000000u));} + + + float ABuc0FromU1(uint i){return float((i )&255u);} + float ABuc1FromU1(uint i){return float((i>> 8)&255u);} + float ABuc2FromU1(uint i){return float((i>>16)&255u);} + float ABuc3FromU1(uint i){return float((i>>24)&255u);} +#line 1728 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + uint ABsc0ToU1(uint d,float i){return (d&0xffffff00u)|((min(uint(i+128.0),255u) )&(0x000000ffu));} + uint ABsc1ToU1(uint d,float i){return (d&0xffff00ffu)|((min(uint(i+128.0),255u)<< 8)&(0x0000ff00u));} + uint ABsc2ToU1(uint d,float i){return (d&0xff00ffffu)|((min(uint(i+128.0),255u)<<16)&(0x00ff0000u));} + uint ABsc3ToU1(uint d,float i){return (d&0x00ffffffu)|((min(uint(i+128.0),255u)<<24)&(0xff000000u));} + + uint ABsc0ToZbU1(uint d,float i){return ((d&0xffffff00u)|((min(uint(trunc(i)+128.0),255u) )&(0x000000ffu)))^0x00000080u;} + uint ABsc1ToZbU1(uint d,float i){return ((d&0xffff00ffu)|((min(uint(trunc(i)+128.0),255u)<< 8)&(0x0000ff00u)))^0x00008000u;} + uint ABsc2ToZbU1(uint d,float i){return ((d&0xff00ffffu)|((min(uint(trunc(i)+128.0),255u)<<16)&(0x00ff0000u)))^0x00800000u;} + uint ABsc3ToZbU1(uint d,float i){return ((d&0x00ffffffu)|((min(uint(trunc(i)+128.0),255u)<<24)&(0xff000000u)))^0x80000000u;} + + float ABsc0FromU1(uint i){return float((i )&255u)-128.0;} + float ABsc1FromU1(uint i){return float((i>> 8)&255u)-128.0;} + float ABsc2FromU1(uint i){return float((i>>16)&255u)-128.0;} + float ABsc3FromU1(uint i){return float((i>>24)&255u)-128.0;} + + float ABsc0FromZbU1(uint i){return float(((i )&255u)^0x80u)-128.0;} + float ABsc1FromZbU1(uint i){return float(((i>> 8)&255u)^0x80u)-128.0;} + float ABsc2FromZbU1(uint i){return float(((i>>16)&255u)^0x80u)-128.0;} + float ABsc3FromZbU1(uint i){return float(((i>>24)&255u)^0x80u)-128.0;} +#line 1842 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + float APrxLoSqrtF1(float a){return asfloat(uint((asuint(float(a))>>AU1_x(uint(1)))+AU1_x(uint(0x1fbc4639))));} + float APrxLoRcpF1(float a){return asfloat(uint(AU1_x(uint(0x7ef07ebb))-asuint(float(a))));} + float APrxMedRcpF1(float a){float b=asfloat(uint(AU1_x(uint(0x7ef19fff))-asuint(float(a))));return b*(-b*a+AF1_x(float(2.0)));} + float APrxLoRsqF1(float a){return asfloat(uint(AU1_x(uint(0x5f347d74))-(asuint(float(a))>>AU1_x(uint(1)))));} + + float2 APrxLoSqrtF2(float2 a){return asfloat(uint2((asuint(float2(a))>>AU2_x(uint(1)))+AU2_x(uint(0x1fbc4639))));} + float2 APrxLoRcpF2(float2 a){return asfloat(uint2(AU2_x(uint(0x7ef07ebb))-asuint(float2(a))));} + float2 APrxMedRcpF2(float2 a){float2 b=asfloat(uint2(AU2_x(uint(0x7ef19fff))-asuint(float2(a))));return b*(-b*a+AF2_x(float(2.0)));} + float2 APrxLoRsqF2(float2 a){return asfloat(uint2(AU2_x(uint(0x5f347d74))-(asuint(float2(a))>>AU2_x(uint(1)))));} + + float3 APrxLoSqrtF3(float3 a){return asfloat(uint3((asuint(float3(a))>>AU3_x(uint(1)))+AU3_x(uint(0x1fbc4639))));} + float3 APrxLoRcpF3(float3 a){return asfloat(uint3(AU3_x(uint(0x7ef07ebb))-asuint(float3(a))));} + float3 APrxMedRcpF3(float3 a){float3 b=asfloat(uint3(AU3_x(uint(0x7ef19fff))-asuint(float3(a))));return b*(-b*a+AF3_x(float(2.0)));} + float3 APrxLoRsqF3(float3 a){return asfloat(uint3(AU3_x(uint(0x5f347d74))-(asuint(float3(a))>>AU3_x(uint(1)))));} + + float4 APrxLoSqrtF4(float4 a){return asfloat(uint4((asuint(float4(a))>>AU4_x(uint(1)))+AU4_x(uint(0x1fbc4639))));} + float4 APrxLoRcpF4(float4 a){return asfloat(uint4(AU4_x(uint(0x7ef07ebb))-asuint(float4(a))));} + float4 APrxMedRcpF4(float4 a){float4 b=asfloat(uint4(AU4_x(uint(0x7ef19fff))-asuint(float4(a))));return b*(-b*a+AF4_x(float(2.0)));} + float4 APrxLoRsqF4(float4 a){return asfloat(uint4(AU4_x(uint(0x5f347d74))-(asuint(float4(a))>>AU4_x(uint(1)))));} +#line 1871 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + float Quart(float a) { a = a * a; return a * a;} + float Oct(float a) { a = a * a; a = a * a; return a * a; } + float2 Quart(float2 a) { a = a * a; return a * a; } + float2 Oct(float2 a) { a = a * a; a = a * a; return a * a; } + float3 Quart(float3 a) { a = a * a; return a * a; } + float3 Oct(float3 a) { a = a * a; a = a * a; return a * a; } + float4 Quart(float4 a) { a = a * a; return a * a; } + float4 Oct(float4 a) { a = a * a; a = a * a; return a * a; } + + float APrxPQToGamma2(float a) { return Quart(a); } + float APrxPQToLinear(float a) { return Oct(a); } + float APrxLoGamma2ToPQ(float a) { return asfloat(uint((asuint(float(a)) >> AU1_x(uint(2))) + AU1_x(uint(0x2F9A4E46)))); } + float APrxMedGamma2ToPQ(float a) { float b = asfloat(uint((asuint(float(a)) >> AU1_x(uint(2))) + AU1_x(uint(0x2F9A4E46)))); float b4 = Quart(b); return b - b * (b4 - a) / (AF1_x(float(4.0)) * b4); } + float APrxHighGamma2ToPQ(float a) { return sqrt(sqrt(a)); } + float APrxLoLinearToPQ(float a) { return asfloat(uint((asuint(float(a)) >> AU1_x(uint(3))) + AU1_x(uint(0x378D8723)))); } + float APrxMedLinearToPQ(float a) { float b = asfloat(uint((asuint(float(a)) >> AU1_x(uint(3))) + AU1_x(uint(0x378D8723)))); float b8 = Oct(b); return b - b * (b8 - a) / (AF1_x(float(8.0)) * b8); } + float APrxHighLinearToPQ(float a) { return sqrt(sqrt(sqrt(a))); } + + float2 APrxPQToGamma2(float2 a) { return Quart(a); } + float2 APrxPQToLinear(float2 a) { return Oct(a); } + float2 APrxLoGamma2ToPQ(float2 a) { return asfloat(uint2((asuint(float2(a)) >> AU2_x(uint(2))) + AU2_x(uint(0x2F9A4E46)))); } + float2 APrxMedGamma2ToPQ(float2 a) { float2 b = asfloat(uint2((asuint(float2(a)) >> AU2_x(uint(2))) + AU2_x(uint(0x2F9A4E46)))); float2 b4 = Quart(b); return b - b * (b4 - a) / (AF1_x(float(4.0)) * b4); } + float2 APrxHighGamma2ToPQ(float2 a) { return sqrt(sqrt(a)); } + float2 APrxLoLinearToPQ(float2 a) { return asfloat(uint2((asuint(float2(a)) >> AU2_x(uint(3))) + AU2_x(uint(0x378D8723)))); } + float2 APrxMedLinearToPQ(float2 a) { float2 b = asfloat(uint2((asuint(float2(a)) >> AU2_x(uint(3))) + AU2_x(uint(0x378D8723)))); float2 b8 = Oct(b); return b - b * (b8 - a) / (AF1_x(float(8.0)) * b8); } + float2 APrxHighLinearToPQ(float2 a) { return sqrt(sqrt(sqrt(a))); } + + float3 APrxPQToGamma2(float3 a) { return Quart(a); } + float3 APrxPQToLinear(float3 a) { return Oct(a); } + float3 APrxLoGamma2ToPQ(float3 a) { return asfloat(uint3((asuint(float3(a)) >> AU3_x(uint(2))) + AU3_x(uint(0x2F9A4E46)))); } + float3 APrxMedGamma2ToPQ(float3 a) { float3 b = asfloat(uint3((asuint(float3(a)) >> AU3_x(uint(2))) + AU3_x(uint(0x2F9A4E46)))); float3 b4 = Quart(b); return b - b * (b4 - a) / (AF1_x(float(4.0)) * b4); } + float3 APrxHighGamma2ToPQ(float3 a) { return sqrt(sqrt(a)); } + float3 APrxLoLinearToPQ(float3 a) { return asfloat(uint3((asuint(float3(a)) >> AU3_x(uint(3))) + AU3_x(uint(0x378D8723)))); } + float3 APrxMedLinearToPQ(float3 a) { float3 b = asfloat(uint3((asuint(float3(a)) >> AU3_x(uint(3))) + AU3_x(uint(0x378D8723)))); float3 b8 = Oct(b); return b - b * (b8 - a) / (AF1_x(float(8.0)) * b8); } + float3 APrxHighLinearToPQ(float3 a) { return sqrt(sqrt(sqrt(a))); } + + float4 APrxPQToGamma2(float4 a) { return Quart(a); } + float4 APrxPQToLinear(float4 a) { return Oct(a); } + float4 APrxLoGamma2ToPQ(float4 a) { return asfloat(uint4((asuint(float4(a)) >> AU4_x(uint(2))) + AU4_x(uint(0x2F9A4E46)))); } + float4 APrxMedGamma2ToPQ(float4 a) { float4 b = asfloat(uint4((asuint(float4(a)) >> AU4_x(uint(2))) + AU4_x(uint(0x2F9A4E46)))); float4 b4 = Quart(b); return b - b * (b4 - a) / (AF1_x(float(4.0)) * b4); } + float4 APrxHighGamma2ToPQ(float4 a) { return sqrt(sqrt(a)); } + float4 APrxLoLinearToPQ(float4 a) { return asfloat(uint4((asuint(float4(a)) >> AU4_x(uint(3))) + AU4_x(uint(0x378D8723)))); } + float4 APrxMedLinearToPQ(float4 a) { float4 b = asfloat(uint4((asuint(float4(a)) >> AU4_x(uint(3))) + AU4_x(uint(0x378D8723)))); float4 b8 = Oct(b); return b - b * (b8 - a) / (AF1_x(float(8.0)) * b8); } + float4 APrxHighLinearToPQ(float4 a) { return sqrt(sqrt(sqrt(a))); } +#line 1927 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + float APSinF1(float x){return x*abs(x)-x;} + float2 APSinF2(float2 x){return x*abs(x)-x;} + float APCosF1(float x){x=AFractF1(x*AF1_x(float(0.5))+AF1_x(float(0.75)));x=x*AF1_x(float(2.0))-AF1_x(float(1.0));return APSinF1(x);} + float2 APCosF2(float2 x){x=AFractF2(x*AF2_x(float(0.5))+AF2_x(float(0.75)));x=x*AF2_x(float(2.0))-AF2_x(float(1.0));return APSinF2(x);} + float2 APSinCosF1(float x){float y=AFractF1(x*AF1_x(float(0.5))+AF1_x(float(0.75)));y=y*AF1_x(float(2.0))-AF1_x(float(1.0));return APSinF2(float2(x,y));} +#line 1968 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + uint AZolAndU1(uint x,uint y){return min(x,y);} + uint2 AZolAndU2(uint2 x,uint2 y){return min(x,y);} + uint3 AZolAndU3(uint3 x,uint3 y){return min(x,y);} + uint4 AZolAndU4(uint4 x,uint4 y){return min(x,y);} + + uint AZolNotU1(uint x){return x^AU1_x(uint(1));} + uint2 AZolNotU2(uint2 x){return x^AU2_x(uint(1));} + uint3 AZolNotU3(uint3 x){return x^AU3_x(uint(1));} + uint4 AZolNotU4(uint4 x){return x^AU4_x(uint(1));} + + uint AZolOrU1(uint x,uint y){return max(x,y);} + uint2 AZolOrU2(uint2 x,uint2 y){return max(x,y);} + uint3 AZolOrU3(uint3 x,uint3 y){return max(x,y);} + uint4 AZolOrU4(uint4 x,uint4 y){return max(x,y);} + + uint AZolF1ToU1(float x){return uint(x);} + uint2 AZolF2ToU2(float2 x){return uint2(x);} + uint3 AZolF3ToU3(float3 x){return uint3(x);} + uint4 AZolF4ToU4(float4 x){return uint4(x);} + + + uint AZolNotF1ToU1(float x){return uint(AF1_x(float(1.0))-x);} + uint2 AZolNotF2ToU2(float2 x){return uint2(AF2_x(float(1.0))-x);} + uint3 AZolNotF3ToU3(float3 x){return uint3(AF3_x(float(1.0))-x);} + uint4 AZolNotF4ToU4(float4 x){return uint4(AF4_x(float(1.0))-x);} + + float AZolU1ToF1(uint x){return float(x);} + float2 AZolU2ToF2(uint2 x){return float2(x);} + float3 AZolU3ToF3(uint3 x){return float3(x);} + float4 AZolU4ToF4(uint4 x){return float4(x);} + + float AZolAndF1(float x,float y){return min(x,y);} + float2 AZolAndF2(float2 x,float2 y){return min(x,y);} + float3 AZolAndF3(float3 x,float3 y){return min(x,y);} + float4 AZolAndF4(float4 x,float4 y){return min(x,y);} + + float ASolAndNotF1(float x,float y){return (-x)*y+AF1_x(float(1.0));} + float2 ASolAndNotF2(float2 x,float2 y){return (-x)*y+AF2_x(float(1.0));} + float3 ASolAndNotF3(float3 x,float3 y){return (-x)*y+AF3_x(float(1.0));} + float4 ASolAndNotF4(float4 x,float4 y){return (-x)*y+AF4_x(float(1.0));} + + float AZolAndOrF1(float x,float y,float z){return ASatF1(x*y+z);} + float2 AZolAndOrF2(float2 x,float2 y,float2 z){return ASatF2(x*y+z);} + float3 AZolAndOrF3(float3 x,float3 y,float3 z){return ASatF3(x*y+z);} + float4 AZolAndOrF4(float4 x,float4 y,float4 z){return ASatF4(x*y+z);} + + float AZolGtZeroF1(float x){return ASatF1(x*AF1_x(float(asfloat(uint(0x7f800000u)))));} + float2 AZolGtZeroF2(float2 x){return ASatF2(x*AF2_x(float(asfloat(uint(0x7f800000u)))));} + float3 AZolGtZeroF3(float3 x){return ASatF3(x*AF3_x(float(asfloat(uint(0x7f800000u)))));} + float4 AZolGtZeroF4(float4 x){return ASatF4(x*AF4_x(float(asfloat(uint(0x7f800000u)))));} + + float AZolNotF1(float x){return AF1_x(float(1.0))-x;} + float2 AZolNotF2(float2 x){return AF2_x(float(1.0))-x;} + float3 AZolNotF3(float3 x){return AF3_x(float(1.0))-x;} + float4 AZolNotF4(float4 x){return AF4_x(float(1.0))-x;} + + float AZolOrF1(float x,float y){return max(x,y);} + float2 AZolOrF2(float2 x,float2 y){return max(x,y);} + float3 AZolOrF3(float3 x,float3 y){return max(x,y);} + float4 AZolOrF4(float4 x,float4 y){return max(x,y);} + + float AZolSelF1(float x,float y,float z){float r=(-x)*z+z;return x*y+r;} + float2 AZolSelF2(float2 x,float2 y,float2 z){float2 r=(-x)*z+z;return x*y+r;} + float3 AZolSelF3(float3 x,float3 y,float3 z){float3 r=(-x)*z+z;return x*y+r;} + float4 AZolSelF4(float4 x,float4 y,float4 z){float4 r=(-x)*z+z;return x*y+r;} + + float AZolSignedF1(float x){return ASatF1(x*AF1_x(float(asfloat(uint(0xff800000u)))));} + float2 AZolSignedF2(float2 x){return ASatF2(x*AF2_x(float(asfloat(uint(0xff800000u)))));} + float3 AZolSignedF3(float3 x){return ASatF3(x*AF3_x(float(asfloat(uint(0xff800000u)))));} + float4 AZolSignedF4(float4 x){return ASatF4(x*AF4_x(float(asfloat(uint(0xff800000u)))));} + + float AZolZeroPassF1(float x,float y){return asfloat(uint((asuint(float(x))!=AU1_x(uint(0)))?AU1_x(uint(0)):asuint(float(y))));} +float2 AZolZeroPassF2(float2 x,float2 y){return asfloat(uint2(select(asuint(float2(x))!=AU2_x(uint(0)),AU2_x(uint(0)),asuint(float2(y)))));} +float3 AZolZeroPassF3(float3 x,float3 y){return asfloat(uint3(select(asuint(float3(x))!=AU3_x(uint(0)),AU3_x(uint(0)),asuint(float3(y)))));} +float4 AZolZeroPassF4(float4 x,float4 y){return asfloat(uint4(select(asuint(float4(x))!=AU4_x(uint(0)),AU4_x(uint(0)),asuint(float4(y)))));} +#line 2166 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + float ATo709F1(float c){float3 j=float3(0.018*4.5,4.5,0.45);float2 k=float2(1.099,-0.099); + return clamp(j.x ,c*j.y ,pow(c,j.z )*k.x +k.y );} + float2 ATo709F2(float2 c){float3 j=float3(0.018*4.5,4.5,0.45);float2 k=float2(1.099,-0.099); + return clamp(j.xx ,c*j.yy ,pow(c,j.zz )*k.xx +k.yy );} + float3 ATo709F3(float3 c){float3 j=float3(0.018*4.5,4.5,0.45);float2 k=float2(1.099,-0.099); + return clamp(j.xxx,c*j.yyy,pow(c,j.zzz)*k.xxx+k.yyy);} + + + float AToGammaF1(float c,float rcpX){return pow(c,AF1_x(float(rcpX)));} + float2 AToGammaF2(float2 c,float rcpX){return pow(c,AF2_x(float(rcpX)));} + float3 AToGammaF3(float3 c,float rcpX){return pow(c,AF3_x(float(rcpX)));} + + float AToPqF1(float x){float p=pow(x,AF1_x(float(0.159302))); + return pow((AF1_x(float(0.835938))+AF1_x(float(18.8516))*p)/(AF1_x(float(1.0))+AF1_x(float(18.6875))*p),AF1_x(float(78.8438)));} + float2 AToPqF1(float2 x){float2 p=pow(x,AF2_x(float(0.159302))); + return pow((AF2_x(float(0.835938))+AF2_x(float(18.8516))*p)/(AF2_x(float(1.0))+AF2_x(float(18.6875))*p),AF2_x(float(78.8438)));} + float3 AToPqF1(float3 x){float3 p=pow(x,AF3_x(float(0.159302))); + return pow((AF3_x(float(0.835938))+AF3_x(float(18.8516))*p)/(AF3_x(float(1.0))+AF3_x(float(18.6875))*p),AF3_x(float(78.8438)));} + + float AToSrgbF1(float c){float3 j=float3(0.0031308*12.92,12.92,1.0/2.4);float2 k=float2(1.055,-0.055); + return clamp(j.x ,c*j.y ,pow(c,j.z )*k.x +k.y );} + float2 AToSrgbF2(float2 c){float3 j=float3(0.0031308*12.92,12.92,1.0/2.4);float2 k=float2(1.055,-0.055); + return clamp(j.xx ,c*j.yy ,pow(c,j.zz )*k.xx +k.yy );} + float3 AToSrgbF3(float3 c){float3 j=float3(0.0031308*12.92,12.92,1.0/2.4);float2 k=float2(1.055,-0.055); + return clamp(j.xxx,c*j.yyy,pow(c,j.zzz)*k.xxx+k.yyy);} + + float AToTwoF1(float c){return sqrt(c);} + float2 AToTwoF2(float2 c){return sqrt(c);} + float3 AToTwoF3(float3 c){return sqrt(c);} + + float AToThreeF1(float c){return pow(c,AF1_x(float(1.0/3.0)));} + float2 AToThreeF2(float2 c){return pow(c,AF2_x(float(1.0/3.0)));} + float3 AToThreeF3(float3 c){return pow(c,AF3_x(float(1.0/3.0)));} + + + + + float AFrom709F1(float c){float3 j=float3(0.081/4.5,1.0/4.5,1.0/0.45);float2 k=float2(1.0/1.099,0.099/1.099); + return AZolSelF1(AZolSignedF1(c-j.x ),c*j.y ,pow(c*k.x +k.y ,j.z ));} + float2 AFrom709F2(float2 c){float3 j=float3(0.081/4.5,1.0/4.5,1.0/0.45);float2 k=float2(1.0/1.099,0.099/1.099); + return AZolSelF2(AZolSignedF2(c-j.xx ),c*j.yy ,pow(c*k.xx +k.yy ,j.zz ));} + float3 AFrom709F3(float3 c){float3 j=float3(0.081/4.5,1.0/4.5,1.0/0.45);float2 k=float2(1.0/1.099,0.099/1.099); + return AZolSelF3(AZolSignedF3(c-j.xxx),c*j.yyy,pow(c*k.xxx+k.yyy,j.zzz));} + + float AFromGammaF1(float c,float x){return pow(c,AF1_x(float(x)));} + float2 AFromGammaF2(float2 c,float x){return pow(c,AF2_x(float(x)));} + float3 AFromGammaF3(float3 c,float x){return pow(c,AF3_x(float(x)));} + + float AFromPqF1(float x){float p=pow(x,AF1_x(float(0.0126833))); + return pow(ASatF1(p-AF1_x(float(0.835938)))/(AF1_x(float(18.8516))-AF1_x(float(18.6875))*p),AF1_x(float(6.27739)));} + float2 AFromPqF1(float2 x){float2 p=pow(x,AF2_x(float(0.0126833))); + return pow(ASatF2(p-AF2_x(float(0.835938)))/(AF2_x(float(18.8516))-AF2_x(float(18.6875))*p),AF2_x(float(6.27739)));} + float3 AFromPqF1(float3 x){float3 p=pow(x,AF3_x(float(0.0126833))); + return pow(ASatF3(p-AF3_x(float(0.835938)))/(AF3_x(float(18.8516))-AF3_x(float(18.6875))*p),AF3_x(float(6.27739)));} + + + float AFromSrgbF1(float c){float3 j=float3(0.04045/12.92,1.0/12.92,2.4);float2 k=float2(1.0/1.055,0.055/1.055); + return AZolSelF1(AZolSignedF1(c-j.x ),c*j.y ,pow(c*k.x +k.y ,j.z ));} + float2 AFromSrgbF2(float2 c){float3 j=float3(0.04045/12.92,1.0/12.92,2.4);float2 k=float2(1.0/1.055,0.055/1.055); + return AZolSelF2(AZolSignedF2(c-j.xx ),c*j.yy ,pow(c*k.xx +k.yy ,j.zz ));} + float3 AFromSrgbF3(float3 c){float3 j=float3(0.04045/12.92,1.0/12.92,2.4);float2 k=float2(1.0/1.055,0.055/1.055); + return AZolSelF3(AZolSignedF3(c-j.xxx),c*j.yyy,pow(c*k.xxx+k.yyy,j.zzz));} + + float AFromTwoF1(float c){return c*c;} + float2 AFromTwoF2(float2 c){return c*c;} + float3 AFromTwoF3(float3 c){return c*c;} + + float AFromThreeF1(float c){return c*c*c;} + float2 AFromThreeF2(float2 c){return c*c*c;} + float3 AFromThreeF3(float3 c){return c*c*c;} +#line 2304 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + uint2 ARmp8x8(uint a){return uint2(ABfe(a,1u,3u),ABfiM(ABfe(a,3u,3u),a,1u));} +#line 2322 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + uint2 ARmpRed8x8(uint a){return uint2(ABfiM(ABfe(a,2u,3u),a,1u),ABfiM(ABfe(a,3u,3u),ABfe(a,1u,2u),2u));} +#line 2609 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_a.h" + float2 opAAbsF2(out float2 d,in float2 a){d=abs(a);return d;} + float3 opAAbsF3(out float3 d,in float3 a){d=abs(a);return d;} + float4 opAAbsF4(out float4 d,in float4 a){d=abs(a);return d;} + + float2 opAAddF2(out float2 d,in float2 a,in float2 b){d=a+b;return d;} + float3 opAAddF3(out float3 d,in float3 a,in float3 b){d=a+b;return d;} + float4 opAAddF4(out float4 d,in float4 a,in float4 b){d=a+b;return d;} + + float2 opAAddOneF2(out float2 d,in float2 a,float b){d=a+AF2_x(float(b));return d;} + float3 opAAddOneF3(out float3 d,in float3 a,float b){d=a+AF3_x(float(b));return d;} + float4 opAAddOneF4(out float4 d,in float4 a,float b){d=a+AF4_x(float(b));return d;} + + float2 opACpyF2(out float2 d,in float2 a){d=a;return d;} + float3 opACpyF3(out float3 d,in float3 a){d=a;return d;} + float4 opACpyF4(out float4 d,in float4 a){d=a;return d;} + + float2 opALerpF2(out float2 d,in float2 a,in float2 b,in float2 c){d=ALerpF2(a,b,c);return d;} + float3 opALerpF3(out float3 d,in float3 a,in float3 b,in float3 c){d=ALerpF3(a,b,c);return d;} + float4 opALerpF4(out float4 d,in float4 a,in float4 b,in float4 c){d=ALerpF4(a,b,c);return d;} + + float2 opALerpOneF2(out float2 d,in float2 a,in float2 b,float c){d=ALerpF2(a,b,AF2_x(float(c)));return d;} + float3 opALerpOneF3(out float3 d,in float3 a,in float3 b,float c){d=ALerpF3(a,b,AF3_x(float(c)));return d;} + float4 opALerpOneF4(out float4 d,in float4 a,in float4 b,float c){d=ALerpF4(a,b,AF4_x(float(c)));return d;} + + float2 opAMaxF2(out float2 d,in float2 a,in float2 b){d=max(a,b);return d;} + float3 opAMaxF3(out float3 d,in float3 a,in float3 b){d=max(a,b);return d;} + float4 opAMaxF4(out float4 d,in float4 a,in float4 b){d=max(a,b);return d;} + + float2 opAMinF2(out float2 d,in float2 a,in float2 b){d=min(a,b);return d;} + float3 opAMinF3(out float3 d,in float3 a,in float3 b){d=min(a,b);return d;} + float4 opAMinF4(out float4 d,in float4 a,in float4 b){d=min(a,b);return d;} + + float2 opAMulF2(out float2 d,in float2 a,in float2 b){d=a*b;return d;} + float3 opAMulF3(out float3 d,in float3 a,in float3 b){d=a*b;return d;} + float4 opAMulF4(out float4 d,in float4 a,in float4 b){d=a*b;return d;} + + float2 opAMulOneF2(out float2 d,in float2 a,float b){d=a*AF2_x(float(b));return d;} + float3 opAMulOneF3(out float3 d,in float3 a,float b){d=a*AF3_x(float(b));return d;} + float4 opAMulOneF4(out float4 d,in float4 a,float b){d=a*AF4_x(float(b));return d;} + + float2 opANegF2(out float2 d,in float2 a){d=-a;return d;} + float3 opANegF3(out float3 d,in float3 a){d=-a;return d;} + float4 opANegF4(out float4 d,in float4 a){d=-a;return d;} + + float2 opARcpF2(out float2 d,in float2 a){d=ARcpF2(a);return d;} + float3 opARcpF3(out float3 d,in float3 a){d=ARcpF3(a);return d;} + float4 opARcpF4(out float4 d,in float4 a){d=ARcpF4(a);return d;} +#line 17 "C:\\github\\Spectrum\\workdir\\shaders\\FSR.hlsl" +#line 65 "C:\\github\\Spectrum\\workdir\\shaders\\FSR.hlsl" +float4 FsrEasuRF(float2 p) { float4 res = InputTexture.GatherRed(linearClampSampler, p, int2(0, 0)); return res; } +float4 FsrEasuGF(float2 p) { float4 res = InputTexture.GatherGreen(linearClampSampler, p, int2(0, 0)); return res; } +float4 FsrEasuBF(float2 p) { float4 res = InputTexture.GatherBlue(linearClampSampler, p, int2(0, 0)); return res; } + + + +#line 1 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_fsr1.h" +#line 156 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_fsr1.h" + void FsrEasuCon( +out uint4 con0, +out uint4 con1, +out uint4 con2, +out uint4 con3, + +float inputViewportInPixelsX, +float inputViewportInPixelsY, + +float inputSizeInPixelsX, +float inputSizeInPixelsY, + +float outputSizeInPixelsX, +float outputSizeInPixelsY){ + + con0[0]=asuint(float(inputViewportInPixelsX*ARcpF1(outputSizeInPixelsX))); + con0[1]=asuint(float(inputViewportInPixelsY*ARcpF1(outputSizeInPixelsY))); + con0[2]=asuint(float(AF1_x(float(0.5))*inputViewportInPixelsX*ARcpF1(outputSizeInPixelsX)-AF1_x(float(0.5)))); + con0[3]=asuint(float(AF1_x(float(0.5))*inputViewportInPixelsY*ARcpF1(outputSizeInPixelsY)-AF1_x(float(0.5)))); + + + con1[0]=asuint(float(ARcpF1(inputSizeInPixelsX))); + con1[1]=asuint(float(ARcpF1(inputSizeInPixelsY))); +#line 193 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_fsr1.h" + con1[2]=asuint(float(AF1_x(float(1.0))*ARcpF1(inputSizeInPixelsX))); + con1[3]=asuint(float(AF1_x(float(-1.0))*ARcpF1(inputSizeInPixelsY))); + + con2[0]=asuint(float(AF1_x(float(-1.0))*ARcpF1(inputSizeInPixelsX))); + con2[1]=asuint(float(AF1_x(float(2.0))*ARcpF1(inputSizeInPixelsY))); + con2[2]=asuint(float(AF1_x(float(1.0))*ARcpF1(inputSizeInPixelsX))); + con2[3]=asuint(float(AF1_x(float(2.0))*ARcpF1(inputSizeInPixelsY))); + con3[0]=asuint(float(AF1_x(float(0.0))*ARcpF1(inputSizeInPixelsX))); + con3[1]=asuint(float(AF1_x(float(4.0))*ARcpF1(inputSizeInPixelsY))); + con3[2]=con3[3]=0;} + + + void FsrEasuConOffset( + out uint4 con0, + out uint4 con1, + out uint4 con2, + out uint4 con3, + + float inputViewportInPixelsX, + float inputViewportInPixelsY, + + float inputSizeInPixelsX, + float inputSizeInPixelsY, + + float outputSizeInPixelsX, + float outputSizeInPixelsY, + + float inputOffsetInPixelsX, + float inputOffsetInPixelsY) { + FsrEasuCon(con0, con1, con2, con3, inputViewportInPixelsX, inputViewportInPixelsY, inputSizeInPixelsX, inputSizeInPixelsY, outputSizeInPixelsX, outputSizeInPixelsY); + con0[2] = asuint(float(AF1_x(float(0.5)) * inputViewportInPixelsX * ARcpF1(outputSizeInPixelsX) - AF1_x(float(0.5)) + inputOffsetInPixelsX)); + con0[3] = asuint(float(AF1_x(float(0.5)) * inputViewportInPixelsY * ARcpF1(outputSizeInPixelsY) - AF1_x(float(0.5)) + inputOffsetInPixelsY)); +} +#line 234 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_fsr1.h" + float4 FsrEasuRF(float2 p); + float4 FsrEasuGF(float2 p); + float4 FsrEasuBF(float2 p); + + + void FsrEasuTapF( + inout float3 aC, + inout float aW, + float2 off, + float2 dir, + float2 len, + float lob, + float clp, + float3 c){ + + float2 v; + v.x=(off.x*( dir.x))+(off.y*dir.y); + v.y=(off.x*(-dir.y))+(off.y*dir.x); + + v*=len; + + float d2=v.x*v.x+v.y*v.y; + + d2=min(d2,clp); + + + + + + + + float wB=AF1_x(float(2.0/5.0))*d2+AF1_x(float(-1.0)); + float wA=lob*d2+AF1_x(float(-1.0)); + wB*=wB; + wA*=wA; + wB=AF1_x(float(25.0/16.0))*wB+AF1_x(float(-(25.0/16.0-1.0))); + float w=wB*wA; + + aC+=c*w;aW+=w;} + + + void FsrEasuSetF( + inout float2 dir, + inout float len, + float2 pp, + bool biS,bool biT,bool biU,bool biV, + float lA,float lB,float lC,float lD,float lE){ + + + + float w = AF1_x(float(0.0)); + if(biS)w=(AF1_x(float(1.0))-pp.x)*(AF1_x(float(1.0))-pp.y); + if(biT)w= pp.x *(AF1_x(float(1.0))-pp.y); + if(biU)w=(AF1_x(float(1.0))-pp.x)* pp.y ; + if(biV)w= pp.x * pp.y ; + + + + + + + float dc=lD-lC; + float cb=lC-lB; + float lenX=max(abs(dc),abs(cb)); + lenX=APrxLoRcpF1(lenX); + float dirX=lD-lB; + dir.x+=dirX*w; + lenX=ASatF1(abs(dirX)*lenX); + lenX*=lenX; + len+=lenX*w; + + float ec=lE-lC; + float ca=lC-lA; + float lenY=max(abs(ec),abs(ca)); + lenY=APrxLoRcpF1(lenY); + float dirY=lE-lA; + dir.y+=dirY*w; + lenY=ASatF1(abs(dirY)*lenY); + lenY*=lenY; + len+=lenY*w;} + + void FsrEasuF( + out float3 pix, + uint2 ip, + uint4 con0, + uint4 con1, + uint4 con2, + uint4 con3){ + + + float2 pp=float2(ip)*asfloat(uint2(con0.xy))+asfloat(uint2(con0.zw)); + float2 fp=floor(pp); + pp-=fp; +#line 344 "C:\\github\\Spectrum\\workdir\\shaders/fsr/ffx_fsr1.h" + float2 p0=fp*asfloat(uint2(con1.xy))+asfloat(uint2(con1.zw)); + + float2 p1=p0+asfloat(uint2(con2.xy)); + float2 p2=p0+asfloat(uint2(con2.zw)); + float2 p3=p0+asfloat(uint2(con3.xy)); + float4 bczzR=FsrEasuRF(p0); + float4 bczzG=FsrEasuGF(p0); + float4 bczzB=FsrEasuBF(p0); + float4 ijfeR=FsrEasuRF(p1); + float4 ijfeG=FsrEasuGF(p1); + float4 ijfeB=FsrEasuBF(p1); + float4 klhgR=FsrEasuRF(p2); + float4 klhgG=FsrEasuGF(p2); + float4 klhgB=FsrEasuBF(p2); + float4 zzonR=FsrEasuRF(p3); + float4 zzonG=FsrEasuGF(p3); + float4 zzonB=FsrEasuBF(p3); + + + float4 bczzL=bczzB*AF4_x(float(0.5))+(bczzR*AF4_x(float(0.5))+bczzG); + float4 ijfeL=ijfeB*AF4_x(float(0.5))+(ijfeR*AF4_x(float(0.5))+ijfeG); + float4 klhgL=klhgB*AF4_x(float(0.5))+(klhgR*AF4_x(float(0.5))+klhgG); + float4 zzonL=zzonB*AF4_x(float(0.5))+(zzonR*AF4_x(float(0.5))+zzonG); + + float bL=bczzL.x; + float cL=bczzL.y; + float iL=ijfeL.x; + float jL=ijfeL.y; + float fL=ijfeL.z; + float eL=ijfeL.w; + float kL=klhgL.x; + float lL=klhgL.y; + float hL=klhgL.z; + float gL=klhgL.w; + float oL=zzonL.z; + float nL=zzonL.w; + + float2 dir=AF2_x(float(0.0)); + float len=AF1_x(float(0.0)); + FsrEasuSetF(dir,len,pp,true, false,false,false,bL,eL,fL,gL,jL); + FsrEasuSetF(dir,len,pp,false,true ,false,false,cL,fL,gL,hL,kL); + FsrEasuSetF(dir,len,pp,false,false,true ,false,fL,iL,jL,kL,nL); + FsrEasuSetF(dir,len,pp,false,false,false,true ,gL,jL,kL,lL,oL); + + + float2 dir2=dir*dir; + float dirR=dir2.x+dir2.y; + bool zro=dirR pass_BRDF: register( b2, space4); +#ifdef __spirv__ +struct _CB_BRDF { uint offset; }; +static _CB_BRDF pass_BRDF = { _hal_push.s4 }; +#else +ConstantBuffer pass_BRDF: register(b4, space4); +#endif ConstantBuffer CreateBRDF() { @@ -26,6 +31,6 @@ ConstantBuffer CreateBRDF() } #ifndef NO_GLOBAL -static const BRDF bRDF_global = CreateBRDF(); -const BRDF GetBRDF(){ return bRDF_global; } +static const ConstantBuffer bRDF_global = CreateBRDF(); +ConstantBuffer GetBRDF(){ return bRDF_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/BlueNoise.h b/workdir/shaders/autogen/BlueNoise.h index e8ca305e..43ee7365 100644 --- a/workdir/shaders/autogen/BlueNoise.h +++ b/workdir/shaders/autogen/BlueNoise.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_BlueNoise: register( b2, space4); +#ifdef __spirv__ +struct _CB_BlueNoise { uint offset; }; +static _CB_BlueNoise pass_BlueNoise = { _hal_push.s4 }; +#else +ConstantBuffer pass_BlueNoise: register(b4, space4); +#endif ConstantBuffer CreateBlueNoise() { @@ -26,6 +31,6 @@ ConstantBuffer CreateBlueNoise() } #ifndef NO_GLOBAL -static const BlueNoise blueNoise_global = CreateBlueNoise(); -const BlueNoise GetBlueNoise(){ return blueNoise_global; } +static const ConstantBuffer blueNoise_global = CreateBlueNoise(); +ConstantBuffer GetBlueNoise(){ return blueNoise_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/Color.h b/workdir/shaders/autogen/Color.h index 47307fab..bab0b901 100644 --- a/workdir/shaders/autogen/Color.h +++ b/workdir/shaders/autogen/Color.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_Color: register( b2, space4); +#ifdef __spirv__ +struct _CB_Color { uint offset; }; +static _CB_Color pass_Color = { _hal_push.s4 }; +#else +ConstantBuffer pass_Color: register(b4, space4); +#endif ConstantBuffer CreateColor() { @@ -26,6 +31,6 @@ ConstantBuffer CreateColor() } #ifndef NO_GLOBAL -static const Color color_global = CreateColor(); -const Color GetColor(){ return color_global; } +static const ConstantBuffer color_global = CreateColor(); +ConstantBuffer GetColor(){ return color_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/ColorRect.h b/workdir/shaders/autogen/ColorRect.h index 550cc045..4a39b399 100644 --- a/workdir/shaders/autogen/ColorRect.h +++ b/workdir/shaders/autogen/ColorRect.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_ColorRect: register( b2, space4); +#ifdef __spirv__ +struct _CB_ColorRect { uint offset; }; +static _CB_ColorRect pass_ColorRect = { _hal_push.s4 }; +#else +ConstantBuffer pass_ColorRect: register(b4, space4); +#endif ConstantBuffer CreateColorRect() { @@ -26,6 +31,6 @@ ConstantBuffer CreateColorRect() } #ifndef NO_GLOBAL -static const ColorRect colorRect_global = CreateColorRect(); -const ColorRect GetColorRect(){ return colorRect_global; } +static const ConstantBuffer colorRect_global = CreateColorRect(); +ConstantBuffer GetColorRect(){ return colorRect_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/CopyTexture.h b/workdir/shaders/autogen/CopyTexture.h index 23219b06..6fbac215 100644 --- a/workdir/shaders/autogen/CopyTexture.h +++ b/workdir/shaders/autogen/CopyTexture.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_CopyTexture: register( b2, space4); +#ifdef __spirv__ +struct _CB_CopyTexture { uint offset; }; +static _CB_CopyTexture pass_CopyTexture = { _hal_push.s4 }; +#else +ConstantBuffer pass_CopyTexture: register(b4, space4); +#endif ConstantBuffer CreateCopyTexture() { @@ -26,6 +31,6 @@ ConstantBuffer CreateCopyTexture() } #ifndef NO_GLOBAL -static const CopyTexture copyTexture_global = CreateCopyTexture(); -const CopyTexture GetCopyTexture(){ return copyTexture_global; } +static const ConstantBuffer copyTexture_global = CreateCopyTexture(); +ConstantBuffer GetCopyTexture(){ return copyTexture_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/Countour.h b/workdir/shaders/autogen/Countour.h index 889e0c24..2c9460b8 100644 --- a/workdir/shaders/autogen/Countour.h +++ b/workdir/shaders/autogen/Countour.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_Countour: register( b2, space4); +#ifdef __spirv__ +struct _CB_Countour { uint offset; }; +static _CB_Countour pass_Countour = { _hal_push.s4 }; +#else +ConstantBuffer pass_Countour: register(b4, space4); +#endif ConstantBuffer CreateCountour() { @@ -26,6 +31,6 @@ ConstantBuffer CreateCountour() } #ifndef NO_GLOBAL -static const Countour countour_global = CreateCountour(); -const Countour GetCountour(){ return countour_global; } +static const ConstantBuffer countour_global = CreateCountour(); +ConstantBuffer GetCountour(){ return countour_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DebugInfo.h b/workdir/shaders/autogen/DebugInfo.h index 1faf6b5b..537f49d4 100644 --- a/workdir/shaders/autogen/DebugInfo.h +++ b/workdir/shaders/autogen/DebugInfo.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DebugInfo: register( b2, space3); +#ifdef __spirv__ +struct _CB_DebugInfo { uint offset; }; +static _CB_DebugInfo pass_DebugInfo = { _hal_push.s3 }; +#else +ConstantBuffer pass_DebugInfo: register(b3, space3); +#endif ConstantBuffer CreateDebugInfo() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDebugInfo() } #ifndef NO_GLOBAL -static const DebugInfo debugInfo_global = CreateDebugInfo(); -const DebugInfo GetDebugInfo(){ return debugInfo_global; } +static const ConstantBuffer debugInfo_global = CreateDebugInfo(); +ConstantBuffer GetDebugInfo(){ return debugInfo_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserDownsample.h b/workdir/shaders/autogen/DenoiserDownsample.h index 2dce80f4..5787c803 100644 --- a/workdir/shaders/autogen/DenoiserDownsample.h +++ b/workdir/shaders/autogen/DenoiserDownsample.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserDownsample: register( b2, space6); +#ifdef __spirv__ +struct _CB_DenoiserDownsample { uint offset; }; +static _CB_DenoiserDownsample pass_DenoiserDownsample = { _hal_push.s6 }; +#else +ConstantBuffer pass_DenoiserDownsample: register(b6, space6); +#endif ConstantBuffer CreateDenoiserDownsample() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserDownsample() } #ifndef NO_GLOBAL -static const DenoiserDownsample denoiserDownsample_global = CreateDenoiserDownsample(); -const DenoiserDownsample GetDenoiserDownsample(){ return denoiserDownsample_global; } +static const ConstantBuffer denoiserDownsample_global = CreateDenoiserDownsample(); +ConstantBuffer GetDenoiserDownsample(){ return denoiserDownsample_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserHistoryFix.h b/workdir/shaders/autogen/DenoiserHistoryFix.h index 15e6b385..1132e778 100644 --- a/workdir/shaders/autogen/DenoiserHistoryFix.h +++ b/workdir/shaders/autogen/DenoiserHistoryFix.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserHistoryFix: register( b2, space6); +#ifdef __spirv__ +struct _CB_DenoiserHistoryFix { uint offset; }; +static _CB_DenoiserHistoryFix pass_DenoiserHistoryFix = { _hal_push.s6 }; +#else +ConstantBuffer pass_DenoiserHistoryFix: register(b6, space6); +#endif ConstantBuffer CreateDenoiserHistoryFix() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserHistoryFix() } #ifndef NO_GLOBAL -static const DenoiserHistoryFix denoiserHistoryFix_global = CreateDenoiserHistoryFix(); -const DenoiserHistoryFix GetDenoiserHistoryFix(){ return denoiserHistoryFix_global; } +static const ConstantBuffer denoiserHistoryFix_global = CreateDenoiserHistoryFix(); +ConstantBuffer GetDenoiserHistoryFix(){ return denoiserHistoryFix_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserReflectionCommon.h b/workdir/shaders/autogen/DenoiserReflectionCommon.h index 13095f63..fe8f07ff 100644 --- a/workdir/shaders/autogen/DenoiserReflectionCommon.h +++ b/workdir/shaders/autogen/DenoiserReflectionCommon.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserReflectionCommon: register( b2, space4); +#ifdef __spirv__ +struct _CB_DenoiserReflectionCommon { uint offset; }; +static _CB_DenoiserReflectionCommon pass_DenoiserReflectionCommon = { _hal_push.s4 }; +#else +ConstantBuffer pass_DenoiserReflectionCommon: register(b4, space4); +#endif ConstantBuffer CreateDenoiserReflectionCommon() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserReflectionCommon() } #ifndef NO_GLOBAL -static const DenoiserReflectionCommon denoiserReflectionCommon_global = CreateDenoiserReflectionCommon(); -const DenoiserReflectionCommon GetDenoiserReflectionCommon(){ return denoiserReflectionCommon_global; } +static const ConstantBuffer denoiserReflectionCommon_global = CreateDenoiserReflectionCommon(); +ConstantBuffer GetDenoiserReflectionCommon(){ return denoiserReflectionCommon_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserReflectionPrefilter.h b/workdir/shaders/autogen/DenoiserReflectionPrefilter.h index 7a3fc026..05f6e3bd 100644 --- a/workdir/shaders/autogen/DenoiserReflectionPrefilter.h +++ b/workdir/shaders/autogen/DenoiserReflectionPrefilter.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserReflectionPrefilter: register( b2, space5); +#ifdef __spirv__ +struct _CB_DenoiserReflectionPrefilter { uint offset; }; +static _CB_DenoiserReflectionPrefilter pass_DenoiserReflectionPrefilter = { _hal_push.s5 }; +#else +ConstantBuffer pass_DenoiserReflectionPrefilter: register(b5, space5); +#endif ConstantBuffer CreateDenoiserReflectionPrefilter() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserReflectionPrefilter() } #ifndef NO_GLOBAL -static const DenoiserReflectionPrefilter denoiserReflectionPrefilter_global = CreateDenoiserReflectionPrefilter(); -const DenoiserReflectionPrefilter GetDenoiserReflectionPrefilter(){ return denoiserReflectionPrefilter_global; } +static const ConstantBuffer denoiserReflectionPrefilter_global = CreateDenoiserReflectionPrefilter(); +ConstantBuffer GetDenoiserReflectionPrefilter(){ return denoiserReflectionPrefilter_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserReflectionReproject.h b/workdir/shaders/autogen/DenoiserReflectionReproject.h index 31559586..f1faa94e 100644 --- a/workdir/shaders/autogen/DenoiserReflectionReproject.h +++ b/workdir/shaders/autogen/DenoiserReflectionReproject.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserReflectionReproject: register( b2, space5); +#ifdef __spirv__ +struct _CB_DenoiserReflectionReproject { uint offset; }; +static _CB_DenoiserReflectionReproject pass_DenoiserReflectionReproject = { _hal_push.s5 }; +#else +ConstantBuffer pass_DenoiserReflectionReproject: register(b5, space5); +#endif ConstantBuffer CreateDenoiserReflectionReproject() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserReflectionReproject() } #ifndef NO_GLOBAL -static const DenoiserReflectionReproject denoiserReflectionReproject_global = CreateDenoiserReflectionReproject(); -const DenoiserReflectionReproject GetDenoiserReflectionReproject(){ return denoiserReflectionReproject_global; } +static const ConstantBuffer denoiserReflectionReproject_global = CreateDenoiserReflectionReproject(); +ConstantBuffer GetDenoiserReflectionReproject(){ return denoiserReflectionReproject_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserReflectionResolve.h b/workdir/shaders/autogen/DenoiserReflectionResolve.h index 37a6fd93..51f2b1ef 100644 --- a/workdir/shaders/autogen/DenoiserReflectionResolve.h +++ b/workdir/shaders/autogen/DenoiserReflectionResolve.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserReflectionResolve: register( b2, space5); +#ifdef __spirv__ +struct _CB_DenoiserReflectionResolve { uint offset; }; +static _CB_DenoiserReflectionResolve pass_DenoiserReflectionResolve = { _hal_push.s5 }; +#else +ConstantBuffer pass_DenoiserReflectionResolve: register(b5, space5); +#endif ConstantBuffer CreateDenoiserReflectionResolve() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserReflectionResolve() } #ifndef NO_GLOBAL -static const DenoiserReflectionResolve denoiserReflectionResolve_global = CreateDenoiserReflectionResolve(); -const DenoiserReflectionResolve GetDenoiserReflectionResolve(){ return denoiserReflectionResolve_global; } +static const ConstantBuffer denoiserReflectionResolve_global = CreateDenoiserReflectionResolve(); +ConstantBuffer GetDenoiserReflectionResolve(){ return denoiserReflectionResolve_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserShadow_Fileter.h b/workdir/shaders/autogen/DenoiserShadow_Fileter.h index 1e54c4a5..abf41cc6 100644 --- a/workdir/shaders/autogen/DenoiserShadow_Fileter.h +++ b/workdir/shaders/autogen/DenoiserShadow_Fileter.h @@ -9,12 +9,17 @@ #define CB_DEFINED struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserShadow_Fileter: register( b2, space4); +#ifdef __spirv__ +struct _CB_DenoiserShadow_Fileter { uint offset; }; +static _CB_DenoiserShadow_Fileter pass_DenoiserShadow_Fileter = { _hal_push.s4 }; +#else +ConstantBuffer pass_DenoiserShadow_Fileter: register(b4, space4); +#endif ConstantBuffer CreateDenoiserShadow_Fileter() { return ResourceDescriptorHeap[pass_DenoiserShadow_Fileter.offset]; } #ifndef NO_GLOBAL -static const DenoiserShadow_Fileter denoiserShadow_Fileter_global = CreateDenoiserShadow_Fileter(); -const DenoiserShadow_Fileter GetDenoiserShadow_Fileter(){ return denoiserShadow_Fileter_global; } +static const ConstantBuffer denoiserShadow_Fileter_global = CreateDenoiserShadow_Fileter(); +ConstantBuffer GetDenoiserShadow_Fileter(){ return denoiserShadow_Fileter_global; } #endif diff --git a/workdir/shaders/autogen/DenoiserShadow_Filter.h b/workdir/shaders/autogen/DenoiserShadow_Filter.h index f0458b7a..6b3aa3d3 100644 --- a/workdir/shaders/autogen/DenoiserShadow_Filter.h +++ b/workdir/shaders/autogen/DenoiserShadow_Filter.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserShadow_Filter: register( b2, space4); +#ifdef __spirv__ +struct _CB_DenoiserShadow_Filter { uint offset; }; +static _CB_DenoiserShadow_Filter pass_DenoiserShadow_Filter = { _hal_push.s4 }; +#else +ConstantBuffer pass_DenoiserShadow_Filter: register(b4, space4); +#endif ConstantBuffer CreateDenoiserShadow_Filter() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserShadow_Filter() } #ifndef NO_GLOBAL -static const DenoiserShadow_Filter denoiserShadow_Filter_global = CreateDenoiserShadow_Filter(); -const DenoiserShadow_Filter GetDenoiserShadow_Filter(){ return denoiserShadow_Filter_global; } +static const ConstantBuffer denoiserShadow_Filter_global = CreateDenoiserShadow_Filter(); +ConstantBuffer GetDenoiserShadow_Filter(){ return denoiserShadow_Filter_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserShadow_FilterLast.h b/workdir/shaders/autogen/DenoiserShadow_FilterLast.h index d0877b1f..76162a8f 100644 --- a/workdir/shaders/autogen/DenoiserShadow_FilterLast.h +++ b/workdir/shaders/autogen/DenoiserShadow_FilterLast.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserShadow_FilterLast: register( b2, space5); +#ifdef __spirv__ +struct _CB_DenoiserShadow_FilterLast { uint offset; }; +static _CB_DenoiserShadow_FilterLast pass_DenoiserShadow_FilterLast = { _hal_push.s5 }; +#else +ConstantBuffer pass_DenoiserShadow_FilterLast: register(b5, space5); +#endif ConstantBuffer CreateDenoiserShadow_FilterLast() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserShadow_FilterLast() } #ifndef NO_GLOBAL -static const DenoiserShadow_FilterLast denoiserShadow_FilterLast_global = CreateDenoiserShadow_FilterLast(); -const DenoiserShadow_FilterLast GetDenoiserShadow_FilterLast(){ return denoiserShadow_FilterLast_global; } +static const ConstantBuffer denoiserShadow_FilterLast_global = CreateDenoiserShadow_FilterLast(); +ConstantBuffer GetDenoiserShadow_FilterLast(){ return denoiserShadow_FilterLast_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserShadow_FilterLocal.h b/workdir/shaders/autogen/DenoiserShadow_FilterLocal.h index e15fe13d..33eb556f 100644 --- a/workdir/shaders/autogen/DenoiserShadow_FilterLocal.h +++ b/workdir/shaders/autogen/DenoiserShadow_FilterLocal.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserShadow_FilterLocal: register( b2, space5); +#ifdef __spirv__ +struct _CB_DenoiserShadow_FilterLocal { uint offset; }; +static _CB_DenoiserShadow_FilterLocal pass_DenoiserShadow_FilterLocal = { _hal_push.s5 }; +#else +ConstantBuffer pass_DenoiserShadow_FilterLocal: register(b5, space5); +#endif ConstantBuffer CreateDenoiserShadow_FilterLocal() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserShadow_FilterLocal() } #ifndef NO_GLOBAL -static const DenoiserShadow_FilterLocal denoiserShadow_FilterLocal_global = CreateDenoiserShadow_FilterLocal(); -const DenoiserShadow_FilterLocal GetDenoiserShadow_FilterLocal(){ return denoiserShadow_FilterLocal_global; } +static const ConstantBuffer denoiserShadow_FilterLocal_global = CreateDenoiserShadow_FilterLocal(); +ConstantBuffer GetDenoiserShadow_FilterLocal(){ return denoiserShadow_FilterLocal_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserShadow_Prepare.h b/workdir/shaders/autogen/DenoiserShadow_Prepare.h index da096750..83e58644 100644 --- a/workdir/shaders/autogen/DenoiserShadow_Prepare.h +++ b/workdir/shaders/autogen/DenoiserShadow_Prepare.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserShadow_Prepare: register( b2, space4); +#ifdef __spirv__ +struct _CB_DenoiserShadow_Prepare { uint offset; }; +static _CB_DenoiserShadow_Prepare pass_DenoiserShadow_Prepare = { _hal_push.s4 }; +#else +ConstantBuffer pass_DenoiserShadow_Prepare: register(b4, space4); +#endif ConstantBuffer CreateDenoiserShadow_Prepare() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserShadow_Prepare() } #ifndef NO_GLOBAL -static const DenoiserShadow_Prepare denoiserShadow_Prepare_global = CreateDenoiserShadow_Prepare(); -const DenoiserShadow_Prepare GetDenoiserShadow_Prepare(){ return denoiserShadow_Prepare_global; } +static const ConstantBuffer denoiserShadow_Prepare_global = CreateDenoiserShadow_Prepare(); +ConstantBuffer GetDenoiserShadow_Prepare(){ return denoiserShadow_Prepare_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DenoiserShadow_TileClassification.h b/workdir/shaders/autogen/DenoiserShadow_TileClassification.h index 5fc779e7..290483cd 100644 --- a/workdir/shaders/autogen/DenoiserShadow_TileClassification.h +++ b/workdir/shaders/autogen/DenoiserShadow_TileClassification.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DenoiserShadow_TileClassification: register( b2, space4); +#ifdef __spirv__ +struct _CB_DenoiserShadow_TileClassification { uint offset; }; +static _CB_DenoiserShadow_TileClassification pass_DenoiserShadow_TileClassification = { _hal_push.s4 }; +#else +ConstantBuffer pass_DenoiserShadow_TileClassification: register(b4, space4); +#endif ConstantBuffer CreateDenoiserShadow_TileClassification() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDenoiserShadow_TileClass } #ifndef NO_GLOBAL -static const DenoiserShadow_TileClassification denoiserShadow_TileClassification_global = CreateDenoiserShadow_TileClassification(); -const DenoiserShadow_TileClassification GetDenoiserShadow_TileClassification(){ return denoiserShadow_TileClassification_global; } +static const ConstantBuffer denoiserShadow_TileClassification_global = CreateDenoiserShadow_TileClassification(); +ConstantBuffer GetDenoiserShadow_TileClassification(){ return denoiserShadow_TileClassification_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DispatchParameters.h b/workdir/shaders/autogen/DispatchParameters.h index cf3dd6bd..315cf907 100644 --- a/workdir/shaders/autogen/DispatchParameters.h +++ b/workdir/shaders/autogen/DispatchParameters.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DispatchParameters: register( b2, space6); +#ifdef __spirv__ +struct _CB_DispatchParameters { uint offset; }; +static _CB_DispatchParameters pass_DispatchParameters = { _hal_push.s6 }; +#else +ConstantBuffer pass_DispatchParameters: register(b6, space6); +#endif ConstantBuffer CreateDispatchParameters() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDispatchParameters() } #ifndef NO_GLOBAL -static const DispatchParameters dispatchParameters_global = CreateDispatchParameters(); -const DispatchParameters GetDispatchParameters(){ return dispatchParameters_global; } +static const ConstantBuffer dispatchParameters_global = CreateDispatchParameters(); +ConstantBuffer GetDispatchParameters(){ return dispatchParameters_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DownsampleDepth.h b/workdir/shaders/autogen/DownsampleDepth.h index 115d9396..f530c4af 100644 --- a/workdir/shaders/autogen/DownsampleDepth.h +++ b/workdir/shaders/autogen/DownsampleDepth.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DownsampleDepth: register( b2, space4); +#ifdef __spirv__ +struct _CB_DownsampleDepth { uint offset; }; +static _CB_DownsampleDepth pass_DownsampleDepth = { _hal_push.s4 }; +#else +ConstantBuffer pass_DownsampleDepth: register(b4, space4); +#endif ConstantBuffer CreateDownsampleDepth() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDownsampleDepth() } #ifndef NO_GLOBAL -static const DownsampleDepth downsampleDepth_global = CreateDownsampleDepth(); -const DownsampleDepth GetDownsampleDepth(){ return downsampleDepth_global; } +static const ConstantBuffer downsampleDepth_global = CreateDownsampleDepth(); +ConstantBuffer GetDownsampleDepth(){ return downsampleDepth_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DrawBoxes.h b/workdir/shaders/autogen/DrawBoxes.h index fcccef3c..82b001ab 100644 --- a/workdir/shaders/autogen/DrawBoxes.h +++ b/workdir/shaders/autogen/DrawBoxes.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DrawBoxes: register( b2, space5); +#ifdef __spirv__ +struct _CB_DrawBoxes { uint offset; }; +static _CB_DrawBoxes pass_DrawBoxes = { _hal_push.s5 }; +#else +ConstantBuffer pass_DrawBoxes: register(b5, space5); +#endif ConstantBuffer CreateDrawBoxes() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDrawBoxes() } #ifndef NO_GLOBAL -static const DrawBoxes drawBoxes_global = CreateDrawBoxes(); -const DrawBoxes GetDrawBoxes(){ return drawBoxes_global; } +static const ConstantBuffer drawBoxes_global = CreateDrawBoxes(); +ConstantBuffer GetDrawBoxes(){ return drawBoxes_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/DrawStencil.h b/workdir/shaders/autogen/DrawStencil.h index fc7dee22..fddea5e7 100644 --- a/workdir/shaders/autogen/DrawStencil.h +++ b/workdir/shaders/autogen/DrawStencil.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_DrawStencil: register( b2, space4); +#ifdef __spirv__ +struct _CB_DrawStencil { uint offset; }; +static _CB_DrawStencil pass_DrawStencil = { _hal_push.s4 }; +#else +ConstantBuffer pass_DrawStencil: register(b4, space4); +#endif ConstantBuffer CreateDrawStencil() { @@ -26,6 +31,6 @@ ConstantBuffer CreateDrawStencil() } #ifndef NO_GLOBAL -static const DrawStencil drawStencil_global = CreateDrawStencil(); -const DrawStencil GetDrawStencil(){ return drawStencil_global; } +static const ConstantBuffer drawStencil_global = CreateDrawStencil(); +ConstantBuffer GetDrawStencil(){ return drawStencil_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/EnvFilter.h b/workdir/shaders/autogen/EnvFilter.h index 963061d3..bbc36870 100644 --- a/workdir/shaders/autogen/EnvFilter.h +++ b/workdir/shaders/autogen/EnvFilter.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_EnvFilter: register( b2, space5); +#ifdef __spirv__ +struct _CB_EnvFilter { uint offset; }; +static _CB_EnvFilter pass_EnvFilter = { _hal_push.s5 }; +#else +ConstantBuffer pass_EnvFilter: register(b5, space5); +#endif ConstantBuffer CreateEnvFilter() { @@ -26,6 +31,6 @@ ConstantBuffer CreateEnvFilter() } #ifndef NO_GLOBAL -static const EnvFilter envFilter_global = CreateEnvFilter(); -const EnvFilter GetEnvFilter(){ return envFilter_global; } +static const ConstantBuffer envFilter_global = CreateEnvFilter(); +ConstantBuffer GetEnvFilter(){ return envFilter_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/EnvSource.h b/workdir/shaders/autogen/EnvSource.h index 1f5f998b..e455df56 100644 --- a/workdir/shaders/autogen/EnvSource.h +++ b/workdir/shaders/autogen/EnvSource.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_EnvSource: register( b2, space6); +#ifdef __spirv__ +struct _CB_EnvSource { uint offset; }; +static _CB_EnvSource pass_EnvSource = { _hal_push.s6 }; +#else +ConstantBuffer pass_EnvSource: register(b6, space6); +#endif ConstantBuffer CreateEnvSource() { @@ -26,6 +31,6 @@ ConstantBuffer CreateEnvSource() } #ifndef NO_GLOBAL -static const EnvSource envSource_global = CreateEnvSource(); -const EnvSource GetEnvSource(){ return envSource_global; } +static const ConstantBuffer envSource_global = CreateEnvSource(); +ConstantBuffer GetEnvSource(){ return envSource_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FSR.h b/workdir/shaders/autogen/FSR.h index 1b3a3aca..3dcf6ab5 100644 --- a/workdir/shaders/autogen/FSR.h +++ b/workdir/shaders/autogen/FSR.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FSR: register( b2, space4); +#ifdef __spirv__ +struct _CB_FSR { uint offset; }; +static _CB_FSR pass_FSR = { _hal_push.s4 }; +#else +ConstantBuffer pass_FSR: register(b4, space4); +#endif ConstantBuffer CreateFSR() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFSR() } #ifndef NO_GLOBAL -static const FSR fSR_global = CreateFSR(); -const FSR GetFSR(){ return fSR_global; } +static const ConstantBuffer fSR_global = CreateFSR(); +ConstantBuffer GetFSR(){ return fSR_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FlowGraph.h b/workdir/shaders/autogen/FlowGraph.h index bbe690aa..9532edf4 100644 --- a/workdir/shaders/autogen/FlowGraph.h +++ b/workdir/shaders/autogen/FlowGraph.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FlowGraph: register( b2, space5); +#ifdef __spirv__ +struct _CB_FlowGraph { uint offset; }; +static _CB_FlowGraph pass_FlowGraph = { _hal_push.s5 }; +#else +ConstantBuffer pass_FlowGraph: register(b5, space5); +#endif ConstantBuffer CreateFlowGraph() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFlowGraph() } #ifndef NO_GLOBAL -static const FlowGraph flowGraph_global = CreateFlowGraph(); -const FlowGraph GetFlowGraph(){ return flowGraph_global; } +static const ConstantBuffer flowGraph_global = CreateFlowGraph(); +ConstantBuffer GetFlowGraph(){ return flowGraph_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FontRendering.h b/workdir/shaders/autogen/FontRendering.h index 04736467..af93d8f2 100644 --- a/workdir/shaders/autogen/FontRendering.h +++ b/workdir/shaders/autogen/FontRendering.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FontRendering: register( b2, space4); +#ifdef __spirv__ +struct _CB_FontRendering { uint offset; }; +static _CB_FontRendering pass_FontRendering = { _hal_push.s4 }; +#else +ConstantBuffer pass_FontRendering: register(b4, space4); +#endif ConstantBuffer CreateFontRendering() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFontRendering() } #ifndef NO_GLOBAL -static const FontRendering fontRendering_global = CreateFontRendering(); -const FontRendering GetFontRendering(){ return fontRendering_global; } +static const ConstantBuffer fontRendering_global = CreateFontRendering(); +ConstantBuffer GetFontRendering(){ return fontRendering_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FontRenderingConstants.h b/workdir/shaders/autogen/FontRenderingConstants.h index 901af9d0..66aaa02c 100644 --- a/workdir/shaders/autogen/FontRenderingConstants.h +++ b/workdir/shaders/autogen/FontRenderingConstants.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FontRenderingConstants: register( b2, space5); +#ifdef __spirv__ +struct _CB_FontRenderingConstants { uint offset; }; +static _CB_FontRenderingConstants pass_FontRenderingConstants = { _hal_push.s5 }; +#else +ConstantBuffer pass_FontRenderingConstants: register(b5, space5); +#endif ConstantBuffer CreateFontRenderingConstants() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFontRenderingConstants() } #ifndef NO_GLOBAL -static const FontRenderingConstants fontRenderingConstants_global = CreateFontRenderingConstants(); -const FontRenderingConstants GetFontRenderingConstants(){ return fontRenderingConstants_global; } +static const ConstantBuffer fontRenderingConstants_global = CreateFontRenderingConstants(); +ConstantBuffer GetFontRenderingConstants(){ return fontRenderingConstants_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FontRenderingGlyphs.h b/workdir/shaders/autogen/FontRenderingGlyphs.h index ecd94acb..1ebf17af 100644 --- a/workdir/shaders/autogen/FontRenderingGlyphs.h +++ b/workdir/shaders/autogen/FontRenderingGlyphs.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FontRenderingGlyphs: register( b2, space6); +#ifdef __spirv__ +struct _CB_FontRenderingGlyphs { uint offset; }; +static _CB_FontRenderingGlyphs pass_FontRenderingGlyphs = { _hal_push.s6 }; +#else +ConstantBuffer pass_FontRenderingGlyphs: register(b6, space6); +#endif ConstantBuffer CreateFontRenderingGlyphs() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFontRenderingGlyphs() } #ifndef NO_GLOBAL -static const FontRenderingGlyphs fontRenderingGlyphs_global = CreateFontRenderingGlyphs(); -const FontRenderingGlyphs GetFontRenderingGlyphs(){ return fontRenderingGlyphs_global; } +static const ConstantBuffer fontRenderingGlyphs_global = CreateFontRenderingGlyphs(); +ConstantBuffer GetFontRenderingGlyphs(){ return fontRenderingGlyphs_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameClassification.h b/workdir/shaders/autogen/FrameClassification.h index 97c9d81d..eec31c17 100644 --- a/workdir/shaders/autogen/FrameClassification.h +++ b/workdir/shaders/autogen/FrameClassification.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameClassification: register( b2, space6); +#ifdef __spirv__ +struct _CB_FrameClassification { uint offset; }; +static _CB_FrameClassification pass_FrameClassification = { _hal_push.s6 }; +#else +ConstantBuffer pass_FrameClassification: register(b6, space6); +#endif ConstantBuffer CreateFrameClassification() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameClassification() } #ifndef NO_GLOBAL -static const FrameClassification frameClassification_global = CreateFrameClassification(); -const FrameClassification GetFrameClassification(){ return frameClassification_global; } +static const ConstantBuffer frameClassification_global = CreateFrameClassification(); +ConstantBuffer GetFrameClassification(){ return frameClassification_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameClassificationInitDispatch.h b/workdir/shaders/autogen/FrameClassificationInitDispatch.h index df96cce5..af484944 100644 --- a/workdir/shaders/autogen/FrameClassificationInitDispatch.h +++ b/workdir/shaders/autogen/FrameClassificationInitDispatch.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameClassificationInitDispatch: register( b2, space6); +#ifdef __spirv__ +struct _CB_FrameClassificationInitDispatch { uint offset; }; +static _CB_FrameClassificationInitDispatch pass_FrameClassificationInitDispatch = { _hal_push.s6 }; +#else +ConstantBuffer pass_FrameClassificationInitDispatch: register(b6, space6); +#endif ConstantBuffer CreateFrameClassificationInitDispatch() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameClassificationInitDis } #ifndef NO_GLOBAL -static const FrameClassificationInitDispatch frameClassificationInitDispatch_global = CreateFrameClassificationInitDispatch(); -const FrameClassificationInitDispatch GetFrameClassificationInitDispatch(){ return frameClassificationInitDispatch_global; } +static const ConstantBuffer frameClassificationInitDispatch_global = CreateFrameClassificationInitDispatch(); +ConstantBuffer GetFrameClassificationInitDispatch(){ return frameClassificationInitDispatch_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameGraph_Debug_Common.h b/workdir/shaders/autogen/FrameGraph_Debug_Common.h index 167cc88e..fd76e4c3 100644 --- a/workdir/shaders/autogen/FrameGraph_Debug_Common.h +++ b/workdir/shaders/autogen/FrameGraph_Debug_Common.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameGraph_Debug_Common: register( b2, space4); +#ifdef __spirv__ +struct _CB_FrameGraph_Debug_Common { uint offset; }; +static _CB_FrameGraph_Debug_Common pass_FrameGraph_Debug_Common = { _hal_push.s4 }; +#else +ConstantBuffer pass_FrameGraph_Debug_Common: register(b4, space4); +#endif ConstantBuffer CreateFrameGraph_Debug_Common() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameGraph_Debug_Common() } #ifndef NO_GLOBAL -static const FrameGraph_Debug_Common frameGraph_Debug_Common_global = CreateFrameGraph_Debug_Common(); -const FrameGraph_Debug_Common GetFrameGraph_Debug_Common(){ return frameGraph_Debug_Common_global; } +static const ConstantBuffer frameGraph_Debug_Common_global = CreateFrameGraph_Debug_Common(); +ConstantBuffer GetFrameGraph_Debug_Common(){ return frameGraph_Debug_Common_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameGraph_Debug_Texture2D.h b/workdir/shaders/autogen/FrameGraph_Debug_Texture2D.h index eea08fa3..610b2b72 100644 --- a/workdir/shaders/autogen/FrameGraph_Debug_Texture2D.h +++ b/workdir/shaders/autogen/FrameGraph_Debug_Texture2D.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameGraph_Debug_Texture2D: register( b2, space5); +#ifdef __spirv__ +struct _CB_FrameGraph_Debug_Texture2D { uint offset; }; +static _CB_FrameGraph_Debug_Texture2D pass_FrameGraph_Debug_Texture2D = { _hal_push.s5 }; +#else +ConstantBuffer pass_FrameGraph_Debug_Texture2D: register(b5, space5); +#endif ConstantBuffer CreateFrameGraph_Debug_Texture2D() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameGraph_Debug_Texture2D() } #ifndef NO_GLOBAL -static const FrameGraph_Debug_Texture2D frameGraph_Debug_Texture2D_global = CreateFrameGraph_Debug_Texture2D(); -const FrameGraph_Debug_Texture2D GetFrameGraph_Debug_Texture2D(){ return frameGraph_Debug_Texture2D_global; } +static const ConstantBuffer frameGraph_Debug_Texture2D_global = CreateFrameGraph_Debug_Texture2D(); +ConstantBuffer GetFrameGraph_Debug_Texture2D(){ return frameGraph_Debug_Texture2D_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameGraph_Debug_Texture2DArray.h b/workdir/shaders/autogen/FrameGraph_Debug_Texture2DArray.h index c0a5afd6..9d8759f9 100644 --- a/workdir/shaders/autogen/FrameGraph_Debug_Texture2DArray.h +++ b/workdir/shaders/autogen/FrameGraph_Debug_Texture2DArray.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameGraph_Debug_Texture2DArray: register( b2, space5); +#ifdef __spirv__ +struct _CB_FrameGraph_Debug_Texture2DArray { uint offset; }; +static _CB_FrameGraph_Debug_Texture2DArray pass_FrameGraph_Debug_Texture2DArray = { _hal_push.s5 }; +#else +ConstantBuffer pass_FrameGraph_Debug_Texture2DArray: register(b5, space5); +#endif ConstantBuffer CreateFrameGraph_Debug_Texture2DArray() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameGraph_Debug_Texture2D } #ifndef NO_GLOBAL -static const FrameGraph_Debug_Texture2DArray frameGraph_Debug_Texture2DArray_global = CreateFrameGraph_Debug_Texture2DArray(); -const FrameGraph_Debug_Texture2DArray GetFrameGraph_Debug_Texture2DArray(){ return frameGraph_Debug_Texture2DArray_global; } +static const ConstantBuffer frameGraph_Debug_Texture2DArray_global = CreateFrameGraph_Debug_Texture2DArray(); +ConstantBuffer GetFrameGraph_Debug_Texture2DArray(){ return frameGraph_Debug_Texture2DArray_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameGraph_Debug_Texture3D.h b/workdir/shaders/autogen/FrameGraph_Debug_Texture3D.h index 7c9823e2..d2adf1b9 100644 --- a/workdir/shaders/autogen/FrameGraph_Debug_Texture3D.h +++ b/workdir/shaders/autogen/FrameGraph_Debug_Texture3D.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameGraph_Debug_Texture3D: register( b2, space5); +#ifdef __spirv__ +struct _CB_FrameGraph_Debug_Texture3D { uint offset; }; +static _CB_FrameGraph_Debug_Texture3D pass_FrameGraph_Debug_Texture3D = { _hal_push.s5 }; +#else +ConstantBuffer pass_FrameGraph_Debug_Texture3D: register(b5, space5); +#endif ConstantBuffer CreateFrameGraph_Debug_Texture3D() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameGraph_Debug_Texture3D() } #ifndef NO_GLOBAL -static const FrameGraph_Debug_Texture3D frameGraph_Debug_Texture3D_global = CreateFrameGraph_Debug_Texture3D(); -const FrameGraph_Debug_Texture3D GetFrameGraph_Debug_Texture3D(){ return frameGraph_Debug_Texture3D_global; } +static const ConstantBuffer frameGraph_Debug_Texture3D_global = CreateFrameGraph_Debug_Texture3D(); +ConstantBuffer GetFrameGraph_Debug_Texture3D(){ return frameGraph_Debug_Texture3D_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameGraph_Debug_TextureCube.h b/workdir/shaders/autogen/FrameGraph_Debug_TextureCube.h index 74a4cac2..d3bd1c22 100644 --- a/workdir/shaders/autogen/FrameGraph_Debug_TextureCube.h +++ b/workdir/shaders/autogen/FrameGraph_Debug_TextureCube.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameGraph_Debug_TextureCube: register( b2, space5); +#ifdef __spirv__ +struct _CB_FrameGraph_Debug_TextureCube { uint offset; }; +static _CB_FrameGraph_Debug_TextureCube pass_FrameGraph_Debug_TextureCube = { _hal_push.s5 }; +#else +ConstantBuffer pass_FrameGraph_Debug_TextureCube: register(b5, space5); +#endif ConstantBuffer CreateFrameGraph_Debug_TextureCube() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameGraph_Debug_TextureCube( } #ifndef NO_GLOBAL -static const FrameGraph_Debug_TextureCube frameGraph_Debug_TextureCube_global = CreateFrameGraph_Debug_TextureCube(); -const FrameGraph_Debug_TextureCube GetFrameGraph_Debug_TextureCube(){ return frameGraph_Debug_TextureCube_global; } +static const ConstantBuffer frameGraph_Debug_TextureCube_global = CreateFrameGraph_Debug_TextureCube(); +ConstantBuffer GetFrameGraph_Debug_TextureCube(){ return frameGraph_Debug_TextureCube_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/FrameInfo.h b/workdir/shaders/autogen/FrameInfo.h index 2b952314..99e1fb1a 100644 --- a/workdir/shaders/autogen/FrameInfo.h +++ b/workdir/shaders/autogen/FrameInfo.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_FrameInfo: register( b2, space0); +#ifdef __spirv__ +struct _CB_FrameInfo { uint offset; }; +static _CB_FrameInfo pass_FrameInfo = { _hal_push.s0 }; +#else +ConstantBuffer pass_FrameInfo: register(b0, space0); +#endif ConstantBuffer CreateFrameInfo() { @@ -26,6 +31,6 @@ ConstantBuffer CreateFrameInfo() } #ifndef NO_GLOBAL -static const FrameInfo frameInfo_global = CreateFrameInfo(); -const FrameInfo GetFrameInfo(){ return frameInfo_global; } +static const ConstantBuffer frameInfo_global = CreateFrameInfo(); +ConstantBuffer GetFrameInfo(){ return frameInfo_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GBuffer.h b/workdir/shaders/autogen/GBuffer.h index 81b7509f..53e5bdc8 100644 --- a/workdir/shaders/autogen/GBuffer.h +++ b/workdir/shaders/autogen/GBuffer.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GBuffer: register( b2, space6); +#ifdef __spirv__ +struct _CB_GBuffer { uint offset; }; +static _CB_GBuffer pass_GBuffer = { _hal_push.s6 }; +#else +ConstantBuffer pass_GBuffer: register(b6, space6); +#endif ConstantBuffer CreateGBuffer() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGBuffer() } #ifndef NO_GLOBAL -static const GBuffer gBuffer_global = CreateGBuffer(); -const GBuffer GetGBuffer(){ return gBuffer_global; } +static const ConstantBuffer gBuffer_global = CreateGBuffer(); +ConstantBuffer GetGBuffer(){ return gBuffer_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GBufferDownsample.h b/workdir/shaders/autogen/GBufferDownsample.h index aaf49bc9..f5f7ef3e 100644 --- a/workdir/shaders/autogen/GBufferDownsample.h +++ b/workdir/shaders/autogen/GBufferDownsample.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GBufferDownsample: register( b2, space6); +#ifdef __spirv__ +struct _CB_GBufferDownsample { uint offset; }; +static _CB_GBufferDownsample pass_GBufferDownsample = { _hal_push.s6 }; +#else +ConstantBuffer pass_GBufferDownsample: register(b6, space6); +#endif ConstantBuffer CreateGBufferDownsample() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGBufferDownsample() } #ifndef NO_GLOBAL -static const GBufferDownsample gBufferDownsample_global = CreateGBufferDownsample(); -const GBufferDownsample GetGBufferDownsample(){ return gBufferDownsample_global; } +static const ConstantBuffer gBufferDownsample_global = CreateGBufferDownsample(); +ConstantBuffer GetGBufferDownsample(){ return gBufferDownsample_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GBufferQuality.h b/workdir/shaders/autogen/GBufferQuality.h index e2b75012..86581984 100644 --- a/workdir/shaders/autogen/GBufferQuality.h +++ b/workdir/shaders/autogen/GBufferQuality.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GBufferQuality: register( b2, space6); +#ifdef __spirv__ +struct _CB_GBufferQuality { uint offset; }; +static _CB_GBufferQuality pass_GBufferQuality = { _hal_push.s6 }; +#else +ConstantBuffer pass_GBufferQuality: register(b6, space6); +#endif ConstantBuffer CreateGBufferQuality() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGBufferQuality() } #ifndef NO_GLOBAL -static const GBufferQuality gBufferQuality_global = CreateGBufferQuality(); -const GBufferQuality GetGBufferQuality(){ return gBufferQuality_global; } +static const ConstantBuffer gBufferQuality_global = CreateGBufferQuality(); +ConstantBuffer GetGBufferQuality(){ return gBufferQuality_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GatherBoxes.h b/workdir/shaders/autogen/GatherBoxes.h index 74002ffb..d10e2694 100644 --- a/workdir/shaders/autogen/GatherBoxes.h +++ b/workdir/shaders/autogen/GatherBoxes.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GatherBoxes: register( b2, space5); +#ifdef __spirv__ +struct _CB_GatherBoxes { uint offset; }; +static _CB_GatherBoxes pass_GatherBoxes = { _hal_push.s5 }; +#else +ConstantBuffer pass_GatherBoxes: register(b5, space5); +#endif ConstantBuffer CreateGatherBoxes() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGatherBoxes() } #ifndef NO_GLOBAL -static const GatherBoxes gatherBoxes_global = CreateGatherBoxes(); -const GatherBoxes GetGatherBoxes(){ return gatherBoxes_global; } +static const ConstantBuffer gatherBoxes_global = CreateGatherBoxes(); +ConstantBuffer GetGatherBoxes(){ return gatherBoxes_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GatherMeshesBoxes.h b/workdir/shaders/autogen/GatherMeshesBoxes.h index 0561f8ad..522f950b 100644 --- a/workdir/shaders/autogen/GatherMeshesBoxes.h +++ b/workdir/shaders/autogen/GatherMeshesBoxes.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GatherMeshesBoxes: register( b2, space5); +#ifdef __spirv__ +struct _CB_GatherMeshesBoxes { uint offset; }; +static _CB_GatherMeshesBoxes pass_GatherMeshesBoxes = { _hal_push.s5 }; +#else +ConstantBuffer pass_GatherMeshesBoxes: register(b5, space5); +#endif ConstantBuffer CreateGatherMeshesBoxes() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGatherMeshesBoxes() } #ifndef NO_GLOBAL -static const GatherMeshesBoxes gatherMeshesBoxes_global = CreateGatherMeshesBoxes(); -const GatherMeshesBoxes GetGatherMeshesBoxes(){ return gatherMeshesBoxes_global; } +static const ConstantBuffer gatherMeshesBoxes_global = CreateGatherMeshesBoxes(); +ConstantBuffer GetGatherMeshesBoxes(){ return gatherMeshesBoxes_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GatherPipeline.h b/workdir/shaders/autogen/GatherPipeline.h index 96e5c9d7..20847878 100644 --- a/workdir/shaders/autogen/GatherPipeline.h +++ b/workdir/shaders/autogen/GatherPipeline.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GatherPipeline: register( b2, space5); +#ifdef __spirv__ +struct _CB_GatherPipeline { uint offset; }; +static _CB_GatherPipeline pass_GatherPipeline = { _hal_push.s5 }; +#else +ConstantBuffer pass_GatherPipeline: register(b5, space5); +#endif ConstantBuffer CreateGatherPipeline() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGatherPipeline() } #ifndef NO_GLOBAL -static const GatherPipeline gatherPipeline_global = CreateGatherPipeline(); -const GatherPipeline GetGatherPipeline(){ return gatherPipeline_global; } +static const ConstantBuffer gatherPipeline_global = CreateGatherPipeline(); +ConstantBuffer GetGatherPipeline(){ return gatherPipeline_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GatherPipelineGlobal.h b/workdir/shaders/autogen/GatherPipelineGlobal.h index 41a38057..a4229c03 100644 --- a/workdir/shaders/autogen/GatherPipelineGlobal.h +++ b/workdir/shaders/autogen/GatherPipelineGlobal.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GatherPipelineGlobal: register( b2, space4); +#ifdef __spirv__ +struct _CB_GatherPipelineGlobal { uint offset; }; +static _CB_GatherPipelineGlobal pass_GatherPipelineGlobal = { _hal_push.s4 }; +#else +ConstantBuffer pass_GatherPipelineGlobal: register(b4, space4); +#endif ConstantBuffer CreateGatherPipelineGlobal() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGatherPipelineGlobal() } #ifndef NO_GLOBAL -static const GatherPipelineGlobal gatherPipelineGlobal_global = CreateGatherPipelineGlobal(); -const GatherPipelineGlobal GetGatherPipelineGlobal(){ return gatherPipelineGlobal_global; } +static const ConstantBuffer gatherPipelineGlobal_global = CreateGatherPipelineGlobal(); +ConstantBuffer GetGatherPipelineGlobal(){ return gatherPipelineGlobal_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/GraphInput.h b/workdir/shaders/autogen/GraphInput.h index 08fff998..bda3f50a 100644 --- a/workdir/shaders/autogen/GraphInput.h +++ b/workdir/shaders/autogen/GraphInput.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_GraphInput: register( b2, space0); +#ifdef __spirv__ +struct _CB_GraphInput { uint offset; }; +static _CB_GraphInput pass_GraphInput = { _hal_push.s0 }; +#else +ConstantBuffer pass_GraphInput: register(b0, space0); +#endif ConstantBuffer CreateGraphInput() { @@ -26,6 +31,6 @@ ConstantBuffer CreateGraphInput() } #ifndef NO_GLOBAL -static const GraphInput graphInput_global = CreateGraphInput(); -const GraphInput GetGraphInput(){ return graphInput_global; } +static const ConstantBuffer graphInput_global = CreateGraphInput(); +ConstantBuffer GetGraphInput(){ return graphInput_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/InitDispatch.h b/workdir/shaders/autogen/InitDispatch.h index 303df20c..ac559225 100644 --- a/workdir/shaders/autogen/InitDispatch.h +++ b/workdir/shaders/autogen/InitDispatch.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_InitDispatch: register( b2, space5); +#ifdef __spirv__ +struct _CB_InitDispatch { uint offset; }; +static _CB_InitDispatch pass_InitDispatch = { _hal_push.s5 }; +#else +ConstantBuffer pass_InitDispatch: register(b5, space5); +#endif ConstantBuffer CreateInitDispatch() { @@ -26,6 +31,6 @@ ConstantBuffer CreateInitDispatch() } #ifndef NO_GLOBAL -static const InitDispatch initDispatch_global = CreateInitDispatch(); -const InitDispatch GetInitDispatch(){ return initDispatch_global; } +static const ConstantBuffer initDispatch_global = CreateInitDispatch(); +ConstantBuffer GetInitDispatch(){ return initDispatch_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/Instance.h b/workdir/shaders/autogen/Instance.h index 584b6d44..194f9b39 100644 --- a/workdir/shaders/autogen/Instance.h +++ b/workdir/shaders/autogen/Instance.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_Instance: register( b2, space7); +#ifdef __spirv__ +struct _CB_Instance { uint offset; }; +static _CB_Instance pass_Instance = { _hal_push.s7 }; +#else +ConstantBuffer pass_Instance: register(b7, space7); +#endif ConstantBuffer CreateInstance() { @@ -26,6 +31,6 @@ ConstantBuffer CreateInstance() } #ifndef NO_GLOBAL -static const Instance instance_global = CreateInstance(); -const Instance GetInstance(){ return instance_global; } +static const ConstantBuffer instance_global = CreateInstance(); +ConstantBuffer GetInstance(){ return instance_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/LineRender.h b/workdir/shaders/autogen/LineRender.h index d1b2b653..db503fc1 100644 --- a/workdir/shaders/autogen/LineRender.h +++ b/workdir/shaders/autogen/LineRender.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_LineRender: register( b2, space4); +#ifdef __spirv__ +struct _CB_LineRender { uint offset; }; +static _CB_LineRender pass_LineRender = { _hal_push.s4 }; +#else +ConstantBuffer pass_LineRender: register(b4, space4); +#endif ConstantBuffer CreateLineRender() { @@ -26,6 +31,6 @@ ConstantBuffer CreateLineRender() } #ifndef NO_GLOBAL -static const LineRender lineRender_global = CreateLineRender(); -const LineRender GetLineRender(){ return lineRender_global; } +static const ConstantBuffer lineRender_global = CreateLineRender(); +ConstantBuffer GetLineRender(){ return lineRender_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/MaterialInfo.h b/workdir/shaders/autogen/MaterialInfo.h index 5ba95196..a0045857 100644 --- a/workdir/shaders/autogen/MaterialInfo.h +++ b/workdir/shaders/autogen/MaterialInfo.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_MaterialInfo: register( b2, space11); +#ifdef __spirv__ +struct _CB_MaterialInfo { uint offset; }; +static _CB_MaterialInfo pass_MaterialInfo = { _hal_push.s11 }; +#else +ConstantBuffer pass_MaterialInfo: register(b11, space11); +#endif ConstantBuffer CreateMaterialInfo() { @@ -26,6 +31,6 @@ ConstantBuffer CreateMaterialInfo() } #ifndef NO_GLOBAL -static const MaterialInfo materialInfo_global = CreateMaterialInfo(); -const MaterialInfo GetMaterialInfo(){ return materialInfo_global; } +static const ConstantBuffer materialInfo_global = CreateMaterialInfo(); +ConstantBuffer GetMaterialInfo(){ return materialInfo_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/MeshInfo.h b/workdir/shaders/autogen/MeshInfo.h index fa931b47..06e60cbe 100644 --- a/workdir/shaders/autogen/MeshInfo.h +++ b/workdir/shaders/autogen/MeshInfo.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_MeshInfo: register( b2, space5); +#ifdef __spirv__ +struct _CB_MeshInfo { uint offset; }; +static _CB_MeshInfo pass_MeshInfo = { _hal_push.s5 }; +#else +ConstantBuffer pass_MeshInfo: register(b5, space5); +#endif ConstantBuffer CreateMeshInfo() { @@ -26,6 +31,6 @@ ConstantBuffer CreateMeshInfo() } #ifndef NO_GLOBAL -static const MeshInfo meshInfo_global = CreateMeshInfo(); -const MeshInfo GetMeshInfo(){ return meshInfo_global; } +static const ConstantBuffer meshInfo_global = CreateMeshInfo(); +ConstantBuffer GetMeshInfo(){ return meshInfo_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/MeshInstanceInfo.h b/workdir/shaders/autogen/MeshInstanceInfo.h index c6da52f7..83415253 100644 --- a/workdir/shaders/autogen/MeshInstanceInfo.h +++ b/workdir/shaders/autogen/MeshInstanceInfo.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_MeshInstanceInfo: register( b2, space6); +#ifdef __spirv__ +struct _CB_MeshInstanceInfo { uint offset; }; +static _CB_MeshInstanceInfo pass_MeshInstanceInfo = { _hal_push.s6 }; +#else +ConstantBuffer pass_MeshInstanceInfo: register(b6, space6); +#endif ConstantBuffer CreateMeshInstanceInfo() { @@ -26,6 +31,6 @@ ConstantBuffer CreateMeshInstanceInfo() } #ifndef NO_GLOBAL -static const MeshInstanceInfo meshInstanceInfo_global = CreateMeshInstanceInfo(); -const MeshInstanceInfo GetMeshInstanceInfo(){ return meshInstanceInfo_global; } +static const ConstantBuffer meshInstanceInfo_global = CreateMeshInstanceInfo(); +ConstantBuffer GetMeshInstanceInfo(){ return meshInstanceInfo_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/MipMapping.h b/workdir/shaders/autogen/MipMapping.h index a4b2db44..81954e6f 100644 --- a/workdir/shaders/autogen/MipMapping.h +++ b/workdir/shaders/autogen/MipMapping.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_MipMapping: register( b2, space4); +#ifdef __spirv__ +struct _CB_MipMapping { uint offset; }; +static _CB_MipMapping pass_MipMapping = { _hal_push.s4 }; +#else +ConstantBuffer pass_MipMapping: register(b4, space4); +#endif ConstantBuffer CreateMipMapping() { @@ -26,6 +31,6 @@ ConstantBuffer CreateMipMapping() } #ifndef NO_GLOBAL -static const MipMapping mipMapping_global = CreateMipMapping(); -const MipMapping GetMipMapping(){ return mipMapping_global; } +static const ConstantBuffer mipMapping_global = CreateMipMapping(); +ConstantBuffer GetMipMapping(){ return mipMapping_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/NinePatch.h b/workdir/shaders/autogen/NinePatch.h index 1e3be468..f09395a5 100644 --- a/workdir/shaders/autogen/NinePatch.h +++ b/workdir/shaders/autogen/NinePatch.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_NinePatch: register( b2, space4); +#ifdef __spirv__ +struct _CB_NinePatch { uint offset; }; +static _CB_NinePatch pass_NinePatch = { _hal_push.s4 }; +#else +ConstantBuffer pass_NinePatch: register(b4, space4); +#endif ConstantBuffer CreateNinePatch() { @@ -26,6 +31,6 @@ ConstantBuffer CreateNinePatch() } #ifndef NO_GLOBAL -static const NinePatch ninePatch_global = CreateNinePatch(); -const NinePatch GetNinePatch(){ return ninePatch_global; } +static const ConstantBuffer ninePatch_global = CreateNinePatch(); +ConstantBuffer GetNinePatch(){ return ninePatch_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/PSSMConstants.h b/workdir/shaders/autogen/PSSMConstants.h index bbc1197d..cd2ab2c0 100644 --- a/workdir/shaders/autogen/PSSMConstants.h +++ b/workdir/shaders/autogen/PSSMConstants.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_PSSMConstants: register( b2, space4); +#ifdef __spirv__ +struct _CB_PSSMConstants { uint offset; }; +static _CB_PSSMConstants pass_PSSMConstants = { _hal_push.s4 }; +#else +ConstantBuffer pass_PSSMConstants: register(b4, space4); +#endif ConstantBuffer CreatePSSMConstants() { @@ -26,6 +31,6 @@ ConstantBuffer CreatePSSMConstants() } #ifndef NO_GLOBAL -static const PSSMConstants pSSMConstants_global = CreatePSSMConstants(); -const PSSMConstants GetPSSMConstants(){ return pSSMConstants_global; } +static const ConstantBuffer pSSMConstants_global = CreatePSSMConstants(); +ConstantBuffer GetPSSMConstants(){ return pSSMConstants_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/PSSMData.h b/workdir/shaders/autogen/PSSMData.h index 848f7662..8571fcd8 100644 --- a/workdir/shaders/autogen/PSSMData.h +++ b/workdir/shaders/autogen/PSSMData.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_PSSMData: register( b2, space5); +#ifdef __spirv__ +struct _CB_PSSMData { uint offset; }; +static _CB_PSSMData pass_PSSMData = { _hal_push.s5 }; +#else +ConstantBuffer pass_PSSMData: register(b5, space5); +#endif ConstantBuffer CreatePSSMData() { @@ -26,6 +31,6 @@ ConstantBuffer CreatePSSMData() } #ifndef NO_GLOBAL -static const PSSMData pSSMData_global = CreatePSSMData(); -const PSSMData GetPSSMData(){ return pSSMData_global; } +static const ConstantBuffer pSSMData_global = CreatePSSMData(); +ConstantBuffer GetPSSMData(){ return pSSMData_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/PSSMDataGlobal.h b/workdir/shaders/autogen/PSSMDataGlobal.h index a7cd2b64..9aed02e4 100644 --- a/workdir/shaders/autogen/PSSMDataGlobal.h +++ b/workdir/shaders/autogen/PSSMDataGlobal.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_PSSMDataGlobal: register( b2, space5); +#ifdef __spirv__ +struct _CB_PSSMDataGlobal { uint offset; }; +static _CB_PSSMDataGlobal pass_PSSMDataGlobal = { _hal_push.s5 }; +#else +ConstantBuffer pass_PSSMDataGlobal: register(b5, space5); +#endif ConstantBuffer CreatePSSMDataGlobal() { @@ -26,6 +31,6 @@ ConstantBuffer CreatePSSMDataGlobal() } #ifndef NO_GLOBAL -static const PSSMDataGlobal pSSMDataGlobal_global = CreatePSSMDataGlobal(); -const PSSMDataGlobal GetPSSMDataGlobal(){ return pSSMDataGlobal_global; } +static const ConstantBuffer pSSMDataGlobal_global = CreatePSSMDataGlobal(); +ConstantBuffer GetPSSMDataGlobal(){ return pSSMDataGlobal_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/PSSMLighting.h b/workdir/shaders/autogen/PSSMLighting.h index ffb1bde5..bab66446 100644 --- a/workdir/shaders/autogen/PSSMLighting.h +++ b/workdir/shaders/autogen/PSSMLighting.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_PSSMLighting: register( b2, space6); +#ifdef __spirv__ +struct _CB_PSSMLighting { uint offset; }; +static _CB_PSSMLighting pass_PSSMLighting = { _hal_push.s6 }; +#else +ConstantBuffer pass_PSSMLighting: register(b6, space6); +#endif ConstantBuffer CreatePSSMLighting() { @@ -26,6 +31,6 @@ ConstantBuffer CreatePSSMLighting() } #ifndef NO_GLOBAL -static const PSSMLighting pSSMLighting_global = CreatePSSMLighting(); -const PSSMLighting GetPSSMLighting(){ return pSSMLighting_global; } +static const ConstantBuffer pSSMLighting_global = CreatePSSMLighting(); +ConstantBuffer GetPSSMLighting(){ return pSSMLighting_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/PickerBuffer.h b/workdir/shaders/autogen/PickerBuffer.h index f4bc7944..7524f954 100644 --- a/workdir/shaders/autogen/PickerBuffer.h +++ b/workdir/shaders/autogen/PickerBuffer.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_PickerBuffer: register( b2, space4); +#ifdef __spirv__ +struct _CB_PickerBuffer { uint offset; }; +static _CB_PickerBuffer pass_PickerBuffer = { _hal_push.s4 }; +#else +ConstantBuffer pass_PickerBuffer: register(b4, space4); +#endif ConstantBuffer CreatePickerBuffer() { @@ -26,6 +31,6 @@ ConstantBuffer CreatePickerBuffer() } #ifndef NO_GLOBAL -static const PickerBuffer pickerBuffer_global = CreatePickerBuffer(); -const PickerBuffer GetPickerBuffer(){ return pickerBuffer_global; } +static const ConstantBuffer pickerBuffer_global = CreatePickerBuffer(); +ConstantBuffer GetPickerBuffer(){ return pickerBuffer_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/Raytracing.h b/workdir/shaders/autogen/Raytracing.h index ce92afeb..9f1a150b 100644 --- a/workdir/shaders/autogen/Raytracing.h +++ b/workdir/shaders/autogen/Raytracing.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_Raytracing: register( b2, space10); +#ifdef __spirv__ +struct _CB_Raytracing { uint offset; }; +static _CB_Raytracing pass_Raytracing = { _hal_push.s10 }; +#else +ConstantBuffer pass_Raytracing: register(b10, space10); +#endif ConstantBuffer CreateRaytracing() { @@ -26,6 +31,6 @@ ConstantBuffer CreateRaytracing() } #ifndef NO_GLOBAL -static const Raytracing raytracing_global = CreateRaytracing(); -const Raytracing GetRaytracing(){ return raytracing_global; } +static const ConstantBuffer raytracing_global = CreateRaytracing(); +ConstantBuffer GetRaytracing(){ return raytracing_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/RaytracingRays.h b/workdir/shaders/autogen/RaytracingRays.h index 354717a6..d20259d1 100644 --- a/workdir/shaders/autogen/RaytracingRays.h +++ b/workdir/shaders/autogen/RaytracingRays.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_RaytracingRays: register( b2, space6); +#ifdef __spirv__ +struct _CB_RaytracingRays { uint offset; }; +static _CB_RaytracingRays pass_RaytracingRays = { _hal_push.s6 }; +#else +ConstantBuffer pass_RaytracingRays: register(b6, space6); +#endif ConstantBuffer CreateRaytracingRays() { @@ -26,6 +31,6 @@ ConstantBuffer CreateRaytracingRays() } #ifndef NO_GLOBAL -static const RaytracingRays raytracingRays_global = CreateRaytracingRays(); -const RaytracingRays GetRaytracingRays(){ return raytracingRays_global; } +static const ConstantBuffer raytracingRays_global = CreateRaytracingRays(); +ConstantBuffer GetRaytracingRays(){ return raytracingRays_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/ReflectionCombine.h b/workdir/shaders/autogen/ReflectionCombine.h index 3a76dd27..78c32e35 100644 --- a/workdir/shaders/autogen/ReflectionCombine.h +++ b/workdir/shaders/autogen/ReflectionCombine.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_ReflectionCombine: register( b2, space4); +#ifdef __spirv__ +struct _CB_ReflectionCombine { uint offset; }; +static _CB_ReflectionCombine pass_ReflectionCombine = { _hal_push.s4 }; +#else +ConstantBuffer pass_ReflectionCombine: register(b4, space4); +#endif ConstantBuffer CreateReflectionCombine() { @@ -26,6 +31,6 @@ ConstantBuffer CreateReflectionCombine() } #ifndef NO_GLOBAL -static const ReflectionCombine reflectionCombine_global = CreateReflectionCombine(); -const ReflectionCombine GetReflectionCombine(){ return reflectionCombine_global; } +static const ConstantBuffer reflectionCombine_global = CreateReflectionCombine(); +ConstantBuffer GetReflectionCombine(){ return reflectionCombine_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/SMAA_Blend.h b/workdir/shaders/autogen/SMAA_Blend.h index d6d89f94..6667b90f 100644 --- a/workdir/shaders/autogen/SMAA_Blend.h +++ b/workdir/shaders/autogen/SMAA_Blend.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_SMAA_Blend: register( b2, space5); +#ifdef __spirv__ +struct _CB_SMAA_Blend { uint offset; }; +static _CB_SMAA_Blend pass_SMAA_Blend = { _hal_push.s5 }; +#else +ConstantBuffer pass_SMAA_Blend: register(b5, space5); +#endif ConstantBuffer CreateSMAA_Blend() { @@ -26,6 +31,6 @@ ConstantBuffer CreateSMAA_Blend() } #ifndef NO_GLOBAL -static const SMAA_Blend sMAA_Blend_global = CreateSMAA_Blend(); -const SMAA_Blend GetSMAA_Blend(){ return sMAA_Blend_global; } +static const ConstantBuffer sMAA_Blend_global = CreateSMAA_Blend(); +ConstantBuffer GetSMAA_Blend(){ return sMAA_Blend_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/SMAA_Global.h b/workdir/shaders/autogen/SMAA_Global.h index a9196a9b..a4bb8c24 100644 --- a/workdir/shaders/autogen/SMAA_Global.h +++ b/workdir/shaders/autogen/SMAA_Global.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_SMAA_Global: register( b2, space4); +#ifdef __spirv__ +struct _CB_SMAA_Global { uint offset; }; +static _CB_SMAA_Global pass_SMAA_Global = { _hal_push.s4 }; +#else +ConstantBuffer pass_SMAA_Global: register(b4, space4); +#endif ConstantBuffer CreateSMAA_Global() { @@ -26,6 +31,6 @@ ConstantBuffer CreateSMAA_Global() } #ifndef NO_GLOBAL -static const SMAA_Global sMAA_Global_global = CreateSMAA_Global(); -const SMAA_Global GetSMAA_Global(){ return sMAA_Global_global; } +static const ConstantBuffer sMAA_Global_global = CreateSMAA_Global(); +ConstantBuffer GetSMAA_Global(){ return sMAA_Global_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/SMAA_Weights.h b/workdir/shaders/autogen/SMAA_Weights.h index f8478512..3d76d3f8 100644 --- a/workdir/shaders/autogen/SMAA_Weights.h +++ b/workdir/shaders/autogen/SMAA_Weights.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_SMAA_Weights: register( b2, space5); +#ifdef __spirv__ +struct _CB_SMAA_Weights { uint offset; }; +static _CB_SMAA_Weights pass_SMAA_Weights = { _hal_push.s5 }; +#else +ConstantBuffer pass_SMAA_Weights: register(b5, space5); +#endif ConstantBuffer CreateSMAA_Weights() { @@ -26,6 +31,6 @@ ConstantBuffer CreateSMAA_Weights() } #ifndef NO_GLOBAL -static const SMAA_Weights sMAA_Weights_global = CreateSMAA_Weights(); -const SMAA_Weights GetSMAA_Weights(){ return sMAA_Weights_global; } +static const ConstantBuffer sMAA_Weights_global = CreateSMAA_Weights(); +ConstantBuffer GetSMAA_Weights(){ return sMAA_Weights_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/SceneData.h b/workdir/shaders/autogen/SceneData.h index 67b1910d..9905849f 100644 --- a/workdir/shaders/autogen/SceneData.h +++ b/workdir/shaders/autogen/SceneData.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_SceneData: register( b2, space1); +#ifdef __spirv__ +struct _CB_SceneData { uint offset; }; +static _CB_SceneData pass_SceneData = { _hal_push.s1 }; +#else +ConstantBuffer pass_SceneData: register(b1, space1); +#endif ConstantBuffer CreateSceneData() { @@ -26,6 +31,6 @@ ConstantBuffer CreateSceneData() } #ifndef NO_GLOBAL -static const SceneData sceneData_global = CreateSceneData(); -const SceneData GetSceneData(){ return sceneData_global; } +static const ConstantBuffer sceneData_global = CreateSceneData(); +ConstantBuffer GetSceneData(){ return sceneData_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/SkyData.h b/workdir/shaders/autogen/SkyData.h index cd285606..0a60977f 100644 --- a/workdir/shaders/autogen/SkyData.h +++ b/workdir/shaders/autogen/SkyData.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_SkyData: register( b2, space4); +#ifdef __spirv__ +struct _CB_SkyData { uint offset; }; +static _CB_SkyData pass_SkyData = { _hal_push.s4 }; +#else +ConstantBuffer pass_SkyData: register(b4, space4); +#endif ConstantBuffer CreateSkyData() { @@ -26,6 +31,6 @@ ConstantBuffer CreateSkyData() } #ifndef NO_GLOBAL -static const SkyData skyData_global = CreateSkyData(); -const SkyData GetSkyData(){ return skyData_global; } +static const ConstantBuffer skyData_global = CreateSkyData(); +ConstantBuffer GetSkyData(){ return skyData_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/SkyFace.h b/workdir/shaders/autogen/SkyFace.h index ae4bf764..bbbc9fcc 100644 --- a/workdir/shaders/autogen/SkyFace.h +++ b/workdir/shaders/autogen/SkyFace.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_SkyFace: register( b2, space5); +#ifdef __spirv__ +struct _CB_SkyFace { uint offset; }; +static _CB_SkyFace pass_SkyFace = { _hal_push.s5 }; +#else +ConstantBuffer pass_SkyFace: register(b5, space5); +#endif ConstantBuffer CreateSkyFace() { @@ -26,6 +31,6 @@ ConstantBuffer CreateSkyFace() } #ifndef NO_GLOBAL -static const SkyFace skyFace_global = CreateSkyFace(); -const SkyFace GetSkyFace(){ return skyFace_global; } +static const ConstantBuffer skyFace_global = CreateSkyFace(); +ConstantBuffer GetSkyFace(){ return skyFace_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/Test.h b/workdir/shaders/autogen/Test.h index 26958a62..d213d29d 100644 --- a/workdir/shaders/autogen/Test.h +++ b/workdir/shaders/autogen/Test.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_Test: register( b2, space4); +#ifdef __spirv__ +struct _CB_Test { uint offset; }; +static _CB_Test pass_Test = { _hal_push.s4 }; +#else +ConstantBuffer pass_Test: register(b4, space4); +#endif ConstantBuffer CreateTest() { @@ -26,6 +31,6 @@ ConstantBuffer CreateTest() } #ifndef NO_GLOBAL -static const Test test_global = CreateTest(); -const Test GetTest(){ return test_global; } +static const ConstantBuffer test_global = CreateTest(); +ConstantBuffer GetTest(){ return test_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/TextureRenderer.h b/workdir/shaders/autogen/TextureRenderer.h index b10d158f..177f562b 100644 --- a/workdir/shaders/autogen/TextureRenderer.h +++ b/workdir/shaders/autogen/TextureRenderer.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_TextureRenderer: register( b2, space4); +#ifdef __spirv__ +struct _CB_TextureRenderer { uint offset; }; +static _CB_TextureRenderer pass_TextureRenderer = { _hal_push.s4 }; +#else +ConstantBuffer pass_TextureRenderer: register(b4, space4); +#endif ConstantBuffer CreateTextureRenderer() { @@ -26,6 +31,6 @@ ConstantBuffer CreateTextureRenderer() } #ifndef NO_GLOBAL -static const TextureRenderer textureRenderer_global = CreateTextureRenderer(); -const TextureRenderer GetTextureRenderer(){ return textureRenderer_global; } +static const ConstantBuffer textureRenderer_global = CreateTextureRenderer(); +ConstantBuffer GetTextureRenderer(){ return textureRenderer_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/TilingPostprocess.h b/workdir/shaders/autogen/TilingPostprocess.h index 48935599..b2b7c65c 100644 --- a/workdir/shaders/autogen/TilingPostprocess.h +++ b/workdir/shaders/autogen/TilingPostprocess.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_TilingPostprocess: register( b2, space2); +#ifdef __spirv__ +struct _CB_TilingPostprocess { uint offset; }; +static _CB_TilingPostprocess pass_TilingPostprocess = { _hal_push.s2 }; +#else +ConstantBuffer pass_TilingPostprocess: register(b2, space2); +#endif ConstantBuffer CreateTilingPostprocess() { @@ -26,6 +31,6 @@ ConstantBuffer CreateTilingPostprocess() } #ifndef NO_GLOBAL -static const TilingPostprocess tilingPostprocess_global = CreateTilingPostprocess(); -const TilingPostprocess GetTilingPostprocess(){ return tilingPostprocess_global; } +static const ConstantBuffer tilingPostprocess_global = CreateTilingPostprocess(); +ConstantBuffer GetTilingPostprocess(){ return tilingPostprocess_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelBlur.h b/workdir/shaders/autogen/VoxelBlur.h index e7e5068e..83933f0e 100644 --- a/workdir/shaders/autogen/VoxelBlur.h +++ b/workdir/shaders/autogen/VoxelBlur.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelBlur: register( b2, space6); +#ifdef __spirv__ +struct _CB_VoxelBlur { uint offset; }; +static _CB_VoxelBlur pass_VoxelBlur = { _hal_push.s6 }; +#else +ConstantBuffer pass_VoxelBlur: register(b6, space6); +#endif ConstantBuffer CreateVoxelBlur() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelBlur() } #ifndef NO_GLOBAL -static const VoxelBlur voxelBlur_global = CreateVoxelBlur(); -const VoxelBlur GetVoxelBlur(){ return voxelBlur_global; } +static const ConstantBuffer voxelBlur_global = CreateVoxelBlur(); +ConstantBuffer GetVoxelBlur(){ return voxelBlur_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelCopy.h b/workdir/shaders/autogen/VoxelCopy.h index 7e5fccc8..57fd9d2b 100644 --- a/workdir/shaders/autogen/VoxelCopy.h +++ b/workdir/shaders/autogen/VoxelCopy.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelCopy: register( b2, space5); +#ifdef __spirv__ +struct _CB_VoxelCopy { uint offset; }; +static _CB_VoxelCopy pass_VoxelCopy = { _hal_push.s5 }; +#else +ConstantBuffer pass_VoxelCopy: register(b5, space5); +#endif ConstantBuffer CreateVoxelCopy() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelCopy() } #ifndef NO_GLOBAL -static const VoxelCopy voxelCopy_global = CreateVoxelCopy(); -const VoxelCopy GetVoxelCopy(){ return voxelCopy_global; } +static const ConstantBuffer voxelCopy_global = CreateVoxelCopy(); +ConstantBuffer GetVoxelCopy(){ return voxelCopy_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelDebug.h b/workdir/shaders/autogen/VoxelDebug.h index 0a765730..ae71dcb0 100644 --- a/workdir/shaders/autogen/VoxelDebug.h +++ b/workdir/shaders/autogen/VoxelDebug.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelDebug: register( b2, space5); +#ifdef __spirv__ +struct _CB_VoxelDebug { uint offset; }; +static _CB_VoxelDebug pass_VoxelDebug = { _hal_push.s5 }; +#else +ConstantBuffer pass_VoxelDebug: register(b5, space5); +#endif ConstantBuffer CreateVoxelDebug() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelDebug() } #ifndef NO_GLOBAL -static const VoxelDebug voxelDebug_global = CreateVoxelDebug(); -const VoxelDebug GetVoxelDebug(){ return voxelDebug_global; } +static const ConstantBuffer voxelDebug_global = CreateVoxelDebug(); +ConstantBuffer GetVoxelDebug(){ return voxelDebug_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelInfo.h b/workdir/shaders/autogen/VoxelInfo.h index b6ee8cfe..7ac8c728 100644 --- a/workdir/shaders/autogen/VoxelInfo.h +++ b/workdir/shaders/autogen/VoxelInfo.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelInfo: register( b2, space4); +#ifdef __spirv__ +struct _CB_VoxelInfo { uint offset; }; +static _CB_VoxelInfo pass_VoxelInfo = { _hal_push.s4 }; +#else +ConstantBuffer pass_VoxelInfo: register(b4, space4); +#endif ConstantBuffer CreateVoxelInfo() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelInfo() } #ifndef NO_GLOBAL -static const VoxelInfo voxelInfo_global = CreateVoxelInfo(); -const VoxelInfo GetVoxelInfo(){ return voxelInfo_global; } +static const ConstantBuffer voxelInfo_global = CreateVoxelInfo(); +ConstantBuffer GetVoxelInfo(){ return voxelInfo_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelLighting.h b/workdir/shaders/autogen/VoxelLighting.h index 2ad27706..27eaeac2 100644 --- a/workdir/shaders/autogen/VoxelLighting.h +++ b/workdir/shaders/autogen/VoxelLighting.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelLighting: register( b2, space5); +#ifdef __spirv__ +struct _CB_VoxelLighting { uint offset; }; +static _CB_VoxelLighting pass_VoxelLighting = { _hal_push.s5 }; +#else +ConstantBuffer pass_VoxelLighting: register(b5, space5); +#endif ConstantBuffer CreateVoxelLighting() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelLighting() } #ifndef NO_GLOBAL -static const VoxelLighting voxelLighting_global = CreateVoxelLighting(); -const VoxelLighting GetVoxelLighting(){ return voxelLighting_global; } +static const ConstantBuffer voxelLighting_global = CreateVoxelLighting(); +ConstantBuffer GetVoxelLighting(){ return voxelLighting_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelMipMap.h b/workdir/shaders/autogen/VoxelMipMap.h index c4e4a4ec..a1dd1f45 100644 --- a/workdir/shaders/autogen/VoxelMipMap.h +++ b/workdir/shaders/autogen/VoxelMipMap.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelMipMap: register( b2, space5); +#ifdef __spirv__ +struct _CB_VoxelMipMap { uint offset; }; +static _CB_VoxelMipMap pass_VoxelMipMap = { _hal_push.s5 }; +#else +ConstantBuffer pass_VoxelMipMap: register(b5, space5); +#endif ConstantBuffer CreateVoxelMipMap() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelMipMap() } #ifndef NO_GLOBAL -static const VoxelMipMap voxelMipMap_global = CreateVoxelMipMap(); -const VoxelMipMap GetVoxelMipMap(){ return voxelMipMap_global; } +static const ConstantBuffer voxelMipMap_global = CreateVoxelMipMap(); +ConstantBuffer GetVoxelMipMap(){ return voxelMipMap_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelOutput.h b/workdir/shaders/autogen/VoxelOutput.h index c81dcaa6..17034adc 100644 --- a/workdir/shaders/autogen/VoxelOutput.h +++ b/workdir/shaders/autogen/VoxelOutput.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelOutput: register( b2, space6); +#ifdef __spirv__ +struct _CB_VoxelOutput { uint offset; }; +static _CB_VoxelOutput pass_VoxelOutput = { _hal_push.s6 }; +#else +ConstantBuffer pass_VoxelOutput: register(b6, space6); +#endif ConstantBuffer CreateVoxelOutput() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelOutput() } #ifndef NO_GLOBAL -static const VoxelOutput voxelOutput_global = CreateVoxelOutput(); -const VoxelOutput GetVoxelOutput(){ return voxelOutput_global; } +static const ConstantBuffer voxelOutput_global = CreateVoxelOutput(); +ConstantBuffer GetVoxelOutput(){ return voxelOutput_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelScreen.h b/workdir/shaders/autogen/VoxelScreen.h index 198ef6e3..f26b7d6d 100644 --- a/workdir/shaders/autogen/VoxelScreen.h +++ b/workdir/shaders/autogen/VoxelScreen.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelScreen: register( b2, space5); +#ifdef __spirv__ +struct _CB_VoxelScreen { uint offset; }; +static _CB_VoxelScreen pass_VoxelScreen = { _hal_push.s5 }; +#else +ConstantBuffer pass_VoxelScreen: register(b5, space5); +#endif ConstantBuffer CreateVoxelScreen() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelScreen() } #ifndef NO_GLOBAL -static const VoxelScreen voxelScreen_global = CreateVoxelScreen(); -const VoxelScreen GetVoxelScreen(){ return voxelScreen_global; } +static const ConstantBuffer voxelScreen_global = CreateVoxelScreen(); +ConstantBuffer GetVoxelScreen(){ return voxelScreen_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelUpscale.h b/workdir/shaders/autogen/VoxelUpscale.h index 7bd8088b..44c18ba0 100644 --- a/workdir/shaders/autogen/VoxelUpscale.h +++ b/workdir/shaders/autogen/VoxelUpscale.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelUpscale: register( b2, space6); +#ifdef __spirv__ +struct _CB_VoxelUpscale { uint offset; }; +static _CB_VoxelUpscale pass_VoxelUpscale = { _hal_push.s6 }; +#else +ConstantBuffer pass_VoxelUpscale: register(b6, space6); +#endif ConstantBuffer CreateVoxelUpscale() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelUpscale() } #ifndef NO_GLOBAL -static const VoxelUpscale voxelUpscale_global = CreateVoxelUpscale(); -const VoxelUpscale GetVoxelUpscale(){ return voxelUpscale_global; } +static const ConstantBuffer voxelUpscale_global = CreateVoxelUpscale(); +ConstantBuffer GetVoxelUpscale(){ return voxelUpscale_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelVisibility.h b/workdir/shaders/autogen/VoxelVisibility.h index 4359a930..155253e4 100644 --- a/workdir/shaders/autogen/VoxelVisibility.h +++ b/workdir/shaders/autogen/VoxelVisibility.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelVisibility: register( b2, space5); +#ifdef __spirv__ +struct _CB_VoxelVisibility { uint offset; }; +static _CB_VoxelVisibility pass_VoxelVisibility = { _hal_push.s5 }; +#else +ConstantBuffer pass_VoxelVisibility: register(b5, space5); +#endif ConstantBuffer CreateVoxelVisibility() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelVisibility() } #ifndef NO_GLOBAL -static const VoxelVisibility voxelVisibility_global = CreateVoxelVisibility(); -const VoxelVisibility GetVoxelVisibility(){ return voxelVisibility_global; } +static const ConstantBuffer voxelVisibility_global = CreateVoxelVisibility(); +ConstantBuffer GetVoxelVisibility(){ return voxelVisibility_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/VoxelZero.h b/workdir/shaders/autogen/VoxelZero.h index 1691447c..a7a6e310 100644 --- a/workdir/shaders/autogen/VoxelZero.h +++ b/workdir/shaders/autogen/VoxelZero.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_VoxelZero: register( b2, space5); +#ifdef __spirv__ +struct _CB_VoxelZero { uint offset; }; +static _CB_VoxelZero pass_VoxelZero = { _hal_push.s5 }; +#else +ConstantBuffer pass_VoxelZero: register(b5, space5); +#endif ConstantBuffer CreateVoxelZero() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelZero() } #ifndef NO_GLOBAL -static const VoxelZero voxelZero_global = CreateVoxelZero(); -const VoxelZero GetVoxelZero(){ return voxelZero_global; } +static const ConstantBuffer voxelZero_global = CreateVoxelZero(); +ConstantBuffer GetVoxelZero(){ return voxelZero_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/Voxelization.h b/workdir/shaders/autogen/Voxelization.h index 2201ff4b..771013df 100644 --- a/workdir/shaders/autogen/Voxelization.h +++ b/workdir/shaders/autogen/Voxelization.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_Voxelization: register( b2, space7); +#ifdef __spirv__ +struct _CB_Voxelization { uint offset; }; +static _CB_Voxelization pass_Voxelization = { _hal_push.s7 }; +#else +ConstantBuffer pass_Voxelization: register(b7, space7); +#endif ConstantBuffer CreateVoxelization() { @@ -26,6 +31,6 @@ ConstantBuffer CreateVoxelization() } #ifndef NO_GLOBAL -static const Voxelization voxelization_global = CreateVoxelization(); -const Voxelization GetVoxelization(){ return voxelization_global; } +static const ConstantBuffer voxelization_global = CreateVoxelization(); +ConstantBuffer GetVoxelization(){ return voxelization_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/WorkGraphTest.h b/workdir/shaders/autogen/WorkGraphTest.h index 6a06a80b..0f35f667 100644 --- a/workdir/shaders/autogen/WorkGraphTest.h +++ b/workdir/shaders/autogen/WorkGraphTest.h @@ -18,7 +18,12 @@ struct CB { uint offset; }; #endif -ConstantBuffer< CB > pass_WorkGraphTest: register( b2, space4); +#ifdef __spirv__ +struct _CB_WorkGraphTest { uint offset; }; +static _CB_WorkGraphTest pass_WorkGraphTest = { _hal_push.s4 }; +#else +ConstantBuffer pass_WorkGraphTest: register(b4, space4); +#endif ConstantBuffer CreateWorkGraphTest() { @@ -26,6 +31,6 @@ ConstantBuffer CreateWorkGraphTest() } #ifndef NO_GLOBAL -static const WorkGraphTest workGraphTest_global = CreateWorkGraphTest(); -const WorkGraphTest GetWorkGraphTest(){ return workGraphTest_global; } +static const ConstantBuffer workGraphTest_global = CreateWorkGraphTest(); +ConstantBuffer GetWorkGraphTest(){ return workGraphTest_global; } #endif \ No newline at end of file diff --git a/workdir/shaders/autogen/layout/DefaultLayout.h b/workdir/shaders/autogen/layout/DefaultLayout.h index e853ce46..d9dd2d9c 100644 --- a/workdir/shaders/autogen/layout/DefaultLayout.h +++ b/workdir/shaders/autogen/layout/DefaultLayout.h @@ -4,6 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "FrameLayout.h" + diff --git a/workdir/shaders/autogen/layout/FrameLayout.h b/workdir/shaders/autogen/layout/FrameLayout.h index 686cea23..c862de26 100644 --- a/workdir/shaders/autogen/layout/FrameLayout.h +++ b/workdir/shaders/autogen/layout/FrameLayout.h @@ -4,10 +4,22 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once SamplerState linearSampler:register(s0); SamplerState pointClampSampler:register(s1); SamplerState linearClampSampler:register(s2); SamplerState anisoBordeSampler:register(s3); -SamplerState pointBorderSampler:register(s4); \ No newline at end of file +SamplerState pointBorderSampler:register(s4); +#ifdef __spirv__ +struct _HALPush { + uint s0; uint s1; uint s2; uint s3; + uint s4; uint s5; uint s6; uint s7; + uint s8; uint s9; uint s10; uint s11; + uint s12; uint s13; uint s14; uint s15; + uint s16; uint s17; uint s18; uint s19; + uint s20; uint s21; uint s22; uint s23; + uint s24; uint s25; uint s26; uint s27; + uint s28; uint s29; uint s30; uint s31; +}; +[[vk::push_constant]] ConstantBuffer<_HALPush> _hal_push; +#endif diff --git a/workdir/shaders/autogen/layout/NoneLayout.h b/workdir/shaders/autogen/layout/NoneLayout.h index 978d1da1..80ec4365 100644 --- a/workdir/shaders/autogen/layout/NoneLayout.h +++ b/workdir/shaders/autogen/layout/NoneLayout.h @@ -4,5 +4,17 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - -#pragma once \ No newline at end of file +#pragma once +#ifdef __spirv__ +struct _HALPush { + uint s0; uint s1; uint s2; uint s3; + uint s4; uint s5; uint s6; uint s7; + uint s8; uint s9; uint s10; uint s11; + uint s12; uint s13; uint s14; uint s15; + uint s16; uint s17; uint s18; uint s19; + uint s20; uint s21; uint s22; uint s23; + uint s24; uint s25; uint s26; uint s27; + uint s28; uint s29; uint s30; uint s31; +}; +[[vk::push_constant]] ConstantBuffer<_HALPush> _hal_push; +#endif diff --git a/workdir/shaders/autogen/rt/DepthOnly.h b/workdir/shaders/autogen/rt/DepthOnly.h index b80f3aac..a7cbe99a 100644 --- a/workdir/shaders/autogen/rt/DepthOnly.h +++ b/workdir/shaders/autogen/rt/DepthOnly.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct DepthOnly diff --git a/workdir/shaders/autogen/rt/GBuffer.h b/workdir/shaders/autogen/rt/GBuffer.h index 44b2fadc..9632790a 100644 --- a/workdir/shaders/autogen/rt/GBuffer.h +++ b/workdir/shaders/autogen/rt/GBuffer.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct GBuffer diff --git a/workdir/shaders/autogen/rt/GBufferDownsampleRT.h b/workdir/shaders/autogen/rt/GBufferDownsampleRT.h index b73baec1..f0ed986b 100644 --- a/workdir/shaders/autogen/rt/GBufferDownsampleRT.h +++ b/workdir/shaders/autogen/rt/GBufferDownsampleRT.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct GBufferDownsampleRT diff --git a/workdir/shaders/autogen/rt/NoOutput.h b/workdir/shaders/autogen/rt/NoOutput.h index ab05cea7..7001b380 100644 --- a/workdir/shaders/autogen/rt/NoOutput.h +++ b/workdir/shaders/autogen/rt/NoOutput.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct NoOutput diff --git a/workdir/shaders/autogen/rt/SingleColor.h b/workdir/shaders/autogen/rt/SingleColor.h index 396e284d..c5d2c2b4 100644 --- a/workdir/shaders/autogen/rt/SingleColor.h +++ b/workdir/shaders/autogen/rt/SingleColor.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct SingleColor diff --git a/workdir/shaders/autogen/rt/SingleColorDepth.h b/workdir/shaders/autogen/rt/SingleColorDepth.h index 6fd696d4..15274351 100644 --- a/workdir/shaders/autogen/rt/SingleColorDepth.h +++ b/workdir/shaders/autogen/rt/SingleColorDepth.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once struct SingleColorDepth diff --git a/workdir/shaders/autogen/tables/AABB.h b/workdir/shaders/autogen/tables/AABB.h index 830a9562..3efcae49 100644 --- a/workdir/shaders/autogen/tables/AABB.h +++ b/workdir/shaders/autogen/tables/AABB.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct AABB diff --git a/workdir/shaders/autogen/tables/BRDF.h b/workdir/shaders/autogen/tables/BRDF.h index b4f07ef6..9551ba0b 100644 --- a/workdir/shaders/autogen/tables/BRDF.h +++ b/workdir/shaders/autogen/tables/BRDF.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct BRDF diff --git a/workdir/shaders/autogen/tables/BlueNoise.h b/workdir/shaders/autogen/tables/BlueNoise.h index 35846cd6..75f1f9b8 100644 --- a/workdir/shaders/autogen/tables/BlueNoise.h +++ b/workdir/shaders/autogen/tables/BlueNoise.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct BlueNoise diff --git a/workdir/shaders/autogen/tables/BoxInfo.h b/workdir/shaders/autogen/tables/BoxInfo.h index 0c150206..abe87960 100644 --- a/workdir/shaders/autogen/tables/BoxInfo.h +++ b/workdir/shaders/autogen/tables/BoxInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct BoxInfo diff --git a/workdir/shaders/autogen/tables/Camera.h b/workdir/shaders/autogen/tables/Camera.h index ca62cb57..ce229315 100644 --- a/workdir/shaders/autogen/tables/Camera.h +++ b/workdir/shaders/autogen/tables/Camera.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "Frustum.h" diff --git a/workdir/shaders/autogen/tables/Color.h b/workdir/shaders/autogen/tables/Color.h index 132cc24e..1737477d 100644 --- a/workdir/shaders/autogen/tables/Color.h +++ b/workdir/shaders/autogen/tables/Color.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct Color diff --git a/workdir/shaders/autogen/tables/ColorRect.h b/workdir/shaders/autogen/tables/ColorRect.h index 1040def7..0126cf57 100644 --- a/workdir/shaders/autogen/tables/ColorRect.h +++ b/workdir/shaders/autogen/tables/ColorRect.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct ColorRect diff --git a/workdir/shaders/autogen/tables/CommandData.h b/workdir/shaders/autogen/tables/CommandData.h index 463cb851..84f80b30 100644 --- a/workdir/shaders/autogen/tables/CommandData.h +++ b/workdir/shaders/autogen/tables/CommandData.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "DispatchMeshArguments.h" diff --git a/workdir/shaders/autogen/tables/CopyTexture.h b/workdir/shaders/autogen/tables/CopyTexture.h index 976027ea..199fd8e0 100644 --- a/workdir/shaders/autogen/tables/CopyTexture.h +++ b/workdir/shaders/autogen/tables/CopyTexture.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct CopyTexture diff --git a/workdir/shaders/autogen/tables/Countour.h b/workdir/shaders/autogen/tables/Countour.h index 4f61c352..5d8bf16c 100644 --- a/workdir/shaders/autogen/tables/Countour.h +++ b/workdir/shaders/autogen/tables/Countour.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct Countour diff --git a/workdir/shaders/autogen/tables/DebugInfo.h b/workdir/shaders/autogen/tables/DebugInfo.h index 407d8667..501b79ae 100644 --- a/workdir/shaders/autogen/tables/DebugInfo.h +++ b/workdir/shaders/autogen/tables/DebugInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "DebugStruct.h" @@ -18,7 +17,7 @@ struct DebugInfo debug.v = v; - uav.debug[id] = debug; + GetDebug()[id] = debug; } diff --git a/workdir/shaders/autogen/tables/DebugStruct.h b/workdir/shaders/autogen/tables/DebugStruct.h index e56eac5d..cf5d30e0 100644 --- a/workdir/shaders/autogen/tables/DebugStruct.h +++ b/workdir/shaders/autogen/tables/DebugStruct.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DebugStruct diff --git a/workdir/shaders/autogen/tables/DenoiserDownsample.h b/workdir/shaders/autogen/tables/DenoiserDownsample.h index 38737d66..3d4dfaf7 100644 --- a/workdir/shaders/autogen/tables/DenoiserDownsample.h +++ b/workdir/shaders/autogen/tables/DenoiserDownsample.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserDownsample diff --git a/workdir/shaders/autogen/tables/DenoiserHistoryFix.h b/workdir/shaders/autogen/tables/DenoiserHistoryFix.h index 43121c6e..4cb7d344 100644 --- a/workdir/shaders/autogen/tables/DenoiserHistoryFix.h +++ b/workdir/shaders/autogen/tables/DenoiserHistoryFix.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserHistoryFix diff --git a/workdir/shaders/autogen/tables/DenoiserReflectionCommon.h b/workdir/shaders/autogen/tables/DenoiserReflectionCommon.h index b69785fe..13e6d027 100644 --- a/workdir/shaders/autogen/tables/DenoiserReflectionCommon.h +++ b/workdir/shaders/autogen/tables/DenoiserReflectionCommon.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserReflectionCommon diff --git a/workdir/shaders/autogen/tables/DenoiserReflectionPrefilter.h b/workdir/shaders/autogen/tables/DenoiserReflectionPrefilter.h index bb5b8b57..051c3bd4 100644 --- a/workdir/shaders/autogen/tables/DenoiserReflectionPrefilter.h +++ b/workdir/shaders/autogen/tables/DenoiserReflectionPrefilter.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserReflectionPrefilter diff --git a/workdir/shaders/autogen/tables/DenoiserReflectionReproject.h b/workdir/shaders/autogen/tables/DenoiserReflectionReproject.h index fb604ecb..1acb9b4b 100644 --- a/workdir/shaders/autogen/tables/DenoiserReflectionReproject.h +++ b/workdir/shaders/autogen/tables/DenoiserReflectionReproject.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserReflectionReproject diff --git a/workdir/shaders/autogen/tables/DenoiserReflectionResolve.h b/workdir/shaders/autogen/tables/DenoiserReflectionResolve.h index b73b69ad..94289243 100644 --- a/workdir/shaders/autogen/tables/DenoiserReflectionResolve.h +++ b/workdir/shaders/autogen/tables/DenoiserReflectionResolve.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserReflectionResolve diff --git a/workdir/shaders/autogen/tables/DenoiserShadow_Filter.h b/workdir/shaders/autogen/tables/DenoiserShadow_Filter.h index 900faacc..46c832ea 100644 --- a/workdir/shaders/autogen/tables/DenoiserShadow_Filter.h +++ b/workdir/shaders/autogen/tables/DenoiserShadow_Filter.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserShadow_Filter diff --git a/workdir/shaders/autogen/tables/DenoiserShadow_FilterLast.h b/workdir/shaders/autogen/tables/DenoiserShadow_FilterLast.h index 46337338..cf71c800 100644 --- a/workdir/shaders/autogen/tables/DenoiserShadow_FilterLast.h +++ b/workdir/shaders/autogen/tables/DenoiserShadow_FilterLast.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserShadow_FilterLast diff --git a/workdir/shaders/autogen/tables/DenoiserShadow_FilterLocal.h b/workdir/shaders/autogen/tables/DenoiserShadow_FilterLocal.h index f7639723..e24d6432 100644 --- a/workdir/shaders/autogen/tables/DenoiserShadow_FilterLocal.h +++ b/workdir/shaders/autogen/tables/DenoiserShadow_FilterLocal.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserShadow_FilterLocal diff --git a/workdir/shaders/autogen/tables/DenoiserShadow_Prepare.h b/workdir/shaders/autogen/tables/DenoiserShadow_Prepare.h index 0e188553..894e98ac 100644 --- a/workdir/shaders/autogen/tables/DenoiserShadow_Prepare.h +++ b/workdir/shaders/autogen/tables/DenoiserShadow_Prepare.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserShadow_Prepare diff --git a/workdir/shaders/autogen/tables/DenoiserShadow_TileClassification.h b/workdir/shaders/autogen/tables/DenoiserShadow_TileClassification.h index 60cf593e..4dd3bc20 100644 --- a/workdir/shaders/autogen/tables/DenoiserShadow_TileClassification.h +++ b/workdir/shaders/autogen/tables/DenoiserShadow_TileClassification.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DenoiserShadow_TileClassification diff --git a/workdir/shaders/autogen/tables/DepthOnly.h b/workdir/shaders/autogen/tables/DepthOnly.h index a04eedb3..6eef93f3 100644 --- a/workdir/shaders/autogen/tables/DepthOnly.h +++ b/workdir/shaders/autogen/tables/DepthOnly.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DepthOnly diff --git a/workdir/shaders/autogen/tables/DispatchArguments.h b/workdir/shaders/autogen/tables/DispatchArguments.h index bdeb24b2..87a9bd73 100644 --- a/workdir/shaders/autogen/tables/DispatchArguments.h +++ b/workdir/shaders/autogen/tables/DispatchArguments.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DispatchArguments diff --git a/workdir/shaders/autogen/tables/DispatchMeshArguments.h b/workdir/shaders/autogen/tables/DispatchMeshArguments.h index f1b3ec8e..2fe3c7ae 100644 --- a/workdir/shaders/autogen/tables/DispatchMeshArguments.h +++ b/workdir/shaders/autogen/tables/DispatchMeshArguments.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DispatchMeshArguments diff --git a/workdir/shaders/autogen/tables/DispatchParameters.h b/workdir/shaders/autogen/tables/DispatchParameters.h index 87e56dd3..b30e3dcf 100644 --- a/workdir/shaders/autogen/tables/DispatchParameters.h +++ b/workdir/shaders/autogen/tables/DispatchParameters.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DispatchParameters @@ -12,14 +11,14 @@ struct DispatchParameters float SurfaceThickness; // float float BilinearThreshold; // float float ShadowContrast; // float - bool IgnoreEdgePixels; // bool - bool UsePrecisionOffset; // bool - bool BilinearSamplingOffsetMode; // bool - bool DebugOutputEdgeMask; // bool - bool DebugOutputThreadIndex; // bool - bool DebugOutputWaveIndex; // bool + uint IgnoreEdgePixels; // uint + uint UsePrecisionOffset; // uint + uint BilinearSamplingOffsetMode; // uint + uint DebugOutputEdgeMask; // uint + uint DebugOutputThreadIndex; // uint + uint DebugOutputWaveIndex; // uint float2 DepthBounds; // float2 - bool UseEarlyOut; // bool + uint UseEarlyOut; // uint float4 LightCoordinate; // float4 int2 WaveOffset; // int2 float FarDepthValue; // float @@ -30,14 +29,14 @@ struct DispatchParameters float GetSurfaceThickness() { return SurfaceThickness; } float GetBilinearThreshold() { return BilinearThreshold; } float GetShadowContrast() { return ShadowContrast; } - bool GetIgnoreEdgePixels() { return IgnoreEdgePixels; } - bool GetUsePrecisionOffset() { return UsePrecisionOffset; } - bool GetBilinearSamplingOffsetMode() { return BilinearSamplingOffsetMode; } - bool GetDebugOutputEdgeMask() { return DebugOutputEdgeMask; } - bool GetDebugOutputThreadIndex() { return DebugOutputThreadIndex; } - bool GetDebugOutputWaveIndex() { return DebugOutputWaveIndex; } + uint GetIgnoreEdgePixels() { return IgnoreEdgePixels; } + uint GetUsePrecisionOffset() { return UsePrecisionOffset; } + uint GetBilinearSamplingOffsetMode() { return BilinearSamplingOffsetMode; } + uint GetDebugOutputEdgeMask() { return DebugOutputEdgeMask; } + uint GetDebugOutputThreadIndex() { return DebugOutputThreadIndex; } + uint GetDebugOutputWaveIndex() { return DebugOutputWaveIndex; } float2 GetDepthBounds() { return DepthBounds; } - bool GetUseEarlyOut() { return UseEarlyOut; } + uint GetUseEarlyOut() { return UseEarlyOut; } float4 GetLightCoordinate() { return LightCoordinate; } int2 GetWaveOffset() { return WaveOffset; } float GetFarDepthValue() { return FarDepthValue; } diff --git a/workdir/shaders/autogen/tables/DownsampleDepth.h b/workdir/shaders/autogen/tables/DownsampleDepth.h index 718c9c01..1027f06d 100644 --- a/workdir/shaders/autogen/tables/DownsampleDepth.h +++ b/workdir/shaders/autogen/tables/DownsampleDepth.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DownsampleDepth diff --git a/workdir/shaders/autogen/tables/DrawBoxes.h b/workdir/shaders/autogen/tables/DrawBoxes.h index 29ee87e0..b5fa2ce1 100644 --- a/workdir/shaders/autogen/tables/DrawBoxes.h +++ b/workdir/shaders/autogen/tables/DrawBoxes.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "BoxInfo.h" diff --git a/workdir/shaders/autogen/tables/DrawIndexedArguments.h b/workdir/shaders/autogen/tables/DrawIndexedArguments.h index f49501a1..e642e3c9 100644 --- a/workdir/shaders/autogen/tables/DrawIndexedArguments.h +++ b/workdir/shaders/autogen/tables/DrawIndexedArguments.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DrawIndexedArguments diff --git a/workdir/shaders/autogen/tables/DrawStencil.h b/workdir/shaders/autogen/tables/DrawStencil.h index 133605df..62bdeee2 100644 --- a/workdir/shaders/autogen/tables/DrawStencil.h +++ b/workdir/shaders/autogen/tables/DrawStencil.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct DrawStencil diff --git a/workdir/shaders/autogen/tables/EnvFilter.h b/workdir/shaders/autogen/tables/EnvFilter.h index 0993c8c5..e459b106 100644 --- a/workdir/shaders/autogen/tables/EnvFilter.h +++ b/workdir/shaders/autogen/tables/EnvFilter.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct EnvFilter diff --git a/workdir/shaders/autogen/tables/EnvSource.h b/workdir/shaders/autogen/tables/EnvSource.h index e48fecbc..5ff54934 100644 --- a/workdir/shaders/autogen/tables/EnvSource.h +++ b/workdir/shaders/autogen/tables/EnvSource.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct EnvSource diff --git a/workdir/shaders/autogen/tables/FSR.h b/workdir/shaders/autogen/tables/FSR.h index 1a1b2bcb..c023ef2b 100644 --- a/workdir/shaders/autogen/tables/FSR.h +++ b/workdir/shaders/autogen/tables/FSR.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "FSRConstants.h" diff --git a/workdir/shaders/autogen/tables/FSRConstants.h b/workdir/shaders/autogen/tables/FSRConstants.h index 8f796c2c..38f63fba 100644 --- a/workdir/shaders/autogen/tables/FSRConstants.h +++ b/workdir/shaders/autogen/tables/FSRConstants.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FSRConstants diff --git a/workdir/shaders/autogen/tables/FlowGraph.h b/workdir/shaders/autogen/tables/FlowGraph.h index b5a96825..9f7c36a2 100644 --- a/workdir/shaders/autogen/tables/FlowGraph.h +++ b/workdir/shaders/autogen/tables/FlowGraph.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FlowGraph diff --git a/workdir/shaders/autogen/tables/FontRendering.h b/workdir/shaders/autogen/tables/FontRendering.h index 2fceb4c1..2bf76573 100644 --- a/workdir/shaders/autogen/tables/FontRendering.h +++ b/workdir/shaders/autogen/tables/FontRendering.h @@ -4,13 +4,12 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FontRendering { uint tex0; // Texture2D - uint positions; // Buffer + uint positions; // StructuredBuffer Texture2D GetTex0() { return ResourceDescriptorHeap[tex0]; } - Buffer GetPositions() { return ResourceDescriptorHeap[positions]; } + StructuredBuffer GetPositions() { return ResourceDescriptorHeap[positions]; } }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/FontRenderingConstants.h b/workdir/shaders/autogen/tables/FontRenderingConstants.h index 044ada76..cfb08ca5 100644 --- a/workdir/shaders/autogen/tables/FontRenderingConstants.h +++ b/workdir/shaders/autogen/tables/FontRenderingConstants.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FontRenderingConstants diff --git a/workdir/shaders/autogen/tables/FontRenderingGlyphs.h b/workdir/shaders/autogen/tables/FontRenderingGlyphs.h index 71db366a..ecc2ca36 100644 --- a/workdir/shaders/autogen/tables/FontRenderingGlyphs.h +++ b/workdir/shaders/autogen/tables/FontRenderingGlyphs.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "Glyph.h" diff --git a/workdir/shaders/autogen/tables/FrameClassification.h b/workdir/shaders/autogen/tables/FrameClassification.h index f3f9462d..595cef67 100644 --- a/workdir/shaders/autogen/tables/FrameClassification.h +++ b/workdir/shaders/autogen/tables/FrameClassification.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FrameClassification diff --git a/workdir/shaders/autogen/tables/FrameClassificationInitDispatch.h b/workdir/shaders/autogen/tables/FrameClassificationInitDispatch.h index 6b2c3c27..32bd836c 100644 --- a/workdir/shaders/autogen/tables/FrameClassificationInitDispatch.h +++ b/workdir/shaders/autogen/tables/FrameClassificationInitDispatch.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "DispatchArguments.h" diff --git a/workdir/shaders/autogen/tables/FrameGraph_Debug_Common.h b/workdir/shaders/autogen/tables/FrameGraph_Debug_Common.h index 6a71fab1..16b96efb 100644 --- a/workdir/shaders/autogen/tables/FrameGraph_Debug_Common.h +++ b/workdir/shaders/autogen/tables/FrameGraph_Debug_Common.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FrameGraph_Debug_Common diff --git a/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2D.h b/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2D.h index 926b1744..50d02f84 100644 --- a/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2D.h +++ b/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2D.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FrameGraph_Debug_Texture2D diff --git a/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2DArray.h b/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2DArray.h index 59664152..119e6fa6 100644 --- a/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2DArray.h +++ b/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture2DArray.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FrameGraph_Debug_Texture2DArray diff --git a/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture3D.h b/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture3D.h index d7e3664c..08a9eb2e 100644 --- a/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture3D.h +++ b/workdir/shaders/autogen/tables/FrameGraph_Debug_Texture3D.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "Camera.h" diff --git a/workdir/shaders/autogen/tables/FrameGraph_Debug_TextureCube.h b/workdir/shaders/autogen/tables/FrameGraph_Debug_TextureCube.h index afa05022..44eaaf9d 100644 --- a/workdir/shaders/autogen/tables/FrameGraph_Debug_TextureCube.h +++ b/workdir/shaders/autogen/tables/FrameGraph_Debug_TextureCube.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct FrameGraph_Debug_TextureCube diff --git a/workdir/shaders/autogen/tables/FrameInfo.h b/workdir/shaders/autogen/tables/FrameInfo.h index f5ea45f3..59cd6e3b 100644 --- a/workdir/shaders/autogen/tables/FrameInfo.h +++ b/workdir/shaders/autogen/tables/FrameInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "Camera.h" diff --git a/workdir/shaders/autogen/tables/Frustum.h b/workdir/shaders/autogen/tables/Frustum.h index d5b12b70..f6839c8b 100644 --- a/workdir/shaders/autogen/tables/Frustum.h +++ b/workdir/shaders/autogen/tables/Frustum.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct Frustum diff --git a/workdir/shaders/autogen/tables/GBuffer.h b/workdir/shaders/autogen/tables/GBuffer.h index e7b25e50..3a7c41fa 100644 --- a/workdir/shaders/autogen/tables/GBuffer.h +++ b/workdir/shaders/autogen/tables/GBuffer.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct GBuffer diff --git a/workdir/shaders/autogen/tables/GBufferDownsample.h b/workdir/shaders/autogen/tables/GBufferDownsample.h index e5a6c770..5ed69f53 100644 --- a/workdir/shaders/autogen/tables/GBufferDownsample.h +++ b/workdir/shaders/autogen/tables/GBufferDownsample.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct GBufferDownsample diff --git a/workdir/shaders/autogen/tables/GBufferDownsampleRT.h b/workdir/shaders/autogen/tables/GBufferDownsampleRT.h index b60ccaf3..9fe57cd6 100644 --- a/workdir/shaders/autogen/tables/GBufferDownsampleRT.h +++ b/workdir/shaders/autogen/tables/GBufferDownsampleRT.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct GBufferDownsampleRT diff --git a/workdir/shaders/autogen/tables/GBufferQuality.h b/workdir/shaders/autogen/tables/GBufferQuality.h index a846ea4c..bea84826 100644 --- a/workdir/shaders/autogen/tables/GBufferQuality.h +++ b/workdir/shaders/autogen/tables/GBufferQuality.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct GBufferQuality diff --git a/workdir/shaders/autogen/tables/GPUAddress.h b/workdir/shaders/autogen/tables/GPUAddress.h index 5fe90362..74db47a0 100644 --- a/workdir/shaders/autogen/tables/GPUAddress.h +++ b/workdir/shaders/autogen/tables/GPUAddress.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct GPUAddress diff --git a/workdir/shaders/autogen/tables/GatherBoxes.h b/workdir/shaders/autogen/tables/GatherBoxes.h index b13cd6aa..aaea84d0 100644 --- a/workdir/shaders/autogen/tables/GatherBoxes.h +++ b/workdir/shaders/autogen/tables/GatherBoxes.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "BoxInfo.h" diff --git a/workdir/shaders/autogen/tables/GatherMeshesBoxes.h b/workdir/shaders/autogen/tables/GatherMeshesBoxes.h index e821d7d7..8e5be82f 100644 --- a/workdir/shaders/autogen/tables/GatherMeshesBoxes.h +++ b/workdir/shaders/autogen/tables/GatherMeshesBoxes.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "BoxInfo.h" diff --git a/workdir/shaders/autogen/tables/GatherPipeline.h b/workdir/shaders/autogen/tables/GatherPipeline.h index d845647f..ff6d5d4f 100644 --- a/workdir/shaders/autogen/tables/GatherPipeline.h +++ b/workdir/shaders/autogen/tables/GatherPipeline.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "CommandData.h" @@ -14,4 +13,5 @@ struct GatherPipeline uint commands[8]; // AppendStructuredBuffer uint4 GetPip_ids(int i) { return pip_ids[i]; } AppendStructuredBuffer GetCommands(int i) { return ResourceDescriptorHeap[commands[i]]; } + }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/GatherPipelineGlobal.h b/workdir/shaders/autogen/tables/GatherPipelineGlobal.h index 45c784bd..207f3678 100644 --- a/workdir/shaders/autogen/tables/GatherPipelineGlobal.h +++ b/workdir/shaders/autogen/tables/GatherPipelineGlobal.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct GatherPipelineGlobal diff --git a/workdir/shaders/autogen/tables/Glyph.h b/workdir/shaders/autogen/tables/Glyph.h index 88ec33cc..df38e0fe 100644 --- a/workdir/shaders/autogen/tables/Glyph.h +++ b/workdir/shaders/autogen/tables/Glyph.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct Glyph diff --git a/workdir/shaders/autogen/tables/GraphInput.h b/workdir/shaders/autogen/tables/GraphInput.h index 4c97eaf2..7cb43537 100644 --- a/workdir/shaders/autogen/tables/GraphInput.h +++ b/workdir/shaders/autogen/tables/GraphInput.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct GraphInput diff --git a/workdir/shaders/autogen/tables/InitDispatch.h b/workdir/shaders/autogen/tables/InitDispatch.h index 5a47f290..49cb5968 100644 --- a/workdir/shaders/autogen/tables/InitDispatch.h +++ b/workdir/shaders/autogen/tables/InitDispatch.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "DispatchArguments.h" diff --git a/workdir/shaders/autogen/tables/Instance.h b/workdir/shaders/autogen/tables/Instance.h index 4a9c58f7..682e3e0f 100644 --- a/workdir/shaders/autogen/tables/Instance.h +++ b/workdir/shaders/autogen/tables/Instance.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct Instance diff --git a/workdir/shaders/autogen/tables/LineRender.h b/workdir/shaders/autogen/tables/LineRender.h index 20a037d2..648115cb 100644 --- a/workdir/shaders/autogen/tables/LineRender.h +++ b/workdir/shaders/autogen/tables/LineRender.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "VSLine.h" diff --git a/workdir/shaders/autogen/tables/MaterialCommandData.h b/workdir/shaders/autogen/tables/MaterialCommandData.h index 25943b17..cd9e7674 100644 --- a/workdir/shaders/autogen/tables/MaterialCommandData.h +++ b/workdir/shaders/autogen/tables/MaterialCommandData.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct MaterialCommandData diff --git a/workdir/shaders/autogen/tables/MaterialInfo.h b/workdir/shaders/autogen/tables/MaterialInfo.h index 8431b15d..7d186c87 100644 --- a/workdir/shaders/autogen/tables/MaterialInfo.h +++ b/workdir/shaders/autogen/tables/MaterialInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct MaterialInfo @@ -13,18 +12,18 @@ struct MaterialInfo uint textures; // Texture2D uint texture_feedbacks; // FeedbackTexture2DMip MaterialCB GetData() { return data; } - FeedbackTexture2DMip GetTexture_feedbacks(int i) + FeedbackTexture2DMip GetTexture_feedbacks(int i) { - StructuredBuffer indirection = ResourceDescriptorHeap[texture_feedbacks]; + StructuredBuffer indirection = ResourceDescriptorHeap[texture_feedbacks]; uint id = indirection.Load(i); - return ResourceDescriptorHeap[id]; + return ResourceDescriptorHeap[id]; } - Texture2D GetTextures(int i) + Texture2D GetTextures(int i) { - StructuredBuffer indirection = ResourceDescriptorHeap[textures]; + StructuredBuffer indirection = ResourceDescriptorHeap[textures]; uint id = indirection.Load(i); - return ResourceDescriptorHeap[id]; + return ResourceDescriptorHeap[id]; } }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/MeshCommandData.h b/workdir/shaders/autogen/tables/MeshCommandData.h index 528f21d5..18886932 100644 --- a/workdir/shaders/autogen/tables/MeshCommandData.h +++ b/workdir/shaders/autogen/tables/MeshCommandData.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "DispatchMeshArguments.h" diff --git a/workdir/shaders/autogen/tables/MeshInfo.h b/workdir/shaders/autogen/tables/MeshInfo.h index 5b4cbeaa..65a27517 100644 --- a/workdir/shaders/autogen/tables/MeshInfo.h +++ b/workdir/shaders/autogen/tables/MeshInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct MeshInfo diff --git a/workdir/shaders/autogen/tables/MeshInstance.h b/workdir/shaders/autogen/tables/MeshInstance.h index 5b012fe8..8d409e05 100644 --- a/workdir/shaders/autogen/tables/MeshInstance.h +++ b/workdir/shaders/autogen/tables/MeshInstance.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct MeshInstance diff --git a/workdir/shaders/autogen/tables/MeshInstanceInfo.h b/workdir/shaders/autogen/tables/MeshInstanceInfo.h index b7705bc2..826b1907 100644 --- a/workdir/shaders/autogen/tables/MeshInstanceInfo.h +++ b/workdir/shaders/autogen/tables/MeshInstanceInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "Meshlet.h" diff --git a/workdir/shaders/autogen/tables/Meshlet.h b/workdir/shaders/autogen/tables/Meshlet.h index 828d7325..9c02b179 100644 --- a/workdir/shaders/autogen/tables/Meshlet.h +++ b/workdir/shaders/autogen/tables/Meshlet.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct Meshlet diff --git a/workdir/shaders/autogen/tables/MeshletCullData.h b/workdir/shaders/autogen/tables/MeshletCullData.h index 8abf083c..77164566 100644 --- a/workdir/shaders/autogen/tables/MeshletCullData.h +++ b/workdir/shaders/autogen/tables/MeshletCullData.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct MeshletCullData diff --git a/workdir/shaders/autogen/tables/MipMapping.h b/workdir/shaders/autogen/tables/MipMapping.h index 12204094..aa7558db 100644 --- a/workdir/shaders/autogen/tables/MipMapping.h +++ b/workdir/shaders/autogen/tables/MipMapping.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct MipMapping @@ -18,5 +17,6 @@ struct MipMapping uint GetNumMipLevels() { return NumMipLevels; } float2 GetTexelSize() { return TexelSize; } RWTexture2D GetOutMip(int i) { return ResourceDescriptorHeap[OutMip[i]]; } + Texture2D GetSrcMip() { return ResourceDescriptorHeap[SrcMip]; } }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/NinePatch.h b/workdir/shaders/autogen/tables/NinePatch.h index 5faa6f99..ef3c395a 100644 --- a/workdir/shaders/autogen/tables/NinePatch.h +++ b/workdir/shaders/autogen/tables/NinePatch.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "vertex_input.h" @@ -13,11 +12,11 @@ struct NinePatch uint vb; // StructuredBuffer uint textures; // Texture2D StructuredBuffer GetVb() { return ResourceDescriptorHeap[vb]; } - Texture2D GetTextures(int i) + Texture2D GetTextures(int i) { - StructuredBuffer indirection = ResourceDescriptorHeap[textures]; + StructuredBuffer indirection = ResourceDescriptorHeap[textures]; uint id = indirection.Load(i); - return ResourceDescriptorHeap[id]; + return ResourceDescriptorHeap[id]; } }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/NoOutput.h b/workdir/shaders/autogen/tables/NoOutput.h index 5d96d058..d4cfaa66 100644 --- a/workdir/shaders/autogen/tables/NoOutput.h +++ b/workdir/shaders/autogen/tables/NoOutput.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct NoOutput diff --git a/workdir/shaders/autogen/tables/PSSMConstants.h b/workdir/shaders/autogen/tables/PSSMConstants.h index 52065f92..7605a3b8 100644 --- a/workdir/shaders/autogen/tables/PSSMConstants.h +++ b/workdir/shaders/autogen/tables/PSSMConstants.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct PSSMConstants diff --git a/workdir/shaders/autogen/tables/PSSMData.h b/workdir/shaders/autogen/tables/PSSMData.h index 7eb8bc1b..3e32d3a5 100644 --- a/workdir/shaders/autogen/tables/PSSMData.h +++ b/workdir/shaders/autogen/tables/PSSMData.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "Camera.h" diff --git a/workdir/shaders/autogen/tables/PSSMDataGlobal.h b/workdir/shaders/autogen/tables/PSSMDataGlobal.h index abc6d97d..fe8bb542 100644 --- a/workdir/shaders/autogen/tables/PSSMDataGlobal.h +++ b/workdir/shaders/autogen/tables/PSSMDataGlobal.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "Camera.h" diff --git a/workdir/shaders/autogen/tables/PSSMLighting.h b/workdir/shaders/autogen/tables/PSSMLighting.h index 4e867e5f..a70b2ff9 100644 --- a/workdir/shaders/autogen/tables/PSSMLighting.h +++ b/workdir/shaders/autogen/tables/PSSMLighting.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "GBuffer.h" diff --git a/workdir/shaders/autogen/tables/PickerBuffer.h b/workdir/shaders/autogen/tables/PickerBuffer.h index 0049950b..49871bbb 100644 --- a/workdir/shaders/autogen/tables/PickerBuffer.h +++ b/workdir/shaders/autogen/tables/PickerBuffer.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct PickerBuffer diff --git a/workdir/shaders/autogen/tables/RayCone.h b/workdir/shaders/autogen/tables/RayCone.h index c68d780d..b5d85217 100644 --- a/workdir/shaders/autogen/tables/RayCone.h +++ b/workdir/shaders/autogen/tables/RayCone.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once diff --git a/workdir/shaders/autogen/tables/RayPayload.h b/workdir/shaders/autogen/tables/RayPayload.h index 13fa2c35..346949c3 100644 --- a/workdir/shaders/autogen/tables/RayPayload.h +++ b/workdir/shaders/autogen/tables/RayPayload.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "RayCone.h" diff --git a/workdir/shaders/autogen/tables/RaytraceInstanceInfo.h b/workdir/shaders/autogen/tables/RaytraceInstanceInfo.h index 24c90cfd..89bb2b4c 100644 --- a/workdir/shaders/autogen/tables/RaytraceInstanceInfo.h +++ b/workdir/shaders/autogen/tables/RaytraceInstanceInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "mesh_vertex_input.h" diff --git a/workdir/shaders/autogen/tables/Raytracing.h b/workdir/shaders/autogen/tables/Raytracing.h index 9fe7bac9..f30feac0 100644 --- a/workdir/shaders/autogen/tables/Raytracing.h +++ b/workdir/shaders/autogen/tables/Raytracing.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct Raytracing diff --git a/workdir/shaders/autogen/tables/RaytracingRays.h b/workdir/shaders/autogen/tables/RaytracingRays.h index dbabe815..798ca893 100644 --- a/workdir/shaders/autogen/tables/RaytracingRays.h +++ b/workdir/shaders/autogen/tables/RaytracingRays.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "GBuffer.h" diff --git a/workdir/shaders/autogen/tables/ReflectionCombine.h b/workdir/shaders/autogen/tables/ReflectionCombine.h index 7c1acfbe..2f04501e 100644 --- a/workdir/shaders/autogen/tables/ReflectionCombine.h +++ b/workdir/shaders/autogen/tables/ReflectionCombine.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "GBuffer.h" diff --git a/workdir/shaders/autogen/tables/SMAA_Blend.h b/workdir/shaders/autogen/tables/SMAA_Blend.h index bf246561..339381c8 100644 --- a/workdir/shaders/autogen/tables/SMAA_Blend.h +++ b/workdir/shaders/autogen/tables/SMAA_Blend.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct SMAA_Blend diff --git a/workdir/shaders/autogen/tables/SMAA_Global.h b/workdir/shaders/autogen/tables/SMAA_Global.h index f18ae994..731c07c3 100644 --- a/workdir/shaders/autogen/tables/SMAA_Global.h +++ b/workdir/shaders/autogen/tables/SMAA_Global.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct SMAA_Global diff --git a/workdir/shaders/autogen/tables/SMAA_Weights.h b/workdir/shaders/autogen/tables/SMAA_Weights.h index 16941ce6..c287d598 100644 --- a/workdir/shaders/autogen/tables/SMAA_Weights.h +++ b/workdir/shaders/autogen/tables/SMAA_Weights.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct SMAA_Weights diff --git a/workdir/shaders/autogen/tables/SceneData.h b/workdir/shaders/autogen/tables/SceneData.h index 77078f98..05d7f2ac 100644 --- a/workdir/shaders/autogen/tables/SceneData.h +++ b/workdir/shaders/autogen/tables/SceneData.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "MaterialCommandData.h" diff --git a/workdir/shaders/autogen/tables/ShadowPayload.h b/workdir/shaders/autogen/tables/ShadowPayload.h index 9863c808..450d1aee 100644 --- a/workdir/shaders/autogen/tables/ShadowPayload.h +++ b/workdir/shaders/autogen/tables/ShadowPayload.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once diff --git a/workdir/shaders/autogen/tables/SingleColor.h b/workdir/shaders/autogen/tables/SingleColor.h index 8720f70f..b4662548 100644 --- a/workdir/shaders/autogen/tables/SingleColor.h +++ b/workdir/shaders/autogen/tables/SingleColor.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct SingleColor diff --git a/workdir/shaders/autogen/tables/SingleColorDepth.h b/workdir/shaders/autogen/tables/SingleColorDepth.h index c2e2834a..c10a125c 100644 --- a/workdir/shaders/autogen/tables/SingleColorDepth.h +++ b/workdir/shaders/autogen/tables/SingleColorDepth.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct SingleColorDepth diff --git a/workdir/shaders/autogen/tables/SkyData.h b/workdir/shaders/autogen/tables/SkyData.h index 6936ecb5..c10174b2 100644 --- a/workdir/shaders/autogen/tables/SkyData.h +++ b/workdir/shaders/autogen/tables/SkyData.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct SkyData diff --git a/workdir/shaders/autogen/tables/SkyFace.h b/workdir/shaders/autogen/tables/SkyFace.h index f1fef2b4..eda1d3c4 100644 --- a/workdir/shaders/autogen/tables/SkyFace.h +++ b/workdir/shaders/autogen/tables/SkyFace.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct SkyFace diff --git a/workdir/shaders/autogen/tables/Test.h b/workdir/shaders/autogen/tables/Test.h index 66c80525..55a9ba81 100644 --- a/workdir/shaders/autogen/tables/Test.h +++ b/workdir/shaders/autogen/tables/Test.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "MeshInstanceInfo.h" @@ -14,18 +13,18 @@ struct Test uint instances; // StructuredBuffer uint tex; // Texture2D float GetData(int i) { return data[i]; } - StructuredBuffer GetInstances(int i) + StructuredBuffer GetInstances(int i) { - StructuredBuffer indirection = ResourceDescriptorHeap[instances]; + StructuredBuffer indirection = ResourceDescriptorHeap[instances]; uint id = indirection.Load(i); - return ResourceDescriptorHeap[id]; + return ResourceDescriptorHeap[id]; } - Texture2D GetTex(int i) + Texture2D GetTex(int i) { - StructuredBuffer indirection = ResourceDescriptorHeap[tex]; + StructuredBuffer indirection = ResourceDescriptorHeap[tex]; uint id = indirection.Load(i); - return ResourceDescriptorHeap[id]; + return ResourceDescriptorHeap[id]; } }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/TextureRenderer.h b/workdir/shaders/autogen/tables/TextureRenderer.h index c63414c1..78768ec6 100644 --- a/workdir/shaders/autogen/tables/TextureRenderer.h +++ b/workdir/shaders/autogen/tables/TextureRenderer.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct TextureRenderer diff --git a/workdir/shaders/autogen/tables/TilingParams.h b/workdir/shaders/autogen/tables/TilingParams.h index 789af0a2..e568229b 100644 --- a/workdir/shaders/autogen/tables/TilingParams.h +++ b/workdir/shaders/autogen/tables/TilingParams.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct TilingParams diff --git a/workdir/shaders/autogen/tables/TilingPostprocess.h b/workdir/shaders/autogen/tables/TilingPostprocess.h index 89957b60..e36da777 100644 --- a/workdir/shaders/autogen/tables/TilingPostprocess.h +++ b/workdir/shaders/autogen/tables/TilingPostprocess.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "TilingParams.h" diff --git a/workdir/shaders/autogen/tables/Triangle.h b/workdir/shaders/autogen/tables/Triangle.h index 2d337aeb..360c8d3c 100644 --- a/workdir/shaders/autogen/tables/Triangle.h +++ b/workdir/shaders/autogen/tables/Triangle.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "mesh_vertex_input.h" diff --git a/workdir/shaders/autogen/tables/VSLine.h b/workdir/shaders/autogen/tables/VSLine.h index fd870e91..33580bbb 100644 --- a/workdir/shaders/autogen/tables/VSLine.h +++ b/workdir/shaders/autogen/tables/VSLine.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct VSLine diff --git a/workdir/shaders/autogen/tables/VoxelBlur.h b/workdir/shaders/autogen/tables/VoxelBlur.h index b6234346..4099c3e0 100644 --- a/workdir/shaders/autogen/tables/VoxelBlur.h +++ b/workdir/shaders/autogen/tables/VoxelBlur.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct VoxelBlur diff --git a/workdir/shaders/autogen/tables/VoxelCopy.h b/workdir/shaders/autogen/tables/VoxelCopy.h index c1be748e..e533c066 100644 --- a/workdir/shaders/autogen/tables/VoxelCopy.h +++ b/workdir/shaders/autogen/tables/VoxelCopy.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "VoxelTilingParams.h" @@ -15,5 +14,7 @@ struct VoxelCopy VoxelTilingParams params; // VoxelTilingParams VoxelTilingParams GetParams() { return params; } RWTexture3D GetTarget(int i) { return ResourceDescriptorHeap[Target[i]]; } + Texture3D GetSource(int i) { return ResourceDescriptorHeap[Source[i]]; } + }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/VoxelDebug.h b/workdir/shaders/autogen/tables/VoxelDebug.h index 826ddf54..985bc896 100644 --- a/workdir/shaders/autogen/tables/VoxelDebug.h +++ b/workdir/shaders/autogen/tables/VoxelDebug.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "GBuffer.h" diff --git a/workdir/shaders/autogen/tables/VoxelInfo.h b/workdir/shaders/autogen/tables/VoxelInfo.h index 64102638..13deb8c7 100644 --- a/workdir/shaders/autogen/tables/VoxelInfo.h +++ b/workdir/shaders/autogen/tables/VoxelInfo.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct VoxelInfo diff --git a/workdir/shaders/autogen/tables/VoxelLighting.h b/workdir/shaders/autogen/tables/VoxelLighting.h index 1914c880..058b5003 100644 --- a/workdir/shaders/autogen/tables/VoxelLighting.h +++ b/workdir/shaders/autogen/tables/VoxelLighting.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "PSSMDataGlobal.h" diff --git a/workdir/shaders/autogen/tables/VoxelMipMap.h b/workdir/shaders/autogen/tables/VoxelMipMap.h index 8238e3ab..70998ae7 100644 --- a/workdir/shaders/autogen/tables/VoxelMipMap.h +++ b/workdir/shaders/autogen/tables/VoxelMipMap.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "VoxelTilingParams.h" @@ -15,5 +14,6 @@ struct VoxelMipMap VoxelTilingParams params; // VoxelTilingParams VoxelTilingParams GetParams() { return params; } RWTexture3D GetOutMips(int i) { return ResourceDescriptorHeap[OutMips[i]]; } + Texture3D GetSrcMip() { return ResourceDescriptorHeap[SrcMip]; } }; \ No newline at end of file diff --git a/workdir/shaders/autogen/tables/VoxelOutput.h b/workdir/shaders/autogen/tables/VoxelOutput.h index b089e897..fbd5df74 100644 --- a/workdir/shaders/autogen/tables/VoxelOutput.h +++ b/workdir/shaders/autogen/tables/VoxelOutput.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct VoxelOutput diff --git a/workdir/shaders/autogen/tables/VoxelScreen.h b/workdir/shaders/autogen/tables/VoxelScreen.h index 0e6e1147..1285ffc8 100644 --- a/workdir/shaders/autogen/tables/VoxelScreen.h +++ b/workdir/shaders/autogen/tables/VoxelScreen.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "GBuffer.h" diff --git a/workdir/shaders/autogen/tables/VoxelTilingParams.h b/workdir/shaders/autogen/tables/VoxelTilingParams.h index 0ad66412..ae4dc1b1 100644 --- a/workdir/shaders/autogen/tables/VoxelTilingParams.h +++ b/workdir/shaders/autogen/tables/VoxelTilingParams.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct VoxelTilingParams diff --git a/workdir/shaders/autogen/tables/VoxelUpscale.h b/workdir/shaders/autogen/tables/VoxelUpscale.h index 7b3fb1d6..be23ee2a 100644 --- a/workdir/shaders/autogen/tables/VoxelUpscale.h +++ b/workdir/shaders/autogen/tables/VoxelUpscale.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct VoxelUpscale diff --git a/workdir/shaders/autogen/tables/VoxelVisibility.h b/workdir/shaders/autogen/tables/VoxelVisibility.h index 6dbeb78a..38629ce8 100644 --- a/workdir/shaders/autogen/tables/VoxelVisibility.h +++ b/workdir/shaders/autogen/tables/VoxelVisibility.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct VoxelVisibility diff --git a/workdir/shaders/autogen/tables/VoxelZero.h b/workdir/shaders/autogen/tables/VoxelZero.h index 6ebb878b..608b4623 100644 --- a/workdir/shaders/autogen/tables/VoxelZero.h +++ b/workdir/shaders/autogen/tables/VoxelZero.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "VoxelTilingParams.h" diff --git a/workdir/shaders/autogen/tables/Voxelization.h b/workdir/shaders/autogen/tables/Voxelization.h index 1054fe74..23a279e9 100644 --- a/workdir/shaders/autogen/tables/Voxelization.h +++ b/workdir/shaders/autogen/tables/Voxelization.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "VoxelInfo.h" diff --git a/workdir/shaders/autogen/tables/WorkGraphTest.h b/workdir/shaders/autogen/tables/WorkGraphTest.h index 0f1a2b8d..ed58a34b 100644 --- a/workdir/shaders/autogen/tables/WorkGraphTest.h +++ b/workdir/shaders/autogen/tables/WorkGraphTest.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "GBuffer.h" diff --git a/workdir/shaders/autogen/tables/mesh_vertex_input.h b/workdir/shaders/autogen/tables/mesh_vertex_input.h index 00dd5b56..e1c81a73 100644 --- a/workdir/shaders/autogen/tables/mesh_vertex_input.h +++ b/workdir/shaders/autogen/tables/mesh_vertex_input.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once diff --git a/workdir/shaders/autogen/tables/node_data.h b/workdir/shaders/autogen/tables/node_data.h index 70b2d8eb..832a5313 100644 --- a/workdir/shaders/autogen/tables/node_data.h +++ b/workdir/shaders/autogen/tables/node_data.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" #include "AABB.h" diff --git a/workdir/shaders/autogen/tables/vertex_input.h b/workdir/shaders/autogen/tables/vertex_input.h index 35a74e3b..ad377eb9 100644 --- a/workdir/shaders/autogen/tables/vertex_input.h +++ b/workdir/shaders/autogen/tables/vertex_input.h @@ -4,7 +4,6 @@ // Generated by SigParser from .sig files in sources/SIGParser/sigs/ // Changes will be lost on next generation. Edit the .sig source files instead. // ============================================================================ - #pragma once #include "sig_hlsl.hlsl" struct vertex_input diff --git a/workdir/shaders/font/gsSimple.hlsl b/workdir/shaders/font/gsSimple.hlsl index 728f6e44..16c3bb02 100644 --- a/workdir/shaders/font/gsSimple.hlsl +++ b/workdir/shaders/font/gsSimple.hlsl @@ -2,7 +2,7 @@ #include "../autogen/FontRenderingConstants.h" -static const Buffer positions = GetFontRendering().GetPositions(); +static const StructuredBuffer positions = GetFontRendering().GetPositions(); static const float4x4 TransformMatrix = GetFontRenderingConstants().GetTransformMatrix(); static const float4 ClipRect = GetFontRenderingConstants().GetClipRect(); @@ -26,6 +26,7 @@ void GS(point GSIn Input[1], inout TriangleStream TriStream) const uint glyphIndex = uint(Input[0].Position.z); float4 texCoords = positions.Load(glyphIndex * 2); float4 offsets = positions.Load(glyphIndex * 2 + 1); + GSOut Output; Output.GlyphColor = Input[0].GlyphColor; float4 positions = basePosition.xyxy + offsets; diff --git a/workdir/shaders/gui/ninepatch.hlsl b/workdir/shaders/gui/ninepatch.hlsl index 0ee1be27..2f7da10c 100644 --- a/workdir/shaders/gui/ninepatch.hlsl +++ b/workdir/shaders/gui/ninepatch.hlsl @@ -31,10 +31,8 @@ quad_output VS(uint index : SV_VERTEXID, uint instance : SV_INSTANCEID) #ifdef BUILD_FUNC_PS float4 PS(quad_output i) : SV_TARGET0 { - float4 col = GetNinePatch().GetTextures(i.texture_offset).Sample(anisoBordeSampler , i.tc); //col.xyz/=col.w; return i.addColor + i.mulColor *col; } #endif - diff --git a/workdir/shaders/gui/rect.hlsl b/workdir/shaders/gui/rect.hlsl index 81831156..487e42aa 100644 --- a/workdir/shaders/gui/rect.hlsl +++ b/workdir/shaders/gui/rect.hlsl @@ -4,7 +4,8 @@ struct quad_output float4 pos : SV_POSITION; }; #include "../autogen/ColorRect.h" -static const float2 pos[4] = (float2[4])GetColorRect().pos; +static const ColorRect _cr = GetColorRect(); +static const float2 pos[4] = { _cr.pos[0].xy, _cr.pos[0].zw, _cr.pos[1].xy, _cr.pos[1].zw }; #ifdef BUILD_FUNC_VS quad_output VS(uint index : SV_VERTEXID) diff --git a/workdir/shaders/voxel_screen.hlsl b/workdir/shaders/voxel_screen.hlsl index 5dcaa407..ae726449 100644 --- a/workdir/shaders/voxel_screen.hlsl +++ b/workdir/shaders/voxel_screen.hlsl @@ -220,16 +220,13 @@ GI_RESULT PS(quad_output i) for (int y = -R; y <= R; y++) { float2 t_tc = i.tc + float2(x, y) / dims; - - - int2 offset = float2(x, y); - - float t_raw_z = gbuffer.GetDepth().SampleLevel(pointClampSampler, i.tc, 1, offset); + float2 t_tc_mip1 = i.tc + float2(x, y) * 2.0 / dims; + float t_raw_z = gbuffer.GetDepth().SampleLevel(pointClampSampler, t_tc_mip1, 1); float3 t_pos = depth_to_wpos(t_raw_z, t_tc, camera.GetInvViewProj()); - float3 t_normal = normalize(gbuffer.GetNormals().SampleLevel(pointClampSampler, i.tc, 1, offset).xyz * 2 - 1); + float3 t_normal = normalize(gbuffer.GetNormals().SampleLevel(pointClampSampler, t_tc_mip1, 1).xyz * 2 - 1); - float4 t_gi = tex_downsampled.SampleLevel(pointClampSampler, i.tc, 0, offset); + float4 t_gi = tex_downsampled.SampleLevel(pointClampSampler, t_tc, 0); float cur_w = saturate(1 - length(t_pos - pos));// 1.0 / (8 * length(t_pos - pos) + 0.1); @@ -549,4 +546,4 @@ GI_RESULT PS_Resize(quad_output i) : SV_Target0 } -#endif \ No newline at end of file +#endif diff --git a/workdir/test_references/cull_back.png b/workdir/test_references/cull_back.png new file mode 100644 index 00000000..00247213 Binary files /dev/null and b/workdir/test_references/cull_back.png differ diff --git a/workdir/test_references/cull_front.png b/workdir/test_references/cull_front.png new file mode 100644 index 00000000..f3160e2e Binary files /dev/null and b/workdir/test_references/cull_front.png differ diff --git a/workdir/test_references/cull_none.png b/workdir/test_references/cull_none.png new file mode 100644 index 00000000..46e512cd Binary files /dev/null and b/workdir/test_references/cull_none.png differ diff --git a/workdir/test_references/fg_uipipeline.png b/workdir/test_references/fg_uipipeline.png new file mode 100644 index 00000000..58fd58ef Binary files /dev/null and b/workdir/test_references/fg_uipipeline.png differ diff --git a/workdir/test_references/font_atlas.png b/workdir/test_references/font_atlas.png new file mode 100644 index 00000000..8fa0950f Binary files /dev/null and b/workdir/test_references/font_atlas.png differ diff --git a/workdir/test_references/font_direct_draw.png b/workdir/test_references/font_direct_draw.png new file mode 100644 index 00000000..f7ffff45 Binary files /dev/null and b/workdir/test_references/font_direct_draw.png differ diff --git a/workdir/test_references/geometry_shader.png b/workdir/test_references/geometry_shader.png new file mode 100644 index 00000000..6c95cddd Binary files /dev/null and b/workdir/test_references/geometry_shader.png differ diff --git a/workdir/test_references/gui_element_colored_rect.png b/workdir/test_references/gui_element_colored_rect.png new file mode 100644 index 00000000..aebd1a83 Binary files /dev/null and b/workdir/test_references/gui_element_colored_rect.png differ diff --git a/workdir/test_references/gui_element_label.png b/workdir/test_references/gui_element_label.png new file mode 100644 index 00000000..ff0efe24 Binary files /dev/null and b/workdir/test_references/gui_element_label.png differ diff --git a/workdir/test_references/gui_element_three_bands.png b/workdir/test_references/gui_element_three_bands.png new file mode 100644 index 00000000..4cec2686 Binary files /dev/null and b/workdir/test_references/gui_element_three_bands.png differ diff --git a/workdir/test_references/gui_full_screen.png b/workdir/test_references/gui_full_screen.png new file mode 100644 index 00000000..3d7c3767 Binary files /dev/null and b/workdir/test_references/gui_full_screen.png differ diff --git a/workdir/test_references/gui_nine_patch_clip_bottom.png b/workdir/test_references/gui_nine_patch_clip_bottom.png new file mode 100644 index 00000000..fe337e25 Binary files /dev/null and b/workdir/test_references/gui_nine_patch_clip_bottom.png differ diff --git a/workdir/test_references/gui_nine_patch_clip_center.png b/workdir/test_references/gui_nine_patch_clip_center.png new file mode 100644 index 00000000..16b43d1b Binary files /dev/null and b/workdir/test_references/gui_nine_patch_clip_center.png differ diff --git a/workdir/test_references/gui_nine_patch_clip_left.png b/workdir/test_references/gui_nine_patch_clip_left.png new file mode 100644 index 00000000..e349088a Binary files /dev/null and b/workdir/test_references/gui_nine_patch_clip_left.png differ diff --git a/workdir/test_references/gui_nine_patch_clip_right.png b/workdir/test_references/gui_nine_patch_clip_right.png new file mode 100644 index 00000000..fc18a978 Binary files /dev/null and b/workdir/test_references/gui_nine_patch_clip_right.png differ diff --git a/workdir/test_references/gui_nine_patch_clip_top.png b/workdir/test_references/gui_nine_patch_clip_top.png new file mode 100644 index 00000000..c962c130 Binary files /dev/null and b/workdir/test_references/gui_nine_patch_clip_top.png differ diff --git a/workdir/test_references/gui_nine_patch_stretch.png b/workdir/test_references/gui_nine_patch_stretch.png new file mode 100644 index 00000000..2266c3ae Binary files /dev/null and b/workdir/test_references/gui_nine_patch_stretch.png differ diff --git a/workdir/test_references/gui_renderer_draw_color.png b/workdir/test_references/gui_renderer_draw_color.png new file mode 100644 index 00000000..b03f7a28 Binary files /dev/null and b/workdir/test_references/gui_renderer_draw_color.png differ diff --git a/workdir/test_references/icon.png b/workdir/test_references/icon.png index 9755ccd7..b94e324c 100644 Binary files a/workdir/test_references/icon.png and b/workdir/test_references/icon.png differ diff --git a/workdir/test_references/instancing.png b/workdir/test_references/instancing.png index 9a77cb9c..7edb4aba 100644 Binary files a/workdir/test_references/instancing.png and b/workdir/test_references/instancing.png differ diff --git a/workdir/test_references/rainbow.png b/workdir/test_references/rainbow.png index e0b285df..59443d94 100644 Binary files a/workdir/test_references/rainbow.png and b/workdir/test_references/rainbow.png differ diff --git a/workdir/test_references/rainbow_vertical.png b/workdir/test_references/rainbow_vertical.png index 21bfa63c..6c16da6c 100644 Binary files a/workdir/test_references/rainbow_vertical.png and b/workdir/test_references/rainbow_vertical.png differ diff --git a/workdir/test_references/sig_color.png b/workdir/test_references/sig_color.png new file mode 100644 index 00000000..4f706d26 Binary files /dev/null and b/workdir/test_references/sig_color.png differ diff --git a/workdir/test_references/sig_copy_texture.png b/workdir/test_references/sig_copy_texture.png new file mode 100644 index 00000000..c20535c7 Binary files /dev/null and b/workdir/test_references/sig_copy_texture.png differ diff --git a/workdir/test_references/triangle.png b/workdir/test_references/triangle.png index 6c12b1ae..bd80ae76 100644 Binary files a/workdir/test_references/triangle.png and b/workdir/test_references/triangle.png differ diff --git a/workdir/test_references/ui_rect_alpha_blend.png b/workdir/test_references/ui_rect_alpha_blend.png new file mode 100644 index 00000000..923fd384 Binary files /dev/null and b/workdir/test_references/ui_rect_alpha_blend.png differ diff --git a/workdir/test_references/ui_rect_layout.png b/workdir/test_references/ui_rect_layout.png new file mode 100644 index 00000000..61698291 Binary files /dev/null and b/workdir/test_references/ui_rect_layout.png differ diff --git a/workdir/test_references/ui_rect_solid.png b/workdir/test_references/ui_rect_solid.png new file mode 100644 index 00000000..15f025fb Binary files /dev/null and b/workdir/test_references/ui_rect_solid.png differ diff --git a/workdir/test_results/icon_actual.png b/workdir/test_results/icon_actual.png deleted file mode 100644 index b94e324c..00000000 Binary files a/workdir/test_results/icon_actual.png and /dev/null differ diff --git a/workdir/test_results/icon_diff.png b/workdir/test_results/icon_diff.png deleted file mode 100644 index 259ec294..00000000 Binary files a/workdir/test_results/icon_diff.png and /dev/null differ