diff options
| -rw-r--r-- | premake5.lua | 37 | ||||
| -rw-r--r-- | slang.sln | 11 | ||||
| -rw-r--r-- | tools/cpu-render-test/cpu-render-test-tool.vcxproj | 213 | ||||
| -rw-r--r-- | tools/cpu-render-test/cpu-render-test-tool.vcxproj.filters | 60 | ||||
| -rw-r--r-- | tools/render-test/cpu-compute-util.cpp | 365 | ||||
| -rw-r--r-- | tools/render-test/cpu-compute-util.h | 40 | ||||
| -rw-r--r-- | tools/render-test/cpu-memory-binding.cpp | 1 | ||||
| -rw-r--r-- | tools/render-test/cpu-render-test-main.cpp | 99 | ||||
| -rw-r--r-- | tools/render-test/options.cpp | 2 | ||||
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 453 | ||||
| -rw-r--r-- | tools/render-test/render-test-tool.vcxproj | 2 | ||||
| -rw-r--r-- | tools/render-test/render-test-tool.vcxproj.filters | 6 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.cpp | 34 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 89 | ||||
| -rw-r--r-- | tools/render-test/slang-support.h | 19 | ||||
| -rw-r--r-- | tools/slang-test/slang-test-main.cpp | 34 |
16 files changed, 994 insertions, 471 deletions
diff --git a/premake5.lua b/premake5.lua index 1f75b50c0..63f83b00e 100644 --- a/premake5.lua +++ b/premake5.lua @@ -510,25 +510,45 @@ if isTargetWindows then systemversion "10.0.14393.0" - -- For Windows targets, we want to copy d3dcompiler_47.dll, + removefiles { "tools/render-test/cpu-render-test-main.cpp" } + + -- For Windows targets, we want to copy -- dxcompiler.dll, and dxil.dll from the Windows SDK redistributable -- directory into the output directory. + -- d3dcompiler_47.dll is copied from the external/slang-binaries submodule. postbuildcommands { '"$(SolutionDir)tools\\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/%{cfg.platform:lower()}/" "%{cfg.targetdir}/" "windows-%{cfg.platform:lower()}"'} end - + +toolSharedLibrary "cpu-render-test" + uuid "5701695E-7324-4B4D-977A-8D56C2A041B1" + + includedirs { ".", "external", "source", "tools/gfx" } + links { "core", "slang", "gfx" } + + addSourceDir("tools/render-test") + + removefiles { "tools/render-test/render-test-main.cpp" } + + if isTargetWindows then + -- For Windows targets, we want to copy + -- dxcompiler.dll, and dxil.dll from the Windows SDK redistributable + -- directory into the output directory. + -- d3dcompiler_47.dll is copied from the external/slang-binaries submodule. + postbuildcommands { '"$(SolutionDir)tools\\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/%{cfg.platform:lower()}/" "%{cfg.targetdir}/"'} + end -- -- `gfx` is a utility library for doing GPU rendering -- and compute, which is used by both our testing and exmaples. -- It depends on teh `core` library, so we need to declare that: -- -tool "gfx" +tool "gfx" uuid "222F7498-B40C-4F3F-A704-DDEB91A4484A" -- Unlike most of the code under `tools/`, this is a library -- rather than a stand-alone executable. kind "StaticLib" - + includedirs { ".", "external", "source", "external/imgui" } -- To special case that we may be building using cygwin on windows. If 'true windows' we build for dx12/vk and run the script @@ -536,9 +556,10 @@ tool "gfx" if isTargetWindows then systemversion "10.0.14393.0" - -- For Windows targets, we want to copy d3dcompiler_47.dll, + -- For Windows targets, we want to copy -- dxcompiler.dll, and dxil.dll from the Windows SDK redistributable - -- directory into the output directory. + -- directory into the output directory. + -- d3dcompiler_47.dll is copied from the external/slang-binaries submodule. postbuildcommands { '"$(SolutionDir)tools\\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/%{cfg.platform:lower()}/" "%{cfg.targetdir}/"'} else removefiles { "tools/gfx/circular-resource-heap-d3d12.cpp", "tools/gfx/d3d-util.cpp", "tools/gfx/descriptor-heap-d3d12.cpp", "tools/gfx/render-d3d11.cpp", "tools/gfx/render-d3d12.cpp", "tools/gfx/render-gl.cpp", "tools/gfx/resource-d3d12.cpp", "tools/gfx/render-vk.cpp", "tools/gfx/vk-swap-chain.cpp", "tools/gfx/window.cpp" } @@ -549,6 +570,10 @@ tool "gfx" removefiles { "tools/gfx/render-vk.cpp", "tools/gfx/vk-device-queue.cpp", "tools/gfx/vk-api.cpp", "tools/gfx/vk-module.cpp", "tools/gfx/vk-swap-chain.cpp", "tools/gfx/vk-util.cpp" } end + filter { "system:linux" } + -- might be able to do pic(true) + buildoptions{"-fPIC"} + -- -- The `slangc` command-line application is just a very thin wrapper -- around the Slang dynamic library, so its build is extermely simple. @@ -23,6 +23,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang-reflection-test-tool" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "render-test-tool", "tools\render-test\render-test-tool.vcxproj", "{61F7EB00-7281-4BF3-9470-7C2EA92620C3}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpu-render-test-tool", "tools\cpu-render-test\cpu-render-test-tool.vcxproj", "{5701695E-7324-4B4D-977A-8D56C2A041B1}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slangc", "source\slangc\slangc.vcxproj", "{D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang", "source\slang\slang.vcxproj", "{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}" @@ -104,6 +106,14 @@ Global {61F7EB00-7281-4BF3-9470-7C2EA92620C3}.Release|Win32.Build.0 = Release|Win32 {61F7EB00-7281-4BF3-9470-7C2EA92620C3}.Release|x64.ActiveCfg = Release|x64 {61F7EB00-7281-4BF3-9470-7C2EA92620C3}.Release|x64.Build.0 = Release|x64 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Debug|Win32.ActiveCfg = Debug|Win32 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Debug|Win32.Build.0 = Debug|Win32 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Debug|x64.ActiveCfg = Debug|x64 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Debug|x64.Build.0 = Debug|x64 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Release|Win32.ActiveCfg = Release|Win32 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Release|Win32.Build.0 = Release|Win32 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Release|x64.ActiveCfg = Release|x64 + {5701695E-7324-4B4D-977A-8D56C2A041B1}.Release|x64.Build.0 = Release|x64 {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|Win32.ActiveCfg = Debug|Win32 {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|Win32.Build.0 = Debug|Win32 {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|x64.ActiveCfg = Debug|x64 @@ -140,5 +150,6 @@ Global {222F7498-B40C-4F3F-A704-DDEB91A4484A} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13} {C5ACCA6E-C04D-4B36-8516-3752B3C13C2F} = {57B5AA5E-C340-1823-CC51-9B17385C7423} {61F7EB00-7281-4BF3-9470-7C2EA92620C3} = {57B5AA5E-C340-1823-CC51-9B17385C7423} + {5701695E-7324-4B4D-977A-8D56C2A041B1} = {57B5AA5E-C340-1823-CC51-9B17385C7423} EndGlobalSection EndGlobal diff --git a/tools/cpu-render-test/cpu-render-test-tool.vcxproj b/tools/cpu-render-test/cpu-render-test-tool.vcxproj new file mode 100644 index 000000000..975aa61b6 --- /dev/null +++ b/tools/cpu-render-test/cpu-render-test-tool.vcxproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" 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="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5701695E-7324-4B4D-977A-8D56C2A041B1}</ProjectGuid> + <IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename> + <Keyword>Win32Proj</Keyword> + <RootNamespace>cpu-render-test-tool</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</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)'=='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> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>..\..\bin\windows-x86\debug\</OutDir> + <IntDir>..\..\intermediate\windows-x86\debug\cpu-render-test-tool\</IntDir> + <TargetName>cpu-render-test-tool</TargetName> + <TargetExt>.dll</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>..\..\bin\windows-x64\debug\</OutDir> + <IntDir>..\..\intermediate\windows-x64\debug\cpu-render-test-tool\</IntDir> + <TargetName>cpu-render-test-tool</TargetName> + <TargetExt>.dll</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>..\..\bin\windows-x86\release\</OutDir> + <IntDir>..\..\intermediate\windows-x86\release\cpu-render-test-tool\</IntDir> + <TargetName>cpu-render-test-tool</TargetName> + <TargetExt>.dll</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>..\..\bin\windows-x64\release\</OutDir> + <IntDir>..\..\intermediate\windows-x64\release\cpu-render-test-tool\</IntDir> + <TargetName>cpu-render-test-tool</TargetName> + <TargetExt>.dll</TargetExt> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>_DEBUG;SLANG_SHARED_LIBRARY_TOOL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\gfx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <Optimization>Disabled</Optimization> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ImportLibrary>..\..\bin\windows-x86\debug\cpu-render-test-tool.lib</ImportLibrary> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x86/" "../../bin/windows-x86/debug/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>_DEBUG;SLANG_SHARED_LIBRARY_TOOL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\gfx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <Optimization>Disabled</Optimization> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ImportLibrary>..\..\bin\windows-x64\debug\cpu-render-test-tool.lib</ImportLibrary> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x64/" "../../bin/windows-x64/debug/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>NDEBUG;SLANG_SHARED_LIBRARY_TOOL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\gfx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <MinimalRebuild>false</MinimalRebuild> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ImportLibrary>..\..\bin\windows-x86\release\cpu-render-test-tool.lib</ImportLibrary> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x86/" "../../bin/windows-x86/release/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>NDEBUG;SLANG_SHARED_LIBRARY_TOOL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\gfx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <MinimalRebuild>false</MinimalRebuild> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ImportLibrary>..\..\bin\windows-x64\release\cpu-render-test-tool.lib</ImportLibrary> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x64/" "../../bin/windows-x64/release/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\render-test\cpu-compute-util.h" /> + <ClInclude Include="..\render-test\cpu-memory-binding.h" /> + <ClInclude Include="..\render-test\options.h" /> + <ClInclude Include="..\render-test\png-serialize-util.h" /> + <ClInclude Include="..\render-test\shader-input-layout.h" /> + <ClInclude Include="..\render-test\shader-renderer-util.h" /> + <ClInclude Include="..\render-test\slang-support.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\render-test\cpu-compute-util.cpp" /> + <ClCompile Include="..\render-test\cpu-memory-binding.cpp" /> + <ClCompile Include="..\render-test\cpu-render-test-main.cpp" /> + <ClCompile Include="..\render-test\options.cpp" /> + <ClCompile Include="..\render-test\png-serialize-util.cpp" /> + <ClCompile Include="..\render-test\shader-input-layout.cpp" /> + <ClCompile Include="..\render-test\shader-renderer-util.cpp" /> + <ClCompile Include="..\render-test\slang-support.cpp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\source\core\core.vcxproj"> + <Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project> + </ProjectReference> + <ProjectReference Include="..\..\source\slang\slang.vcxproj"> + <Project>{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}</Project> + </ProjectReference> + <ProjectReference Include="..\gfx\gfx.vcxproj"> + <Project>{222F7498-B40C-4F3F-A704-DDEB91A4484A}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tools/cpu-render-test/cpu-render-test-tool.vcxproj.filters b/tools/cpu-render-test/cpu-render-test-tool.vcxproj.filters new file mode 100644 index 000000000..2b822a5be --- /dev/null +++ b/tools/cpu-render-test/cpu-render-test-tool.vcxproj.filters @@ -0,0 +1,60 @@ +<?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="..\render-test\cpu-compute-util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\render-test\cpu-memory-binding.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\render-test\options.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\render-test\png-serialize-util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\render-test\shader-input-layout.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\render-test\shader-renderer-util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\render-test\slang-support.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\render-test\cpu-compute-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\render-test\cpu-memory-binding.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\render-test\cpu-render-test-main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\render-test\options.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\render-test\png-serialize-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\render-test\shader-input-layout.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\render-test\shader-renderer-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\render-test\slang-support.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/tools/render-test/cpu-compute-util.cpp b/tools/render-test/cpu-compute-util.cpp new file mode 100644 index 000000000..85a8fb1b0 --- /dev/null +++ b/tools/render-test/cpu-compute-util.cpp @@ -0,0 +1,365 @@ +#define _CRT_SECURE_NO_WARNINGS 1 + +#include "cpu-compute-util.h" + +#include "../../slang-com-helper.h" + +#include "../../source/core/slang-std-writers.h" +#include "../../source/core/slang-token-reader.h" + +#define SLANG_PRELUDE_NAMESPACE CPPPrelude +#include "../../prelude/slang-cpp-types.h" + +namespace renderer_test { +using namespace Slang; + +/* static */SlangResult CPUComputeUtil::writeBindings(const ShaderInputLayout& layout, const List<CPUMemoryBinding::Buffer>& buffers, const String& fileName) +{ + FILE * f = fopen(fileName.getBuffer(), "wb"); + if (!f) + { + return SLANG_FAIL; + } + + const auto& entries = layout.entries; + + for (int i = 0; i < entries.getCount(); ++i) + { + const auto& entry = entries[i]; + if (entry.isOutput) + { + const auto& buffer = buffers[i]; + + unsigned int* ptr = (unsigned int*)buffer.m_data; + + const int size = int(entry.bufferData.getCount()); + // Must be the same size or less than allocated buffer + SLANG_ASSERT(size * sizeof(unsigned int) <= buffer.m_sizeInBytes); + + for (int i = 0; i < size; ++i) + { + unsigned int v = ptr[i]; + + fprintf(f, "%X\n", v); + } + } + } + fclose(f); + return SLANG_OK; +} + + +template <int COUNT> +struct OneTexture2D : public CPUComputeUtil::Resource, public CPPPrelude::ITexture2D +{ + void setOne(void* out) + { + float* dst = (float*)out; + for (int i = 0; i < COUNT; ++i) + { + dst[i] = 1.0f; + } + } + + virtual void Load(const CPPPrelude::int3& v, void* out) SLANG_OVERRIDE + { + setOne(out); + } + virtual void Sample(CPPPrelude::SamplerState samplerState, const CPPPrelude::float2& loc, void* out) SLANG_OVERRIDE + { + setOne(out); + } + virtual void SampleLevel(CPPPrelude::SamplerState samplerState, const CPPPrelude::float2& loc, float level, void* out) SLANG_OVERRIDE + { + setOne(out); + } + + OneTexture2D() + { + m_interface = static_cast<CPPPrelude::ITexture2D*>(this); + } +}; + +static CPUComputeUtil::Resource* _newOneTexture2D(int elemCount) +{ + switch (elemCount) + { + case 1: return new OneTexture2D<1>(); + case 2: return new OneTexture2D<2>(); + case 3: return new OneTexture2D<3>(); + case 4: return new OneTexture2D<4>(); + default: return nullptr; + } +} + +/* static */SlangResult CPUComputeUtil::calcBindings(const ShaderCompilerUtil::OutputAndLayout& compilationAndLayout, Context& outContext) +{ + auto request = compilationAndLayout.output.request; + auto reflection = (slang::ShaderReflection*) spGetReflection(request); + + const auto& sourcePath = compilationAndLayout.sourcePath; + + auto& binding = outContext.binding; + + binding.init(reflection, 0); + + auto& buffers = outContext.buffers; + buffers.clear(); + + // Okay we need to find all of the bindings and match up to those in the layout + const ShaderInputLayout& layout = compilationAndLayout.layout; + + { + auto outStream = StdWriters::getOut(); + auto& entries = layout.entries; + buffers.setCount(entries.getCount()); + + for (int entryIndex = 0; entryIndex < entries.getCount(); ++entryIndex) + { + auto& entry = entries[entryIndex]; + + if (entry.name.getLength() == 0) + { + outStream.print("No 'name' specified for resources in '%s'\n", sourcePath.getBuffer()); + return SLANG_FAIL; + } + + // We will parse the 'name' as may be path to a resource + TokenReader parser(entry.name); + + CPUMemoryBinding::Location location; + + { + Token nameToken = parser.ReadToken(); + if (nameToken.Type != TokenType::Identifier) + { + outStream.print("Invalid input syntax at line %d", int(parser.NextToken().Position.Line)); + return SLANG_FAIL; + } + location = binding.find(nameToken.Content.getBuffer()); + if (location.isInvalid()) + { + outStream.print("Unable to find entry in '%s' for '%s' (for CPU name must be specified) \n", sourcePath.getBuffer(), entry.name.getBuffer()); + return SLANG_FAIL; + } + } + + while (!parser.IsEnd()) + { + Token token = parser.NextToken(0); + + if (token.Type == TokenType::LBracket) + { + parser.ReadToken(); + int index = parser.ReadInt(); + SLANG_ASSERT(index >= 0); + + location = location.toIndex(index); + if (location.isInvalid()) + { + outStream.print("Unable to find entry in '%d' in '%s'\n", index, entry.name.getBuffer()); + return SLANG_FAIL; + } + parser.ReadMatchingToken(TokenType::RBracket); + } + else if (token.Type == TokenType::Dot) + { + parser.ReadToken(); + Token identifierToken = parser.ReadMatchingToken(TokenType::Identifier); + + location = location.toField(identifierToken.Content.getBuffer()); + if (location.isInvalid()) + { + outStream.print("Unable to find field '%s' in '%s'\n", identifierToken.Content.getBuffer(), entry.name.getBuffer()); + return SLANG_FAIL; + } + } + else if (token.Type == TokenType::Comma) + { + // Break out + break; + } + else + { + throw TextFormatException("Invalid input syntax at line " + parser.NextToken().Position.Line); + } + } + + auto& srcEntry = layout.entries[entryIndex]; + + auto typeLayout = location.getTypeLayout(); + const auto kind = typeLayout->getKind(); + switch (kind) + { + case slang::TypeReflection::Kind::Vector: + case slang::TypeReflection::Kind::Matrix: + case slang::TypeReflection::Kind::Array: + case slang::TypeReflection::Kind::Scalar: + case slang::TypeReflection::Kind::Struct: + { + SLANG_RETURN_ON_FAIL(binding.setInplace(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int))); + break; + } + default: + break; + case slang::TypeReflection::Kind::ConstantBuffer: + { + SLANG_RETURN_ON_FAIL(binding.setBufferContents(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int))); + break; + } + case slang::TypeReflection::Kind::ParameterBlock: + { + auto elementTypeLayout = typeLayout->getElementTypeLayout(); + SLANG_UNUSED(elementTypeLayout); + break; + } + case slang::TypeReflection::Kind::TextureBuffer: + { + auto elementTypeLayout = typeLayout->getElementTypeLayout(); + SLANG_UNUSED(elementTypeLayout); + break; + } + case slang::TypeReflection::Kind::ShaderStorageBuffer: + { + auto elementTypeLayout = typeLayout->getElementTypeLayout(); + SLANG_UNUSED(elementTypeLayout); + break; + } + case slang::TypeReflection::Kind::GenericTypeParameter: + { + const char* name = typeLayout->getName(); + SLANG_UNUSED(name); + break; + } + case slang::TypeReflection::Kind::Interface: + { + const char* name = typeLayout->getName(); + SLANG_UNUSED(name); + break; + } + case slang::TypeReflection::Kind::Resource: + { + auto type = typeLayout->getType(); + auto shape = type->getResourceShape(); + + //auto access = type->getResourceAccess(); + + switch (shape & SLANG_RESOURCE_BASE_SHAPE_MASK) + { + default: + assert(!"unhandled case"); + break; + case SLANG_TEXTURE_2D: + { + slang::TypeReflection* typeReflection = location.getTypeLayout()->getResourceResultType(); + + int count = 1; + if (typeReflection->getKind() == slang::TypeReflection::Kind::Vector) + { + count = int(typeReflection->getElementCount()); + } + + RefPtr<Resource> resource = _newOneTexture2D(count); + outContext.m_resources.add(resource); + + SLANG_RETURN_ON_FAIL(binding.setObject(location, resource->getInterface())); + break; + } + case SLANG_TEXTURE_1D: + case SLANG_TEXTURE_3D: + case SLANG_TEXTURE_CUBE: + case SLANG_TEXTURE_BUFFER: + { + // Just set to null for now + SLANG_RETURN_ON_FAIL(binding.setObject(location, nullptr)); + break; + } + case SLANG_BYTE_ADDRESS_BUFFER: + case SLANG_STRUCTURED_BUFFER: + { + CPUMemoryBinding::Buffer buffer; + SLANG_RETURN_ON_FAIL(binding.setNewBuffer(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int), buffer)); + buffers[entryIndex] = buffer; + break; + } + } + if (shape & SLANG_TEXTURE_ARRAY_FLAG) + { + + } + if (shape & SLANG_TEXTURE_MULTISAMPLE_FLAG) + { + + } + + break; + } + } + } + } + + return SLANG_OK; +} + +/* static */SlangResult CPUComputeUtil::execute(const ShaderCompilerUtil::OutputAndLayout& compilationAndLayout, Context& context) +{ + auto request = compilationAndLayout.output.request; + auto reflection = (slang::ShaderReflection*) spGetReflection(request); + + ComPtr<ISlangSharedLibrary> sharedLibrary; + SLANG_RETURN_ON_FAIL(spGetEntryPointHostCallable(request, 0, 0, sharedLibrary.writeRef())); + + // Use reflection to find the entry point name + + struct UniformState; + typedef void(*Func)(CPPPrelude::ComputeVaryingInput* varyingInput, CPPPrelude::UniformEntryPointParams* uniformEntryPointParams, UniformState* uniformState); + + slang::EntryPointReflection* entryPoint = nullptr; + Func func = nullptr; + { + auto entryPointCount = reflection->getEntryPointCount(); + SLANG_ASSERT(entryPointCount == 1); + + entryPoint = reflection->getEntryPointByIndex(0); + + const char* entryPointName = entryPoint->getName(); + func = (Func)sharedLibrary->findFuncByName(entryPointName); + + if (!func) + { + return SLANG_FAIL; + } + } + + SlangUInt numThreadsPerAxis[3]; + entryPoint->getComputeThreadGroupSize(3, numThreadsPerAxis); + + { + UniformState* uniformState = (UniformState*)context.binding.m_rootBuffer.m_data; + CPPPrelude::UniformEntryPointParams* uniformEntryPointParams = (CPPPrelude::UniformEntryPointParams*)context.binding.m_entryPointBuffer.m_data; + + CPPPrelude::ComputeVaryingInput varying; + varying.groupID = {}; + + for (int z = 0; z < int(numThreadsPerAxis[2]); ++z) + { + varying.groupThreadID.z = z; + for (int y = 0; y < int(numThreadsPerAxis[1]); ++y) + { + varying.groupThreadID.y = y; + for (int x = 0; x < int(numThreadsPerAxis[0]); ++x) + { + varying.groupThreadID.x = x; + + func(&varying, uniformEntryPointParams, uniformState); + } + } + } + } + + return SLANG_OK; +} + + + +} // renderer_test diff --git a/tools/render-test/cpu-compute-util.h b/tools/render-test/cpu-compute-util.h new file mode 100644 index 000000000..cbc4e6e58 --- /dev/null +++ b/tools/render-test/cpu-compute-util.h @@ -0,0 +1,40 @@ +#ifndef CPU_COMPUTE_UTIL_H +#define CPU_COMPUTE_UTIL_H + +#include "cpu-memory-binding.h" +#include "slang-support.h" +#include "options.h" + +#include "../../source/core/slang-smart-pointer.h" + +namespace renderer_test { + +struct CPUComputeUtil +{ + struct Resource : public RefObject + { + void* getInterface() const { return m_interface; } + void* m_interface; + }; + + struct Context + { + /// Holds the binding information + CPUMemoryBinding binding; + /// Buffers are held in same order as entries in layout (useful for dumping out bindings) + List<CPUMemoryBinding::Buffer> buffers; + /// Holds the resources created (in calcBindings) + List<RefPtr<Resource> > m_resources; + }; + + static SlangResult calcBindings(const ShaderCompilerUtil::OutputAndLayout& compilationAndLayout, Context& outContext); + + static SlangResult execute(const ShaderCompilerUtil::OutputAndLayout& compilationAndLayout, Context& outContext); + + static SlangResult writeBindings(const ShaderInputLayout& layout, const List<CPUMemoryBinding::Buffer>& buffers, const Slang::String& fileName); +}; + + +} // renderer_test + +#endif //CPU_MEMORY_BINDING_H diff --git a/tools/render-test/cpu-memory-binding.cpp b/tools/render-test/cpu-memory-binding.cpp index 7760c5919..612c2fc57 100644 --- a/tools/render-test/cpu-memory-binding.cpp +++ b/tools/render-test/cpu-memory-binding.cpp @@ -46,6 +46,7 @@ SlangResult CPUMemoryBinding::init(slang::ShaderReflection* reflection, int entr { m_reflection = reflection; m_rootBuffer = Buffer(); + m_entryPointBuffer = Buffer(); m_allBuffers.clear(); m_arena.deallocateAll(); diff --git a/tools/render-test/cpu-render-test-main.cpp b/tools/render-test/cpu-render-test-main.cpp new file mode 100644 index 000000000..d754f9359 --- /dev/null +++ b/tools/render-test/cpu-render-test-main.cpp @@ -0,0 +1,99 @@ +// cpu-render-test-main.cpp + +#include "options.h" + +#include "slang-support.h" + +#include "../source/core/slang-io.h" + +#include "shader-input-layout.h" +#include <stdio.h> +#include <stdlib.h> + +#include "../../source/core/slang-test-tool-util.h" + +#include "cpu-compute-util.h" + +SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSession* session, int argcIn, const char*const* argvIn) +{ + using namespace renderer_test; + using namespace Slang; + + StdWriters::setSingleton(stdWriters); + + // Parse command-line options + SLANG_RETURN_ON_FAIL(parseOptions(argcIn, argvIn, StdWriters::getError())); + + // Declare window pointer before renderer, such that window is released after renderer + RefPtr<renderer_test::Window> window; + // Renderer is constructed (later) using the window + Slang::RefPtr<Renderer> renderer; + + ShaderCompilerUtil::Input input; + + input.profile = ""; + input.target = SLANG_TARGET_NONE; + input.args = &gOptions.slangArgs[0]; + input.argCount = gOptions.slangArgCount; + + SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; + SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE; + char const* profileName = ""; + switch (gOptions.rendererType) + { + case RendererType::CPU: + input.target = SLANG_HOST_CALLABLE; + input.profile = ""; + nativeLanguage = SLANG_SOURCE_LANGUAGE_CPP; + slangPassThrough = SLANG_PASS_THROUGH_GENERIC_C_CPP; + break; + default: + fprintf(stderr, "error: unexpected\n"); + return SLANG_FAIL; + } + + switch (gOptions.inputLanguageID) + { + case Options::InputLanguageID::Slang: + input.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG; + input.passThrough = SLANG_PASS_THROUGH_NONE; + break; + + case Options::InputLanguageID::Native: + input.sourceLanguage = nativeLanguage; + input.passThrough = slangPassThrough; + break; + + default: + break; + } + + // Use the profile name set on options if set + input.profile = gOptions.profileName ? gOptions.profileName : input.profile; + + { + ShaderCompilerUtil::OutputAndLayout compilationAndLayout; + SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions.sourcePath, gOptions.shaderType, input, compilationAndLayout)); + + CPUComputeUtil::Context context; + SLANG_RETURN_ON_FAIL(CPUComputeUtil::calcBindings(compilationAndLayout, context)); + SLANG_RETURN_ON_FAIL(CPUComputeUtil::execute(compilationAndLayout, context)); + + // Dump everything out that was written + return CPUComputeUtil::writeBindings(compilationAndLayout.layout, context.buffers, gOptions.outputPath); + } +} + +int main(int argc, char** argv) +{ + using namespace Slang; + SlangSession* session = spCreateSession(nullptr); + + TestToolUtil::setSessionDefaultPrelude(argv[0], session); + auto stdWriters = StdWriters::initDefaultSingleton(); + SlangResult res = innerMain(stdWriters, session, argc, argv); + spDestroySession(session); + + return (int)TestToolUtil::getReturnCode(res); +} + diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp index f8c2c1d12..a9e51b8e0 100644 --- a/tools/render-test/options.cpp +++ b/tools/render-test/options.cpp @@ -15,7 +15,7 @@ namespace renderer_test { using namespace Slang; -static const Options gDefaultOptions; +static const Options gDefaultOptions = Options(); Options gOptions; diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 440ba9c82..5b9621142 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -21,13 +21,9 @@ #include <stdio.h> #include <stdlib.h> -#define SLANG_PRELUDE_NAMESPACE CPPPrelude -#include "../../prelude/slang-cpp-types.h" - #include "../../source/core/slang-test-tool-util.h" -#include "../../source/core/slang-memory-arena.h" -#include "cpu-memory-binding.h" +#include "cpu-compute-util.h" #define WIN32_LEAN_AND_MEAN #define NOMINMAX @@ -241,436 +237,6 @@ class RenderTestApp int m_numAddedConstantBuffers; ///< Constant buffers can be added to the binding directly. Will be added at the end. }; -// Entry point name to use for vertex/fragment shader -static const char vertexEntryPointName[] = "vertexMain"; -static const char fragmentEntryPointName[] = "fragmentMain"; -static const char computeEntryPointName[] = "computeMain"; - -static SlangResult _readSource(const String& inSourcePath, List<char>& outSourceText) -{ - // Read in the source code - FILE* sourceFile = fopen(inSourcePath.getBuffer(), "rb"); - if (!sourceFile) - { - fprintf(stderr, "error: failed to open '%s' for reading\n", inSourcePath.getBuffer()); - return SLANG_FAIL; - } - fseek(sourceFile, 0, SEEK_END); - size_t sourceSize = ftell(sourceFile); - fseek(sourceFile, 0, SEEK_SET); - - outSourceText.setCount(sourceSize + 1); - fread(outSourceText.getBuffer(), sourceSize, 1, sourceFile); - fclose(sourceFile); - outSourceText[sourceSize] = 0; - - return SLANG_OK; -} - -struct CompileOutput -{ - ShaderCompilerUtil::Output compileOutput; - ShaderInputLayout layout; -}; - -static SlangResult _compile(SlangSession* session, const String& sourcePath, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input, CompileOutput& output) -{ - List<char> sourceText; - SLANG_RETURN_ON_FAIL(_readSource(sourcePath, sourceText)); - - auto& layout = output.layout; - - // Default the amount of renderTargets based on shader type - switch (shaderType) - { - default: - layout.numRenderTargets = 1; - break; - - case Options::ShaderProgramType::Compute: - layout.numRenderTargets = 0; - break; - } - - // Parse the layout - layout.parse(sourceText.getBuffer()); - layout.updateForTarget(input.target); - - // Setup SourceInfo - ShaderCompileRequest::SourceInfo sourceInfo; - sourceInfo.path = sourcePath.getBuffer(); - sourceInfo.dataBegin = sourceText.getBuffer(); - // Subtract 1 because it's zero terminated - sourceInfo.dataEnd = sourceText.getBuffer() + sourceText.getCount() - 1; - - ShaderCompileRequest compileRequest; - compileRequest.source = sourceInfo; - if (shaderType == Options::ShaderProgramType::Graphics || shaderType == Options::ShaderProgramType::GraphicsCompute) - { - compileRequest.vertexShader.source = sourceInfo; - compileRequest.vertexShader.name = vertexEntryPointName; - compileRequest.fragmentShader.source = sourceInfo; - compileRequest.fragmentShader.name = fragmentEntryPointName; - } - else - { - compileRequest.computeShader.source = sourceInfo; - compileRequest.computeShader.name = computeEntryPointName; - } - compileRequest.globalGenericTypeArguments = layout.globalGenericTypeArguments; - compileRequest.entryPointGenericTypeArguments = layout.entryPointGenericTypeArguments; - compileRequest.globalExistentialTypeArguments = layout.globalExistentialTypeArguments; - compileRequest.entryPointExistentialTypeArguments = layout.entryPointExistentialTypeArguments; - - return ShaderCompilerUtil::compileProgram(session, input, compileRequest, output.compileOutput); -} - -static SlangResult _writeBindings(const ShaderInputLayout& layout, const List<CPUMemoryBinding::Buffer>& buffers, const String& fileName) -{ - FILE * f = fopen(fileName.getBuffer(), "wb"); - if (!f) - { - return SLANG_FAIL; - } - - const auto& entries = layout.entries; - - for (int i = 0; i < entries.getCount(); ++i) - { - const auto& entry = entries[i]; - if (entry.isOutput) - { - const auto& buffer = buffers[i]; - - unsigned int* ptr = (unsigned int*)buffer.m_data; - - const int size = int(entry.bufferData.getCount()); - // Must be the same size or less thatn allocated buffer - SLANG_ASSERT(size * sizeof(unsigned int) <= buffer.m_sizeInBytes); - - for (int i = 0; i < size; ++i) - { - unsigned int v = ptr[i]; - - fprintf(f, "%X\n", v); - } - } - } - fclose(f); - return SLANG_OK; -} - -struct CPUResource: public RefObject -{ - void* getInterface() const { return m_interface; } - void* m_interface; -}; - -template <int COUNT> -struct OneTexture2D: public CPUResource, public CPPPrelude::ITexture2D -{ - void setOne(void* out) - { - float* dst = (float*)out; - for (int i = 0; i < COUNT; ++i) - { - dst[i] = 1.0f; - } - } - - virtual void Load(const CPPPrelude::int3& v, void* out) SLANG_OVERRIDE - { - setOne(out); - } - virtual void Sample(CPPPrelude::SamplerState samplerState, const CPPPrelude::float2& loc, void* out) SLANG_OVERRIDE - { - setOne(out); - } - virtual void SampleLevel(CPPPrelude::SamplerState samplerState, const CPPPrelude::float2& loc, float level, void* out) SLANG_OVERRIDE - { - setOne(out); - } - - OneTexture2D() - { - m_interface = static_cast<CPPPrelude::ITexture2D*>(this); - } -}; - -static CPUResource* _newOneTexture2D(int elemCount) -{ - switch (elemCount) - { - case 1: return new OneTexture2D<1>(); - case 2: return new OneTexture2D<2>(); - case 3: return new OneTexture2D<3>(); - case 4: return new OneTexture2D<4>(); - default: return nullptr; - } -} - -static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input) -{ - CompileOutput output; - SLANG_RETURN_ON_FAIL(_compile(session, sourcePath, shaderType, input, output)); - - ComPtr<ISlangSharedLibrary> sharedLibrary; - SLANG_RETURN_ON_FAIL(spGetEntryPointHostCallable(output.compileOutput.request, 0, 0, sharedLibrary.writeRef())); - - // Use reflection to find the entry point name - auto request = output.compileOutput.request; - - struct UniformState; - typedef void(*Func)(CPPPrelude::ComputeVaryingInput* varyingInput, CPPPrelude::UniformEntryPointParams* params, UniformState* uniformState); - - auto reflection = (slang::ShaderReflection*) spGetReflection(request); - - slang::EntryPointReflection* entryPoint = nullptr; - Func func = nullptr; - { - auto entryPointCount = reflection->getEntryPointCount(); - SLANG_ASSERT(entryPointCount == 1); - - entryPoint = reflection->getEntryPointByIndex(0); - - const char* entryPointName = entryPoint->getName(); - func = (Func) sharedLibrary->findFuncByName(entryPointName); - - if (!func) - { - return SLANG_FAIL; - } - } - - CPUMemoryBinding binding; - SLANG_RETURN_ON_FAIL(binding.init(reflection, 0)); - - List<CPUMemoryBinding::Buffer> buffers; - - // Okay we need to find all of the bindings and match up to those in the layout - ShaderInputLayout& layout = output.layout; - - List<RefPtr<CPUResource> > resources; - - { - auto& outStream = StdWriters::getOut(); - auto& entries = layout.entries; - buffers.setCount(entries.getCount()); - - for (int entryIndex = 0; entryIndex < entries.getCount(); ++entryIndex) - { - auto& entry = entries[entryIndex]; - - if (entry.name.getLength() == 0) - { - outStream.print("No 'name' specified for resources in '%s'\n", sourcePath.getBuffer()); - return SLANG_FAIL; - } - - // We will parse the 'name' as may be path to a resource - TokenReader parser(entry.name); - - CPUMemoryBinding::Location location; - - { - Token nameToken = parser.ReadToken(); - if (nameToken.Type != TokenType::Identifier) - { - outStream.print("Invalid input syntax at line %d", int(parser.NextToken().Position.Line)); - return SLANG_FAIL; - } - location = binding.find(nameToken.Content.getBuffer()); - if (location.isInvalid()) - { - outStream.print("Unable to find entry in '%s' for '%s' (for CPU name must be specified) \n", sourcePath.getBuffer(), entry.name.getBuffer()); - return SLANG_FAIL; - } - } - - while (!parser.IsEnd()) - { - Token token = parser.NextToken(0); - - if (token.Type == TokenType::LBracket) - { - parser.ReadToken(); - int index = parser.ReadInt(); - SLANG_ASSERT(index >= 0); - - location = location.toIndex(index); - if (location.isInvalid()) - { - outStream.print("Unable to find entry in '%d' in '%s'\n", index, entry.name.getBuffer()); - return SLANG_FAIL; - } - parser.ReadMatchingToken(TokenType::RBracket); - } - else if (token.Type == TokenType::Dot) - { - parser.ReadToken(); - Token identifierToken = parser.ReadMatchingToken(TokenType::Identifier); - - location = location.toField(identifierToken.Content.getBuffer()); - if (location.isInvalid()) - { - outStream.print("Unable to find field '%s' in '%s'\n", identifierToken.Content.getBuffer(), entry.name.getBuffer()); - return SLANG_FAIL; - } - } - else if (token.Type == TokenType::Comma) - { - // Break out - break; - } - else - { - throw TextFormatException("Invalid input syntax at line " + parser.NextToken().Position.Line); - } - } - - auto& srcEntry = layout.entries[entryIndex]; - - auto typeLayout = location.getTypeLayout(); - const auto kind = typeLayout->getKind(); - switch (kind) - { - case slang::TypeReflection::Kind::Vector: - case slang::TypeReflection::Kind::Matrix: - case slang::TypeReflection::Kind::Array: - case slang::TypeReflection::Kind::Scalar: - case slang::TypeReflection::Kind::Struct: - { - SLANG_RETURN_ON_FAIL(binding.setInplace(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int))); - break; - } - default: - break; - case slang::TypeReflection::Kind::ConstantBuffer: - { - SLANG_RETURN_ON_FAIL(binding.setBufferContents(location, srcEntry.bufferData.getBuffer(),srcEntry.bufferData.getCount() * sizeof(unsigned int) )); - break; - } - case slang::TypeReflection::Kind::ParameterBlock: - { - auto elementTypeLayout = typeLayout->getElementTypeLayout(); - SLANG_UNUSED(elementTypeLayout); - break; - } - case slang::TypeReflection::Kind::TextureBuffer: - { - auto elementTypeLayout = typeLayout->getElementTypeLayout(); - SLANG_UNUSED(elementTypeLayout); - break; - } - case slang::TypeReflection::Kind::ShaderStorageBuffer: - { - auto elementTypeLayout = typeLayout->getElementTypeLayout(); - SLANG_UNUSED(elementTypeLayout); - break; - } - case slang::TypeReflection::Kind::GenericTypeParameter: - { - const char* name = typeLayout->getName(); - SLANG_UNUSED(name); - break; - } - case slang::TypeReflection::Kind::Interface: - { - const char* name = typeLayout->getName(); - SLANG_UNUSED(name); - break; - } - case slang::TypeReflection::Kind::Resource: - { - auto type = typeLayout->getType(); - auto shape = type->getResourceShape(); - - //auto access = type->getResourceAccess(); - - switch (shape & SLANG_RESOURCE_BASE_SHAPE_MASK) - { - default: - assert(!"unhandled case"); - break; - case SLANG_TEXTURE_2D: - { - slang::TypeReflection* typeReflection = location.getTypeLayout()->getResourceResultType(); - - int count = 1; - if (typeReflection->getKind() == slang::TypeReflection::Kind::Vector) - { - count = int(typeReflection->getElementCount()); - } - - RefPtr<CPUResource> resource = _newOneTexture2D(count); - resources.add(resource); - - SLANG_RETURN_ON_FAIL(binding.setObject(location, resource->getInterface())); - break; - } - case SLANG_TEXTURE_1D: - case SLANG_TEXTURE_3D: - case SLANG_TEXTURE_CUBE: - case SLANG_TEXTURE_BUFFER: - { - // Just set to null for now - SLANG_RETURN_ON_FAIL(binding.setObject(location, nullptr)); - break; - } - case SLANG_BYTE_ADDRESS_BUFFER: - case SLANG_STRUCTURED_BUFFER: - { - CPUMemoryBinding::Buffer buffer; - SLANG_RETURN_ON_FAIL(binding.setNewBuffer(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int), buffer )); - buffers[entryIndex] = buffer; - break; - } - } - if (shape & SLANG_TEXTURE_ARRAY_FLAG) - { - - } - if (shape & SLANG_TEXTURE_MULTISAMPLE_FLAG) - { - - } - - break; - } - } - } - } - - SlangUInt numThreadsPerAxis[3]; - entryPoint->getComputeThreadGroupSize(3, numThreadsPerAxis); - - { - UniformState* uniformState = (UniformState*)binding.m_rootBuffer.m_data; - CPPPrelude::UniformEntryPointParams* params = (CPPPrelude::UniformEntryPointParams*)binding.m_entryPointBuffer.m_data; - - CPPPrelude::ComputeVaryingInput varying; - varying.groupID = {}; - - for (int z = 0; z < int(numThreadsPerAxis[2]); ++z) - { - varying.groupThreadID.z = z; - for (int y = 0; y < int(numThreadsPerAxis[1]); ++y) - { - varying.groupThreadID.y = y; - for (int x = 0; x < int(numThreadsPerAxis[0]); ++x) - { - varying.groupThreadID.x = x; - - func(&varying, params, uniformState); - } - } - } - } - - // Dump everything out that was write (we wrote in place!) - return _writeBindings(layout, buffers, gOptions.outputPath); -} - SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input) { SLANG_RETURN_ON_FAIL(_initializeShaders(session, renderer, shaderType, input)); @@ -769,10 +335,10 @@ SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer, Result RenderTestApp::_initializeShaders(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input) { - CompileOutput output; - SLANG_RETURN_ON_FAIL(_compile(session, gOptions.sourcePath, shaderType, input, output)); + ShaderCompilerUtil::OutputAndLayout output; + SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions.sourcePath, shaderType, input, output)); m_shaderInputLayout = output.layout; - m_shaderProgram = renderer->createProgram(output.compileOutput.desc); + m_shaderProgram = renderer->createProgram(output.output.desc); return m_shaderProgram ? SLANG_OK : SLANG_FAIL; } @@ -1024,8 +590,15 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe if (!renderer) { - SLANG_RETURN_ON_FAIL(_doCPUCompute(session, gOptions.sourcePath, gOptions.shaderType, input)); - return SLANG_OK; + ShaderCompilerUtil::OutputAndLayout compilationAndLayout; + SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions.sourcePath, gOptions.shaderType, input, compilationAndLayout)); + + CPUComputeUtil::Context context; + SLANG_RETURN_ON_FAIL(CPUComputeUtil::calcBindings(compilationAndLayout, context)); + SLANG_RETURN_ON_FAIL(CPUComputeUtil::execute(compilationAndLayout, context)); + + // Dump everything out that was written + return CPUComputeUtil::writeBindings(compilationAndLayout.layout, context.buffers, gOptions.outputPath); } { diff --git a/tools/render-test/render-test-tool.vcxproj b/tools/render-test/render-test-tool.vcxproj index 0399d67e0..3e0c0ae56 100644 --- a/tools/render-test/render-test-tool.vcxproj +++ b/tools/render-test/render-test-tool.vcxproj @@ -179,6 +179,7 @@ </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> + <ClInclude Include="cpu-compute-util.h" /> <ClInclude Include="cpu-memory-binding.h" /> <ClInclude Include="options.h" /> <ClInclude Include="png-serialize-util.h" /> @@ -187,6 +188,7 @@ <ClInclude Include="slang-support.h" /> </ItemGroup> <ItemGroup> + <ClCompile Include="cpu-compute-util.cpp" /> <ClCompile Include="cpu-memory-binding.cpp" /> <ClCompile Include="options.cpp" /> <ClCompile Include="png-serialize-util.cpp" /> diff --git a/tools/render-test/render-test-tool.vcxproj.filters b/tools/render-test/render-test-tool.vcxproj.filters index 43767fc8d..769d53aed 100644 --- a/tools/render-test/render-test-tool.vcxproj.filters +++ b/tools/render-test/render-test-tool.vcxproj.filters @@ -9,6 +9,9 @@ </Filter> </ItemGroup> <ItemGroup> + <ClInclude Include="cpu-compute-util.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="cpu-memory-binding.h"> <Filter>Header Files</Filter> </ClInclude> @@ -29,6 +32,9 @@ </ClInclude> </ItemGroup> <ItemGroup> + <ClCompile Include="cpu-compute-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="cpu-memory-binding.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp index 810e31c2c..7f75805e9 100644 --- a/tools/render-test/shader-input-layout.cpp +++ b/tools/render-test/shader-input-layout.cpp @@ -440,6 +440,23 @@ namespace renderer_test } } + template <typename F> + void _iteratePixels(int dimension, int size, unsigned int * buffer, F f) + { + if (dimension == 1) + for (int i = 0; i < size; i++) + buffer[i] = f(i, 0, 0); + else if (dimension == 2) + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + buffer[i*size + j] = f(j, i, 0); + else if (dimension == 3) + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + for (int k = 0; k < size; k++) + buffer[i*size*size + j * size + k] = f(k, j, i); + }; + void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& inputDesc) { int arrLen = inputDesc.arrayLength; @@ -453,21 +470,6 @@ namespace renderer_test output.textureSize = inputDesc.size; output.mipLevels = Math::Log2Floor(output.textureSize) + 1; output.dataBuffer.setCount(output.mipLevels * output.arraySize); - auto iteratePixels = [&](int dimension, int size, unsigned int * buffer, auto f) - { - if (dimension == 1) - for (int i = 0; i < size; i++) - buffer[i] = f(i, 0, 0); - else if (dimension == 2) - for (int i = 0; i < size; i++) - for (int j = 0; j < size; j++) - buffer[i*size + j] = f(j, i, 0); - else if (dimension == 3) - for (int i = 0; i < size; i++) - for (int j = 0; j < size; j++) - for (int k = 0; k < size; k++) - buffer[i*size*size + j*size + k] = f(k, j, i); - }; int slice = 0; for (int i = 0; i < arraySize; i++) @@ -482,7 +484,7 @@ namespace renderer_test bufferLen *= size*size; dataBuffer[slice].setCount(bufferLen); - iteratePixels(inputDesc.dimension, size, dataBuffer[slice].getBuffer(), [&](int x, int y, int z) -> unsigned int + _iteratePixels(inputDesc.dimension, size, dataBuffer[slice].getBuffer(), [&](int x, int y, int z) -> unsigned int { if (inputDesc.content == InputTextureContent::Zero) { diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp index 230f78453..df7e91df8 100644 --- a/tools/render-test/slang-support.cpp +++ b/tools/render-test/slang-support.cpp @@ -10,6 +10,12 @@ #include <stdio.h> namespace renderer_test { +using namespace Slang; + +// Entry point name to use for vertex/fragment shader +static const char vertexEntryPointName[] = "vertexMain"; +static const char fragmentEntryPointName[] = "fragmentMain"; +static const char computeEntryPointName[] = "computeMain"; /* static */ SlangResult ShaderCompilerUtil::compileProgram(SlangSession* session, const Input& input, const ShaderCompileRequest& request, Output& out) { @@ -138,7 +144,9 @@ namespace renderer_test { { fprintf(stderr, "%s", diagnostics); } - if (SLANG_SUCCEEDED(res)) + + SLANG_RETURN_ON_FAIL(res); + { size_t codeSize = 0; char const* code = (char const*) spGetEntryPointCode(slangRequest, computeEntryPoint, &codeSize); @@ -166,7 +174,9 @@ namespace renderer_test { // OutputDebugStringA(diagnostics); fprintf(stderr, "%s", diagnostics); } - if (SLANG_SUCCEEDED(res)) + + SLANG_RETURN_ON_FAIL(res); + { size_t vertexCodeSize = 0; char const* vertexCode = (char const*) spGetEntryPointCode(slangRequest, vertexEntryPoint, &vertexCodeSize); @@ -193,4 +203,79 @@ namespace renderer_test { return SLANG_OK; } +/* static */SlangResult ShaderCompilerUtil::readSource(const String& inSourcePath, List<char>& outSourceText) +{ + // Read in the source code + FILE* sourceFile = fopen(inSourcePath.getBuffer(), "rb"); + if (!sourceFile) + { + fprintf(stderr, "error: failed to open '%s' for reading\n", inSourcePath.getBuffer()); + return SLANG_FAIL; + } + fseek(sourceFile, 0, SEEK_END); + size_t sourceSize = ftell(sourceFile); + fseek(sourceFile, 0, SEEK_SET); + + outSourceText.setCount(sourceSize + 1); + fread(outSourceText.getBuffer(), sourceSize, 1, sourceFile); + fclose(sourceFile); + outSourceText[sourceSize] = 0; + + return SLANG_OK; +} + +/* static */SlangResult ShaderCompilerUtil::compileWithLayout(SlangSession* session, const String& sourcePath, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input, OutputAndLayout& output) +{ + List<char> sourceText; + SLANG_RETURN_ON_FAIL(readSource(sourcePath, sourceText)); + + output.sourcePath = sourcePath; + + auto& layout = output.layout; + + // Default the amount of renderTargets based on shader type + switch (shaderType) + { + default: + layout.numRenderTargets = 1; + break; + + case Options::ShaderProgramType::Compute: + layout.numRenderTargets = 0; + break; + } + + // Parse the layout + layout.parse(sourceText.getBuffer()); + layout.updateForTarget(input.target); + + // Setup SourceInfo + ShaderCompileRequest::SourceInfo sourceInfo; + sourceInfo.path = sourcePath.getBuffer(); + sourceInfo.dataBegin = sourceText.getBuffer(); + // Subtract 1 because it's zero terminated + sourceInfo.dataEnd = sourceText.getBuffer() + sourceText.getCount() - 1; + + ShaderCompileRequest compileRequest; + compileRequest.source = sourceInfo; + if (shaderType == Options::ShaderProgramType::Graphics || shaderType == Options::ShaderProgramType::GraphicsCompute) + { + compileRequest.vertexShader.source = sourceInfo; + compileRequest.vertexShader.name = vertexEntryPointName; + compileRequest.fragmentShader.source = sourceInfo; + compileRequest.fragmentShader.name = fragmentEntryPointName; + } + else + { + compileRequest.computeShader.source = sourceInfo; + compileRequest.computeShader.name = computeEntryPointName; + } + compileRequest.globalGenericTypeArguments = layout.globalGenericTypeArguments; + compileRequest.entryPointGenericTypeArguments = layout.entryPointGenericTypeArguments; + compileRequest.globalExistentialTypeArguments = layout.globalExistentialTypeArguments; + compileRequest.entryPointExistentialTypeArguments = layout.entryPointExistentialTypeArguments; + + return ShaderCompilerUtil::compileProgram(session, input, compileRequest, output.output); +} + } // renderer_test diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h index 662098546..543ab3258 100644 --- a/tools/render-test/slang-support.h +++ b/tools/render-test/slang-support.h @@ -6,6 +6,7 @@ #include <slang.h> #include "shader-input-layout.h" +#include "options.h" namespace renderer_test { @@ -33,6 +34,12 @@ struct ShaderCompilerUtil } void reset() { + { + desc.pipelineType = PipelineType::Unknown; + desc.kernels = nullptr; + desc.kernelCount = 0; + } + kernelDescs.clear(); if (request && session) { @@ -52,8 +59,20 @@ struct ShaderCompilerUtil ShaderProgram::Desc desc; SlangCompileRequest* request = nullptr; SlangSession* session = nullptr; + }; + struct OutputAndLayout + { + Output output; + ShaderInputLayout layout; + Slang::String sourcePath; + }; + + static SlangResult compileWithLayout(SlangSession* session, const Slang::String& sourcePath, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input, OutputAndLayout& output); + + static SlangResult readSource(const Slang::String& inSourcePath, List<char>& outSourceText); + static SlangResult compileProgram(SlangSession* session, const Input& input, const ShaderCompileRequest& request, Output& out); }; diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index af78dbb14..3b14b353b 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -607,7 +607,7 @@ static SlangResult _extractRenderTestRequirements(const CommandLine& cmdLine, Te // to render-test what renderer will be used. // That a similar logic has to be kept inside the implementation of render-test and both this // and render-test will have to be kept in sync. - + bool useDxil = cmdLine.findArgIndex(UnownedStringSlice::fromLiteral("-use-dxil")) >= 0; bool usePassthru = false; @@ -751,11 +751,26 @@ static SlangResult _extractReflectionTestRequirements(const CommandLine& cmdLine return SLANG_OK; } +static SlangResult _tryUseCPURenderTest(TestContext* context, CommandLine& ioCmdLine) +{ + String exeName = Path::getFileNameWithoutExt(ioCmdLine.m_executable); + + if (exeName == "render-test") + { + bool useCPU = ioCmdLine.findArgIndex(UnownedStringSlice::fromLiteral("-cpu")) >= 0; + if (useCPU) + { + ioCmdLine.setExecutablePath(Path::combine(context->options.binDir, String("cpu-render-test") + ProcessUtil::getExecutableSuffix())); + } + } + return SLANG_OK; +} + static SlangResult _extractTestRequirements(const CommandLine& cmdLine, TestRequirements* ioInfo) { String exeName = Path::getFileNameWithoutExt(cmdLine.m_executable); - if (exeName == "render-test") + if (exeName == "render-test" || exeName == "cpu-render-test") { return _extractRenderTestRequirements(cmdLine, ioInfo); } @@ -787,10 +802,11 @@ static RenderApiFlags _getAvailableRenderApiFlags(TestContext* context) if (apiType == RenderApiType::CPU) { - // TODO(JS): Only enable CPU on Windows for now -#if SLANG_WINDOWS_FAMILY - availableRenderApiFlags |= RenderApiFlags(1) << int(apiType); -#endif + // Check that the session has the generic C/CPP compiler availability - which is all we should need for CPU target + if (SLANG_SUCCEEDED(spSessionCheckPassThroughSupport(context->getSession(), SLANG_PASS_THROUGH_GENERIC_C_CPP))) + { + availableRenderApiFlags |= RenderApiFlags(1) << int(apiType); + } continue; } @@ -809,6 +825,8 @@ static RenderApiFlags _getAvailableRenderApiFlags(TestContext* context) builder << "-" << RenderApiUtil::getApiName(apiType); cmdLine.addArg(builder); + _tryUseCPURenderTest(context, cmdLine); + // Run the render-test tool and see if the device could startup ExecuteResult exeRes; if (SLANG_SUCCEEDED(spawnAndWaitSharedLibrary(context, "device-startup", cmdLine, exeRes)) @@ -2046,6 +2064,8 @@ TestResult runComputeComparisonImpl(TestContext* context, TestInput& input, cons auto actualOutputFile = outputStem + ".actual.txt"; cmdLine.addArg(actualOutputFile); + _tryUseCPURenderTest(context, cmdLine); + if (context->isExecuting()) { // clear the stale actual output file first. This will allow us to detect error if render-test fails and outputs nothing. @@ -2161,6 +2181,8 @@ TestResult doRenderComparisonTestRun(TestContext* context, TestInput& input, cha cmdLine.addArg("-o"); cmdLine.addArg(outputStem + outputKind + ".png"); + _tryUseCPURenderTest(context, cmdLine); + ExecuteResult exeRes; TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes)); |
