summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/visual-studio/generate-capabilities/generate-capabilities.vcxproj164
-rw-r--r--build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj1
-rw-r--r--build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters3
-rw-r--r--build/visual-studio/platform-test/platform-test.vcxproj305
-rw-r--r--build/visual-studio/platform-test/platform-test.vcxproj.filters13
-rw-r--r--build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj296
-rw-r--r--build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj.filters21
-rw-r--r--slang.h8
-rw-r--r--source/compiler-core/slang-source-loc.cpp12
-rw-r--r--source/compiler-core/slang-source-loc.h5
-rw-r--r--source/core/slang-io.cpp12
-rw-r--r--source/core/slang-io.h3
-rwxr-xr-xsource/slang/slang-compiler.h12
-rw-r--r--source/slang/slang-serialize-container.cpp402
-rw-r--r--source/slang/slang-serialize-container.h3
-rw-r--r--source/slang/slang-serialize-types.h3
-rw-r--r--source/slang/slang.cpp101
-rw-r--r--tools/gfx-unit-test/precompiled-module-cache.cpp238
18 files changed, 1430 insertions, 172 deletions
diff --git a/build/visual-studio/generate-capabilities/generate-capabilities.vcxproj b/build/visual-studio/generate-capabilities/generate-capabilities.vcxproj
new file mode 100644
index 000000000..021eff9c9
--- /dev/null
+++ b/build/visual-studio/generate-capabilities/generate-capabilities.vcxproj
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|Win32">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|x64">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|ARM64">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|Win32">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|x64">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|ARM64">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C765C62E-33D2-8129-FCC5-198768F1A391}</ProjectGuid>
+ <IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>generate-capabilities</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Utility</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Utility</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'" Label="Configuration">
+ <ConfigurationType>Utility</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Utility</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Utility</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'" Label="Configuration">
+ <ConfigurationType>Utility</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>..\..\..\bin\windows-x86\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x86\debug\generate-capabilities\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>..\..\..\bin\windows-x64\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x64\debug\generate-capabilities\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <OutDir>..\..\..\bin\windows-aarch64\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-aarch64\debug\generate-capabilities\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>..\..\..\bin\windows-x86\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x86\release\generate-capabilities\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>..\..\..\bin\windows-x64\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x64\release\generate-capabilities\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <OutDir>..\..\..\bin\windows-aarch64\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-aarch64\release\generate-capabilities\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\source\slang\slang-capabilities.capdef">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"../../../bin/windows-x86/debug/slang-capability-generator" "%(FullPath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"../../../bin/windows-x64/debug/slang-capability-generator" "%(FullPath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">"../../../bin/windows-aarch64/debug/slang-capability-generator" "%(FullPath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"../../../bin/windows-x86/release/slang-capability-generator" "%(FullPath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"../../../bin/windows-x64/release/slang-capability-generator" "%(FullPath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">"../../../bin/windows-aarch64/release/slang-capability-generator" "%(FullPath)"</Command>
+ <Outputs>../../../source/slang/slang-generated-capability-defs.h</Outputs>
+ <Message>slang-capability-generator for source/slang/slang-capabilities.capdef</Message>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../../source/slang/slang-capabilities.capdef;../../../bin/windows-x86/debug/slang-capability-generator.exe</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../../source/slang/slang-capabilities.capdef;../../../bin/windows-x64/debug/slang-capability-generator.exe</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">../../../source/slang/slang-capabilities.capdef;../../../bin/windows-aarch64/debug/slang-capability-generator.exe</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../../source/slang/slang-capabilities.capdef;../../../bin/windows-x86/release/slang-capability-generator.exe</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../../source/slang/slang-capabilities.capdef;../../../bin/windows-x64/release/slang-capability-generator.exe</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">../../../source/slang/slang-capabilities.capdef;../../../bin/windows-aarch64/release/slang-capability-generator.exe</AdditionalInputs>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
index e70470ef6..2be387a2a 100644
--- a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
+++ b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
@@ -309,6 +309,7 @@
<ClCompile Include="..\..\..\tools\gfx-unit-test\mutable-shader-object.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\nested-parameter-block.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\precompiled-module-2.cpp" />
+ <ClCompile Include="..\..\..\tools\gfx-unit-test\precompiled-module-cache.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\precompiled-module.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\ray-tracing-tests.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\resolve-resource-tests.cpp" />
diff --git a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
index 9d2c70a92..162ea49b1 100644
--- a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
+++ b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
@@ -83,6 +83,9 @@
<ClCompile Include="..\..\..\tools\gfx-unit-test\precompiled-module-2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\tools\gfx-unit-test\precompiled-module-cache.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\tools\gfx-unit-test\precompiled-module.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/build/visual-studio/platform-test/platform-test.vcxproj b/build/visual-studio/platform-test/platform-test.vcxproj
new file mode 100644
index 000000000..7f9eb6013
--- /dev/null
+++ b/build/visual-studio/platform-test/platform-test.vcxproj
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|Win32">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|x64">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|ARM64">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|Win32">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|x64">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|ARM64">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F385D6A7-DF6C-989F-88BD-FEBC74831106}</ProjectGuid>
+ <IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>platform-test</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x86\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x86\debug\platform-test\</IntDir>
+ <TargetName>platform-test</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x64\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x64\debug\platform-test\</IntDir>
+ <TargetName>platform-test</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-aarch64\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-aarch64\debug\platform-test\</IntDir>
+ <TargetName>platform-test</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x86\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x86\release\platform-test\</IntDir>
+ <TargetName>platform-test</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x64\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x64\release\platform-test\</IntDir>
+ <TargetName>platform-test</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-aarch64\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-aarch64\release\platform-test\</IntDir>
+ <TargetName>platform-test</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>_DEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>_DEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>_DEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>NDEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>NDEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>NDEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\examples\platform-test\main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\example-base\example-base.vcxproj">
+ <Project>{37BED5B5-23FA-D81F-8C0C-F1167867813A}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\slang\slang.vcxproj">
+ <Project>{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\gfx\gfx.vcxproj">
+ <Project>{222F7498-B40C-4F3F-A704-DDEB91A4484A}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\gfx-util\gfx-util.vcxproj">
+ <Project>{F5ADB74E-02A7-44FB-AA3B-FC02F8AC7A4B}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\platform\platform.vcxproj">
+ <Project>{3565FE5E-4FA3-11EB-AE93-0242AC130002}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\core\core.vcxproj">
+ <Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/build/visual-studio/platform-test/platform-test.vcxproj.filters b/build/visual-studio/platform-test/platform-test.vcxproj.filters
new file mode 100644
index 000000000..5fb5eb4dc
--- /dev/null
+++ b/build/visual-studio/platform-test/platform-test.vcxproj.filters
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\examples\platform-test\main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj b/build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj
new file mode 100644
index 000000000..1ab291e8d
--- /dev/null
+++ b/build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj
@@ -0,0 +1,296 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|Win32">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|x64">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug aarch64|ARM64">
+ <Configuration>Debug aarch64</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|Win32">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|x64">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release aarch64|ARM64">
+ <Configuration>Release aarch64</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FD16CA29-C66A-430A-822C-C09655088611}</ProjectGuid>
+ <IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>slang-capability-generator</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x86\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x86\debug\slang-capability-generator\</IntDir>
+ <TargetName>slang-capability-generator</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x64\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x64\debug\slang-capability-generator\</IntDir>
+ <TargetName>slang-capability-generator</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-aarch64\debug\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-aarch64\debug\slang-capability-generator\</IntDir>
+ <TargetName>slang-capability-generator</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x86\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x86\release\slang-capability-generator\</IntDir>
+ <TargetName>slang-capability-generator</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-x64\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-x64\release\slang-capability-generator\</IntDir>
+ <TargetName>slang-capability-generator</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>..\..\..\bin\windows-aarch64\release\</OutDir>
+ <IntDir>..\..\..\intermediate\windows-aarch64\release\slang-capability-generator\</IntDir>
+ <TargetName>slang-capability-generator</TargetName>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>_DEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>_DEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug aarch64|ARM64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>_DEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>NDEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>NDEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release aarch64|ARM64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>NDEBUG;WIN32_LEAN_AND_MEAN;VC_EXTRALEAN;NOMINMAX;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\tools\slang-capability-generator\slang-capability-diagnostic-defs.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\tools\slang-capability-generator\capability-generator-main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\compiler-core\compiler-core.vcxproj">
+ <Project>{12C1E89D-F5D0-41D3-8E8D-FB3F358F8126}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\core\core.vcxproj">
+ <Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj.filters b/build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj.filters
new file mode 100644
index 000000000..bc38eaf38
--- /dev/null
+++ b/build/visual-studio/slang-capability-generator/slang-capability-generator.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{21EB8090-0D4E-1035-B6D3-48EBA215DCB7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\tools\slang-capability-generator\slang-capability-diagnostic-defs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\tools\slang-capability-generator\capability-generator-main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/slang.h b/slang.h
index 8fad8fbc6..30aa8f2a8 100644
--- a/slang.h
+++ b/slang.h
@@ -947,6 +947,8 @@ extern "C"
DebugInformationFormat, // intValue0: DebugInfoFormat
VulkanBindShiftAll, // intValue0: kind; intValue1: shift
GenerateWholeProgram, // bool
+ UseUpToDateBinaryModule, // bool, when set, will only load
+ // precompiled modules if it is up-to-date with its source.
CountOf,
};
@@ -4633,6 +4635,12 @@ namespace slang
virtual SLANG_NO_THROW SlangInt SLANG_MCALL getLoadedModuleCount() = 0;
virtual SLANG_NO_THROW IModule* SLANG_MCALL getLoadedModule(SlangInt index) = 0;
+
+ /** Checks if a precompiled binary module is up-to-date with the current compiler
+ * option settings and the source file contents.
+ */
+ virtual SLANG_NO_THROW bool SLANG_MCALL isBinaryModuleUpToDate(
+ const char* modulePath, slang::IBlob* binaryModuleBlob) = 0;
};
#define SLANG_UUID_ISession ISession::getTypeGuid()
diff --git a/source/compiler-core/slang-source-loc.cpp b/source/compiler-core/slang-source-loc.cpp
index fe08f8dfc..872c40f0d 100644
--- a/source/compiler-core/slang-source-loc.cpp
+++ b/source/compiler-core/slang-source-loc.cpp
@@ -4,7 +4,6 @@
#include "../core/slang-string-util.h"
#include "../core/slang-string-escape-util.h"
#include "../core/slang-char-encode.h"
-
#include "slang-artifact-representation-impl.h"
#include "slang-artifact-impl.h"
#include "slang-artifact-util.h"
@@ -602,6 +601,17 @@ SourceFile::~SourceFile()
{
}
+SHA1::Digest SourceFile::getDigest()
+{
+ if (m_digest == SHA1::Digest())
+ {
+ DigestBuilder<SHA1> builder;
+ builder.append(getContent());
+ m_digest = builder.finalize();
+ }
+ return m_digest;
+}
+
String SourceFile::calcVerbosePath() const
{
ISlangFileSystemExt* fileSystemExt = getSourceManager()->getFileSystemExt();
diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h
index f432b2432..a5919d809 100644
--- a/source/compiler-core/slang-source-loc.h
+++ b/source/compiler-core/slang-source-loc.h
@@ -6,6 +6,7 @@
#include "../core/slang-memory-arena.h"
#include "../core/slang-string-slice-pool.h"
#include "../core/slang-castable.h"
+#include "../core/slang-crypto.h"
#include "slang-source-map.h"
@@ -277,6 +278,8 @@ public:
/// Dtor
~SourceFile();
+ SHA1::Digest getDigest();
+
protected:
SourceManager* m_sourceManager; ///< The source manager this belongs to
@@ -286,6 +289,8 @@ public:
UnownedStringSlice m_content; ///< The actual contents of the file.
size_t m_contentSize; ///< The size of the actual contents
+ SHA1::Digest m_digest;
+
// In order to speed up lookup of line number information,
// we will cache the starting offset of each line break in
// the input file:
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index c546dd059..c08f499b9 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -36,6 +36,7 @@
#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
+#include <filesystem>
namespace Slang
{
@@ -660,6 +661,17 @@ namespace Slang
#endif
}
+ String Path::getRelativePath(String base, String path)
+ {
+ std::filesystem::path p1(base.getBuffer());
+ std::filesystem::path p2(path.getBuffer());
+ std::error_code ec;
+ auto result = std::filesystem::relative(p2, p1, ec);
+ if (ec)
+ return path;
+ return String(UnownedStringSlice(result.generic_u8string().c_str()));
+ }
+
SlangResult Path::remove(const String& path)
{
#ifdef _WIN32
diff --git a/source/core/slang-io.h b/source/core/slang-io.h
index 125ac135c..fcacee1db 100644
--- a/source/core/slang-io.h
+++ b/source/core/slang-io.h
@@ -213,6 +213,9 @@ namespace Slang
static SlangResult remove(const String& path);
static bool equals(String path1, String path2);
+
+ /// Turn `path` into a relative path from base.
+ static String getRelativePath(String base, String path);
};
struct URI
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 7da003b8a..6c55a7807 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -256,6 +256,12 @@ namespace Slang
/// Add all of the paths that `module` depends on to the list
void addDependency(Module* module);
+ void clear()
+ {
+ m_fileList.clear();
+ m_fileSet.clear();
+ }
+
private:
// TODO: We are using a `HashSet` here to deduplicate
@@ -1400,6 +1406,7 @@ namespace Slang
/// Register a source file that this module depends on
void addFileDependency(SourceFile* sourceFile);
+ void clearFileDependency() { m_fileDependencyList.clear(); }
/// Set the AST for this module.
///
/// This should only be called once, during creation of the module.
@@ -1819,6 +1826,7 @@ namespace Slang
SlangCompileRequest** outCompileRequest) override;
virtual SLANG_NO_THROW SlangInt SLANG_MCALL getLoadedModuleCount() override;
virtual SLANG_NO_THROW slang::IModule* SLANG_MCALL getLoadedModule(SlangInt index) override;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isBinaryModuleUpToDate(const char* modulePath, slang::IBlob* binaryModuleBlob) override;
// Updates the supplied builder with linkage-related information, which includes preprocessor
// defines, the compiler version, and other compiler options. This is then merged with the hash
@@ -1952,6 +1960,8 @@ namespace Slang
DiagnosticSink* sink,
const LoadedModuleDictionary* additionalLoadedModules);
+ SourceFile* loadSourceFile(String pathFrom, String path);
+
void loadParsedModule(
RefPtr<FrontEndCompileRequest> compileRequest,
RefPtr<TranslationUnitRequest> translationUnit,
@@ -1961,6 +1971,8 @@ namespace Slang
/// Load a module of the given name.
Module* loadModule(String const& name);
+ bool isBinaryModuleUpToDate(String fromPath, RiffContainer* container);
+
RefPtr<Module> findOrImportModule(
Name* name,
SourceLoc const& loc,
diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp
index 39b67614d..c9db7ff5e 100644
--- a/source/slang/slang-serialize-container.cpp
+++ b/source/slang/slang-serialize-container.cpp
@@ -11,7 +11,7 @@
#include "slang-serialize-ir.h"
#include "slang-serialize-source-loc.h"
#include "slang-serialize-factory.h"
-
+#include "../core/slang-stream.h"
#include "slang-parser.h"
#include "slang-mangled-lexer.h"
@@ -80,7 +80,31 @@ namespace Slang {
dstModule.irModule = module->getIRModule();
SLANG_ASSERT(dstModule.irModule);
}
-
+ DigestBuilder<SHA1> digestBuilder;
+ module->getOptionSet().buildHash(digestBuilder);
+ auto fileDependencies = module->getFileDependencies();
+ String canonicalModulePath;
+ if (auto modulePath = module->getFilePath())
+ {
+ canonicalModulePath = Path::getParentDirectory(modulePath);
+ Path::getCanonical(canonicalModulePath, canonicalModulePath);
+ }
+ for (auto file : fileDependencies)
+ {
+ digestBuilder.append(file->getDigest());
+ if (file->getPathInfo().hasFoundPath())
+ {
+ String canonicalFilePath = file->getPathInfo().foundPath;
+ Path::getCanonical(file->getPathInfo().foundPath, canonicalFilePath);
+ canonicalFilePath = Path::getRelativePath(canonicalModulePath, canonicalFilePath);
+ dstModule.dependentFiles.add(canonicalFilePath);
+ }
+ else
+ {
+ dstModule.dependentFiles.add(file->getPathInfo().getMostUniqueIdentity());
+ }
+ }
+ dstModule.digest = digestBuilder.finalize();
outData.modules.add(dstModule);
}
@@ -189,6 +213,24 @@ namespace Slang {
// Okay, we need to serialize this module to our container file.
// We currently don't serialize it's name..., but support for that could be added.
+ // First, we write a header that can be used to verify if the precompiled module is up-to-date.
+ // The header has:
+ // 1) a digest of all compile options and dependent source files.
+ // 2) a list of source file paths.
+ //
+ {
+ RiffContainer::ScopeChunk scopeHeader(container, RiffContainer::Chunk::Kind::Data, SerialBinary::kModuleHeaderFourCc);
+ OwnedMemoryStream headerMemStream(FileAccess::Write);
+ StringBuilder filePathsSB;
+ for (auto fileDependency : module.dependentFiles)
+ filePathsSB << fileDependency << "\n";
+ headerMemStream.write(module.digest.data, sizeof(module.digest.data));
+ uint32_t fileListLength = (uint32_t)filePathsSB.getLength();
+ headerMemStream.write(&fileListLength, sizeof(uint32_t));
+ headerMemStream.write(filePathsSB.getBuffer(), fileListLength);
+ container->write(headerMemStream.getContents().getBuffer(), headerMemStream.getContents().getCount());
+ }
+
// Write the IR information
if ((options.optionFlags & SerialOptionFlag::IRModule) && module.irModule)
{
@@ -357,16 +399,53 @@ static List<ExtensionDecl*>& _getCandidateExtensionList(
RefPtr<ASTBuilder> astBuilder = options.astBuilder;
NodeBase* astRootNode = nullptr;
RefPtr<IRModule> irModule;
+ SerialContainerData::Module module;
+ bool hasHeader = false;
+ if (auto headerChunk = as<RiffContainer::DataChunk>(chunk, SerialBinary::kModuleHeaderFourCc))
+ {
+ hasHeader = true;
+ MemoryStreamBase memStream(
+ FileAccess::Read,
+ headerChunk->getSingleData()->getPayload(),
+ headerChunk->getSingleData()->getSize());
+ size_t readSize = 0;
+ memStream.read(module.digest.data, sizeof(SHA1::Digest), readSize);
+ if (readSize != sizeof(SHA1::Digest))
+ return SLANG_FAIL;
+ uint32_t fileListLength = 0;
+ memStream.read(&fileListLength, sizeof(uint32_t), readSize);
+ if (readSize != sizeof(uint32_t))
+ return SLANG_FAIL;
+ List<uint8_t> fileListContent;
+ fileListContent.setCount(fileListLength);
+ memStream.read(fileListContent.getBuffer(), fileListContent.getCount(), readSize);
+ if (readSize != (size_t)fileListContent.getCount())
+ return SLANG_FAIL;
+ UnownedStringSlice fileListString((const char*)fileListContent.getBuffer(), fileListContent.getCount());
+ List<UnownedStringSlice> fileList;
+ StringUtil::split(fileListString, '\n', fileList);
+ for (auto file : fileList)
+ {
+ if (file.getLength())
+ {
+ module.dependentFiles.add(file);
+ }
+ }
+ // Onto next chunk
+ chunk = chunk->m_next;
+ }
if (auto irChunk = as<RiffContainer::ListChunk>(chunk, IRSerialBinary::kIRModuleFourCc))
{
- IRSerialData serialData;
-
- SLANG_RETURN_ON_FAIL(IRSerialReader::readContainer(irChunk, containerCompressionType, &serialData));
+ if (!options.readHeaderOnly)
+ {
+ IRSerialData serialData;
+ SLANG_RETURN_ON_FAIL(IRSerialReader::readContainer(irChunk, containerCompressionType, &serialData));
- // Read IR back from serialData
- IRSerialReader reader;
- SLANG_RETURN_ON_FAIL(reader.read(serialData, options.session, sourceLocReader, irModule));
+ // Read IR back from serialData
+ IRSerialReader reader;
+ SLANG_RETURN_ON_FAIL(reader.read(serialData, options.session, sourceLocReader, irModule));
+ }
// Onto next chunk
chunk = chunk->m_next;
@@ -374,207 +453,210 @@ static List<ExtensionDecl*>& _getCandidateExtensionList(
if (auto astChunk = as<RiffContainer::ListChunk>(chunk, ASTSerialBinary::kSlangASTModuleFourCC))
{
- RiffContainer::Data* astData = astChunk->findContainedData(ASTSerialBinary::kSlangASTModuleDataFourCC);
-
- if (astData)
+ if (!options.readHeaderOnly)
{
- if (!serialClasses)
- {
- SLANG_RETURN_ON_FAIL(SerialClassesUtil::create(serialClasses));
- }
-
- // TODO(JS): We probably want to store off better information about each of the translation unit
- // including some kind of 'name'.
- // For now we just generate a name.
+ RiffContainer::Data* astData = astChunk->findContainedData(ASTSerialBinary::kSlangASTModuleDataFourCC);
- StringBuilder buf;
- buf << "tu" << out.modules.getCount();
- if (!astBuilder)
+ if (astData)
{
- astBuilder = new ASTBuilder(options.sharedASTBuilder, buf.produceString());
- }
+ if (!serialClasses)
+ {
+ SLANG_RETURN_ON_FAIL(SerialClassesUtil::create(serialClasses));
+ }
- /// We need to make the current ASTBuilder available for access via thread_local global.
- SetASTBuilderContextRAII astBuilderRAII(astBuilder);
+ // TODO(JS): We probably want to store off better information about each of the translation unit
+ // including some kind of 'name'.
+ // For now we just generate a name.
- DefaultSerialObjectFactory objectFactory(astBuilder);
+ StringBuilder buf;
+ buf << "tu" << out.modules.getCount();
+ if (!astBuilder)
+ {
+ astBuilder = new ASTBuilder(options.sharedASTBuilder, buf.produceString());
+ }
- SerialReader reader(serialClasses, &objectFactory);
+ /// We need to make the current ASTBuilder available for access via thread_local global.
+ SetASTBuilderContextRAII astBuilderRAII(astBuilder);
- // Sets up the entry table - one entry for each 'object'.
- // No native objects are constructed. No objects are deserialized.
- SLANG_RETURN_ON_FAIL(reader.loadEntries((const uint8_t*)astData->getPayload(), astData->getSize()));
+ DefaultSerialObjectFactory objectFactory(astBuilder);
- // Construct a native object for each table entry (where appropriate).
- // Note that this *doesn't* set all object pointers - some are special cased and created on demand (strings)
- // and imported symbols will have their object pointers unset (they are resolved in next step)
- SLANG_RETURN_ON_FAIL(reader.constructObjects(options.namePool));
+ SerialReader reader(serialClasses, &objectFactory);
- // Resolve external references if the linkage is specified
- if (options.linkage)
- {
- const auto& entries = reader.getEntries();
- auto& objects = reader.getObjects();
- const Index entriesCount = entries.getCount();
+ // Sets up the entry table - one entry for each 'object'.
+ // No native objects are constructed. No objects are deserialized.
+ SLANG_RETURN_ON_FAIL(reader.loadEntries((const uint8_t*)astData->getPayload(), astData->getSize()));
- String currentModuleName;
- Module* currentModule = nullptr;
+ // Construct a native object for each table entry (where appropriate).
+ // Note that this *doesn't* set all object pointers - some are special cased and created on demand (strings)
+ // and imported symbols will have their object pointers unset (they are resolved in next step)
+ SLANG_RETURN_ON_FAIL(reader.constructObjects(options.namePool));
- // Index from 1 (0 is null)
- for (Index i = 1; i < entriesCount; ++i)
+ // Resolve external references if the linkage is specified
+ if (options.linkage)
{
- const SerialInfo::Entry* entry = entries[i];
- if (entry->typeKind == SerialTypeKind::ImportSymbol)
- {
- UnownedStringSlice mangledName = reader.getStringSlice(SerialIndex(i));
+ const auto& entries = reader.getEntries();
+ auto& objects = reader.getObjects();
+ const Index entriesCount = entries.getCount();
- String moduleName;
- SLANG_RETURN_ON_FAIL(MangledNameParser::parseModuleName(mangledName, moduleName));
+ String currentModuleName;
+ Module* currentModule = nullptr;
- // If we already have looked up this module and it has the same name just use what we have
- Module* readModule = nullptr;
- if (currentModule && moduleName == currentModuleName.getUnownedSlice())
- {
- readModule = currentModule;
- }
- else
+ // Index from 1 (0 is null)
+ for (Index i = 1; i < entriesCount; ++i)
+ {
+ const SerialInfo::Entry* entry = entries[i];
+ if (entry->typeKind == SerialTypeKind::ImportSymbol)
{
- // The modules are loaded on the linkage.
- Linkage* linkage = options.linkage;
+ UnownedStringSlice mangledName = reader.getStringSlice(SerialIndex(i));
- NamePool* namePool = linkage->getNamePool();
- Name* moduleNameName = namePool->getName(moduleName);
+ String moduleName;
+ SLANG_RETURN_ON_FAIL(MangledNameParser::parseModuleName(mangledName, moduleName));
- readModule = linkage->findOrImportModule(moduleNameName, SourceLoc::fromRaw(0), options.sink, additionalLoadedModules);
- if (!readModule)
+ // If we already have looked up this module and it has the same name just use what we have
+ Module* readModule = nullptr;
+ if (currentModule && moduleName == currentModuleName.getUnownedSlice())
{
- return SLANG_FAIL;
+ readModule = currentModule;
}
+ else
+ {
+ // The modules are loaded on the linkage.
+ Linkage* linkage = options.linkage;
- // Set the current module and name
- currentModule = readModule;
- currentModuleName = moduleName;
- }
+ NamePool* namePool = linkage->getNamePool();
+ Name* moduleNameName = namePool->getName(moduleName);
- // Look up the symbol
- NodeBase* nodeBase = readModule->findExportFromMangledName(mangledName);
+ readModule = linkage->findOrImportModule(moduleNameName, SourceLoc::fromRaw(0), options.sink, additionalLoadedModules);
+ if (!readModule)
+ {
+ return SLANG_FAIL;
+ }
- if (!nodeBase)
- {
- if (options.sink)
+ // Set the current module and name
+ currentModule = readModule;
+ currentModuleName = moduleName;
+ }
+
+ // Look up the symbol
+ NodeBase* nodeBase = readModule->findExportFromMangledName(mangledName);
+
+ if (!nodeBase)
{
- options.sink->diagnose(SourceLoc::fromRaw(0), Diagnostics::unableToFindSymbolInModule, mangledName, moduleName);
+ if (options.sink)
+ {
+ options.sink->diagnose(SourceLoc::fromRaw(0), Diagnostics::unableToFindSymbolInModule, mangledName, moduleName);
+ }
+
+ // If didn't find the export then we create an UnresolvedDecl node to represent the error.
+ auto unresolved = astBuilder->create<UnresolvedDecl>();
+ unresolved->nameAndLoc.name =
+ options.linkage->getNamePool()->getName(mangledName);
+ nodeBase = unresolved;
}
- // If didn't find the export then we create an UnresolvedDecl node to represent the error.
- auto unresolved = astBuilder->create<UnresolvedDecl>();
- unresolved->nameAndLoc.name =
- options.linkage->getNamePool()->getName(mangledName);
- nodeBase = unresolved;
+ // set the result
+ objects[i] = nodeBase;
}
-
- // set the result
- objects[i] = nodeBase;
}
}
- }
-
- // Set the sourceLocReader before doing de-serialize, such can lookup the remapped sourceLocs
- reader.getExtraObjects().set(sourceLocReader);
-
- // TODO(JS):
- // If modules can have more complicated relationships (like a two modules can refer to symbols
- // from each other), then we can make this work by
- // 1) deserialize *without* the external symbols being set up
- // 2) calculate the symbols
- // 3) deserialize the other module (in the same way)
- // 4) run deserializeObjects *again* on each module
- // This is less efficient than it might be (because deserialize phase is done twice) so if this is necessary
- // may want a mechanism that *just* does reference lookups.
- //
- // For now if we assume a module can only access symbols from another module, and not the reverse.
- // So we just need to deserialize and we are done
- SLANG_RETURN_ON_FAIL(reader.deserializeObjects());
-
- // Get the root node. It's at index 1 (0 is the null value).
- astRootNode = reader.getPointer(SerialIndex(1)).dynamicCast<NodeBase>();
- // Go through all AST nodes:
- // 1) Add the extensions to the module mapTypeToCandidateExtensions cache
- // 2) We need to fix the callback pointers for parsing
- // 3) Register all `Val`s to the ASTBuilder's deduplication map.
+ // Set the sourceLocReader before doing de-serialize, such can lookup the remapped sourceLocs
+ reader.getExtraObjects().set(sourceLocReader);
+
+ // TODO(JS):
+ // If modules can have more complicated relationships (like a two modules can refer to symbols
+ // from each other), then we can make this work by
+ // 1) deserialize *without* the external symbols being set up
+ // 2) calculate the symbols
+ // 3) deserialize the other module (in the same way)
+ // 4) run deserializeObjects *again* on each module
+ // This is less efficient than it might be (because deserialize phase is done twice) so if this is necessary
+ // may want a mechanism that *just* does reference lookups.
+ //
+ // For now if we assume a module can only access symbols from another module, and not the reverse.
+ // So we just need to deserialize and we are done
+ SLANG_RETURN_ON_FAIL(reader.deserializeObjects());
+
+ // Get the root node. It's at index 1 (0 is the null value).
+ astRootNode = reader.getPointer(SerialIndex(1)).dynamicCast<NodeBase>();
+
+ // Go through all AST nodes:
+ // 1) Add the extensions to the module mapTypeToCandidateExtensions cache
+ // 2) We need to fix the callback pointers for parsing
+ // 3) Register all `Val`s to the ASTBuilder's deduplication map.
- {
- ModuleDecl* moduleDecl = as<ModuleDecl>(astRootNode);
+ {
+ ModuleDecl* moduleDecl = as<ModuleDecl>(astRootNode);
- // Maps from keyword name name to index in (syntaxParseInfos)
- // Will be filled in lazily if needed (for SyntaxDecl setup)
- Dictionary<Name*, Index> syntaxKeywordDict;
-
- OrderedDictionary<Val*, List<Val**>> valUses;
+ // Maps from keyword name name to index in (syntaxParseInfos)
+ // Will be filled in lazily if needed (for SyntaxDecl setup)
+ Dictionary<Name*, Index> syntaxKeywordDict;
- // Get the parse infos
- const auto syntaxParseInfos = getSyntaxParseInfos();
- SLANG_ASSERT(syntaxParseInfos.getCount());
+ OrderedDictionary<Val*, List<Val**>> valUses;
- for (auto& obj : reader.getObjects())
- {
+ // Get the parse infos
+ const auto syntaxParseInfos = getSyntaxParseInfos();
+ SLANG_ASSERT(syntaxParseInfos.getCount());
- if (obj.m_kind == SerialTypeKind::NodeBase)
+ for (auto& obj : reader.getObjects())
{
- NodeBase* nodeBase = (NodeBase*)obj.m_ptr;
- SLANG_ASSERT(nodeBase);
- if (ExtensionDecl* extensionDecl = dynamicCast<ExtensionDecl>(nodeBase))
+ if (obj.m_kind == SerialTypeKind::NodeBase)
{
- if (auto targetDeclRefType = as<DeclRefType>(extensionDecl->targetType))
+ NodeBase* nodeBase = (NodeBase*)obj.m_ptr;
+ SLANG_ASSERT(nodeBase);
+
+ if (ExtensionDecl* extensionDecl = dynamicCast<ExtensionDecl>(nodeBase))
{
- // Attach our extension to that type as a candidate...
- if (auto aggTypeDeclRef = targetDeclRefType->getDeclRef().as<AggTypeDecl>())
+ if (auto targetDeclRefType = as<DeclRefType>(extensionDecl->targetType))
{
- auto aggTypeDecl = aggTypeDeclRef.getDecl();
+ // Attach our extension to that type as a candidate...
+ if (auto aggTypeDeclRef = targetDeclRefType->getDeclRef().as<AggTypeDecl>())
+ {
+ auto aggTypeDecl = aggTypeDeclRef.getDecl();
- _getCandidateExtensionList(aggTypeDecl, moduleDecl->mapTypeToCandidateExtensions).add(extensionDecl);
+ _getCandidateExtensionList(aggTypeDecl, moduleDecl->mapTypeToCandidateExtensions).add(extensionDecl);
+ }
}
}
- }
- else if (SyntaxDecl* syntaxDecl = dynamicCast<SyntaxDecl>(nodeBase))
- {
- // Set up the dictionary lazily
- if (syntaxKeywordDict.getCount() == 0)
+ else if (SyntaxDecl* syntaxDecl = dynamicCast<SyntaxDecl>(nodeBase))
{
- NamePool* namePool = options.session->getNamePool();
- for (Index i = 0; i < syntaxParseInfos.getCount(); ++i)
+ // Set up the dictionary lazily
+ if (syntaxKeywordDict.getCount() == 0)
{
- const auto& entry = syntaxParseInfos[i];
- syntaxKeywordDict.add(namePool->getName(entry.keywordName), i);
+ NamePool* namePool = options.session->getNamePool();
+ for (Index i = 0; i < syntaxParseInfos.getCount(); ++i)
+ {
+ const auto& entry = syntaxParseInfos[i];
+ syntaxKeywordDict.add(namePool->getName(entry.keywordName), i);
+ }
+ // Must have something in it at this point
+ SLANG_ASSERT(syntaxKeywordDict.getCount());
}
- // Must have something in it at this point
- SLANG_ASSERT(syntaxKeywordDict.getCount());
- }
- // Look up the index
- Index* entryIndexPtr = syntaxKeywordDict.tryGetValue(syntaxDecl->getName());
- if (entryIndexPtr)
- {
- // Set up SyntaxDecl based on the ParseSyntaxIndo
- auto& info = syntaxParseInfos[*entryIndexPtr];
- syntaxDecl->parseCallback = *info.callback;
- syntaxDecl->parseUserData = const_cast<ReflectClassInfo*>(info.classInfo);
+ // Look up the index
+ Index* entryIndexPtr = syntaxKeywordDict.tryGetValue(syntaxDecl->getName());
+ if (entryIndexPtr)
+ {
+ // Set up SyntaxDecl based on the ParseSyntaxIndo
+ auto& info = syntaxParseInfos[*entryIndexPtr];
+ syntaxDecl->parseCallback = *info.callback;
+ syntaxDecl->parseUserData = const_cast<ReflectClassInfo*>(info.classInfo);
+ }
+ else
+ {
+ // If we don't find a setup entry, we use `parseSimpleSyntax`, and set
+ // the parseUserData to the ReflectClassInfo (as parseSimpleSyntax needs this)
+ syntaxDecl->parseCallback = &parseSimpleSyntax;
+ SLANG_ASSERT(syntaxDecl->syntaxClass.classInfo);
+ syntaxDecl->parseUserData = const_cast<ReflectClassInfo*>(syntaxDecl->syntaxClass.classInfo);
+ }
}
- else
+ else if (Val* val = dynamicCast<Val>(nodeBase))
{
- // If we don't find a setup entry, we use `parseSimpleSyntax`, and set
- // the parseUserData to the ReflectClassInfo (as parseSimpleSyntax needs this)
- syntaxDecl->parseCallback = &parseSimpleSyntax;
- SLANG_ASSERT(syntaxDecl->syntaxClass.classInfo);
- syntaxDecl->parseUserData = const_cast<ReflectClassInfo*>(syntaxDecl->syntaxClass.classInfo);
+ val->_setUnique();
}
}
- else if (Val* val = dynamicCast<Val>(nodeBase))
- {
- val->_setUnique();
- }
}
}
}
@@ -586,8 +668,6 @@ static List<ExtensionDecl*>& _getCandidateExtensionList(
if (astBuilder || irModule)
{
- SerialContainerData::Module module;
-
module.astBuilder = astBuilder;
module.astRootNode = astRootNode;
module.irModule = irModule;
diff --git a/source/slang/slang-serialize-container.h b/source/slang/slang-serialize-container.h
index a2b596a24..9b9fbe6a1 100644
--- a/source/slang/slang-serialize-container.h
+++ b/source/slang/slang-serialize-container.h
@@ -53,6 +53,8 @@ struct SerialContainerData
RefPtr<IRModule> irModule; ///< The IR for the module
RefPtr<ASTBuilder> astBuilder; ///< The astBuilder that owns the astRootNode
NodeBase* astRootNode = nullptr; ///< The module decl
+ List<String> dependentFiles;
+ SHA1::Digest digest;
};
struct EntryPoint
@@ -92,6 +94,7 @@ struct SerialContainerUtil
ASTBuilder* astBuilder = nullptr; // Optional. If not provided will create one in SerialContainerData.
Linkage* linkage = nullptr;
DiagnosticSink* sink = nullptr;
+ bool readHeaderOnly = false;
};
/// Add module to outData
diff --git a/source/slang/slang-serialize-types.h b/source/slang/slang-serialize-types.h
index 7623eb4cf..6be35ba09 100644
--- a/source/slang/slang-serialize-types.h
+++ b/source/slang/slang-serialize-types.h
@@ -144,6 +144,9 @@ struct SerialBinary
/// Container
static const FourCC kContainerHeaderFourCc = SLANG_FOUR_CC('S', 'c', 'h', 'd');
+ // Module header
+ static const FourCC kModuleHeaderFourCc = SLANG_FOUR_CC('S', 'm', 'h', 'd');
+
struct ContainerHeader
{
uint32_t compressionType; ///< Holds the compression type used (if used at all)
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 62fb3cbdb..c0f89b0dc 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -3165,12 +3165,19 @@ RefPtr<Module> Linkage::loadModuleFromIRBlobImpl(
String mostUniqueIdentity = filePathInfo.getMostUniqueIdentity();
SLANG_ASSERT(mostUniqueIdentity.getLength() > 0);
- mapPathToLoadedModule.add(mostUniqueIdentity, resultModule);
- mapNameToLoadedModules.add(name, resultModule);
-
RiffContainer container;
MemoryStreamBase readStream(FileAccess::Read, fileContentsBlob->getBufferPointer(), fileContentsBlob->getBufferSize());
SLANG_RETURN_NULL_ON_FAIL(RiffUtil::read(&readStream, container));
+
+ if (m_optionSet.getBoolOption(CompilerOptionName::UseUpToDateBinaryModule))
+ {
+ if (!isBinaryModuleUpToDate(filePathInfo.foundPath, &container))
+ return nullptr;
+ }
+
+ mapPathToLoadedModule.add(mostUniqueIdentity, resultModule);
+ mapNameToLoadedModules.add(name, resultModule);
+
SerialContainerUtil::ReadOptions readOptions;
readOptions.linkage = this;
readOptions.astBuilder = getASTBuilder();
@@ -3180,12 +3187,25 @@ RefPtr<Module> Linkage::loadModuleFromIRBlobImpl(
readOptions.sourceManager = getSourceManager();
readOptions.namePool = getNamePool();
SerialContainerData containerData;
- SLANG_RETURN_NULL_ON_FAIL(SerialContainerUtil::read(&container, readOptions, additionalLoadedModules, containerData));
- if (containerData.modules.getCount() != 1)
+ if (SLANG_FAILED(SerialContainerUtil::read(&container, readOptions, additionalLoadedModules, containerData)) ||
+ containerData.modules.getCount() != 1)
+ {
+ mapPathToLoadedModule.remove(mostUniqueIdentity);
+ mapNameToLoadedModules.remove(name);
return nullptr;
+ }
auto moduleEntry = containerData.modules.getFirst();
resultModule->setIRModule(moduleEntry.irModule);
resultModule->setModuleDecl(as<ModuleDecl>(moduleEntry.astRootNode));
+ resultModule->clearFileDependency();
+ for (auto file : moduleEntry.dependentFiles)
+ {
+ auto sourceFile = loadSourceFile(filePathInfo.foundPath, file);
+ if (sourceFile)
+ {
+ resultModule->addFileDependency(sourceFile);
+ }
+ }
prepareDeserializedModule(resultModule, sink);
@@ -3463,7 +3483,7 @@ RefPtr<Module> Linkage::findOrImportModule(
// We've found a file that we can load for the given module, so
// go ahead and perform the module-load action
- return loadModule(
+ auto resultModule = loadModule(
name,
filePathInfo,
fileContents,
@@ -3471,6 +3491,8 @@ RefPtr<Module> Linkage::findOrImportModule(
sink,
loadedModules,
(checkBinaryModule == 1 ? ModuleBlobType::IR : ModuleBlobType::Source));
+ if (resultModule)
+ return resultModule;
}
// Error: we cannot find the file.
@@ -3479,6 +3501,67 @@ RefPtr<Module> Linkage::findOrImportModule(
return nullptr;
}
+SourceFile* Linkage::loadSourceFile(String pathFrom, String path)
+{
+ IncludeSystem includeSystem(&getSearchDirectories(), getFileSystemExt(), getSourceManager());
+ ComPtr<slang::IBlob> blob;
+ PathInfo pathInfo;
+ SLANG_RETURN_NULL_ON_FAIL(includeSystem.findFile(path, pathFrom, pathInfo));
+ SourceFile* sourceFile = nullptr;
+ SLANG_RETURN_NULL_ON_FAIL(includeSystem.loadFile(pathInfo, blob, sourceFile));
+ return sourceFile;
+}
+
+ // Check if a serialized module is up-to-date with current compiler options and source files.
+bool Linkage::isBinaryModuleUpToDate(String fromPath, RiffContainer* container)
+{
+ DiagnosticSink sink;
+ SerialContainerUtil::ReadOptions readOptions;
+ readOptions.linkage = this;
+ readOptions.astBuilder = getASTBuilder();
+ readOptions.session = getSessionImpl();
+ readOptions.sharedASTBuilder = getASTBuilder()->getSharedASTBuilder();
+ readOptions.sink = &sink;
+ readOptions.sourceManager = getSourceManager();
+ readOptions.namePool = getNamePool();
+ readOptions.readHeaderOnly = true;
+
+ SerialContainerData containerData;
+ if (SLANG_FAILED(SerialContainerUtil::read(container, readOptions, nullptr, containerData)))
+ return false;
+
+ if (containerData.modules.getCount() != 1)
+ return false;
+
+ auto& moduleHeader = containerData.modules[0];
+ DigestBuilder<SHA1> digestBuilder;
+ m_optionSet.buildHash(digestBuilder);
+ for (auto file : moduleHeader.dependentFiles)
+ {
+ auto sourceFile = loadSourceFile(fromPath, file);
+ if (!sourceFile)
+ {
+ // If we cannot find the source file from `fromPath`,
+ // try again from the module's source file path.
+ if (moduleHeader.dependentFiles.getCount() != 0)
+ sourceFile = loadSourceFile(moduleHeader.dependentFiles.getFirst(), file);
+ }
+ if (!sourceFile)
+ return false;
+ digestBuilder.append(sourceFile->getDigest());
+ }
+ return digestBuilder.finalize() == moduleHeader.digest;
+}
+
+SLANG_NO_THROW bool SLANG_MCALL Linkage::isBinaryModuleUpToDate(const char* modulePath, slang::IBlob* binaryModuleBlob)
+{
+ RiffContainer container;
+ MemoryStreamBase readStream(FileAccess::Read, binaryModuleBlob->getBufferPointer(), binaryModuleBlob->getBufferSize());
+ if (SLANG_FAILED(RiffUtil::read(&readStream, container)))
+ return false;
+ return isBinaryModuleUpToDate(modulePath, &container);
+}
+
SourceFile* Linkage::findFile(Name* name, SourceLoc loc, IncludeSystem& outIncludeSystem)
{
auto fileName = getFileNameFromModuleName(name);
@@ -3665,7 +3748,7 @@ Module::Module(Linkage* linkage, ASTBuilder* astBuilder)
{
m_astBuilder = linkage->getASTBuilder();
}
-
+ getOptionSet() = linkage->m_optionSet;
addModuleDependency(this);
}
@@ -4004,9 +4087,7 @@ SLANG_NO_THROW void SLANG_MCALL ComponentType::getEntryPointHash(
// Enumerate all file dependencies and add them to the hash.
for (SourceFile* sourceFile : getFileDependencies())
{
- // TODO: We want to lazily evaluate & cache the source file digest
- SHA1::Digest digest = SHA1::compute(sourceFile->getContent().begin(), sourceFile->getContent().getLength());
- builder.append(digest);
+ builder.append(sourceFile->getDigest());
}
buildHash(builder);
diff --git a/tools/gfx-unit-test/precompiled-module-cache.cpp b/tools/gfx-unit-test/precompiled-module-cache.cpp
new file mode 100644
index 000000000..97d6e1c34
--- /dev/null
+++ b/tools/gfx-unit-test/precompiled-module-cache.cpp
@@ -0,0 +1,238 @@
+#include "tools/unit-test/slang-unit-test.h"
+
+#include "slang-gfx.h"
+#include "gfx-test-util.h"
+#include "tools/gfx-util/shader-cursor.h"
+#include "source/core/slang-basic.h"
+#include "source/core/slang-blob.h"
+#include "source/core/slang-memory-file-system.h"
+#include "source/core/slang-io.h"
+
+using namespace gfx;
+
+namespace gfx_test
+{
+ // Test that precompiled module cache is working.
+
+ Slang::ComPtr<slang::ISession> createSession(gfx::IDevice* device, ISlangFileSystemExt* fileSys)
+ {
+ Slang::ComPtr<slang::ISession> slangSession;
+ device->getSlangSession(slangSession.writeRef());
+ slang::SessionDesc sessionDesc = {};
+ sessionDesc.searchPathCount = 1;
+ const char* searchPath = "cache/";
+ sessionDesc.searchPaths = &searchPath;
+ sessionDesc.targetCount = 1;
+ sessionDesc.compilerOptionEntryCount = 1;
+ slang::CompilerOptionEntry entry;
+ entry.name = slang::CompilerOptionName::UseUpToDateBinaryModule;
+ entry.value.kind = slang::CompilerOptionValueKind::Int;
+ entry.value.intValue0 = 1;
+ sessionDesc.compilerOptionEntries = &entry;
+ slang::TargetDesc targetDesc = {};
+ switch (device->getDeviceInfo().deviceType)
+ {
+ case gfx::DeviceType::DirectX12:
+ targetDesc.format = SLANG_DXIL;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("sm_6_1");
+ break;
+ case gfx::DeviceType::Vulkan:
+ targetDesc.format = SLANG_SPIRV;
+ targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460");
+ break;
+ }
+ sessionDesc.targets = &targetDesc;
+ sessionDesc.fileSystem = fileSys;
+ auto globalSession = slangSession->getGlobalSession();
+ globalSession->createSession(sessionDesc, slangSession.writeRef());
+ return slangSession;
+ }
+
+ static Slang::Result precompileProgram(
+ gfx::IDevice* device,
+ ISlangMutableFileSystem* fileSys,
+ const char* shaderModuleName)
+ {
+ Slang::ComPtr<slang::ISession> slangSession = createSession(device, fileSys);
+
+ Slang::ComPtr<slang::IBlob> diagnosticsBlob;
+ slang::IModule* module = slangSession->loadModule(shaderModuleName, diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return SLANG_FAIL;
+
+ // Write loaded modules to memory file system.
+ for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++)
+ {
+ auto module = slangSession->getLoadedModule(i);
+ auto path = module->getFilePath();
+ if (path)
+ {
+ auto name = module->getName();
+ ComPtr<ISlangBlob> outBlob;
+ module->serialize(outBlob.writeRef());
+ fileSys->saveFileBlob((Slang::String("cache/") + Slang::String(name) + ".slang-module").getBuffer(), outBlob);
+ }
+ }
+ return SLANG_OK;
+ }
+
+ void precompiledModuleCacheTestImpl(IDevice* device, UnitTestContext* context)
+ {
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ // First, Initialize our file system.
+ ComPtr<ISlangMutableFileSystem> memoryFileSystem = ComPtr<ISlangMutableFileSystem>(new Slang::MemoryFileSystem());
+ memoryFileSystem->createDirectory("cache");
+
+ const char* moduleSrc = R"(
+ import "precompiled-module-imported";
+
+ // Main entry-point.
+
+ using namespace ns;
+
+ [shader("compute")]
+ [numthreads(4, 1, 1)]
+ void computeMain(
+ uint3 sv_dispatchThreadID : SV_DispatchThreadID,
+ uniform RWStructuredBuffer <float> buffer)
+ {
+ buffer[sv_dispatchThreadID.x] = helperFunc() + helperFunc1();
+ }
+ )";
+ memoryFileSystem->saveFile("precompiled-module.slang", moduleSrc, strlen(moduleSrc));
+
+ const char* moduleSrc2 = R"(
+ module "precompiled-module-imported";
+
+ __include "precompiled-module-included.slang";
+
+ namespace ns
+ {
+ public int helperFunc()
+ {
+ return 1;
+ }
+ }
+ )";
+ memoryFileSystem->saveFile("precompiled-module-imported.slang", moduleSrc2, strlen(moduleSrc2));
+ const char* moduleSrc3 = R"(
+ implementing "precompiled-module-imported";
+
+ namespace ns
+ {
+ public int helperFunc1()
+ {
+ return 2;
+ }
+ }
+ )";
+ memoryFileSystem->saveFile("precompiled-module-included.slang", moduleSrc3, strlen(moduleSrc3));
+
+ // Precompile a module.
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(precompileProgram(device, memoryFileSystem.get(), "precompiled-module-imported"));
+
+ // Next, load the precompiled slang program.
+ Slang::ComPtr<slang::ISession> slangSession = createSession(device, memoryFileSystem);
+ ComPtr<ISlangBlob> binaryBlob;
+ memoryFileSystem->loadFile("cache/precompiled-module-imported.slang-module", binaryBlob.writeRef());
+ auto upToDate = slangSession->isBinaryModuleUpToDate("precompiled-module-imported.slang", binaryBlob);
+ SLANG_CHECK(upToDate); // The module should be up-to-date.
+
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(device, slangSession, shaderProgram, "precompiled-module", "computeMain", slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ device->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ const int numberCount = 4;
+ float initialData[] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.sizeInBytes = numberCount * sizeof(float);
+ bufferDesc.format = gfx::Format::Unknown;
+ bufferDesc.elementSize = sizeof(float);
+ bufferDesc.allowedStates = ResourceStateSet(
+ ResourceState::ShaderResource,
+ ResourceState::UnorderedAccess,
+ ResourceState::CopyDestination,
+ ResourceState::CopySource);
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.memoryType = MemoryType::DeviceLocal;
+
+ ComPtr<IBufferResource> numbersBuffer;
+ GFX_CHECK_CALL_ABORT(device->createBufferResource(
+ bufferDesc,
+ (void*)initialData,
+ numbersBuffer.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(
+ device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef()));
+
+ // We have done all the set up work, now it is time to start recording a command buffer for
+ // GPU execution.
+ {
+ ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
+ auto queue = device->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor entryPointCursor(
+ rootObject->getEntryPoint(0)); // get a cursor the the first entry-point.
+ // Bind buffer view to the entry point.
+ entryPointCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->waitOnHost();
+ }
+
+ compareComputeResult(
+ device,
+ numbersBuffer,
+ Slang::makeArray<float>(3.0f, 3.0f, 3.0f, 3.0f));
+
+ // Now we change the source and check if the precompiled module is still up-to-date.
+ const char* moduleSrc4 = R"(
+ implementing "precompiled-module-imported";
+ namespace ns {
+ public int helperFunc1() {
+ return 2;
+ }
+ }
+ )";
+ memoryFileSystem->saveFile("precompiled-module-included.slang", moduleSrc4, strlen(moduleSrc4));
+
+ slangSession = createSession(device, memoryFileSystem);
+ upToDate = slangSession->isBinaryModuleUpToDate("precompiled-module-imported.slang", binaryBlob);
+ SLANG_CHECK(!upToDate); // The module should not be up-to-date because the source has changed.
+ }
+
+ SLANG_UNIT_TEST(precompiledModuleCacheD3D12)
+ {
+ runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12);
+ }
+
+ SLANG_UNIT_TEST(precompiledModuleCacheVulkan)
+ {
+ runTestImpl(precompiledModuleCacheTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan);
+ }
+
+}