diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2016-08-20 06:35:47 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2016-08-20 06:35:47 +0000 |
| commit | 2b64f003622ee7871fd7aec041622427dd2fc88f (patch) | |
| tree | 893dab48c6d0e7121e047d8d3bb6d5bf172ce2d5 /Graphics | |
| parent | Release v1.0.0 (diff) | |
| download | DiligentCore-2b64f003622ee7871fd7aec041622427dd2fc88f.tar.gz DiligentCore-2b64f003622ee7871fd7aec041622427dd2fc88f.zip | |
Updated to Diligent Engine 2.0
Diffstat (limited to 'Graphics')
373 files changed, 28573 insertions, 7953 deletions
diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj b/Graphics/GraphicsEngine/build/UWP/GraphicsEngine.vcxproj index 7a0d8593..883c9e2f 100644 --- a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj +++ b/Graphics/GraphicsEngine/build/UWP/GraphicsEngine.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|ARM"> <Configuration>Debug</Configuration> @@ -27,88 +27,89 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{9df5553c-ca9d-4cb6-a06a-ca905119c00b}</ProjectGuid> + <ProjectGuid>{dfe6435d-cc9d-4ca1-bf4e-5640c522d815}</ProjectGuid> + <Keyword>StaticLibrary</Keyword> <RootNamespace>GraphicsEngine</RootNamespace> <DefaultLanguage>en-US</DefaultLanguage> - <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> <AppContainerApplication>true</AppContainerApplication> <ApplicationType>Windows Store</ApplicationType> - <ApplicationTypeRevision>8.1</ApplicationTypeRevision> - <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + <WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion> + <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion> + <ApplicationTypeRevision>10.0</ApplicationTypeRevision> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="..\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + <Import Project="..\Windows.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" /> + </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmDbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmRel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <GenerateManifest>false</GenerateManifest> </PropertyGroup> @@ -129,10 +130,8 @@ </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> - <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> </ClCompile> <Link> <SubSystem>Console</SubSystem> @@ -142,10 +141,8 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> - <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> </ClCompile> <Link> <SubSystem>Console</SubSystem> @@ -155,10 +152,8 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> - <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> </ClCompile> <Link> <SubSystem>Console</SubSystem> @@ -168,10 +163,8 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> - <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> </ClCompile> <Link> <SubSystem>Console</SubSystem> @@ -181,7 +174,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -193,7 +185,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> diff --git a/Graphics/GraphicsEngine/build/UWP/GraphicsEngine.vcxproj.filters b/Graphics/GraphicsEngine/build/UWP/GraphicsEngine.vcxproj.filters new file mode 100644 index 00000000..c31757ec --- /dev/null +++ b/Graphics/GraphicsEngine/build/UWP/GraphicsEngine.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/Android/gcc_Debug.h b/Graphics/GraphicsEngine/build/Win32/Android/gcc_Debug.h index da574716..da574716 100644 --- a/Graphics/GraphicsEngine/build/Windows/Android/gcc_Debug.h +++ b/Graphics/GraphicsEngine/build/Win32/Android/gcc_Debug.h diff --git a/Graphics/GraphicsEngine/build/Windows/Android/gcc_Release.h b/Graphics/GraphicsEngine/build/Win32/Android/gcc_Release.h index da574716..da574716 100644 --- a/Graphics/GraphicsEngine/build/Windows/Android/gcc_Release.h +++ b/Graphics/GraphicsEngine/build/Win32/Android/gcc_Release.h diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Debug.vgdbsettings b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine-Debug.vgdbsettings index 3f5b24b1..3f5b24b1 100644 --- a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Debug.vgdbsettings +++ b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine-Debug.vgdbsettings diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Release.vgdbsettings b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine-Release.vgdbsettings index 669691f2..669691f2 100644 --- a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine-Release.vgdbsettings +++ b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine-Release.vgdbsettings diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine.vcxproj index 34dfc85e..f2e38dc4 100644 --- a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj +++ b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine.vcxproj @@ -69,31 +69,27 @@ </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> - <Import Project="..\WindowsStore\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" Condition="Exists('..\WindowsStore\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems')" /> + <Import Project="..\Windows.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" Condition="Exists('..\Windows.Shared\GraphicsEngine.Shared.vcxitems')" /> </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" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngine.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngine.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </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" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngine.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngine.props" /> + <Import Project="..\Windows.Shared\GraphicsEngine.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <Import Project="..\..\..\..\Shared\build\Windows\Android32d.props" /> @@ -114,7 +110,6 @@ </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -125,7 +120,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -139,7 +133,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> @@ -154,7 +147,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> @@ -175,6 +167,12 @@ <None Include="jni\Application.mk" /> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\src\EngineMemory.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\src\ResourceMapping.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj.filters b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine.vcxproj.filters index f9817491..6bcb0a74 100644 --- a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.vcxproj.filters +++ b/Graphics/GraphicsEngine/build/Win32/GraphicsEngine.vcxproj.filters @@ -23,5 +23,8 @@ <ClCompile Include="..\..\src\Texture.cpp"> <Filter>android_src</Filter> </ClCompile> + <ClCompile Include="..\..\src\EngineMemory.cpp"> + <Filter>android_src</Filter> + </ClCompile> </ItemGroup> </Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/jni/Android.mk b/Graphics/GraphicsEngine/build/Win32/jni/Android.mk index 5d40b9a3..a2975140 100644 --- a/Graphics/GraphicsEngine/build/Windows/jni/Android.mk +++ b/Graphics/GraphicsEngine/build/Win32/jni/Android.mk @@ -19,6 +19,6 @@ LOCAL_C_INCLUDES := $(PROJECT_ROOT)/include $(PROJECT_ROOT)/interface $(SOLUTION # Source files #VisualGDBAndroid: AutoUpdateSourcesInNextLine -LOCAL_SRC_FILES := ../../../src/ResourceMapping.cpp ../../../src/Texture.cpp +LOCAL_SRC_FILES := ../../../src/EngineMemory.cpp ../../../src/ResourceMapping.cpp ../../../src/Texture.cpp include $(BUILD_STATIC_LIBRARY) diff --git a/Graphics/GraphicsEngine/build/Windows/jni/Application.mk b/Graphics/GraphicsEngine/build/Win32/jni/Application.mk index 45f02b20..45f02b20 100644 --- a/Graphics/GraphicsEngine/build/Windows/jni/Application.mk +++ b/Graphics/GraphicsEngine/build/Win32/jni/Application.mk diff --git a/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.Shared.vcxitems b/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.Shared.vcxitems new file mode 100644 index 00000000..b388caf2 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.Shared.vcxitems @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{0cdd843c-089d-4fee-be9f-c08fa2b51acb}</ItemsProjectGuid> + <ItemsRootNamespace>GraphicsEngine</ItemsRootNamespace> + <ItemsProjectName>GraphicsEngine.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\EngineMemory.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ResourceMapping.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferViewBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Defines.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceContextBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceObjectBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\EngineMemory.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\PipelineStateBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ResourceMappingImpl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SamplerBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceBindingBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\StateObjectsRegistry.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SwapChainBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureViewBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BlendState.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Buffer.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferView.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\CommandList.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Constants.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DepthStencilState.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceCaps.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceContext.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceObject.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\MapHelper.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\PipelineState.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RasterizerState.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDevice.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ResourceMapping.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Sampler.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Shader.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderResourceBinding.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SwapChain.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Texture.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureView.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\GraphicsTypes.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\InputLayout.h" /> + </ItemGroup> + <ItemGroup> + <Text Include="$(MSBuildThisFileDirectory)..\..\CMakeLists.txt"> + <DeploymentContent>false</DeploymentContent> + </Text> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.Shared.vcxitems.filters b/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.Shared.vcxitems.filters new file mode 100644 index 00000000..4a458938 --- /dev/null +++ b/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.Shared.vcxitems.filters @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{32eded03-121f-406a-8a23-6721ca9116ee}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{d881c412-cc78-41fb-997c-0d6543c1e477}</UniqueIdentifier> + </Filter> + <Filter Include="interface"> + <UniqueIdentifier>{c38a8d65-5100-44be-b1a5-453d901c892f}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ResourceMapping.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\EngineMemory.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceObjectBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ResourceMappingImpl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SamplerBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\StateObjectsRegistry.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureViewBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferViewBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Defines.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceContextBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DepthStencilState.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceCaps.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceContext.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceObject.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\MapHelper.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RasterizerState.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDevice.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ResourceMapping.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Sampler.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Shader.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Texture.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureView.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BlendState.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Buffer.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferView.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\Constants.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SwapChain.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SwapChainBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\GraphicsTypes.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\PipelineState.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\PipelineStateBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\InputLayout.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderResourceBinding.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceBindingBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\EngineMemory.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\CommandList.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListBase.h"> + <Filter>include</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Text Include="$(MSBuildThisFileDirectory)..\..\CMakeLists.txt" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/EngineRoot.props b/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.props index 6e4b958b..53a6cd34 100644 --- a/Graphics/GraphicsTools/build/Windows/EngineRoot.props +++ b/Graphics/GraphicsEngine/build/Windows.Shared/GraphicsEngine.props @@ -5,7 +5,9 @@ <EngineRoot>..\..\..\..</EngineRoot> <GraphicsRoot>..\..\..</GraphicsRoot> </PropertyGroup> - <PropertyGroup /> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath)</IncludePath> + </PropertyGroup> <ItemDefinitionGroup /> <ItemGroup> <BuildMacro Include="EngineRoot"> diff --git a/Graphics/GraphicsEngine/build/Windows/EngineRoot.props b/Graphics/GraphicsEngine/build/Windows/EngineRoot.props deleted file mode 100644 index 6e4b958b..00000000 --- a/Graphics/GraphicsEngine/build/Windows/EngineRoot.props +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros"> - <EngineRoot>..\..\..\..</EngineRoot> - <GraphicsRoot>..\..\..</GraphicsRoot> - </PropertyGroup> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup> - <BuildMacro Include="EngineRoot"> - <Value>$(EngineRoot)</Value> - </BuildMacro> - <BuildMacro Include="GraphicsRoot"> - <Value>$(GraphicsRoot)</Value> - </BuildMacro> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.props b/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.props deleted file mode 100644 index f5ff61e5..00000000 --- a/Graphics/GraphicsEngine/build/Windows/GraphicsEngine.props +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <IncludePath>$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath)</IncludePath> - </PropertyGroup> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/EngineRoot.props b/Graphics/GraphicsEngine/build/WindowsStore/EngineRoot.props deleted file mode 100644 index fcb891c0..00000000 --- a/Graphics/GraphicsEngine/build/WindowsStore/EngineRoot.props +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros"> - <EngineRoot>..\..\..\..\..</EngineRoot> - <GraphicsRoot>..\..\..\..</GraphicsRoot> - </PropertyGroup> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup> - <BuildMacro Include="EngineRoot"> - <Value>$(EngineRoot)</Value> - </BuildMacro> - <BuildMacro Include="GraphicsRoot"> - <Value>$(GraphicsRoot)</Value> - </BuildMacro> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems deleted file mode 100644 index e8d4f5a7..00000000 --- a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup Label="Globals"> - <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> - <HasSharedItems>true</HasSharedItems> - <ItemsProjectGuid>{0cdd843c-089d-4fee-be9f-c08fa2b51acb}</ItemsProjectGuid> - <ItemsRootNamespace>GraphicsEngine</ItemsRootNamespace> - <ItemsProjectName>GraphicsEngine.Shared</ItemsProjectName> - <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ProjectCapability Include="SourceItemsFromImports" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ResourceMapping.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Defines.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DepthStencilStateBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceObjectBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ResourceMappingImpl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\StateObjectsRegistry.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescriptionBase.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendState.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Buffer.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferView.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Constants.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilState.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceCaps.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContext.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceObject.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\MapHelper.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerState.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDevice.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ResourceMapping.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Sampler.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Shader.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChain.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Texture.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureView.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\GraphicsTypes.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescription.h" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems.filters b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems.filters deleted file mode 100644 index 8014c299..00000000 --- a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Shared/GraphicsEngine.Shared.vcxitems.filters +++ /dev/null @@ -1,138 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="include"> - <UniqueIdentifier>{32eded03-121f-406a-8a23-6721ca9116ee}</UniqueIdentifier> - </Filter> - <Filter Include="src"> - <UniqueIdentifier>{d881c412-cc78-41fb-997c-0d6543c1e477}</UniqueIdentifier> - </Filter> - <Filter Include="interface"> - <UniqueIdentifier>{c38a8d65-5100-44be-b1a5-453d901c892f}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ResourceMapping.cpp"> - <Filter>src</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceObjectBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ResourceMappingImpl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\StateObjectsRegistry.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescriptionBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Defines.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DepthStencilStateBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilState.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceCaps.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContext.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceObject.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\MapHelper.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerState.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDevice.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ResourceMapping.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Sampler.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Shader.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Texture.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureView.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescription.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendState.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Buffer.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferView.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\Constants.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChain.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainBase.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\GraphicsTypes.h"> - <Filter>interface</Filter> - </ClInclude> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj.filters b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj.filters deleted file mode 100644 index a7761ab0..00000000 --- a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.Windows/GraphicsEngine.Windows.vcxproj.filters +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - </ItemGroup> -</Project> diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj.filters b/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj.filters deleted file mode 100644 index a7761ab0..00000000 --- a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj.filters +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - </ItemGroup> -</Project> diff --git a/Graphics/GraphicsEngine/include/BlendStateBase.h b/Graphics/GraphicsEngine/include/BlendStateBase.h deleted file mode 100644 index 78494b46..00000000 --- a/Graphics/GraphicsEngine/include/BlendStateBase.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Implementation of the Diligent::BlendStateBase template class - -#include "BlendState.h" -#include "DeviceObjectBase.h" - -namespace Diligent -{ - -/// Template class implementing base functionality for a blend state object. - -/// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::IBlendStateD3D11 or Diligent::IBlendStateGL). -/// \tparam RenderDeviceBaseInterface - base interface for the render device -/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, -/// or Diligent::IRenderDeviceGLES). -template<class BaseInterface = IBlendState, class RenderDeviceBaseInterface = IRenderDevice> -class BlendStateBase : public DeviceObjectBase<BaseInterface, BlendStateDesc> -{ -public: - typedef DeviceObjectBase<BaseInterface, BlendStateDesc> TDeviceObjectBase; - typedef RenderDeviceBase < RenderDeviceBaseInterface > TRenderDeviceBase; - - /// \param pDevice - pointer to the device. - /// \param BSDesc - blend state description. - /// \param bIsDeviceInternal - flag indicating if the blend state is an internal device object and - /// must not keep a strong reference to the device. - BlendStateBase( IRenderDevice *pDevice, const BlendStateDesc& BSDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, BSDesc, nullptr, bIsDeviceInternal ) - { - } - - ~BlendStateBase() - { - /// \note Destructor cannot directly remove the object from the registry as this may cause a - /// deadlock at the point where StateObjectsRegistry::Find() locks the weak pointer: if we - /// are in dtor, the object is locked by Diligent::RefCountedObject::Release() and - /// StateObjectsRegistry::Find() will wait for that lock to be released. - /// A the same time this thread will be waiting for the other thread to unlock the registry.\n - /// Thus destructor only notifies the registry that there is a deleted object. - /// The reference to the object will be removed later. - auto &BlendStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetBSRegistry(); - // StateObjectsRegistry::ReportDeletedObject() does not lock the registry, but only - // atomically increments the outstanding deleted objects counter. - BlendStateRegistry.ReportDeletedObject(); - } - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_BlendState, TDeviceObjectBase ) -}; - -} diff --git a/Graphics/GraphicsEngine/include/BufferBase.h b/Graphics/GraphicsEngine/include/BufferBase.h index 43b07662..ded3bbc3 100644 --- a/Graphics/GraphicsEngine/include/BufferBase.h +++ b/Graphics/GraphicsEngine/include/BufferBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ #include "Buffer.h" #include "DeviceObjectBase.h" #include "GraphicsUtilities.h" +#include "STDAllocator.h" #include <memory> namespace Diligent @@ -37,22 +38,39 @@ namespace Diligent /// Template class implementing base functionality for a buffer object /// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::IBufferD3D11 or Diligent::IBufferGL). +/// (Diligent::IBufferD3D11, Diligent::IBufferD3D12 or Diligent::IBufferGL). /// \tparam BufferViewImplType - type of the buffer view implementation -/// (Diligent::BufferViewD3D11Impl or Diligent::BufferVeiwGLImpl) -template<class BaseInterface, class BufferViewImplType> -class BufferBase : public DeviceObjectBase < BaseInterface, BufferDesc > +/// (Diligent::BufferViewD3D11Impl, Diligent::BufferViewD3D12Impl or Diligent::BufferViewGLImpl) +/// \tparam TBuffObjAllocator - type of the allocator that is used to allocate memory for the buffer object instances +/// \tparam TBuffViewObjAllocator - type of the allocator that is used to allocate memory for the buffer view object instances +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +class BufferBase : public DeviceObjectBase < BaseInterface, BufferDesc, TBuffObjAllocator > { public: - typedef DeviceObjectBase<BaseInterface, BufferDesc> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, BufferDesc, TBuffObjAllocator> TDeviceObjectBase; + /// \param BuffObjAllocator - allocator that was used to allocate memory for this instance of the buffer object. + /// \param BuffViewObjAllocator - allocator that is used to allocate memory for the buffer view instances. + /// This parameter is only used for debug purposes. /// \param pDevice - pointer to the device. /// \param BuffDesc - buffer description. /// \param bIsDeviceInternal - flag indicating if the buffer is an internal device object and /// must not keep a strong reference to the device. - BufferBase( IRenderDevice *pDevice, const BufferDesc& BuffDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, BuffDesc, nullptr, bIsDeviceInternal ) + BufferBase( TBuffObjAllocator &BuffObjAllocator, + TBuffViewObjAllocator &BuffViewObjAllocator, + IRenderDevice *pDevice, + const BufferDesc& BuffDesc, + bool bIsDeviceInternal = false ) : + TDeviceObjectBase( BuffObjAllocator, pDevice, BuffDesc, nullptr, bIsDeviceInternal ), +#ifdef _DEBUG + m_dbgBuffViewAllocator(BuffViewObjAllocator), +#endif + m_pDefaultUAV(nullptr, STDDeleter<BufferViewImplType, TBuffViewObjAllocator>(BuffViewObjAllocator) ), + m_pDefaultSRV(nullptr, STDDeleter<BufferViewImplType, TBuffViewObjAllocator>(BuffViewObjAllocator) ) { +#define VERIFY_BUFFER(Expr, ...) VERIFY(Expr, "Buffer \"", this->m_Desc.Name ? this->m_Desc.Name : "", "\": ", ##__VA_ARGS__) + +#ifdef _DEBUG Uint32 AllowedBindFlags = BIND_VERTEX_BUFFER | BIND_INDEX_BUFFER | BIND_UNIFORM_BUFFER | BIND_SHADER_RESOURCE | BIND_STREAM_OUTPUT | BIND_UNORDERED_ACCESS | @@ -62,142 +80,162 @@ public: "BIND_SHADER_RESOURCE (8), BIND_STREAM_OUTPUT (16), BIND_UNORDERED_ACCESS (128), " "BIND_INDIRECT_DRAW_ARGS (256)"; -#define VERIFY_BUFFER(Expr, ...) VERIFY(Expr, "Buffer \"", m_Desc.Name ? m_Desc.Name : "", "\": ", ##__VA_ARGS__) - VERIFY_BUFFER( (BuffDesc.BindFlags & ~AllowedBindFlags) == 0, "Incorrect bind flags specified (", BuffDesc.BindFlags & ~AllowedBindFlags, "). Only the following flags are allowed:\n", strAllowedBindFlags ); - - m_Desc = BuffDesc; - if( (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || - (m_Desc.BindFlags & BIND_SHADER_RESOURCE) ) +#endif + + if( (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || + (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE) ) { - VERIFY_BUFFER( m_Desc.Mode > BUFFER_MODE_UNDEFINED && m_Desc.Mode < BUFFER_MODE_NUM_MODES, "Buffer mode (", m_Desc.Mode, ") is not correct" ); - if( m_Desc.Mode == BUFFER_MODE_STRUCTURED ) + VERIFY_BUFFER( this->m_Desc.Mode > BUFFER_MODE_UNDEFINED && this->m_Desc.Mode < BUFFER_MODE_NUM_MODES, "Buffer mode (", this->m_Desc.Mode, ") is not correct" ); + if( this->m_Desc.Mode == BUFFER_MODE_STRUCTURED ) { - VERIFY_BUFFER( m_Desc.ElementByteStride != 0, "Element stride cannot be zero for structured buffer" ); + VERIFY_BUFFER( this->m_Desc.ElementByteStride != 0, "Element stride cannot be zero for structured buffer" ); } - if( m_Desc.Mode == BUFFER_MODE_FORMATED ) + if( this->m_Desc.Mode == BUFFER_MODE_FORMATED ) { - VERIFY_BUFFER( m_Desc.Format.ValueType != VT_UNDEFINED, "Value type is not specified for a formated buffer" ); - VERIFY_BUFFER( m_Desc.Format.NumComponents != 0, "Num components cannot be zero in a formated buffer" ); - if( m_Desc.ElementByteStride == 0 ) - m_Desc.ElementByteStride = static_cast<Uint32>(GetValueSize( m_Desc.Format.ValueType )) * m_Desc.Format.NumComponents; + VERIFY_BUFFER( this->m_Desc.Format.ValueType != VT_UNDEFINED, "Value type is not specified for a formated buffer" ); + VERIFY_BUFFER( this->m_Desc.Format.NumComponents != 0, "Num components cannot be zero in a formated buffer" ); + if( this->m_Desc.ElementByteStride == 0 ) + this->m_Desc.ElementByteStride = static_cast<Uint32>(GetValueSize( this->m_Desc.Format.ValueType )) * this->m_Desc.Format.NumComponents; } } } IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Buffer, TDeviceObjectBase ) + /// Base implementation of IBuffer::UpdateData(); validates input parameters. virtual void UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData )override = 0; + /// Base implementation of IBuffer::CopyData(); validates input parameters. virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override = 0; + /// Base implementation of IBuffer::Map(); validates input parameters. virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; - virtual void Unmap( IDeviceContext *pContext )override = 0; + /// Base implementation of IBuffer::Unmap() + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override = 0; + /// Implementation of IBuffer::CreateView(); calls CreateViewInternal() virtual function + /// that creates buffer view for the specific engine implementation. virtual void CreateView( const struct BufferViewDesc &ViewDesc, IBufferView **ppView )override; + /// Implementation of IBuffer::GetDefaultView(). virtual IBufferView* GetDefaultView( BUFFER_VIEW_TYPE ViewType )override; + /// Creates default buffer views. + + /// + /// - Creates default shader resource view addressing the entire buffer if Diligent::BIND_SHADER_RESOURCE flag is set + /// - Creates default unordered access view addressing the entire buffer if Diligent::BIND_UNORDERED_ACCESS flag is set + /// + /// The function calls CreateViewInternal(). void CreateDefaultViews(); protected: + + /// Pure virtual function that creates buffer view for the specific engine implementation. virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView ) = 0; + /// Corrects buffer view description and validates view parameters. void CorrectBufferViewDesc( struct BufferViewDesc &ViewDesc ); - BufferDesc m_Desc; +#ifdef _DEBUG + TBuffViewObjAllocator &m_dbgBuffViewAllocator; +#endif + + /// Default UAV addressing the entire buffer + std::unique_ptr<BufferViewImplType, STDDeleter<BufferViewImplType, TBuffViewObjAllocator> > m_pDefaultUAV; - std::unique_ptr<BufferViewImplType> m_pDefaultUAV; - std::unique_ptr<BufferViewImplType> m_pDefaultSRV; + /// Default SRV addressing the entire buffer + std::unique_ptr<BufferViewImplType, STDDeleter<BufferViewImplType, TBuffViewObjAllocator> > m_pDefaultSRV; }; -template<class BaseInterface, class BufferViewImplType> -void BufferBase<BaseInterface, BufferViewImplType> :: UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData ) +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData ) { - VERIFY_BUFFER( m_Desc.Usage == USAGE_DEFAULT, "Only default usage buffers can be updated with UpdateData()" ); - VERIFY_BUFFER( Offset < m_Desc.uiSizeInBytes, "Offset (", Offset, ") exceeds the buffer size (", m_Desc.uiSizeInBytes, ")" ); - VERIFY_BUFFER( Size + Offset <= m_Desc.uiSizeInBytes, "Update region [", Offset, ",", Size + Offset, ") is out of buffer bounds [0,",m_Desc.uiSizeInBytes,")" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DEFAULT, "Only default usage buffers can be updated with UpdateData()" ); + VERIFY_BUFFER( Offset < this->m_Desc.uiSizeInBytes, "Offset (", Offset, ") exceeds the buffer size (", this->m_Desc.uiSizeInBytes, ")" ); + VERIFY_BUFFER( Size + Offset <= this->m_Desc.uiSizeInBytes, "Update region [", Offset, ",", Size + Offset, ") is out of buffer bounds [0,",this->m_Desc.uiSizeInBytes,")" ); } -template<class BaseInterface, class BufferViewImplType> -void BufferBase<BaseInterface, BufferViewImplType> :: CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size ) +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size ) { - VERIFY_BUFFER( DstOffset + Size <= m_Desc.uiSizeInBytes, "Destination range [", DstOffset, ",", DstOffset + Size, ") is out of buffer bounds [0,",m_Desc.uiSizeInBytes,")" ); - VERIFY_BUFFER( SrcOffset + Size <= pSrcBuffer->GetDesc().uiSizeInBytes, "Source range [", SrcOffset, ",", SrcOffset + Size, ") is out of buffer bounds [0,",m_Desc.uiSizeInBytes,")" ); + VERIFY_BUFFER( DstOffset + Size <= this->m_Desc.uiSizeInBytes, "Destination range [", DstOffset, ",", DstOffset + Size, ") is out of buffer bounds [0,",this->m_Desc.uiSizeInBytes,")" ); + VERIFY_BUFFER( SrcOffset + Size <= pSrcBuffer->GetDesc().uiSizeInBytes, "Source range [", SrcOffset, ",", SrcOffset + Size, ") is out of buffer bounds [0,",this->m_Desc.uiSizeInBytes,")" ); } -template<class BaseInterface, class BufferViewImplType> -void BufferBase<BaseInterface, BufferViewImplType> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) { switch( MapType ) { case MAP_READ: - VERIFY_BUFFER( m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read from" ); - VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading was not created with CPU_ACCESS_READ flag" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read from" ); + VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading was not created with CPU_ACCESS_READ flag" ); break; case MAP_WRITE: - VERIFY_BUFFER( m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be written to" ); - VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for writing was not created with CPU_ACCESS_WRITE flag" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be written to" ); + VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for writing was not created with CPU_ACCESS_WRITE flag" ); break; case MAP_READ_WRITE: - VERIFY_BUFFER( m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read and written" ); - VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_WRITE flag" ); - VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_READ flag" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Only buffers with usage USAGE_CPU_ACCESSIBLE can be read and written" ); + VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_WRITE flag" ); + VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_READ), "Buffer being mapped for reading & writing was not created with CPU_ACCESS_READ flag" ); break; case MAP_WRITE_DISCARD: - VERIFY_BUFFER( m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write discard flag" ); - VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write discard flag" ); + VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); break; case MAP_WRITE_NO_OVERWRITE: - VERIFY_BUFFER( m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write no overwrite flag" ); - VERIFY_BUFFER( (m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); + VERIFY_BUFFER( this->m_Desc.Usage == USAGE_DYNAMIC, "Only dynamic buffers can be mapped with write no overwrite flag" ); + VERIFY_BUFFER( (this->m_Desc.CPUAccessFlags & CPU_ACCESS_WRITE), "Dynamic buffer must be created with CPU_ACCESS_WRITE flag" ); break; default: UNEXPECTED( "Unknown map type" ); } } -template<class BaseInterface, class BufferViewImplType> -void BufferBase<BaseInterface, BufferViewImplType> :: Unmap( IDeviceContext *pContext ) +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) { } -template<class BaseInterface, class BufferViewImplType> -void BufferBase<BaseInterface, BufferViewImplType> :: CreateView( const struct BufferViewDesc &ViewDesc, IBufferView **ppView ) +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CreateView( const struct BufferViewDesc &ViewDesc, IBufferView **ppView ) { CreateViewInternal( ViewDesc, ppView, false ); } -template<class BaseInterface, class BufferViewImplType> -void BufferBase<BaseInterface, BufferViewImplType> :: CorrectBufferViewDesc( struct BufferViewDesc &ViewDesc ) +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CorrectBufferViewDesc( struct BufferViewDesc &ViewDesc ) { if( ViewDesc.ByteWidth == 0 ) - ViewDesc.ByteWidth = m_Desc.uiSizeInBytes; - if( ViewDesc.ByteOffset + ViewDesc.ByteWidth > m_Desc.uiSizeInBytes ) - LOG_ERROR_AND_THROW( "Buffer view range [", ViewDesc.ByteOffset, ", ", ViewDesc.ByteOffset + ViewDesc.ByteWidth, ") is out of the buffer boundaries [0, ", m_Desc.uiSizeInBytes, ")." ); - if( (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || - (m_Desc.BindFlags & BIND_SHADER_RESOURCE) ) + ViewDesc.ByteWidth = this->m_Desc.uiSizeInBytes; + if( ViewDesc.ByteOffset + ViewDesc.ByteWidth > this->m_Desc.uiSizeInBytes ) + LOG_ERROR_AND_THROW( "Buffer view range [", ViewDesc.ByteOffset, ", ", ViewDesc.ByteOffset + ViewDesc.ByteWidth, ") is out of the buffer boundaries [0, ", this->m_Desc.uiSizeInBytes, ")." ); + if( (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || + (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE) ) { - VERIFY( m_Desc.ElementByteStride != 0, "Element byte stride is zero" ); - if( (ViewDesc.ByteOffset % m_Desc.ElementByteStride) != 0 ) - LOG_ERROR_AND_THROW( "Buffer view byte offset (", ViewDesc.ByteOffset, ") is not multiple of element byte stride (", m_Desc.ElementByteStride, ")." ); - if( (ViewDesc.ByteWidth % m_Desc.ElementByteStride) != 0 ) - LOG_ERROR_AND_THROW( "Buffer view byte width (", ViewDesc.ByteWidth, ") is not multiple of element byte stride (", m_Desc.ElementByteStride, ")." ); + VERIFY( this->m_Desc.ElementByteStride != 0, "Element byte stride is zero" ); + if( (ViewDesc.ByteOffset % this->m_Desc.ElementByteStride) != 0 ) + LOG_ERROR_AND_THROW( "Buffer view byte offset (", ViewDesc.ByteOffset, ") is not multiple of element byte stride (", this->m_Desc.ElementByteStride, ")." ); + if( (ViewDesc.ByteWidth % this->m_Desc.ElementByteStride) != 0 ) + LOG_ERROR_AND_THROW( "Buffer view byte width (", ViewDesc.ByteWidth, ") is not multiple of element byte stride (", this->m_Desc.ElementByteStride, ")." ); } } -template<class BaseInterface, class BufferViewImplType> -IBufferView* BufferBase<BaseInterface, BufferViewImplType> ::GetDefaultView( BUFFER_VIEW_TYPE ViewType ) +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +IBufferView* BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> ::GetDefaultView( BUFFER_VIEW_TYPE ViewType ) { switch( ViewType ) { @@ -207,10 +245,10 @@ IBufferView* BufferBase<BaseInterface, BufferViewImplType> ::GetDefaultView( BUF } } -template<class BaseInterface, class BufferViewImplType> -void BufferBase<BaseInterface, BufferViewImplType> :: CreateDefaultViews() +template<class BaseInterface, class BufferViewImplType, class TBuffObjAllocator, class TBuffViewObjAllocator> +void BufferBase<BaseInterface, BufferViewImplType, TBuffObjAllocator, TBuffViewObjAllocator> :: CreateDefaultViews() { - if( m_Desc.BindFlags & BIND_UNORDERED_ACCESS ) + if( this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS ) { BufferViewDesc ViewDesc; ViewDesc.ViewType = BUFFER_VIEW_UNORDERED_ACCESS; @@ -220,7 +258,7 @@ void BufferBase<BaseInterface, BufferViewImplType> :: CreateDefaultViews() VERIFY( m_pDefaultUAV->GetDesc().ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected view type" ); } - if( m_Desc.BindFlags & BIND_SHADER_RESOURCE ) + if( this->m_Desc.BindFlags & BIND_SHADER_RESOURCE ) { BufferViewDesc ViewDesc; ViewDesc.ViewType = BUFFER_VIEW_SHADER_RESOURCE; diff --git a/Graphics/GraphicsEngine/include/BufferViewBase.h b/Graphics/GraphicsEngine/include/BufferViewBase.h index 59ce395a..00eb5008 100644 --- a/Graphics/GraphicsEngine/include/BufferViewBase.h +++ b/Graphics/GraphicsEngine/include/BufferViewBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,27 +37,30 @@ namespace Diligent /// Template class implementing base functionality for a buffer view object /// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::IBufferViewD3D11 or Diligent::IBufferViewGL). -template<class BaseInterface = IBufferView> -class BufferViewBase : public DeviceObjectBase<BaseInterface, BufferViewDesc> +/// (Diligent::IBufferViewD3D11, Diligent::IBufferViewD3D12 or Diligent::IBufferViewGL). +/// \tparam BuffViewObjAllocator - type of the allocator that is used to allocate memory for the buffer view object instances +template<class BaseInterface, class BuffViewObjAllocator> +class BufferViewBase : public DeviceObjectBase<BaseInterface, BufferViewDesc, BuffViewObjAllocator> { public: - typedef DeviceObjectBase<BaseInterface, BufferViewDesc> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, BufferViewDesc, BuffViewObjAllocator> TDeviceObjectBase; + /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the buffer view object /// \param pDevice - pointer to the render device. /// \param ViewDesc - buffer view description. /// \param pBuffer - pointer to the buffer that the view is to be created for. /// \param bIsDefaultView - flag indicating if the view is default view, and is thus /// part of the buffer object. In this case the view will attach /// to the buffer's reference counters. - BufferViewBase( class IRenderDevice *pDevice, + BufferViewBase( BuffViewObjAllocator &ObjAllocator, + class IRenderDevice *pDevice, const BufferViewDesc& ViewDesc, class IBuffer *pBuffer, bool bIsDefaultView ) : // Default views are created as part of the buffer, so we cannot not keep strong // reference to the buffer to avoid cyclic links. Instead, we will attach to the // reference counters of the buffer. - TDeviceObjectBase( pDevice, ViewDesc, bIsDefaultView ? pBuffer : nullptr ), + TDeviceObjectBase( ObjAllocator, pDevice, ViewDesc, bIsDefaultView ? pBuffer : nullptr ), m_pBuffer( pBuffer ), // For non-default view, we will keep strong reference to buffer m_spBuffer(bIsDefaultView ? nullptr : pBuffer) @@ -65,15 +68,16 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_BufferView, TDeviceObjectBase ) - virtual IBuffer* GetBuffer() + /// Implementation of IBufferView::GetBuffer() + virtual IBuffer* GetBuffer()override final { return m_pBuffer; } protected: - /// Reference to the buffer - IBuffer* m_pBuffer; + /// Pointer to the buffer + IBuffer* const m_pBuffer; /// Strong reference to the buffer. Used for non-default views /// to keep the buffer alive diff --git a/Graphics/GraphicsEngine/include/CommandListBase.h b/Graphics/GraphicsEngine/include/CommandListBase.h new file mode 100644 index 00000000..fd917490 --- /dev/null +++ b/Graphics/GraphicsEngine/include/CommandListBase.h @@ -0,0 +1,66 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::CommandListBase template class + +#include "CommandList.h" +#include "DeviceObjectBase.h" +#include "RenderDeviceBase.h" + +namespace Diligent +{ + +struct CommandListDesc : public DeviceObjectAttribs +{ +}; + +/// Template class implementing base functionality for a command list object. + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::ICommandListD3D11 or Diligent::ICommandListD3D12). +/// \tparam CommandListObjAllocator - allocator that is used to allocate memory for command list object instances +template<class BaseInterface, class CommandListObjAllocator> +class CommandListBase : public DeviceObjectBase<BaseInterface, CommandListDesc, CommandListObjAllocator> +{ +public: + typedef DeviceObjectBase<BaseInterface, CommandListDesc, CommandListObjAllocator> TDeviceObjectBase; + + /// \param ObjAllocator - Allocator that was used to allocate memory for this instance of the command list object + /// \param pDevice - pointer to the device. + /// \param bIsDeviceInternal - flag indicating if the CommandList is an internal device object and + /// must not keep a strong reference to the device. + CommandListBase( CommandListObjAllocator &ObjAllocator, IRenderDevice *pDevice, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( ObjAllocator, pDevice, CommandListDesc(), nullptr, bIsDeviceInternal ) + {} + + ~CommandListBase() + { + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_CommandList, TDeviceObjectBase ) +}; + +} diff --git a/Graphics/GraphicsEngine/include/Defines.h b/Graphics/GraphicsEngine/include/Defines.h index 7f6a56e3..23585de3 100644 --- a/Graphics/GraphicsEngine/include/Defines.h +++ b/Graphics/GraphicsEngine/include/Defines.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngine/include/DepthStencilStateBase.h b/Graphics/GraphicsEngine/include/DepthStencilStateBase.h deleted file mode 100644 index dbfe43d3..00000000 --- a/Graphics/GraphicsEngine/include/DepthStencilStateBase.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Implementation of the Diligent::DepthStencilStateBase template class - -#include "DepthStencilState.h" -#include "DeviceObjectBase.h" - -namespace Diligent -{ - -/// Template class implementing base functionality for a depth stencil state object. - -/// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::IDepthStencilStateD3D11 or Diligent::IDepthStencilStateGL). -/// \tparam RenderDeviceBaseInterface - base interface for the render device -/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, -/// or Diligent::IRenderDeviceGLES). -template<class BaseInterface = IDepthStencilState, class RenderDeviceBaseInterface = IRenderDevice> -class DepthStencilStateBase : public DeviceObjectBase<BaseInterface, DepthStencilStateDesc> -{ -public: - typedef DeviceObjectBase<BaseInterface, DepthStencilStateDesc> TDeviceObjectBase; - typedef RenderDeviceBase<RenderDeviceBaseInterface> TRenderDeviceBase; - - /// \param pDevice - pointer to the device. - /// \param DSSDesc - depth-stencil state description. - /// \param bIsDeviceInternal - flag indicating if the state is an internal device object and - /// must not keep a strong reference to the device. - DepthStencilStateBase( IRenderDevice *pDevice, const DepthStencilStateDesc& DSSDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, DSSDesc, nullptr, bIsDeviceInternal ) - { - } - - ~DepthStencilStateBase() - { - /// \note Destructor cannot directly remove the object from the registry as this may cause a - /// deadlock. See BlendStateBase::~BlendStateBase() for details. - auto &DSStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetDSStateRegistry(); - DSStateRegistry.ReportDeletedObject(); - } - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DepthStencilState, TDeviceObjectBase ) -}; - -} diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h index 26885aa4..f18a8f85 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.h +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,8 +49,8 @@ struct VertexStreamInfo { /// Strong reference to the buffer object RefCntAutoPtr<IBuffer> pBuffer; - Uint32 Stride; ///< Stride - Uint32 Offset; ///< Offset + Uint32 Stride; ///< Stride in bytes + Uint32 Offset; ///< Offset in bytes VertexStreamInfo() : Stride( 0 ), Offset( 0 ) @@ -64,25 +64,30 @@ struct VertexStreamInfo /// the pipeline: buffers, states, samplers, shaders, etc. /// The context also keeps strong references to the device and /// the swap chain. -template<typename BaseInterface = IDeviceContext> -class DeviceContextBase : public ObjectBase<BaseInterface> +template<typename BaseInterface> +class DeviceContextBase : public ObjectBase<BaseInterface, IMemoryAllocator> { public: - DeviceContextBase(IRenderDevice *pRenderDevice) : + + typedef ObjectBase<BaseInterface, IMemoryAllocator> TObjectBase; + + /// \param RawMemAllocator - allocator that was used to allocate memory for this instance of the device context object. + /// \param pRenderDevice - render device. + /// \param bIsDeferred - flag indicating if this instance is a deferred context + DeviceContextBase(IMemoryAllocator& RawMemAllocator, IRenderDevice *pRenderDevice, bool bIsDeferred) : + TObjectBase(nullptr, &RawMemAllocator), m_pDevice(pRenderDevice), m_IndexDataStartOffset( 0 ), m_StencilRef( 0 ), - m_SamplesBlendMask( 0 ) + m_NumVertexStreams(0), + m_bIsDeferred(bIsDeferred) { for( int i = 0; i < 4; ++i ) m_BlendFactors[i] = -1; - m_VertexStreams.reserve( MaxBufferSlots ); - m_Viewports.reserve( 16 ); - m_ScissorRects.reserve( 16 ); // Set dummy render target array size to make sure that // render targets are actually bound the first time // SetRenderTargets() is called - m_pBoundRenderTargets.resize( 8 ); + m_NumBoundRenderTargets = _countof(m_pBoundRenderTargets); } ~DeviceContextBase() @@ -91,89 +96,62 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceContext, ObjectBase<BaseInterface> ) - virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) = 0; - - virtual void ClearState() = 0; - - virtual void SetShaders( IShader **ppShaders, Uint32 NumShadersToSet ) - { - m_pBoundShaders.resize( NumShadersToSet ); - for( Uint32 i = 0; i < NumShadersToSet; ++i ) - m_pBoundShaders[i] = ppShaders[i]; -#ifdef DEBUG_CHECKS - { - Uint32 BoundShaders = 0; - for( auto sh = m_pBoundShaders.begin(); sh != m_pBoundShaders.end(); ++sh ) - { - auto ShaderType = (*sh)->GetDesc().ShaderType; - if( BoundShaders & ShaderType ) - { - LOG_ERROR_MESSAGE( "More than one shader of type ", GetShaderTypeLiteralName( ShaderType ), " is being set to the pipeline" ); - BoundShaders |= ShaderType; - } - } - } -#endif - } - - virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) - { - } - - // Body of the pure virtual function cannot be inlined - /// Caches the strong reference to the vertex description - virtual void SetVertexDescription( IVertexDescription *pVertexDesc ) = 0; - - /// Caches the strong reference to the index buffer - virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) = 0; + /// Base implementation of IDeviceContext::SetVertexBuffers(); validates parameters and + /// caches references to the buffers. + inline virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) = 0; - /// If the new depth stencil parameters differ from the cached values, - /// updates the values and returns true. Otherwise returns false. - bool SetDepthStencilState( IDepthStencilState *pDSState, Uint32 StencilRef, Uint32 Dummy = 0); + inline virtual void ClearState() = 0; + /// Base implementation of IDeviceContext::SetPipelineState(); caches references to the pipeline state object. + inline virtual void SetPipelineState(IPipelineState *pPipelineState) = 0; - /// If the new rasterizer state differs from the cached state, - /// updates the cached state and returns true. Otherwise returns false. - bool SetRasterizerState( IRasterizerState *pRS, Uint32 Dummy = 0 ); + /// Base implementation of IDeviceContext::CommitShaderResources(); validates parameters. + inline bool CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags, int); + /// Base implementation of IDeviceContext::SetIndexBuffer(); caches the strong reference to the index buffer + inline virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) = 0; - /// If the new blend parameters differ from the cached values, - /// updates the cached values and returns true. Otherwise returns false. - bool SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask, Uint32 Dummy = 0 ); - /// Caches the viewports - void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 &RTWidth, Uint32 &RTHeight ); + inline void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 &RTWidth, Uint32 &RTHeight ); /// Caches the scissor rects - void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 &RTWidth, Uint32 &RTHeight ); + inline void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 &RTWidth, Uint32 &RTHeight ); /// Caches the render target and depth stencil views. Returns true if any view is different /// from the cached value and false otherwise. - bool SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil, Uint32 Dummy = 0 ); + inline bool SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil, Uint32 Dummy = 0 ); /// Sets the strong pointer to the swap chain - void SetSwapChain( ISwapChain *pSwapChain ) { m_pSwapChain = pSwapChain; } + inline void SetSwapChain( ISwapChain *pSwapChain ) { m_pSwapChain = pSwapChain; } - bool IsDefaultFBBound(){ return m_pBoundRenderTargets.size() == 0 && m_pBoundDepthStencil == nullptr; } + /// Returns the swap chain + ISwapChain *GetSwapChain() { return m_pSwapChain; } - void GetDepthStencilState(IDepthStencilState **ppDSS, Uint32 &StencilRef); + /// Returns true if currently bound frame buffer is the default frame buffer + inline bool IsDefaultFBBound(){ return m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil == nullptr; } - void GetRasterizerState( IRasterizerState **ppRS ); + /// Returns currently bound pipeline state and blend factors + inline void GetPipelineState(IPipelineState **ppPSO, float* BlendFactors, Uint32 &StencilRef); - void GetBlendState( IBlendState **ppBS, float* BlendFactors, Uint32& SamplesBlendMask ); + /// Returns currently bound render targets + inline void GetRenderTargets(Uint32 &NumRenderTargets, ITextureView **ppRTVs, ITextureView **ppDSV); - void GetRenderTargets(Uint32 &NumRenderTargets, ITextureView **ppRTVs, ITextureView **ppDSV); + /// Returns currently set viewports + inline void GetViewports( Uint32 &NumViewports, Viewport *pViewports ); - /// Creates and binds default depth stencil, rasterizer & blend states - void CreateDefaultStates(); + /// Returns the render device + IRenderDevice *GetDevice(){return m_pDevice;} - void GetShaders( IShader **ppShaders, Uint32 &NumShaders ); +protected: + inline bool SetBlendFactors(const float *BlendFactors, int Dummy); - void GetViewports( Uint32 &NumViewports, Viewport *pViewports ); + inline bool SetStencilRef(Uint32 StencilRef, int Dummy); -protected: /// Returns the size of the currently bound render target - void GetRenderTargetSize( Uint32 &RTWidth, Uint32 &RTHeight ); + inline void GetRenderTargetSize( Uint32 &RTWidth, Uint32 &RTHeight ); + + /// Clears all cached resources + inline void ClearStateCache(); /// Strong reference to the device. RefCntAutoPtr<IRenderDevice> m_pDevice; @@ -182,59 +160,51 @@ protected: /// weak reference to the immediate context. RefCntAutoPtr<ISwapChain> m_pSwapChain; - /// Vector of strong references to bound shaders - std::vector< RefCntAutoPtr<IShader> > m_pBoundShaders; - /// Vertex streams. Every stream holds strong reference to the buffer - std::vector<VertexStreamInfo> m_VertexStreams; + VertexStreamInfo m_VertexStreams[MaxBufferSlots]; + + /// Number of bound vertex streams + Uint32 m_NumVertexStreams = 0; - /// Strong reference to the bound vertex description object - RefCntAutoPtr<IVertexDescription> m_pVertexDesc; + /// Strong reference to the bound pipeline state object + RefCntAutoPtr<IPipelineState> m_pPipelineState; /// Strong reference to the bound index buffer RefCntAutoPtr<IBuffer> m_pIndexBuffer; + /// Offset from the beginning of the index buffer to the start of the index data, in bytes. Uint32 m_IndexDataStartOffset; - /// Strong references to the bound depth-stencil state - RefCntAutoPtr< IDepthStencilState > m_pDSState; - - /// Strong references to the bound rasterizer state - RefCntAutoPtr< IRasterizerState> m_pRasterizerState; - - /// Strong references to the bound blend state - RefCntAutoPtr< IBlendState> m_pBlendState; - /// Current stencil reference value Uint32 m_StencilRef; /// Curent blend factors Float32 m_BlendFactors[4]; - /// Current samples blend mask - Uint32 m_SamplesBlendMask; - /// Current viewports - std::vector<Viewport> m_Viewports; + Viewport m_Viewports[MaxRenderTargets]; + /// Number of current viewports + Uint32 m_NumViewports = 0; /// Current scissor rects - std::vector<Rect> m_ScissorRects; + Rect m_ScissorRects[MaxRenderTargets]; + /// Number of current scissor rects + Uint32 m_NumScissorRects = 0; - /// Vector of strong references to bound render targets - std::vector< RefCntAutoPtr<ITextureView> > m_pBoundRenderTargets; + /// Vector of strong references to the bound render targets + RefCntAutoPtr<ITextureView> m_pBoundRenderTargets[MaxRenderTargets]; + /// Number of bound render targets + Uint32 m_NumBoundRenderTargets = 0; /// Strong references to the bound depth stencil view RefCntAutoPtr<ITextureView> m_pBoundDepthStencil; -private: - RefCntAutoPtr<IDepthStencilState> m_pDefaultDSS; - RefCntAutoPtr<IRasterizerState> m_pDefaultRS; - RefCntAutoPtr<IBlendState> m_pDefaultBS; + bool m_bIsDeferred = false; }; template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) +inline void DeviceContextBase<BaseInterface> :: SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) { if( StartSlot >= MaxBufferSlots ) { @@ -250,9 +220,12 @@ void DeviceContextBase<BaseInterface> :: SetVertexBuffers( Uint32 StartSlot, Uin if( Flags & SET_VERTEX_BUFFERS_FLAG_RESET ) { - m_VertexStreams.clear(); + for(Uint32 s=0; s < m_NumVertexStreams; ++s) + m_VertexStreams[s] = VertexStreamInfo(); + m_NumVertexStreams = 0; } - m_VertexStreams.resize( std::max(m_VertexStreams.size(), static_cast<size_t>(StartSlot + NumBuffersSet) ) ); + m_NumVertexStreams = std::max(m_NumVertexStreams, StartSlot + NumBuffersSet ); + for( Uint32 Buff = 0; Buff < NumBuffersSet; ++Buff ) { auto &CurrStream = m_VertexStreams[StartSlot + Buff]; @@ -271,27 +244,50 @@ void DeviceContextBase<BaseInterface> :: SetVertexBuffers( Uint32 StartSlot, Uin #endif } // Remove null buffers from the end of the array - while(m_VertexStreams.size() > 0 && !m_VertexStreams.back().pBuffer) - m_VertexStreams.pop_back(); + while(m_NumVertexStreams > 0 && !m_VertexStreams[m_NumVertexStreams-1].pBuffer) + m_VertexStreams[m_NumVertexStreams--] = VertexStreamInfo(); } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: ClearState() +inline void DeviceContextBase<BaseInterface> :: SetPipelineState(IPipelineState *pPipelineState) { - UNSUPPORTED("This function is not implemented") - //m_VertexStreams.clear(); - //m_pIndexBuffer.Release(); - //m_IndexDataStartOffset = 0; + m_pPipelineState = pPipelineState; } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: SetVertexDescription( IVertexDescription *pVertexDesc ) +inline bool DeviceContextBase<BaseInterface> :: CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags, int) { - m_pVertexDesc = pVertexDesc; +#ifdef _DEBUG + if (!m_pPipelineState) + { + LOG_ERROR_MESSAGE("No pipeline state is bound to the pipeline"); + return false; + } + + if (pShaderResourceBinding) + { + auto *pPSO = pShaderResourceBinding->GetPipelineState(); + if (pPSO != m_pPipelineState) + { + LOG_ERROR_MESSAGE("Shader resource binding object does not match currently bound pipeline state"); + return false; + } + } +#endif + return true; } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) +inline void DeviceContextBase<BaseInterface> :: ClearState() +{ + UNSUPPORTED("This function is deprecated") + //m_VertexStreams.clear(); + //m_pIndexBuffer.Release(); + //m_IndexDataStartOffset = 0; +} + +template<typename BaseInterface> +inline void DeviceContextBase<BaseInterface> :: SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) { m_pIndexBuffer = pIndexBuffer; m_IndexDataStartOffset = ByteOffset; @@ -305,151 +301,56 @@ void DeviceContextBase<BaseInterface> :: SetIndexBuffer( IBuffer *pIndexBuffer, } -/// \param [in] pDSState - pointer to the new depth-stencil state interface. -/// \param [in] StencilRef - new stencil reference value. -/// \param [in] Dummy - dummy argument required to make function signature distinct -/// from IDeviceContext::SetDepthStencilState(). This is required -/// because otherwise this overloaded function will only differ in -/// the return type which is not allowed. -/// \return -/// - True if either new depth stencil state or stencil reference value differs from -/// currently cached values. -/// - False otherwise. -/// -/// \remarks The method caches *strong reference* to the provided interface in m_pDSState. template<typename BaseInterface> -bool DeviceContextBase<BaseInterface> :: SetDepthStencilState( IDepthStencilState *pDSState, Uint32 StencilRef, Uint32 Dummy ) -{ - // If null depth-stencil state is provided, bind default state - if( !pDSState ) - pDSState = m_pDefaultDSS; - - // Here m_pDSState is certainly a live object because we keep the - // strong reference. pDSState is also clearly live object, so we can - // safely compare pointers. - if( m_pDSState != pDSState || m_StencilRef != StencilRef ) +inline void DeviceContextBase<BaseInterface> :: GetPipelineState(IPipelineState **ppPSO, float* BlendFactors, Uint32 &StencilRef) +{ + VERIFY( ppPSO != nullptr, "Null pointer provided null" ); + VERIFY( *ppPSO == nullptr, "Memory address contains a pointer to a non-null blend state" ); + if(m_pPipelineState) { - m_pDSState = pDSState; - m_StencilRef = StencilRef; - return true; + m_pPipelineState->QueryInterface( IID_PipelineState, reinterpret_cast<IObject**>( ppPSO ) ); + } + else + { + *ppPSO = nullptr; } - return false; -} + for( Uint32 f = 0; f < 4; ++f ) + BlendFactors[f] = m_BlendFactors[f]; + StencilRef = m_StencilRef; +}; -/// \param [in] pRS - pointer to the new rasterizer state interface. -/// \param [in] Dummy - dummy argument required to make function signature distinct -/// from IDeviceContext::SetRasterizerState(). This is required -/// because otherwise this overloaded function will only differ in -/// the return type which is not allowed. -/// \return -/// - True if the new rasterizer state differ from the cached state. -/// - False otherwise. -/// -/// \remarks The method caches *strong reference* to the provided interface in m_pRasterizerState. template<typename BaseInterface> -bool DeviceContextBase<BaseInterface> :: SetRasterizerState( IRasterizerState *pRS, Uint32 Dummy ) +inline bool DeviceContextBase<BaseInterface> ::SetBlendFactors(const float *BlendFactors, int) { - // If null rasterizer state provided, bind default state - if( !pRS ) - pRS = m_pDefaultRS; - - // Here m_pRasterizerState is certainly a live object because we keep the - // strong reference. pRS is also clearly live object, so we can - // safely compare pointers. - if( m_pRasterizerState != pRS ) + bool FactorsDiffer = false; + for( Uint32 f = 0; f < 4; ++f ) { - m_pRasterizerState = pRS; - return true; + if( m_BlendFactors[f] != BlendFactors[f] ) + FactorsDiffer = true; + m_BlendFactors[f] = BlendFactors[f]; } - - return false; + return FactorsDiffer; } - -/// \param [in] pBS - pointer to the new blend state interface. -/// \param [in] pBlendFactors - new blend factors. -/// \param [in] SampleMask - new sample mask. -/// \param [in] Dummy - dummy argument required to make function signature distinct -/// from IDeviceContext::SetBlendState(). This is required -/// because otherwise this overloaded function will only differ in -/// the return type which is not allowed. -/// \return -/// - True if either the new blend state, blend factors or sample mask value differs from -/// the currently cached values. -/// - False otherwise. -/// -/// \remarks The method caches *strong reference* to the provided interface in m_pBlendState. template<typename BaseInterface> -bool DeviceContextBase<BaseInterface> :: SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask, Uint32 Dummy ) +inline bool DeviceContextBase<BaseInterface> :: SetStencilRef(Uint32 StencilRef, int) { - // If null blend state provided, bind default state - if( !pBS ) - pBS = m_pDefaultBS; - - static const float DefaultBlendFactors[4] = { 1, 1, 1, 1 }; - if( pBlendFactors == nullptr ) - pBlendFactors = DefaultBlendFactors; - - // Here m_pBlendState is certainly a live object because we keep the - // strong reference. pBS is also clearly live object, so we can - // safely compare pointers. - if( m_pBlendState != pBS || - m_BlendFactors[0] != pBlendFactors[0] || - m_BlendFactors[1] != pBlendFactors[1] || - m_BlendFactors[2] != pBlendFactors[2] || - m_BlendFactors[3] != pBlendFactors[3] || - m_SamplesBlendMask != SampleMask ) + if (m_StencilRef != StencilRef) { - m_pBlendState = pBS; - m_SamplesBlendMask = SampleMask; - for( int i = 0; i < 4; ++i ) - m_BlendFactors[i] = pBlendFactors[i]; - + m_StencilRef = StencilRef; return true; } - return false; } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: GetDepthStencilState(IDepthStencilState **ppDSS, Uint32 &StencilRef) -{ - VERIFY( ppDSS != nullptr, "Null pointer provided null" ); - VERIFY( *ppDSS == nullptr, "Memory address contains a pointer to a non-null depth-stencil state" ); - VERIFY( m_pDSState, "No depth-stencil state is bound. At least default state must always be bound. Did you forget to call CreateDefaultStates()?" ); - m_pDSState->QueryInterface( IID_DepthStencilState, reinterpret_cast<IObject**>( ppDSS ) ); - StencilRef = m_StencilRef; -}; - -template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: GetRasterizerState(IRasterizerState **ppRS ) -{ - VERIFY( ppRS != nullptr, "Null pointer provided null" ); - VERIFY( *ppRS == nullptr, "Memory address contains a pointer to a non-null rasterizer state" ); - VERIFY( m_pRasterizerState, "No rasterizer state is bound. At least default state must always be bound. Did you forget to call CreateDefaultStates()?" ); - m_pRasterizerState->QueryInterface( IID_RasterizerState, reinterpret_cast<IObject**>( ppRS ) ); -} - -template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: GetBlendState( IBlendState **ppBS, float* BlendFactors, Uint32& SamplesBlendMask ) -{ - VERIFY( ppBS != nullptr, "Null pointer provided null" ); - VERIFY( *ppBS == nullptr, "Memory address contains a pointer to a non-null blend state" ); - VERIFY( m_pBlendState, "No blend state is bound. At least default state must always be bound. Did you forget to call CreateDefaultStates()?" ); - m_pBlendState->QueryInterface( IID_BlendState, reinterpret_cast<IObject**>( ppBS ) ); - for( Uint32 f = 0; f < 4; ++f ) - BlendFactors[f] = m_BlendFactors[f]; - SamplesBlendMask = m_SamplesBlendMask; -} - -template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: GetRenderTargetSize( Uint32 &RTWidth, Uint32 &RTHeight ) +inline void DeviceContextBase<BaseInterface> :: GetRenderTargetSize( Uint32 &RTWidth, Uint32 &RTHeight ) { RTWidth = 0; RTHeight = 0; // First, try to find non-null render target - for( Uint32 rt = 0; rt < m_pBoundRenderTargets.size(); ++rt ) + for( Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt ) if( auto *pRTView = m_pBoundRenderTargets[rt].RawPtr() ) { // Use render target size as viewport size @@ -487,22 +388,24 @@ void DeviceContextBase<BaseInterface> :: GetRenderTargetSize( Uint32 &RTWidth, U } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 &RTWidth, Uint32 &RTHeight ) +inline void DeviceContextBase<BaseInterface> :: SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 &RTWidth, Uint32 &RTHeight ) { if( RTWidth == 0 || RTHeight == 0 ) { GetRenderTargetSize( RTWidth, RTHeight ); } - m_Viewports.resize(NumViewports); + VERIFY(NumViewports < MaxRenderTargets, "Num viewports (", NumViewports,") exceeds the limit (", MaxRenderTargets, ")") + m_NumViewports = std::min(MaxRenderTargets, NumViewports); + Viewport DefaultVP( 0, 0, static_cast<float>(RTWidth), static_cast<float>(RTHeight) ); // If no viewports are specified, use default viewport - if( NumViewports == 1 && pViewports == nullptr ) + if( m_NumViewports == 1 && pViewports == nullptr ) { pViewports = &DefaultVP; } - for( Uint32 vp = 0; vp < NumViewports; ++vp ) + for( Uint32 vp = 0; vp < m_NumViewports; ++vp ) { m_Viewports[vp] = pViewports[vp]; VERIFY( m_Viewports[vp].Width >= 0, "Incorrect viewport width (", m_Viewports[vp].Width, ")" ); @@ -512,26 +415,28 @@ void DeviceContextBase<BaseInterface> :: SetViewports( Uint32 NumViewports, cons } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: GetViewports( Uint32 &NumViewports, Viewport *pViewports ) +inline void DeviceContextBase<BaseInterface> :: GetViewports( Uint32 &NumViewports, Viewport *pViewports ) { - NumViewports = static_cast<Uint32>( m_Viewports.size() ); + NumViewports = m_NumViewports; if( pViewports ) { - for( Uint32 vp = 0; vp < m_Viewports.size(); ++vp ) + for( Uint32 vp = 0; vp < m_NumViewports; ++vp ) pViewports[vp] = m_Viewports[vp]; } } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 &RTWidth, Uint32 &RTHeight ) +inline void DeviceContextBase<BaseInterface> :: SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 &RTWidth, Uint32 &RTHeight ) { if( RTWidth == 0 || RTHeight == 0 ) { GetRenderTargetSize( RTWidth, RTHeight ); } - m_ScissorRects.resize( NumRects ); - for( Uint32 sr = 0; sr < NumRects; ++sr ) + VERIFY(NumRects < MaxRenderTargets, "Num scissor rects (", NumRects,") exceeds the limit (", MaxRenderTargets, ")") + m_NumScissorRects = std::min(MaxRenderTargets, NumRects); + + for( Uint32 sr = 0; sr < m_NumScissorRects; ++sr ) { m_ScissorRects[sr] = pRects[sr]; VERIFY( m_ScissorRects[sr].left <= m_ScissorRects[sr].right, "Incorrect horizontal bounds for a scissor rect [", m_ScissorRects[sr].left, ", ", m_ScissorRects[sr].right, ")" ); @@ -540,13 +445,16 @@ void DeviceContextBase<BaseInterface> :: SetScissorRects( Uint32 NumRects, const } template<typename BaseInterface> -bool DeviceContextBase<BaseInterface> :: SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil, Uint32 Dummy ) +inline bool DeviceContextBase<BaseInterface> :: SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil, Uint32 Dummy ) { bool bBindRenderTargets = false; - if( NumRenderTargets != m_pBoundRenderTargets.size() ) + if( NumRenderTargets != m_NumBoundRenderTargets ) { bBindRenderTargets = true; - m_pBoundRenderTargets.resize(NumRenderTargets); + for(Uint32 rt=NumRenderTargets; rt<m_NumBoundRenderTargets; ++rt ) + m_pBoundRenderTargets[rt].Release(); + + m_NumBoundRenderTargets = NumRenderTargets; } for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) @@ -587,9 +495,9 @@ bool DeviceContextBase<BaseInterface> :: SetRenderTargets( Uint32 NumRenderTarge } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: GetRenderTargets( Uint32 &NumRenderTargets, ITextureView **ppRTVs, ITextureView **ppDSV ) +inline void DeviceContextBase<BaseInterface> :: GetRenderTargets( Uint32 &NumRenderTargets, ITextureView **ppRTVs, ITextureView **ppDSV ) { - NumRenderTargets = static_cast<Uint32>( m_pBoundRenderTargets.size() ); + NumRenderTargets = m_NumBoundRenderTargets; if( ppRTVs ) { @@ -620,40 +528,51 @@ void DeviceContextBase<BaseInterface> :: GetRenderTargets( Uint32 &NumRenderTarg } template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: CreateDefaultStates() +inline void DeviceContextBase<BaseInterface> :: ClearStateCache() { - DepthStencilStateDesc DefaultDSSDesc; - DefaultDSSDesc.Name = "Default depth stencil state"; - m_pDevice->CreateDepthStencilState( DefaultDSSDesc, &m_pDefaultDSS ); - - RasterizerStateDesc DefaultRSDesc; - DefaultRSDesc.Name = "Default rasterizer state"; - m_pDevice->CreateRasterizerState( DefaultRSDesc, &m_pDefaultRS ); - - BlendStateDesc DefaultBlendState; - DefaultBlendState.Name = "Default blend state"; - m_pDevice->CreateBlendState( DefaultBlendState, &m_pDefaultBS ); - - SetDepthStencilState( m_pDefaultDSS, 0 ); - SetRasterizerState( m_pDefaultRS ); - float BlendFactors[4] = { 1, 1, 1, 1 }; - SetBlendState( m_pDefaultBS, BlendFactors, 0xFFFFFFFF ); -} + for(Uint32 stream=0; stream < m_NumVertexStreams; ++stream) + m_VertexStreams[stream] = VertexStreamInfo(); +#ifdef _DEBUG + for(Uint32 stream=m_NumVertexStreams; stream < _countof(m_VertexStreams); ++stream) + { + VERIFY(m_VertexStreams[stream].pBuffer == nullptr, "Unexpected non-null buffer"); + VERIFY(m_VertexStreams[stream].Offset == 0, "Unexpected non-zero offset"); + VERIFY(m_VertexStreams[stream].Stride == 0, "Unexpected non-zero stride"); + } +#endif + m_NumVertexStreams = 0; -template<typename BaseInterface> -void DeviceContextBase<BaseInterface> :: GetShaders( IShader **ppShaders, Uint32 &NumShaders ) -{ - NumShaders = static_cast<Uint32>( m_pBoundShaders.size() ); - if( ppShaders == nullptr ) - return; - for( Uint32 s = 0; s < NumShaders; ++s ) - { - VERIFY( ppShaders[s] == nullptr, "Non-null pointer found in shader array element #", s ); - if( auto pBoundShader = m_pBoundShaders[s] ) - pBoundShader->QueryInterface( IID_Shader, reinterpret_cast<IObject**>( ppShaders + s ) ); - else - ppShaders[s] = nullptr; + m_pPipelineState.Release(); + + m_pIndexBuffer.Release(); + m_IndexDataStartOffset = 0; + + m_StencilRef = 0; + + for( int i = 0; i < 4; ++i ) + m_BlendFactors[i] = -1; + + for(Uint32 vp=0; vp < m_NumViewports; ++vp) + m_Viewports[vp] = Viewport(); + m_NumViewports = 0; + + for(Uint32 sr=0; sr < m_NumScissorRects; ++sr) + m_ScissorRects[sr] = Rect(); + m_NumScissorRects = 0; + + /// Vector of strong references to bound render targets + for(Uint32 rt=0; rt < m_NumBoundRenderTargets; ++rt ) + m_pBoundRenderTargets[rt].Release(); +#ifdef _DEBUG + for (Uint32 rt = m_NumBoundRenderTargets; rt < _countof(m_pBoundRenderTargets); ++rt) + { + VERIFY(m_pBoundRenderTargets[rt] == nullptr, "Non-null render target found") } +#endif + // Set this to max RT count to force render targets to be bound next time + m_NumBoundRenderTargets = _countof(m_pBoundRenderTargets); + + m_pBoundDepthStencil.Release(); } } diff --git a/Graphics/GraphicsEngine/include/DeviceObjectBase.h b/Graphics/GraphicsEngine/include/DeviceObjectBase.h index f96b6d7c..f4ca83f9 100644 --- a/Graphics/GraphicsEngine/include/DeviceObjectBase.h +++ b/Graphics/GraphicsEngine/include/DeviceObjectBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,21 +36,24 @@ template<typename BaseInterface> class RenderDeviceBase; /// Template class implementing base functionality for a device object -template<class BaseInterface, typename ObjectDescType> -class DeviceObjectBase : public ObjectBase<BaseInterface> +template<class BaseInterface, typename ObjectDescType, typename TObjectAllocator> +class DeviceObjectBase : public ObjectBase<BaseInterface, TObjectAllocator> { public: + typedef ObjectBase<BaseInterface, TObjectAllocator> TBase; + /// \param ObjAllocator - allocator that was used to allocate memory for this instance /// \param pDevice - pointer to the render device. /// \param ObjDesc - object description. /// \param pOwner - owner object. /// \param bIsDeviceInternal - flag indicating if the object is an internal device object /// and must not keep a strong reference to the device. - DeviceObjectBase( class IRenderDevice *pDevice, + DeviceObjectBase( TObjectAllocator &ObjAllocator, + class IRenderDevice *pDevice, const ObjectDescType &ObjDesc, IObject *pOwner = nullptr, bool bIsDeviceInternal = false) : - ObjectBase<BaseInterface>(pOwner), + TBase(pOwner, &ObjAllocator), m_pDevice( pDevice ), // Do not keep strong reference to the device if the object is an internal device object m_spDevice( bIsDeviceInternal ? nullptr : pDevice ), @@ -70,9 +73,9 @@ public: { } - IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceObject, ObjectBase<BaseInterface> ) + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_DeviceObject, TBase ) - virtual const ObjectDescType& GetDesc()const override + virtual const ObjectDescType& GetDesc()const override final { return m_Desc; } @@ -88,11 +91,15 @@ public: return m_UniqueID.GetID(); } + IRenderDevice *GetDevice()const{return m_pDevice;} + protected: - IRenderDevice *GetDevice(){return m_pDevice;} + /// Copy of a device object name. - /// Copy of a device object name + /// When new object is created, its description structure is copied + /// to m_Desc, the name is copied to m_ObjectNameCopy, and + /// m_Desc.Name pointer is set to m_ObjectNameCopy.c_str(). const String m_ObjectNameCopy; /// Object description diff --git a/Graphics/GraphicsEngine/include/EngineMemory.h b/Graphics/GraphicsEngine/include/EngineMemory.h new file mode 100644 index 00000000..bf5f157c --- /dev/null +++ b/Graphics/GraphicsEngine/include/EngineMemory.h @@ -0,0 +1,73 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::BufferBase template class + +#include "MemoryAllocator.h" + +namespace Diligent +{ + /// Sets raw memory allocator. This function must be called before any memory allocation/deallocation function + /// is called. + void SetRawAllocator(IMemoryAllocator *pRawAllocator); + + /// Returns raw memory allocator + IMemoryAllocator& GetRawAllocator(); +} + +#define NEW(Allocator, Desc, Type, ...) new(Allocator, Desc, __FILE__, __LINE__) Type(Allocator, ##__VA_ARGS__) +#define ALLOCATE(Allocator, Desc, Size) (Allocator).Allocate(Size, Desc, __FILE__, __LINE__) +#define FREE(Allocator, Ptr) Allocator.Free(Ptr) + +#if 0 +inline void* operator new(size_t Size, const char* dbgDescription, const char* dbgFileName, const int dbgLineNumber) +{ + return Diligent::GetRawAllocator().Allocate(Size, dbgDescription, dbgFileName, dbgLineNumber); +} + +inline void* operator new[](size_t Size, const char* dbgDescription, const char* dbgFileName, const int dbgLineNumber) +{ + return Diligent::GetRawAllocator().Allocate(Size, dbgDescription, dbgFileName, dbgLineNumber); +} + +// Arguments of the delete operator must exactly match the arguments of new +inline void operator delete(void* Ptr, const char* dbgDescription, const char* dbgFileName, const int dbgLineNumber) +{ + Diligent::GetRawAllocator().Free(Ptr); +} + +inline void operator delete[](void* Ptr, const char* dbgDescription, const char* dbgFileName, const int dbgLineNumber) +{ + Diligent::GetRawAllocator().Free(Ptr); +} + +#define MemAlloc(Size, Desc) GetRawAllocator().Allocate(Size, Desc, __FILE__, __LINE__) +#define MemFree(Ptr) GetRawAllocator().Free(Ptr) +#define New(Desc) new(Desc, __FILE__, __LINE__) +#define Delete delete + + +#endif
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.h b/Graphics/GraphicsEngine/include/PipelineStateBase.h new file mode 100644 index 00000000..1cb7d453 --- /dev/null +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.h @@ -0,0 +1,194 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::PipelineStateBase template class + +#include "PipelineState.h" +#include "DeviceObjectBase.h" +#include "STDAllocator.h" +#include "EngineMemory.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a pipeline state object. + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IPipelineStateD3D11, Diligent::IPipelineStateD3D12 or Diligent::IPipelineStateGL). +/// \tparam RenderDeviceBaseInterface - base interface for the render device +/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceD3D12, Diligent::IRenderDeviceGL, +/// or Diligent::IRenderDeviceGLES). +template<class BaseInterface, class RenderDeviceBaseInterface, class PSOAllocator> +class PipelineStateBase : public DeviceObjectBase<BaseInterface, PipelineStateDesc, PSOAllocator> +{ +public: + typedef DeviceObjectBase<BaseInterface, PipelineStateDesc, PSOAllocator> TDeviceObjectBase; + typedef RenderDeviceBase < RenderDeviceBaseInterface > TRenderDeviceBase; + + /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the pipeline state object + /// \param pDevice - pointer to the device. + /// \param PSODesc - pipeline state description. + /// \param bIsDeviceInternal - flag indicating if the blend state is an internal device object and + /// must not keep a strong reference to the device. + PipelineStateBase( PSOAllocator &ObjAllocator, IRenderDevice *pDevice, const PipelineStateDesc& PSODesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( ObjAllocator, pDevice, PSODesc, nullptr, bIsDeviceInternal ), + m_LayoutElements( PSODesc.GraphicsPipeline.InputLayout.NumElements, LayoutElement(), STD_ALLOCATOR_RAW_MEM(LayoutElement, GetRawAllocator(), "Allocator for vector<LayoutElement>" ) ), + m_NumShaders(0) + { + memset(m_ppShaders, 0, sizeof(m_ppShaders)); + + if (this->m_Desc.IsComputePipeline) + { + const auto &ComputePipeline = PSODesc.ComputePipeline; + if (ComputePipeline.pCS == nullptr) + { + LOG_ERROR_AND_THROW( "Compute shader is not provided" ); + } + +#define VALIDATE_SHADER_TYPE(Shader, ExpectedType, ShaderName)\ + if (Shader && Shader->GetDesc().ShaderType != ExpectedType) \ + { \ + LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(Shader->GetDesc().ShaderType), " is not valid type for ", ShaderName, " shader" );\ + } + VALIDATE_SHADER_TYPE(ComputePipeline.pCS, SHADER_TYPE_COMPUTE, "compute") + + m_pCS = ComputePipeline.pCS; + m_ppShaders[0] = ComputePipeline.pCS; + m_NumShaders = 1; + } + else + { + const auto &GraphicsPipeline = PSODesc.GraphicsPipeline; + + VALIDATE_SHADER_TYPE(GraphicsPipeline.pVS, SHADER_TYPE_VERTEX, "vertex") + VALIDATE_SHADER_TYPE(GraphicsPipeline.pPS, SHADER_TYPE_PIXEL, "pixel") + VALIDATE_SHADER_TYPE(GraphicsPipeline.pGS, SHADER_TYPE_GEOMETRY, "geometry") + VALIDATE_SHADER_TYPE(GraphicsPipeline.pHS, SHADER_TYPE_HULL, "hull") + VALIDATE_SHADER_TYPE(GraphicsPipeline.pDS, SHADER_TYPE_DOMAIN, "domain") +#undef VALIDATE_SHADER_TYPE + + m_pVS = GraphicsPipeline.pVS; + m_pPS = GraphicsPipeline.pPS; + m_pGS = GraphicsPipeline.pGS; + m_pDS = GraphicsPipeline.pDS; + m_pHS = GraphicsPipeline.pHS; + + if( GraphicsPipeline.pVS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pVS; + if( GraphicsPipeline.pPS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pPS; + if( GraphicsPipeline.pGS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pGS; + if( GraphicsPipeline.pHS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pHS; + if( GraphicsPipeline.pDS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pDS; + } + + const auto &InputLayout = PSODesc.GraphicsPipeline.InputLayout; + for( size_t Elem = 0; Elem < InputLayout.NumElements; ++Elem ) + m_LayoutElements[Elem] = InputLayout.LayoutElements[Elem]; + this->m_Desc.GraphicsPipeline.InputLayout.LayoutElements = m_LayoutElements.data(); + + // Correct description and compute offsets and tight strides + for( auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It ) + { + if( It->ValueType == VT_FLOAT32 || It->ValueType == VT_FLOAT16 ) + It->IsNormalized = false; // Floating point values cannot be normalized + + auto BuffSlot = It->BufferSlot; + if( BuffSlot >= _countof(m_TightStrides) ) + { + UNEXPECTED("Buffer slot (", BuffSlot, ") exceeds the limit (", _countof(m_TightStrides), ")"); + continue; + } + + auto &CurrStride = m_TightStrides[BuffSlot]; + if( It->RelativeOffset < CurrStride ) + { + if( It->RelativeOffset == 0 ) + It->RelativeOffset = CurrStride; + else + UNEXPECTED( "Overlapping layout elements" ); + } + + CurrStride += It->NumComponents * GetValueSize( It->ValueType ); + } + } + + ~PipelineStateBase() + { + /* + /// \note Destructor cannot directly remove the object from the registry as this may cause a + /// deadlock at the point where StateObjectsRegistry::Find() locks the weak pointer: if we + /// are in dtor, the object is locked by Diligent::RefCountedObject::Release() and + /// StateObjectsRegistry::Find() will wait for that lock to be released. + /// A the same time this thread will be waiting for the other thread to unlock the registry.\n + /// Thus destructor only notifies the registry that there is a deleted object. + /// The reference to the object will be removed later. + auto &PipelineStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetBSRegistry(); + auto &RasterizerStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetRSRegistry(); + auto &DSSRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetDSSRegistry(); + // StateObjectsRegistry::ReportDeletedObject() does not lock the registry, but only + // atomically increments the outstanding deleted objects counter. + PipelineStateRegistry.ReportDeletedObject(); + RasterizerStateRegistry.ReportDeletedObject(); + DSSRegistry.ReportDeletedObject(); + */ + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_PipelineState, TDeviceObjectBase ) + + virtual const Uint32* GetTightStrides()const + { + return m_TightStrides; + } + + IShader* GetVS(){return m_pVS;} + IShader* GetPS(){return m_pPS;} + IShader* GetGS(){return m_pGS;} + IShader* GetDS(){return m_pDS;} + IShader* GetHS(){return m_pHS;} + IShader* GetCS(){return m_pCS;} + + IShader* const* GetShaders()const{return m_ppShaders;} + Uint32 GetNumShaders()const{return m_NumShaders;} + +protected: + std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement> > m_LayoutElements; + + // The size of this array must be equal to the + // maximum number of buffer slots, because a layout + // element can refer to any input slot + Uint32 m_TightStrides[MaxBufferSlots] = {}; + + RefCntAutoPtr<IShader> m_pVS; ///< Strong reference to the vertex shader + RefCntAutoPtr<IShader> m_pPS; ///< Strong reference to the pixel shader + RefCntAutoPtr<IShader> m_pGS; ///< Strong reference to the geometry shader + RefCntAutoPtr<IShader> m_pDS; ///< Strong reference to the domain shader + RefCntAutoPtr<IShader> m_pHS; ///< Strong reference to the hull shader + RefCntAutoPtr<IShader> m_pCS; ///< Strong reference to the compute shader + IShader *m_ppShaders[5]; ///< Array of pointers to shaders that this PSO uses + Uint32 m_NumShaders; ///< Number of shaders that this PSO uses +}; + +} diff --git a/Graphics/GraphicsEngine/include/RasterizerStateBase.h b/Graphics/GraphicsEngine/include/RasterizerStateBase.h deleted file mode 100644 index a3c90275..00000000 --- a/Graphics/GraphicsEngine/include/RasterizerStateBase.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Implementation of the Diligent::RasterizerStateBase template class - -#include "RasterizerState.h" -#include "DeviceObjectBase.h" - -namespace Diligent -{ - -/// Template class implementing base functionality for a rasterizer object. - -/// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::IRasterizerStateD3D11 or Diligent::IRasterizerStateGL). -/// \tparam RenderDeviceBaseInterface - base interface for the render device -/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, -/// or Diligent::IRenderDeviceGLES). -template<class BaseInterface = IRasterizerState, class RenderDeviceBaseInterface = IRenderDevice> -class RasterizerStateBase : public DeviceObjectBase<BaseInterface, RasterizerStateDesc> -{ -public: - typedef DeviceObjectBase<BaseInterface, RasterizerStateDesc> TDeviceObjectBase; - typedef RenderDeviceBase < RenderDeviceBaseInterface > TRenderDeviceBase; - - /// \param pDevice - pointer to the device. - /// \param RSDesc - rasterizer state description. - /// \param bIsDeviceInternal - flag indicating if the state is an internal device object and - /// must not keep a strong reference to the device. - RasterizerStateBase( IRenderDevice *pDevice, const RasterizerStateDesc& RSDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, RSDesc, nullptr, bIsDeviceInternal ) - { - } - - ~RasterizerStateBase() - { - /// \note Destructor cannot directly remove the object from the registry as this may cause a - /// deadlock. See BlendStateBase::~BlendStateBase() for details. - auto &RasterizerStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetRSRegistry(); - RasterizerStateRegistry.ReportDeletedObject(); - } - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_RasterizerState, TDeviceObjectBase ) -}; - -} diff --git a/Graphics/GraphicsEngine/include/RenderDeviceBase.h b/Graphics/GraphicsEngine/include/RenderDeviceBase.h index 97103f23..bccb4b10 100644 --- a/Graphics/GraphicsEngine/include/RenderDeviceBase.h +++ b/Graphics/GraphicsEngine/include/RenderDeviceBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,9 +36,9 @@ #include "DeviceContext.h" #include "SwapChain.h" #include "GraphicsUtilities.h" - -using Diligent::RefCntAutoPtr; -using Diligent::RefCntWeakPtr; +#include "FixedBlockMemoryAllocator.h" +#include "EngineMemory.h" +#include "STDAllocator.h" namespace std { @@ -48,8 +48,8 @@ namespace std { size_t operator()( const Diligent::SamplerDesc &SamDesc ) const { - // Sampler name is ignored in comparison operator - // and should not be hashed + // Sampler name is ignored in comparison operator + // and should not be hashed return Diligent::ComputeHash( // SamDesc.Name, static_cast<int>(SamDesc.MinFilter), static_cast<int>(SamDesc.MagFilter), @@ -75,9 +75,9 @@ namespace std size_t operator()( const Diligent::StencilOpDesc &StOpDesc ) const { return Diligent::ComputeHash( static_cast<int>( StOpDesc.StencilFailOp ), - static_cast<int>( StOpDesc.StencilDepthFailOp ), - static_cast<int>( StOpDesc.StencilPassOp ), - static_cast<int>( StOpDesc.StencilFunc ) ); + static_cast<int>( StOpDesc.StencilDepthFailOp ), + static_cast<int>( StOpDesc.StencilPassOp ), + static_cast<int>( StOpDesc.StencilFunc ) ); } }; @@ -85,19 +85,16 @@ namespace std template<> struct hash<Diligent::DepthStencilStateDesc> { - size_t operator()( const Diligent::DepthStencilStateDesc &DSSDesc ) const + size_t operator()( const Diligent::DepthStencilStateDesc &DepthStencilDesc ) const { - // Depth-stencil state name is ignored in comparison operator - // and should not be hashed - return Diligent::ComputeHash( // DSSDesc.Name, - DSSDesc.DepthEnable, - DSSDesc.DepthWriteEnable, - static_cast<int>(DSSDesc.DepthFunc), - DSSDesc.StencilEnable, - DSSDesc.StencilReadMask, - DSSDesc.StencilWriteMask, - DSSDesc.FrontFace, - DSSDesc.BackFace ); + return Diligent::ComputeHash( DepthStencilDesc.DepthEnable, + DepthStencilDesc.DepthWriteEnable, + static_cast<int>(DepthStencilDesc.DepthFunc), + DepthStencilDesc.StencilEnable, + DepthStencilDesc.StencilReadMask, + DepthStencilDesc.StencilWriteMask, + DepthStencilDesc.FrontFace, + DepthStencilDesc.BackFace ); } }; @@ -105,20 +102,17 @@ namespace std template<> struct hash<Diligent::RasterizerStateDesc> { - size_t operator()( const Diligent::RasterizerStateDesc &RSDesc ) const + size_t operator()( const Diligent::RasterizerStateDesc &RasterizerDesc ) const { - // Rasterizer state name is ignored in comparison operator - // and should not be hashed - return Diligent::ComputeHash( // RSDesc.Name, - static_cast<int>( RSDesc.FillMode ), - static_cast<int>( RSDesc.CullMode ), - RSDesc.FrontCounterClockwise, - RSDesc.DepthBias, - RSDesc.DepthBiasClamp, - RSDesc.SlopeScaledDepthBias, - RSDesc.DepthClipEnable, - RSDesc.ScissorEnable, - RSDesc.AntialiasedLineEnable ); + return Diligent::ComputeHash( static_cast<int>( RasterizerDesc.FillMode ), + static_cast<int>( RasterizerDesc.CullMode ), + RasterizerDesc.FrontCounterClockwise, + RasterizerDesc.DepthBias, + RasterizerDesc.DepthBiasClamp, + RasterizerDesc.SlopeScaledDepthBias, + RasterizerDesc.DepthClipEnable, + RasterizerDesc.ScissorEnable, + RasterizerDesc.AntialiasedLineEnable ); } }; @@ -143,17 +137,14 @@ namespace std rt.RenderTargetWriteMask ); } Diligent::HashCombine( Seed, - // Blend state name is ignored in comparison operator - // and should not be hashed - // BSDesc.Name, - BSDesc.AlphaToCoverageEnable, - BSDesc.IndependentBlendEnable ); + BSDesc.AlphaToCoverageEnable, + BSDesc.IndependentBlendEnable ); return Seed; } }; - /// Hash function specialization for Diligent::BlendStateDesc structure. + /// Hash function specialization for Diligent::TextureViewDesc structure. template<> struct hash<Diligent::TextureViewDesc> { @@ -162,7 +153,7 @@ namespace std std::size_t Seed = 0; Diligent::HashCombine( Seed, static_cast<Diligent::Int32>(TexViewDesc.ViewType), - static_cast<Diligent::Int32>(TexViewDesc.TextureType), + static_cast<Diligent::Int32>(TexViewDesc.TextureDim), static_cast<Diligent::Int32>(TexViewDesc.Format), TexViewDesc.MostDetailedMip, TexViewDesc.NumMipLevels, @@ -179,30 +170,63 @@ namespace Diligent /// Base implementation of a render device +/// \tparam BaseInterface - base interface that this class will inheret. /// \warning /// Render device must *NOT* hold strong references to any /// object it creates to avoid circular dependencies. /// Device context, swap chain and all object the device creates /// keep strong reference to the device. -/// Device only holds weak reference to immediate context. -template<typename BaseInterface = IRenderDevice> -class RenderDeviceBase : public ObjectBase<BaseInterface> +/// Device only holds weak reference to the immediate context. +template<typename BaseInterface> +class RenderDeviceBase : public ObjectBase<BaseInterface, IMemoryAllocator> { public: - RenderDeviceBase() : - m_TextureFormatsInfo( TEX_FORMAT_NUM_FORMATS ), - m_TexFmtInfoInitFlags( TEX_FORMAT_NUM_FORMATS ), - m_SamplersRegistry("sampler"), - m_DSSRegistry("ds state"), - m_RSRegistry("rasterizer state"), - m_BSRegistry("blend state") + + typedef ObjectBase<BaseInterface, IMemoryAllocator> TObjectBase; + + /// \param RawMemAllocator - allocator that will be used to allocate memory for all device objects (including render device itself) + /// \param NumDeferredContexts - number of deferred device contexts + /// \param TextureObjSize - size of the texture object, in bytes + /// \param TexViewObjSize - size of the texture view object, in bytes + /// \param BufferObjSize - size of the buffer object, in bytes + /// \param BuffViewObjSize - size of the buffer view object, in bytes + /// \param ShaderObjSize - size of the shader object, in bytes + /// \param SamplerObjSize - size of the sampler object, in bytes + /// \param PSOSize - size of the pipeline state object, in bytes + /// \param SRBSize - size of the shader resource binding object, in bytes + /// \remarks Render device uses fixed block allocators (see FixedBlockMemoryAllocator) to allocate memory for + /// device objects. The object sizes provided to constructor are used to initialize the allocators. + RenderDeviceBase(IMemoryAllocator &RawMemAllocator, + Uint32 NumDeferredContexts, + size_t TextureObjSize, + size_t TexViewObjSize, + size_t BufferObjSize, + size_t BuffViewObjSize, + size_t ShaderObjSize, + size_t SamplerObjSize, + size_t PSOSize, + size_t SRBSize) : + TObjectBase(nullptr, &RawMemAllocator), + m_TextureFormatsInfo( TEX_FORMAT_NUM_FORMATS, TextureFormatInfoExt(), STD_ALLOCATOR_RAW_MEM(TextureFormatInfoExt, RawMemAllocator, "Allocator for vector<TextureFormatInfoExt>") ), + m_TexFmtInfoInitFlags( TEX_FORMAT_NUM_FORMATS, false, STD_ALLOCATOR_RAW_MEM(bool, RawMemAllocator, "Allocator for vector<bool>") ), + m_wpDeferredContexts(NumDeferredContexts, RefCntWeakPtr<IDeviceContext>(), STD_ALLOCATOR_RAW_MEM(RefCntWeakPtr<IDeviceContext>, RawMemAllocator, "Allocator for vector< RefCntWeakPtr<IDeviceContext> >")), + m_SamplersRegistry(RawMemAllocator, "sampler"), + m_TexObjAllocator(RawMemAllocator, TextureObjSize, 64), + m_TexViewObjAllocator(RawMemAllocator, TexViewObjSize, 64), + m_BufObjAllocator(RawMemAllocator, BufferObjSize, 128), + m_BuffViewObjAllocator(RawMemAllocator, BuffViewObjSize, 128), + m_ShaderObjAllocator(RawMemAllocator, ShaderObjSize, 32), + m_SamplerObjAllocator(RawMemAllocator, SamplerObjSize, 32), + m_PSOAllocator(RawMemAllocator, PSOSize, 128), + m_SRBAllocator(RawMemAllocator, SRBSize, 1024), + m_ResMappingAllocator(RawMemAllocator, sizeof(ResourceMappingImpl), 16) { // Initialize texture format info for( Uint32 Fmt = TEX_FORMAT_UNKNOWN; Fmt < TEX_FORMAT_NUM_FORMATS; ++Fmt ) static_cast<TextureFormatAttribs&>(m_TextureFormatsInfo[Fmt]) = GetTextureFormatAttribs( static_cast<TEXTURE_FORMAT>(Fmt) ); // https://msdn.microsoft.com/en-us/library/windows/desktop/ff471325(v=vs.85).aspx - std::vector<TEXTURE_FORMAT> FilterableFormats = + TEXTURE_FORMAT FilterableFormats[] = { TEX_FORMAT_RGBA32_FLOAT, // OpenGL ES3.1 does not require this format to be filterable TEX_FORMAT_RGBA16_FLOAT, @@ -243,8 +267,8 @@ public: TEX_FORMAT_BC5_SNORM, TEX_FORMAT_B5G6R5_UNORM }; - for( auto fmt = FilterableFormats.begin(); fmt != FilterableFormats.end(); ++fmt ) - m_TextureFormatsInfo[ *fmt ].Filterable = true; + for( Uint32 fmt = 0; fmt < _countof(FilterableFormats); ++fmt ) + m_TextureFormatsInfo[ FilterableFormats[fmt] ].Filterable = true; } ~RenderDeviceBase() @@ -253,14 +277,17 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_RenderDevice, ObjectBase<BaseInterface> ) - virtual void CreateResourceMapping( const ResourceMappingDesc &MappingDesc, IResourceMapping **ppMapping ); + /// Implementation of IRenderDevice::CreateResourceMapping(). + virtual void CreateResourceMapping( const ResourceMappingDesc &MappingDesc, IResourceMapping **ppMapping )override final; - virtual const DeviceCaps& GetDeviceCaps()const + /// Implementation of IRenderDevice::GetDeviceCaps(). + virtual const DeviceCaps& GetDeviceCaps()const override final { return m_DeviceCaps; } - virtual const TextureFormatInfo &GetTextureFormatInfo(TEXTURE_FORMAT TexFormat) + /// Implementation of IRenderDevice::GetTextureFormatInfo(). + virtual const TextureFormatInfo &GetTextureFormatInfo(TEXTURE_FORMAT TexFormat)override final { VERIFY( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS, "Texture format out of range" ); const auto& TexFmtInfo = m_TextureFormatsInfo[TexFormat]; @@ -268,7 +295,8 @@ public: return TexFmtInfo; } - virtual const TextureFormatInfoExt &GetTextureFormatInfoExt( TEXTURE_FORMAT TexFormat ) + /// Implementation of IRenderDevice::GetTextureFormatInfoExt(). + virtual const TextureFormatInfoExt &GetTextureFormatInfoExt( TEXTURE_FORMAT TexFormat )override final { VERIFY( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS, "Texture format out of range" ); const auto& TexFmtInfo = m_TextureFormatsInfo[TexFormat]; @@ -287,9 +315,6 @@ public: } StateObjectsRegistry<SamplerDesc> &GetSamplerRegistry(){ return m_SamplersRegistry; } - StateObjectsRegistry<DepthStencilStateDesc> &GetDSStateRegistry(){ return m_DSSRegistry; } - StateObjectsRegistry<RasterizerStateDesc> &GetRSRegistry() { return m_RSRegistry; } - StateObjectsRegistry<BlendStateDesc> &GetBSRegistry() { return m_BSRegistry; } /// Set weak reference to the immediate context void SetImmediateContext(IDeviceContext *pImmediateContext) @@ -298,7 +323,25 @@ public: m_wpImmediateContext = pImmediateContext; } + /// Set weak reference to the deferred context + void SetDeferredContext(size_t Ctx, IDeviceContext *pDeferredCtx) + { + VERIFY( m_wpDeferredContexts[Ctx].Lock() == nullptr, "Deferred context has already been set" ); + m_wpDeferredContexts[Ctx] = pDeferredCtx; + } + + /// Returns number of deferred contexts + size_t GetNumDeferredContexts()const + { + return m_wpDeferredContexts.size(); + } + RefCntAutoPtr<IDeviceContext> GetImmediateContext(){ return m_wpImmediateContext.Lock(); } + RefCntAutoPtr<IDeviceContext> GetDeferredContext(size_t Ctx){ return m_wpDeferredContexts[Ctx].Lock(); } + + FixedBlockMemoryAllocator& GetTexViewObjAllocator(){return m_TexViewObjAllocator;} + FixedBlockMemoryAllocator& GetBuffViewObjAllocator(){return m_BuffViewObjAllocator;} + FixedBlockMemoryAllocator& GetSRBAllocator(){return m_SRBAllocator;} protected: @@ -314,15 +357,25 @@ protected: // This is safe because every object unregisters itself // when it is deleted. StateObjectsRegistry<SamplerDesc> m_SamplersRegistry; ///< Sampler state registry - StateObjectsRegistry<DepthStencilStateDesc> m_DSSRegistry;///< Depth-stencil state registry - StateObjectsRegistry<RasterizerStateDesc> m_RSRegistry; ///< Rasterizer state registry - StateObjectsRegistry<BlendStateDesc> m_BSRegistry; ///< Blend state registry - std::vector<TextureFormatInfoExt> m_TextureFormatsInfo; - std::vector<bool> m_TexFmtInfoInitFlags; + std::vector<TextureFormatInfoExt, STDAllocatorRawMem<TextureFormatInfoExt> > m_TextureFormatsInfo; + std::vector<bool, STDAllocatorRawMem<bool> > m_TexFmtInfoInitFlags; /// Weak reference to the immediate context. Immediate context holds strong reference /// to the device, so we must use weak reference to avoid circular dependencies. - Diligent::RefCntWeakPtr<IDeviceContext> m_wpImmediateContext; + RefCntWeakPtr<IDeviceContext> m_wpImmediateContext; + + /// Weak references to deferred contexts. + std::vector< RefCntWeakPtr<IDeviceContext>, STDAllocatorRawMem<RefCntWeakPtr<IDeviceContext> > > m_wpDeferredContexts; + + FixedBlockMemoryAllocator m_TexObjAllocator; ///< Allocator for texture objects + FixedBlockMemoryAllocator m_TexViewObjAllocator; ///< Allocator for texture view objects + FixedBlockMemoryAllocator m_BufObjAllocator; ///< Allocator for buffer objects + FixedBlockMemoryAllocator m_BuffViewObjAllocator; ///< Allocator for buffer view objects + FixedBlockMemoryAllocator m_ShaderObjAllocator; ///< Allocator for shader objects + FixedBlockMemoryAllocator m_SamplerObjAllocator; ///< Allocator for sampler objects + FixedBlockMemoryAllocator m_PSOAllocator; ///< Allocator for pipeline state objects + FixedBlockMemoryAllocator m_SRBAllocator; ///< Allocator for shader resource binding objects + FixedBlockMemoryAllocator m_ResMappingAllocator; ///< Allocator for resource mapping objects }; @@ -334,20 +387,20 @@ void RenderDeviceBase<BaseInterface>::CreateResourceMapping( const ResourceMappi return; VERIFY( *ppMapping == nullptr, "Overwriting reference to existing object may cause memory leaks" ); - auto *pResourceMapping( new ResourceMappingImpl() ); + auto *pResourceMapping( NEW(m_ResMappingAllocator, "ResourceMappingImpl instance", ResourceMappingImpl, GetRawAllocator()) ); pResourceMapping->QueryInterface( IID_ResourceMapping, reinterpret_cast<IObject**>(ppMapping) ); if( MappingDesc.pEntries ) { for( auto *pEntry = MappingDesc.pEntries; pEntry->Name && pEntry->pObject; ++pEntry ) { - (*ppMapping)->AddResource( pEntry->Name, pEntry->pObject, true ); + (*ppMapping)->AddResourceArray( pEntry->Name, pEntry->ArrayIndex, &pEntry->pObject, 1, true ); } } } -/// \tparam TObjectType - type of the object being created (IBuffer, ITexture, IBlendState, etc.) -/// \tparam TObjectDescType - type of the object description structure (BufferDesc, TextureDesc, BlendStateDesc, etc.) +/// \tparam TObjectType - type of the object being created (IBuffer, ITexture, etc.) +/// \tparam TObjectDescType - type of the object description structure (BufferDesc, TextureDesc, etc.) /// \tparam TObjectConstructor - type of the function that constructs the object /// \param ObjectTypeName - string name of the object type ("buffer", "texture", etc.) /// \param Desc - object description diff --git a/Graphics/GraphicsEngine/include/ResourceMappingImpl.h b/Graphics/GraphicsEngine/include/ResourceMappingImpl.h index 6d412485..509632d7 100644 --- a/Graphics/GraphicsEngine/include/ResourceMappingImpl.h +++ b/Graphics/GraphicsEngine/include/ResourceMappingImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,29 +30,103 @@ #include "ObjectBase.h" #include <unordered_map> #include "HashUtils.h" +#include "STDAllocator.h" namespace Diligent { + struct ResMappingHashKey + { + ResMappingHashKey(const Char* Str, bool bMakeCopy, Uint32 ArrInd): + StrKey(Str, bMakeCopy), + ArrayIndex(ArrInd) + { + } + + ResMappingHashKey(ResMappingHashKey &&rhs) : + StrKey(std::move(rhs.StrKey)), + ArrayIndex(rhs.ArrayIndex) + {} + + bool operator == (const ResMappingHashKey& RHS)const + { + return StrKey == RHS.StrKey && ArrayIndex == RHS.ArrayIndex; + } + + size_t GetHash()const + { + if( Hash == 0 ) + { + Hash = ComputeHash( StrKey, ArrayIndex ); + } + + return Hash; + } + + + ResMappingHashKey( const ResMappingHashKey& ) = delete; + ResMappingHashKey& operator = ( const ResMappingHashKey& ) = delete; + ResMappingHashKey& operator = ( ResMappingHashKey&& ) = delete; + + HashMapStringKey StrKey; + Uint32 ArrayIndex; + mutable size_t Hash = 0; + }; +} + +namespace std +{ + template<> + struct hash<Diligent::ResMappingHashKey> + { + size_t operator()( const Diligent::ResMappingHashKey &Key ) const + { + return Key.GetHash(); + } + }; +} + +namespace Diligent +{ + class FixedBlockMemoryAllocator; + /// Implementation of the resource mapping - class ResourceMappingImpl : public ObjectBase<IResourceMapping> + class ResourceMappingImpl : public ObjectBase<IResourceMapping, FixedBlockMemoryAllocator> { public: + typedef ObjectBase<IResourceMapping, FixedBlockMemoryAllocator> TObjectBase; + + /// \param ObjAllocator allocator that was used to allocate memory for this instance of the resource mapping object. + /// \param RawMemAllocator raw memory allocator that is used by the m_HashTable member + ResourceMappingImpl(FixedBlockMemoryAllocator &ObjAllocator, IMemoryAllocator &RawMemAllocator) : + TObjectBase(nullptr, &ObjAllocator), + m_HashTable(STD_ALLOCATOR_RAW_MEM(HashTableElem, RawMemAllocator, "Allocator for unordered_map< ResMappingHashKey, RefCntAutoPtr<IDeviceObject> >") ) + {} + ~ResourceMappingImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + + /// Implementation of IResourceMapping::AddResource() + virtual void AddResource( const Char *Name, IDeviceObject *pObject, bool bIsUnique )override final; - virtual void AddResource( const Char *Name, IDeviceObject *pObject, bool bIsUnique ); - virtual void RemoveResource( IDeviceObject *pObject ); - virtual void RemoveResourceByName( const Char *Name ); + /// Implementation of IResourceMapping::AddResourceArray() + virtual void AddResourceArray( const Char *Name, Uint32 StartIndex, IDeviceObject * const* ppObjects, Uint32 NumElements, bool bIsUnique )override final; + + /// Implementation of IResourceMapping::RemoveResourceByName() + virtual void RemoveResourceByName( const Char *Name, Uint32 ArrayIndex )override final; - /// Finds resource in the mapping. If no resource is found, nullptr is returned - virtual void GetResource( const Char *Name, IDeviceObject **ppResource ); + /// Implementation of IResourceMapping::GetResource() + virtual void GetResource( const Char *Name, IDeviceObject **ppResource, Uint32 ArrayIndex )override final; + + /// Returns number of resources in the resource mapping. virtual size_t GetSize(); private: + ThreadingTools::LockHelper Lock(); ThreadingTools::LockFlag m_LockFlag; - std::unordered_map< Diligent::HashMapStringKey, Diligent::RefCntAutoPtr<IDeviceObject> > m_HashTable; + typedef std::pair<ResMappingHashKey, RefCntAutoPtr<IDeviceObject> > HashTableElem; + std::unordered_map< ResMappingHashKey, RefCntAutoPtr<IDeviceObject>, std::hash<ResMappingHashKey>, std::equal_to<ResMappingHashKey>, STDAllocatorRawMem<HashTableElem> > m_HashTable; }; } diff --git a/Graphics/GraphicsEngine/include/SamplerBase.h b/Graphics/GraphicsEngine/include/SamplerBase.h index de8ff566..cc6b8a94 100644 --- a/Graphics/GraphicsEngine/include/SamplerBase.h +++ b/Graphics/GraphicsEngine/include/SamplerBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,29 +36,30 @@ namespace Diligent /// Template class implementing base functionality for a sampler object. /// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::ISamplerD3D11 or Diligent::ISamplerGL). +/// (Diligent::ISamplerD3D11, Diligent::ISamplerD3D12 or Diligent::ISamplerGL). /// \tparam RenderDeviceBaseInterface - base interface for the render device -/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceGL, -/// or Diligent::IRenderDeviceGLES). -template<class BaseInterface = ISampler, class RenderDeviceBaseInterface = IRenderDevice> -class SamplerBase : public DeviceObjectBase<BaseInterface, SamplerDesc> +/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceD3D12, Diligent::IRenderDeviceGL, or Diligent::IRenderDeviceGLES). +/// \tparam SamplerObjAllocator - type of the allocator that is used to allocate memory for the sampler object instances +template<class BaseInterface, class RenderDeviceBaseInterface, class SamplerObjAllocator> +class SamplerBase : public DeviceObjectBase<BaseInterface, SamplerDesc, SamplerObjAllocator> { public: - typedef DeviceObjectBase<BaseInterface, SamplerDesc> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, SamplerDesc, SamplerObjAllocator> TDeviceObjectBase; typedef RenderDeviceBase<RenderDeviceBaseInterface> TRenderDeviceBase; + /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the sampler object /// \param pDevice - pointer to the device. /// \param SamDesc - sampler description. /// \param bIsDeviceInternal - flag indicating if the sampler is an internal device object and /// must not keep a strong reference to the device. - SamplerBase( IRenderDevice *pDevice, const SamplerDesc& SamDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, SamDesc, nullptr, bIsDeviceInternal ) + SamplerBase( SamplerObjAllocator &ObjAllocator, IRenderDevice *pDevice, const SamplerDesc& SamDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( ObjAllocator, pDevice, SamDesc, nullptr, bIsDeviceInternal ) {} ~SamplerBase() { /// \note Destructor cannot directly remove the object from the registry as this may cause a - /// deadlock. See BlendStateBase::~BlendStateBase() for details. + /// deadlock. auto &SamplerRegistry = static_cast<TRenderDeviceBase *>(this->GetDevice())->GetSamplerRegistry(); SamplerRegistry.ReportDeletedObject(); } diff --git a/Graphics/GraphicsEngine/include/ShaderBase.h b/Graphics/GraphicsEngine/include/ShaderBase.h index b2f89341..1e03b352 100644 --- a/Graphics/GraphicsEngine/include/ShaderBase.h +++ b/Graphics/GraphicsEngine/include/ShaderBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,39 +28,134 @@ #include "Shader.h" #include "DeviceObjectBase.h" +#include "STDAllocator.h" +#include "PlatformMisc.h" +#include "EngineMemory.h" namespace Diligent { +inline SHADER_TYPE GetShaderTypeFromIndex( Int32 Index ) +{ + return static_cast<SHADER_TYPE>(1 << Index); +} + +inline Int32 GetShaderTypeIndex( SHADER_TYPE Type ) +{ + Int32 ShaderIndex = PlatformMisc::GetLSB(Type); + +#ifdef _DEBUG + switch( Type ) + { + case SHADER_TYPE_UNKNOWN: VERIFY_EXPR(ShaderIndex == -1); break; + case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderIndex == 0); break; + case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderIndex == 1); break; + case SHADER_TYPE_GEOMETRY:VERIFY_EXPR(ShaderIndex == 2); break; + case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderIndex == 3); break; + case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderIndex == 4); break; + case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderIndex == 5); break; + default: UNEXPECTED( "Unexpected shader type (", Type, ")" ); break; + } + VERIFY( Type == GetShaderTypeFromIndex(ShaderIndex), "Incorrect shader type index" ); +#endif + return ShaderIndex; +} + +static const int VSInd = GetShaderTypeIndex(SHADER_TYPE_VERTEX); +static const int PSInd = GetShaderTypeIndex(SHADER_TYPE_PIXEL); +static const int GSInd = GetShaderTypeIndex(SHADER_TYPE_GEOMETRY); +static const int HSInd = GetShaderTypeIndex(SHADER_TYPE_HULL); +static const int DSInd = GetShaderTypeIndex(SHADER_TYPE_DOMAIN); +static const int CSInd = GetShaderTypeIndex(SHADER_TYPE_COMPUTE); + +template<typename TNameCompare> +SHADER_VARIABLE_TYPE GetShaderVariableType(SHADER_VARIABLE_TYPE DefaultVariableType, const ShaderVariableDesc *VariableDesc, Uint32 NumVars, TNameCompare NameCompare) +{ + for (Uint32 v = 0; v < NumVars; ++v) + { + const auto &CurrVarDesc = VariableDesc[v]; + if ( NameCompare(CurrVarDesc.Name) ) + { + return CurrVarDesc.Type; + } + } + return DefaultVariableType; +} + +inline SHADER_VARIABLE_TYPE GetShaderVariableType(const Char* Name, SHADER_VARIABLE_TYPE DefaultVariableType, const ShaderVariableDesc *VariableDesc, Uint32 NumVars) +{ + return GetShaderVariableType(DefaultVariableType, VariableDesc, NumVars, + [&](const char *VarName) + { + return strcmp(VarName, Name) == 0; + } + ); +} + + /// Base implementation of a shader variable -struct ShaderVariableBase : public ObjectBase<IShaderVariable> + +struct ShaderVariableBase : public IShaderVariable { - ShaderVariableBase(IShader *pShader) : - // Shader variables are always created as part of the shader, - // so we must provide owner pointer to the base class constructor - ObjectBase<IShaderVariable>(pShader), - m_pShader(pShader) - {} + ShaderVariableBase(IObject &Owner) : + // Shader variables are always created as part of the shader, or + // shader resource binding, so we must provide owner pointer to + // the base class constructor + m_Owner(Owner) + { + } - virtual IShader* GetShader()override + IObject& GetOwner() { - return m_pShader; + return m_Owner; } - IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_ShaderVariable, ObjectBase<IShaderVariable> ) + virtual IReferenceCounters* GetReferenceCounters()const override final + { + return m_Owner.GetReferenceCounters(); + } + + virtual Atomics::Long AddRef()override final + { + return m_Owner.AddRef(); + } + + virtual Atomics::Long Release()override final + { + return m_Owner.Release(); + } + + virtual void QueryInterface( const INTERFACE_ID &IID, IObject **ppInterface )override final + { + if( ppInterface == nullptr ) + return; + + *ppInterface = nullptr; + if( IID == IID_ShaderVariable || IID == IID_Unknown ) + { + *ppInterface = this; + (*ppInterface)->AddRef(); + } + } protected: - IShader *m_pShader; + IObject &m_Owner; }; /// Implementation of a dummy shader variable that silently ignores all operations struct DummyShaderVariable : ShaderVariableBase { - DummyShaderVariable(IShader *pShader) : - ShaderVariableBase(pShader) + DummyShaderVariable(IObject &Owner) : + ShaderVariableBase(Owner) {} - virtual void Set( IDeviceObject *pObject )override + virtual void Set( IDeviceObject *pObject )override final + { + // Ignore operation + // Probably output warning + } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final { // Ignore operation // Probably output warning @@ -68,25 +163,77 @@ struct DummyShaderVariable : ShaderVariableBase }; /// Template class implementing base functionality for a shader object -template<class BaseInterface = IShader, class RenderDeviceBaseInterface = IRenderDevice> -class ShaderBase : public DeviceObjectBase<BaseInterface, ShaderDesc> + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IShaderD3D11, Diligent::IShaderD3D12 or Diligent::IShaderGL). +/// \tparam RenderDeviceBaseInterface - base interface for the render device +/// (Diligent::IRenderDeviceD3D11, Diligent::IRenderDeviceD3D12, Diligent::IRenderDeviceGL, or Diligent::IRenderDeviceGLES). +/// \tparam ShaderObjAllocator - type of the allocator that is used to allocate memory for the shader object instances +template<class BaseInterface, class RenderDeviceBaseInterface, class ShaderObjAllocator> +class ShaderBase : public DeviceObjectBase<BaseInterface, ShaderDesc, ShaderObjAllocator> { public: - typedef DeviceObjectBase<BaseInterface, ShaderDesc> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, ShaderDesc, ShaderObjAllocator> TDeviceObjectBase; + /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the shader object /// \param pDevice - pointer to the device. /// \param ShdrDesc - shader description. /// \param bIsDeviceInternal - flag indicating if the shader is an internal device object and /// must not keep a strong reference to the device. - ShaderBase( IRenderDevice *pDevice, const ShaderDesc& ShdrDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, ShdrDesc, nullptr, bIsDeviceInternal ), - m_DummyShaderVar(this) - {} + ShaderBase( ShaderObjAllocator &ObjAllocator, IRenderDevice *pDevice, const ShaderDesc& ShdrDesc, bool bIsDeviceInternal = false ) : + TDeviceObjectBase( ObjAllocator, pDevice, ShdrDesc, nullptr, bIsDeviceInternal ), + m_DummyShaderVar(*this), + m_VariablesDesc(ShdrDesc.NumVariables, ShaderVariableDesc(), STD_ALLOCATOR_RAW_MEM(ShaderVariableDesc, GetRawAllocator(), "Allocator for vector<ShaderVariableDesc>") ), + m_StringPool(ShdrDesc.NumVariables + ShdrDesc.NumStaticSamplers, String(), STD_ALLOCATOR_RAW_MEM(String, GetRawAllocator(), "Allocator for vector<String>")), + m_StaticSamplers(ShdrDesc.NumStaticSamplers, StaticSamplerDesc(), STD_ALLOCATOR_RAW_MEM(StaticSamplerDesc, GetRawAllocator(), "Allocator for vector<StaticSamplerDesc>") ) + { + auto Str = m_StringPool.begin(); + if(this->m_Desc.VariableDesc) + { + for (Uint32 v = 0; v < this->m_Desc.NumVariables; ++v, ++Str) + { + m_VariablesDesc[v] = this->m_Desc.VariableDesc[v]; + VERIFY( m_VariablesDesc[v].Name != nullptr, "Variable name not provided" ) + *Str = m_VariablesDesc[v].Name; + m_VariablesDesc[v].Name = Str->c_str(); + } + this->m_Desc.VariableDesc = m_VariablesDesc.data(); + } + if(this->m_Desc.StaticSamplers) + { + for (Uint32 s = 0; s < this->m_Desc.NumStaticSamplers; ++s, ++Str) + { + m_StaticSamplers[s] = this->m_Desc.StaticSamplers[s]; + VERIFY( m_StaticSamplers[s].TextureName != nullptr, "Static sampler texture name not provided" ) + *Str = m_StaticSamplers[s].TextureName; + m_StaticSamplers[s].TextureName = Str->c_str(); +#ifdef _DEBUG + const auto &BorderColor = m_StaticSamplers[s].Desc.BorderColor; + if( !(BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 0 || + BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 1 || + BorderColor[0] == 1 && BorderColor[1] == 1 && BorderColor[2] == 1 && BorderColor[3] == 0) ) + { + LOG_WARNING_MESSAGE("Static sampler for variable \"", *Str , "\" specifies border color (", BorderColor[0], ", ", BorderColor[1], ", ", BorderColor[2], ", ", BorderColor[3], "). D3D12 static samplers only allow transparent black (0,0,0,1), opaque black (0,0,0,0) or opaque white (1,1,1,0) as border colors") + } +#endif + } + this->m_Desc.StaticSamplers = m_StaticSamplers.data(); + } + + VERIFY_EXPR(Str == m_StringPool.end()) + } IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Shader, TDeviceObjectBase ) protected: DummyShaderVariable m_DummyShaderVar; ///< Dummy shader variable + + /// Shader variable descriptions + std::vector<ShaderVariableDesc, STDAllocatorRawMem<ShaderVariableDesc> > m_VariablesDesc; + /// String pool that is used to hold copies of variable names and static sampler names + std::vector<String, STDAllocatorRawMem<String> > m_StringPool; + /// Static sampler descriptions + std::vector<StaticSamplerDesc, STDAllocatorRawMem<StaticSamplerDesc> > m_StaticSamplers; }; } diff --git a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h new file mode 100644 index 00000000..ce5435f7 --- /dev/null +++ b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h @@ -0,0 +1,75 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::ShaderResourceBindingBase template class + +#include "ShaderResourceBinding.h" +#include "ObjectBase.h" +#include "GraphicsTypes.h" +#include "RefCntAutoPtr.h" + +namespace Diligent +{ + +/// Template class implementing base functionality for a shader resource binding + +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::IShaderResourceBindingGL, Diligent::IShaderResourceBindingD3D11, or Diligent::IShaderResourceBindingD3D12). +/// \tparam SRBAllocator - type of the allocator that is used to allocate memory for the shader resource binding object instances +template<class BaseInterface, class SRBAllocator> +class ShaderResourceBindingBase : public ObjectBase<BaseInterface, SRBAllocator> +{ +public: + typedef ObjectBase<BaseInterface, SRBAllocator> TObjectBase; + + /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the shader resource binding object + /// \param pPSO - pipeline state that this SRB belongs to. + /// \param IsInternal - flag indicating if the shader resource binding is an internal PSO object and + /// must not keep a strong reference to the PSO. + ShaderResourceBindingBase( SRBAllocator &ObjAllocator, IPipelineState *pPSO, bool IsInternal = false ) : + TObjectBase( IsInternal ? pPSO : nullptr, &ObjAllocator ), + m_pPSO( pPSO ), + m_spPSO( IsInternal ? nullptr : pPSO ) + {} + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_ShaderResourceBinding, TObjectBase ) + + /// Implementation of IShaderResourceBinding::GetPipelineState(). + virtual IPipelineState* GetPipelineState()override final + { + return m_pPSO; + } + +protected: + + /// Strong reference to PSO. We must use strong reference, because + /// shader resource binding uses PSO's memory allocator to allocate + /// memory for shader resource cache. + Diligent::RefCntAutoPtr<IPipelineState> m_spPSO; + IPipelineState *m_pPSO; +}; + +} diff --git a/Graphics/GraphicsEngine/include/StateObjectsRegistry.h b/Graphics/GraphicsEngine/include/StateObjectsRegistry.h index e26d1183..35840476 100644 --- a/Graphics/GraphicsEngine/include/StateObjectsRegistry.h +++ b/Graphics/GraphicsEngine/include/StateObjectsRegistry.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ #include "DeviceObject.h" #include <unordered_map> +#include "STDAllocator.h" namespace Diligent { @@ -60,8 +61,9 @@ namespace Diligent /// Number of outstanding deleted objects to purge the registry. static const int DeletedObjectsToPurge = 32; - StateObjectsRegistry(const Char* RegistryName) : - m_RegistryName( RegistryName ) + StateObjectsRegistry(IMemoryAllocator &RawAllocator, const Char* RegistryName) : + m_RegistryName( RegistryName ), + m_DescToObjHashMap(STD_ALLOCATOR_RAW_MEM(HashMapElem, RawAllocator, "Allocator for unordered_map<ResourceDescType, RefCntWeakPtr<IDeviceObject> >") ) {} ~StateObjectsRegistry() @@ -196,7 +198,8 @@ namespace Diligent Atomics::AtomicLong m_NumDeletedObjects; /// Hash map that stores weak pointers to the referenced objects - std::unordered_map<ResourceDescType, Diligent::RefCntWeakPtr<IDeviceObject> > m_DescToObjHashMap; + typedef std::pair< ResourceDescType, RefCntWeakPtr<IDeviceObject> > HashMapElem; + std::unordered_map<ResourceDescType, RefCntWeakPtr<IDeviceObject>, std::hash<ResourceDescType>, std::equal_to<ResourceDescType>, STDAllocatorRawMem<HashMapElem> > m_DescToObjHashMap; /// Registry name used for debug output const String m_RegistryName; diff --git a/Graphics/GraphicsEngine/include/SwapChainBase.h b/Graphics/GraphicsEngine/include/SwapChainBase.h index c3400877..9b65e80f 100644 --- a/Graphics/GraphicsEngine/include/SwapChainBase.h +++ b/Graphics/GraphicsEngine/include/SwapChainBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,17 +34,26 @@ namespace Diligent /// Base implementation of the swap chain. +/// \tparam BaseInterface - base interface that this class will inheret +/// (Diligent::ISwapChainGL, Diligent::ISwapChainD3D11, or Diligent::ISwapChainD3D12). +/// \tparam SwapChainAllocator - type of the allocator that is used to allocate memory for the swap chain object instance /// \remarks Swap chain holds the strong reference to the device and a weak reference to the /// immediate context. -template<class BaseInterface = ISwapChain> -class SwapChainBase : public ObjectBase<BaseInterface> +template<class BaseInterface, class SwapChainAllocator> +class SwapChainBase : public ObjectBase<BaseInterface, SwapChainAllocator> { public: - typedef ObjectBase<BaseInterface> TObjectBase; + typedef ObjectBase<BaseInterface, SwapChainAllocator> TObjectBase; - SwapChainBase( IRenderDevice *pDevice, - IDeviceContext *pDeviceContext, - const SwapChainDesc& SCDesc ) : + /// \param Allocator - allocator that was used to allocate memory for this instance of the swap chain object + /// \param pDevice - pointer to the device. + /// \param pDeviceContext - pointer to the device context. + /// \param SCDesc - swap chain description + SwapChainBase( SwapChainAllocator &Allocator, + IRenderDevice *pDevice, + IDeviceContext *pDeviceContext, + const SwapChainDesc& SCDesc ) : + TObjectBase(nullptr, &Allocator), m_pRenderDevice(pDevice), m_wpDeviceContext(pDeviceContext), m_SwapChainDesc(SCDesc) @@ -57,7 +66,8 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_SwapChain, TObjectBase ) - virtual const SwapChainDesc& GetDesc()const + /// Implementation of ISwapChain::GetDesc() + virtual const SwapChainDesc& GetDesc()const override final { return m_SwapChainDesc; } @@ -70,6 +80,7 @@ protected: { m_SwapChainDesc.Width = NewWidth; m_SwapChainDesc.Height = NewHeight; + LOG_INFO_MESSAGE("Changing display resolution to ", m_SwapChainDesc.Width, "x", m_SwapChainDesc.Height); return true; } diff --git a/Graphics/GraphicsEngine/include/TextureBase.h b/Graphics/GraphicsEngine/include/TextureBase.h index 094de62d..4769a97f 100644 --- a/Graphics/GraphicsEngine/include/TextureBase.h +++ b/Graphics/GraphicsEngine/include/TextureBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ #include "Texture.h" #include "DeviceObjectBase.h" #include "GraphicsUtilities.h" +#include "STDAllocator.h" #include <memory> namespace Diligent @@ -43,49 +44,61 @@ void VliadateCopyTextureDataParams( const TextureDesc &SrcTexDesc, Uint32 SrcMip /// Base implementation of the ITexture interface /// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::ITextureD3D11 or Diligent::ITextureGL). +/// (Diligent::ITextureD3D11, Diligent::ITextureD3D12 or Diligent::ITextureGL). /// \tparam TTextureViewImpl - type of the texture view implementation -/// (Diligent::TextureViewD3D11Impl or Diligent::TextureViewGLImpl). -template<class BaseInterface, class TTextureViewImpl> -class TextureBase : public DeviceObjectBase<BaseInterface, TextureDesc> +/// (Diligent::TextureViewD3D11Impl, Diligent::TextureViewD3D12Impl or Diligent::TextureViewGLImpl). +/// \tparam TTexObjAllocator - type of the allocator that is used to allocate memory for the texture object instances +/// \tparam TTexViewObjAllocator - type of the allocator that is used to allocate memory for the texture view object instances +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +class TextureBase : public DeviceObjectBase<BaseInterface, TextureDesc, TTexObjAllocator> { public: - typedef DeviceObjectBase<BaseInterface, TextureDesc> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, TextureDesc, TTexObjAllocator> TDeviceObjectBase; + /// \param TexObjAllocator - allocator that was used to allocate memory for this instance of the texture object + /// \param TexViewObjAllocator - allocator that is used to allocate memory for the instances of the texture view object. + /// This parameter is only used for debug purposes. /// \param pDevice - pointer to the device /// \param Desc - texture description /// \param bIsDeviceInternal - flag indicating if the texture is an internal device object and /// must not keep a strong reference to the device - TextureBase( IRenderDevice *pDevice, const TextureDesc& Desc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, Desc, nullptr, bIsDeviceInternal ) + TextureBase( TTexObjAllocator &TexObjAllocator, + TTexViewObjAllocator &TexViewObjAllocator, + IRenderDevice *pDevice, + const TextureDesc& Desc, + bool bIsDeviceInternal = false ) : + TDeviceObjectBase( TexObjAllocator, pDevice, Desc, nullptr, bIsDeviceInternal ), +#ifdef _DEBUG + m_dbgTexViewObjAllocator(TexViewObjAllocator), +#endif + m_pDefaultSRV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)), + m_pDefaultRTV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)), + m_pDefaultDSV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)), + m_pDefaultUAV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)) { if( this->m_Desc.MipLevels == 0 ) { - // Compute the number of levels in the full mipmap chain based - // on the maximum texture dimension - Uint32 MaxDim = 0; - if( this->m_Desc.Type == TEXTURE_TYPE_1D || - this->m_Desc.Type == TEXTURE_TYPE_1D_ARRAY ) + // Compute the number of levels in the full mipmap chain + if( this->m_Desc.Type == RESOURCE_DIM_TEX_1D || + this->m_Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) { - MaxDim = this->m_Desc.Width; + this->m_Desc.MipLevels = ComputeMipLevelsCount(this->m_Desc.Width); } - else if( this->m_Desc.Type == TEXTURE_TYPE_2D || - this->m_Desc.Type == TEXTURE_TYPE_2D_ARRAY ) + else if( this->m_Desc.Type == RESOURCE_DIM_TEX_2D || + this->m_Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || + this->m_Desc.Type == RESOURCE_DIM_TEX_CUBE || + this->m_Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY ) { - MaxDim = std::max( this->m_Desc.Width, this->m_Desc.Height ); + this->m_Desc.MipLevels = ComputeMipLevelsCount( this->m_Desc.Width, this->m_Desc.Height ); } - else if( this->m_Desc.Type == TEXTURE_TYPE_3D ) + else if( this->m_Desc.Type == RESOURCE_DIM_TEX_3D ) { - MaxDim = std::max( this->m_Desc.Width, this->m_Desc.Height ); - MaxDim = std::max( MaxDim, this->m_Desc.Depth ); + this->m_Desc.MipLevels = ComputeMipLevelsCount( this->m_Desc.Width, this->m_Desc.Height, this->m_Desc.Depth ); } else { UNEXPECTED( "Unkwnown texture type" ); } - while( (MaxDim >> this->m_Desc.MipLevels) > 0 ) - ++this->m_Desc.MipLevels; - VERIFY( MaxDim >= (1U << (this->m_Desc.MipLevels-1)) && MaxDim < (1U << this->m_Desc.MipLevels), "Incorrect number of Mip levels" ) } // Validate correctness of texture description @@ -94,14 +107,17 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Texture, TDeviceObjectBase ) + /// Implementaiton of ITexture::CreateView(); calls CreateViewInternal() virtual function that + /// creates texture view for the specific engine implementation. virtual void CreateView( const struct TextureViewDesc &ViewDesc, ITextureView **ppView )override { CreateViewInternal( ViewDesc, ppView, false ); } + /// Base implementaiton of ITexture::UpdateData(); validates input parameters virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) = 0; - + /// Base implementaiton of ITexture::CopyData(); validates input parameters virtual void CopyData( IDeviceContext *pContext, ITexture *pSrcTexture, Uint32 SrcMipLevel, @@ -113,22 +129,42 @@ public: Uint32 DstY, Uint32 DstZ ) = 0; + /// Base implementaiton of ITexture::Map() virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) = 0; - virtual void Unmap( IDeviceContext *pContext ) = 0; + /// Base implementaiton of ITexture::Unmap() + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) = 0; + + /// Creates default texture views. + /// + /// - Creates default shader resource view addressing the entire texture if Diligent::BIND_SHADER_RESOURCE flag is set. + /// - Creates default render target view addressing the most detailed mip level if Diligent::BIND_RENDER_TARGET flag is set. + /// - Creates default depth-stencil view addressing the most detailed mip level if Diligent::BIND_DEPTH_STENCIL flag is set. + /// - Creates default unordered access view addressing the entire texture if Diligent::BIND_UNORDERED_ACCESS flag is set. + /// + /// The function calls CreateViewInternal(). void CreateDefaultViews(); protected: + /// Pure virtual function that creates texture view for the specific engine implementation. virtual void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView ) = 0; +#ifdef _DEBUG + TTexViewObjAllocator &m_dbgTexViewObjAllocator; +#endif // WARNING! We cannot use ITextureView here, because ITextureView has no virtual dtor! - std::unique_ptr<TTextureViewImpl> m_pDefaultSRV; - std::unique_ptr<TTextureViewImpl> m_pDefaultRTV; - std::unique_ptr<TTextureViewImpl> m_pDefaultDSV; - std::unique_ptr<TTextureViewImpl> m_pDefaultUAV; - + /// Default SRV addressing the entire texture + std::unique_ptr<TTextureViewImpl, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>> m_pDefaultSRV; + /// Default RTV addressing the most detailed mip level + std::unique_ptr<TTextureViewImpl, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>> m_pDefaultRTV; + /// Default DSV addressing the most detailed mip level + std::unique_ptr<TTextureViewImpl, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>> m_pDefaultDSV; + /// Default UAV addressing the entire texture + std::unique_ptr<TTextureViewImpl, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>> m_pDefaultUAV; + + /// Implementation of ITexture::GetDefaultView(). ITextureView* GetDefaultView( TEXTURE_VIEW_TYPE ViewType )override { switch( ViewType ) @@ -150,8 +186,8 @@ protected: }; -template<class BaseInterface, class TTextureViewImpl> -TEXTURE_FORMAT TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureViewFormat( TEXTURE_FORMAT Fmt, TEXTURE_VIEW_TYPE TexViewType ) +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +TEXTURE_FORMAT TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CorrectTextureViewFormat( TEXTURE_FORMAT Fmt, TEXTURE_VIEW_TYPE TexViewType ) { // Correct texture view format for depth stencil view if( TexViewType == TEXTURE_VIEW_DEPTH_STENCIL ) @@ -203,8 +239,8 @@ TEXTURE_FORMAT TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureVie return Fmt; } -template<class BaseInterface, class TTextureViewImpl> -void TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureViewDesc(struct TextureViewDesc &ViewDesc) +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CorrectTextureViewDesc(struct TextureViewDesc &ViewDesc) { #define TEX_VIEW_VALIDATION_ERROR(...) LOG_ERROR_AND_THROW( "Texture view \"", ViewDesc.Name ? ViewDesc.Name : "", "\": ", ##__VA_ARGS__ ); @@ -217,65 +253,159 @@ void TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureViewDesc(stru if( ViewDesc.Format == TEX_FORMAT_UNKNOWN ) ViewDesc.Format = CorrectTextureViewFormat( this->m_Desc.Format, ViewDesc.ViewType ); - if( ViewDesc.TextureType == TEXTURE_TYPE_UNDEFINED ) - ViewDesc.TextureType = this->m_Desc.Type; + if( ViewDesc.TextureDim == RESOURCE_DIM_UNDEFINED ) + { + if (this->m_Desc.Type == RESOURCE_DIM_TEX_CUBE || this->m_Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) + { + switch (ViewDesc.ViewType) + { + case TEXTURE_VIEW_SHADER_RESOURCE: + ViewDesc.TextureDim = this->m_Desc.Type; + break; + + case TEXTURE_VIEW_RENDER_TARGET: + case TEXTURE_VIEW_DEPTH_STENCIL: + case TEXTURE_VIEW_UNORDERED_ACCESS: + ViewDesc.TextureDim = RESOURCE_DIM_TEX_2D_ARRAY; + break; + + default: UNEXPECTED("Unexpected view type") + } + } + else + { + ViewDesc.TextureDim = this->m_Desc.Type; + } + } switch( this->m_Desc.Type ) { - case TEXTURE_TYPE_1D: - if( ViewDesc.TextureType != TEXTURE_TYPE_1D ) + case RESOURCE_DIM_TEX_1D: + if( ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D ) { TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 1D view: only Texture 1D is allowed" ); } break; - case TEXTURE_TYPE_1D_ARRAY: - if( ViewDesc.TextureType != TEXTURE_TYPE_1D_ARRAY && - ViewDesc.TextureType != TEXTURE_TYPE_1D ) + case RESOURCE_DIM_TEX_1D_ARRAY: + if( ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D_ARRAY && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D ) { TEX_VIEW_VALIDATION_ERROR( "Incorrect view type for Texture 1D Array: only Texture 1D or Texture 1D Array are allowed" ); } break; - case TEXTURE_TYPE_2D: - if(ViewDesc.TextureType != TEXTURE_TYPE_2D ) + case RESOURCE_DIM_TEX_2D: + if(ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D ) { TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 2D view: only Texture 2D is allowed" ); } break; - case TEXTURE_TYPE_2D_ARRAY: - if( ViewDesc.TextureType != TEXTURE_TYPE_2D_ARRAY && - ViewDesc.TextureType != TEXTURE_TYPE_2D ) + case RESOURCE_DIM_TEX_2D_ARRAY: + if( ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D ) { TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 2D Array view: only Texture 2D or Texture 2D Array are allowed" ); } break; - case TEXTURE_TYPE_3D: - if( ViewDesc.TextureType != TEXTURE_TYPE_3D ) + case RESOURCE_DIM_TEX_3D: + if( ViewDesc.TextureDim != RESOURCE_DIM_TEX_3D ) { TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture 3D view: only Texture 3D is allowed" ); } break; + case RESOURCE_DIM_TEX_CUBE: + if(ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE) + { + if(ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture cube SRV: Texture 2D, Texture 2D array or Texture Cube is allowed" ); + } + } + else + { + if(ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture cube non-shader resource view: Texture 2D or Texture 2D array is allowed" ); + } + } + break; + + case RESOURCE_DIM_TEX_CUBE_ARRAY: + if(ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE) + { + if(ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE_ARRAY) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture cube array SRV: Texture 2D, Texture 2D array, Texture Cube or Texture Cube Array is allowed" ); + } + } + else + { + if(ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D && + ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY) + { + TEX_VIEW_VALIDATION_ERROR( "Incorrect texture type for Texture cube array non-shader resource view: Texture 2D or Texture 2D array is allowed" ); + } + } + break; + default: UNEXPECTED( "Unexpected texture type" ); break; } - if( ViewDesc.TextureType == TEXTURE_TYPE_1D_ARRAY || - ViewDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + if ( ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE ) + { + VERIFY(ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Unexpected view type: SRV is expected"); + if(ViewDesc.NumArraySlices != 6 && ViewDesc.NumArraySlices != 0) + TEX_VIEW_VALIDATION_ERROR( "Texture cube SRV is expected to have 6 array slices, while ", ViewDesc.NumArraySlices, " is provided" ); + if(ViewDesc.FirstArraySlice != 0) + TEX_VIEW_VALIDATION_ERROR( "First slice (", ViewDesc.FirstArraySlice, ") must be 0 for non-array texture cube SRV" ); + } + if ( ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY ) + { + VERIFY(ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Unexpected view type: SRV is expected"); + if((ViewDesc.NumArraySlices % 6) != 0) + TEX_VIEW_VALIDATION_ERROR( "Number of slices in texture cube array SRV is expected to be multiple of 6. ", ViewDesc.NumArraySlices, " slices provided." ); + } + + if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D || + ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D) + { + if(ViewDesc.FirstArraySlice != 0) + TEX_VIEW_VALIDATION_ERROR( "First slice (", ViewDesc.FirstArraySlice, ") must be 0 for non-array texture 1D/2D views" ); + + if(ViewDesc.NumArraySlices > 1) + TEX_VIEW_VALIDATION_ERROR( "Number of slices in the view (", ViewDesc.NumArraySlices, ") must be 1 (or 0) for non-array texture 1D/2D views" ); + } + else if( ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY || + ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY || + ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE || + ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY ) { if( ViewDesc.FirstArraySlice + ViewDesc.NumArraySlices > this->m_Desc.ArraySize ) TEX_VIEW_VALIDATION_ERROR( "First slice (", ViewDesc.FirstArraySlice, ") and number of slices in the view (", ViewDesc.NumArraySlices, ") specify more slices than target texture has (", this->m_Desc.ArraySize, ")" ); } - else if( ViewDesc.TextureType == TEXTURE_TYPE_3D ) + else if( ViewDesc.TextureDim == RESOURCE_DIM_TEX_3D ) { auto MipDepth = this->m_Desc.Depth >> ViewDesc.MostDetailedMip; if( ViewDesc.FirstDepthSlice + ViewDesc.NumDepthSlices > MipDepth ) TEX_VIEW_VALIDATION_ERROR( "First slice (", ViewDesc.FirstDepthSlice, ") and number of slices in the view (", ViewDesc.NumDepthSlices, ") specify more slices than target 3D texture mip level has (", MipDepth, ")" ); } + else + { + UNEXPECTED("Unexpected texture dimension") + } + #undef TEX_VIEW_VALIDATION_ERROR if( ViewDesc.NumMipLevels == 0 ) @@ -288,10 +418,12 @@ void TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureViewDesc(stru if( ViewDesc.NumArraySlices == 0 ) { - if( ViewDesc.TextureType == TEXTURE_TYPE_1D_ARRAY || - ViewDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) + if( ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY || + ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY || + ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE || + ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY ) ViewDesc.NumArraySlices = this->m_Desc.ArraySize - ViewDesc.FirstArraySlice; - else if( ViewDesc.TextureType == TEXTURE_TYPE_3D ) + else if( ViewDesc.TextureDim == RESOURCE_DIM_TEX_3D ) { auto MipDepth = this->m_Desc.Depth >> ViewDesc.MostDetailedMip; ViewDesc.NumDepthSlices = MipDepth - ViewDesc.FirstDepthSlice; @@ -311,8 +443,8 @@ void TextureBase<BaseInterface, TTextureViewImpl> :: CorrectTextureViewDesc(stru } } -template<class BaseInterface, class TTextureViewImpl> -void TextureBase<BaseInterface, TTextureViewImpl> :: CreateDefaultViews() +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CreateDefaultViews() { if(this->m_Desc.BindFlags & BIND_SHADER_RESOURCE ) { @@ -357,14 +489,14 @@ void TextureBase<BaseInterface, TTextureViewImpl> :: CreateDefaultViews() } -template<class BaseInterface, class TTextureViewImpl> -void TextureBase<BaseInterface, TTextureViewImpl> :: UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { ValidateUpdateDataParams( this->m_Desc, MipLevel, Slice, DstBox, SubresData ); } -template<class BaseInterface, class TTextureViewImpl> -void TextureBase<BaseInterface, TTextureViewImpl> :: CopyData( IDeviceContext *pContext, +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: CopyData( IDeviceContext *pContext, ITexture *pSrcTexture, Uint32 SrcMipLevel, Uint32 SrcSlice, @@ -381,13 +513,13 @@ void TextureBase<BaseInterface, TTextureViewImpl> :: CopyData( IDeviceContext *p this->GetDesc(), DstMipLevel, DstSlice, DstX, DstY, DstZ ); } -template<class BaseInterface, class TTextureViewImpl> -void TextureBase<BaseInterface, TTextureViewImpl> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) { } -template<class BaseInterface, class TTextureViewImpl> -void TextureBase<BaseInterface, TTextureViewImpl> :: Unmap( IDeviceContext *pContext ) +template<class BaseInterface, class TTextureViewImpl, class TTexObjAllocator, class TTexViewObjAllocator> +void TextureBase<BaseInterface, TTextureViewImpl, TTexObjAllocator, TTexViewObjAllocator> :: Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) { } diff --git a/Graphics/GraphicsEngine/include/TextureViewBase.h b/Graphics/GraphicsEngine/include/TextureViewBase.h index af2c93d8..92dbb647 100644 --- a/Graphics/GraphicsEngine/include/TextureViewBase.h +++ b/Graphics/GraphicsEngine/include/TextureViewBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,21 +37,31 @@ namespace Diligent /// Template class implementing base functionality for a texture view interface /// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::ITextureViewD3D11 or Diligent::ITextureViewGL). -template<class BaseInterface = ITextureView> -class TextureViewBase : public DeviceObjectBase<BaseInterface, TextureViewDesc> +/// (Diligent::ITextureViewD3D11, Diligent::ITextureViewD3D12 or Diligent::ITextureViewGL). +/// \taparam TexViewObjAllocator - type of the allocator that is used to allocate memory for the texture view object instances +template<class BaseInterface, class TexViewObjAllocator> +class TextureViewBase : public DeviceObjectBase<BaseInterface, TextureViewDesc, TexViewObjAllocator> { public: - typedef DeviceObjectBase<BaseInterface, TextureViewDesc> TDeviceObjectBase; + typedef DeviceObjectBase<BaseInterface, TextureViewDesc, TexViewObjAllocator> TDeviceObjectBase; - TextureViewBase( IRenderDevice *pDevice, - const TextureViewDesc& ViewDesc, - class ITexture *pTexture, - bool bIsDefaultView ) : + + /// \param ObjAllocator - allocator that was used to allocate memory for this instance of the texture view object + /// \param pDevice - pointer to the render device. + /// \param ViewDesc - texture view description. + /// \param pTexture - pointer to the texture that the view is to be created for. + /// \param bIsDefaultView - flag indicating if the view is default view, and is thus + /// part of the texture object. In this case the view will attach + /// to the texture's reference counters. + TextureViewBase( TexViewObjAllocator &ObjAllocator, + IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + class ITexture *pTexture, + bool bIsDefaultView ) : // Default views are created as part of the texture, so we cannot not keep strong // reference to the texture to avoid cyclic links. Instead, we will attach to the // reference counters of the texture. - TDeviceObjectBase( pDevice, ViewDesc, bIsDefaultView ? pTexture : nullptr ), + TDeviceObjectBase( ObjAllocator, pDevice, ViewDesc, bIsDefaultView ? pTexture : nullptr ), m_pTexture( pTexture ), // For non-default view, we will keep strong reference to texture m_spTexture(bIsDefaultView ? nullptr : pTexture) @@ -59,18 +69,21 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_TextureView, TDeviceObjectBase ) - virtual void SetSampler( class ISampler *pSampler ) + /// Implementation of ITextureView::SetSampler() + virtual void SetSampler( class ISampler *pSampler )override final { VERIFY( this->m_Desc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Texture view \"", this->m_Desc.Name, "\": A sampler can be attached to a shader resource view only. The view type is ", GetTexViewTypeLiteralName(this->m_Desc.ViewType) ); m_pSampler = pSampler; } - virtual ISampler* GetSampler() + /// Implementation of ITextureView::GetSampler() + virtual ISampler* GetSampler()override final { return m_pSampler; } - virtual ITexture* GetTexture() + /// Implementation of ITextureView::GetTexture() + virtual ITexture* GetTexture()override final { return m_pTexture; } diff --git a/Graphics/GraphicsEngine/include/VertexDescriptionBase.h b/Graphics/GraphicsEngine/include/VertexDescriptionBase.h deleted file mode 100644 index fdab3db6..00000000 --- a/Graphics/GraphicsEngine/include/VertexDescriptionBase.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Implementation of the Diligent::VertexDescriptionBase template class - -#include "VertexDescription.h" -#include "DeviceObjectBase.h" -#include "GraphicsUtilities.h" - -namespace Diligent -{ - -/// Template class implementing base functionality for a vertex description object - -/// \tparam BaseInterface - base interface that this class will inheret -/// (Diligent::IVertexDescriptionD3D11 or Diligent::IVertexDescriptionGL). -template<class BaseInterface = IVertexDescription> -class VertexDescriptionBase : public DeviceObjectBase<BaseInterface, LayoutDesc> -{ -public: - typedef DeviceObjectBase<BaseInterface, LayoutDesc> TDeviceObjectBase; - - /// \param pDevice - pointer to the device. - /// \param LayoutDesc - layout description. - /// \param bIsDeviceInternal - flag indicating if the vertex description is an internal device object and - /// must not keep a strong reference to the device. - VertexDescriptionBase( IRenderDevice *pDevice, const LayoutDesc &LayoutDesc, bool bIsDeviceInternal = false ) : - TDeviceObjectBase( pDevice, LayoutDesc, nullptr, bIsDeviceInternal), - m_TightStrides( MaxBufferSlots ), // The size of this array must be equal to the - // maximum number of buffer slots, because a layout - // element can refer to any input slot - m_LayoutElements( LayoutDesc.NumElements ) - { - for( size_t Elem = 0; Elem < LayoutDesc.NumElements; ++Elem ) - m_LayoutElements[Elem] = LayoutDesc.LayoutElements[Elem]; - this->m_Desc.LayoutElements = m_LayoutElements.data(); - - // Correct description and compute offsets and tight strides - for( auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It ) - { - if( It->ValueType == VT_FLOAT32 || It->ValueType == VT_FLOAT16 ) - It->IsNormalized = false; // Floating point values cannot be normalized - - auto BuffSlot = It->BufferSlot; - if( BuffSlot >= m_TightStrides.size() ) - m_TightStrides.resize( BuffSlot + 1 ); - - auto &CurrStride = m_TightStrides[BuffSlot]; - if( It->RelativeOffset < CurrStride ) - { - if( It->RelativeOffset == 0 ) - It->RelativeOffset = CurrStride; - else - UNEXPECTED( "Overlapping layout elements" ); - } - - CurrStride += It->NumComponents * GetValueSize( It->ValueType ); - } - } - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_VertexDescription, TDeviceObjectBase ) - - virtual const Uint32* GetTightStrides() - { - return m_TightStrides.data(); - } - -protected: - std::vector<LayoutElement> m_LayoutElements; - std::vector<Uint32> m_TightStrides; -}; - -} diff --git a/Graphics/GraphicsEngine/include/pch.h b/Graphics/GraphicsEngine/include/pch.h index c911c398..cdc2f875 100644 --- a/Graphics/GraphicsEngine/include/pch.h +++ b/Graphics/GraphicsEngine/include/pch.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngine/interface/BlendState.h b/Graphics/GraphicsEngine/interface/BlendState.h index 3673bfae..2e14e9eb 100644 --- a/Graphics/GraphicsEngine/interface/BlendState.h +++ b/Graphics/GraphicsEngine/interface/BlendState.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,99 +24,94 @@ #pragma once /// \file -/// Definition of the Diligent::IBlendState interface and related data structures +/// Blend state description -#include "DeviceObject.h" +#include "BasicTypes.h" namespace Diligent { -/// IBlendState interface unique identifier -// {81CFB7AC-6B9F-45FA-ACE2-CC6A9EDE4E75} -static const Diligent::INTERFACE_ID IID_BlendState = -{ 0x81cfb7ac, 0x6b9f, 0x45fa, { 0xac, 0xe2, 0xcc, 0x6a, 0x9e, 0xde, 0x4e, 0x75 } }; - - /// Blend factors /// [D3D11_BLEND]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476086(v=vs.85).aspx +/// [D3D12_BLEND]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770338(v=vs.85).aspx /// [glBlendFuncSeparate]: https://www.opengl.org/wiki/GLAPI/glBlendFuncSeparate /// This enumeration defines blend factors for alpha-blending. -/// It generatlly mirrows [D3D11_BLEND][] enumeration and is used by RenderTargetBlendDesc structure +/// It generatlly mirrors [D3D11_BLEND][] and [D3D12_BLEND][] enumerations and is used by RenderTargetBlendDesc structure /// to define source and destination blend factors for color and alpha channels. -/// \sa [D3D11_BLEND on MSDN][D3D11_BLEND], [glBlendFuncSeparate on OpenGL.org][glBlendFuncSeparate] +/// \sa [D3D11_BLEND on MSDN][D3D11_BLEND], [D3D12_BLEND on MSDN][D3D12_BLEND], [glBlendFuncSeparate on OpenGL.org][glBlendFuncSeparate] enum BLEND_FACTOR : Int32 { /// Undefined blend factor BLEND_FACTOR_UNDEFINED = 0, /// The blend factor is zero.\n - /// D3D11 counterpart: D3D11_BLEND_ZERO. OpenGL counterpart: GL_ZERO. + /// Direct3D counterpart: D3D11_BLEND_ZERO/D3D12_BLEND_ZERO. OpenGL counterpart: GL_ZERO. BLEND_FACTOR_ZERO, /// The blend factor is one.\n - /// D3D11 counterpart: D3D11_BLEND_ONE. OpenGL counterpart: GL_ONE. + /// Direct3D counterpart: D3D11_BLEND_ONE/D3D12_BLEND_ONE. OpenGL counterpart: GL_ONE. BLEND_FACTOR_ONE, /// The blend factor is RGB data from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_SRC_COLOR. OpenGL counterpart: GL_SRC_COLOR. + /// Direct3D counterpart: D3D11_BLEND_SRC_COLOR/D3D12_BLEND_SRC_COLOR. OpenGL counterpart: GL_SRC_COLOR. BLEND_FACTOR_SRC_COLOR, /// The blend factor is 1-RGB, where RGB is the data from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_INV_SRC_COLOR. OpenGL counterpart: GL_ONE_MINUS_SRC_COLOR. + /// Direct3D counterpart: D3D11_BLEND_INV_SRC_COLOR/D3D12_BLEND_INV_SRC_COLOR. OpenGL counterpart: GL_ONE_MINUS_SRC_COLOR. BLEND_FACTOR_INV_SRC_COLOR, /// The blend factor is alpha (A) data from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_SRC_ALPHA. OpenGL counterpart: GL_SRC_ALPHA. + /// Direct3D counterpart: D3D11_BLEND_SRC_ALPHA/D3D12_BLEND_SRC_ALPHA. OpenGL counterpart: GL_SRC_ALPHA. BLEND_FACTOR_SRC_ALPHA, /// The blend factor is 1-A, where A is alpha data from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_INV_SRC_ALPHA. OpenGL counterpart: GL_ONE_MINUS_SRC_ALPHA. + /// Direct3D counterpart: D3D11_BLEND_INV_SRC_ALPHA/D3D12_BLEND_INV_SRC_ALPHA. OpenGL counterpart: GL_ONE_MINUS_SRC_ALPHA. BLEND_FACTOR_INV_SRC_ALPHA, /// The blend factor is alpha (A) data from a render target.\n - /// D3D11 counterpart: D3D11_BLEND_DEST_ALPHA. OpenGL counterpart: GL_DST_ALPHA. + /// Direct3D counterpart: D3D11_BLEND_DEST_ALPHA/D3D12_BLEND_DEST_ALPHA. OpenGL counterpart: GL_DST_ALPHA. BLEND_FACTOR_DEST_ALPHA, /// The blend factor is 1-A, where A is alpha data from a render target.\n - /// D3D11 counterpart: D3D11_BLEND_INV_DEST_ALPHA. OpenGL counterpart: GL_ONE_MINUS_DST_ALPHA. + /// Direct3D counterpart: D3D11_BLEND_INV_DEST_ALPHA/D3D12_BLEND_INV_DEST_ALPHA. OpenGL counterpart: GL_ONE_MINUS_DST_ALPHA. BLEND_FACTOR_INV_DEST_ALPHA, /// The blend factor is RGB data from a render target.\n - /// D3D11 counterpart: D3D11_BLEND_DEST_COLOR. OpenGL counterpart: GL_DST_COLOR. + /// Direct3D counterpart: D3D11_BLEND_DEST_COLOR/D3D12_BLEND_DEST_COLOR. OpenGL counterpart: GL_DST_COLOR. BLEND_FACTOR_DEST_COLOR, /// The blend factor is 1-RGB, where RGB is the data from a render target.\n - /// D3D11 counterpart: D3D11_BLEND_INV_DEST_COLOR. OpenGL counterpart: GL_ONE_MINUS_DST_COLOR. + /// Direct3D counterpart: D3D11_BLEND_INV_DEST_COLOR/D3D12_BLEND_INV_DEST_COLOR. OpenGL counterpart: GL_ONE_MINUS_DST_COLOR. BLEND_FACTOR_INV_DEST_COLOR, /// The blend factor is (f,f,f,1), where f = min(As, 1-Ad), /// As is alpha data from a pixel shader, and Ad is alpha data from a render target.\n - /// D3D11 counterpart: D3D11_BLEND_SRC_ALPHA_SAT. OpenGL counterpart: GL_SRC_ALPHA_SATURATE. + /// Direct3D counterpart: D3D11_BLEND_SRC_ALPHA_SAT/D3D12_BLEND_SRC_ALPHA_SAT. OpenGL counterpart: GL_SRC_ALPHA_SATURATE. BLEND_FACTOR_SRC_ALPHA_SAT, - /// The blend factor is the constant blend factor set with IDeviceContext::SetBlendState().\n - /// D3D11 counterpart: D3D11_BLEND_BLEND_FACTOR. OpenGL counterpart: GL_CONSTANT_COLOR. + /// The blend factor is the constant blend factor set with IDeviceContext::SetBlendFactors().\n + /// Direct3D counterpart: D3D11_BLEND_BLEND_FACTOR/D3D12_BLEND_BLEND_FACTOR. OpenGL counterpart: GL_CONSTANT_COLOR. BLEND_FACTOR_BLEND_FACTOR, - /// The blend factor is one minus constant blend factor set with IDeviceContext::SetBlendState().\n - /// D3D11 counterpart: D3D11_BLEND_INV_BLEND_FACTOR. OpenGL counterpart: GL_ONE_MINUS_CONSTANT_COLOR. + /// The blend factor is one minus constant blend factor set with IDeviceContext::SetBlendFactors().\n + /// Direct3D counterpart: D3D11_BLEND_INV_BLEND_FACTOR/D3D12_BLEND_INV_BLEND_FACTOR. OpenGL counterpart: GL_ONE_MINUS_CONSTANT_COLOR. BLEND_FACTOR_INV_BLEND_FACTOR, /// The blend factor is the second RGB data output from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_SRC1_COLOR. OpenGL counterpart: GL_SRC1_COLOR. + /// Direct3D counterpart: D3D11_BLEND_SRC1_COLOR/D3D12_BLEND_SRC1_COLOR. OpenGL counterpart: GL_SRC1_COLOR. BLEND_FACTOR_SRC1_COLOR, /// The blend factor is 1-RGB, where RGB is the second RGB data output from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_INV_SRC1_COLOR. OpenGL counterpart: GL_ONE_MINUS_SRC1_COLOR. + /// Direct3D counterpart: D3D11_BLEND_INV_SRC1_COLOR/D3D12_BLEND_INV_SRC1_COLOR. OpenGL counterpart: GL_ONE_MINUS_SRC1_COLOR. BLEND_FACTOR_INV_SRC1_COLOR, /// The blend factor is the second alpha (A) data output from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_SRC1_ALPHA. OpenGL counterpart: GL_SRC1_ALPHA. + /// Direct3D counterpart: D3D11_BLEND_SRC1_ALPHA/D3D12_BLEND_SRC1_ALPHA. OpenGL counterpart: GL_SRC1_ALPHA. BLEND_FACTOR_SRC1_ALPHA, /// The blend factor is 1-A, where A is the second alpha data output from a pixel shader.\n - /// D3D11 counterpart: D3D11_BLEND_INV_SRC1_ALPHA. OpenGL counterpart: GL_ONE_MINUS_SRC1_ALPHA. + /// Direct3D counterpart: D3D11_BLEND_INV_SRC1_ALPHA/D3D12_BLEND_INV_SRC1_ALPHA. OpenGL counterpart: GL_ONE_MINUS_SRC1_ALPHA. BLEND_FACTOR_INV_SRC1_ALPHA, /// Helper value that stores the total number of blend factors in the enumeration. @@ -126,34 +121,35 @@ enum BLEND_FACTOR : Int32 /// Blending operation /// [D3D11_BLEND_OP]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476088(v=vs.85).aspx +/// [D3D12_BLEND_OP]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770340(v=vs.85).aspx /// [glBlendEquationSeparate]: https://www.opengl.org/wiki/GLAPI/glBlendEquationSeparate -/// This enumeration describes blending operation for RGB or Alpha channels and generally mirrows -/// [D3D11_BLEND_OP][] enum. It is used by RenderTargetBlendDesc structure to define RGB and Alpha +/// This enumeration describes blending operation for RGB or Alpha channels and generally mirrors +/// [D3D11_BLEND_OP][] and [D3D12_BLEND_OP][] enums. It is used by RenderTargetBlendDesc structure to define RGB and Alpha /// blending operations -/// \sa [D3D11_BLEND_OP on MSDN][D3D11_BLEND_OP], [glBlendEquationSeparate on OpenGL.org][glBlendEquationSeparate] +/// \sa [D3D11_BLEND_OP on MSDN][D3D11_BLEND_OP], [D3D12_BLEND_OP on MSDN][D3D12_BLEND_OP], [glBlendEquationSeparate on OpenGL.org][glBlendEquationSeparate] enum BLEND_OPERATION : Int32 { /// Undefined blend operation BLEND_OPERATION_UNDEFINED = 0, /// Add source and destination color components.\n - /// D3D11 counterpart: D3D11_BLEND_OP_ADD. OpenGL counterpart: GL_FUNC_ADD. + /// Direct3D counterpart: D3D11_BLEND_OP_ADD/D3D12_BLEND_OP_ADD. OpenGL counterpart: GL_FUNC_ADD. BLEND_OPERATION_ADD, /// Subtract destination color components from source color components.\n - /// D3D11 counterpart: D3D11_BLEND_OP_SUBTRACT. OpenGL counterpart: GL_FUNC_SUBTRACT. + /// Direct3D counterpart: D3D11_BLEND_OP_SUBTRACT/D3D12_BLEND_OP_SUBTRACT. OpenGL counterpart: GL_FUNC_SUBTRACT. BLEND_OPERATION_SUBTRACT, /// Subtract source color components from destination color components.\n - /// D3D11 counterpart: D3D11_BLEND_OP_REV_SUBTRACT. OpenGL counterpart: GL_FUNC_REVERSE_SUBTRACT. + /// Direct3D counterpart: D3D11_BLEND_OP_REV_SUBTRACT/D3D12_BLEND_OP_REV_SUBTRACT. OpenGL counterpart: GL_FUNC_REVERSE_SUBTRACT. BLEND_OPERATION_REV_SUBTRACT, /// Compute the minimum of source and destination color components.\n - /// D3D11 counterpart: D3D11_BLEND_OP_MIN. OpenGL counterpart: GL_MIN. + /// Direct3D counterpart: D3D11_BLEND_OP_MIN/D3D12_BLEND_OP_MIN. OpenGL counterpart: GL_MIN. BLEND_OPERATION_MIN, /// Compute the maximum of source and destination color components.\n - /// D3D11 counterpart: D3D11_BLEND_OP_MAX. OpenGL counterpart: GL_MAX. + /// Direct3D counterpart: D3D11_BLEND_OP_MAX/D3D12_BLEND_OP_MAX. OpenGL counterpart: GL_MAX. BLEND_OPERATION_MAX, /// Helper value that stores the total number of blend operations in the enumeration. @@ -182,6 +178,84 @@ enum COLOR_MASK : Int32 COLOR_MASK_ALL = ( ( ( COLOR_MASK_RED | COLOR_MASK_GREEN ) | COLOR_MASK_BLUE ) | COLOR_MASK_ALPHA ) }; + +/// Logic operation + +/// [D3D12_LOGIC_OP]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770379(v=vs.85).aspx +/// This enumeration describes logic operation and generally mirrors [D3D12_LOGIC_OP][] enum. +/// It is used by RenderTargetBlendDesc structure to define logic operation. +/// Only available on D3D12 engine +/// \sa [D3D12_LOGIC_OP on MSDN][D3D12_LOGIC_OP] +enum LOGIC_OPERATION +{ + /// Clear the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_CLEAR. + LOGIC_OP_CLEAR = 0, + + /// Set the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_SET. + LOGIC_OP_SET, + + /// Copy the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_COPY. + LOGIC_OP_COPY, + + /// Perform an inverted-copy of the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_COPY_INVERTED. + LOGIC_OP_COPY_INVERTED, + + /// No operation is performed on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_NOOP. + LOGIC_OP_NOOP, + + /// Invert the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_INVERT. + LOGIC_OP_INVERT, + + /// Perform a logical AND operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_AND. + LOGIC_OP_AND, + + /// Perform a logical NAND operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_NAND. + LOGIC_OP_NAND, + + /// Perform a logical OR operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_OR. + LOGIC_OP_OR, + + /// Perform a logical NOR operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_NOR. + LOGIC_OP_NOR, + + /// Perform a logical XOR operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_XOR. + LOGIC_OP_XOR, + + /// Perform a logical equal operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_EQUIV. + LOGIC_OP_EQUIV, + + /// Perform a logical AND and reverse operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_AND_REVERSE. + LOGIC_OP_AND_REVERSE, + + /// Perform a logical AND and invert operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_AND_INVERTED. + LOGIC_OP_AND_INVERTED, + + /// Perform a logical OR and reverse operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_OR_REVERSE. + LOGIC_OP_OR_REVERSE, + + /// Perform a logical OR and invert operation on the render target.\n + /// Direct3D12 counterpart: D3D12_LOGIC_OP_OR_INVERTED. + LOGIC_OP_OR_INVERTED, + + /// Helper value that stores the total number of logical operations in the enumeration. + LOGIC_OP_NUM_OPERATIONS +}; + /// Describes a blend state for a single render target /// This structure is used by BlendStateDesc to describe @@ -191,6 +265,9 @@ struct RenderTargetBlendDesc /// Enable or disable blending for this render target. Bool BlendEnable; + /// Enable or disable a logical operation for this render target. + Bool LogicOperationEnable; + /// Specifies the blend factor to apply to the RGB value output from the pixel shader BLEND_FACTOR SrcBlend; @@ -213,6 +290,9 @@ struct RenderTargetBlendDesc /// after applying the SrcBlendAlpha and DestBlendAlpha factors. BLEND_OPERATION BlendOpAlpha; + /// Defines logical operation for the render target. + LOGIC_OPERATION LogicOp; + /// Render target write mask Uint32 RenderTargetWriteMask; @@ -221,21 +301,25 @@ struct RenderTargetBlendDesc /// Member | Default value /// ----------------------|-------------- /// BlendEnable | False - /// SrcBlend | BLEND_FACTOR_ONE - /// DestBlend | BLEND_FACTOR_ZERO - /// BlendOp | BLEND_OPERATION_ADD - /// SrcBlendAlpha | BLEND_FACTOR_ONE - /// DestBlendAlpha | BLEND_FACTOR_ZERO - /// BlendOpAlpha | BLEND_OPERATION_ADD - /// RenderTargetWriteMask | COLOR_MASK_ALL + /// LogicOperationEnable | False + /// SrcBlend | Diligent::BLEND_FACTOR_ONE + /// DestBlend | Diligent::BLEND_FACTOR_ZERO + /// BlendOp | Diligent::BLEND_OPERATION_ADD + /// SrcBlendAlpha | Diligent::BLEND_FACTOR_ONE + /// DestBlendAlpha | Diligent::BLEND_FACTOR_ZERO + /// BlendOpAlpha | Diligent::BLEND_OPERATION_ADD + /// LogicOp | Diligent::LOGIC_OP_NOOP + /// RenderTargetWriteMask | Diligent::COLOR_MASK_ALL RenderTargetBlendDesc() : BlendEnable ( False ), + LogicOperationEnable(False), SrcBlend ( BLEND_FACTOR_ONE ), DestBlend ( BLEND_FACTOR_ZERO ), BlendOp ( BLEND_OPERATION_ADD ), SrcBlendAlpha ( BLEND_FACTOR_ONE ), DestBlendAlpha ( BLEND_FACTOR_ZERO ), BlendOpAlpha ( BLEND_OPERATION_ADD ), + LogicOp ( LOGIC_OP_NOOP ), RenderTargetWriteMask( COLOR_MASK_ALL ) {} @@ -249,21 +333,22 @@ struct RenderTargetBlendDesc bool operator == (const RenderTargetBlendDesc& rhs)const { return BlendEnable == rhs.BlendEnable && + LogicOperationEnable == rhs.LogicOperationEnable && SrcBlend == rhs.SrcBlend && DestBlend == rhs.DestBlend && BlendOp == rhs.BlendOp && SrcBlendAlpha == rhs.SrcBlendAlpha && DestBlendAlpha == rhs.DestBlendAlpha && BlendOpAlpha == rhs.BlendOpAlpha && + LogicOp == rhs.LogicOp && RenderTargetWriteMask == rhs.RenderTargetWriteMask; } }; /// Blend state description -/// This structure describes the blend state which is used in a call to -/// IRenderDevice::CreateBlendState() to create a blend state object -struct BlendStateDesc : DeviceObjectAttribs +/// This structure describes the blend state and is part of the GraphicsPipelineDesc. +struct BlendStateDesc { /// Specifies whether to use alpha-to-coverage as a multisampling technique /// when setting a pixel to a render target. Default value: False. @@ -305,8 +390,6 @@ struct BlendStateDesc : DeviceObjectAttribs /// but differ in render target other than 0, the operator will return False /// even though the two blend states created from these structures will be identical. /// - False otherwise - /// \remarks - /// The operator ignores DeviceObjectAttribs::Name field as it does not affect the blend state. bool operator == (const BlendStateDesc& RHS)const { bool bRTsEqual = true; @@ -318,27 +401,9 @@ struct BlendStateDesc : DeviceObjectAttribs } return bRTsEqual && - // Name is primarily used for debug purposes and does not affect the state. - // It is ignored in comparison operation. - // strcmp(Name, RHS.Name) == 0 && AlphaToCoverageEnable == RHS.AlphaToCoverageEnable && IndependentBlendEnable== RHS.IndependentBlendEnable; } }; -/// Blend state interface - -/// The interface holds the blending state that can be bound to the pipeline by a call -/// to IDeviceContext::SetBlendState(). To create a blend state, call -/// IRenderDevice::CreateBlendState(). -class IBlendState : public IDeviceObject -{ -public: - /// Queries the specific interface, see IObject::QueryInterface() for details. - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; - - /// Returns the blend state description used to create the object - virtual const BlendStateDesc& GetDesc()const = 0; -}; - } diff --git a/Graphics/GraphicsEngine/interface/Buffer.h b/Graphics/GraphicsEngine/interface/Buffer.h index 45dc21bc..847a04c1 100644 --- a/Graphics/GraphicsEngine/interface/Buffer.h +++ b/Graphics/GraphicsEngine/interface/Buffer.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -129,9 +129,9 @@ struct BufferDesc : DeviceObjectAttribs /// --------------------|-------------- /// uiSizeInBytes | 0 /// BindFlags | 0 - /// Usage | USAGE_DEFAULT + /// Usage | Diligent::USAGE_DEFAULT /// CPUAccessFlags | 0 - /// Mode | BUFFER_MODE_UNDEFINED + /// Mode | Diligent::BUFFER_MODE_UNDEFINED /// ElementByteStride | 0 /// Members of BufferDesc::Format are initialized with default values by BufferFormat::BufferFormat() BufferDesc() : @@ -148,7 +148,7 @@ struct BufferDesc : DeviceObjectAttribs struct BufferData { /// Pointer to the data - PVoid pData; + const void* pData; /// Data size, in bytes Uint32 DataSize; @@ -206,7 +206,9 @@ public: /// Unmaps the previously mapped buffer /// \param [in] pContext - Pointer to the device context interface to be used to perform the operation. - virtual void Unmap( IDeviceContext *pContext ) = 0; + /// \param [in] MapType - Type of the map operation. This parameter must match to the type that was + /// provided to the Map() method. + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) = 0; /// Creates a new buffer view diff --git a/Graphics/GraphicsEngine/interface/BufferView.h b/Graphics/GraphicsEngine/interface/BufferView.h index 93d52887..f817b3e6 100644 --- a/Graphics/GraphicsEngine/interface/BufferView.h +++ b/Graphics/GraphicsEngine/interface/BufferView.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ struct BufferViewDesc : DeviceObjectAttribs /// Default values: /// Member | Default value /// --------------------|-------------- - /// ViewType | BUFFER_VIEW_UNDEFINED + /// ViewType | Diligent::BUFFER_VIEW_UNDEFINED /// ByteOffset | 0 /// ByteWidth | 0 BufferViewDesc() : diff --git a/Graphics/GraphicsEngine/interface/CommandList.h b/Graphics/GraphicsEngine/interface/CommandList.h new file mode 100644 index 00000000..e6939c3d --- /dev/null +++ b/Graphics/GraphicsEngine/interface/CommandList.h @@ -0,0 +1,49 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Defines Diligent::IBuffer interface and related data structures + +#include "DeviceObject.h" + +namespace Diligent +{ + +// {C38C68F2-8A8C-4ED5-B7EE-69126E75DCD8} +static const Diligent::INTERFACE_ID IID_CommandList = +{ 0xc38c68f2, 0x8a8c, 0x4ed5, { 0xb7, 0xee, 0x69, 0x12, 0x6e, 0x75, 0xdc, 0xd8 } }; + +/// Command list interface + +/// Command list has no methods. When command list recording is finished, it is executed by +/// IDeviceContext::ExecuteCommandList(). +class ICommandList : public IDeviceObject +{ +public: + + +}; + +} diff --git a/Graphics/GraphicsEngine/interface/Constants.h b/Graphics/GraphicsEngine/interface/Constants.h index 50d9d427..7c1505bb 100644 --- a/Graphics/GraphicsEngine/interface/Constants.h +++ b/Graphics/GraphicsEngine/interface/Constants.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngine/interface/DepthStencilState.h b/Graphics/GraphicsEngine/interface/DepthStencilState.h index 75347935..de796255 100644 --- a/Graphics/GraphicsEngine/interface/DepthStencilState.h +++ b/Graphics/GraphicsEngine/interface/DepthStencilState.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,22 +24,19 @@ #pragma once /// \file -/// Definition of the Diligent::IDepthStencilState interface and related data structures +/// Definition of data types that describe depth-stencil state -#include "DeviceObject.h" +#include "BasicTypes.h" namespace Diligent { -// {51C3A67F-FADD-411A-BA36-BDE9EE29722B} -static const Diligent::INTERFACE_ID IID_DepthStencilState = -{ 0x51c3a67f, 0xfadd, 0x411a, { 0xba, 0x36, 0xbd, 0xe9, 0xee, 0x29, 0x72, 0x2b } }; - /// Stencil operation /// [D3D11_STENCIL_OP]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476219(v=vs.85).aspx -/// This enumeration describes the stencil operation and generally mirrows -/// [D3D11_STENCIL_OP][] enumeration. +/// [D3D12_STENCIL_OP]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770409(v=vs.85).aspx +/// This enumeration describes the stencil operation and generally mirrors +/// [D3D11_STENCIL_OP][]/[D3D12_STENCIL_OP][] enumeration. /// It is used by Diligent::StencilOpDesc structure to describe the stencil fail, depth fail /// and stencil pass operations enum STENCIL_OP : Int32 @@ -48,37 +45,37 @@ enum STENCIL_OP : Int32 STENCIL_OP_UNDEFINED = 0, /// Keep the existing stencil data.\n - /// D3D11 Counterpart: D3D11_STENCIL_OP_KEEP. OpenGL counterpart: GL_KEEP. + /// Direct3D counterpart: D3D11_STENCIL_OP_KEEP/D3D12_STENCIL_OP_KEEP. OpenGL counterpart: GL_KEEP. STENCIL_OP_KEEP = 1, /// Set the stencil data to 0.\n - /// D3D11 Counterpart: D3D11_STENCIL_OP_ZERO. OpenGL counterpart: GL_ZERO. + /// Direct3D counterpart: D3D11_STENCIL_OP_ZERO/D3D12_STENCIL_OP_ZERO. OpenGL counterpart: GL_ZERO. STENCIL_OP_ZERO = 2, - /// Set the stencil data to the reference value set by calling IDeviceContext::SetDepthStencilState().\n - /// D3D11 Counterpart: D3D11_STENCIL_OP_REPLACE. OpenGL counterpart: GL_REPLACE. + /// Set the stencil data to the reference value set by calling IDeviceContext::SetStencilRef().\n + /// Direct3D counterpart: D3D11_STENCIL_OP_REPLACE/D3D12_STENCIL_OP_REPLACE. OpenGL counterpart: GL_REPLACE. STENCIL_OP_REPLACE = 3, /// Increment the current stencil value, and clamp to the maximum representable unsigned value.\n - /// D3D11 Counterpart: D3D11_STENCIL_OP_INCR_SAT. OpenGL counterpart: GL_INCR. + /// Direct3D counterpart: D3D11_STENCIL_OP_INCR_SAT/D3D12_STENCIL_OP_INCR_SAT. OpenGL counterpart: GL_INCR. STENCIL_OP_INCR_SAT = 4, /// Decrement the current stencil value, and clamp to 0.\n - /// D3D11 Counterpart: D3D11_STENCIL_OP_DECR_SAT. OpenGL counterpart: GL_DECR. + /// Direct3D counterpart: D3D11_STENCIL_OP_DECR_SAT/D3D12_STENCIL_OP_DECR_SAT. OpenGL counterpart: GL_DECR. STENCIL_OP_DECR_SAT = 5, /// Bitwise invert the current stencil buffer value.\n - /// D3D11 Counterpart: D3D11_STENCIL_OP_INVERT. OpenGL counterpart: GL_INVERT. + /// Direct3D counterpart: D3D11_STENCIL_OP_INVERT/D3D12_STENCIL_OP_INVERT. OpenGL counterpart: GL_INVERT. STENCIL_OP_INVERT = 6, /// Increment the current stencil value, and wrap the value to zero when incrementing /// the maximum representable unsigned value. \n - /// D3D11 Counterpart: D3D11_STENCIL_OP_INCR. OpenGL counterpart: GL_INCR_WRAP. + /// Direct3D counterpart: D3D11_STENCIL_OP_INCR/D3D12_STENCIL_OP_INCR. OpenGL counterpart: GL_INCR_WRAP. STENCIL_OP_INCR_WRAP = 7, /// Decrement the current stencil value, and wrap the value to the maximum representable /// unsigned value when decrementing a value of zero.\n - /// D3D11 Counterpart: D3D11_STENCIL_OP_DECR. OpenGL counterpart: GL_DECR_WRAP. + /// Direct3D counterpart: D3D11_STENCIL_OP_DECR/D3D12_STENCIL_OP_DECR. OpenGL counterpart: GL_DECR_WRAP. STENCIL_OP_DECR_WRAP = 8, /// Helper value that stores the total number of stencil operations in the enumeration. @@ -88,7 +85,8 @@ enum STENCIL_OP : Int32 /// Describes stencil operations that are performed based on the results of depth test. /// [D3D11_DEPTH_STENCILOP_DESC]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476109(v=vs.85).aspx -/// The structure generally mirrows [D3D11_DEPTH_STENCILOP_DESC][] structure. +/// [D3D12_DEPTH_STENCILOP_DESC]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770355(v=vs.85).aspx +/// The structure generally mirrors [D3D11_DEPTH_STENCILOP_DESC][]/[D3D12_DEPTH_STENCILOP_DESC][] structure. /// It is used by Diligent::DepthStencilStateDesc structure to describe the stencil /// operations for the front and back facing polygons. struct StencilOpDesc @@ -111,10 +109,10 @@ struct StencilOpDesc /// Default values: /// Member | Default value /// --------------------|-------------- - /// StencilFailOp | STENCIL_OP_KEEP - /// StencilDepthFailOp | STENCIL_OP_KEEP - /// StencilPassOp | STENCIL_OP_KEEP - /// StencilFunc | COMPARISON_FUNC_ALWAYS + /// StencilFailOp | Diligent::STENCIL_OP_KEEP + /// StencilDepthFailOp | Diligent::STENCIL_OP_KEEP + /// StencilPassOp | Diligent::STENCIL_OP_KEEP + /// StencilFunc | Diligent::COMPARISON_FUNC_ALWAYS StencilOpDesc() : StencilFailOp ( STENCIL_OP_KEEP ), StencilDepthFailOp( STENCIL_OP_KEEP ), @@ -140,10 +138,11 @@ struct StencilOpDesc /// Depth stencil state description /// [D3D11_DEPTH_STENCIL_DESC]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476110(v=vs.85).aspx -/// This structure describes the depth stencil state which is used in a call to -/// IRenderDevice::CreateDepthStencilState() and generally mirrows [D3D11_DEPTH_STENCIL_DESC][] +/// [D3D12_DEPTH_STENCIL_DESC]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770356(v=vs.85).aspx +/// This structure describes the depth stencil state and is part of the GraphicsPipelineDesc. +/// The structure generally mirrors [D3D11_DEPTH_STENCIL_DESC][]/[D3D12_DEPTH_STENCIL_DESC][] /// structure. -struct DepthStencilStateDesc : DeviceObjectAttribs +struct DepthStencilStateDesc { /// Enable depth-stencil operations. When it is set to False, /// depth test always passes, depth writes are disabled, @@ -179,7 +178,7 @@ struct DepthStencilStateDesc : DeviceObjectAttribs /// --------------------|-------------- /// DepthEnable | True /// DepthWriteEnable | True - /// DepthFunc | COMPARISON_FUNC_LESS + /// DepthFunc | Diligent::COMPARISON_FUNC_LESS /// StencilEnable | False /// StencilReadMask | 0xFF /// StencilWriteMask | 0xFF @@ -201,15 +200,9 @@ struct DepthStencilStateDesc : DeviceObjectAttribs /// \return /// - True if all members of the two structures are equal. /// - False otherwise - /// \remarks - /// The operator ignores DeviceObjectAttribs::Name field as it does not affect - /// the depth-stencil state. bool operator == (const DepthStencilStateDesc& rhs)const { - // Name is primarily used for debug purposes and does not affect the state. - // It is ignored in comparison operation. - return // strcmp(Name, rhs.Name) == 0 && - DepthEnable == rhs.DepthEnable && + return DepthEnable == rhs.DepthEnable && DepthWriteEnable == rhs.DepthWriteEnable && DepthFunc == rhs.DepthFunc && StencilEnable == rhs.StencilEnable && @@ -220,19 +213,4 @@ struct DepthStencilStateDesc : DeviceObjectAttribs } }; -/// Depth stencil state interface - -/// The interface holds the depth-stencil state that can be bound to the pipeline by a call -/// to IDeviceContext::SetDepthStencilState(). To create a depth-stencil state, call -/// IRenderDevice::CreateDepthStencilState(). -class IDepthStencilState : public IDeviceObject -{ -public: - /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; - - /// Returns the depth stencil state description used to create the object - virtual const DepthStencilStateDesc& GetDesc()const = 0; -}; - } diff --git a/Graphics/GraphicsEngine/interface/DeviceCaps.h b/Graphics/GraphicsEngine/interface/DeviceCaps.h index 3d8284ed..4265ce04 100644 --- a/Graphics/GraphicsEngine/interface/DeviceCaps.h +++ b/Graphics/GraphicsEngine/interface/DeviceCaps.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,8 @@ namespace Diligent enum class DeviceType : Int32 { Undefined = 0, ///< Undefined device - DirectX, ///< DirectX device + D3D11, ///< D3D11 device + D3D12, ///< D3D12 device OpenGL, ///< OpenGL device OpenGLES ///< OpenGLES device }; @@ -77,13 +78,17 @@ namespace Diligent /// Indicates if device supports texture views bool bTextureViewSupported; + /// Indicates if device supports cubemap arrays + bool bCubemapArraysSupported; + /// Initializes the structure members with default values TextureCaps(): bTexture1DSupported( True ), bTexture1DArraySupported( True ), bTexture2DMSSupported( True ), bTexture2DMSArraySupported( True ), - bTextureViewSupported( True ) + bTextureViewSupported( True ), + bCubemapArraysSupported( True ) {} }; @@ -110,6 +115,9 @@ namespace Diligent /// Indicates if device supports wireframe fill mode Bool bWireframeFillSupported; + /// Indicates if device supports multithreaded resource creation + Bool bMultithreadedResourceCreationSupported; + /// Texture sampling capabilities. See Diligent::SamplerCaps. SamplerCaps SamCaps; @@ -123,7 +131,8 @@ namespace Diligent MinorVersion( 0 ), bSeparableProgramSupported( True ), bIndirectRenderingSupported( True ), - bWireframeFillSupported( True ) + bWireframeFillSupported( True ), + bMultithreadedResourceCreationSupported( False ) {} }; } diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index c1998091..20a0f0b4 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ #include "DeviceCaps.h" #include "Constants.h" #include "Buffer.h" -#include "VertexDescription.h" +#include "InputLayout.h" #include "Shader.h" #include "Texture.h" #include "Sampler.h" @@ -39,6 +39,8 @@ #include "BufferView.h" #include "DepthStencilState.h" #include "BlendState.h" +#include "PipelineState.h" +#include "CommandList.h" namespace Diligent { @@ -56,19 +58,19 @@ enum PRIMITIVE_TOPOLOGY : Int32 PRIMITIVE_TOPOLOGY_UNDEFINED = 0, /// Interpret the vertex data as a list of triangles.\n - /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST. OpenGL counterpart: GL_TRIANGLES. + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST. OpenGL counterpart: GL_TRIANGLES. PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, /// Interpret the vertex data as a triangle strip.\n - /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP. OpenGL counterpart: GL_TRIANGLE_STRIP. + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP. OpenGL counterpart: GL_TRIANGLE_STRIP. PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, /// Interpret the vertex data as a list of points.\n - /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_POINTLIST. OpenGL counterpart: GL_POINTS. + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_POINTLIST. OpenGL counterpart: GL_POINTS. PRIMITIVE_TOPOLOGY_POINT_LIST, /// Interpret the vertex data as a list of lines.\n - /// D3D11 counterpart: D3D11_PRIMITIVE_TOPOLOGY_LINELIST. OpenGL counterpart: GL_LINES. + /// D3D counterpart: D3D_PRIMITIVE_TOPOLOGY_LINELIST. OpenGL counterpart: GL_LINES. PRIMITIVE_TOPOLOGY_LINE_LIST, /// Helper value that stores the total number of topologies in the enumeration @@ -228,6 +230,17 @@ enum SET_VERTEX_BUFFERS_FLAGS : Int32 SET_VERTEX_BUFFERS_FLAG_RESET = 0x01 }; +/// Defines allowed flags for IDeviceContext::CommitShaderResources() function. +enum COMMIT_SHADER_RESOURCES_FLAG +{ + /// Transition resources being committed + + /// If this flag is specified when IDeviceContext::CommitShaderResources() is called, + /// the engine will transition all shader resources to the correct state. + COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES = 0x01 +}; + + /// Describes the viewport. /// This structure is used by IDeviceContext::SetViewports(). @@ -304,25 +317,51 @@ public: /// Queries the specific interface, see IObject::QueryInterface() for details virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; - /// Binds shaders to the pipeline + /// Sets the pipeline state + + /// \param [in] pPipelineState - Pointer to IPipelineState interface to bind to the context. + virtual void SetPipelineState(IPipelineState *pPipelineState) = 0; + + + /// Transitions shader resources to the require states. + /// \param [in] pPipelineState - Pipeline state object that was used to create the shader resource binding. + /// \param [in] pShaderResourceBinding - Shader resource binding whose resources will be transitioned. + /// \remarks This method explicitly transitiones all resources to the correct states. + /// If this method was called, there is no need to specify Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES + /// when calling IDeviceContext::CommitShaderResources() + virtual void TransitionShaderResources(IPipelineState *pPipelineState, IShaderResourceBinding *pShaderResourceBinding) = 0; + + /// Commits shader resources to the device context + + /// \param [in] pShaderResourceBinding - Shader resource binding whose resources will be committed. + /// If pipeline state contains no shader resources, this parameter + /// can be null. + /// \param [in] Flags - Additional flags for the operation. See Diligent::COMMIT_SHADER_RESOURCES_FLAG + /// for a list of allowed values. + /// + /// \remarks Pipeline state object that was used to create the shader resource binding must be bound + /// to the pipeline when CommitShaderResources() is called. If no pipeline state object is bound + /// or the pipeline state object does not match shader resource binding, the method will fail.\n + /// If Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag is specified, + /// the engine will also transition all shader resources to the correct state. If the flag + /// is not specified, it is assumed that all resources are already in correct states.\n + /// Resources can be explicitly transitioned to the required states by calling + /// IDeviceContext::TransitionShaderResources() + virtual void CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags) = 0; - /// \param [in] ppShaders - Array of pointers to IShader interface. - /// \param [in] NumShadersToSet - Number of shaders to bind. - /// \remarks All shaders must be set atomically. All shaders that are not specified - /// in a call to SetShaders() will be unbound.\n - /// The device context keeps strong references to all bound shaders. - /// Thus a shader cannot be released until it is unbound from the context. - virtual void SetShaders(IShader **ppShaders, Uint32 NumShadersToSet) = 0; + /// Sets the stencil reference value - /// Binds resources for all shaders bound to the pipeline + /// \param [in] StencilRef - Stencil reference value. + virtual void SetStencilRef(Uint32 StencilRef) = 0; - /// \param [in] pResourceMapping - Pointer to the resource mapping interface. - /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. - /// \remarks This function is intended to be used with older OpenGL devices that - /// do not support program pipelines (OpenGL4.1-, OpenGLES3.0-).\n - /// The function should be called AFTER all the required shaders are bound to the - /// context. It should also be called for every shader combination. - virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) = 0; + + /// \param [in] pBlendFactors - Array of four blend factors, one for each RGBA component. + /// Theses factors are used if the blend state uses one of the + /// Diligent::BLEND_FACTOR_BLEND_FACTOR or + /// Diligent::BLEND_FACTOR_INV_BLEND_FACTOR + /// blend factors. If nullptr is provided, + /// default blend factors array {1,1,1,1} will be used. + virtual void SetBlendFactors(const float* pBlendFactors = nullptr) = 0; /// Binds vertex buffers to the pipeline. @@ -337,7 +376,7 @@ public: /// in the vertex-buffer array. Each stride is the size (in bytes) of the /// elements that are to be used from that vertex buffer. /// If this parameter is nullptr, tight strides from the input layout - /// will be used for each buffer. See IVertexDescription::GetTightStrides(). + /// will be used for each buffer. See IPipelineState::GetTightStrides(). /// \param [in] pOffsets - Pointer to an array of offset values; one offset value for each buffer /// in the vertex-buffer array. Each offset is the number of bytes between /// the first element of a vertex buffer and the first element that will be @@ -359,14 +398,6 @@ public: /// Clears the context state. virtual void ClearState() = 0; - /// Sets vertex description - - /// \param [in] pVertexDesc - Pointer to IVertexDescription interface that describes - /// how to read data from input vertex buffers. - /// \remarks The device context keeps strong reference to the vertex description. - /// Thus a vertex description object cannot be released until it is unbound - /// from the context. - virtual void SetVertexDescription(IVertexDescription *pVertexDesc) = 0; /// Binds an index buffer to the pipeline @@ -380,42 +411,6 @@ public: virtual void SetIndexBuffer(IBuffer *pIndexBuffer, Uint32 ByteOffset) = 0; - /// Sets the depth stencil state - - /// \param [in] pDepthStencilState - Pointer to the IDepthStencilState interface holding the state - /// \param [in] StencilRef - Stencil reference value used in stencil operations. - /// See DepthStencilStateDesc. - /// \remarks The device context keeps strong reference to the bound depth-stencil state. - /// Thus a depth-stencil state object cannot be released until it is unbound - /// from the context. - virtual void SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef = 0 ) = 0; - - /// Sets the rasterizer state - - /// \param [in] pRS - Pointer to the IRasterizerState interface holding the state - /// \remarks The device context keeps strong reference to the bound rasterizer state. - /// Thus a rasterizer state object cannot be released until it is unbound - /// from the context. - virtual void SetRasterizerState( IRasterizerState *pRS ) = 0; - - /// Sets the blend state - - /// \param [in] pBS - Pointer to the IBlendState interface holding the state - /// \param [in] pBlendFactors - Array of four blend factors, one for each RGBA component. - /// Theses factors are used if the blend state uses one of the - /// Diligent::BLEND_FACTOR_BLEND_FACTOR or - /// Diligent::BLEND_FACTOR_INV_BLEND_FACTOR - /// blend factors. If nullptr is provided, - /// default blend factors array {1,1,1,1} will be used. - /// \param [in] SampleMask - 32-bit sample mask that determines which samples get updated - /// in all the active render targets. A sample mask is always applied; - /// it is independent of whether multisampling is enabled, and does not - /// depend on whether an application uses multisample render targets. - /// \remarks The device context keeps strong reference to the bound blend state. - /// Thus a blend state object cannot be released until it is unbound - /// from the context. - virtual void SetBlendState( IBlendState *pBS, const float* pBlendFactors = nullptr, Uint32 SampleMask = 0xFFFFFFFF ) = 0; - /// Sets an array of viewports /// \param [in] NumViewports - Number of viewports to set. @@ -503,6 +498,17 @@ public: /// \note The render target view must be bound to the pipeline for clear operation to be performed. virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA = nullptr ) = 0; + /// Finishes recording commands and generates a command list + + /// \param [out] ppCommandList - Memory location where pointer to the recorded command list will be written. + virtual void FinishCommandList(class ICommandList **ppCommandList) = 0; + + /// Executes recorded commands in a command list + + /// \param [in] pCommandList - Pointer to the command list to executre. + /// \remarks After command list is executed, it is no longer valid and should be released. + virtual void ExecuteCommandList(class ICommandList *pCommandList) = 0; + /// Flushes the command buffer virtual void Flush() = 0; }; diff --git a/Graphics/GraphicsEngine/interface/DeviceObject.h b/Graphics/GraphicsEngine/interface/DeviceObject.h index 6a3cde70..00ce8eb8 100644 --- a/Graphics/GraphicsEngine/interface/DeviceObject.h +++ b/Graphics/GraphicsEngine/interface/DeviceObject.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 4f8bbcba..c59295c4 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ namespace Diligent /// [D3D11_BIND_FLAG]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476085(v=vs.85).aspx /// /// This enumeration describes which parts of the pipeline a resource can be bound to. - /// It generally mirrows [D3D11_BIND_FLAG][] enumeration. It is used by + /// It generally mirrors [D3D11_BIND_FLAG][] enumeration. It is used by /// - BufferDesc to describe bind flags for a buffer /// - TextureDesc to describe bind flags for a texture enum BIND_FLAGS : Int32 @@ -77,7 +77,7 @@ namespace Diligent /// Resource usage /// [D3D11_USAGE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476259(v=vs.85).aspx - /// This enumeration describes expected resource usage. It generally mirrows [D3D11_USAGE] enumeration. + /// This enumeration describes expected resource usage. It generally mirrors [D3D11_USAGE] enumeration. /// The enumeration is used by /// - BufferDesc to describe usage for a buffer /// - TextureDesc to describe usage for a texture @@ -119,7 +119,7 @@ namespace Diligent /// [D3D11_MAP]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476181(v=vs.85).aspx /// Describes how a mapped resource will be accessed. This enumeration generally - /// mirrows [D3D11_MAP][] enumeration. It is used by + /// mirrors [D3D11_MAP][] enumeration. It is used by /// - IBuffer::Map to describe buffer mapping type /// - ITexture::Map to describe texture mapping type enum MAP_TYPE : Int32 @@ -162,22 +162,23 @@ namespace Diligent MAP_FLAG_DO_NOT_WAIT = 0x001 }; - /// Describes texture type + /// Describes resource dimension /// This enumeration is used by /// - TextureDesc to describe texture type /// - TextureViewDesc to describe texture view type - enum TEXTURE_TYPE : Int32 + enum RESOURCE_DIMENSION : Int32 { - TEXTURE_TYPE_UNDEFINED = 0, ///< Texture type undefined - TEXTURE_TYPE_1D, ///< One-dimensional texture - TEXTURE_TYPE_1D_ARRAY, ///< One-dimensional texture array - TEXTURE_TYPE_2D, ///< Two-dimensional texture - TEXTURE_TYPE_2D_ARRAY, ///< Two-dimensional texture array - TEXTURE_TYPE_3D, ///< Three-dimensional texture - TEXTURE_TYPE_CUBE, ///< Cube-map texture - TEXTURE_TYPE_CUBE_ARRAY, ///< Cube-map array texture - TEXTURE_TYPE_NUM_TYPES ///< Helper value that stores the total number of texture types in the enumeration + RESOURCE_DIM_UNDEFINED = 0, ///< Texture type undefined + RESOURCE_DIM_BUFFER, ///< Buffer + RESOURCE_DIM_TEX_1D, ///< One-dimensional texture + RESOURCE_DIM_TEX_1D_ARRAY, ///< One-dimensional texture array + RESOURCE_DIM_TEX_2D, ///< Two-dimensional texture + RESOURCE_DIM_TEX_2D_ARRAY, ///< Two-dimensional texture array + RESOURCE_DIM_TEX_3D, ///< Three-dimensional texture + RESOURCE_DIM_TEX_CUBE, ///< Cube-map texture + RESOURCE_DIM_TEX_CUBE_ARRAY, ///< Cube-map array texture + RESOURCE_DIM_NUM_DIMENSIONS ///< Helper value that stores the total number of texture types in the enumeration }; /// Texture view type @@ -232,7 +233,7 @@ namespace Diligent /// Texture formats - /// This enumeration describes available texture formats and generally mirrows DXGI_FORMAT enumeration. + /// This enumeration describes available texture formats and generally mirrors DXGI_FORMAT enumeration. /// The table below provides detailed information on each format. Most of the formats are widely supported /// by all modern APIs (DX10+, OpenGL3.3+ and OpenGLES3.0+). Specific requirements are additionally indicated. /// \sa <a href = "https://msdn.microsoft.com/en-us/library/windows/desktop/bb173059(v=vs.85).aspx">DXGI_FORMAT enumeration on MSDN</a>, @@ -783,14 +784,21 @@ namespace Diligent FILTER_TYPE_COMPARISON_POINT, ///< Comparison-point filtering FILTER_TYPE_COMPARISON_LINEAR, ///< Comparison-linear filtering FILTER_TYPE_COMPARISON_ANISOTROPIC, ///< Comparison-anisotropic filtering + FILTER_TYPE_MINIMUM_POINT, ///< Minimum-point filtering (DX12 only) + FILTER_TYPE_MINIMUM_LINEAR, ///< Minimum-linear filtering (DX12 only) + FILTER_TYPE_MINIMUM_ANISOTROPIC, ///< Minimum-anisotropic filtering (DX12 only) + FILTER_TYPE_MAXIMUM_POINT, ///< Maximum-point filtering (DX12 only) + FILTER_TYPE_MAXIMUM_LINEAR, ///< Maximum-linear filtering (DX12 only) + FILTER_TYPE_MAXIMUM_ANISOTROPIC, ///< Maximum-anisotropic filtering (DX12 only) FILTER_TYPE_NUM_FILTERS ///< Helper value that stores the total number of filter types in the enumeration }; /// Texture address mode /// [D3D11_TEXTURE_ADDRESS_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476256(v=vs.85).aspx + /// [D3D12_TEXTURE_ADDRESS_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770441(v=vs.85).aspx /// Defines a technique for resolving texture coordinates that are outside of - /// the boundaries of a texture. The enumeration generally mirrows [D3D11_TEXTURE_ADDRESS_MODE][] enumeration. + /// the boundaries of a texture. The enumeration generally mirrors [D3D11_TEXTURE_ADDRESS_MODE][]/[D3D12_TEXTURE_ADDRESS_MODE][] enumeration. /// It is used by SamplerDesc structure to define the address mode for U,V and W texture coordinates. enum TEXTURE_ADDRESS_MODE : Int32 { @@ -798,27 +806,27 @@ namespace Diligent TEXTURE_ADDRESS_UNKNOWN = 0, /// Tile the texture at every integer junction. \n - /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_WRAP. OpenGL counterpart: GL_REPEAT + /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_WRAP/D3D12_TEXTURE_ADDRESS_MODE_WRAP. OpenGL counterpart: GL_REPEAT TEXTURE_ADDRESS_WRAP = 1, /// Flip the texture at every integer junction. \n - /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR. OpenGL counterpart: GL_MIRRORED_REPEAT + /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR/D3D12_TEXTURE_ADDRESS_MODE_MIRROR. OpenGL counterpart: GL_MIRRORED_REPEAT TEXTURE_ADDRESS_MIRROR = 2, /// Texture coordinates outside the range [0.0, 1.0] are set to the /// texture color at 0.0 or 1.0, respectively. \n - /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_CLAMP. OpenGL counterpart: GL_CLAMP_TO_EDGE + /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_CLAMP/D3D12_TEXTURE_ADDRESS_MODE_CLAMP. OpenGL counterpart: GL_CLAMP_TO_EDGE TEXTURE_ADDRESS_CLAMP = 3, /// Texture coordinates outside the range [0.0, 1.0] are set to the border color specified /// specified in SamplerDesc structure. \n - /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_BORDER. OpenGL counterpart: GL_CLAMP_TO_BORDER + /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_BORDER/D3D12_TEXTURE_ADDRESS_MODE_BORDER. OpenGL counterpart: GL_CLAMP_TO_BORDER TEXTURE_ADDRESS_BORDER = 4, /// Similar to TEXTURE_ADDRESS_MIRROR and TEXTURE_ADDRESS_CLAMP. Takes the absolute /// value of the texture coordinate (thus, mirroring around 0), and then clamps to /// the maximum value. \n - /// D3D11 Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR_ONCE. OpenGL counterpart: GL_MIRROR_CLAMP_TO_EDGE + /// Direct3D Counterpart: D3D11_TEXTURE_ADDRESS_MIRROR_ONCE/D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE. OpenGL counterpart: GL_MIRROR_CLAMP_TO_EDGE /// \note GL_MIRROR_CLAMP_TO_EDGE is only available in OpenGL4.4+, and is not available until at least OpenGLES3.1 TEXTURE_ADDRESS_MIRROR_ONCE = 5, @@ -829,45 +837,46 @@ namespace Diligent /// Comparison function /// [D3D11_COMPARISON_FUNC]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476101(v=vs.85).aspx - /// This enumeartion defines a comparison function. It generally mirrows [D3D11_COMPARISON_FUNC] enum and is used by + /// [D3D12_COMPARISON_FUNC]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770349(v=vs.85).aspx + /// This enumeartion defines a comparison function. It generally mirrors [D3D11_COMPARISON_FUNC]/[D3D12_COMPARISON_FUNC] enum and is used by /// - SamplerDesc to define a comparison function if one of the comparison mode filters is used /// - StencilOpDesc to define a stencil function /// - DepthStencilStateDesc to define a depth function enum COMPARISON_FUNCTION : Int32 { /// Unknown comparison function - COMPARISON_FUNC_UNKNOW = 0, + COMPARISON_FUNC_UNKNOWN = 0, /// Comparison never passes. \n - /// D3D11 counterpart: D3D11_COMPARISON_NEVER. OpenGL counterpart: GL_NEVER. + /// Direct3D counterpart: D3D11_COMPARISON_NEVER/D3D12_COMPARISON_FUNC_NEVER. OpenGL counterpart: GL_NEVER. COMPARISON_FUNC_NEVER, /// Comparison passes if the source data is less than the destination data.\n - /// D3D11 counterpart: D3D11_COMPARISON_LESS. OpenGL counterpart: GL_LESS. + /// Direct3D counterpart: D3D11_COMPARISON_LESS/D3D12_COMPARISON_FUNC_LESS. OpenGL counterpart: GL_LESS. COMPARISON_FUNC_LESS, /// Comparison passes if the source data is equal to the destination data.\n - /// D3D11 counterpart: 3D11_COMPARISON_EQUAL. OpenGL counterpart: GL_EQUAL. + /// Direct3D counterpart: D3D11_COMPARISON_EQUAL/D3D12_COMPARISON_FUNC_EQUAL. OpenGL counterpart: GL_EQUAL. COMPARISON_FUNC_EQUAL, /// Comparison passes if the source data is less than or equal to the destination data.\n - /// D3D11 counterpart: D3D11_COMPARISON_LESS_EQUAL. OpenGL counterpart: GL_LEQUAL. + /// Direct3D counterpart: D3D11_COMPARISON_LESS_EQUAL/D3D12_COMPARISON_FUNC_LESS_EQUAL. OpenGL counterpart: GL_LEQUAL. COMPARISON_FUNC_LESS_EQUAL, /// Comparison passes if the source data is greater than the destination data.\n - /// D3D11 counterpart: 3D11_COMPARISON_GREATER. OpenGL counterpart: GL_GREATER. + /// Direct3D counterpart: 3D11_COMPARISON_GREATER/D3D12_COMPARISON_FUNC_GREATER. OpenGL counterpart: GL_GREATER. COMPARISON_FUNC_GREATER, /// Comparison passes if the source data is not equal to the destination data.\n - /// D3D11 counterpart: D3D11_COMPARISON_NOT_EQUAL. OpenGL counterpart: GL_NOTEQUAL. + /// Direct3D counterpart: D3D11_COMPARISON_NOT_EQUAL/D3D12_COMPARISON_FUNC_NOT_EQUAL. OpenGL counterpart: GL_NOTEQUAL. COMPARISON_FUNC_NOT_EQUAL, /// Comparison passes if the source data is greater than or equal to the destination data.\n - /// D3D11 counterpart: D3D11_COMPARISON_GREATER_EQUAL. OpenGL counterpart: GL_GEQUAL. + /// Direct3D counterpart: D3D11_COMPARISON_GREATER_EQUAL/D3D12_COMPARISON_FUNC_GREATER_EQUAL. OpenGL counterpart: GL_GEQUAL. COMPARISON_FUNC_GREATER_EQUAL, /// Comparison always passes. \n - /// D3D11 counterpart: D3D11_COMPARISON_ALWAYS. OpenGL counterpart: GL_ALWAYS. + /// Direct3D counterpart: D3D11_COMPARISON_ALWAYS/D3D12_COMPARISON_FUNC_ALWAYS. OpenGL counterpart: GL_ALWAYS. COMPARISON_FUNC_ALWAYS, /// Helper value that stores the total number of comparison functions in the enumeration @@ -915,13 +924,25 @@ namespace Diligent /// Sample count. Default value is 1 Uint32 SamplesCount; + /// Number of buffers int the swap chain + Uint32 BufferCount; + + /// Default depth value, which is used as optimized depth clear value in D3D12 + Float32 DefaultDepthValue; + + /// Default stencil value, which is used as optimized stencil clear value in D3D12 + Uint8 DefaultStencilValue; + /// Constructor intializes the structure members with default values SwapChainDesc() : Width(0), Height(0), ColorBufferFormat( TEX_FORMAT_RGBA8_UNORM_SRGB ), DepthBufferFormat( TEX_FORMAT_D32_FLOAT ), - SamplesCount( 1 ) + SamplesCount( 1 ), + BufferCount( 2 ), + DefaultDepthValue(1.f), + DefaultStencilValue(0) {} }; @@ -929,12 +950,47 @@ namespace Diligent struct EngineCreationAttribs { const Char* strShaderCachePath; - + /// Pointer to the raw memory allocator that will be used for all memory allocation/deallocation + /// operations in an engine + class IMemoryAllocator *pRawMemAllocator; EngineCreationAttribs() : - strShaderCachePath(nullptr) + strShaderCachePath(nullptr), + pRawMemAllocator(nullptr) {} }; + /// Attributes specific to D3D12 engine + struct EngineD3D12Attribs : public EngineCreationAttribs + { + /// Size of the CPU descriptor heap allocations for different heap types. + Uint32 CPUDescriptorHeapAllocationSize[4] = + { + 1024, // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + 256, // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 128, // D3D12_DESCRIPTOR_HEAP_TYPE_RTV + 64 // D3D12_DESCRIPTOR_HEAP_TYPE_DSV + }; + + /// Size of the GPU descriptor heap allocations for different heap types. + Uint32 GPUDescriptorHeapSize[2] = + { + 16384, // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + 1024 // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + }; + + /// Size of the dynamic GPU descriptor heap region for different heap types. + Uint32 GPUDescriptorHeapDynamicSize[2] = + { + 4096, // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + 1024 // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + }; + + /// Number of commands to flush the command list. Only draw/dispatch commands count + /// towards the limit. Command lists are only flushed when pipeline state is changed + /// or when backbuffer is presented. + Uint32 NumCommandsToFlushCmdList = 256; + }; + /// Box struct Box { diff --git a/Graphics/GraphicsEngine/interface/VertexDescription.h b/Graphics/GraphicsEngine/interface/InputLayout.h index 4883ab40..fa37536e 100644 --- a/Graphics/GraphicsEngine/interface/VertexDescription.h +++ b/Graphics/GraphicsEngine/interface/InputLayout.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,17 +24,13 @@ #pragma once /// \file -/// Definition of the Diligent::IVertexDescription interface and related data structures +/// Definition input layout -#include "DeviceObject.h" +#include "BasicTypes.h" namespace Diligent { -// {2D6915E5-003B-4C68-BDF0-8F93FA7AD4BC} -static const Diligent::INTERFACE_ID IID_VertexDescription = -{ 0x2d6915e5, 0x3b, 0x4c68, { 0xbd, 0xf0, 0x8f, 0x93, 0xfa, 0x7a, 0xd4, 0xbc } }; - static const Uint32 iMaxLayoutElements = 16; /// Description of a single element of the input layout @@ -107,34 +103,17 @@ struct LayoutElement /// Layout description -/// This structure is used by IRenderDevice::CreateVertexDescription(). -struct LayoutDesc : DeviceObjectAttribs +/// This structure is used by IRenderDevice::CreatePipelineState(). +struct InputLayoutDesc { /// Array of layout elements const LayoutElement *LayoutElements; + /// Number of layout elements Uint32 NumElements; - LayoutDesc() : + InputLayoutDesc() : LayoutElements(nullptr), NumElements(0) {} }; -/// Vertex description interface - -/// Vertex description is created by a call to IRenderDevice::CreateVertexDescription(). -/// To bind vertex descption, call IDeviceContext::SetVertexDescription(). -class IVertexDescription : public IDeviceObject -{ -public: - /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; - - /// Returns layout description used to create the object - virtual const LayoutDesc &GetDesc()const = 0; - - /// Returns tight strides for each input buffer slot. Tight strides are computed - /// assuming that all layout elements in the buffer are tightly packed. - virtual const Uint32* GetTightStrides() = 0; -}; - } diff --git a/Graphics/GraphicsEngine/interface/MapHelper.h b/Graphics/GraphicsEngine/interface/MapHelper.h index 9f2aae72..b0d54e69 100644 --- a/Graphics/GraphicsEngine/interface/MapHelper.h +++ b/Graphics/GraphicsEngine/interface/MapHelper.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,21 +43,24 @@ namespace Diligent /// MapHelper<float> UniformData( pDeviceContext, pUniformBuff, MAP_WRITE_DISCARD, 0 ); /// UniformData[0] = UniformData[1] = UniformData[2] = UniformData[3] = 1; /// } -template<typename DataType> +template<typename DataType, bool KeepStrongReferences = false> class MapHelper { public: /// Initializes the class member with null values MapHelper() : - m_pMappedData(nullptr) + m_pMappedData(nullptr), + m_pBuffer(nullptr), + m_pContext(nullptr), + m_MapType(static_cast<MAP_TYPE>(-1)) { } /// Initializes the object and maps the provided resource. /// See Map() for details. MapHelper( IDeviceContext *pContext, IBuffer *pBuffer, MAP_TYPE MapType, Uint32 MapFlags ) : - m_pMappedData(nullptr) + MapHelper() { Map(pContext, pBuffer, MapType, MapFlags); } @@ -66,11 +69,13 @@ public: MapHelper(MapHelper&& Helper) : m_pBuffer( std::move(Helper.m_pBuffer) ), m_pMappedData( std::move(Helper.m_pMappedData) ), - m_pContext( std::move(Helper.m_pContext) ) + m_pContext( std::move(Helper.m_pContext) ), + m_MapType( std::move(Helper.m_MapType) ) { - Helper.m_pBuffer.Release(); - Helper.m_pContext.Release(); + Helper.m_pBuffer = nullptr; + Helper.m_pContext = nullptr; Helper.m_pMappedData = nullptr; + Helper.m_MapType = static_cast<MAP_TYPE>(-1); } /// Move-assignement operator: takes over resource ownership from Helper @@ -79,9 +84,11 @@ public: m_pBuffer = std::move(Helper.m_pBuffer); m_pMappedData = std::move(Helper.m_pMappedData); m_pContext = std::move( Helper.m_pContext ); - Helper.m_pBuffer.Release(); - Helper.m_pContext.Release(); + m_MapType = std::move(Helper.m_MapType); + Helper.m_pBuffer = nullptr; + Helper.m_pContext = nullptr; Helper.m_pMappedData = nullptr; + Helper.m_MapType = static_cast<MAP_TYPE>(-1); return *this; } @@ -97,6 +104,7 @@ public: Unmap(); m_pContext = pContext; m_pBuffer = pBuffer; + m_MapType = MapType; m_pBuffer->Map(m_pContext, MapType, MapFlags, (PVoid&)m_pMappedData); VERIFY( m_pMappedData, "Map failed" ); } @@ -106,10 +114,11 @@ public: { if( m_pBuffer ) { - m_pBuffer->Unmap(m_pContext); - m_pBuffer.Release(); + m_pBuffer->Unmap(m_pContext, m_MapType); + m_pBuffer = nullptr; + m_MapType = static_cast<MAP_TYPE>(-1); } - m_pContext.Release(); + m_pContext = nullptr; m_pMappedData = nullptr; } @@ -135,14 +144,31 @@ private: MapHelper(const MapHelper&); MapHelper& operator=(const MapHelper&); - /// Strong auto pointer to the resource - RefCntAutoPtr<IBuffer> m_pBuffer; + template<typename PtrType, bool UseStrongReference> + struct PtrTypeSelector{}; - /// Strong auto pointer to the context - RefCntAutoPtr<IDeviceContext> m_pContext; + template<typename PtrType> + struct PtrTypeSelector<PtrType, true> + { + typedef RefCntAutoPtr<PtrType> Type; + }; + + template<typename PtrType> + struct PtrTypeSelector<PtrType, false> + { + typedef PtrType* Type; + }; + + /// Pointer / strong auto pointer to the resource + typename PtrTypeSelector<IBuffer, KeepStrongReferences>::Type m_pBuffer; + + /// Pointer / strong auto pointer to the context + typename PtrTypeSelector<IDeviceContext, KeepStrongReferences>::Type m_pContext; /// Pointer to the mapped data DataType *m_pMappedData; + + MAP_TYPE m_MapType; }; } diff --git a/Graphics/GraphicsEngine/interface/PipelineState.h b/Graphics/GraphicsEngine/interface/PipelineState.h new file mode 100644 index 00000000..34503ef9 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/PipelineState.h @@ -0,0 +1,233 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRenderDevice interface and related data structures + +#include "GraphicsTypes.h" +#include "Object.h" +#include "BlendState.h" +#include "RasterizerState.h" +#include "DepthStencilState.h" +#include "InputLayout.h" +#include "ShaderResourceBinding.h" + +namespace Diligent +{ + +/// Primitive topology type + +/// [D3D12_PRIMITIVE_TOPOLOGY_TYPE]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770385(v=vs.85).aspx +/// This enumeration describes primitive topology type. It generally mirrors [D3D12_PRIMITIVE_TOPOLOGY_TYPE] enumeration. +/// The enumeration is used by GraphicsPipelineDesc to describe how the pipeline interprets +/// geometry or hull shader input primitives +enum PRIMITIVE_TOPOLOGY_TYPE : Int32 +{ + /// Topology is not defined + PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED = 0, + + /// Interpret the input primitive as a point. + PRIMITIVE_TOPOLOGY_TYPE_POINT, + + /// Interpret the input primitive as a line. + PRIMITIVE_TOPOLOGY_TYPE_LINE, + + /// Interpret the input primitive as a triangle. + PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, + + /// Interpret the input primitive as a control point patch. + PRIMITIVE_TOPOLOGY_TYPE_PATCH, + + /// Total number of topology types + PRIMITIVE_TOPOLOGY_TYPE_NUM_TYPES +}; + +/// Sample description + +/// This structure is used by GraphicsPipelineDesc to describe multisampling parameters +struct SampleDesc +{ + /// Sample count + Uint32 Count; + + /// Quality + Uint32 Quality; + + SampleDesc() : + Count(1), + Quality(0) + {} +}; + + +/// Graphics pipeline state description + +/// This structure describes the graphics pipeline state and is part of the PipelineStateDesc structure. +struct GraphicsPipelineDesc +{ + /// Vertex shader to be used with the pipeline + IShader *pVS; + + /// Pixel shader to be used with the pipeline + IShader *pPS; + + /// Domain shader to be used with the pipeline + IShader *pDS; + + /// Hull shader to be used with the pipeline + IShader *pHS; + + /// Geometry shader to be used with the pipeline + IShader *pGS; + + //D3D12_STREAM_OUTPUT_DESC StreamOutput; + + /// Blend state description + BlendStateDesc BlendDesc; + + /// 32-bit sample mask that determines which samples get updated + /// in all the active render targets. A sample mask is always applied; + /// it is independent of whether multisampling is enabled, and does not + /// depend on whether an application uses multisample render targets. + Uint32 SampleMask; + + /// Rasterizer state description + RasterizerStateDesc RasterizerDesc; + + /// Depth-stencil state description + DepthStencilStateDesc DepthStencilDesc; + + /// Input layout + InputLayoutDesc InputLayout; + //D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; + + /// Primitive topology type + PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; + + /// Number of render targets in the RTVFormats member + Uint32 NumRenderTargets; + + /// Render target formats + TEXTURE_FORMAT RTVFormats[8]; + + /// Depth-stencil format + TEXTURE_FORMAT DSVFormat; + + /// Multisampling parameters + SampleDesc SmplDesc; + + /// Node mask. + Uint32 NodeMask; + + //D3D12_CACHED_PIPELINE_STATE CachedPSO; + //D3D12_PIPELINE_STATE_FLAGS Flags; + + GraphicsPipelineDesc() : + pVS(nullptr), + pPS(nullptr), + pDS(nullptr), + pHS(nullptr), + pGS(nullptr), + PrimitiveTopologyType(PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE), + SampleMask(0xFFFFFFFF), + NumRenderTargets(0), + NodeMask(0) + { + for(size_t rt = 0; rt < _countof(RTVFormats); ++rt) + RTVFormats[rt] = TEX_FORMAT_UNKNOWN; + DSVFormat = TEX_FORMAT_UNKNOWN; + }; +}; + + +/// Compute pipeline state description + +/// This structure describes the compute pipeline state and is part of the PipelineStateDesc structure. +struct ComputePipelineDesc +{ + /// Compute shader to be used with the pipeline + IShader *pCS; + ComputePipelineDesc() : + pCS(nullptr) + {} +}; + +/// Pipeline state description +struct PipelineStateDesc : DeviceObjectAttribs +{ + /// Flag indicating if pipeline state is a compute pipeline state + bool IsComputePipeline; + + /// Graphics pipeline state description. This memeber is ignored if IsComputePipeline == True + GraphicsPipelineDesc GraphicsPipeline; + + /// Compute pipeline state description. This memeber is ignored if IsComputePipeline == False + ComputePipelineDesc ComputePipeline; + + /// Shader resource binding allocation granularity + + /// This member defines allocation granularity for internal resources required by the shader resource + /// binding object instances. + Uint32 SRBAllocationGranularity; + + PipelineStateDesc() : + IsComputePipeline(false), + SRBAllocationGranularity(1) + {} +}; + +// {06084AE5-6A71-4FE8-84B9-395DD489A28C} +static const Diligent::INTERFACE_ID IID_PipelineState = +{ 0x6084ae5, 0x6a71, 0x4fe8, { 0x84, 0xb9, 0x39, 0x5d, 0xd4, 0x89, 0xa2, 0x8c } }; + +/** + * Pipeline state interface + */ +class IPipelineState : public IDeviceObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns the blend state description used to create the object + virtual const PipelineStateDesc& GetDesc()const = 0; + + /// Binds resources for all shaders in the pipeline state + + /// \param [in] pResourceMapping - Pointer to the resource mapping interface. + /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. + /// \remarks For older OpenGL devices that do not support program pipelines + /// (OpenGL4.1-, OpenGLES3.0-). This function is the only way to bind + /// shader resources. + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) = 0; + + /// Creates a shader resource binding object + + /// \param [out] ppShaderResourceBinding - memory location where pointer to the new shader resource + /// binding object is written. + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding ) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/RasterizerState.h b/Graphics/GraphicsEngine/interface/RasterizerState.h index e69bf635..a475595d 100644 --- a/Graphics/GraphicsEngine/interface/RasterizerState.h +++ b/Graphics/GraphicsEngine/interface/RasterizerState.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,9 @@ #pragma once /// \file -/// Definition of the Diligent::IRasterizerState interface and related data structures +/// Rasterizer state description -#include "DeviceObject.h" +#include "BasicTypes.h" namespace Diligent { @@ -34,19 +34,20 @@ namespace Diligent /// Fill mode /// [D3D11_FILL_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476131(v=vs.85).aspx -/// This enumeration determines the fill mode to use when rendering triangles and mirrows the -/// [D3D11_FILL_MODE][] enum. It is used by RasterizerStateDesc structure to define the fill mode. +/// [D3D12_FILL_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770366(v=vs.85).aspx +/// This enumeration determines the fill mode to use when rendering triangles and mirrors the +/// [D3D11_FILL_MODE][]/[D3D12_FILL_MODE][] enum. It is used by RasterizerStateDesc structure to define the fill mode. enum FILL_MODE : Int32 { /// Undefined fill mode. FILL_MODE_UNDEFINED = 0, /// Rasterize triangles using wireframe fill. \n - /// D3D11 counterpart: D3D11_FILL_WIREFRAME. OpenGL counterpart: GL_LINE. + /// Direct3D counterpart: D3D11_FILL_WIREFRAME/D3D12_FILL_MODE_WIREFRAME. OpenGL counterpart: GL_LINE. FILL_MODE_WIREFRAME, /// Rasterize triangles using solid fill. \n - /// D3D11 counterpart: D3D11_FILL_SOLID. OpenGL counterpart: GL_FILL. + /// Direct3D counterpart: D3D11_FILL_SOLID/D3D12_FILL_MODE_SOLID. OpenGL counterpart: GL_FILL. FILL_MODE_SOLID, /// Helper value that stores the total number of fill modes in the enumeration. @@ -56,40 +57,37 @@ enum FILL_MODE : Int32 /// Cull mode /// [D3D11_CULL_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476108(v=vs.85).aspx -/// This enumeration defines which triangles are not drawn during the rasterization and mirrows -/// [D3D11_CULL_MODE][] enum. It is used by RasterizerStateDesc structure to define the polygin cull mode. +/// [D3D12_CULL_MODE]: https://msdn.microsoft.com/en-us/library/windows/desktop/dn770354(v=vs.85).aspx +/// This enumeration defines which triangles are not drawn during the rasterization and mirrors +/// [D3D11_CULL_MODE][]/[D3D12_CULL_MODE][] enum. It is used by RasterizerStateDesc structure to define the polygon cull mode. enum CULL_MODE : Int32 { /// Undefined cull mode. CULL_MODE_UNDEFINED = 0, /// Draw all triangles. \n - /// D3D11 counterpart: D3D11_CULL_NONE. OpenGL counterpart: glDisable( GL_CULL_FACE ). + /// Direct3D counterpart: D3D11_CULL_NONE/D3D12_CULL_MODE_NONE. OpenGL counterpart: glDisable( GL_CULL_FACE ). CULL_MODE_NONE, /// Do not draw triangles that are front-facing. Front- and back-facing triangles are determined /// by the RasterizerStateDesc::FrontCounterClockwise member. \n - /// D3D11 counterpart: D3D11_CULL_FRONT. OpenGL counterpart: GL_FRONT. + /// Direct3D counterpart: D3D11_CULL_FRONT/D3D12_CULL_MODE_FRONT. OpenGL counterpart: GL_FRONT. CULL_MODE_FRONT, /// Do not draw triangles that are back-facing. Front- and back-facing triangles are determined /// by the RasterizerStateDesc::FrontCounterClockwise member. \n - /// D3D11 counterpart: D3D11_CULL_BACK. OpenGL counterpart: GL_BACK. + /// Direct3D counterpart: D3D11_CULL_BACK/D3D12_CULL_MODE_BACK. OpenGL counterpart: GL_BACK. CULL_MODE_BACK, /// Helper value that stores the total number of cull modes in the enumeration. CULL_MODE_NUM_MODES }; -// {530A181E-2777-4DAA-B837-ED7D3C28418E} -static const Diligent::INTERFACE_ID IID_RasterizerState = -{ 0x530a181e, 0x2777, 0x4daa, { 0xb8, 0x37, 0xed, 0x7d, 0x3c, 0x28, 0x41, 0x8e } }; /// Rasterizer state description -/// This structure describes the rasterizer state which is used in a call to -/// IRenderDevice::CreateRasterizerState() to create a rasterizer state object -struct RasterizerStateDesc : DeviceObjectAttribs +/// This structure describes the rasterizer state and is part of the GraphicsPipelineDesc. +struct RasterizerStateDesc { /// Determines traingle fill mode, see Diligent::FILL_MODE for details. FILL_MODE FillMode; @@ -157,14 +155,9 @@ struct RasterizerStateDesc : DeviceObjectAttribs /// \return /// - True if all members of the two structures are equal. /// - False otherwise - /// The operator ignores DeviceObjectAttribs::Name field as it does not affect - /// the rasterizer state. bool operator == (const RasterizerStateDesc& RHS)const { - // Name is primarily used for debug purposes and does not affect the state. - // It is ignored in comparison operation. - return // strcmp(Name, RHS.Name) == 0 && - FillMode == RHS.FillMode && + return FillMode == RHS.FillMode && CullMode == RHS.CullMode && FrontCounterClockwise == RHS.FrontCounterClockwise && DepthBias == RHS.DepthBias && @@ -176,19 +169,4 @@ struct RasterizerStateDesc : DeviceObjectAttribs } }; -/// Rasterizer state interface - -/// The interface holds the rasterizer state object that can be bound to the pipeline by a call -/// to IDeviceContext::SetRasterizerState(). To create a rasterizer state, call -/// IRenderDevice::CreateRasterizerState(). -class IRasterizerState : public IDeviceObject -{ -public: - /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; - - /// Returns the rasterizer state description used to create the object - virtual const RasterizerStateDesc& GetDesc()const = 0; -}; - -} +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngine/interface/RenderDevice.h b/Graphics/GraphicsEngine/interface/RenderDevice.h index f8471e11..5a0ca892 100644 --- a/Graphics/GraphicsEngine/interface/RenderDevice.h +++ b/Graphics/GraphicsEngine/interface/RenderDevice.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,13 +31,15 @@ #include "DeviceCaps.h" #include "Constants.h" #include "Buffer.h" -#include "VertexDescription.h" +#include "InputLayout.h" #include "Shader.h" #include "Texture.h" #include "Sampler.h" #include "ResourceMapping.h" #include "TextureView.h" #include "BufferView.h" +#include "PipelineState.h" + #include "DepthStencilState.h" #include "RasterizerState.h" #include "BlendState.h" @@ -49,9 +51,7 @@ namespace Diligent static const Diligent::INTERFACE_ID IID_RenderDevice = { 0xf0e9b607, 0xae33, 0x4b2b, { 0xb1, 0xaf, 0xa8, 0xb2, 0xc3, 0x10, 0x40, 0x22 } }; -/** - * Render device interface - */ +/// Render device interface class IRenderDevice : public IObject { public: @@ -78,22 +78,6 @@ public: const BufferData& BuffData, IBuffer **ppBuffer) = 0; - /// Creates a new vertex description object. - - /// \param [in] LayoutDesc - Layout description, see GraphisEngine::LayoutDesc for details. - /// \param [in] pVertexShader - Pointer to the vertex shader which this input layout - /// will be used with. If layout description is not compatible - /// with the shader's input signature, the method fails. - /// \param [out] ppVertexDesc - Address of the memory location where the pointer to the - /// vertex description interface will be stored. - /// The function calls AddRef(), so that the new object will contain - /// one refernce. - /// \remark The same vertex description object can be used with all shaders that have - /// the same input semantic. - virtual void CreateVertexDescription( const LayoutDesc& LayoutDesc, - IShader *pVertexShader, - IVertexDescription **ppVertexDesc ) = 0; - /// Creates a new shader object /// \param [in] CreationAttribs - Shader creation attributes, see @@ -154,44 +138,16 @@ public: virtual void CreateResourceMapping( const ResourceMappingDesc &MappingDesc, IResourceMapping **ppMapping ) = 0; - /// Creates a new depth stencil state object - - /// \param [in] DSSDesc - Depth-stencil state description, see Diligent::DepthStencilStateDesc for details. - /// \param [out] ppDepthStencilState - Address of the memory location where the pointer to the - /// depth-stencil state interface will be stored. - /// The function calls AddRef(), so that the new object will contain - /// one refernce. - /// \remark If an application attempts to create a depth-stencil state interface with the same attributes - /// as an existing interface, the same interface will be returned. - /// \note In D3D11, 4096 unique depth-stencil state objects can be created on a device at a time. - virtual void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, - IDepthStencilState **ppDepthStencilState ) = 0; - - /// Creates a rasterizer state object - - /// \param [in] RSDesc - Rasterizer state description, see Diligent::RasterizerStateDesc for details. - /// \param [out] ppRasterizerState - Address of the memory location where the pointer to the - /// rasterizer state interface will be stored. - /// The function calls AddRef(), so that the new object will contain - /// one refernce. - /// \remark If an application attempts to create a rasterizer state interface with the same attributes - /// as an existing interface, the same interface will be returned. - /// \note In D3D11, 4096 unique rasterizer state objects can be created on a device at a time. - virtual void CreateRasterizerState( const RasterizerStateDesc &RSDesc, - IRasterizerState **ppRasterizerState ) = 0; + /// Creates a new pipeline state object - /// Creates a blend state object + /// \param [in] PipelineDesc - Pipeline state description, see Diligent::PipelineStateDesc for details. + /// \param [out] ppPipelineState - Address of the memory location where the pointer to the + /// pipeline state interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one refernce. + virtual void CreatePipelineState( const PipelineStateDesc &PipelineDesc, + IPipelineState **ppPipelineState ) = 0; - /// \param [in] BSDesc - Blend state description, see Diligent::BlendStateDesc for details. - /// \param [out] ppBlendState - Address of the memory location where the pointer to the - /// blend state interface will be stored. - /// The function calls AddRef(), so that the new object will contain - /// one refernce. - /// \remark If an application attempts to create a blend state interface with the same attributes - /// as an existing interface, the same interface will be returned. - /// \note In D3D11, 4096 unique blend state objects can be created on a device at a time. - virtual void CreateBlendState( const BlendStateDesc &BSDesc, - IBlendState **ppBlendState ) = 0; /// Gets the device capabilities, see Diligent::DeviceCaps for details virtual const DeviceCaps& GetDeviceCaps()const = 0; diff --git a/Graphics/GraphicsEngine/interface/ResourceMapping.h b/Graphics/GraphicsEngine/interface/ResourceMapping.h index f4ee7a17..191ae66f 100644 --- a/Graphics/GraphicsEngine/interface/ResourceMapping.h +++ b/Graphics/GraphicsEngine/interface/ResourceMapping.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,13 +43,16 @@ namespace Diligent /// Pointer to the object's interface IDeviceObject *pObject; + Uint32 ArrayIndex; /// Initializes the structure members - /// \param [in] InitName - Object name. Default value is nullptr - /// \param [in] pInitObject - Pointer to the object. Default value is nullptr - ResourceMappingEntry( const Char* InitName = nullptr, IDeviceObject *pInitObject = nullptr) : - Name( InitName ), - pObject( pInitObject ) + /// \param [in] _Name - Object name. Default value is nullptr + /// \param [in] _pObject - Pointer to the object. Default value is nullptr + /// \param [in] _ArrayIndex - For array resources, index in the array + ResourceMappingEntry( const Char* _Name = nullptr, IDeviceObject *_pObject = nullptr, Uint32 _ArrayIndex = 0) : + Name( _Name ), + pObject( _pObject ), + ArrayIndex(_ArrayIndex) {} }; @@ -92,25 +95,38 @@ namespace Diligent /// object will not be released as long as it is in the resource mapping. virtual void AddResource( const Char *Name, IDeviceObject *pObject, bool bIsUnique ) = 0; - /// Removes a resource from the mapping. - /// \param [in] pObject - Pointer to the object to remove. - virtual void RemoveResource( IDeviceObject *pObject ) = 0; + /// Adds resource array to the mapping. + + /// \param [in] Name - Resource array name. + /// \param [in] StartIndex - First index in the array, where the first element will be inserted + /// \param [in] ppObjects - Pointer to the array of objects. + /// \param [in] NumElements - Number of elements to add + /// \param [in] bIsUnique - Flag indicating if a resource with the same name + /// is allowed to be found in the mapping. In the latter + /// case, the new resource replaces the existing one. + /// + /// \remarks Resource mapping increases the reference counter for referenced objects. So an + /// object will not be released as long as it is in the resource mapping. + virtual void AddResourceArray( const Char *Name, Uint32 StartIndex, IDeviceObject* const* ppObjects, Uint32 NumElements, bool bIsUnique ) = 0; + /// Removes a resource from the mapping using its literal name. /// \param [in] Name - Name of the resource to remove. - virtual void RemoveResourceByName( const Char *Name ) = 0; + /// \param [in] ArrayIndex - For array resources, index in the array + virtual void RemoveResourceByName( const Char *Name, Uint32 ArrayIndex = 0 ) = 0; /// Finds a resource in the mapping. /// \param [in] Name - Resource name. + /// \param [in] ArrayIndex - for arrays, index of the array element. /// \param [out] ppResource - Address of the memory location where the pointer /// to the object with the given name will be written. /// If no object is found, nullptr will be written. /// \remarks The method increases the reference counter /// of the returned object, so Release() must be called. - virtual void GetResource( const Char *Name, IDeviceObject **ppResource ) = 0; + virtual void GetResource( const Char *Name, IDeviceObject **ppResource, Uint32 ArrayIndex = 0 ) = 0; /// Returns the size of the resource mapping, i.e. the number of objects. virtual size_t GetSize() = 0; diff --git a/Graphics/GraphicsEngine/interface/Sampler.h b/Graphics/GraphicsEngine/interface/Sampler.h index 52742b3c..1f3c82a2 100644 --- a/Graphics/GraphicsEngine/interface/Sampler.h +++ b/Graphics/GraphicsEngine/interface/Sampler.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index 61861648..15d81342 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ #include "DeviceObject.h" #include "ResourceMapping.h" #include "FileStream.h" +#include "Sampler.h" namespace Diligent { @@ -58,13 +59,20 @@ enum SHADER_PROFILE : Int32 SHADER_PROFILE_DEFAULT = 0, SHADER_PROFILE_DX_4_0, SHADER_PROFILE_DX_5_0, + SHADER_PROFILE_DX_5_1, SHADER_PROFILE_GL_4_2 }; +/// Describes shader source code language enum SHADER_SOURCE_LANGUAGE : Int32 { + /// Default language (GLSL for OpenGL/OpenGLES devices, HLSL for Direct3D11/Direct3D12 devices) SHADER_SOURCE_LANGUAGE_DEFAULT = 0, + + /// The source language is HLSL SHADER_SOURCE_LANGUAGE_HLSL, + + /// The source language is GLSL SHADER_SOURCE_LANGUAGE_GLSL }; @@ -72,8 +80,8 @@ enum SHADER_SOURCE_LANGUAGE : Int32 /// and IDeviceContext::BindShaderResources(). enum BIND_SHADER_RESOURCES_FLAGS : Int32 { - /// Reset all bindings. If this specified, all existing bindings will be - /// broken. By default all existing bindings are presereved. + /// Reset all bindings. If this flag is specified, all existing bindings will be + /// broken. By default all existing bindings are preserved. BIND_SHADER_RESOURCES_RESET_BINDINGS = 0x01, /// If this flag is specified, only unresolved bindings will be updated. @@ -84,10 +92,56 @@ enum BIND_SHADER_RESOURCES_FLAGS : Int32 /// If this flag is specified, all shader bindings are expected /// to be resolved after the call. If this is not the case, debug error - /// will be output. + /// will be displayed. BIND_SHADER_RESOURCES_ALL_RESOLVED = 0x04 }; +/// Describes shader variable type that is used by ShaderVariableDesc +enum SHADER_VARIABLE_TYPE : Int32 +{ + /// Shader variable is constant across all shader instances. + /// It must be set *once* directly through IShader::BindResources() or through + /// the shader variable. + SHADER_VARIABLE_TYPE_STATIC = 0, + + /// Shader variable is constant across shader resource bindings instance (see IShaderResourceBinding). + /// It must be set *once* through IShaderResourceBinding::BindResources() or through + /// the shader variable. It cannot be set through IShader interface + SHADER_VARIABLE_TYPE_MUTABLE, + + /// Shader variable is dynamic. It can be set multiple times for every instance of shader resource + /// bindings (see IShaderResourceBinding). It cannot be set through IShader interface + SHADER_VARIABLE_TYPE_DYNAMIC, + + /// Total number of shader variable types + SHADER_VARIABLE_TYPE_NUM_TYPES +}; + +/// Describes shader variable +struct ShaderVariableDesc +{ + /// Shader variable name + const char *Name; + + /// Shader variable type. See Diligent::SHADER_VARIABLE_TYPE for a list of allowed types + SHADER_VARIABLE_TYPE Type; + ShaderVariableDesc(const char *_Name = nullptr, SHADER_VARIABLE_TYPE _Type = SHADER_VARIABLE_TYPE_STATIC) : + Name(_Name), + Type(_Type) + {} +}; + + +/// Static sampler description +struct StaticSamplerDesc +{ + /// Sampler description + SamplerDesc Desc; + + /// Name of the texture variable that static sampler will be assigned to + const char* TextureName = nullptr; +}; + /// Shader description struct ShaderDesc : DeviceObjectAttribs { @@ -97,10 +151,32 @@ struct ShaderDesc : DeviceObjectAttribs Bool bCacheCompiledShader; SHADER_PROFILE TargetProfile; + /// Default shader variable type. This type will be used if shader + /// variable description is not found in array VariableDesc points to + /// or if VariableDesc == nullptr + SHADER_VARIABLE_TYPE DefaultVariableType; + + /// Array of shader variable descriptions + const ShaderVariableDesc *VariableDesc; + + /// Number of elements in VariableDesc array + Uint32 NumVariables; + + /// Number of static samplers in StaticSamplers array + Uint32 NumStaticSamplers; + + /// Array of static sampler descriptions + StaticSamplerDesc *StaticSamplers; + ShaderDesc() : ShaderType(SHADER_TYPE_VERTEX), bCacheCompiledShader(False), - TargetProfile(SHADER_PROFILE_DEFAULT) + TargetProfile(SHADER_PROFILE_DEFAULT), + DefaultVariableType(SHADER_VARIABLE_TYPE_STATIC), + VariableDesc(nullptr), + NumVariables(0), + NumStaticSamplers(0), + StaticSamplers(nullptr) {} }; @@ -170,12 +246,7 @@ public: /// be assigned to a constant buffer variable. virtual void Set(IDeviceObject *pObject) = 0; - /// Returns the shader which this shader variable - /// belongs to - - /// \remark The method does not increment the reference counter - /// of the returned interface. - virtual class IShader* GetShader() = 0; + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) = 0; }; /// Shader interface diff --git a/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h new file mode 100644 index 00000000..7a757a3f --- /dev/null +++ b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h @@ -0,0 +1,68 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IShaderResourceBinding interface and related data structures + +#include "Object.h" + +namespace Diligent +{ + +// {061F8774-9A09-48E8-8411-B5BD20560104} +static const Diligent::INTERFACE_ID IID_ShaderResourceBinding = +{ 0x61f8774, 0x9a09, 0x48e8, { 0x84, 0x11, 0xb5, 0xbd, 0x20, 0x56, 0x1, 0x4 } }; + + +/// Shader resource binding interface +class IShaderResourceBinding : public IObject +{ +public: + /// Queries the specific interface, see IObject::QueryInterface() for details + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + + /// Returns pointer to the referenced buffer object. + + /// The method calls AddRef() on the returned interface, + /// so Release() must be called to avoid memory leaks. + virtual class IPipelineState* GetPipelineState() = 0; + + /// Binds all resource using the resource mapping + + /// \param [in] ShaderFlags - Flags for the shader stages, for which resources will be bound. + /// Any combination of Diligent::SHADER_TYPE may be specified. + /// \param [in] pResMapping - Shader resource mapping, where required resources will be looked up + /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags) = 0; + + /// Returns variable + + /// \param [in] ShaderType - Type of the shader to look up the variable. + /// Must be one of Diligent::SHADER_TYPE. + /// \param Name - Variable name + virtual IShaderVariable *GetVariable(SHADER_TYPE ShaderType, const char *Name) = 0; +}; + +} diff --git a/Graphics/GraphicsEngine/interface/SwapChain.h b/Graphics/GraphicsEngine/interface/SwapChain.h index c451bbf6..aae576bb 100644 --- a/Graphics/GraphicsEngine/interface/SwapChain.h +++ b/Graphics/GraphicsEngine/interface/SwapChain.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngine/interface/Texture.h b/Graphics/GraphicsEngine/interface/Texture.h index de352a3c..0c3c2c1e 100644 --- a/Graphics/GraphicsEngine/interface/Texture.h +++ b/Graphics/GraphicsEngine/interface/Texture.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,11 +35,43 @@ namespace Diligent static const Diligent::INTERFACE_ID IID_Texture = { 0xa64b0e60, 0x1b5e, 0x4cfd, { 0xb8, 0x80, 0x66, 0x3a, 0x1a, 0xdc, 0xbe, 0x98 } }; +/// Defines optimized depth-stencil clear value. +struct DepthStencilClearValue +{ + /// Depth clear value + Float32 Depth; + /// Stencil clear value + Uint8 Stencil; + DepthStencilClearValue() : + Depth(1.f), + Stencil(0) + {} +}; + +/// Defines optimized clear value. +struct OptimizedClearValue +{ + /// Format + TEXTURE_FORMAT Format; + /// Render target clear value + Float32 Color[ 4 ]; + /// Depth stencil clear value + DepthStencilClearValue DepthStencil; + OptimizedClearValue() : + Format(TEX_FORMAT_UNKNOWN) + { + Color[0] = 0; + Color[1] = 0; + Color[2] = 0; + Color[3] = 0; + } +}; + /// Texture description struct TextureDesc : DeviceObjectAttribs { - /// Texture type. See Diligent::TEXTURE_TYPE for details. - TEXTURE_TYPE Type; + /// Texture type. See Diligent::RESOURCE_DIMENSION for details. + RESOURCE_DIMENSION Type; /// Texture width, in pixels. Uint32 Width; @@ -84,12 +116,15 @@ struct TextureDesc : DeviceObjectAttribs /// Miscellaneous flags, see Diligent::MISC_TEXTURE_FLAG for details. Uint32 MiscFlags; + /// Optimized clear value + OptimizedClearValue ClearValue; + /// Initializes the structure members with default values /// Default values: /// Member | Default value /// ----------------|-------------- - /// Type | TEXTURE_TYPE_UNDEFINED + /// Type | RESOURCE_DIM_UNDEFINED /// Width | 0 /// Height | 0 /// ArraySize | 1 @@ -101,7 +136,7 @@ struct TextureDesc : DeviceObjectAttribs /// CPUAccessFlags | 0 /// MiscFlags | 0 TextureDesc() : - Type(TEXTURE_TYPE_UNDEFINED), + Type(RESOURCE_DIM_UNDEFINED), Width(0), Height(0), ArraySize(1), @@ -142,6 +177,13 @@ struct TextureSubResData Stride(0), DepthStride(0) {} + + /// Initializes the structure members with provided values + TextureSubResData(void *_pData, Uint32 _Stride, Uint32 _DepthStride=0): + pData(_pData), + Stride(_Stride), + DepthStride(_DepthStride) + {} }; /// Describes the initial data to store in the texture @@ -248,7 +290,7 @@ public: /// Map the texture - not implemented yet virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData ) = 0; /// Unmap the textute - not implemented yet - virtual void Unmap( IDeviceContext *pContext ) = 0; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) = 0; }; } diff --git a/Graphics/GraphicsEngine/interface/TextureView.h b/Graphics/GraphicsEngine/interface/TextureView.h index b55e2f0e..63780f7d 100644 --- a/Graphics/GraphicsEngine/interface/TextureView.h +++ b/Graphics/GraphicsEngine/interface/TextureView.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,10 +59,10 @@ struct TextureViewDesc : DeviceObjectAttribs /// View interpretation of the original texture. For instance, /// one slice of a 2D texture array can be viewed as a 2D texture. - /// See Diligent::TEXTURE_TYPE for a list of texture types. - /// If default value Diligent::TEXTURE_TYPE_UNDEFINED is provided, + /// See Diligent::RESOURCE_DIMENSION for a list of texture types. + /// If default value Diligent::RESOURCE_DIM_UNDEFINED is provided, /// the view type will match the type of the referenced texture. - TEXTURE_TYPE TextureType; + RESOURCE_DIMENSION TextureDim; /// View format. If default value Diligent::TEX_FORMAT_UNKNOWN is provided, /// the view format will match the referenced texture format. @@ -109,7 +109,7 @@ struct TextureViewDesc : DeviceObjectAttribs /// Member | Default value /// --------------------|-------------- /// ViewType | TEXTURE_VIEW_UNDEFINED - /// TextureType | TEXTURE_TYPE_UNDEFINED + /// TextureDim | RESOURCE_DIM_UNDEFINED /// Format | TEX_FORMAT_UNKNOWN /// MostDetailedMip | 0 /// NumMipLevels | 0 @@ -118,7 +118,7 @@ struct TextureViewDesc : DeviceObjectAttribs /// AccessFlags | 0 TextureViewDesc() : ViewType( TEXTURE_VIEW_UNDEFINED ), - TextureType( TEXTURE_TYPE_UNDEFINED ), + TextureDim( RESOURCE_DIM_UNDEFINED ), Format(TEX_FORMAT_UNKNOWN), MostDetailedMip(0), NumMipLevels(0), @@ -140,7 +140,7 @@ struct TextureViewDesc : DeviceObjectAttribs // It is ignored in comparison operation. return //strcmp(Name, RHS.Name) == 0 && ViewType == RHS.ViewType && - TextureType == RHS.TextureType && + TextureDim == RHS.TextureDim && Format == RHS.Format && MostDetailedMip == RHS.MostDetailedMip && NumMipLevels == RHS.NumMipLevels && diff --git a/Graphics/GraphicsEngine/src/EngineMemory.cpp b/Graphics/GraphicsEngine/src/EngineMemory.cpp new file mode 100644 index 00000000..b981724f --- /dev/null +++ b/Graphics/GraphicsEngine/src/EngineMemory.cpp @@ -0,0 +1,73 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// stdafx.cpp : source file that includes just the standard includes +// RenderEngine.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "pch.h" +#include "EngineMemory.h" +#include "DefaultRawMemoryAllocator.h" + +namespace Diligent +{ + +static IMemoryAllocator *g_pRawAllocator; +void SetRawAllocator(IMemoryAllocator *pRawAllocator) +{ + if (pRawAllocator == nullptr) + { + LOG_INFO_MESSAGE("User-defined allocator is not provided. Using default allocator.") + pRawAllocator = &DefaultRawMemoryAllocator::GetAllocator(); + } + g_pRawAllocator = pRawAllocator; +} + +IMemoryAllocator& GetRawAllocator() +{ + return *g_pRawAllocator; +} + +} +#if 0 + +void* operator new(size_t Size) +{ + return Diligent::GetRawAllocator().Allocate(Size, "<Unknown>", "<Unknown>", -1); +} + +void* operator new[](size_t Size) +{ + return Diligent::GetRawAllocator().Allocate(Size, "<Unknown>", "<Unknown>", -1); +} + +void operator delete(void* Ptr) +{ + Diligent::GetRawAllocator().Free(Ptr); +} + +void operator delete[](void* Ptr) +{ + Diligent::GetRawAllocator().Free(Ptr); +} +#endif diff --git a/Graphics/GraphicsEngine/src/ResourceMapping.cpp b/Graphics/GraphicsEngine/src/ResourceMapping.cpp index 47a54ed9..7bfb6ceb 100644 --- a/Graphics/GraphicsEngine/src/ResourceMapping.cpp +++ b/Graphics/GraphicsEngine/src/ResourceMapping.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,71 +33,62 @@ namespace Diligent { } - IMPLEMENT_QUERY_INTERFACE( ResourceMappingImpl, IID_ResourceMapping, ObjectBase<IResourceMapping> ) + IMPLEMENT_QUERY_INTERFACE( ResourceMappingImpl, IID_ResourceMapping, TObjectBase ) ThreadingTools::LockHelper ResourceMappingImpl::Lock() { return std::move( ThreadingTools::LockHelper( m_LockFlag ) ); } - void ResourceMappingImpl::AddResource( const Char *Name, IDeviceObject *pObject, bool bIsUnique ) + void ResourceMappingImpl::AddResourceArray( const Char *Name, Uint32 StartIndex, IDeviceObject * const* ppObjects, Uint32 NumElements, bool bIsUnique ) { if( Name == nullptr || *Name == 0 ) return; auto LockHelper = Lock(); - // Try to construct new element in place - auto Elems = - m_HashTable.emplace( - make_pair( Diligent::HashMapStringKey(Name, true), // Make a copy of the source string - Diligent::RefCntAutoPtr<IDeviceObject>(pObject) - ) - ); - // If there is already element with the same name, replace it - if( !Elems.second && Elems.first->second != pObject ) + for(Uint32 Elem = 0; Elem < NumElements; ++Elem) { - if( bIsUnique ) + auto *pObject = ppObjects[Elem]; + + // Try to construct new element in place + auto Elems = + m_HashTable.emplace( + make_pair( Diligent::ResMappingHashKey(Name, true, StartIndex+Elem), // Make a copy of the source string + Diligent::RefCntAutoPtr<IDeviceObject>(pObject) + ) + ); + // If there is already element with the same name, replace it + if( !Elems.second && Elems.first->second != pObject ) { - UNEXPECTED( "Resource with the same name already exists" ); - LOG_WARNING_MESSAGE( - "Resource with name ", Name, " marked is unique, but already present in the hash.\n" - "New resource will be used\n." ); + if( bIsUnique ) + { + UNEXPECTED( "Resource with the same name already exists" ); + LOG_WARNING_MESSAGE( + "Resource with name ", Name, " marked is unique, but already present in the hash.\n" + "New resource will be used\n." ); + } + Elems.first->second = pObject; } - Elems.first->second = pObject; } } - void ResourceMappingImpl::RemoveResourceByName( const Char *Name ) + void ResourceMappingImpl::AddResource(const Char *Name, IDeviceObject *pObject, bool bIsUnique) { - if( *Name == 0 ) - return; - - auto LockHelper = Lock(); - // Remove object with the given name - // Name will be implicitly converted to HashMapStringKey without making a copy - auto It = m_HashTable.erase( Name ); + AddResourceArray( Name, 0, &pObject, 1, bIsUnique ); } - void ResourceMappingImpl::RemoveResource( IDeviceObject *pObject ) + void ResourceMappingImpl::RemoveResourceByName( const Char *Name, Uint32 ArrayIndex ) { - const auto *Name = pObject->GetDesc().Name; - VERIFY( Name, "Name is null" ); if( *Name == 0 ) return; auto LockHelper = Lock(); - - // Find active object with the same name + // Remove object with the given name // Name will be implicitly converted to HashMapStringKey without making a copy - auto It = m_HashTable.find( Name ); - // Check if the active object is in fact the object being removed - if( It != m_HashTable.end() && It->second == pObject ) - { - m_HashTable.erase( It ); - } + m_HashTable.erase( ResMappingHashKey(Name, false, ArrayIndex) ); } - void ResourceMappingImpl::GetResource( const Char *Name, IDeviceObject **ppResource ) + void ResourceMappingImpl::GetResource( const Char *Name, IDeviceObject **ppResource, Uint32 ArrayIndex ) { VERIFY(Name, "Name is null") if( *Name == 0 ) @@ -114,7 +105,7 @@ namespace Diligent // Find an object with the requested name // Name will be implicitly converted to HashMapStringKey without making a copy - auto It = m_HashTable.find( Name ); + auto It = m_HashTable.find( ResMappingHashKey(Name, false, ArrayIndex) ); if( It != m_HashTable.end() ) { *ppResource = It->second.RawPtr(); diff --git a/Graphics/GraphicsEngine/src/Texture.cpp b/Graphics/GraphicsEngine/src/Texture.cpp index 60440bdc..244e93b7 100644 --- a/Graphics/GraphicsEngine/src/Texture.cpp +++ b/Graphics/GraphicsEngine/src/Texture.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,30 +32,39 @@ void ValidateTextureDesc( const TextureDesc& Desc ) #define LOG_TEXTURE_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Texture \"", Desc.Name ? Desc.Name : "", "\": ", ##__VA_ARGS__) // Perform some parameter correctness check - if( Desc.Type == TEXTURE_TYPE_1D || Desc.Type == TEXTURE_TYPE_1D_ARRAY ) + if( Desc.Type == RESOURCE_DIM_TEX_1D || Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) { if( Desc.Height != 1 ) LOG_TEXTURE_ERROR_AND_THROW("Height (", Desc.Height,") of Texture 1D/Texture 1D Array must be 1"); } - if( Desc.Type == TEXTURE_TYPE_1D || Desc.Type == TEXTURE_TYPE_2D ) + if( Desc.Type == RESOURCE_DIM_TEX_1D || Desc.Type == RESOURCE_DIM_TEX_2D ) { if( Desc.ArraySize != 1 ) LOG_TEXTURE_ERROR_AND_THROW("Texture 1D/2D must have one array slice (", Desc.ArraySize, " provided). Use Texture 1D/2D array if you need more than one slice."); } + if( Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY ) + { + if( Desc.Width != Desc.Height ) + LOG_TEXTURE_ERROR_AND_THROW("For cube map textures, texture width (", Desc.Width," provided) must match texture height (", Desc.Height, " provided)"); + + if( Desc.ArraySize < 6 ) + LOG_TEXTURE_ERROR_AND_THROW("Texture cube/cube array must have at least 6 slices (", Desc.ArraySize, " provided)."); + } + Uint32 MaxDim = 0; - if( Desc.Type == TEXTURE_TYPE_1D || Desc.Type == TEXTURE_TYPE_1D_ARRAY ) + if( Desc.Type == RESOURCE_DIM_TEX_1D || Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) MaxDim = Desc.Width; - else if( Desc.Type == TEXTURE_TYPE_2D || Desc.Type == TEXTURE_TYPE_2D_ARRAY ) + else if( Desc.Type == RESOURCE_DIM_TEX_2D || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY ) MaxDim = std::max(Desc.Width, Desc.Height); - else if( Desc.Type == TEXTURE_TYPE_3D ) + else if( Desc.Type == RESOURCE_DIM_TEX_3D ) MaxDim = std::max( std::max(Desc.Width, Desc.Height), Desc.Depth ); VERIFY( MaxDim >= (1U << (Desc.MipLevels-1)), "Texture \"", Desc.Name ? Desc.Name : "", "\": Incorrect number of Mip levels (", Desc.MipLevels, ")" ) if( Desc.SampleCount > 1 ) { - if( !(Desc.Type == TEXTURE_TYPE_2D || Desc.Type == TEXTURE_TYPE_2D_ARRAY) ) + if( !(Desc.Type == RESOURCE_DIM_TEX_2D || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY) ) LOG_TEXTURE_ERROR_AND_THROW("Only Texture 2D/Texture 2D Array can be multisampled"); if( Desc.MipLevels != 1 ) @@ -80,14 +89,16 @@ void ValidateTextureDesc( const TextureDesc& Desc ) void ValidateTextureRegion(const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &Box) { #define VERIFY_TEX_PARAMS(Expr, ...) VERIFY(Expr, "Texture \"", TexDesc.Name ? TexDesc.Name : "", "\": ", ##__VA_ARGS__) - +#ifdef _DEBUG VERIFY_TEX_PARAMS( MipLevel < TexDesc.MipLevels, "Mip level (", MipLevel, ") is out of allowed range [0, ", TexDesc.MipLevels-1, "]" ); VERIFY_TEX_PARAMS( Box.MinX < Box.MaxX, "Incorrect X range [",Box.MinX, ", ", Box.MaxX, ")" ); VERIFY_TEX_PARAMS( Box.MinY < Box.MaxY, "Incorrect Y range [",Box.MinY, ", ", Box.MaxY, ")" ); VERIFY_TEX_PARAMS( Box.MinZ < Box.MaxZ, "Incorrect Z range [",Box.MinZ, ", ", Box.MaxZ, ")" ); - if( TexDesc.Type == TEXTURE_TYPE_1D_ARRAY || - TexDesc.Type == TEXTURE_TYPE_2D_ARRAY ) + if( TexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY || + TexDesc.Type == RESOURCE_DIM_TEX_2D_ARRAY || + TexDesc.Type == RESOURCE_DIM_TEX_CUBE || + TexDesc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) { VERIFY_TEX_PARAMS( Slice < TexDesc.ArraySize, "Array slice (", Slice, ") is out of range [0,", TexDesc.ArraySize-1, "]" ); } @@ -96,20 +107,22 @@ void ValidateTextureRegion(const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 S VERIFY_TEX_PARAMS( Slice == 0, "Array slice (", Slice, ") must be 0 for non-array textures" ); } + Uint32 MipWidth = std::max(TexDesc.Width >> MipLevel, 1U); VERIFY_TEX_PARAMS( Box.MaxX <= MipWidth, "Region max X coordinate (", Box.MaxX, ") is out of allowed range [0, ", MipWidth, "]" ); - if( TexDesc.Type != TEXTURE_TYPE_1D && - TexDesc.Type != TEXTURE_TYPE_1D_ARRAY ) + if( TexDesc.Type != RESOURCE_DIM_TEX_1D && + TexDesc.Type != RESOURCE_DIM_TEX_1D_ARRAY ) { Uint32 MipHeight = std::max(TexDesc.Height >> MipLevel, 1U); VERIFY_TEX_PARAMS( Box.MaxY <= MipHeight, "Region max Y coordinate (", Box.MaxY, ") is out of allowed range [0, ", MipHeight, "]" ); } - if( TexDesc.Type == TEXTURE_TYPE_3D ) + if( TexDesc.Type == RESOURCE_DIM_TEX_3D ) { Uint32 MipDepth = std::max(TexDesc.Depth >> MipLevel, 1U); VERIFY_TEX_PARAMS( Box.MaxZ <= MipDepth, "Region max Z coordinate (", Box.MaxZ, ") is out of allowed range [0, ", MipDepth, "]" ); } +#endif } void ValidateUpdateDataParams( const TextureDesc &TexDesc, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) @@ -128,13 +141,13 @@ void VliadateCopyTextureDataParams( const TextureDesc &SrcTexDesc, Uint32 SrcMip if( pSrcBox == nullptr ) { SrcBox.MaxX = std::max( SrcTexDesc.Width >> SrcMipLevel, 1u ); - if( SrcTexDesc.Type == TEXTURE_TYPE_1D || - SrcTexDesc.Type == TEXTURE_TYPE_1D_ARRAY ) + if( SrcTexDesc.Type == RESOURCE_DIM_TEX_1D || + SrcTexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) SrcBox.MaxY = 1; else SrcBox.MaxY = std::max( SrcTexDesc.Height >> SrcMipLevel, 1u ); - if( SrcTexDesc.Type == TEXTURE_TYPE_3D ) + if( SrcTexDesc.Type == RESOURCE_DIM_TEX_3D ) SrcBox.MaxZ = std::max( SrcTexDesc.Depth >> SrcMipLevel, 1u ); else SrcBox.MaxZ = 1; diff --git a/Graphics/GraphicsEngine/src/pch.cpp b/Graphics/GraphicsEngine/src/pch.cpp index bf010b17..b2c201a7 100644 --- a/Graphics/GraphicsEngine/src/pch.cpp +++ b/Graphics/GraphicsEngine/src/pch.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj b/Graphics/GraphicsEngineD3D11/build/UWP/GraphicsEngineD3D11.vcxproj index 095b7883..d31d9a69 100644 --- a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj +++ b/Graphics/GraphicsEngineD3D11/build/UWP/GraphicsEngineD3D11.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|ARM"> <Configuration>Debug</Configuration> @@ -27,88 +27,89 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{3838fd2b-3c87-4caf-95de-95e7c3947c26}</ProjectGuid> + <ProjectGuid>{29acd2a7-4c49-4973-9673-8f57ef37070f}</ProjectGuid> + <Keyword>StaticLibrary</Keyword> <RootNamespace>GraphicsEngineD3D11</RootNamespace> <DefaultLanguage>en-US</DefaultLanguage> - <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> <AppContainerApplication>true</AppContainerApplication> <ApplicationType>Windows Store</ApplicationType> - <ApplicationTypeRevision>8.1</ApplicationTypeRevision> - <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + <WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion> + <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion> + <ApplicationTypeRevision>10.0</ApplicationTypeRevision> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="..\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" /> + </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmDbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmRel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <GenerateManifest>false</GenerateManifest> </PropertyGroup> @@ -129,7 +130,6 @@ </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -141,7 +141,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -153,7 +152,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -165,7 +163,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -177,7 +174,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -189,7 +185,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> diff --git a/Graphics/GraphicsEngineD3D11/build/UWP/GraphicsEngineD3D11.vcxproj.filters b/Graphics/GraphicsEngineD3D11/build/UWP/GraphicsEngineD3D11.vcxproj.filters new file mode 100644 index 00000000..c31757ec --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/UWP/GraphicsEngineD3D11.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj b/Graphics/GraphicsEngineD3D11/build/Win32/GraphicsEngineD3D11.vcxproj index 7a6e1ebd..571c5660 100644 --- a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj +++ b/Graphics/GraphicsEngineD3D11/build/Win32/GraphicsEngineD3D11.vcxproj @@ -35,22 +35,36 @@ </ProjectConfiguration> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\..\..\..\Common\build\Windows\Common.vcxproj"> + <ProjectReference Include="..\..\..\..\Common\build\Win32\Common.vcxproj"> <Project>{7380f7e6-315f-4b4e-92eb-e6aeee865298}</Project> </ProjectReference> - <ProjectReference Include="..\..\..\..\Platforms\Basic\build\Windows\BasicPlatform.vcxproj"> + <ProjectReference Include="..\..\..\..\Platforms\Basic\build\Win32\BasicPlatform.vcxproj"> <Project>{8ada5f93-7a38-4ad8-b8f5-1ffd4d4f630c}</Project> </ProjectReference> - <ProjectReference Include="..\..\..\..\Platforms\Windows\build\Windows\WindowsPlatform.vcxproj"> + <ProjectReference Include="..\..\..\..\Platforms\Win32\build\Win32\WindowsPlatform.vcxproj"> <Project>{58f32677-436b-412a-bbf8-2b1310d82cd8}</Project> </ProjectReference> - <ProjectReference Include="..\..\..\GraphicsEngine\build\Windows\GraphicsEngine.vcxproj"> + <ProjectReference Include="..\..\..\GraphicsEngineD3DBase\build\Win32\GraphicsEngineD3DBase.vcxproj"> + <Project>{40fd58ed-aabc-4cbd-bee4-33116995a626}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsEngine\build\Win32\GraphicsEngine.vcxproj"> <Project>{052dd700-477c-4512-a7f4-b05ebef5c80e}</Project> </ProjectReference> - <ProjectReference Include="..\..\..\GraphicsTools\build\Windows\GraphicsTools.vcxproj"> + <ProjectReference Include="..\..\..\GraphicsTools\build\Win32\GraphicsTools.vcxproj"> <Project>{c6014499-0cf2-43ec-a773-a4e354fb2d74}</Project> </ProjectReference> </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\DLLMain.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\..\src\GraphicsEngineD3D11.def" /> + </ItemGroup> <PropertyGroup Label="Globals"> <ProjectGuid>{FE289CC7-15D6-4A76-B9CB-F61CAB3192C9}</ProjectGuid> <Keyword>Win32Proj</Keyword> @@ -111,58 +125,50 @@ </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> - <Import Project="..\WindowsStore\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" Condition="Exists('..\WindowsStore\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems')" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" Condition="Exists('..\Windows.Shared\GraphicsEngineD3D11.Shared.vcxitems')" /> </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" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> </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" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsEngineD3D11.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D11.props" /> <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> @@ -184,7 +190,6 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" /> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -199,7 +204,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -216,7 +220,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -232,7 +235,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -250,11 +252,13 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalOptions>/Qvec-report:1 %(AdditionalOptions)</AdditionalOptions> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -269,11 +273,13 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalOptions>/Qvec-report:1 %(AdditionalOptions)</AdditionalOptions> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -290,11 +296,13 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalOptions>/Qvec-report:1 %(AdditionalOptions)</AdditionalOptions> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -310,11 +318,13 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet> + <AdditionalOptions>/Qvec-report:1 %(AdditionalOptions)</AdditionalOptions> </ClCompile> <Link> <SubSystem>Windows</SubSystem> diff --git a/Graphics/GraphicsEngineD3D11/build/Win32/GraphicsEngineD3D11.vcxproj.filters b/Graphics/GraphicsEngineD3D11/build/Win32/GraphicsEngineD3D11.vcxproj.filters new file mode 100644 index 00000000..afa04bc6 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Win32/GraphicsEngineD3D11.vcxproj.filters @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="..\..\src\DLLMain.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="..\..\src\GraphicsEngineD3D11.def" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.Shared.vcxitems b/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.Shared.vcxitems new file mode 100644 index 00000000..9e8c8b8f --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.Shared.vcxitems @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{3c22010c-99f3-4321-8f55-36da8f97a980}</ItemsProjectGuid> + <ItemsRootNamespace>GraphicsEngineD3D11</ItemsRootNamespace> + <ItemsProjectName>GraphicsEngineD3D11.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\EngineD3D11Defines.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceCacheD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferViewD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D11DebugUtilities.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D11TypeConversions.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D11TypeDefinitions.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceContextD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\PipelineStateD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceBindingD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceLayoutD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourcesD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\EngineD3D11Attribs.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\PipelineStateD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SamplerD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SwapChainD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\targetver.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Texture1D_D3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Texture2D_D3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Texture3D_D3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureBaseD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureViewD3D11Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferViewD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceContextD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceFactoryD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SamplerD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderResourceBindingD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SwapChainD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureD3D11.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureViewD3D11.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferViewD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\CommandListD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D11DebugUtilities.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D11TypeConversions.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DeviceContextD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\PipelineStateD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceFactoryD3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SamplerD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceBindingD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceCacheD3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceLayoutD3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourcesD3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SwapChainD3D11Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture1D_D3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture2D_D3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture3D_D3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureBaseD3D11.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureViewD3D11Impl.cpp" /> + </ItemGroup> + <ItemGroup> + <Text Include="$(MSBuildThisFileDirectory)..\..\CMakeLists.txt"> + <DeploymentContent>false</DeploymentContent> + </Text> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters b/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters new file mode 100644 index 00000000..e23371f0 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="src"> + <UniqueIdentifier>{326ec87b-f6ab-4291-a28f-631b2b240d3a}</UniqueIdentifier> + </Filter> + <Filter Include="include"> + <UniqueIdentifier>{a12cf1d4-8cb0-4360-898a-d69d16e288c5}</UniqueIdentifier> + </Filter> + <Filter Include="interface"> + <UniqueIdentifier>{e3e50068-d75b-4663-bee9-5ca137971e89}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\DeviceContextD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceFactoryD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SamplerD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureViewD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferViewD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SamplerD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Texture1D_D3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Texture2D_D3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\Texture3D_D3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureBaseD3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureViewD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferViewD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D11TypeConversions.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceContextD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SwapChainD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SwapChainD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\targetver.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D11DebugUtilities.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\PipelineStateD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\PipelineStateD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D11TypeDefinitions.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceBindingD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderResourceBindingD3D11.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceCacheD3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceLayoutD3D11.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\EngineD3D11Attribs.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\EngineD3D11Defines.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListD3D11Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourcesD3D11.h"> + <Filter>include</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SamplerD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture1D_D3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture2D_D3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\Texture3D_D3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureBaseD3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureViewD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferViewD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D11TypeConversions.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DeviceContextD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SwapChainD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceFactoryD3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D11DebugUtilities.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\PipelineStateD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceBindingD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceCacheD3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceLayoutD3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\CommandListD3D11Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourcesD3D11.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Text Include="$(MSBuildThisFileDirectory)..\..\CMakeLists.txt" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.props b/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.props new file mode 100644 index 00000000..c72d8cf0 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/build/Windows.Shared/GraphicsEngineD3D11.props @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..</GraphicsRoot> + <ProjectRoot>..\..</ProjectRoot> + </PropertyGroup> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsEngineD3D11\include;$(GraphicsRoot)\GraphicsEngineD3D11\interface;$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsEngineD3DBase\include;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + <BuildMacro Include="ProjectRoot"> + <Value>$(ProjectRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.props b/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.props deleted file mode 100644 index db23faae..00000000 --- a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.props +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <IncludePath>$(GraphicsRoot)\GraphicsEngineD3D11\include;$(GraphicsRoot)\GraphicsEngineD3D11\interface;$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> - </PropertyGroup> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/EngineRoot.props b/Graphics/GraphicsEngineD3D11/build/WindowsStore/EngineRoot.props deleted file mode 100644 index fcb891c0..00000000 --- a/Graphics/GraphicsEngineD3D11/build/WindowsStore/EngineRoot.props +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros"> - <EngineRoot>..\..\..\..\..</EngineRoot> - <GraphicsRoot>..\..\..\..</GraphicsRoot> - </PropertyGroup> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup> - <BuildMacro Include="EngineRoot"> - <Value>$(EngineRoot)</Value> - </BuildMacro> - <BuildMacro Include="GraphicsRoot"> - <Value>$(GraphicsRoot)</Value> - </BuildMacro> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems deleted file mode 100644 index 0850b1e0..00000000 --- a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems +++ /dev/null @@ -1,89 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup Label="Globals"> - <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> - <HasSharedItems>true</HasSharedItems> - <ItemsProjectGuid>{3c22010c-99f3-4321-8f55-36da8f97a980}</ItemsProjectGuid> - <ItemsRootNamespace>GraphicsEngineD3D11</ItemsRootNamespace> - <ItemsProjectName>GraphicsEngineD3D11.Shared</ItemsProjectName> - <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ProjectCapability Include="SourceItemsFromImports" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3DErrors.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11DebugUtilities.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11TypeConversions.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DSStateD3D11Impl.h" /> - <CustomBuild Include="$(MSBuildThisFileDirectory)..\..\..\include\HLSLDefinitions.fxh"> - <FileType>CppHeader</FileType> - <Command>$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.fxh</Command> - <Outputs>$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> - </CustomBuild> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\targetver.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture1D_D3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture2D_D3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture3D_D3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBaseD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescD3D11Impl.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendStateD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferViewD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilStateD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContextD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerStateD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceFactoryD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SamplerD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ShaderD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChainD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureViewD3D11.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescriptionD3D11.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BlendStateD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferViewD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11DebugUtilities.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11TypeConversions.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DeviceContextD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DLLMain.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DSStateD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RasterizerStateD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceFactoryD3D11.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SamplerD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ShaderD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SwapChainD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture1D_D3D11.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture2D_D3D11.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture3D_D3D11.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureBaseD3D11.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureViewD3D11Impl.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\VertexDescD3D11Impl.cpp" /> - </ItemGroup> - <ItemGroup> - <None Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsEngineD3D11.def" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters deleted file mode 100644 index dd1617f1..00000000 --- a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Shared/GraphicsEngineD3D11.Shared.vcxitems.filters +++ /dev/null @@ -1,196 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="src"> - <UniqueIdentifier>{326ec87b-f6ab-4291-a28f-631b2b240d3a}</UniqueIdentifier> - </Filter> - <Filter Include="include"> - <UniqueIdentifier>{a12cf1d4-8cb0-4360-898a-d69d16e288c5}</UniqueIdentifier> - </Filter> - <Filter Include="interface"> - <UniqueIdentifier>{e3e50068-d75b-4663-bee9-5ca137971e89}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DepthStencilStateD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\DeviceContextD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RasterizerStateD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\RenderDeviceFactoryD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SamplerD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\ShaderD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\TextureViewD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\VertexDescriptionD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BlendStateD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\BufferViewD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DSStateD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RasterizerStateD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\RenderDeviceD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SamplerD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture1D_D3D11.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture2D_D3D11.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\Texture3D_D3D11.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureBaseD3D11.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\TextureViewD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\VertexDescD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BlendStateD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BufferViewD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11TypeConversions.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\DeviceContextD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\interface\SwapChainD3D11.h"> - <Filter>interface</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\SwapChainD3D11Impl.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\targetver.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3D11DebugUtilities.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\D3DErrors.h"> - <Filter>include</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SamplerD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\ShaderD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture1D_D3D11.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture2D_D3D11.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\Texture3D_D3D11.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureBaseD3D11.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\TextureViewD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\VertexDescD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BlendStateD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BufferViewD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11TypeConversions.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DeviceContextD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DSStateD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RasterizerStateD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\SwapChainD3D11Impl.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\RenderDeviceFactoryD3D11.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\D3D11DebugUtilities.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\DLLMain.cpp"> - <Filter>src</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsEngineD3D11.def"> - <Filter>src</Filter> - </None> - </ItemGroup> - <ItemGroup> - <CustomBuild Include="$(MSBuildThisFileDirectory)..\..\..\include\HLSLDefinitions.fxh"> - <Filter>include</Filter> - </CustomBuild> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj.filters b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj.filters deleted file mode 100644 index 4228787f..00000000 --- a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.Windows/GraphicsEngineD3D11.Windows.vcxproj.filters +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj deleted file mode 100644 index 37889180..00000000 --- a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj +++ /dev/null @@ -1,144 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{581c72cf-7f31-4eba-8f6e-743ca5774742}</ProjectGuid> - <RootNamespace>GraphicsEngineD3D11</RootNamespace> - <DefaultLanguage>en-US</DefaultLanguage> - <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> - <AppContainerApplication>true</AppContainerApplication> - <ApplicationType>Windows Phone</ApplicationType> - <ApplicationTypeRevision>8.1</ApplicationTypeRevision> - <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120_wp81</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120_wp81</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120_wp81</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120_wp81</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="..\GraphicsEngineD3D11.Shared\GraphicsEngineD3D11.Shared.vcxitems" Label="Shared" /> - <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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> - </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngineD3D11.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> - <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> - <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> - </Link> - </ItemDefinitionGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj.filters b/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj.filters deleted file mode 100644 index 4228787f..00000000 --- a/Graphics/GraphicsEngineD3D11/build/WindowsStore/GraphicsEngineD3D11.WindowsPhone/GraphicsEngineD3D11.WindowsPhone.vcxproj.filters +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h index 190599cd..290b633f 100644 --- a/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,21 +34,43 @@ namespace Diligent { +class FixedBlockMemoryAllocator; + +enum class D3D11BufferState +{ + Undefined = 0x00, + ShaderResource = 0x01, + ConstantBuffer = 0x02, + VertexBuffer = 0x04, + IndexBuffer = 0x08, + UnorderedAccess = 0x10, + AnyInput = ShaderResource | ConstantBuffer | VertexBuffer | IndexBuffer +}; + /// Implementation of the Diligent::IBufferD3D11 interface -class BufferD3D11Impl : public BufferBase<IBufferD3D11, BufferViewD3D11Impl> +class BufferD3D11Impl : public BufferBase<IBufferD3D11, BufferViewD3D11Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> { public: - typedef BufferBase<IBufferD3D11, BufferViewD3D11Impl> TBufferBase; - BufferD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const BufferDesc& BuffDesc, const BufferData &BuffData = BufferData()); + typedef BufferBase<IBufferD3D11, BufferViewD3D11Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> TBufferBase; + BufferD3D11Impl(FixedBlockMemoryAllocator &BufferObjMemAllocator, + FixedBlockMemoryAllocator &BuffViewObjMemAllocator, + class RenderDeviceD3D11Impl *pDeviceD3D11, + const BufferDesc& BuffDesc, + const BufferData &BuffData = BufferData()); ~BufferD3D11Impl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + + virtual void UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData )override final; + virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override final; + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override final; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override final; + virtual ID3D11Buffer *GetD3D11Buffer()override final{ return m_pd3d11Buffer; } - virtual void UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData )override; - virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override; - virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; - virtual void Unmap( IDeviceContext *pContext )override; - virtual ID3D11Buffer *GetD3D11Buffer()override{ return m_pd3d11Buffer; } + void ResetState(D3D11BufferState State){m_State = static_cast<Uint32>(State);} + void AddState(D3D11BufferState State){m_State |= static_cast<Uint32>(State);} + void ClearState(D3D11BufferState State){m_State &= ~static_cast<Uint32>(State);} + bool CheckState(D3D11BufferState State){return (m_State & static_cast<Uint32>(State)) ? true : false;} private: virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView )override; @@ -57,7 +79,9 @@ private: void CreateSRV( struct BufferViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); friend class DeviceContextD3D11Impl; - Diligent::CComPtr<ID3D11Buffer> m_pd3d11Buffer; ///< D3D11 buffer object + CComPtr<ID3D11Buffer> m_pd3d11Buffer; ///< D3D11 buffer object + + Uint32 m_State = static_cast<Uint32>(D3D11BufferState::Undefined); }; } diff --git a/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.h index 37308ae9..07321a16 100644 --- a/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,24 +33,29 @@ namespace Diligent { +class FixedBlockMemoryAllocator; /// Implementation of the Diligent::IBufferViewD3D11 interface -class BufferViewD3D11Impl : public BufferViewBase<IBufferViewD3D11> +class BufferViewD3D11Impl : public BufferViewBase<IBufferViewD3D11, FixedBlockMemoryAllocator> { public: - typedef BufferViewBase<IBufferViewD3D11> TBufferViewBase; + typedef BufferViewBase<IBufferViewD3D11, FixedBlockMemoryAllocator> TBufferViewBase; - BufferViewD3D11Impl( IRenderDevice *pDevice, - const BufferViewDesc& ViewDesc, - class IBuffer *pBuffer, - ID3D11View* pD3D11View, - bool bIsDefaultView); + BufferViewD3D11Impl( FixedBlockMemoryAllocator &BuffViewObjAllocator, + IRenderDevice *pDevice, + const BufferViewDesc& ViewDesc, + class IBuffer *pBuffer, + ID3D11View* pD3D11View, + bool bIsDefaultView); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) final; - virtual ID3D11View* GetD3D11View(); + virtual ID3D11View* GetD3D11View()override final + { + return m_pD3D11View; + } protected: - Diligent::CComPtr<ID3D11View> m_pD3D11View; ///<D3D11 view + CComPtr<ID3D11View> m_pD3D11View; ///<D3D11 view }; } diff --git a/Graphics/GraphicsEngineD3D11/include/CommandListD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/CommandListD3D11Impl.h new file mode 100644 index 00000000..cf84c431 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/CommandListD3D11Impl.h @@ -0,0 +1,53 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::CommandListD3D11Impl class + +#include "RenderDeviceD3D11.h" +#include "CommandListBase.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Implementation of the Diligent::ICommandListD3D11 interface +class CommandListD3D11Impl : public CommandListBase<ICommandList, FixedBlockMemoryAllocator> +{ +public: + typedef CommandListBase<ICommandList, FixedBlockMemoryAllocator> TCommandListBase; + CommandListD3D11Impl(FixedBlockMemoryAllocator &CommandListObjMemAllocator, + IRenderDevice *pDevice, + ID3D11CommandList *pd3d11CommandList); + ~CommandListD3D11Impl(); + + ID3D11CommandList *GetD3D11CommandList(){ return m_pd3d11CommandList; } + +private: + CComPtr<ID3D11CommandList> m_pd3d11CommandList; ///< D3D11 CommandList object +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/D3D11DebugUtilities.h b/Graphics/GraphicsEngineD3D11/include/D3D11DebugUtilities.h index 1becfb17..cddc4249 100644 --- a/Graphics/GraphicsEngineD3D11/include/D3D11DebugUtilities.h +++ b/Graphics/GraphicsEngineD3D11/include/D3D11DebugUtilities.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,32 +26,8 @@ /// \file /// Debug utilities -#include "DeviceObject.h" -#include "ShaderD3D11Impl.h" - -#ifdef _DEBUG -# define VERIFY_RESOURCE_ARRAYS -#endif namespace Diligent { -#ifdef VERIFY_RESOURCE_ARRAYS - - /// Debug function that verifies that cached engine objects and d3d11 shader resource views in two provided arrays are consistent - void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSRV > &SRVs, const std::vector<ID3D11ShaderResourceView*> d3d11SRVs, IShader *pShader ); - - /// Debug function that verifies that cached engine objects and d3d11 unordered access views in two provided arrays are consistent - void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundUAV > &UAVs, const std::vector<ID3D11UnorderedAccessView*> d3d11UAVs, IShader *pShader ); - - /// Debug function that verifies that cached engine objects and d3d11 constant buffers in two provided arrays are consistent - void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundCB > &CBs, const std::vector<ID3D11Buffer*> d3d11CBs, IShader *pShader ); - - /// Debug function that verifies that cached engine objects and d3d11 samplers in two provided arrays are consistent - void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSampler >&Samplers, const std::vector<ID3D11SamplerState*> d3d11Samplers, IShader *pShader ); - -#else - - #define dbgVerifyResourceArrays(...) -#endif } diff --git a/Graphics/GraphicsEngineD3D11/include/D3D11TypeConversions.h b/Graphics/GraphicsEngineD3D11/include/D3D11TypeConversions.h index ddc76591..21031ea8 100644 --- a/Graphics/GraphicsEngineD3D11/include/D3D11TypeConversions.h +++ b/Graphics/GraphicsEngineD3D11/include/D3D11TypeConversions.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ /// Type conversion routines #include "GraphicsTypes.h" +#include "DXGITypeConversions.h" namespace Diligent { @@ -45,22 +46,7 @@ inline UINT BindFlagsToD3D11BindFlags(Uint32 BindFlags) return D3D11BindFlags; } -inline D3D11_PRIMITIVE_TOPOLOGY TopologyToDX11Topology(PRIMITIVE_TOPOLOGY Topology) -{ - switch( Topology ) - { - case PRIMITIVE_TOPOLOGY_UNDEFINED: return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - case PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - case PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - case PRIMITIVE_TOPOLOGY_POINT_LIST: return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; - case PRIMITIVE_TOPOLOGY_LINE_LIST: return D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - default: UNEXPECTED("Unsupported primitive topology" ); return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - } -} - -DXGI_FORMAT TypeToDXGI_Format(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized); - -DXGI_FORMAT TexFormatToDXGI_Format(TEXTURE_FORMAT TexFormat, Uint32 BindFlags = 0); +D3D11_PRIMITIVE_TOPOLOGY TopologyToD3D11Topology(PRIMITIVE_TOPOLOGY Topology); inline D3D11_USAGE UsageToD3D11Usage(USAGE Usage) { @@ -110,38 +96,21 @@ inline UINT MiscTextureFlagsToD3D11Flags(Uint32 Flags) } D3D11_FILTER FilterTypeToD3D11Filter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter); - -inline D3D11_TEXTURE_ADDRESS_MODE TexAddressModeToD3D11AddressMode(TEXTURE_ADDRESS_MODE Mode) -{ - switch(Mode) - { - case TEXTURE_ADDRESS_UNKNOWN: UNEXPECTED("Texture address mode is not specified" ); return D3D11_TEXTURE_ADDRESS_CLAMP; - case TEXTURE_ADDRESS_WRAP: return D3D11_TEXTURE_ADDRESS_WRAP; - case TEXTURE_ADDRESS_MIRROR: return D3D11_TEXTURE_ADDRESS_MIRROR; - case TEXTURE_ADDRESS_CLAMP: return D3D11_TEXTURE_ADDRESS_CLAMP; - case TEXTURE_ADDRESS_BORDER: return D3D11_TEXTURE_ADDRESS_BORDER; - case TEXTURE_ADDRESS_MIRROR_ONCE: return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; - default: UNEXPECTED("Unknown texture address mode" ); return D3D11_TEXTURE_ADDRESS_CLAMP; - } -} - -inline D3D11_COMPARISON_FUNC ComparisonFuncToD3D11ComparisonFunc(COMPARISON_FUNCTION Func) -{ - switch(Func) - { - case COMPARISON_FUNC_UNKNOW: UNEXPECTED("Comparison function is not specified" ); return D3D11_COMPARISON_ALWAYS; - case COMPARISON_FUNC_NEVER: return D3D11_COMPARISON_NEVER; - case COMPARISON_FUNC_LESS: return D3D11_COMPARISON_LESS; - case COMPARISON_FUNC_EQUAL: return D3D11_COMPARISON_EQUAL; - case COMPARISON_FUNC_LESS_EQUAL: return D3D11_COMPARISON_LESS_EQUAL; - case COMPARISON_FUNC_GREATER: return D3D11_COMPARISON_GREATER; - case COMPARISON_FUNC_NOT_EQUAL: return D3D11_COMPARISON_NOT_EQUAL; - case COMPARISON_FUNC_GREATER_EQUAL: return D3D11_COMPARISON_GREATER_EQUAL; - case COMPARISON_FUNC_ALWAYS: return D3D11_COMPARISON_ALWAYS; - default: UNEXPECTED("Unknown comparison function" ); return D3D11_COMPARISON_ALWAYS; - } -} - -D3D11_STENCIL_OP StencilOpToD3D11StencilOp( STENCIL_OP ); +D3D11_TEXTURE_ADDRESS_MODE TexAddressModeToD3D11AddressMode(TEXTURE_ADDRESS_MODE Mode); + +D3D11_COMPARISON_FUNC ComparisonFuncToD3D11ComparisonFunc(COMPARISON_FUNCTION Func); +void DepthStencilStateDesc_To_D3D11_DEPTH_STENCIL_DESC(const DepthStencilStateDesc &DepthStencilDesc, D3D11_DEPTH_STENCIL_DESC &d3d11DSSDesc); +void RasterizerStateDesc_To_D3D11_RASTERIZER_DESC(const RasterizerStateDesc &RasterizerDesc, D3D11_RASTERIZER_DESC &d3d11RSDesc); +void BlendStateDesc_To_D3D11_BLEND_DESC(const BlendStateDesc &BSDesc, D3D11_BLEND_DESC &D3D11BSDesc); +void LayoutElements_To_D3D11_INPUT_ELEMENT_DESCs(const std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement> > &LayoutElements, + std::vector<D3D11_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D11_INPUT_ELEMENT_DESC> > &D3D11InputElements); + +void TextureViewDesc_to_D3D11_SRV_DESC(const TextureViewDesc& TexViewDesc, D3D11_SHADER_RESOURCE_VIEW_DESC &D3D11SRVDesc, Uint32 SampleCount); +void TextureViewDesc_to_D3D11_RTV_DESC(const TextureViewDesc& TexViewDesc, D3D11_RENDER_TARGET_VIEW_DESC &D3D11RTVDesc, Uint32 SampleCount); +void TextureViewDesc_to_D3D11_DSV_DESC(const TextureViewDesc& TexViewDesc, D3D11_DEPTH_STENCIL_VIEW_DESC &D3D11DSVDesc, Uint32 SampleCount); +void TextureViewDesc_to_D3D11_UAV_DESC(const TextureViewDesc& TexViewDesc, D3D11_UNORDERED_ACCESS_VIEW_DESC &D3D11UAVDesc); + +void BufferViewDesc_to_D3D11_SRV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& SRVDesc, D3D11_SHADER_RESOURCE_VIEW_DESC &D3D11SRVDesc); +void BufferViewDesc_to_D3D11_UAV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& UAVDesc, D3D11_UNORDERED_ACCESS_VIEW_DESC &D3D11UAVDesc); } diff --git a/Graphics/GraphicsEngineD3D11/include/D3D11TypeDefinitions.h b/Graphics/GraphicsEngineD3D11/include/D3D11TypeDefinitions.h new file mode 100644 index 00000000..bd35a89e --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/D3D11TypeDefinitions.h @@ -0,0 +1,181 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definitions of D3D11 types + +// Filters +#define D3D_FILTER_MIN_MAG_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MIN_MAG_POINT_MIP_LINEAR D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MIN_POINT_MAG_MIP_LINEAR D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR +#define D3D_FILTER_MIN_LINEAR_MAG_MIP_POINT D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT +#define D3D_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MIN_MAG_LINEAR_MIP_POINT D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MIN_MAG_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_LINEAR +#define D3D_FILTER_ANISOTROPIC D3D11_FILTER_ANISOTROPIC + +#define D3D_FILTER_COMPARISON_MIN_MAG_MIP_POINT D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR +#define D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR +#define D3D_FILTER_COMPARISON_ANISOTROPIC D3D11_FILTER_COMPARISON_ANISOTROPIC + +// Minimum/maximum filtering is not supported in d3d11 +#define D3D_FILTER_MINIMUM_MIN_MAG_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_ANISOTROPIC D3D11_FILTER_MIN_MAG_MIP_POINT + +#define D3D_FILTER_MAXIMUM_MIN_MAG_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR D3D11_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_ANISOTROPIC D3D11_FILTER_MIN_MAG_MIP_POINT + + +// Comparison functions +#define D3D_COMPARISON_FUNC_NEVER D3D11_COMPARISON_NEVER +#define D3D_COMPARISON_FUNC_LESS D3D11_COMPARISON_LESS +#define D3D_COMPARISON_FUNC_EQUAL D3D11_COMPARISON_EQUAL +#define D3D_COMPARISON_FUNC_LESS_EQUAL D3D11_COMPARISON_LESS_EQUAL +#define D3D_COMPARISON_FUNC_GREATER D3D11_COMPARISON_GREATER +#define D3D_COMPARISON_FUNC_NOT_EQUAL D3D11_COMPARISON_NOT_EQUAL +#define D3D_COMPARISON_FUNC_GREATER_EQUAL D3D11_COMPARISON_GREATER_EQUAL +#define D3D_COMPARISON_FUNC_ALWAYS D3D11_COMPARISON_ALWAYS + +// Stencil operations +#define D3D_STENCIL_OP_KEEP D3D11_STENCIL_OP_KEEP +#define D3D_STENCIL_OP_ZERO D3D11_STENCIL_OP_ZERO +#define D3D_STENCIL_OP_REPLACE D3D11_STENCIL_OP_REPLACE +#define D3D_STENCIL_OP_INCR_SAT D3D11_STENCIL_OP_INCR_SAT +#define D3D_STENCIL_OP_DECR_SAT D3D11_STENCIL_OP_DECR_SAT +#define D3D_STENCIL_OP_INVERT D3D11_STENCIL_OP_INVERT +#define D3D_STENCIL_OP_INCR D3D11_STENCIL_OP_INCR +#define D3D_STENCIL_OP_DECR D3D11_STENCIL_OP_DECR + +// Depth write masks +#define D3D_DEPTH_WRITE_MASK_ALL D3D11_DEPTH_WRITE_MASK_ALL +#define D3D_DEPTH_WRITE_MASK_ZERO D3D11_DEPTH_WRITE_MASK_ZERO + +// Cull modes +#define D3D_CULL_MODE_NONE D3D11_CULL_NONE +#define D3D_CULL_MODE_FRONT D3D11_CULL_FRONT +#define D3D_CULL_MODE_BACK D3D11_CULL_BACK + +// Fill modes +#define D3D_FILL_MODE_WIREFRAME D3D11_FILL_WIREFRAME +#define D3D_FILL_MODE_SOLID D3D11_FILL_SOLID + +// Blend sources +#define D3D_BLEND_ZERO D3D11_BLEND_ZERO +#define D3D_BLEND_ONE D3D11_BLEND_ONE +#define D3D_BLEND_SRC_COLOR D3D11_BLEND_SRC_COLOR +#define D3D_BLEND_INV_SRC_COLOR D3D11_BLEND_INV_SRC_COLOR +#define D3D_BLEND_SRC_ALPHA D3D11_BLEND_SRC_ALPHA +#define D3D_BLEND_INV_SRC_ALPHA D3D11_BLEND_INV_SRC_ALPHA +#define D3D_BLEND_DEST_ALPHA D3D11_BLEND_DEST_ALPHA +#define D3D_BLEND_INV_DEST_ALPHA D3D11_BLEND_INV_DEST_ALPHA +#define D3D_BLEND_DEST_COLOR D3D11_BLEND_DEST_COLOR +#define D3D_BLEND_INV_DEST_COLOR D3D11_BLEND_INV_DEST_COLOR +#define D3D_BLEND_SRC_ALPHA_SAT D3D11_BLEND_SRC_ALPHA_SAT +#define D3D_BLEND_BLEND_FACTOR D3D11_BLEND_BLEND_FACTOR +#define D3D_BLEND_INV_BLEND_FACTOR D3D11_BLEND_INV_BLEND_FACTOR +#define D3D_BLEND_SRC1_COLOR D3D11_BLEND_SRC1_COLOR +#define D3D_BLEND_INV_SRC1_COLOR D3D11_BLEND_INV_SRC1_COLOR +#define D3D_BLEND_SRC1_ALPHA D3D11_BLEND_SRC1_ALPHA +#define D3D_BLEND_INV_SRC1_ALPHA D3D11_BLEND_INV_SRC1_ALPHA + +// Blend operations +#define D3D_BLEND_OP_ADD D3D11_BLEND_OP_ADD +#define D3D_BLEND_OP_SUBTRACT D3D11_BLEND_OP_SUBTRACT +#define D3D_BLEND_OP_REV_SUBTRACT D3D11_BLEND_OP_REV_SUBTRACT +#define D3D_BLEND_OP_MIN D3D11_BLEND_OP_MIN +#define D3D_BLEND_OP_MAX D3D11_BLEND_OP_MAX + +// Color masks +#define D3D_COLOR_WRITE_ENABLE_RED D3D11_COLOR_WRITE_ENABLE_RED +#define D3D_COLOR_WRITE_ENABLE_GREEN D3D11_COLOR_WRITE_ENABLE_GREEN +#define D3D_COLOR_WRITE_ENABLE_BLUE D3D11_COLOR_WRITE_ENABLE_BLUE +#define D3D_COLOR_WRITE_ENABLE_ALPHA D3D11_COLOR_WRITE_ENABLE_ALPHA + +// Input classification +#define D3D_INPUT_CLASSIFICATION_PER_VERTEX_DATA D3D11_INPUT_PER_VERTEX_DATA +#define D3D_INPUT_CLASSIFICATION_PER_INSTANCE_DATA D3D11_INPUT_PER_INSTANCE_DATA + +// Texture address modes +#define D3D_TEXTURE_ADDRESS_WRAP D3D11_TEXTURE_ADDRESS_WRAP +#define D3D_TEXTURE_ADDRESS_MIRROR D3D11_TEXTURE_ADDRESS_MIRROR +#define D3D_TEXTURE_ADDRESS_CLAMP D3D11_TEXTURE_ADDRESS_CLAMP +#define D3D_TEXTURE_ADDRESS_BORDER D3D11_TEXTURE_ADDRESS_BORDER +#define D3D_TEXTURE_ADDRESS_MIRROR_ONCE D3D11_TEXTURE_ADDRESS_MIRROR_ONCE + + +// SRV Dimensions +// d3d11.h aliases D3D11_SRV_DIMENSION as D3D_SRV_DIMENSION, so there is no +// need to redefine this enum + +// RTV Dimensions +#define D3D_RTV_DIMENSION_UNKNOWN D3D11_RTV_DIMENSION_UNKNOWN +#define D3D_RTV_DIMENSION_BUFFER D3D11_RTV_DIMENSION_BUFFER +#define D3D_RTV_DIMENSION_TEXTURE1D D3D11_RTV_DIMENSION_TEXTURE1D +#define D3D_RTV_DIMENSION_TEXTURE1DARRAY D3D11_RTV_DIMENSION_TEXTURE1DARRAY +#define D3D_RTV_DIMENSION_TEXTURE2D D3D11_RTV_DIMENSION_TEXTURE2D +#define D3D_RTV_DIMENSION_TEXTURE2DARRAY D3D11_RTV_DIMENSION_TEXTURE2DARRAY +#define D3D_RTV_DIMENSION_TEXTURE2DMS D3D11_RTV_DIMENSION_TEXTURE2DMS +#define D3D_RTV_DIMENSION_TEXTURE2DMSARRAY D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY +#define D3D_RTV_DIMENSION_TEXTURE3D D3D11_RTV_DIMENSION_TEXTURE3D + + +// DSV Dimensions +#define D3D_DSV_DIMENSION_UNKNOWN D3D11_DSV_DIMENSION_UNKNOWN +#define D3D_DSV_DIMENSION_TEXTURE1D D3D11_DSV_DIMENSION_TEXTURE1D +#define D3D_DSV_DIMENSION_TEXTURE1DARRAY D3D11_DSV_DIMENSION_TEXTURE1DARRAY +#define D3D_DSV_DIMENSION_TEXTURE2D D3D11_DSV_DIMENSION_TEXTURE2D +#define D3D_DSV_DIMENSION_TEXTURE2DARRAY D3D11_DSV_DIMENSION_TEXTURE2DARRAY +#define D3D_DSV_DIMENSION_TEXTURE2DMS D3D11_DSV_DIMENSION_TEXTURE2DMS +#define D3D_DSV_DIMENSION_TEXTURE2DMSARRAY D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY + +// UAV Dimensions +#define D3D_UAV_DIMENSION_UNKNOWN D3D11_UAV_DIMENSION_UNKNOWN +#define D3D_UAV_DIMENSION_BUFFER D3D11_UAV_DIMENSION_BUFFER +#define D3D_UAV_DIMENSION_TEXTURE1D D3D11_UAV_DIMENSION_TEXTURE1D +#define D3D_UAV_DIMENSION_TEXTURE1DARRAY D3D11_UAV_DIMENSION_TEXTURE1DARRAY +#define D3D_UAV_DIMENSION_TEXTURE2D D3D11_UAV_DIMENSION_TEXTURE2D +#define D3D_UAV_DIMENSION_TEXTURE2DARRAY D3D11_UAV_DIMENSION_TEXTURE2DARRAY +#define D3D_UAV_DIMENSION_TEXTURE3D D3D11_UAV_DIMENSION_TEXTURE3D diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h index a4102db6..e3b2c498 100644 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,42 +43,44 @@ class DeviceContextD3D11Impl : public DeviceContextBase<IDeviceContextD3D11> public: typedef DeviceContextBase<IDeviceContextD3D11> TDeviceContextBase; - DeviceContextD3D11Impl(IRenderDevice *pDevice, ID3D11DeviceContext *pd3d11DeviceContext); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + DeviceContextD3D11Impl(IMemoryAllocator &Allocator, IRenderDevice *pDevice, ID3D11DeviceContext *pd3d11DeviceContext, const struct EngineD3D11Attribs &EngineAttribs, bool bIsDeferred); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual void SetShaders( IShader **ppShaders, Uint32 NumShadersToSet )override; + virtual void SetPipelineState(IPipelineState *pPipelineState)override final; - virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override; + virtual void TransitionShaderResources(IPipelineState *pPipelineState, IShaderResourceBinding *pShaderResourceBinding)override final; - virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override; - virtual void ClearState()override; + virtual void CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags)override final; - virtual void SetVertexDescription( IVertexDescription *pVertexDesc )override; + virtual void SetStencilRef(Uint32 StencilRef)override final; - virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override; + virtual void SetBlendFactors(const float* pBlendFactors = nullptr)override final; - virtual void SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef = 0 )override; + virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override final; + virtual void ClearState()override final; - virtual void SetRasterizerState( IRasterizerState *pRS )override; + virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override final; - virtual void SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask )override; + virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )override final; - virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )override; + virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )override final; - virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )override; + virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil )override final; - virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil )override; + virtual void Draw( DrawAttribs &DrawAttribs )override final; - virtual void Draw( DrawAttribs &DrawAttribs )override; + virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )override final; - virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )override; + virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil)override final; - virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil)override; + virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA )override final; - virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA )override; - - virtual void Flush()override; + virtual void Flush()override final; + void FinishCommandList(class ICommandList **ppCommandList)override final; + + virtual void ExecuteCommandList(class ICommandList *pCommandList)override final; + ID3D11DeviceContext* GetD3D11DeviceContext(){ return m_pd3d11DeviceContext; } void RebindRenderTargets(); @@ -93,166 +95,187 @@ public: private: - /// Goes through the list of bound shaders and binds all required - /// d3d11 resource to the d3d11 device context, for each shader. - void SetD3DShadersAndResources(); - - /// Binds d3d11 index buffer to the d3d11 device context. - void SetD3DIndexBuffer(VALUE_TYPE IndexType); - - /// Binds d3d11 vertex buffers to the d3d11 device context. - void SetD3DVertexBuffers(); + /// Commits d3d11 index buffer to the d3d11 device context. + void CommitD3D11IndexBuffer(VALUE_TYPE IndexType); - /// Binds d3d11 constant buffers to the d3d11 device context - void SetD3DConstantBuffers ( class ShaderD3D11Impl *pShader ); - /// Binds d3d11 shader resource views to the d3d11 device context - void SetD3DSRVs ( class ShaderD3D11Impl *pShader ); - /// Binds d3d11 unordered access views to the d3d11 device context - void SetD3DUAVs ( class ShaderD3D11Impl *pShader ); - /// Binds d3d11 samplers to the d3d11 device context - void SetD3DSamplers ( class ShaderD3D11Impl *pShader ); + /// Commits d3d11 vertex buffers to the d3d11 device context. + void CommitD3D11VertexBuffers(class PipelineStateD3D11Impl *pPipelineStateD3D11); /// Helper template function used to facilitate resource unbinding - template<typename TBoundResourceType, - typename TD3D11ResourceType, - typename TSetD3D11View> - void UnbindResourceView(std::vector<TBoundResourceType> BoundResourcesArr[], - std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], + template<typename TD3D11ResourceViewType, + typename TSetD3D11View, + size_t NumSlots> + void UnbindResourceView(TD3D11ResourceViewType CommittedD3D11ViewsArr[][NumSlots], + ID3D11Resource* CommittedD3D11ResourcesArr[][NumSlots], + Uint8 NumCommittedResourcesArr[], IDeviceObject *pResToUnbind, + ID3D11Resource *pd3d11ResToUndind, TSetD3D11View SetD3D11ViewMethods[]); /// Unbinds a texture from the shader resource view slots. /// \note The function only unbinds the texture from d3d11 device /// context. All shader bindings are retained. - void UnbindTextureFromInput(ITexture *pTexture); + void UnbindTextureFromInput(TextureBaseD3D11 *pTexture, ID3D11Resource *pd3d11Resource); /// Unbinds a buffer from the input (shader resource views slots, index /// and vertex buffer slots). /// \note The function only unbinds the buffer from d3d11 device /// context. All shader bindings are retained. - void UnbindBufferFromInput(IBuffer *pBuffer); + void UnbindBufferFromInput(BufferD3D11Impl *pBuffer, ID3D11Resource *pd3d11Buffer); /// Unbinds a resource from the UAV slots. /// \note The function only unbinds the texture from the device /// context. All shader bindings are retained. - void UnbindResourceFromUAV(IDeviceObject *pResource); + void UnbindResourceFromUAV(IDeviceObject *pResource, ID3D11Resource *pd3d11Resource); /// Unbinds a texture from render target slots. - void UnbindTextureFromRenderTarget(IDeviceObject *pResource); + void UnbindTextureFromRenderTarget(TextureBaseD3D11 *pResource); /// Unbinds a texture from depth-stencil. - void UnbindTextureFromDepthStencil(IDeviceObject *pResource); - - /// Helper template function that facilitates shader binding - /// \tparam TD3D11ShaderType - Type of D3D11 shader being set (ID3D11PixelShader, ID3D11VertexShader, etc.) - /// \tparam TBindShaderMethdType - Type of the d3d11 device context mehtod that sets the shader - /// (ID3D11DeviceContext::VSSetShader, ID3D11DeviceContext::PSSetShader, etc.) - /// \param BoundShaderFlags - Flags indicating which shader stages are currently active - /// \param NewShaders - Array of pointers to the new shaders to be bound - /// \param ShaderType - Type of the shader being bound - /// \param BindShaderMethod - Pointer to the d3d11 device context mehtod that sets the shader - /// (ID3D11DeviceContext::VSSetShader, ID3D11DeviceContext::PSSetShader, etc.) - template<typename TD3D11ShaderType, typename TBindShaderMethdType> - void SetD3D11ShaderHelper(Uint32 BoundShaderFlags, - ShaderD3D11Impl* NewShaders[], - SHADER_TYPE ShaderType, - TBindShaderMethdType BindShaderMethod); - - Diligent::CComPtr<ID3D11DeviceContext> m_pd3d11DeviceContext; ///< D3D11 device context - DrawAttribs m_LastDrawAttribs; - - /// An array of D3D11 constant buffers currently bound to the D3D11 device context, - /// for each shader type. - std::vector<ID3D11Buffer*> m_BoundD3D11CBs [NumShaderTypes]; - /// An array of D3D11 shader resource views currently bound to the D3D11 device context, - /// for each shader type. - std::vector<ID3D11ShaderResourceView*> m_BoundD3D11SRVs [NumShaderTypes]; - /// An array of D3D11 samplers currently bound to the D3D11 device context, - /// for each shader type. - std::vector<ID3D11SamplerState*> m_BoundD3D11Samplers[NumShaderTypes]; - /// An array of D3D11 UAVs currently bound to the D3D11 device context, - /// for each shader type. - std::vector<ID3D11UnorderedAccessView*> m_BoundD3D11UAVs [NumShaderTypes]; - - /// An array of strong references to resources associated with the bound - /// constant buffers, for each shader type. - std::vector<ShaderD3D11Impl::BoundCB> m_BoundCBs[NumShaderTypes]; - /// An array of strong references to resources associated with the - /// bound SRV, for each shader type. - std::vector<ShaderD3D11Impl::BoundSRV> m_BoundSRVs[NumShaderTypes]; - /// An array of strong references to resources associated with the - /// bound samplers, for each shader type. - std::vector<ShaderD3D11Impl::BoundSampler> m_BoundSamplers[NumShaderTypes]; - /// An array of strong references to resources associated with the - /// bound UAVs, for each shader type. - std::vector<ShaderD3D11Impl::BoundUAV> m_BoundUAVs[NumShaderTypes]; - - /// An array of D3D11 vertex buffers currently bound to the D3D device context - std::vector< Diligent::CComPtr<ID3D11Buffer> > m_BoundD3D11VertexBuffers; - /// An array of strides of currently bound vertex buffers - std::vector< UINT > m_BoundD3D11VBStrides; - /// An array of offsets of currently bound vertex buffers - std::vector< UINT > m_BoundD3D11VBOffsets; - - /// Strong reference to the D3D11 buffer currently bound as index buffer + void UnbindTextureFromDepthStencil(TextureBaseD3D11 *pTexD3D11); + + template<bool TransitionResources, + bool CommitResources> + void TransitionAndCommitShaderResources(IPipelineState *pPSO, IShaderResourceBinding *pShaderResourceBinding); + + void ClearStateCache(); + + CComPtr<ID3D11DeviceContext> m_pd3d11DeviceContext; ///< D3D11 device context + + /// An array of D3D11 constant buffers committed to the D3D11 device context, + /// for each shader type. Device context addref's all bound resources, so we do + /// not need to keep strong references + ID3D11Buffer* m_CommittedD3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + + /// An array of D3D11 shader resource views committed to the D3D11 device context, + /// for each shader type. Device context addref's all bound resources, so we do + /// not need to keep strong references + ID3D11ShaderResourceView* m_CommittedD3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + + /// An array of D3D11 samplers committed to the D3D11 device context, + /// for each shader type. Device context addref's all bound resources, so we do + /// not need to keep strong references + ID3D11SamplerState* m_CommittedD3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + + /// An array of D3D11 UAVs committed to the D3D11 device context, + /// for each shader type. Device context addref's all bound resources, so we do + /// not need to keep strong references + ID3D11UnorderedAccessView* m_CommittedD3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT]; + + /// An array of D3D11 resources commited as SRV to the D3D11 device context, + /// for each shader type. Device context addref's all bound resources, so we do + /// not need to keep strong references + ID3D11Resource* m_CommittedD3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + + /// An array of D3D11 resources commited as UAV to the D3D11 device context, + /// for each shader type. Device context addref's all bound resources, so we do + /// not need to keep strong references + ID3D11Resource* m_CommittedD3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT]; + + Uint8 m_NumCommittedCBs[NumShaderTypes] = {}; + Uint8 m_NumCommittedSRVs[NumShaderTypes]= {}; + Uint8 m_NumCommittedSamplers[NumShaderTypes]= {}; + Uint8 m_NumCommittedUAVs[NumShaderTypes]= {}; + + /// An array of D3D11 vertex buffers committed to the D3D device context + /// There is no need to keep strong references because D3D11 device context + /// already does. Buffers cannot be destroyed while bound to the context. + /// We only mirror all bindings. + ID3D11Buffer* m_CommittedD3D11VertexBuffers[MaxBufferSlots] = {}; + /// An array of strides of committed vertex buffers + UINT m_CommittedD3D11VBStrides[MaxBufferSlots]; + /// An array of offsets of committed vertex buffers + UINT m_CommittedD3D11VBOffsets[MaxBufferSlots]; + /// Number committed vertex buffers + UINT m_NumCommittedD3D11VBs; + /// Flag indicating if currently committed D3D11 vertex buffers are up to date + bool m_bCommittedD3D11VBsUpToDate = false; + + /// D3D11 input layout committed to the device object. + /// Device context keeps the layout alive, so there is no need + /// to keep strong reference + ID3D11InputLayout *m_CommittedD3D11InputLayout = nullptr; + + /// Strong reference to the D3D11 buffer committed as index buffer /// to the D3D device context - Diligent::CComPtr<ID3D11Buffer> m_BoundD3D11IndexBuffer; - /// Format of currently bound D3D11 index buffer - DXGI_FORMAT m_BoundD3D11IndexFmt; - /// Offset of currently bound D3D11 index buffer - Uint32 m_BoundD3D11IndexDataStartOffset; + CComPtr<ID3D11Buffer> m_CommittedD3D11IndexBuffer; + /// Format of the committed D3D11 index buffer + VALUE_TYPE m_CommittedIBFormat; + /// Offset of the committed D3D11 index buffer + Uint32 m_CommittedD3D11IndexDataStartOffset; + /// Flag indicating if currently committed D3D11 index buffer is up to date + bool m_bCommittedD3D11IBUpToDate = false; - /// Strong references to the currently bound D3D11 shaders - Diligent::CComPtr<ID3D11DeviceChild> m_BoundD3DShaders[NumShaderTypes]; + D3D11_PRIMITIVE_TOPOLOGY m_CommittedD3D11PrimTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + PRIMITIVE_TOPOLOGY m_CommittedPrimitiveTopology = PRIMITIVE_TOPOLOGY_UNDEFINED; -#ifdef VERIFY_CONTEXT_BINDINGS - /// Helper template function used to facilitate context verification - template<UINT MaxResources, typename TD3D11ResourceType, typename TGetD3D11ResourcesType> - void dbgVerifyContextResources(std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], - TGetD3D11ResourcesType GetD3D11ResMethods[], - const Char *ResourceName, - SHADER_TYPE ShaderType); + /// Strong references to the committed D3D11 shaders + CComPtr<ID3D11DeviceChild> m_CommittedD3DShaders[NumShaderTypes]; - /// Debug function that verifies that SRVs cached in m_BoundD3D11SRVs - /// array comply with resources actually bound to the D3D11 device context - void dbgVerifyContextSRVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + Uint32 m_DebugFlags; - /// Debug function that verifies that UAVs cached in m_BoundD3D11UAVs - /// array comply with resources actually bound to the D3D11 device context - void dbgVerifyContextUAVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + FixedBlockMemoryAllocator m_CmdListAllocator; - /// Debug function that verifies that samplers cached in m_BoundD3D11Samplers - /// array comply with resources actually bound to the D3D11 device context - void dbgVerifyContextSamplers(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); +#ifdef VERIFY_CONTEXT_BINDINGS + /// Verifies that bound render target formats are consistent with the PSO + void dbgVerifyRenderTargetFormats(); - /// Debug function that verifies that constant buffers cached in m_BoundD3D11CBs - /// array comply with buffers actually bound to the D3D11 device context - void dbgVerifyContextCBs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + /// Helper template function used to facilitate context verification + template<UINT MaxResources, typename TD3D11ResourceType, typename TGetD3D11ResourcesType> + void dbgVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources], + Uint8 NumCommittedResourcesArr[], + TGetD3D11ResourcesType GetD3D11ResMethods[], + const Char *ResourceName, + SHADER_TYPE ShaderType); + + /// Helper template function used to facilitate validation of SRV and UAV consistency with D3D11 resources + template<UINT MaxResources, typename TD3D11ViewType> + void dbgVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources], + ID3D11Resource* CommittedD3D11ResourcesArr[][MaxResources], + Uint8 NumCommittedResourcesArr[], + const Char *ResourceName, + SHADER_TYPE ShaderType); + + /// Debug function that verifies that SRVs cached in m_CommittedD3D11SRVs + /// array comply with resources actually committed to the D3D11 device context + void dbgVerifyCommittedSRVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + + /// Debug function that verifies that UAVs cached in m_CommittedD3D11UAVs + /// array comply with resources actually committed to the D3D11 device context + void dbgVerifyCommittedUAVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + + /// Debug function that verifies that samplers cached in m_CommittedD3D11Samplers + /// array comply with resources actually committed to the D3D11 device context + void dbgVerifyCommittedSamplers(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); + + /// Debug function that verifies that constant buffers cached in m_CommittedD3D11CBs + /// array comply with buffers actually committed to the D3D11 device context + void dbgVerifyCommittedCBs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN); /// Debug function that verifies that the index buffer cached in - /// m_BoundD3D11IndexBuffer is the buffer actually bound to the D3D11 + /// m_CommittedD3D11IndexBuffer is the buffer actually committed to the D3D11 /// device context - void dbgVerifyIndexBuffer(); + void dbgVerifyCommittedIndexBuffer(); /// Debug function that verifies that vertex buffers cached in - /// m_BoundD3D11VertexBuffers are the buffers actually bound to the D3D11 + /// m_CommittedD3D11VertexBuffers are the buffers actually committed to the D3D11 /// device context - void dbgVerifyVertexBuffers(); + void dbgVerifyCommittedVertexBuffers(); /// Debug function that verifies that shaders cached in - /// m_BoundD3DShaders are the shaders actually bound to the D3D11 + /// m_CommittedD3DShaders are the shaders actually committed to the D3D11 /// device context - void dbgVerifyShaders(); + void dbgVerifyCommittedShaders(); #else - - #define dbgVerifyContextSRVs(...) - #define dbgVerifyContextUAVs(...) - #define dbgVerifyContextSamplers(...) - #define dbgVerifyContextCBs(...) - #define dbgVerifyIndexBuffer(...) - #define dbgVerifyVertexBuffers(...) - #define dbgVerifyShaders(...) + #define dbgVerifyRenderTargetFormats(...) + #define dbgVerifyCommittedSRVs(...) + #define dbgVerifyCommittedUAVs(...) + #define dbgVerifyCommittedSamplers(...) + #define dbgVerifyCommittedCBs(...) + #define dbgVerifyCommittedIndexBuffer(...) + #define dbgVerifyCommittedVertexBuffers(...) + #define dbgVerifyCommittedShaders(...) #endif }; diff --git a/Graphics/GraphicsEngineD3D11/include/EngineD3D11Defines.h b/Graphics/GraphicsEngineD3D11/include/EngineD3D11Defines.h new file mode 100644 index 00000000..9a5cee9b --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/EngineD3D11Defines.h @@ -0,0 +1,28 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#ifdef _DEBUG +# define VERIFY_SHADER_BINDINGS +#endif diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h new file mode 100644 index 00000000..cb89e92a --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h @@ -0,0 +1,100 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::PipelineStateD3D11Impl class + +#include "PipelineStateD3D11.h" +#include "RenderDeviceD3D11.h" +#include "PipelineStateBase.h" +#include "ShaderD3D11Impl.h" +#include "AdaptiveFixedBlockAllocator.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::IPipelineStateD3D11 interface +class PipelineStateD3D11Impl : public PipelineStateBase<IPipelineStateD3D11, IRenderDeviceD3D11, FixedBlockMemoryAllocator> +{ +public: + typedef PipelineStateBase<IPipelineStateD3D11, IRenderDeviceD3D11, FixedBlockMemoryAllocator> TPipelineStateBase; + + PipelineStateD3D11Impl(FixedBlockMemoryAllocator &PSOAllocator, class RenderDeviceD3D11Impl *pDeviceD3D11, const PipelineStateDesc& PipelineDesc); + ~PipelineStateD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + + /// Implementation of the IPipelineStateD3D11::GetD3D11BlendState() method. + virtual ID3D11BlendState* GetD3D11BlendState()override final; + + /// Implementation of the IPipelineStateD3D11::GetD3D11RasterizerState() method. + virtual ID3D11RasterizerState* GetD3D11RasterizerState()override final; + + /// Implementation of the IPipelineStateD3D11::GetD3D11DepthStencilState() method. + virtual ID3D11DepthStencilState* GetD3D11DepthStencilState()override final; + + virtual ID3D11InputLayout* GetD3D11InputLayout()override final; + + virtual ID3D11VertexShader* GetD3D11VertexShader()override final; + virtual ID3D11PixelShader* GetD3D11PixelShader()override final; + virtual ID3D11GeometryShader* GetD3D11GeometryShader()override final; + virtual ID3D11DomainShader* GetD3D11DomainShader()override final; + virtual ID3D11HullShader* GetD3D11HullShader()override final; + virtual ID3D11ComputeShader* GetD3D11ComputeShader()override final; + + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override final; + + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override final; + + class ShaderResourceBindingD3D11Impl* GetDefaultResourceBinding(){return m_pDefaultShaderResBinding.get();} + IMemoryAllocator &GetResourceCacheDataAllocator(Uint32 Ind) + { + VERIFY_EXPR(Ind < _countof(m_ResourceCacheDataAllocators)); + return m_ResourceCacheDataAllocators[Ind]; + } + IMemoryAllocator &GetShaderResLayoutDataAllocators(Uint32 Ind) + { + VERIFY_EXPR(Ind < _countof(m_ShaderResLayoutDataAllocators)); + return m_ShaderResLayoutDataAllocators[Ind]; + } + IShaderVariable* GetDummyShaderVariable(){return &m_DummyShaderVar;} + +private: + CComPtr<ID3D11BlendState> m_pd3d11BlendState; + CComPtr<ID3D11RasterizerState> m_pd3d11RasterizerState; + CComPtr<ID3D11DepthStencilState> m_pd3d11DepthStencilState; + CComPtr<ID3D11InputLayout> m_pd3d11InputLayout; + + AdaptiveFixedBlockAllocator m_ShaderResLayoutDataAllocators[5]; // Use separate allocator for every shader stage + AdaptiveFixedBlockAllocator m_ResourceCacheDataAllocators[5]; // Use separate allocator for every shader stage + + // Do not use strong reference to avoid cyclic references + std::unique_ptr<class ShaderResourceBindingD3D11Impl, STDDeleter<ShaderResourceBindingD3D11Impl, FixedBlockMemoryAllocator> > m_pDefaultShaderResBinding; + + DummyShaderVariable m_DummyShaderVar; ///< Dummy shader variable +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h index 0f374b5c..0d4547e5 100644 --- a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,47 +27,41 @@ /// Declaration of Diligent::RenderDeviceD3D11Impl class #include "RenderDeviceD3D11.h" -#include "RenderDeviceBase.h" +#include "RenderDeviceD3DBase.h" #include "DeviceContextD3D11.h" +#include "EngineD3D11Attribs.h" -/// Namespace for the Direct3D11 implementation of the graphics engine namespace Diligent { /// Implementation of the Diligent::IRenderDeviceD3D11 interface -class RenderDeviceD3D11Impl : public RenderDeviceBase<IRenderDeviceD3D11> +class RenderDeviceD3D11Impl : public RenderDeviceD3DBase<IRenderDeviceD3D11> { public: - typedef RenderDeviceBase<IRenderDeviceD3D11> TRenderDeviceBase; + typedef RenderDeviceD3DBase<IRenderDeviceD3D11> TRenderDeviceBase; - RenderDeviceD3D11Impl( ID3D11Device *pd3d11Device ); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + RenderDeviceD3D11Impl( IMemoryAllocator &RawMemAllocator, const EngineD3D11Attribs& EngineAttribs, ID3D11Device *pd3d11Device, Uint32 NumDeferredContexts ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer); + virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer)override final; - virtual void CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc ); + virtual void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader)override final; - virtual void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader); - - virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture); + virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture)override final; - virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler); - - virtual void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState ); + virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler)override final; - virtual void CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState ); + virtual void CreatePipelineState( const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState )override final; - virtual void CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState ); + ID3D11Device* GetD3D11Device()override final{return m_pd3d11Device;} - ID3D11Device* GetD3D11Device(){return m_pd3d11Device;} - private: virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat ); - void FlagSupportedTexFormats(); + EngineD3D11Attribs m_EngineAttribs; /// D3D11 device - Diligent::CComPtr<ID3D11Device> m_pd3d11Device; + CComPtr<ID3D11Device> m_pd3d11Device; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.h index f48d645e..3fd8b138 100644 --- a/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,23 +33,23 @@ namespace Diligent { +class FixedBlockMemoryAllocator; /// Implementation of the Diligent::ISamplerD3D11 interface -class SamplerD3D11Impl : public SamplerBase<ISamplerD3D11, IRenderDeviceD3D11> +class SamplerD3D11Impl : public SamplerBase<ISamplerD3D11, IRenderDeviceD3D11, FixedBlockMemoryAllocator> { public: - typedef SamplerBase<ISamplerD3D11, IRenderDeviceD3D11> TSamplerBase; + typedef SamplerBase<ISamplerD3D11, IRenderDeviceD3D11, FixedBlockMemoryAllocator> TSamplerBase; - SamplerD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const SamplerDesc& SamplerDesc); + SamplerD3D11Impl(FixedBlockMemoryAllocator &SamplerObjAllocator, class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const SamplerDesc& SamplerDesc); ~SamplerD3D11Impl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) final; - virtual ID3D11SamplerState* GetD3D11SamplerState(){ return m_pd3dSampler; } + virtual ID3D11SamplerState* GetD3D11SamplerState()override final{ return m_pd3dSampler; } private: - friend class ShaderD3D11Impl; /// D3D11 sampler - Diligent::CComPtr<ID3D11SamplerState> m_pd3dSampler; + CComPtr<ID3D11SamplerState> m_pd3dSampler; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h index 4066947e..44ecad0f 100644 --- a/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,203 +29,55 @@ #include "ShaderD3D11.h" #include "RenderDeviceD3D11.h" #include "ShaderBase.h" - -#ifdef _DEBUG -# define VERIFY_SHADER_BINDINGS -#endif +#include "ShaderD3DBase.h" +#include "ShaderResourceLayoutD3D11.h" +#include "ShaderResourceCacheD3D11.h" +#include "EngineD3D11Defines.h" +#include "ShaderResourcesD3D11.h" namespace Diligent { +class FixedBlockMemoryAllocator; class ResourceMapping; /// Implementation of the Diligent::IShaderD3D11 interface -class ShaderD3D11Impl : public ShaderBase<IShaderD3D11, IRenderDeviceD3D11> +class ShaderD3D11Impl : public ShaderBase<IShaderD3D11, IRenderDeviceD3D11, FixedBlockMemoryAllocator>, public ShaderD3DBase { public: - typedef ShaderBase<IShaderD3D11, IRenderDeviceD3D11> TShaderBase; + typedef ShaderBase<IShaderD3D11, IRenderDeviceD3D11, FixedBlockMemoryAllocator> TShaderBase; - ShaderD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const ShaderCreationAttribs &ShaderCreationAttribs); + ShaderD3D11Impl(FixedBlockMemoryAllocator &ShaderObjAllocator, class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const ShaderCreationAttribs &CreationAttribs); ~ShaderD3D11Impl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override; + virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override final; - virtual IShaderVariable* GetShaderVariable( const Char* Name )override; - - /// Describes resources associated with the bound constant buffer - struct BoundCB - { - /// Strong reference to the buffer - Diligent::RefCntAutoPtr<IDeviceObject> pBuff; - /// Strong referene to the D3D11 buffer interface - Diligent::CComPtr<ID3D11Buffer> pd3d11Buff; - }; - - /// Describes resources associated with the bound sampler - struct BoundSampler - { - /// Strong reference to the sampler - Diligent::RefCntAutoPtr<IDeviceObject> pSampler; - /// Strong referene to the D3D11 sampler state interface - Diligent::CComPtr<ID3D11SamplerState> pd3d11Sampler; - }; - - /// Describes resources associated with the bound SRV - struct BoundSRV - { - /// Strong reference to the resource bound as SRV - Diligent::RefCntAutoPtr<IDeviceObject> pResource; - /// Strong reference to the resource view - Diligent::RefCntAutoPtr<IDeviceObject> pView; - /// Strong referene to the D3D11 SRV interface - Diligent::CComPtr<ID3D11ShaderResourceView> pd3d11View; - }; - - /// Describes resources associated with the bound UAV - struct BoundUAV - { - /// Strong reference to the resource bound as UAV - Diligent::RefCntAutoPtr<IDeviceObject> pResource; - /// Strong reference to the resource view - Diligent::RefCntAutoPtr<IDeviceObject> pView; - /// Strong referene to the D3D11 UAV interface - Diligent::CComPtr<ID3D11UnorderedAccessView> pd3d11View; - }; - - /// Returns a const reference to the zero-slot-based array of bound constant buffers - const std::vector< BoundCB >& GetBoundCBs() { return m_BoundCBs; } - /// Returns a const reference to the zero-slot-based array of bound samplers - const std::vector< BoundSampler >& GetBoundSamplers() { return m_BoundSamplers; } - /// Returns a const reference to the zero-slot-based array bound SRVs - const std::vector< BoundSRV >& GetBoundSRVs() { return m_BoundSRVs; } - /// Returns a const reference to the zero-slot-based array bound UAVs - const std::vector< BoundUAV >& GetBoundUAVs() { return m_BoundUAVs; } - - virtual ID3D11DeviceChild* GetD3D11Shader()override{ return m_pShader; } - -#ifdef VERIFY_SHADER_BINDINGS - void dbgVerifyBindings(); -#endif + virtual IShaderVariable* GetShaderVariable( const Char* Name )override final; -private: - void BindConstantBuffers( IResourceMapping* pResourceMapping, Uint32 Flags ); - - void BindSRVsAndSamplers( IResourceMapping* pResourceMapping, Uint32 Flags ); - - void BindUAVs( IResourceMapping* pResourceMapping, Uint32 Flags ); - - static const String m_SamplerSuffix; - - struct D3D11ShaderVarBase : ShaderVariableBase - { - D3D11ShaderVarBase( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint ) : - ShaderVariableBase( pShader ), - Name(_Name), - BindPoint(_BindPoint) - {} - - String Name; - UINT BindPoint; - const String& GetName(){ return Name; } - }; - - struct ConstBuffBindInfo : D3D11ShaderVarBase - { - ConstBuffBindInfo( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint ) : - D3D11ShaderVarBase( pShader, _Name, _BindPoint ) - {} - virtual void Set(IDeviceObject *pObject)override; - bool IsBound(); - }; - - struct TexAndSamplerBindInfo : D3D11ShaderVarBase - { - TexAndSamplerBindInfo( ShaderD3D11Impl *pShader, const String& _TexName, UINT _TexBindPoint, const String &_SamplerName, UINT _SamplerBindPoint ) : - D3D11ShaderVarBase( pShader, _TexName, _TexBindPoint), - SamplerName(_SamplerName), - SamplerBindPoint(_SamplerBindPoint) - {} - - String SamplerName; - UINT SamplerBindPoint; - virtual void Set(IDeviceObject *pObject)override; - bool IsBound(); - }; - - struct UAVBindInfoBase : public D3D11ShaderVarBase - { - UAVBindInfoBase( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint, D3D_SHADER_INPUT_TYPE _Type ) : - D3D11ShaderVarBase( pShader, _Name, _BindPoint), - Type(_Type) - {} - - bool IsBound(); - D3D_SHADER_INPUT_TYPE Type; - }; - - struct TexUAVBindInfo : UAVBindInfoBase - { - TexUAVBindInfo( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint, D3D_SHADER_INPUT_TYPE _Type ) : - UAVBindInfoBase( pShader, _Name, _BindPoint, _Type ) - {} - - virtual void Set(IDeviceObject *pObject)override; - }; - - struct BuffUAVBindInfo : UAVBindInfoBase - { - BuffUAVBindInfo( ShaderD3D11Impl *pShader, const String& _Name, UINT _BindPoint, D3D_SHADER_INPUT_TYPE _Type ) : - UAVBindInfoBase( pShader, _Name, _BindPoint, _Type ) - {} - - virtual void Set(IDeviceObject *pObject)override; - }; - - struct BuffSRVBindInfo : D3D11ShaderVarBase - { - BuffSRVBindInfo( ShaderD3D11Impl *pShader, const String &_Name, UINT _BindPoint ) : - D3D11ShaderVarBase( pShader, _Name, _BindPoint) - {} - - virtual void Set(IDeviceObject *pObject)override; - bool IsBound(); - }; - - void LoadShaderResources(); - - friend class VertexDescD3D11Impl; - friend class DeviceContextD3D11Impl; - /// D3D11 shader - Diligent::CComPtr<ID3D11DeviceChild> m_pShader; - Diligent::CComPtr<ID3DBlob> m_pShaderByteCode;// Only stored for Vertex Shader + virtual ID3D11DeviceChild* GetD3D11Shader()override final{ return m_pShader; } - std::vector<ConstBuffBindInfo> m_ConstanBuffers; - std::vector<TexAndSamplerBindInfo> m_TexAndSamplers; - std::vector<TexUAVBindInfo> m_TexUAVs; - std::vector<BuffUAVBindInfo> m_BuffUAVs; - std::vector<BuffSRVBindInfo> m_BuffSRVs; + ID3DBlob* GetBytecode(){return m_pShaderByteCode;} + ShaderResourceLayoutD3D11& GetStaticResourceLayout(){return m_StaticResLayout;} + const std::shared_ptr<const ShaderResourcesD3D11>& GetResources(){return m_pShaderResources;} + Uint32 GetShaderTypeIndex(){return m_ShaderTypeIndex;} - /// An array of bound constant buffers. The data always starts at - /// slot 0 even when no resource is actually bound to the slot. - std::vector<BoundCB> m_BoundCBs; - - /// An array of bound samplers. The data always starts at - /// slot 0 even when no sampler is actually bound to the slot. - std::vector<BoundSampler> m_BoundSamplers; +private: - /// An array of bound SRVs. The data always starts at - /// slot 0 even when no resource is actually bound to the slot. - std::vector<BoundSRV> m_BoundSRVs; + DummyShaderVariable m_DummyShaderVar; ///< Dummy shader variable - /// An array of bound UAVs. The data always starts at - /// slot 0 even when no resource is actually bound to the slot. - std::vector<BoundUAV> m_BoundUAVs; + /// D3D11 shader + CComPtr<ID3D11DeviceChild> m_pShader; + + // ShaderResources class instance must be referenced through the shared pointer, because + // it is referenced by ShaderResourceLayoutD3D11 class instances + std::shared_ptr<const ShaderResourcesD3D11> m_pShaderResources; - /// Hash map to look up shader variables by name. - std::unordered_map<Diligent::HashMapStringKey, IShaderVariable* > m_VariableHash; + ShaderResourceCacheD3D11 m_StaticResCache; + ShaderResourceLayoutD3D11 m_StaticResLayout; + Uint32 m_ShaderTypeIndex; // VS == 0, PS == 1, GS == 2, HS == 3, DS == 4, CS == 5 }; } diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h new file mode 100644 index 00000000..8afcab2c --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h @@ -0,0 +1,81 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceBindingD3D11Impl class + +#include "ShaderResourceBindingD3D11.h" +#include "RenderDeviceD3D11.h" +#include "ShaderResourceBindingBase.h" +#include "ShaderResourceCacheD3D11.h" +#include "ShaderResourceLayoutD3D11.h" +#include "STDAllocator.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::IShaderResourceBindingD3D11 interface +class ShaderResourceBindingD3D11Impl : public ShaderResourceBindingBase<IShaderResourceBindingD3D11, FixedBlockMemoryAllocator> +{ +public: + typedef ShaderResourceBindingBase<IShaderResourceBindingD3D11, FixedBlockMemoryAllocator> TBase; + ShaderResourceBindingD3D11Impl(FixedBlockMemoryAllocator &SRBAllocator, class PipelineStateD3D11Impl *pPSO, bool IsInternal); + ~ShaderResourceBindingD3D11Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags)override final; + + virtual IShaderVariable *GetVariable(SHADER_TYPE ShaderType, const char *Name)override final; + + ShaderResourceCacheD3D11 &GetResourceCache(Uint32 Ind){VERIFY_EXPR(Ind < m_NumActiveShaders); return m_pBoundResourceCaches[Ind];} + ShaderResourceLayoutD3D11 &GetResourceLayout(Uint32 Ind){VERIFY_EXPR(Ind < m_NumActiveShaders); return m_pResourceLayouts[Ind];} + + void BindStaticShaderResources(); + inline bool IsStaticResourcesBound(){return m_bIsStaticResourcesBound;} + + Uint32 GetNumActiveShaders() + { + return static_cast<Uint32>(m_NumActiveShaders); + } + + Int32 GetActiveShaderTypeIndex(Uint32 s){return m_ShaderTypeIndex[s];} + +private: + // The caches are indexed by the shader order in the PSO, not shader index + ShaderResourceCacheD3D11* m_pBoundResourceCaches = nullptr; + ShaderResourceLayoutD3D11* m_pResourceLayouts = nullptr; + + Int8 m_ShaderTypeIndex[6] = {}; + + // Resource layout index in m_ResourceLayouts[] array for every shader stage + Int8 m_ResourceLayoutIndex[6]; + Uint8 m_NumActiveShaders = 0; + + bool m_bIsStaticResourcesBound = false; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.h new file mode 100644 index 00000000..0964ba9c --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.h @@ -0,0 +1,316 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceCacheD3D11 class + +#include "TextureBaseD3D11.h" +#include "BufferD3D11Impl.h" +#include "SamplerD3D11Impl.h" + +namespace Diligent +{ + +/// The class implements a cache that holds resources bound to a specific shader stage +// All resources are stored in the continuous memory using the following layout: +// +// | CachedCB | ID3D11Buffer* || CachedResource | ID3D11ShaderResourceView* || CachedSampler | ID3D11SamplerState* || CachedResource | ID3D11UnorderedAccessView*|| +// |---------------------------------------------------||--------------------------|---------------------------||------------------------------|-----------------------------||-------------------------|---------------------------|| +// | 0 | 1 | ... | CBCount-1 | 0 | 1 | ...| CBCount-1 || 0 | 1 | ... | SRVCount-1 | 0 | 1 | ... | SRVCount-1 || 0 | 1 | ... | SamplerCount-1 | 0 | 1 | ...| SamplerCount-1 ||0 | 1 | ... | UAVCount-1 | 0 | 1 | ... | UAVCount-1 || +// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// +// +class ShaderResourceCacheD3D11 +{ +public: + ShaderResourceCacheD3D11() + {} + + ~ShaderResourceCacheD3D11(); + + + ShaderResourceCacheD3D11(const ShaderResourceCacheD3D11&) = delete; + ShaderResourceCacheD3D11& operator = (const ShaderResourceCacheD3D11&) = delete; + ShaderResourceCacheD3D11(ShaderResourceCacheD3D11&&) = delete; + ShaderResourceCacheD3D11& operator = (ShaderResourceCacheD3D11&&) = delete; + + /// Describes resources associated with the cached constant buffer + struct CachedCB + { + /// Strong reference to the buffer + RefCntAutoPtr<BufferD3D11Impl> pBuff; + __forceinline void Set(RefCntAutoPtr<BufferD3D11Impl> &&_pBuff) + { + pBuff = std::move(_pBuff); + } + }; + + /// Describes resources associated with the cached sampler + struct CachedSampler + { + /// Strong reference to the sampler + RefCntAutoPtr<class SamplerD3D11Impl> pSampler; + __forceinline void Set(SamplerD3D11Impl *pSam) + { + pSampler = pSam; + } + }; + + /// Describes resources associated with the cached SRV or UAV + struct CachedResource + { + /// Wee keep strong reference to the view instead of the reference + /// to the texture or buffer because this is more efficient from + /// performance point of view: this avoids one pair of + /// AddStrongRef()/ReleaseStrongRef(). The view holds strong reference + /// to the texture or the buffer, so it makes no difference. + RefCntAutoPtr<IDeviceObject> pView; + TextureBaseD3D11* pTexture; + BufferD3D11Impl* pBuffer; + // There is no need to keep strong reference to D3D11 resource as + // it is already kept by either pTexture or pBuffer + ID3D11Resource *pd3d11Resource; + CachedResource() : pTexture(nullptr), pBuffer(nullptr), pd3d11Resource(nullptr) + {} + + __forceinline void Set(RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView) + { + pBuffer = nullptr; + // Avoid unnecessary virtual function calls + pTexture = pTexView ? ValidatedCast<TextureBaseD3D11>(pTexView->TextureViewD3D11Impl::GetTexture()) : nullptr; + pView.Attach(pTexView.Detach()); + pd3d11Resource = pTexture ? pTexture->TextureBaseD3D11::GetD3D11Texture() : nullptr; + } + + __forceinline void Set(RefCntAutoPtr<BufferViewD3D11Impl>&& pBufView) + { + pTexture = nullptr; + // Avoid unnecessary virtual function calls + pBuffer = pBufView ? ValidatedCast<BufferD3D11Impl>(pBufView->BufferViewD3D11Impl::GetBuffer()) : nullptr; + pView.Attach(pBufView.Detach()); + pd3d11Resource = pBuffer ? pBuffer->BufferD3D11Impl::GetD3D11Buffer() : nullptr; + } + }; + + void Initialize(Int32 CBCount, Int32 SRVCount, Int32 SamplerCount, Int32 UAVCount, class IMemoryAllocator &MemAllocator); + void Destroy(class IMemoryAllocator &MemAllocator); + + + __forceinline void SetCB(Uint32 Slot, RefCntAutoPtr<BufferD3D11Impl> &&pBuffD3D11Impl) + { + auto *pd3d11Buff = pBuffD3D11Impl ? pBuffD3D11Impl->BufferD3D11Impl::GetD3D11Buffer() : nullptr; + SetD3D11ResourceInternal<CachedCB>(Slot, GetCBCount(), &ShaderResourceCacheD3D11::GetCBArrays, std::move(pBuffD3D11Impl), pd3d11Buff); + } + + __forceinline void SetTexSRV(Uint32 Slot, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView) + { + auto pd3d11SRV = pTexView ? static_cast<ID3D11ShaderResourceView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr; + SetD3D11ResourceInternal<CachedResource>(Slot, GetSRVCount(), &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pTexView), pd3d11SRV); + } + + __forceinline void SetBufSRV(Uint32 Slot, RefCntAutoPtr<BufferViewD3D11Impl> &&pBuffView) + { + auto pd3d11SRV = pBuffView ? static_cast<ID3D11ShaderResourceView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr; + SetD3D11ResourceInternal<CachedResource>(Slot, GetSRVCount(), &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pBuffView), pd3d11SRV); + } + + __forceinline void SetTexUAV(Uint32 Slot, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView) + { + auto pd3d11UAV = pTexView ? static_cast<ID3D11UnorderedAccessView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr; + SetD3D11ResourceInternal<CachedResource>(Slot, GetUAVCount(), &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pTexView), pd3d11UAV); + } + + __forceinline void SetBufUAV(Uint32 Slot, RefCntAutoPtr<BufferViewD3D11Impl> &&pBuffView) + { + auto pd3d11UAV = pBuffView ? static_cast<ID3D11UnorderedAccessView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr; + SetD3D11ResourceInternal<CachedResource>(Slot, GetUAVCount(), &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pBuffView), pd3d11UAV); + } + + __forceinline void SetSampler(Uint32 Slot, SamplerD3D11Impl *pSampler) + { + auto *pd3d11Sampler = pSampler ? pSampler->SamplerD3D11Impl::GetD3D11SamplerState() : nullptr; + SetD3D11ResourceInternal<CachedSampler>(Slot, GetSamplerCount(), &ShaderResourceCacheD3D11::GetSamplerArrays, pSampler, pd3d11Sampler); + } + + __forceinline bool IsCBBound(Uint32 Slot)const + { + CachedCB* CBs = nullptr; + ID3D11Buffer** d3d11CBs = nullptr; + const_cast<ShaderResourceCacheD3D11*>(this)->GetCBArrays(CBs, d3d11CBs); + if( Slot < GetCBCount() && d3d11CBs[Slot] != nullptr ) + { + VERIFY(CBs[Slot].pBuff != nullptr, "No relevant buffer resource") + return true; + } + return false; + } + + __forceinline bool IsSRVBound(Uint32 Slot, bool dbgIsTextureView)const + { + CachedResource* SRVResources = nullptr; + ID3D11ShaderResourceView** d3d11SRVs = nullptr; + const_cast<ShaderResourceCacheD3D11*>(this)->GetSRVArrays(SRVResources, d3d11SRVs); + if( Slot < GetSRVCount() && d3d11SRVs[Slot] != nullptr ) + { + VERIFY( ( dbgIsTextureView && SRVResources[Slot].pTexture != nullptr) || + (!dbgIsTextureView && SRVResources[Slot].pBuffer != nullptr), "No relevant resource"); + return true; + } + return false; + } + + __forceinline bool IsUAVBound(Uint32 Slot, bool dbgIsTextureView)const + { + CachedResource* UAVResources = nullptr; + ID3D11UnorderedAccessView** d3d11UAVs = nullptr; + const_cast<ShaderResourceCacheD3D11*>(this)->GetUAVArrays(UAVResources, d3d11UAVs); + if( Slot < GetUAVCount() && d3d11UAVs[Slot] != nullptr ) + { + VERIFY( ( dbgIsTextureView && UAVResources[Slot].pTexture != nullptr) || + (!dbgIsTextureView && UAVResources[Slot].pBuffer != nullptr), "No relevant resource"); + return true; + } + return false; + } + + __forceinline bool IsSamplerBound(Uint32 Slot)const + { + CachedSampler* Samplers = nullptr; + ID3D11SamplerState** d3d11Samplers = nullptr; + const_cast<ShaderResourceCacheD3D11*>(this)->GetSamplerArrays(Samplers, d3d11Samplers); + if( Slot < GetSamplerCount() && d3d11Samplers[Slot] != nullptr ) + { + VERIFY(Samplers[Slot].pSampler != nullptr, "No relevant sampler") + return true; + } + return false; + } + + void dbgVerifyCacheConsistency(); + + + static __forceinline Uint32 PackResourceCounts(Uint32 CBCount, Uint32 SRVCount, Uint32 SamplerCount, Uint32 UAVCount) + { + VERIFY_EXPR(CBCount <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ); + VERIFY_EXPR(SRVCount <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); + VERIFY_EXPR(SamplerCount <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT); + VERIFY_EXPR(UAVCount <= D3D11_PS_CS_UAV_REGISTER_COUNT); + return (CBCount & 0xFF) | ((SRVCount & 0xFF) << 8) | ((SamplerCount & 0xFF) << 16) | ((UAVCount & 0xFF) << 24); + } + + static __forceinline Uint32 UnpackCBCount (Uint32 PackedCounts) {return (PackedCounts >> 0) & 0xFF; } + static __forceinline Uint32 UnpackSRVCount (Uint32 PackedCounts) {return (PackedCounts >> 8) & 0xFF; } + static __forceinline Uint32 UnpackSamplerCount (Uint32 PackedCounts) {return (PackedCounts >> 16) & 0xFF; } + static __forceinline Uint32 UnpackUAVCount (Uint32 PackedCounts) {return (PackedCounts >> 24) & 0xFF; } + + __forceinline Uint32 GetCBCount() const{ return UnpackCBCount (m_ResourceCounts);} + __forceinline Uint32 GetSRVCount() const{ return UnpackSRVCount (m_ResourceCounts);} + __forceinline Uint32 GetSamplerCount()const{ return UnpackSamplerCount(m_ResourceCounts);} + __forceinline Uint32 GetUAVCount() const{ return UnpackUAVCount (m_ResourceCounts);} + __forceinline Uint32 GetPackedCounts()const{ return m_ResourceCounts;} + + __forceinline void GetResourceArrays(CachedCB* &CBs, ID3D11Buffer** &pd3d11CBs, + CachedResource* &SRVResources, ID3D11ShaderResourceView** &d3d11SRVs, + CachedSampler* &Samplers, ID3D11SamplerState** &pd3d11Samplers, + CachedResource* &UAVResources, ID3D11UnorderedAccessView** &pd3d11UAVs) + { + VERIFY_EXPR(IsInitialized()); + CBs = reinterpret_cast<CachedCB*>( m_pResourceData ); + pd3d11CBs = reinterpret_cast<ID3D11Buffer**>( CBs + GetCBCount() ); + SRVResources = reinterpret_cast<CachedResource*>( pd3d11CBs + GetCBCount() ); + d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView**>( SRVResources + GetSRVCount() ); + Samplers = reinterpret_cast<CachedSampler*>( d3d11SRVs + GetSRVCount() ); + pd3d11Samplers = reinterpret_cast<ID3D11SamplerState**>( Samplers + GetSamplerCount() ); + UAVResources = reinterpret_cast<CachedResource*>( pd3d11Samplers + GetSamplerCount() ); + pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView**>( UAVResources + GetUAVCount() ); + } + + __forceinline void GetCBArrays(CachedCB* &CBs, ID3D11Buffer** &pd3d11CBs) + { + CBs = reinterpret_cast<CachedCB*>( m_pResourceData ); + pd3d11CBs = reinterpret_cast<ID3D11Buffer**>( CBs + GetCBCount() ); + } + + __forceinline void GetSRVArrays(CachedResource* &SRVResources, ID3D11ShaderResourceView** &d3d11SRVs) + { + SRVResources = reinterpret_cast<CachedResource*>( m_pResourceData + (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * GetCBCount() ); + d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView**>( SRVResources + GetSRVCount() ); + } + + __forceinline void GetSamplerArrays(CachedSampler* &Samplers, ID3D11SamplerState** &pd3d11Samplers) + { + Samplers = reinterpret_cast<CachedSampler*>( m_pResourceData + + (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * GetCBCount() + + (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)) * GetSRVCount() ); + pd3d11Samplers = reinterpret_cast<ID3D11SamplerState**>( Samplers + GetSamplerCount() ); + } + + __forceinline void GetUAVArrays(CachedResource* &UAVResources, ID3D11UnorderedAccessView** &pd3d11UAVs) + { + UAVResources = reinterpret_cast<CachedResource*>( m_pResourceData + + (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * GetCBCount() + + (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)) * GetSRVCount() + + (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)) * GetSamplerCount() ); + pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView**>( UAVResources + GetUAVCount() ); + } + + __forceinline bool IsInitialized()const{return m_ResourceCounts != InvalidResourceCounts;} + +private: + + template<typename TCachedResourceType, typename TGetResourceArraysFunc, typename TSrcResourceType, typename TD3D11ResourceType> + __forceinline void SetD3D11ResourceInternal(Uint32 Slot, Uint32 Size, + TGetResourceArraysFunc GetArrays, + TSrcResourceType &&pResource, + TD3D11ResourceType *pd3d11Resource) + { + VERIFY(Slot < Size, "Resource cache is not big enough" ) + VERIFY(pResource != nullptr && pd3d11Resource != nullptr || pResource == nullptr && pd3d11Resource == nullptr, + "Resource and D3D11 resource must be set/unset atomically") + TCachedResourceType* Resources; + TD3D11ResourceType** d3d11ResArr; + (this->*GetArrays)(Resources, d3d11ResArr); + Resources[Slot].Set(std::forward<TSrcResourceType>(pResource)); + d3d11ResArr[Slot] = pd3d11Resource; + } + + static const Uint32 InvalidResourceCounts = 0xFFFFFFFF; + // Resource limits in D3D11: + // Max CB count: 14 + // Max SRV count: 128 + // Max Sampler count: 16 + // Max UAV count: 8 + Uint32 m_ResourceCounts = InvalidResourceCounts; // CBCount == (m_ResourceCounts >> 0) & 0xFF + // SRVCount == (m_ResourceCounts >> 8) & 0xFF + // SamplerCount == (m_ResourceCounts >> 16) & 0xFF + // UAVCount == (m_ResourceCounts >> 24) & 0xFF + Uint8 *m_pResourceData = nullptr; + +#ifdef _DEBUG + IMemoryAllocator *m_pdbgMemoryAllocator = nullptr; +#endif +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h new file mode 100644 index 00000000..f55b4dce --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h @@ -0,0 +1,300 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceLayoutD3D11 class + +// Set this define to 1 to use unordered_map to store shader variables. +// Note that sizeof(m_VariableHash)==128 (release mode, MS compiler, x64). +#define USE_VARIABLE_HASH_MAP 0 + + +#include "ShaderResources.h" +#include "ShaderBase.h" +#include "ShaderResourceCacheD3D11.h" +#include "EngineD3D11Defines.h" +#include "STDAllocator.h" +#include "ShaderVariableD3DBase.h" +#include "ShaderResourcesD3D11.h" + +namespace Diligent +{ + +class IMemoryAllocator; + +/// Diligent::ShaderResourceLayoutD3D11 class +class ShaderResourceLayoutD3D11 +{ +public: + ShaderResourceLayoutD3D11(IObject &Owner, IMemoryAllocator& ResLayoutDataAllocator); + ~ShaderResourceLayoutD3D11(); + + ShaderResourceLayoutD3D11(const ShaderResourceLayoutD3D11&) = delete; + ShaderResourceLayoutD3D11& operator = (const ShaderResourceLayoutD3D11&) = delete; + ShaderResourceLayoutD3D11(ShaderResourceLayoutD3D11&&) = default; + ShaderResourceLayoutD3D11& operator = (ShaderResourceLayoutD3D11&&) = delete; + + void Initialize(const std::shared_ptr<const ShaderResourcesD3D11>& pSrcResources, + const SHADER_VARIABLE_TYPE *VarTypes, + Uint32 NumVarTypes, + ShaderResourceCacheD3D11& ResourceCache, + IMemoryAllocator& ResCacheDataAllocator, + IMemoryAllocator& ResLayoutDataAllocator); + + void CopyResources(ShaderResourceCacheD3D11 &DstCache); + + using ShaderVariableD3D11Base = ShaderVariableD3DBase<ShaderResourceLayoutD3D11>; + + struct ConstBuffBindInfo : ShaderVariableD3D11Base + { + ConstBuffBindInfo( const D3DShaderResourceAttribs& ResourceAttribs, + ShaderResourceLayoutD3D11 &ParentResLayout ) : + ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs) + {} + // Non-virtual function + __forceinline void BindResource(IDeviceObject *pObject, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout); + virtual void Set(IDeviceObject *pObject)override final{ BindResource(pObject, 0, nullptr); } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + for(Uint32 elem=0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement+elem, nullptr); + } + + __forceinline bool IsBound(Uint32 ArrayIndex); + }; + + struct TexAndSamplerBindInfo : ShaderVariableD3D11Base + { + TexAndSamplerBindInfo( const D3DShaderResourceAttribs& _TextureAttribs, + const D3DShaderResourceAttribs& _SamplerAttribs, + ShaderResourceLayoutD3D11 &ParentResLayout) : + ShaderVariableD3D11Base(ParentResLayout, _TextureAttribs), + SamplerAttribs(_SamplerAttribs) + {} + + // Non-virtual function + __forceinline void BindResource(IDeviceObject *pObject, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout); + virtual void Set(IDeviceObject *pObject)override final{ BindResource(pObject, 0, nullptr); } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + for(Uint32 elem=0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement+elem, nullptr); + } + + __forceinline bool IsBound(Uint32 ArrayIndex); + + static const D3DShaderResourceAttribs InvalidSamplerAttribs; + + const D3DShaderResourceAttribs &SamplerAttribs; + }; + + struct TexUAVBindInfo : ShaderVariableD3D11Base + { + TexUAVBindInfo( const D3DShaderResourceAttribs& ResourceAttribs, + ShaderResourceLayoutD3D11 &ParentResLayout ) : + ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs) + {} + + // Provide non-virtual function + __forceinline void BindResource(IDeviceObject *pObject, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout); + virtual void Set(IDeviceObject *pObject)override final{ BindResource(pObject, 0, nullptr); } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + for(Uint32 elem=0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement+elem, nullptr); + } + + __forceinline bool IsBound(Uint32 ArrayIndex); + }; + + struct BuffUAVBindInfo : ShaderVariableD3D11Base + { + BuffUAVBindInfo( const D3DShaderResourceAttribs& ResourceAttribs, + ShaderResourceLayoutD3D11 &ParentResLayout ) : + ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs) + {} + + // Non-virtual function + __forceinline void BindResource(IDeviceObject *pObject, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout); + virtual void Set(IDeviceObject *pObject)override final{ BindResource(pObject, 0, nullptr); } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + for(Uint32 elem=0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement+elem, nullptr); + } + + __forceinline bool IsBound(Uint32 ArrayIndex); + }; + + struct BuffSRVBindInfo : ShaderVariableD3D11Base + { + BuffSRVBindInfo( const D3DShaderResourceAttribs& ResourceAttribs, + ShaderResourceLayoutD3D11 &ParentResLayout ) : + ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs) + {} + + // Non-virtual function + __forceinline void BindResource(IDeviceObject *pObject, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout); + virtual void Set(IDeviceObject *pObject)override final{ BindResource(pObject, 0, nullptr); } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + for(Uint32 elem=0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement+elem, nullptr); + } + + __forceinline bool IsBound(Uint32 ArrayIndex); + }; + + // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive + // while Layout is alive + void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D11 &dbgResourceCache ); + +#ifdef VERIFY_SHADER_BINDINGS + void dbgVerifyBindings()const; +#endif + + IShaderVariable* GetShaderVariable( const Char* Name ); + __forceinline SHADER_TYPE GetShaderType()const{return m_pResources->GetShaderType();} + + IObject& GetOwner(){return m_Owner;} +private: + + void InitVariablesHashMap(); + + const Char* GetShaderName()const; + + // No need to use shared pointer, as the resource cache is either part of the same + // ShaderD3D11Impl object, or ShaderResourceBindingD3D11Impl object + ShaderResourceCacheD3D11 *m_pResourceCache = nullptr; + + std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer; + + // Offsets in bytes + Uint16 m_TexAndSamplersOffset = 0; + Uint16 m_TexUAVsOffset = 0; + Uint16 m_BuffUAVsOffset = 0; + Uint16 m_BuffSRVsOffset = 0; + + Uint8 m_NumCBs = 0; // Max == 14 + Uint8 m_NumTexSRVs = 0; // Max == 128 + Uint8 m_NumTexUAVs = 0; // Max == 8 + Uint8 m_NumBufUAVs = 0; // Max == 8 + Uint8 m_NumBufSRVs = 0; // Max == 128 + + ConstBuffBindInfo& GetCB(Uint32 cb) + { + VERIFY_EXPR(cb<m_NumCBs); + return reinterpret_cast<ConstBuffBindInfo*>(m_ResourceBuffer.get())[cb]; + } + const ConstBuffBindInfo& GetCB(Uint32 cb)const + { + VERIFY_EXPR(cb<m_NumCBs); + return reinterpret_cast<ConstBuffBindInfo*>(m_ResourceBuffer.get())[cb]; + } + + TexAndSamplerBindInfo& GetTexSRV(Uint32 t) + { + VERIFY_EXPR(t<m_NumTexSRVs); + return reinterpret_cast<TexAndSamplerBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_TexAndSamplersOffset )[t]; + } + const TexAndSamplerBindInfo& GetTexSRV(Uint32 t)const + { + VERIFY_EXPR(t<m_NumTexSRVs); + return reinterpret_cast<TexAndSamplerBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_TexAndSamplersOffset )[t]; + } + + TexUAVBindInfo& GetTexUAV(Uint32 u) + { + VERIFY_EXPR(u < m_NumTexUAVs); + return reinterpret_cast<TexUAVBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_TexUAVsOffset)[u]; + } + const TexUAVBindInfo& GetTexUAV(Uint32 u)const + { + VERIFY_EXPR(u < m_NumTexUAVs); + return reinterpret_cast<TexUAVBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_TexUAVsOffset)[u]; + } + + BuffUAVBindInfo& GetBufUAV(Uint32 u) + { + VERIFY_EXPR(u < m_NumBufUAVs); + return reinterpret_cast<BuffUAVBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_BuffUAVsOffset)[u]; + } + const BuffUAVBindInfo& GetBufUAV(Uint32 u)const + { + VERIFY_EXPR(u < m_NumBufUAVs); + return reinterpret_cast<BuffUAVBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_BuffUAVsOffset)[u]; + } + + BuffSRVBindInfo& GetBufSRV(Uint32 s) + { + VERIFY_EXPR(s < m_NumBufSRVs); + return reinterpret_cast<BuffSRVBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_BuffSRVsOffset)[s]; + } + const BuffSRVBindInfo& GetBufSRV(Uint32 s)const + { + VERIFY_EXPR(s < m_NumBufSRVs); + return reinterpret_cast<BuffSRVBindInfo*>( reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + m_BuffSRVsOffset)[s]; + } + + template<typename THandleCB, + typename THandleTexSRV, + typename THandleTexUAV, + typename THandleBufSRV, + typename THandleBufUAV> + void HandleResources(THandleCB HandleCB, + THandleTexSRV HandleTexSRV, + THandleTexUAV HandleTexUAV, + THandleBufSRV HandleBufSRV, + THandleBufUAV HandleBufUAV) + { + for (Uint32 cb = 0; cb < m_NumCBs; ++cb) + HandleCB(GetCB(cb)); + for (Uint32 t = 0; t < m_NumTexSRVs; ++t) + HandleTexSRV(GetTexSRV(t)); + for (Uint32 u = 0; u < m_NumTexUAVs; ++u) + HandleTexUAV(GetTexUAV(u)); + for (Uint32 s = 0; s < m_NumBufSRVs; ++s) + HandleBufSRV(GetBufSRV(s)); + for (Uint32 u = 0; u < m_NumBufUAVs; ++u) + HandleBufUAV(GetBufUAV(u)); + } + +#if USE_VARIABLE_HASH_MAP + // Hash map to look up shader variables by name. + // Note that sizeof(m_VariableHash)==128 (release mode, MS compiler, x64). + typedef std::pair<HashMapStringKey, IShaderVariable*> VariableHashData; + std::unordered_map<HashMapStringKey, IShaderVariable*, std::hash<HashMapStringKey>, std::equal_to<HashMapStringKey>, STDAllocatorRawMem<VariableHashData> > m_VariableHash; +#endif + + std::shared_ptr<const ShaderResourcesD3D11> m_pResources; + IObject &m_Owner; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourcesD3D11.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourcesD3D11.h new file mode 100644 index 00000000..772de5b9 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourcesD3D11.h @@ -0,0 +1,139 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourcesD3D11 class + + +// ShaderResourcesD3D11 are created by ShaderD3D11Impl instances. They are then referenced by ShaderResourceLayoutD3D11 objects, which are in turn +// created by instances of ShaderResourceBindingsD3D11Impl (and ShaderD3D11Impl too) +// +// _________________ +// | | +// | ShaderD3D11Impl | +// |_________________| +// | +// |shared_ptr +// ________V_____________ _____________________________________________________________________ +// | | unique_ptr | | | | | | | +// | ShaderResourcesD3D11 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | +// |______________________| |________|___________|___________|___________|___________|____________| +// A A A A A A A +// | \ \ \ \ \ | +// |shared_ptr Ref Ref Ref Ref Ref | +// ________|__________________ ____\_________\__________\__________\___________\_______ | +// | | unique_ptr | | | | | | | +// | ShaderResourceLayoutD3D11 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | | +// |___________________________| |________|___________|___________|___________|___________| | +// | Ref +// |______________________________________________| +// +// +// One ShaderResources instance can be referenced by multiple objects +// +// +// ____<m_pResourceLayouts>___ ________________________________ +// | | | | +// ----| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl | +// | |___________________________| |________________________________| +// | +// | +// _________________ ______________________ | ____<m_pResourceLayouts>___ ________________________________ +// | | shared_ptr | | shared_ptr| | | | | +// | ShaderD3D11Impl |--------------->| ShaderResourcesD3D11 |<---------------| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl | +// |_________________| |______________________| | |___________________________| |________________________________| +// | A | +// V | | +// ____<m_StaticResLayout>____ | | ____<m_pResourceLayouts>___ ________________________________ +// | | shared_ptr | | | | | | +// | ShaderResourceLayoutD3D11 |------------------- ----| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl | +// |___________________________| |___________________________| |________________________________| +// +// + + +#include "ShaderResources.h" + +namespace Diligent +{ + +/// Diligent::ShaderResources class +class ShaderResourcesD3D11 : public ShaderResources +{ +public: + // Loads shader resources from the compiled shader bytecode + ShaderResourcesD3D11(class RenderDeviceD3D11Impl *pDeviceD3D11Impl, ID3DBlob *pShaderBytecode, const ShaderDesc &ShdrDesc); + ~ShaderResourcesD3D11(); + + __forceinline Int32 GetMaxCBBindPoint() const{return m_MaxCBBindPoint; } + __forceinline Int32 GetMaxSRVBindPoint() const{return m_MaxSRVBindPoint; } + __forceinline Int32 GetMaxSamplerBindPoint()const{return m_MaxSamplerBindPoint; } + __forceinline Int32 GetMaxUAVBindPoint() const{return m_MaxUAVBindPoint; } + +#ifdef VERIFY_SHADER_BINDINGS + void dbgVerifyCommittedResources(ID3D11Buffer* CommittedD3D11CBs[], + ID3D11ShaderResourceView* CommittedD3D11SRVs[], + ID3D11Resource* CommittedD3D11SRVResources[], + ID3D11SamplerState* CommittedD3D11Samplers[], + ID3D11UnorderedAccessView* CommittedD3D11UAVs[], + ID3D11Resource* CommittedD3D11UAVResources[], + class ShaderResourceCacheD3D11 &ResourceCache)const; +#endif + + const Char *GetShaderName()const{return m_ShaderName;} + + void InitStaticSamplers(class ShaderResourceCacheD3D11 &ResourceCache)const; + +private: + typedef Int8 MaxBindPointType; + + MaxBindPointType m_MaxCBBindPoint = -1; // Max == 13 + MaxBindPointType m_MaxSRVBindPoint = -1; // Max == 127 + MaxBindPointType m_MaxSamplerBindPoint = -1; // Max == 15 + MaxBindPointType m_MaxUAVBindPoint = -1; // Max == 7 + Uint8 m_NumStaticSamplers = 0; // Max == 16 + + static const UINT MaxAllowedBindPoint = std::numeric_limits<MaxBindPointType>::max(); + static_assert(D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT-1 <= MaxAllowedBindPoint, "Not enough bits to represent max CB slot" ); + static_assert(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT-1 <= MaxAllowedBindPoint, "Not enough bits to represent max SRV slot"); + static_assert(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT-1 <= MaxAllowedBindPoint, "Not enough bits to represent max Sampler slot"); + static_assert(D3D11_PS_CS_UAV_REGISTER_COUNT-1 <= MaxAllowedBindPoint, "Not enough bits to represent max UAV slot"); + + // ShaderResourcesD3D11 is part of the ShaderD3D11Impl object, so we can simply + // reference shader name without the need to copy it + const Char* m_ShaderName; + + typedef std::pair<const D3DShaderResourceAttribs*, RefCntAutoPtr<ISampler> > StaticSamplerAttribs; + StaticSamplerAttribs& GetStaticSampler(Uint32 n) + { + VERIFY_EXPR(n < m_NumStaticSamplers); + return reinterpret_cast< StaticSamplerAttribs* >(m_StaticSamplers.get())[n]; + } + + // We have to use void, because we will be calling destructors manually + std::unique_ptr< void, STDDeleterRawMem<void > > m_StaticSamplers; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h index 32cef19f..d7a15c7d 100644 --- a/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,21 +32,23 @@ namespace Diligent { +class IMemoryAllocator; /// Implementation of the Diligent::ISwapChainD3D11 interface -class SwapChainD3D11Impl : public SwapChainBase<ISwapChainD3D11> +class SwapChainD3D11Impl : public SwapChainBase<ISwapChainD3D11, IMemoryAllocator> { public: - typedef SwapChainBase<ISwapChainD3D11> TSwapChainBase; - SwapChainD3D11Impl(const SwapChainDesc& SwapChainDesc, - class RenderDeviceD3D11Impl* pRenderDeviceD3D11, - class DeviceContextD3D11Impl* pDeviceContextD3D11, - void* pNativeWndHandle); + typedef SwapChainBase<ISwapChainD3D11, IMemoryAllocator> TSwapChainBase; + SwapChainD3D11Impl(IMemoryAllocator &Allocator, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceD3D11Impl* pRenderDeviceD3D11, + class DeviceContextD3D11Impl* pDeviceContextD3D11, + void* pNativeWndHandle); ~SwapChainD3D11Impl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual void Present(); - virtual void Resize( Uint32 NewWidth, Uint32 NewHeight ); + virtual void Present()override final; + virtual void Resize( Uint32 NewWidth, Uint32 NewHeight )override final; virtual IDXGISwapChain *GetDXGISwapChain(){ return m_pSwapChain; } @@ -56,11 +58,11 @@ public: private: void CreateRTVandDSV(); /// D3D11 swap chain - Diligent::CComPtr<IDXGISwapChain> m_pSwapChain; + CComPtr<IDXGISwapChain> m_pSwapChain; /// Back buffer render target view - Diligent::CComPtr<ID3D11RenderTargetView> m_pRenderTargetView; + CComPtr<ID3D11RenderTargetView> m_pRenderTargetView; /// Back buffer depth-stencil view - Diligent::CComPtr<ID3D11DepthStencilView> m_pDepthStencilView; + CComPtr<ID3D11DepthStencilView> m_pDepthStencilView; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/Texture1D_D3D11.h b/Graphics/GraphicsEngineD3D11/include/Texture1D_D3D11.h index e1cdcb2f..3e53aad5 100644 --- a/Graphics/GraphicsEngineD3D11/include/Texture1D_D3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/Texture1D_D3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,17 +31,22 @@ namespace Diligent { +/// Implementation of a 1D texture class Texture1D_D3D11 : public TextureBaseD3D11 { public: - Texture1D_D3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + Texture1D_D3D11(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + class RenderDeviceD3D11Impl *pDeviceD3D11, + const TextureDesc& TexDesc, + const TextureData &InitData = TextureData()); ~Texture1D_D3D11(); protected: - virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); - virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ); - virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ); - virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ); + virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV )override final; + virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV )override final; + virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV )override final; + virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV )override final; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/Texture2D_D3D11.h b/Graphics/GraphicsEngineD3D11/include/Texture2D_D3D11.h index e098bce1..ed958499 100644 --- a/Graphics/GraphicsEngineD3D11/include/Texture2D_D3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/Texture2D_D3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,17 +31,22 @@ namespace Diligent { +/// Implementation of a 2D texture class Texture2D_D3D11 : public TextureBaseD3D11 { public: - Texture2D_D3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + Texture2D_D3D11(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + class RenderDeviceD3D11Impl *pDeviceD3D11, + const TextureDesc& TexDesc, + const TextureData &InitData = TextureData()); ~Texture2D_D3D11(); protected: - virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); - virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ); - virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ); - virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ); + virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV )override final; + virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV )override final; + virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV )override final; + virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV )override final; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/Texture3D_D3D11.h b/Graphics/GraphicsEngineD3D11/include/Texture3D_D3D11.h index d5e11c8a..44e4ced9 100644 --- a/Graphics/GraphicsEngineD3D11/include/Texture3D_D3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/Texture3D_D3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,17 +31,22 @@ namespace Diligent { +/// Implementation of a 3D texture class Texture3D_D3D11 : public TextureBaseD3D11 { public: - Texture3D_D3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + Texture3D_D3D11(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + class RenderDeviceD3D11Impl *pDeviceD3D11, + const TextureDesc& TexDesc, + const TextureData &InitData = TextureData()); ~Texture3D_D3D11(); protected: - virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ); - virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ); - virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV ); - virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ); + virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV )override final; + virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV )override final; + virtual void CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilView **ppD3D11DSV )override final; + virtual void CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV )override final; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h index e787f238..66da6f6e 100644 --- a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,24 +34,40 @@ namespace Diligent { +class FixedBlockMemoryAllocator; + +enum class D3D11TextureState +{ + Undefined = 0x0, + ShaderResource = 0x1, + RenderTarget = 0x2, + DepthStencil = 0x4, + UnorderedAccess = 0x8, + Output = RenderTarget | DepthStencil | UnorderedAccess +}; + /// Base implementation of the Diligent::ITextureD3D11 interface -class TextureBaseD3D11 : public TextureBase<ITextureD3D11, TextureViewD3D11Impl> +class TextureBaseD3D11 : public TextureBase<ITextureD3D11, TextureViewD3D11Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> { public: - typedef TextureBase<ITextureD3D11, TextureViewD3D11Impl> TTextureBase; + typedef TextureBase<ITextureD3D11, TextureViewD3D11Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> TTextureBase; - TextureBaseD3D11(class RenderDeviceD3D11Impl *pDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData = TextureData()); + TextureBaseD3D11(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + class RenderDeviceD3D11Impl *pDeviceD3D11, + const TextureDesc& TexDesc, + const TextureData &InitData = TextureData()); ~TextureBaseD3D11(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override; + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override final; //virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size); - virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; - virtual void Unmap( IDeviceContext *pContext )override; + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override final; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override final; - virtual ID3D11Resource* GetD3D11Texture(){ return m_pd3d11Texture; } + virtual ID3D11Resource* GetD3D11Texture()override final{ return m_pd3d11Texture; } void CopyData(IDeviceContext *pContext, ITexture *pSrcTexture, @@ -64,9 +80,15 @@ public: Uint32 DstY, Uint32 DstZ); + void ResetState(D3D11TextureState State){m_State = static_cast<Uint32>(State);} + void AddState(D3D11TextureState State){m_State |= static_cast<Uint32>(State);} + void ClearState(D3D11TextureState State){m_State &= ~static_cast<Uint32>(State);} + bool CheckState(D3D11TextureState State){return (m_State & static_cast<Uint32>(State)) ? true : false;} + protected: - void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override; - void PrepareD3D11InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<D3D11_SUBRESOURCE_DATA> &D3D11InitData); + void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override final; + void PrepareD3D11InitData(const TextureData &InitData, Uint32 NumSubresources, + std::vector<D3D11_SUBRESOURCE_DATA, STDAllocatorRawMem<D3D11_SUBRESOURCE_DATA> > &D3D11InitData); virtual void CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ) = 0; virtual void CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetView **ppD3D11RTV ) = 0; @@ -75,7 +97,9 @@ protected: friend class RenderDeviceD3D11Impl; /// D3D11 texture - Diligent::CComPtr<ID3D11Resource> m_pd3d11Texture; + CComPtr<ID3D11Resource> m_pd3d11Texture; + + Uint32 m_State = static_cast<Uint32>(D3D11TextureState::Undefined); }; } diff --git a/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.h index 6e138b41..7a35d7e3 100644 --- a/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,27 +33,33 @@ namespace Diligent { +class FixedBlockMemoryAllocator; + /// Implementation of the Diligent::ITextureViewD3D11 interface -class TextureViewD3D11Impl : public TextureViewBase<ITextureViewD3D11> +class TextureViewD3D11Impl : public TextureViewBase<ITextureViewD3D11, FixedBlockMemoryAllocator> { public: - typedef TextureViewBase<ITextureViewD3D11> TTextureViewBase; + typedef TextureViewBase<ITextureViewD3D11, FixedBlockMemoryAllocator> TTextureViewBase; - TextureViewD3D11Impl( IRenderDevice *pDevice, + TextureViewD3D11Impl( FixedBlockMemoryAllocator &TexViewAllocator, + IRenderDevice *pDevice, const TextureViewDesc& ViewDesc, class ITexture *pTexture, ID3D11View* pD3D11View, bool bIsDefaultView); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual ID3D11View* GetD3D11View()override; + virtual ID3D11View* GetD3D11View()override final + { + return m_pD3D11View; + } - void GenerateMips( IDeviceContext *pContext )override; + void GenerateMips( IDeviceContext *pContext )override final; protected: /// D3D11 view - Diligent::CComPtr<ID3D11View> m_pD3D11View; + CComPtr<ID3D11View> m_pD3D11View; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/pch.h b/Graphics/GraphicsEngineD3D11/include/pch.h index d948fd48..e55827a0 100644 --- a/Graphics/GraphicsEngineD3D11/include/pch.h +++ b/Graphics/GraphicsEngineD3D11/include/pch.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,13 +38,13 @@ #include <vector> #include <exception> #include <algorithm> -#if defined(PLATFORM_WINDOWS) +#if defined(PLATFORM_WIN32) #include <d3d11.h> -#elif defined(PLATFORM_WINDOWS_STORE) +#elif defined(PLATFORM_UNIVERSAL_WINDOWS) #include <d3d11_2.h> #endif -#include "PlatformDefinitions.h" +#include "EngineD3D11Defines.h" #include "Errors.h" #include "RefCntAutoPtr.h" #include "DebugUtilities.h" @@ -52,4 +52,4 @@ #include "RenderDeviceBase.h" #include "D3D11TypeConversions.h" #include "ValidatedCast.h" -#include "ComPtr.h"
\ No newline at end of file +#include <atlcomcli.h>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/include/targetver.h b/Graphics/GraphicsEngineD3D11/include/targetver.h index e76fe941..5a309b33 100644 --- a/Graphics/GraphicsEngineD3D11/include/targetver.h +++ b/Graphics/GraphicsEngineD3D11/include/targetver.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/interface/BufferD3D11.h b/Graphics/GraphicsEngineD3D11/interface/BufferD3D11.h index 46195298..cdd1c72b 100644 --- a/Graphics/GraphicsEngineD3D11/interface/BufferD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/BufferD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/interface/BufferViewD3D11.h b/Graphics/GraphicsEngineD3D11/interface/BufferViewD3D11.h index 32a75461..3b9d3d5c 100644 --- a/Graphics/GraphicsEngineD3D11/interface/BufferViewD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/BufferViewD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/interface/DeviceContextD3D11.h b/Graphics/GraphicsEngineD3D11/interface/DeviceContextD3D11.h index 972249b4..e5d1cb54 100644 --- a/Graphics/GraphicsEngineD3D11/interface/DeviceContextD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/DeviceContextD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/interface/EngineD3D11Attribs.h b/Graphics/GraphicsEngineD3D11/interface/EngineD3D11Attribs.h new file mode 100644 index 00000000..88fcaf66 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/EngineD3D11Attribs.h @@ -0,0 +1,65 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Engine D3D11 attribs + +#include "BasicTypes.h" + +namespace Diligent +{ + /// Debug flags that can be specified when creating Direct3D11-based engine implementation. + /// + /// \sa CreateDeviceAndContextsD3D11Type, CreateSwapChainD3D11Type, LoadGraphicsEngineD3D11 + enum class EngineD3D11DebugFlags : Uint32 + { + /// Before executing draw/dispatch command, verify that + /// all required shader resources are bound to the device context + VerifyCommittedShaderResources = 0x01, + + /// Verify that all committed cotext resources are relevant, + /// i.e. they are consistent with the committed resource cache. + /// This is very expensive operation and should generally not be + /// necessary. + VerifyCommittedResourceRelevance = 0x02 + }; + + /// Attributes of the Direct3D11-based engine implementation + struct EngineD3D11Attribs : public EngineCreationAttribs + { + /// Debug flags. See Diligent::EngineD3D11DebugFlags for a list of allowed values. + /// + /// \sa CreateDeviceAndContextsD3D11Type, CreateSwapChainD3D11Type, LoadGraphicsEngineD3D11 + Uint32 DebugFlags; + + EngineD3D11Attribs() : + DebugFlags(0) + { + #ifdef _DEBUG + DebugFlags = static_cast<Uint32>(EngineD3D11DebugFlags::VerifyCommittedShaderResources); + #endif + } + }; +} diff --git a/Graphics/GraphicsEngineD3D11/interface/PipelineStateD3D11.h b/Graphics/GraphicsEngineD3D11/interface/PipelineStateD3D11.h new file mode 100644 index 00000000..8eab72e4 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/PipelineStateD3D11.h @@ -0,0 +1,107 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IPipeplineStateD3D11 interface + +#include "PipelineState.h" + +namespace Diligent +{ + +// {3EA6E3F4-9966-47FC-8CE8-0EB3E2273061} +static const INTERFACE_ID IID_PipelineStateD3D11 = +{ 0x3ea6e3f4, 0x9966, 0x47fc, { 0x8c, 0xe8, 0xe, 0xb3, 0xe2, 0x27, 0x30, 0x61 } }; + +/// Interface to the blend state object implemented in D3D11 +class IPipelineStateD3D11 : public IPipelineState +{ +public: + + /// Returns a pointer to the ID3D11BlendState interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11BlendState* GetD3D11BlendState() = 0; + + + /// Returns a pointer to the ID3D11RasterizerState interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11RasterizerState* GetD3D11RasterizerState() = 0; + + + /// Returns a pointer to the ID3D11DepthStencilState interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11DepthStencilState* GetD3D11DepthStencilState() = 0; + + /// Returns a pointer to the ID3D11InputLayout interface of the internal Direct3D11 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11InputLayout* GetD3D11InputLayout() = 0; + + /// Returns a pointer to the ID3D11VertexShader interface of the internal vertex shader object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11VertexShader* GetD3D11VertexShader() = 0; + + /// Returns a pointer to the interface of the internal pixel shader object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11PixelShader* GetD3D11PixelShader() = 0; + + + /// Returns a pointer to the ID3D11GeometryShader interface of the internal geometry shader object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11GeometryShader* GetD3D11GeometryShader() = 0; + + /// Returns a pointer to the ID3D11DomainShader interface of the internal domain shader object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11DomainShader* GetD3D11DomainShader() = 0; + + /// Returns a pointer to the ID3D11HullShader interface of the internal hull shader object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11HullShader* GetD3D11HullShader() = 0; + + /// Returns a pointer to the ID3D11ComputeShader interface of the internal compute shader object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D11ComputeShader* GetD3D11ComputeShader() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceD3D11.h b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceD3D11.h index 2baaa564..cd003a85 100644 --- a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ static const Diligent::INTERFACE_ID IID_RenderDeviceD3D11 = { 0x5b1cbb8, 0xfcad, 0x49ee, { 0xba, 0xda, 0x78, 0x1, 0x22, 0x3e, 0xc3, 0xfe } }; /// Interface to the render device object implemented in D3D11 -class IRenderDeviceD3D11 : public Diligent::IRenderDevice +class IRenderDeviceD3D11 : public IRenderDevice { public: diff --git a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h index d289fb65..c651a1e6 100644 --- a/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/RenderDeviceFactoryD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,24 +23,30 @@ #pragma once +/// \file +/// Declaration of functions that initialize Direct3D11-based engine implementation + #include "Errors.h" +#include "EngineD3D11Attribs.h" extern "C" { #ifdef ENGINE_DLL - typedef void (*CreateDeviceAndImmediateContextD3D11Type)( - const Diligent::EngineCreationAttribs& CreationAttribs, + + typedef void (*CreateDeviceAndContextsD3D11Type)( + const Diligent::EngineD3D11Attribs& EngineAttribs, Diligent::IRenderDevice **ppDevice, - Diligent::IDeviceContext **ppContext ); + Diligent::IDeviceContext **ppContexts, + Diligent::Uint32 NumDeferredContexts ); typedef void (*CreateSwapChainD3D11Type)( Diligent::IRenderDevice *pDevice, Diligent::IDeviceContext *pImmediateContext, - const Diligent::SwapChainDesc& SwapChainDesc, + const Diligent::SwapChainDesc& SCDesc, void* pNativeWndHandle, Diligent::ISwapChain **ppSwapChain ); - static void LoadGraphicsEngineD3D11(CreateDeviceAndImmediateContextD3D11Type &CreateDeviceFunc, CreateSwapChainD3D11Type &CreateSwapChainFunc) + static void LoadGraphicsEngineD3D11(CreateDeviceAndContextsD3D11Type &CreateDeviceFunc, CreateSwapChainD3D11Type &CreateSwapChainFunc) { CreateDeviceFunc = nullptr; CreateSwapChainFunc = nullptr; @@ -66,10 +72,10 @@ extern "C" return; } - CreateDeviceFunc = reinterpret_cast<CreateDeviceAndImmediateContextD3D11Type>( GetProcAddress(hModule, "CreateDeviceAndImmediateContextD3D11") ); + CreateDeviceFunc = reinterpret_cast<CreateDeviceAndContextsD3D11Type>( GetProcAddress(hModule, "CreateDeviceAndContextsD3D11") ); if( CreateDeviceFunc == NULL ) { - LOG_ERROR_MESSAGE( "Failed to load CreateDeviceAndImmediateContextD3D11() from ", LibName, " library." ); + LOG_ERROR_MESSAGE( "Failed to load CreateDeviceAndContextsD3D11() from ", LibName, " library." ); FreeLibrary( hModule ); return; } @@ -83,12 +89,14 @@ extern "C" } } #else - void CreateDeviceAndImmediateContextD3D11( const Diligent::EngineCreationAttribs& CreationAttribs, - Diligent::IRenderDevice **ppDevice, - Diligent::IDeviceContext **ppContext ); - void CreateSwapChainD3D11( Diligent::IRenderDevice *pDevice, + void CreateDeviceAndContextsD3D11( const Diligent::EngineD3D11Attribs& EngineAttribs, + Diligent::IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppContexts, + Diligent::Uint32 NumDeferredContexts ); + + void CreateSwapChainD3D11( Diligent::IRenderDevice *pDevice, Diligent::IDeviceContext *pImmediateContext, - const Diligent::SwapChainDesc& SwapChainDesc, + const Diligent::SwapChainDesc& SCDesc, void* pNativeWndHandle, Diligent::ISwapChain **ppSwapChain ); #endif diff --git a/Graphics/GraphicsEngineD3D11/interface/SamplerD3D11.h b/Graphics/GraphicsEngineD3D11/interface/SamplerD3D11.h index 4266f89b..b5266bf1 100644 --- a/Graphics/GraphicsEngineD3D11/interface/SamplerD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/SamplerD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/interface/ShaderD3D11.h b/Graphics/GraphicsEngineD3D11/interface/ShaderD3D11.h index c05cf13f..e6c43492 100644 --- a/Graphics/GraphicsEngineD3D11/interface/ShaderD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/ShaderD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/VertexDescriptionGL.h b/Graphics/GraphicsEngineD3D11/interface/ShaderResourceBindingD3D11.h index 1a785e9b..fd0be846 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/VertexDescriptionGL.h +++ b/Graphics/GraphicsEngineD3D11/interface/ShaderResourceBindingD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,22 +24,22 @@ #pragma once /// \file -/// Definition of the Diligent::IVertexDescriptionGL interface +/// Definition of the Diligent::IShaderResourceBindingD3D11 interface and related data structures -#include "VertexDescription.h" +#include "ShaderResourceBinding.h" namespace Diligent { -// {4CBEE16A-7C22-4F10-8CB5-6D4E393638C7} -static const Diligent::INTERFACE_ID IID_VertexDescriptionGL = -{ 0x4cbee16a, 0x7c22, 0x4f10, { 0x8c, 0xb5, 0x6d, 0x4e, 0x39, 0x36, 0x38, 0xc7 } }; +// {97A6D4AC-D4AF-4AA9-B46C-67417B89026A} +static const Diligent::INTERFACE_ID IID_ShaderResourceBindingD3D11 = +{ 0x97a6d4ac, 0xd4af, 0x4aa9, { 0xb4, 0x6c, 0x67, 0x41, 0x7b, 0x89, 0x2, 0x6a } }; -/// Interface to the vertex description object implemented in OpenGL -class IVertexDescriptionGL : public Diligent::IVertexDescription +/// Shader resource binding interface +class IShaderResourceBindingD3D11 : public IShaderResourceBinding { public: - + }; } diff --git a/Graphics/GraphicsEngineD3D11/interface/SwapChainD3D11.h b/Graphics/GraphicsEngineD3D11/interface/SwapChainD3D11.h index 2419a8ec..54a4d0ae 100644 --- a/Graphics/GraphicsEngineD3D11/interface/SwapChainD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/SwapChainD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/interface/TextureD3D11.h b/Graphics/GraphicsEngineD3D11/interface/TextureD3D11.h index a08ff236..59ffd8ad 100644 --- a/Graphics/GraphicsEngineD3D11/interface/TextureD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/TextureD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/interface/TextureViewD3D11.h b/Graphics/GraphicsEngineD3D11/interface/TextureViewD3D11.h index 7b44ca0b..93bd2492 100644 --- a/Graphics/GraphicsEngineD3D11/interface/TextureViewD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/TextureViewD3D11.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/src/BlendStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BlendStateD3D11Impl.cpp deleted file mode 100644 index eb336523..00000000 --- a/Graphics/GraphicsEngineD3D11/src/BlendStateD3D11Impl.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#include "pch.h" -#include "BlendStateD3D11Impl.h" -#include "RenderDeviceD3D11Impl.h" - -namespace Diligent -{ - -D3D11_BLEND BlendFactorToD3D11Blend( BLEND_FACTOR bf ) -{ - // Note that this code is safe for multithreaded environments since - // bIsInit is set to true only AFTER the entire map is initialized. - static bool bIsInit = false; - static D3D11_BLEND D3D11Blend[BLEND_FACTOR_NUM_FACTORS] = {}; - if( !bIsInit ) - { - // In a multithreaded environment, several threads can potentially enter - // this block. This is not a problem since they will just initialize the - // memory with the same values more than once - D3D11Blend[ BLEND_FACTOR_ZERO ] = D3D11_BLEND_ZERO; - D3D11Blend[ BLEND_FACTOR_ONE ] = D3D11_BLEND_ONE; - D3D11Blend[ BLEND_FACTOR_SRC_COLOR ] = D3D11_BLEND_SRC_COLOR; - D3D11Blend[ BLEND_FACTOR_INV_SRC_COLOR ] = D3D11_BLEND_INV_SRC_COLOR; - D3D11Blend[ BLEND_FACTOR_SRC_ALPHA ] = D3D11_BLEND_SRC_ALPHA; - D3D11Blend[ BLEND_FACTOR_INV_SRC_ALPHA ] = D3D11_BLEND_INV_SRC_ALPHA; - D3D11Blend[ BLEND_FACTOR_DEST_ALPHA ] = D3D11_BLEND_DEST_ALPHA; - D3D11Blend[ BLEND_FACTOR_INV_DEST_ALPHA ] = D3D11_BLEND_INV_DEST_ALPHA; - D3D11Blend[ BLEND_FACTOR_DEST_COLOR ] = D3D11_BLEND_DEST_COLOR; - D3D11Blend[ BLEND_FACTOR_INV_DEST_COLOR ] = D3D11_BLEND_INV_DEST_COLOR; - D3D11Blend[ BLEND_FACTOR_SRC_ALPHA_SAT ] = D3D11_BLEND_SRC_ALPHA_SAT; - D3D11Blend[ BLEND_FACTOR_BLEND_FACTOR ] = D3D11_BLEND_BLEND_FACTOR; - D3D11Blend[ BLEND_FACTOR_INV_BLEND_FACTOR ] = D3D11_BLEND_INV_BLEND_FACTOR; - D3D11Blend[ BLEND_FACTOR_SRC1_COLOR ] = D3D11_BLEND_SRC1_COLOR; - D3D11Blend[ BLEND_FACTOR_INV_SRC1_COLOR ] = D3D11_BLEND_INV_SRC1_COLOR; - D3D11Blend[ BLEND_FACTOR_SRC1_ALPHA ] = D3D11_BLEND_SRC1_ALPHA; - D3D11Blend[ BLEND_FACTOR_INV_SRC1_ALPHA ] = D3D11_BLEND_INV_SRC1_ALPHA; - - bIsInit = true; - } - if( bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS ) - { - auto d3dbf = D3D11Blend[bf]; - VERIFY( d3dbf != 0, "Incorrect blend factor" ); - return d3dbf; - } - else - { - UNEXPECTED("Incorrect blend factor (", bf, ")" ) - return static_cast<D3D11_BLEND>( 0 ); - } -} - -D3D11_BLEND_OP BlendOperation2D3D11BlendOp( BLEND_OPERATION BlendOp ) -{ - static bool bIsInit = false; - static D3D11_BLEND_OP D3D11BlendOp[BLEND_OPERATION_NUM_OPERATIONS] = {}; - if( !bIsInit ) - { - D3D11BlendOp[ BLEND_OPERATION_ADD ] = D3D11_BLEND_OP_ADD; - D3D11BlendOp[ BLEND_OPERATION_SUBTRACT ] = D3D11_BLEND_OP_SUBTRACT; - D3D11BlendOp[ BLEND_OPERATION_REV_SUBTRACT ] = D3D11_BLEND_OP_REV_SUBTRACT; - D3D11BlendOp[ BLEND_OPERATION_MIN ] = D3D11_BLEND_OP_MIN; - D3D11BlendOp[ BLEND_OPERATION_MAX ] = D3D11_BLEND_OP_MAX; - - bIsInit = true; - } - - if( BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS ) - { - auto d3dbop = D3D11BlendOp[BlendOp]; - VERIFY( d3dbop != 0, "Incorrect blend operation" ); - return d3dbop; - } - else - { - UNEXPECTED( "Incorrect blend operation (", BlendOp, ")" ) - return static_cast<D3D11_BLEND_OP>(0); - } -} - -BlendStateD3D11Impl::BlendStateD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, - const BlendStateDesc& BlendStateDesc) : - TBlendStateBase(pRenderDeviceD3D11, BlendStateDesc) -{ - D3D11_BLEND_DESC D3D11BSDesc; - D3D11BSDesc.AlphaToCoverageEnable = BlendStateDesc.AlphaToCoverageEnable ? TRUE : FALSE; - D3D11BSDesc.IndependentBlendEnable = BlendStateDesc.IndependentBlendEnable ? TRUE : FALSE; - VERIFY( BlendStateDesc.MaxRenderTargets >= 8, "Number of render targets is expected to be at least 8" ); - for( int i = 0; i < 8; ++i ) - { - const auto& SrcRTDesc = BlendStateDesc.RenderTargets[i]; - auto &DstRTDesc = D3D11BSDesc.RenderTarget[i]; - DstRTDesc.BlendEnable = SrcRTDesc.BlendEnable ? TRUE : FALSE; - - DstRTDesc.SrcBlend = BlendFactorToD3D11Blend(SrcRTDesc.SrcBlend); - DstRTDesc.DestBlend = BlendFactorToD3D11Blend(SrcRTDesc.DestBlend); - DstRTDesc.BlendOp = BlendOperation2D3D11BlendOp(SrcRTDesc.BlendOp); - - DstRTDesc.SrcBlendAlpha = BlendFactorToD3D11Blend(SrcRTDesc.SrcBlendAlpha); - DstRTDesc.DestBlendAlpha = BlendFactorToD3D11Blend(SrcRTDesc.DestBlendAlpha); - DstRTDesc.BlendOpAlpha = BlendOperation2D3D11BlendOp(SrcRTDesc.BlendOpAlpha); - - DstRTDesc.RenderTargetWriteMask = - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_RED) ? D3D11_COLOR_WRITE_ENABLE_RED : 0) | - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_GREEN) ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0) | - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_BLUE) ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0) | - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_ALPHA) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0); - } - - auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); - CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateBlendState( &D3D11BSDesc, &m_pd3d11BlendState ), - "Failed to create D3D11 blend state object" ); -} - -BlendStateD3D11Impl::~BlendStateD3D11Impl() -{ - -} - -IMPLEMENT_QUERY_INTERFACE( BlendStateD3D11Impl, IID_BlendStateD3D11, TBlendStateBase ) - -} diff --git a/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp index 97905e47..7c4282d4 100644 --- a/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,20 +22,25 @@ */ #include "pch.h" +#include <atlbase.h> + #include "BufferD3D11Impl.h" #include "RenderDeviceD3D11Impl.h" #include "DeviceContextD3D11Impl.h" #include "D3D11TypeConversions.h" #include "BufferViewD3D11Impl.h" #include "GraphicsUtilities.h" - -using namespace Diligent; +#include "EngineMemory.h" namespace Diligent { -BufferD3D11Impl :: BufferD3D11Impl(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const BufferDesc& BuffDesc, const BufferData &BuffData /*= BufferData()*/) : - TBufferBase(pRenderDeviceD3D11, BuffDesc) +BufferD3D11Impl :: BufferD3D11Impl(FixedBlockMemoryAllocator &BufferObjMemAllocator, + FixedBlockMemoryAllocator &BuffViewObjMemAllocator, + RenderDeviceD3D11Impl *pRenderDeviceD3D11, + const BufferDesc& BuffDesc, + const BufferData &BuffData /*= BufferData()*/) : + TBufferBase(BufferObjMemAllocator, BuffViewObjMemAllocator, pRenderDeviceD3D11, BuffDesc, false) { #define LOG_BUFFER_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Buffer \"", BuffDesc.Name ? BuffDesc.Name : "", "\": ", ##__VA_ARGS__); @@ -141,9 +146,9 @@ void BufferD3D11Impl :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 M VERIFY( pMappedData || (MapFlags & MAP_FLAG_DO_NOT_WAIT) && (hr == DXGI_ERROR_WAS_STILL_DRAWING), "Map failed" ); } -void BufferD3D11Impl::Unmap( IDeviceContext *pContext ) +void BufferD3D11Impl::Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) { - TBufferBase::Unmap( pContext ); + TBufferBase::Unmap( pContext, MapType ); auto *pd3d11DeviceContext = static_cast<DeviceContextD3D11Impl*>(pContext)->GetD3D11DeviceContext(); pd3d11DeviceContext->Unmap(m_pd3d11Buffer, 0); @@ -159,18 +164,22 @@ void BufferD3D11Impl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IB try { + auto *pDeviceD3D11Impl = ValidatedCast<RenderDeviceD3D11Impl>(GetDevice()); + auto &BuffViewAllocator = pDeviceD3D11Impl->GetBuffViewObjAllocator(); + VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" ); + BufferViewDesc ViewDesc = OrigViewDesc; if( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS ) { CComPtr<ID3D11UnorderedAccessView> pUAV; CreateUAV( ViewDesc, &pUAV ); - *ppView = new BufferViewD3D11Impl( GetDevice(), ViewDesc, this, pUAV, bIsDefaultView ); + *ppView = NEW(BuffViewAllocator, "BufferViewD3D11Impl instance", BufferViewD3D11Impl, pDeviceD3D11Impl, ViewDesc, this, pUAV, bIsDefaultView ); } else if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE ) { CComPtr<ID3D11ShaderResourceView> pSRV; CreateSRV( ViewDesc, &pSRV ); - *ppView = new BufferViewD3D11Impl( GetDevice(), ViewDesc, this, pSRV, bIsDefaultView ); + *ppView = NEW(BuffViewAllocator, "BufferViewD3D11Impl instance", BufferViewD3D11Impl, pDeviceD3D11Impl, ViewDesc, this, pSRV, bIsDefaultView ); } if( !bIsDefaultView && *ppView ) @@ -185,24 +194,10 @@ void BufferD3D11Impl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IB void BufferD3D11Impl::CreateUAV( BufferViewDesc &UAVDesc, ID3D11UnorderedAccessView **ppD3D11UAV ) { - D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; - memset( &D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc) ); - const auto &BuffFmt = m_Desc.Format; - if( m_Desc.Mode == BUFFER_MODE_FORMATED ) - D3D11_UAVDesc.Format = TypeToDXGI_Format( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); - CorrectBufferViewDesc( UAVDesc ); - if( UAVDesc.ByteOffset != 0 ) - { - VERIFY( m_Desc.Mode == BUFFER_MODE_STRUCTURED, "Non-zero byte offset is only supported for structured buffers" ); - } - VERIFY( UAVDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); - VERIFY( (UAVDesc.ByteOffset % m_Desc.ElementByteStride) == 0, "Byte offest is not multiple of element byte stride" ); - VERIFY( (UAVDesc.ByteWidth % m_Desc.ElementByteStride) == 0, "Byte width is not multiple of element byte stride" ); - D3D11_UAVDesc.Buffer.FirstElement = UAVDesc.ByteOffset / m_Desc.ElementByteStride; - D3D11_UAVDesc.Buffer.NumElements = UAVDesc.ByteWidth / m_Desc.ElementByteStride; - D3D11_UAVDesc.Buffer.Flags = 0; // D3D11_BUFFER_UAV_FLAG_RAW, D3D11_BUFFER_UAV_FLAG_APPEND, D3D11_BUFFER_UAV_FLAG_COUNTER - D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + + D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; + BufferViewDesc_to_D3D11_UAV_DESC(m_Desc, UAVDesc, D3D11_UAVDesc); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Buffer, &D3D11_UAVDesc, ppD3D11UAV ), @@ -211,23 +206,10 @@ void BufferD3D11Impl::CreateUAV( BufferViewDesc &UAVDesc, ID3D11UnorderedAccessV void BufferD3D11Impl::CreateSRV( struct BufferViewDesc &SRVDesc, ID3D11ShaderResourceView **ppD3D11SRV ) { - D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; - memset( &D3D11_SRVDesc, 0, sizeof( D3D11_SRVDesc ) ); - const auto &BuffFmt = m_Desc.Format; - if( m_Desc.Mode == BUFFER_MODE_FORMATED ) - D3D11_SRVDesc.Format = TypeToDXGI_Format( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); - CorrectBufferViewDesc( SRVDesc ); - if( SRVDesc.ByteOffset != 0 ) - { - VERIFY( m_Desc.Mode == BUFFER_MODE_STRUCTURED, "Non-zero byte offset is only supported for structured buffers" ); - } - VERIFY( SRVDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); - VERIFY( (SRVDesc.ByteOffset % m_Desc.ElementByteStride) == 0, "Byte offest is not multiple of element byte stride" ); - VERIFY( (SRVDesc.ByteWidth % m_Desc.ElementByteStride) == 0, "Byte width is not multiple of element byte stride" ); - D3D11_SRVDesc.Buffer.FirstElement = SRVDesc.ByteOffset / m_Desc.ElementByteStride; - D3D11_SRVDesc.Buffer.NumElements = SRVDesc.ByteWidth / m_Desc.ElementByteStride; - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + + D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; + BufferViewDesc_to_D3D11_SRV_DESC(m_Desc, SRVDesc, D3D11_SRVDesc); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Buffer, &D3D11_SRVDesc, ppD3D11SRV ), diff --git a/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp index 6f8239d8..3aa8ca1b 100644 --- a/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,21 +27,17 @@ namespace Diligent { -BufferViewD3D11Impl::BufferViewD3D11Impl( IRenderDevice *pDevice, - const BufferViewDesc& ViewDesc, - IBuffer *pBuffer, - ID3D11View* pD3D11View, - bool bIsDefaultView ) : - TBufferViewBase( pDevice, ViewDesc, pBuffer, bIsDefaultView ), +BufferViewD3D11Impl::BufferViewD3D11Impl( FixedBlockMemoryAllocator &BuffViewObjAllocator, + IRenderDevice *pDevice, + const BufferViewDesc& ViewDesc, + IBuffer *pBuffer, + ID3D11View* pD3D11View, + bool bIsDefaultView ) : + TBufferViewBase( BuffViewObjAllocator, pDevice, ViewDesc, pBuffer, bIsDefaultView ), m_pD3D11View( pD3D11View ) { } -ID3D11View* BufferViewD3D11Impl::GetD3D11View() -{ - return m_pD3D11View; -} - IMPLEMENT_QUERY_INTERFACE( BufferViewD3D11Impl, IID_BufferViewD3D11, TBufferViewBase ) } diff --git a/Graphics/GraphicsEngineOpenGL/src/VertexDescGLImpl.cpp b/Graphics/GraphicsEngineD3D11/src/CommandListD3D11Impl.cpp index 0b2b6b50..2c74c3ec 100644 --- a/Graphics/GraphicsEngineOpenGL/src/VertexDescGLImpl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/CommandListD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,24 +22,24 @@ */ #include "pch.h" +#include <atlbase.h> -#include "VertexDescGLImpl.h" -#include "RenderDeviceGLImpl.h" +#include "CommandListD3D11Impl.h" +#include "EngineMemory.h" namespace Diligent { -VertexDescGLImpl::VertexDescGLImpl( RenderDeviceGLImpl *pDeviceGL, const LayoutDesc &LayoutDesc, bool bIsDeviceInternal ) : - TVertexDescriptionBase(pDeviceGL, LayoutDesc) +CommandListD3D11Impl :: CommandListD3D11Impl(FixedBlockMemoryAllocator &CommandListObjMemAllocator, + IRenderDevice *pDevice, + ID3D11CommandList *pd3d11CommandList) : + TCommandListBase(CommandListObjMemAllocator, pDevice), + m_pd3d11CommandList(pd3d11CommandList) { - } -VertexDescGLImpl::~VertexDescGLImpl() +CommandListD3D11Impl :: ~CommandListD3D11Impl() { - static_cast<RenderDeviceGLImpl*>( GetDevice() )->m_VAOCache.OnDestroyVertexDesc(this); } -IMPLEMENT_QUERY_INTERFACE( VertexDescGLImpl, IID_VertexDescriptionGL, TVertexDescriptionBase ) - } diff --git a/Graphics/GraphicsEngineD3D11/src/D3D11DebugUtilities.cpp b/Graphics/GraphicsEngineD3D11/src/D3D11DebugUtilities.cpp index 686df365..440a616e 100644 --- a/Graphics/GraphicsEngineD3D11/src/D3D11DebugUtilities.cpp +++ b/Graphics/GraphicsEngineD3D11/src/D3D11DebugUtilities.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,176 +23,9 @@ #include "pch.h" #include "D3D11DebugUtilities.h" -#include "TextureViewD3D11.h" -#include "BufferViewD3D11.h" -#include "BufferD3D11.h" -#include "SamplerD3D11.h" -#include "GraphicsUtilities.h" -namespace Diligent -{ - -#ifdef VERIFY_RESOURCE_ARRAYS - -template<typename TResourceArr, typename TD3D11ResourceArr, typename TTestProc> -void dbgVerifyResourceArraysInternal( TResourceArr &Resources, TD3D11ResourceArr& d3d11Resources, TTestProc TestProc ) -{ - VERIFY( Resources.size() == d3d11Resources.size(), "Inconsistent resource array sizes (", Resources.size(), ",", d3d11Resources.size(), ")" ); - auto NumSlots = std::min(Resources.size(), d3d11Resources.size()); - for( Uint32 Slot = 0; Slot < NumSlots; ++Slot ) - { - auto &Res = Resources.at(Slot); - const auto &d3d11Res = d3d11Resources.at( Slot ); - TestProc( Slot, Res, d3d11Res ); - } -} - -static const Char* GetD3D11ResName( const ID3D11ShaderResourceView* ){ return "SRV"; } -static const Char* GetD3D11ResName( const ID3D11UnorderedAccessView* ){ return "UAV"; } -static const Char* GetD3D11ResName( const ID3D11Buffer* ){ return "constant buffer"; } -static const Char* GetD3D11ResName( const ID3D11SamplerState* ){ return "sampler"; } -template<typename TBoundResourceType, typename TD3D11ResourceType> -class dbgVerifyResourceViewArrays -{ -public: - dbgVerifyResourceViewArrays( TEXTURE_VIEW_TYPE TVT, BUFFER_VIEW_TYPE BVT, IShader *pShader ) : - TexViewType( TVT ), - BuffViewType( BVT ), - ShaderTypeName(GetShaderTypeLiteralName(pShader->GetDesc().ShaderType)), - ShaderName(pShader->GetDesc().Name) - {} - - void operator()( int Slot, const TBoundResourceType& BoundRes, const TD3D11ResourceType* d3d11View ) - { - TD3D11ResourceType *pD3D11ResTypeMarker = nullptr; -#define VERFIY_RESOURCE_BINDING(Exp, Intro, Res, ...) \ - VERIFY(Exp, Intro, " \"", Res->GetDesc().Name, "\" bound as ", GetD3D11ResName(pD3D11ResTypeMarker)," to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot, ' ', __VA_ARGS__) - - if( !d3d11View ) - { - VERFIY_RESOURCE_BINDING( !BoundRes.pResource, "Unexpected non-null resource", BoundRes.pResource ) - VERFIY_RESOURCE_BINDING( !BoundRes.pView, "Unexpected non-null resource view", BoundRes.pView ) - } - - if( BoundRes.pView ) - { - auto ncView = const_cast<IDeviceObject*>(BoundRes.pView.RawPtr()); - RefCntAutoPtr<ITextureViewD3D11> pTexView; - ncView->QueryInterface( IID_TextureViewD3D11, reinterpret_cast<IObject**>(static_cast<ITextureViewD3D11**>(&pTexView)) ); - RefCntAutoPtr<IBufferViewD3D11> pBuffView; - ncView->QueryInterface( IID_BufferViewD3D11, reinterpret_cast<IObject**>(static_cast<IBufferViewD3D11**>(&pBuffView)) ); - VERFIY_RESOURCE_BINDING( pTexView || pBuffView, "Resource", ncView, "is expected to be a texture view or a buffer view" ); - if( pTexView ) - { - auto ViewType = pTexView->GetDesc().ViewType; - VERFIY_RESOURCE_BINDING( ViewType == TexViewType, "Texture view", ncView, "has incorrect type: ", GetTexViewTypeLiteralName( TexViewType ), " is expected, while ", GetTexViewTypeLiteralName( ViewType ), " provided" ); - auto *d3d11RefView = pTexView->GetD3D11View(); - VERFIY_RESOURCE_BINDING( d3d11RefView == d3d11View && BoundRes.pd3d11View.RawPtr() == d3d11RefView, "Texture view", ncView, "does not match D3D11 resoruce" ); - auto *pTex = pTexView->GetTexture(); - VERFIY_RESOURCE_BINDING( pTex == BoundRes.pResource, "Texture view", ncView, "is not the view of resource \"", BoundRes.pResource->GetDesc().Name, "\"" ); - } - - if( pBuffView ) - { - auto ViewType = pBuffView->GetDesc().ViewType; - VERFIY_RESOURCE_BINDING( ViewType == BuffViewType, "Buffer view", ncView, "has incorrect type: ", GetBufferViewTypeLiteralName( BuffViewType ), " is expected, while ", GetBufferViewTypeLiteralName( ViewType ), " provided" ); - auto *d3d11RefView = pBuffView->GetD3D11View(); - VERFIY_RESOURCE_BINDING( d3d11RefView == d3d11View && BoundRes.pd3d11View.RawPtr() == d3d11RefView, "Buffer view", ncView, "does not match D3D11 resource" ); - auto *pBuf = pBuffView->GetBuffer(); - VERFIY_RESOURCE_BINDING( pBuf == BoundRes.pResource, "Buffer view", ncView, "is not the view of resource \"", BoundRes.pResource->GetDesc().Name, "\"" ); - } - } - else - { - VERIFY( !BoundRes.pResource, "Unexpected non-null resource bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot); - VERIFY( !BoundRes.pd3d11View, "Unexpected non-null D3D11 resource view bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot); - } - } -private: - TEXTURE_VIEW_TYPE TexViewType; - BUFFER_VIEW_TYPE BuffViewType; - const Char* ShaderTypeName; - const char* ShaderName; -}; - -void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSRV >&SRVs, const std::vector<ID3D11ShaderResourceView*> d3d11SRVs, IShader *pShader ) -{ - dbgVerifyResourceArraysInternal(SRVs, d3d11SRVs, dbgVerifyResourceViewArrays<ShaderD3D11Impl::BoundSRV, ID3D11ShaderResourceView>(TEXTURE_VIEW_SHADER_RESOURCE, BUFFER_VIEW_SHADER_RESOURCE, pShader)); -} - -void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundUAV >&UAVs, const std::vector<ID3D11UnorderedAccessView*> d3d11UAVs, IShader *pShader ) -{ - dbgVerifyResourceArraysInternal(UAVs, d3d11UAVs, dbgVerifyResourceViewArrays<ShaderD3D11Impl::BoundUAV, ID3D11UnorderedAccessView>(TEXTURE_VIEW_UNORDERED_ACCESS, BUFFER_VIEW_UNORDERED_ACCESS, pShader)); -} - -void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundCB >&CBs, const std::vector<ID3D11Buffer*> d3d11CBs, IShader *pShader ) -{ - const auto* ShaderTypeName = GetShaderTypeLiteralName( pShader->GetDesc().ShaderType ); - const auto &ShaderName = pShader->GetDesc().Name; - ID3D11Buffer *pD3D11ResTypeMarker = nullptr; - - dbgVerifyResourceArraysInternal( CBs, d3d11CBs, - [&]( int Slot, const ShaderD3D11Impl::BoundCB& CB, const ID3D11Buffer* d3d11CB ) - { - if( !d3d11CB ) - { - VERFIY_RESOURCE_BINDING( !CB.pBuff, "Unexpected non-null resource", CB.pBuff ) - } - - if( CB.pBuff ) - { - auto ncCB = const_cast<IDeviceObject*>(CB.pBuff.RawPtr()); - RefCntAutoPtr<IBufferD3D11> pBuff; - ncCB->QueryInterface( IID_BufferD3D11, reinterpret_cast<IObject**>(static_cast<IBufferD3D11**>(&pBuff)) ); - VERFIY_RESOURCE_BINDING( pBuff, "Resource", ncCB, "is expected to be a buffer" ); - if( pBuff ) - { - auto *d3d11RefBuff = pBuff->GetD3D11Buffer(); - VERFIY_RESOURCE_BINDING( d3d11RefBuff == d3d11CB && d3d11RefBuff == CB.pd3d11Buff, "Constant buffer", ncCB, "does not match D3D11 buffer" ); - } - } - else - { - VERIFY( !d3d11CB, "Unexpected non-null D3D11 buffer bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot); - } - } - ); -} - -void dbgVerifyResourceArrays( const std::vector< ShaderD3D11Impl::BoundSampler >&Samplers, const std::vector<ID3D11SamplerState*> d3d11Samplers, IShader *pShader ) +namespace Diligent { - const auto* ShaderTypeName = GetShaderTypeLiteralName( pShader->GetDesc().ShaderType ); - const auto &ShaderName = pShader->GetDesc().Name; - ID3D11SamplerState *pD3D11ResTypeMarker = nullptr; - - dbgVerifyResourceArraysInternal( Samplers, d3d11Samplers, - [&]( int Slot, const ShaderD3D11Impl::BoundSampler& Sampler, const ID3D11SamplerState* d3d11Sampler ) - { - if( !d3d11Sampler ) - { - VERFIY_RESOURCE_BINDING( !Sampler.pSampler, "Unexpected non-null resource", Sampler.pSampler ) - } - if( Sampler.pSampler ) - { - auto ncSampler = const_cast<IDeviceObject*>(Sampler.pSampler.RawPtr()); - RefCntAutoPtr<ISamplerD3D11> pSamplerD3D11; - ncSampler->QueryInterface( IID_SamplerD3D11, reinterpret_cast<IObject**>(static_cast<ISamplerD3D11**>(&pSamplerD3D11)) ); - VERFIY_RESOURCE_BINDING( pSamplerD3D11, "Resource", ncSampler, "is expected to be a sampler" ); - if( pSamplerD3D11 ) - { - auto *d3d11RefSampler = pSamplerD3D11->GetD3D11SamplerState(); - VERFIY_RESOURCE_BINDING( d3d11RefSampler == d3d11Sampler && d3d11RefSampler == Sampler.pd3d11Sampler, "Sampler", ncSampler, "does not match D3D11 sampler" ); - } - } - else - { - VERIFY( !d3d11Sampler, "Unexpected non-null D3D11 sampler bound to shader \"", ShaderName, "\" (", ShaderTypeName, ") at slot ", Slot ); - } - } - ); -} - -#endif } diff --git a/Graphics/GraphicsEngineD3D11/src/D3D11TypeConversions.cpp b/Graphics/GraphicsEngineD3D11/src/D3D11TypeConversions.cpp index ac6265f2..5c340a30 100644 --- a/Graphics/GraphicsEngineD3D11/src/D3D11TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D11/src/D3D11TypeConversions.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,481 +24,98 @@ #include "pch.h" #include "D3D11TypeConversions.h" +#include "D3D11TypeDefinitions.h" +#include "D3DTypeConversionImpl.h" +#include "D3DViewDescConversionImpl.h" + namespace Diligent { -DXGI_FORMAT TypeToDXGI_Format(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized) +D3D11_FILTER FilterTypeToD3D11Filter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter) { - switch(ValType) - { - case VT_FLOAT16: - { - VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R16_FLOAT; - case 2: return DXGI_FORMAT_R16G16_FLOAT; - case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT; - default: UNEXPECTED("Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - - case VT_FLOAT32: - { - VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R32_FLOAT; - case 2: return DXGI_FORMAT_R32G32_FLOAT; - case 3: return DXGI_FORMAT_R32G32B32_FLOAT; - case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - - case VT_INT32: - { - VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R32_SINT; - case 2: return DXGI_FORMAT_R32G32_SINT; - case 3: return DXGI_FORMAT_R32G32B32_SINT; - case 4: return DXGI_FORMAT_R32G32B32A32_SINT; - default: UNEXPECTED("Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - - case VT_UINT32: - { - VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R32_UINT; - case 2: return DXGI_FORMAT_R32G32_UINT; - case 3: return DXGI_FORMAT_R32G32B32_UINT; - case 4: return DXGI_FORMAT_R32G32B32A32_UINT; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - - case VT_INT16: - { - if( bIsNormalized ) - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R16_SNORM; - case 2: return DXGI_FORMAT_R16G16_SNORM; - case 4: return DXGI_FORMAT_R16G16B16A16_SNORM; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - else - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R16_SINT; - case 2: return DXGI_FORMAT_R16G16_SINT; - case 4: return DXGI_FORMAT_R16G16B16A16_SINT; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - } - - case VT_UINT16: - { - if( bIsNormalized ) - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R16_UNORM; - case 2: return DXGI_FORMAT_R16G16_UNORM; - case 4: return DXGI_FORMAT_R16G16B16A16_UNORM; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - else - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R16_UINT; - case 2: return DXGI_FORMAT_R16G16_UINT; - case 4: return DXGI_FORMAT_R16G16B16A16_UINT; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - } - - case VT_INT8: - { - if( bIsNormalized ) - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R8_SNORM; - case 2: return DXGI_FORMAT_R8G8_SNORM; - case 4: return DXGI_FORMAT_R8G8B8A8_SNORM; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - else - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R8_SINT; - case 2: return DXGI_FORMAT_R8G8_SINT; - case 4: return DXGI_FORMAT_R8G8B8A8_SINT; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - } - - case VT_UINT8: - { - if( bIsNormalized ) - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R8_UNORM; - case 2: return DXGI_FORMAT_R8G8_UNORM; - case 4: return DXGI_FORMAT_R8G8B8A8_UNORM; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - else - { - switch(NumComponents) - { - case 1: return DXGI_FORMAT_R8_UINT; - case 2: return DXGI_FORMAT_R8G8_UINT; - case 4: return DXGI_FORMAT_R8G8B8A8_UINT; - default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; - } - } - } + return FilterTypeToD3DFilter<D3D11_FILTER>(MinFilter, MagFilter, MipFilter); +} - default: UNEXPECTED( "Unusupported format" ); return DXGI_FORMAT_UNKNOWN; - } +D3D11_TEXTURE_ADDRESS_MODE TexAddressModeToD3D11AddressMode(TEXTURE_ADDRESS_MODE Mode) +{ + return TexAddressModeToD3DAddressMode<D3D11_TEXTURE_ADDRESS_MODE>(Mode); } -DXGI_FORMAT CorrectDXGIFormat( DXGI_FORMAT DXGIFormat, Uint32 BindFlags ) +D3D11_COMPARISON_FUNC ComparisonFuncToD3D11ComparisonFunc(COMPARISON_FUNCTION Func) { - if( (BindFlags & BIND_DEPTH_STENCIL) && (BindFlags != BIND_DEPTH_STENCIL) ) - { - switch( DXGIFormat ) - { - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_D32_FLOAT: - DXGIFormat = DXGI_FORMAT_R32_TYPELESS; - break; + return ComparisonFuncToD3DComparisonFunc<D3D11_COMPARISON_FUNC>(Func); +} - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_D16_UNORM: - DXGIFormat = DXGI_FORMAT_R16_TYPELESS; - break; +void DepthStencilStateDesc_To_D3D11_DEPTH_STENCIL_DESC(const DepthStencilStateDesc &DepthStencilDesc, D3D11_DEPTH_STENCIL_DESC &d3d11DSSDesc) +{ + DepthStencilStateDesc_To_D3D_DEPTH_STENCIL_DESC<D3D11_DEPTH_STENCIL_DESC, D3D11_DEPTH_STENCILOP_DESC, D3D11_STENCIL_OP, D3D11_COMPARISON_FUNC>(DepthStencilDesc, d3d11DSSDesc); +} - default: - UNEXPECTED( "Unsupported format" ); - break; - } - } +void RasterizerStateDesc_To_D3D11_RASTERIZER_DESC(const RasterizerStateDesc &RasterizerDesc, D3D11_RASTERIZER_DESC &d3d11RSDesc) +{ + RasterizerStateDesc_To_D3D_RASTERIZER_DESC<D3D11_RASTERIZER_DESC, D3D11_FILL_MODE, D3D11_CULL_MODE>(RasterizerDesc, d3d11RSDesc); + d3d11RSDesc.ScissorEnable = RasterizerDesc.ScissorEnable ? TRUE : FALSE; +} - if( BindFlags == BIND_DEPTH_STENCIL ) - { - switch( DXGIFormat ) - { - case DXGI_FORMAT_R32_FLOAT: - DXGIFormat = DXGI_FORMAT_D32_FLOAT; - break; - case DXGI_FORMAT_R16_UNORM: - DXGIFormat = DXGI_FORMAT_D16_UNORM; - break; - } - } +void BlendStateDesc_To_D3D11_BLEND_DESC(const BlendStateDesc &BSDesc, D3D11_BLEND_DESC &d3d11BSDesc) +{ + BlendStateDescToD3DBlendDesc<D3D11_BLEND_DESC, D3D11_BLEND, D3D11_BLEND_OP>(BSDesc, d3d11BSDesc); - if( BindFlags == BIND_SHADER_RESOURCE || BindFlags == BIND_UNORDERED_ACCESS ) + for( int i = 0; i < 8; ++i ) { - switch( DXGIFormat ) + const auto& SrcRTDesc = BSDesc.RenderTargets[i]; + if (SrcRTDesc.LogicOperationEnable) { - case DXGI_FORMAT_D32_FLOAT: - DXGIFormat = DXGI_FORMAT_R32_FLOAT; - break; - - case DXGI_FORMAT_D16_UNORM: - DXGIFormat = DXGI_FORMAT_R16_UNORM; - break; + LOG_ERROR("Logical operations on render targets are not supported by D3D11 device"); } } - - return DXGIFormat; } -DXGI_FORMAT TexFormatToDXGI_Format(TEXTURE_FORMAT TexFormat, Uint32 BindFlags) +void LayoutElements_To_D3D11_INPUT_ELEMENT_DESCs(const std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement> > &LayoutElements, + std::vector<D3D11_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D11_INPUT_ELEMENT_DESC> > &D3D11InputElements) { - static Bool bFormatMapIntialized = false; - static DXGI_FORMAT FmtToDXGIFmtMap[TEX_FORMAT_NUM_FORMATS] = {DXGI_FORMAT_UNKNOWN}; - if( !bFormatMapIntialized ) - { - FmtToDXGIFmtMap[ TEX_FORMAT_UNKNOWN ] = DXGI_FORMAT_UNKNOWN; - - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_TYPELESS ] = DXGI_FORMAT_R32G32B32A32_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_FLOAT ] = DXGI_FORMAT_R32G32B32A32_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_UINT ] = DXGI_FORMAT_R32G32B32A32_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_SINT ] = DXGI_FORMAT_R32G32B32A32_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_TYPELESS ] = DXGI_FORMAT_R32G32B32_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_FLOAT ] = DXGI_FORMAT_R32G32B32_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_UINT ] = DXGI_FORMAT_R32G32B32_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_SINT ] = DXGI_FORMAT_R32G32B32_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_TYPELESS ] = DXGI_FORMAT_R16G16B16A16_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_FLOAT ] = DXGI_FORMAT_R16G16B16A16_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_UNORM ] = DXGI_FORMAT_R16G16B16A16_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_UINT ] = DXGI_FORMAT_R16G16B16A16_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_SNORM ] = DXGI_FORMAT_R16G16B16A16_SNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_SINT ] = DXGI_FORMAT_R16G16B16A16_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_RG32_TYPELESS ] = DXGI_FORMAT_R32G32_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RG32_FLOAT ] = DXGI_FORMAT_R32G32_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_RG32_UINT ] = DXGI_FORMAT_R32G32_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_RG32_SINT ] = DXGI_FORMAT_R32G32_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_R32G8X24_TYPELESS ] = DXGI_FORMAT_R32G8X24_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_D32_FLOAT_S8X24_UINT ] = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS ]= DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_X32_TYPELESS_G8X24_UINT ]= DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_TYPELESS ] = DXGI_FORMAT_R10G10B10A2_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_UNORM ] = DXGI_FORMAT_R10G10B10A2_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_UINT ] = DXGI_FORMAT_R10G10B10A2_UINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_R11G11B10_FLOAT ] = DXGI_FORMAT_R11G11B10_FLOAT; - - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_TYPELESS ] = DXGI_FORMAT_R8G8B8A8_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UNORM ] = DXGI_FORMAT_R8G8B8A8_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UNORM_SRGB ] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UINT ] = DXGI_FORMAT_R8G8B8A8_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_SNORM ] = DXGI_FORMAT_R8G8B8A8_SNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_SINT ] = DXGI_FORMAT_R8G8B8A8_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_RG16_TYPELESS ] = DXGI_FORMAT_R16G16_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RG16_FLOAT ] = DXGI_FORMAT_R16G16_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_RG16_UNORM ] = DXGI_FORMAT_R16G16_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RG16_UINT ] = DXGI_FORMAT_R16G16_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_RG16_SNORM ] = DXGI_FORMAT_R16G16_SNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RG16_SINT ] = DXGI_FORMAT_R16G16_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_R32_TYPELESS ] = DXGI_FORMAT_R32_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_D32_FLOAT ] = DXGI_FORMAT_D32_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_R32_FLOAT ] = DXGI_FORMAT_R32_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_R32_UINT ] = DXGI_FORMAT_R32_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_R32_SINT ] = DXGI_FORMAT_R32_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_R24G8_TYPELESS ] = DXGI_FORMAT_R24G8_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_D24_UNORM_S8_UINT ] = DXGI_FORMAT_D24_UNORM_S8_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_R24_UNORM_X8_TYPELESS ] = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_X24_TYPELESS_G8_UINT ] = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_RG8_TYPELESS ] = DXGI_FORMAT_R8G8_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_RG8_UNORM ] = DXGI_FORMAT_R8G8_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RG8_UINT ] = DXGI_FORMAT_R8G8_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_RG8_SNORM ] = DXGI_FORMAT_R8G8_SNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_RG8_SINT ] = DXGI_FORMAT_R8G8_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_R16_TYPELESS ] = DXGI_FORMAT_R16_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_R16_FLOAT ] = DXGI_FORMAT_R16_FLOAT; - FmtToDXGIFmtMap[ TEX_FORMAT_D16_UNORM ] = DXGI_FORMAT_D16_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_R16_UNORM ] = DXGI_FORMAT_R16_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_R16_UINT ] = DXGI_FORMAT_R16_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_R16_SNORM ] = DXGI_FORMAT_R16_SNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_R16_SINT ] = DXGI_FORMAT_R16_SINT; - - FmtToDXGIFmtMap[ TEX_FORMAT_R8_TYPELESS ] = DXGI_FORMAT_R8_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_R8_UNORM ] = DXGI_FORMAT_R8_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_R8_UINT ] = DXGI_FORMAT_R8_UINT; - FmtToDXGIFmtMap[ TEX_FORMAT_R8_SNORM ] = DXGI_FORMAT_R8_SNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_R8_SINT ] = DXGI_FORMAT_R8_SINT; - FmtToDXGIFmtMap[ TEX_FORMAT_A8_UNORM ] = DXGI_FORMAT_A8_UNORM; - - FmtToDXGIFmtMap[ TEX_FORMAT_R1_UNORM ] = DXGI_FORMAT_R1_UNORM ; - FmtToDXGIFmtMap[ TEX_FORMAT_RGB9E5_SHAREDEXP ] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; - FmtToDXGIFmtMap[ TEX_FORMAT_RG8_B8G8_UNORM ] = DXGI_FORMAT_R8G8_B8G8_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_G8R8_G8B8_UNORM ] = DXGI_FORMAT_G8R8_G8B8_UNORM; - - FmtToDXGIFmtMap[ TEX_FORMAT_BC1_TYPELESS ] = DXGI_FORMAT_BC1_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BC1_UNORM ] = DXGI_FORMAT_BC1_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BC1_UNORM_SRGB ] = DXGI_FORMAT_BC1_UNORM_SRGB; - FmtToDXGIFmtMap[ TEX_FORMAT_BC2_TYPELESS ] = DXGI_FORMAT_BC2_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BC2_UNORM ] = DXGI_FORMAT_BC2_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BC2_UNORM_SRGB ] = DXGI_FORMAT_BC2_UNORM_SRGB; - FmtToDXGIFmtMap[ TEX_FORMAT_BC3_TYPELESS ] = DXGI_FORMAT_BC3_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BC3_UNORM ] = DXGI_FORMAT_BC3_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BC3_UNORM_SRGB ] = DXGI_FORMAT_BC3_UNORM_SRGB; - FmtToDXGIFmtMap[ TEX_FORMAT_BC4_TYPELESS ] = DXGI_FORMAT_BC4_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BC4_UNORM ] = DXGI_FORMAT_BC4_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BC4_SNORM ] = DXGI_FORMAT_BC4_SNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BC5_TYPELESS ] = DXGI_FORMAT_BC5_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BC5_UNORM ] = DXGI_FORMAT_BC5_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BC5_SNORM ] = DXGI_FORMAT_BC5_SNORM; - - FmtToDXGIFmtMap[ TEX_FORMAT_B5G6R5_UNORM ] = DXGI_FORMAT_B5G6R5_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_B5G5R5A1_UNORM ] = DXGI_FORMAT_B5G5R5A1_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_UNORM ] = DXGI_FORMAT_B8G8R8A8_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_UNORM ] = DXGI_FORMAT_B8G8R8X8_UNORM; + LayoutElements_To_D3D_INPUT_ELEMENT_DESCs<D3D11_INPUT_ELEMENT_DESC>(LayoutElements, D3D11InputElements); +} - FmtToDXGIFmtMap[ TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ]= DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM; +D3D11_PRIMITIVE_TOPOLOGY TopologyToD3D11Topology(PRIMITIVE_TOPOLOGY Topology) +{ + return TopologyToD3DTopology<D3D11_PRIMITIVE_TOPOLOGY>(Topology); +} - FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_TYPELESS ] = DXGI_FORMAT_B8G8R8A8_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_UNORM_SRGB ] = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_TYPELESS ] = DXGI_FORMAT_B8G8R8X8_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_UNORM_SRGB ] = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; - FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_TYPELESS ] = DXGI_FORMAT_BC6H_TYPELESS; - FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_UF16 ] = DXGI_FORMAT_BC6H_UF16; - FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_SF16 ] = DXGI_FORMAT_BC6H_SF16; - FmtToDXGIFmtMap[ TEX_FORMAT_BC7_TYPELESS ] = DXGI_FORMAT_BC7_TYPELESS ; - FmtToDXGIFmtMap[ TEX_FORMAT_BC7_UNORM ] = DXGI_FORMAT_BC7_UNORM; - FmtToDXGIFmtMap[ TEX_FORMAT_BC7_UNORM_SRGB ] = DXGI_FORMAT_BC7_UNORM_SRGB; - - bFormatMapIntialized = true; - } - if( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS ) - { - auto DXGIFormat = FmtToDXGIFmtMap[TexFormat]; - VERIFY( TexFormat == TEX_FORMAT_UNKNOWN || DXGIFormat != DXGI_FORMAT_UNKNOWN, "Unsupported texture format" ); - if( BindFlags != 0 ) - DXGIFormat = CorrectDXGIFormat( DXGIFormat, BindFlags ); - return DXGIFormat; - } - else - { - UNEXPECTED( "Texture format (", TexFormat, ") is out of allowed range [0, ", TEX_FORMAT_NUM_FORMATS-1, "]" ); - return DXGI_FORMAT_UNKNOWN; - } +void TextureViewDesc_to_D3D11_SRV_DESC(const TextureViewDesc& TexViewDesc, D3D11_SHADER_RESOURCE_VIEW_DESC &D3D11SRVDesc, Uint32 SampleCount) +{ + TextureViewDesc_to_D3D_SRV_DESC(TexViewDesc, D3D11SRVDesc, SampleCount); } -D3D11_FILTER FilterTypeToD3D11Filter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter) +void TextureViewDesc_to_D3D11_RTV_DESC(const TextureViewDesc& TexViewDesc, D3D11_RENDER_TARGET_VIEW_DESC &D3D11RTVDesc, Uint32 SampleCount) { - switch( MinFilter ) - { - case FILTER_TYPE_POINT: - if( MagFilter == FILTER_TYPE_POINT ) - { - if( MipFilter == FILTER_TYPE_POINT ) - return D3D11_FILTER_MIN_MAG_MIP_POINT; - else if( MipFilter == FILTER_TYPE_LINEAR ) - return D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; - } - else if( MagFilter == FILTER_TYPE_LINEAR ) - { - if( MipFilter == FILTER_TYPE_POINT ) - return D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; - else if( MipFilter == FILTER_TYPE_LINEAR ) - return D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_LINEAR: - if( MagFilter == FILTER_TYPE_POINT ) - { - if( MipFilter == FILTER_TYPE_POINT ) - return D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; - else if( MipFilter == FILTER_TYPE_LINEAR ) - return D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - } - else if( MagFilter == FILTER_TYPE_LINEAR ) - { - if( MipFilter == FILTER_TYPE_POINT ) - return D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; - else if( MipFilter == FILTER_TYPE_LINEAR ) - return D3D11_FILTER_MIN_MAG_MIP_LINEAR; - } - break; + TextureViewDesc_to_D3D_RTV_DESC(TexViewDesc, D3D11RTVDesc, SampleCount); +} - case FILTER_TYPE_ANISOTROPIC: - VERIFY( MagFilter == FILTER_TYPE_ANISOTROPIC && MipFilter == FILTER_TYPE_ANISOTROPIC, - "For anistropic filtering, all filters must be anisotropic" ); - return D3D11_FILTER_ANISOTROPIC; - break; +void TextureViewDesc_to_D3D11_DSV_DESC(const TextureViewDesc& TexViewDesc, D3D11_DEPTH_STENCIL_VIEW_DESC &D3D11DSVDesc, Uint32 SampleCount) +{ + TextureViewDesc_to_D3D_DSV_DESC(TexViewDesc, D3D11DSVDesc, SampleCount); +} - case FILTER_TYPE_COMPARISON_POINT: - if( MagFilter == FILTER_TYPE_COMPARISON_POINT ) - { - if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) - return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT; - else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) - return D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR; - } - else if( MagFilter == FILTER_TYPE_COMPARISON_LINEAR ) - { - if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) - return D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT; - else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) - return D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR; - } - break; +void TextureViewDesc_to_D3D11_UAV_DESC(const TextureViewDesc& TexViewDesc, D3D11_UNORDERED_ACCESS_VIEW_DESC &D3D11UAVDesc) +{ + TextureViewDesc_to_D3D_UAV_DESC(TexViewDesc, D3D11UAVDesc); +} - case FILTER_TYPE_COMPARISON_LINEAR: - if( MagFilter == FILTER_TYPE_COMPARISON_POINT ) - { - if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) - return D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT; - else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) - return D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - } - else if( MagFilter == FILTER_TYPE_COMPARISON_LINEAR ) - { - if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) - return D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; - else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) - return D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; - } - break; - case FILTER_TYPE_COMPARISON_ANISOTROPIC: - VERIFY( MagFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC && MipFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC, - "For comparison anistropic filtering, all filters must be anisotropic" ); - return D3D11_FILTER_COMPARISON_ANISOTROPIC; - break; - } - UNEXPECTED( "Unsupported filter combination" ); - return D3D11_FILTER_MIN_MAG_MIP_POINT; +void BufferViewDesc_to_D3D11_SRV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& SRVDesc, D3D11_SHADER_RESOURCE_VIEW_DESC &D3D11SRVDesc) +{ + BufferViewDesc_to_D3D_SRV_DESC(BuffDesc, SRVDesc, D3D11SRVDesc); } -D3D11_STENCIL_OP StencilOpToD3D11StencilOp( STENCIL_OP StencilOp ) +void BufferViewDesc_to_D3D11_UAV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& UAVDesc, D3D11_UNORDERED_ACCESS_VIEW_DESC &D3D11UAVDesc) { - static bool bIsInit = false; - static D3D11_STENCIL_OP StOp2D3D11StOpMap[STENCIL_OP_NUM_OPS] = {}; - if( !bIsInit ) - { - StOp2D3D11StOpMap[ STENCIL_OP_KEEP ] = D3D11_STENCIL_OP_KEEP; - StOp2D3D11StOpMap[ STENCIL_OP_ZERO ] = D3D11_STENCIL_OP_ZERO; - StOp2D3D11StOpMap[ STENCIL_OP_REPLACE ] = D3D11_STENCIL_OP_REPLACE; - StOp2D3D11StOpMap[ STENCIL_OP_INCR_SAT ] = D3D11_STENCIL_OP_INCR_SAT; - StOp2D3D11StOpMap[ STENCIL_OP_DECR_SAT ] = D3D11_STENCIL_OP_DECR_SAT; - StOp2D3D11StOpMap[ STENCIL_OP_INVERT ] = D3D11_STENCIL_OP_INVERT; - StOp2D3D11StOpMap[ STENCIL_OP_INCR_WRAP] = D3D11_STENCIL_OP_INCR; - StOp2D3D11StOpMap[ STENCIL_OP_DECR_WRAP] = D3D11_STENCIL_OP_DECR; - - bIsInit = true; - } - - if( StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS ) - { - auto D3D11StencilOp = StOp2D3D11StOpMap[StencilOp]; - VERIFY( D3D11StencilOp != 0, "Unexpected stencil op" ); - return D3D11StencilOp; - } - else - { - UNEXPECTED( "Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS - 1, "]" ) - return static_cast<D3D11_STENCIL_OP>(0); - } + BufferViewDesc_to_D3D_UAV_DESC(BuffDesc, UAVDesc, D3D11UAVDesc); + D3D11UAVDesc.Buffer.Flags = 0; // D3D11_BUFFER_UAV_FLAG_RAW, D3D11_BUFFER_UAV_FLAG_APPEND, D3D11_BUFFER_UAV_FLAG_COUNTER } - } diff --git a/Graphics/GraphicsEngineD3D11/src/DLLMain.cpp b/Graphics/GraphicsEngineD3D11/src/DLLMain.cpp index 373d1570..fff890c0 100644 --- a/Graphics/GraphicsEngineD3D11/src/DLLMain.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DLLMain.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3D11/src/DSStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DSStateD3D11Impl.cpp deleted file mode 100644 index 218664c1..00000000 --- a/Graphics/GraphicsEngineD3D11/src/DSStateD3D11Impl.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#include "pch.h" -#include "DSStateD3D11Impl.h" -#include "RenderDeviceD3D11Impl.h" - -namespace Diligent -{ - -D3D11_DEPTH_STENCILOP_DESC StencilOpDesc2D3D11StencilOpDesc(const StencilOpDesc &StOpDesc) -{ - D3D11_DEPTH_STENCILOP_DESC D3D11StOpDesc; - D3D11StOpDesc.StencilFailOp = StencilOpToD3D11StencilOp( StOpDesc.StencilFailOp ); - D3D11StOpDesc.StencilDepthFailOp = StencilOpToD3D11StencilOp( StOpDesc.StencilDepthFailOp ); - D3D11StOpDesc.StencilPassOp = StencilOpToD3D11StencilOp( StOpDesc.StencilPassOp ); - D3D11StOpDesc.StencilFunc = ComparisonFuncToD3D11ComparisonFunc( StOpDesc.StencilFunc ); - return D3D11StOpDesc; -} - -DSStateD3D11Impl::DSStateD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const DepthStencilStateDesc& DepthStencilStateDesc) : - TDepthStencilStateBase(pRenderDeviceD3D11, DepthStencilStateDesc) -{ - D3D11_DEPTH_STENCIL_DESC D3D11DSSDesc; - D3D11DSSDesc.DepthEnable = DepthStencilStateDesc.DepthEnable ? TRUE : FALSE; - D3D11DSSDesc.DepthWriteMask = DepthStencilStateDesc.DepthWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; - D3D11DSSDesc.DepthFunc = ComparisonFuncToD3D11ComparisonFunc( DepthStencilStateDesc.DepthFunc ); - D3D11DSSDesc.StencilEnable = DepthStencilStateDesc.StencilEnable ? TRUE : FALSE; - D3D11DSSDesc.StencilReadMask = DepthStencilStateDesc.StencilReadMask; - D3D11DSSDesc.StencilWriteMask = DepthStencilStateDesc.StencilWriteMask; - D3D11DSSDesc.FrontFace = StencilOpDesc2D3D11StencilOpDesc( DepthStencilStateDesc.FrontFace ); - D3D11DSSDesc.BackFace = StencilOpDesc2D3D11StencilOpDesc( DepthStencilStateDesc.BackFace ); - - auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); - CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateDepthStencilState( &D3D11DSSDesc, &m_pd3d11DepthStencilState ), - "Failed to create D3D11 depth stencil state" ); -} - -DSStateD3D11Impl::~DSStateD3D11Impl() -{ - -} - -IMPLEMENT_QUERY_INTERFACE( DSStateD3D11Impl, IID_DepthStencilStateD3D11, TDepthStencilStateBase ) - -} diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index a6e14dd5..69514bf0 100644 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ #include "pch.h" #include "DeviceContextD3D11Impl.h" #include "BufferD3D11Impl.h" -#include "VertexDescD3D11Impl.h" #include "ShaderD3D11Impl.h" #include "Texture1D_D3D11.h" #include "Texture2D_D3D11.h" @@ -32,209 +31,86 @@ #include "SamplerD3D11Impl.h" #include "D3D11TypeConversions.h" #include "TextureViewD3D11Impl.h" -#include "DSStateD3D11Impl.h" -#include "RasterizerStateD3D11Impl.h" -#include "BlendStateD3D11Impl.h" -#include "DSStateD3D11Impl.h" +#include "PipelineStateD3D11Impl.h" #include "SwapChainD3D11Impl.h" #include "D3D11DebugUtilities.h" +#include "ShaderResourceBindingD3D11Impl.h" +#include "EngineD3D11Attribs.h" +#include "EngineD3D11Defines.h" +#include "CommandListD3D11Impl.h" using namespace Diligent; namespace Diligent { - - DeviceContextD3D11Impl::DeviceContextD3D11Impl( IRenderDevice *pDevice, ID3D11DeviceContext *pd3d11DeviceContext ) : - TDeviceContextBase(pDevice), + DeviceContextD3D11Impl::DeviceContextD3D11Impl( IMemoryAllocator &Allocator, IRenderDevice *pDevice, ID3D11DeviceContext *pd3d11DeviceContext, const struct EngineD3D11Attribs &EngineAttribs, bool bIsDeferred ) : + TDeviceContextBase(Allocator, pDevice, bIsDeferred), m_pd3d11DeviceContext( pd3d11DeviceContext ), - m_BoundD3D11IndexFmt(DXGI_FORMAT_UNKNOWN), - m_BoundD3D11IndexDataStartOffset(0) + m_CommittedIBFormat(VT_UNDEFINED), + m_CommittedD3D11IndexDataStartOffset(0), + m_DebugFlags(EngineAttribs.DebugFlags), + m_NumCommittedD3D11VBs(0), + m_CmdListAllocator(GetRawAllocator(), sizeof(CommandListD3D11Impl), 64 ) { - for( int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType ) - { - m_BoundCBs [ShaderType].reserve( D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ); // 14 - m_BoundD3D11CBs[ShaderType].reserve( D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ); // 14 - - m_BoundSamplers [ShaderType].reserve( D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT );// 16 - m_BoundD3D11Samplers[ShaderType].reserve( D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT );// 16 - - m_BoundSRVs [ShaderType].reserve( D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT );// 128 - m_BoundD3D11SRVs[ShaderType].reserve( D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT );// 128 - - m_BoundUAVs [ShaderType].reserve( D3D11_PS_CS_UAV_REGISTER_COUNT );// 8 - m_BoundD3D11UAVs[ShaderType].reserve( D3D11_PS_CS_UAV_REGISTER_COUNT );// 8 - } + memset(m_NumCommittedCBs, 0, sizeof(m_NumCommittedCBs)); + memset(m_NumCommittedSRVs, 0, sizeof(m_NumCommittedSRVs)); + memset(m_NumCommittedSamplers, 0, sizeof(m_NumCommittedSamplers)); + memset(m_NumCommittedUAVs, 0, sizeof(m_NumCommittedUAVs)); + + memset(m_CommittedD3D11CBs, 0, sizeof(m_CommittedD3D11CBs)); + memset(m_CommittedD3D11SRVs, 0, sizeof(m_CommittedD3D11SRVs)); + memset(m_CommittedD3D11Samplers, 0, sizeof(m_CommittedD3D11Samplers)); + memset(m_CommittedD3D11UAVs, 0, sizeof(m_CommittedD3D11UAVs)); + memset(m_CommittedD3D11SRVResources, 0, sizeof(m_CommittedD3D11SRVResources)); + memset(m_CommittedD3D11UAVResources, 0, sizeof(m_CommittedD3D11UAVResources)); + + memset(m_CommittedD3D11VBStrides, 0, sizeof(m_CommittedD3D11VBStrides)); + memset(m_CommittedD3D11VBOffsets, 0, sizeof(m_CommittedD3D11VBOffsets)); } IMPLEMENT_QUERY_INTERFACE( DeviceContextD3D11Impl, IID_DeviceContextD3D11, TDeviceContextBase ) - void DeviceContextD3D11Impl::SetShaders( IShader **ppShaders, Uint32 NumShadersToSet ) + void DeviceContextD3D11Impl::SetPipelineState(IPipelineState *pPipelineState) { - TDeviceContextBase::SetShaders( ppShaders, NumShadersToSet ); - } - - void DeviceContextD3D11Impl::BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) - { - TDeviceContextBase::BindShaderResources( pResourceMapping, Flags ); - for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end(); ++it ) + TDeviceContextBase::SetPipelineState( pPipelineState ); + auto *pPipelineStateD3D11 = ValidatedCast<PipelineStateD3D11Impl>(pPipelineState); + auto &Desc = pPipelineStateD3D11->GetDesc(); + if (Desc.IsComputePipeline) { - (*it)->BindResources( pResourceMapping, Flags ); - } - } - - - SHADER_TYPE GetShaderTypeFromIndex( Int32 Index ) - { - return static_cast<SHADER_TYPE>(1 << Index); - } - - Int32 GetShaderTypeIndex( SHADER_TYPE Type ) - { - auto ShaderIndex = 0; - switch( Type ) - { - case SHADER_TYPE_UNKNOWN: ShaderIndex = -1; break; - case SHADER_TYPE_VERTEX: ShaderIndex = 0; break; - case SHADER_TYPE_PIXEL: ShaderIndex = 1; break; - case SHADER_TYPE_GEOMETRY:ShaderIndex = 2; break; - case SHADER_TYPE_HULL: ShaderIndex = 3; break; - case SHADER_TYPE_DOMAIN: ShaderIndex = 4; break; - case SHADER_TYPE_COMPUTE: ShaderIndex = 5; break; - default: UNEXPECTED( "Unexpected shader type (", Type, ")" ); ShaderIndex = -1; - } - VERIFY( Type == GetShaderTypeFromIndex(ShaderIndex), "Incorrect shader type index" ); - return ShaderIndex; - } - - const ID3D11Buffer* GetD3D11Resource( const ShaderD3D11Impl::BoundCB &CB ) { return CB.pd3d11Buff; } - const ID3D11SamplerState* GetD3D11Resource( const ShaderD3D11Impl::BoundSampler &Sampler ){ return Sampler.pd3d11Sampler; } - const ID3D11ShaderResourceView* GetD3D11Resource( const ShaderD3D11Impl::BoundSRV &SRV ) { return SRV.pd3d11View; } - const ID3D11UnorderedAccessView* GetD3D11Resource( const ShaderD3D11Impl::BoundUAV &UAV ) { return UAV.pd3d11View; } - - /// This helper template function facilitates binding different D3D11 resources to the device context - - /// \tparam TD3D11ResourceType - Type of D3D11 resource being bound (ID3D11ShaderResourceView, - /// ID3D11UnorderedAccessView, ID3D11Buffer or ID3D11SamplerState). - /// \tparam TBoundResourceType - Type of the struct describing resources associated with the - /// bound entity (ShaderD3D11Impl::BoundCB, ShaderD3D11Impl::BoundSRV, etc.) - /// \tparam TGetResourcesMethod - Type of the method that is used to get the bound resources array from - /// the shader (such as &ShaderD3D11Impl::GetBoundCBs). - /// \tparam TUnbindProc - Type of the procedure that unbinds the resource from the context - /// (for instance, if resource is set as SRV, it must be unbound from UAV slots) - /// \tparam TD3D11ResourceSetMethod - Type of the method that bounds the new resources to the D3D11 - /// device context - /// \param pShader - Pointer to the shader whose resources are to be bound - /// \param BoundResourcesArr - Pointer to the array of structures describing currently bound - /// shader resources, for each shader stage - /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 - /// shader resources, for each shader stage - /// \param GetResources - Pointer to the method to get array of bound shader resources from the shader - /// \param UnbindProc - Function to perform required unbind steps - /// \param D3D11ResourceSetMethod - Function to set the new D3D11 resources to the D3D11 device context - template<typename TD3D11ResourceType, - typename TBoundResourceType, - typename TGetResourcesMethod, - typename TUnbindProc, - typename TD3D11ResourceSetMethod> - void UpdateBoundResources(ShaderD3D11Impl *pShader, - std::vector<TBoundResourceType> BoundResourcesArr[], - std::vector<TD3D11ResourceType*> BoundD3D11ResourcesArr[], - TGetResourcesMethod GetResources, - TUnbindProc UnbindProc, - TD3D11ResourceSetMethod D3D11ResourceSetMethod) - { - const auto &NewResources = (pShader->*GetResources)(); - auto NumNewResources = NewResources.size(); - if( NumNewResources == 0 ) - return; - - auto ShaderType = pShader->GetDesc().ShaderType; - auto ShaderInd = GetShaderTypeIndex(ShaderType); - // Get currently bound resources for the shader type - auto &BoundResources = BoundResourcesArr [ShaderInd]; - auto &BoundD3D11Resources = BoundD3D11ResourcesArr[ShaderInd]; - - VERIFY(BoundD3D11Resources.size() == BoundResources.size(), "Inconsistent array sizes") - if( NumNewResources > BoundD3D11Resources.size() ) - BoundD3D11Resources.resize(NumNewResources); - if( NumNewResources > BoundResources.size() ) - BoundResources.resize(NumNewResources); - - // Compute the minimum and the maximum slot numbers of updated D3D11 resources - Int32 MinSlot = std::numeric_limits<Int32>::max(); - Int32 MaxSlot = std::numeric_limits<Int32>::min(); - for( Int32 iSlot = 0; iSlot < static_cast<Int32>(NumNewResources); ++iSlot ) - { - const auto& pNewRes = NewResources [iSlot]; - const auto& pNewD3D11Res = GetD3D11Resource(pNewRes); - if( pNewD3D11Res != nullptr && pNewD3D11Res != BoundD3D11Resources[iSlot] ) + auto *pd3d11CS = pPipelineStateD3D11->GetD3D11ComputeShader(); + if (pd3d11CS == nullptr) { - // Perform the required steps to unbind the resource - UnbindProc( pNewRes ); + LOG_ERROR("Compute shader is not set in the pipeline"); + return; + } - MinSlot = std::min( MinSlot, iSlot ); - MaxSlot = std::max( MaxSlot, iSlot ); - BoundD3D11Resources[iSlot] = const_cast<TD3D11ResourceType*>(pNewD3D11Res); - BoundResources[iSlot] = pNewRes; +#define COMMIT_SHADER(SN, ShaderName)\ + { \ + auto *pd3d11Shader = pPipelineStateD3D11->GetD3D11##ShaderName(); \ + if (m_CommittedD3DShaders[SN##Ind] != pd3d11Shader) \ + { \ + m_CommittedD3DShaders[SN##Ind] = pd3d11Shader; \ + m_pd3d11DeviceContext->SN##SetShader(pd3d11Shader, nullptr, 0); \ + } \ } - } - if( MaxSlot >= MinSlot ) + COMMIT_SHADER(CS, ComputeShader); + } + else { - D3D11ResourceSetMethod(ShaderInd, MinSlot, MaxSlot - MinSlot + 1, &BoundD3D11Resources[MinSlot]); + COMMIT_SHADER(VS, VertexShader); + COMMIT_SHADER(PS, PixelShader); + COMMIT_SHADER(GS, GeometryShader); + COMMIT_SHADER(HS, HullShader); + COMMIT_SHADER(DS, DomainShader); +#undef COMMIT_SHADER + + m_pd3d11DeviceContext->OMSetBlendState( pPipelineStateD3D11->GetD3D11BlendState(), m_BlendFactors, Desc.GraphicsPipeline.SampleMask ); + m_pd3d11DeviceContext->RSSetState( pPipelineStateD3D11->GetD3D11RasterizerState() ); + m_pd3d11DeviceContext->OMSetDepthStencilState( pPipelineStateD3D11->GetD3D11DepthStencilState(), m_StencilRef ); + + m_pd3d11DeviceContext->IASetInputLayout(pPipelineStateD3D11->GetD3D11InputLayout()); } - - // Verify that the resource array and the D3D11 resource array are consistent - dbgVerifyResourceArrays( BoundResources, BoundD3D11Resources, pShader ); - } - - /// Template function that facilitates binding D3D11 SRVs, CBs and samplers to the device context - - /// \tparam TD3D11ResourceType - Type of D3D11 resource being bound (ID3D11ShaderResourceView, - /// ID3D11Buffer or ID3D11SamplerState). - /// \tparam TBoundResourceType - Type of the struct describing resources associated with the - /// bound entity (ShaderD3D11Impl::BoundCB, ShaderD3D11Impl::BoundSRV, etc.) - /// \tparam TGetResourcesMethod - Type of the method that is used to get the bound resources array from - /// the shader (such as &ShaderD3D11Impl::GetBoundCBs). - /// \tparam TUnbindProc - Type of the procedure that unbinds the resource from the context - /// (for instance, if resource is set as SRV, it must be unbound from UAV slots) - /// \tparam TSetD3D11Resource - Type of the D3D11 device context method used to set the - /// resource (such as &ID3D11DeviceContext::SetShaderResources) - /// \param pShader - Pointer to the shader whose resources are to be bound - /// \param BoundResourcesArr - Pointer to the array of structures describing currently bound - /// shader resources, for each shader stage - /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 - /// shader resources, for each shader stage - /// \param GetResources - Pointer to the method to get array of bound shader resources from the shader - /// \param UnbindProc - Function to perform required unbind steps - /// \param SetD3D11ResourcesArr - Pointer to the array of device context methods used - /// to set the resource, for every shader stage - /// \param pd3d11DeviceCtx - Device context - template<typename TD3D11ResourceType, - typename TBoundResourceType, - typename TGetResourcesMethod, - typename TUnbindProc, - typename TSetD3D11Resource> - void UpdateBoundResources(ShaderD3D11Impl *pShader, - std::vector<TBoundResourceType> BoundResourcesArr[], - std::vector<TD3D11ResourceType*> BoundD3D11ResourcesArr[], - TGetResourcesMethod GetResources, - TUnbindProc UnbindProc, - TSetD3D11Resource SetD3D11ResourcesArr[], - ID3D11DeviceContext *pd3d11DeviceCtx) - { - UpdateBoundResources(pShader, BoundResourcesArr, BoundD3D11ResourcesArr, - GetResources, UnbindProc, - [&](Int32 ShaderInd, UINT MinSlot, UINT NumSlots, TD3D11ResourceType** ppD3D11Resources) - { - auto SetD3D11Resources = SetD3D11ResourcesArr[ShaderInd]; - VERIFY(SetD3D11Resources, "Set D3D11 resource function pointer is null."); - if( SetD3D11Resources ) - { - (pd3d11DeviceCtx->*SetD3D11Resources)(MinSlot, NumSlots, ppD3D11Resources); - } - } - ); } /// Helper macro used to create an array of device context methods to @@ -266,347 +142,583 @@ namespace Diligent &ID3D11DeviceContext::CSSetUnorderedAccessViews }; - void DeviceContextD3D11Impl::SetD3DConstantBuffers( ShaderD3D11Impl *pShader ) - { - UpdateBoundResources(pShader, m_BoundCBs, m_BoundD3D11CBs, - &ShaderD3D11Impl::GetBoundCBs, - [&](const ShaderD3D11Impl::BoundCB &BoundCB) - { - auto *pResource = const_cast<IDeviceObject *>(BoundCB.pBuff.RawPtr()); - RefCntAutoPtr<IBuffer> pBuff; - pResource->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>( static_cast<IBuffer**>(&pBuff) ) ); - if( pBuff ) - { - if( pBuff->GetDesc().BindFlags & BIND_UNORDERED_ACCESS ) - UnbindResourceFromUAV( pBuff ); - } - else - { - UNEXPECTED( "Resource \"", pResource->GetDesc().Name, "\" is expected to be a buffer" ) - } - }, - SetCBMethods, - m_pd3d11DeviceContext ); - dbgVerifyContextCBs(pShader->GetDesc().ShaderType); - } - - void DeviceContextD3D11Impl::SetD3DSRVs( ShaderD3D11Impl *pShader ) + template<bool TransitionResources, + bool CommitResources> + void DeviceContextD3D11Impl::TransitionAndCommitShaderResources(IPipelineState *pPSO, IShaderResourceBinding *pShaderResourceBinding) { - UpdateBoundResources(pShader, m_BoundSRVs, m_BoundD3D11SRVs, - &ShaderD3D11Impl::GetBoundSRVs, - [&](const ShaderD3D11Impl::BoundSRV &BoundSRV) - { - auto *pResource = const_cast<IDeviceObject *>(BoundSRV.pResource.RawPtr()); - RefCntAutoPtr<ITexture> pTexture; - pResource->QueryInterface( IID_Texture, reinterpret_cast<IObject**>( static_cast<ITexture**>(&pTexture) ) ); - if( pTexture ) - { - auto BindFlags = pTexture->GetDesc().BindFlags; - if( BindFlags & BIND_UNORDERED_ACCESS ) - UnbindResourceFromUAV(pTexture); - if( BindFlags & BIND_RENDER_TARGET ) - UnbindTextureFromRenderTarget(pTexture); - if( BindFlags & BIND_DEPTH_STENCIL ) - UnbindTextureFromDepthStencil(pTexture); - } - else + static_assert(TransitionResources || CommitResources, "At least one of TransitionResources or CommitResources flags is expected to be true"); + +#ifdef _DEBUG + auto pdbgPipelineStateD3D11 = ValidatedCast<PipelineStateD3D11Impl>( pPSO ); + auto ppdbgShaders = pdbgPipelineStateD3D11->GetShaders(); +#endif + + auto pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding); + if(!pShaderResBindingD3D11) + { + auto pPipelineStateD3D11 = ValidatedCast<PipelineStateD3D11Impl>( pPSO ); + pShaderResBindingD3D11 = pPipelineStateD3D11->GetDefaultResourceBinding(); + } +#ifdef _DEBUG + else + { + if (pdbgPipelineStateD3D11 != pShaderResourceBinding->GetPipelineState()) + { + LOG_ERROR_MESSAGE("Shader resource binding does not match Pipeline State"); + return; + } + } +#endif + + if(!pShaderResBindingD3D11->IsStaticResourcesBound()) + pShaderResBindingD3D11->BindStaticShaderResources(); + + auto NumShaders = pShaderResBindingD3D11->GetNumActiveShaders(); + VERIFY(NumShaders == pdbgPipelineStateD3D11->GetNumShaders(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state"); + + for (Uint32 s = 0; s < NumShaders; ++s) + { + auto ShaderTypeInd = pShaderResBindingD3D11->GetActiveShaderTypeIndex(s); +#ifdef _DEBUG + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>(ppdbgShaders[s]); + VERIFY_EXPR( ShaderTypeInd == static_cast<Int32>(pShaderD3D11->GetShaderTypeIndex()) ); +#endif + + auto &Cache = pShaderResBindingD3D11->GetResourceCache(s); + auto PackedResCounts = Cache.GetPackedCounts(); + + ShaderResourceCacheD3D11::CachedCB* CachedCBs; + ID3D11Buffer** d3d11CBs; + ShaderResourceCacheD3D11::CachedResource* CachedSRVResources; + ID3D11ShaderResourceView** d3d11SRVs; + ShaderResourceCacheD3D11::CachedSampler* CachedSamplers; + ID3D11SamplerState** d3d11Samplers; + ShaderResourceCacheD3D11::CachedResource* CachedUAVResources; + ID3D11UnorderedAccessView** d3d11UAVs; + Cache.GetResourceArrays(CachedCBs, d3d11CBs, CachedSRVResources, d3d11SRVs, CachedSamplers, d3d11Samplers, CachedUAVResources, d3d11UAVs); + +#ifdef VERIFY_SHADER_BINDINGS + { + pShaderResBindingD3D11->GetResourceLayout(s).dbgVerifyBindings(); + // Static resource bindings are verified in BindStaticShaderResources() + } +#endif + + // Transition and commit Constant Buffers + auto NumCBs = ShaderResourceCacheD3D11::UnpackCBCount(PackedResCounts); + if(NumCBs) + { + auto *CommittedD3D11CBs = m_CommittedD3D11CBs[ShaderTypeInd]; + UINT MinSlot = UINT_MAX; + UINT MaxSlot = 0; + for(Uint32 cb=0; cb < NumCBs; ++cb) + { + VERIFY_EXPR(cb < Cache.GetCBCount()); + + if(TransitionResources) + { + auto &CB = CachedCBs[cb]; + if( auto *pBuff = const_cast<BufferD3D11Impl*>(CB.pBuff.RawPtr()) ) + { + // WARNING! This code is not thread-safe. If several threads change + // the buffer state, the results will be undefined. + // The solution may be to keep track of the state for each thread + // individually, or not rely on the state and check current context bindings + if(!pBuff->CheckState(D3D11BufferState::ConstantBuffer)) + { + if( pBuff->CheckState(D3D11BufferState::UnorderedAccess) ) { - RefCntAutoPtr<IBuffer> pBuffer; - pResource->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(static_cast<IBuffer**>(&pBuffer)) ); - if( pBuffer ) - { - if( pBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS ) - UnbindResourceFromUAV( pBuffer ); - } - else - { - UNEXPECTED( "Resource \"", pResource->GetDesc().Name, "\" is expected to be a texture or a buffer." ) - } + UnbindResourceFromUAV( pBuff, d3d11CBs[cb] ); + pBuff->ClearState(D3D11BufferState::UnorderedAccess); } - }, - SetSRVMethods, - m_pd3d11DeviceContext ); - dbgVerifyContextSRVs(pShader->GetDesc().ShaderType); - } + pBuff->AddState(D3D11BufferState::ConstantBuffer); + } + } + } +#ifdef _DEBUG + else + { + VERIFY_EXPR(CommitResources) + auto &CB = CachedCBs[cb]; + if( auto *pBuff = const_cast<BufferD3D11Impl*>(CB.pBuff.RawPtr()) ) + { + if (!pBuff->CheckState(D3D11BufferState::ConstantBuffer)) + { + LOG_ERROR_MESSAGE("Buffer \"", pBuff->GetDesc().Name, "\" has not been transitioned to Constant Buffer state. Did you forget to call TransitionResources()?") + } + } + } +#endif - void DeviceContextD3D11Impl::SetD3DSamplers( ShaderD3D11Impl *pShader ) - { - UpdateBoundResources(pShader, m_BoundSamplers, m_BoundD3D11Samplers, - &ShaderD3D11Impl::GetBoundSamplers, - [](const ShaderD3D11Impl::BoundSampler& ){}, // Do nothing - SetSamplerMethods, - m_pd3d11DeviceContext ); - dbgVerifyContextSamplers(pShader->GetDesc().ShaderType); - } + if(CommitResources) + { + bool IsNewCB = CommittedD3D11CBs[cb] != d3d11CBs[cb]; + MinSlot = IsNewCB ? std::min(MinSlot, cb) : MinSlot; + MaxSlot = IsNewCB ? cb : MaxSlot; + CommittedD3D11CBs[cb] = d3d11CBs[cb]; + } + } + + if(CommitResources) + { + if(MinSlot != UINT_MAX) + { + auto SetCBMethod = SetCBMethods[ShaderTypeInd]; + (m_pd3d11DeviceContext->*SetCBMethod)(MinSlot, MaxSlot-MinSlot+1, CommittedD3D11CBs+MinSlot); + m_NumCommittedCBs[ShaderTypeInd] = std::max(m_NumCommittedCBs[ShaderTypeInd], static_cast<Uint8>(NumCBs)); + } - void DeviceContextD3D11Impl::SetD3DUAVs( ShaderD3D11Impl *pShader ) - { - UpdateBoundResources(pShader, m_BoundUAVs, m_BoundD3D11UAVs, - &ShaderD3D11Impl::GetBoundUAVs, - [&](const ShaderD3D11Impl::BoundUAV& BoundUAV) + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedCBs(pShaderD3D11->GetDesc().ShaderType); + } + } + } + + + // Transition and commit Shader Resource Views + auto NumSRVs = ShaderResourceCacheD3D11::UnpackSRVCount(PackedResCounts); + if(NumSRVs) + { + auto *CommittedD3D11SRVs = m_CommittedD3D11SRVs[ShaderTypeInd]; + auto *CommittedD3D11SRVRes = m_CommittedD3D11SRVResources[ShaderTypeInd]; + + UINT MinSlot = UINT_MAX; + UINT MaxSlot = 0; + + for(Uint32 srv=0; srv < NumSRVs; ++srv) + { + VERIFY_EXPR(srv < Cache.GetSRVCount()); + auto &SRVRes = CachedSRVResources[srv]; + // WARNING! This code is not thread-safe. If several threads change + // the resource state, the results will be undefined. + // The solution may be to keep track of the state for each thread + // individually, or not rely on the state and check current context bindings + if( TransitionResources ) + { + if (auto *pTexture = const_cast<TextureBaseD3D11*>(SRVRes.pTexture)) + { + if( !pTexture->CheckState(D3D11TextureState::ShaderResource) ) { - auto *pResource = const_cast<IDeviceObject *>(BoundUAV.pResource.RawPtr()); - RefCntAutoPtr<ITexture> pTexture; - pResource->QueryInterface( IID_Texture, reinterpret_cast<IObject**>( static_cast<ITexture**>(&pTexture) ) ); - if( pTexture ) + if( pTexture->CheckState(D3D11TextureState::UnorderedAccess) ) { - // It is unlikely the texture is not used for input, so do not - // check the bind flags - UnbindTextureFromInput( pTexture ); + UnbindResourceFromUAV(pTexture, SRVRes.pd3d11Resource); + pTexture->ClearState(D3D11TextureState::UnorderedAccess); } - else + if( pTexture->CheckState(D3D11TextureState::RenderTarget) ) + UnbindTextureFromRenderTarget(pTexture); + if( pTexture->CheckState(D3D11TextureState::DepthStencil) ) + UnbindTextureFromDepthStencil(pTexture); + pTexture->ResetState(D3D11TextureState::ShaderResource); + } + } + else if(auto *pBuffer = const_cast<BufferD3D11Impl*>(SRVRes.pBuffer)) + { + if( !pBuffer->CheckState(D3D11BufferState::ShaderResource) ) + { + if( pBuffer->CheckState(D3D11BufferState::UnorderedAccess) ) { - RefCntAutoPtr<IBuffer> pBuffer; - pResource->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(static_cast<IBuffer**>(&pBuffer)) ); - if( pBuffer ) - { - // It is unlikely the buffer is not used for input, so do not - // check the bind flags - UnbindBufferFromInput( pBuffer ); - } - else - { - UNEXPECTED( "Resource \"", pResource->GetDesc().Name, "\" is expected to be a texture or a buffer." ) - } + UnbindResourceFromUAV( pBuffer, SRVRes.pd3d11Resource ); + pBuffer->ClearState(D3D11BufferState::UnorderedAccess); } - }, - [&](Int32 ShaderInd, UINT MinUAVSlot, UINT NumUAVSlots, ID3D11UnorderedAccessView** ppUAVs) + pBuffer->AddState(D3D11BufferState::ShaderResource); + } + } + } +#ifdef _DEBUG + else + { + VERIFY_EXPR(CommitResources) + if (auto *pTexture = const_cast<TextureBaseD3D11*>(SRVRes.pTexture)) + { + if( !pTexture->CheckState(D3D11TextureState::ShaderResource) ) { - switch( ShaderInd ) - { - case 0: // SHADER_TYPE_PIXEL: - UNSUPPORTED( "UAVs are not currently implemented in pixel shader" ); - /// \TODO: need to keep track of bound RTVs and provide the render targets here. - /// Also, we need to unbind UAVs appropriatelly. - /// Maybe deffer actual render target binding to the Draw call()? - m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews( 0, nullptr, nullptr, MinUAVSlot, NumUAVSlots, ppUAVs, nullptr ); - break; - - case 1: //SHADER_TYPE_VERTEX: - case 2: //SHADER_TYPE_GEOMETRY: - case 3: //SHADER_TYPE_DOMAIN: - case 4: //SHADER_TYPE_HULL: - UNSUPPORTED( "UAVs are not currently supported in this type of shader" ); - break; - - case 5: //SHADER_TYPE_COMPUTE: - m_pd3d11DeviceContext->CSSetUnorderedAccessViews( MinUAVSlot, NumUAVSlots, ppUAVs, nullptr ); - break; - - default: UNEXPECTED( "Unknown shader type" ); - } + LOG_ERROR_MESSAGE("Texture \"", pTexture->GetDesc().Name, "\" has not been transitioned to Shader Resource state. Did you forget to call TransitionResources()?") } - ); - dbgVerifyContextUAVs(pShader->GetDesc().ShaderType); - } + } + else if(auto *pBuffer = const_cast<BufferD3D11Impl*>(SRVRes.pBuffer)) + { + if( !pBuffer->CheckState(D3D11BufferState::ShaderResource) ) + { + LOG_ERROR_MESSAGE("Texture \"", pBuffer->GetDesc().Name, "\" has not been transitioned to Shader Resource state. Did you forget to call TransitionResources()?") + } + } + } +#endif - template<typename TD3D11ShaderType, typename TBindShaderMethdType> - void DeviceContextD3D11Impl :: SetD3D11ShaderHelper(Uint32 BoundShaderFlags, - ShaderD3D11Impl* NewShaders[], - SHADER_TYPE ShaderType, - TBindShaderMethdType BindShaderMethod) - { - auto ShaderTypeInd = GetShaderTypeIndex( ShaderType ); - auto &BoundD3D11Shader = m_BoundD3DShaders[ShaderTypeInd]; - auto *pShaderD3D11 = NewShaders[ShaderTypeInd]; - if( BoundShaderFlags & ShaderType ) - { - VERIFY( pShaderD3D11 != nullptr, "Shader is null" ); - VERIFY( pShaderD3D11->GetDesc().ShaderType == ShaderType, "Unexpected shader type" ); - if( BoundD3D11Shader != pShaderD3D11->m_pShader ) + if(CommitResources) + { + bool IsNewSRV = CommittedD3D11SRVs[srv] != d3d11SRVs[srv]; + MinSlot = IsNewSRV ? std::min(MinSlot, srv) : MinSlot; + MaxSlot = IsNewSRV ? srv : MaxSlot; + + CommittedD3D11SRVRes[srv] = SRVRes.pd3d11Resource; + CommittedD3D11SRVs[srv] = d3d11SRVs[srv]; + } + } + + if(CommitResources) + { + if(MinSlot != UINT_MAX) + { + auto SetSRVMethod = SetSRVMethods[ShaderTypeInd]; + (m_pd3d11DeviceContext->*SetSRVMethod)(MinSlot, MaxSlot-MinSlot+1, CommittedD3D11SRVs+MinSlot); + m_NumCommittedSRVs[ShaderTypeInd] = std::max(m_NumCommittedSRVs[ShaderTypeInd], static_cast<Uint8>(NumSRVs)); + } + + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedSRVs(pShaderD3D11->GetDesc().ShaderType); + } + } + } + + + // Commit samplers (no transitions for samplers) + if(CommitResources) { - BoundD3D11Shader = pShaderD3D11->m_pShader; - RefCntAutoPtr<TD3D11ShaderType> pd3d11Shader; - pShaderD3D11->m_pShader->QueryInterface(__uuidof(TD3D11ShaderType), reinterpret_cast<void**>( static_cast<TD3D11ShaderType**>(&pd3d11Shader) ) ); - (m_pd3d11DeviceContext->*BindShaderMethod)(pd3d11Shader, nullptr, 0); + auto NumSamplers = ShaderResourceCacheD3D11::UnpackSamplerCount(PackedResCounts); + if(NumSamplers) + { + auto *CommittedD3D11Samplers = m_CommittedD3D11Samplers[ShaderTypeInd]; + UINT MinSlot = std::numeric_limits<UINT>::max(); + UINT MaxSlot = 0; + for(Uint32 sam=0; sam < NumSamplers; ++sam) + { + VERIFY_EXPR(sam < Cache.GetSamplerCount()); + + bool IsNewSam = CommittedD3D11Samplers[sam] != d3d11Samplers[sam]; + MinSlot = IsNewSam ? std::min(MinSlot, sam) : MinSlot; + MaxSlot = IsNewSam ? sam : MaxSlot; + + CommittedD3D11Samplers[sam] = d3d11Samplers[sam]; + } + + if(MinSlot != UINT_MAX) + { + auto SetSamplerMethod = SetSamplerMethods[ShaderTypeInd]; + (m_pd3d11DeviceContext->*SetSamplerMethod)(MinSlot, MaxSlot-MinSlot+1, CommittedD3D11Samplers+MinSlot); + m_NumCommittedSamplers[ShaderTypeInd] = std::max(m_NumCommittedSamplers[ShaderTypeInd], static_cast<Uint8>(NumSamplers)); + } + + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedSamplers(pShaderD3D11->GetDesc().ShaderType); + } + } } - } - else - { - if( BoundD3D11Shader != nullptr ) + + + // Commit Unordered Access Views + auto NumUAVs = ShaderResourceCacheD3D11::UnpackUAVCount(PackedResCounts); + if(NumUAVs) + { + auto *CommittedD3D11UAVs = m_CommittedD3D11UAVs[ShaderTypeInd]; + auto *CommittedD3D11UAVRes = m_CommittedD3D11UAVResources[ShaderTypeInd]; + + UINT MinSlot = UINT_MAX; + UINT MaxSlot = 0; + + for(Uint32 uav=0; uav < NumUAVs; ++uav) + { + VERIFY_EXPR(uav < Cache.GetUAVCount()); + auto &UAVRes = CachedUAVResources[uav]; + // WARNING! This code is not thread-safe. If several threads change + // the resource state, the results will be undefined. + // The solution may be to keep track of the state for each thread + // individually, or not rely on the state and check current context bindings + if(TransitionResources) + { + if ( auto* pTexture = const_cast<TextureBaseD3D11*>(UAVRes.pTexture) ) + { + if( !pTexture->CheckState(D3D11TextureState::UnorderedAccess) ) + { + if( pTexture->CheckState(D3D11TextureState::ShaderResource) ) + UnbindTextureFromInput( pTexture, UAVRes.pd3d11Resource ); + pTexture->ResetState(D3D11TextureState::UnorderedAccess); + } + } + else if( auto *pBuffer = const_cast<BufferD3D11Impl*>(UAVRes.pBuffer) ) + { + if( !pBuffer->CheckState(D3D11BufferState::UnorderedAccess) ) + { + if( pBuffer->CheckState(D3D11BufferState::AnyInput) ) + UnbindBufferFromInput( pBuffer, UAVRes.pd3d11Resource ); + pBuffer->ResetState(D3D11BufferState::UnorderedAccess); + } + } + } +#ifdef _DEBUG + else + { + if ( auto* pTexture = const_cast<TextureBaseD3D11*>(UAVRes.pTexture) ) + { + if( !pTexture->CheckState(D3D11TextureState::UnorderedAccess) ) + { + LOG_ERROR_MESSAGE("Texture \"", pTexture->GetDesc().Name, "\" has not been transitioned to Unordered Access state. Did you forget to call TransitionResources()?") + } + } + else if( auto *pBuffer = const_cast<BufferD3D11Impl*>(UAVRes.pBuffer) ) + { + if( !pBuffer->CheckState(D3D11BufferState::UnorderedAccess) ) + { + LOG_ERROR_MESSAGE("Buffer \"", pBuffer->GetDesc().Name, "\" has not been transitioned to Unordered Access state. Did you forget to call TransitionResources()?") + } + } + } +#endif + if(CommitResources) + { + bool IsNewUAV = CommittedD3D11UAVs[uav] != d3d11UAVs[uav]; + MinSlot = IsNewUAV ? std::min(MinSlot, uav) : MinSlot; + MaxSlot = IsNewUAV ? uav : MaxSlot; + + CommittedD3D11UAVRes[uav] = UAVRes.pd3d11Resource; + CommittedD3D11UAVs[uav] = d3d11UAVs[uav]; + } + } + + if(CommitResources) + { + if(MinSlot != UINT_MAX) + { + auto SetUAVMethod = SetUAVMethods[ShaderTypeInd]; + (m_pd3d11DeviceContext->*SetUAVMethod)(MinSlot, MaxSlot-MinSlot+1, CommittedD3D11UAVs+MinSlot, nullptr); + m_NumCommittedUAVs[ShaderTypeInd] = std::max(m_NumCommittedUAVs[ShaderTypeInd], static_cast<Uint8>(NumUAVs)); + } + + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedUAVs(pShaderD3D11->GetDesc().ShaderType); + } + } + } + +#ifdef VERIFY_SHADER_BINDINGS + if( CommitResources && m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedShaderResources ) { - BoundD3D11Shader = nullptr; - (m_pd3d11DeviceContext->*BindShaderMethod)(nullptr, nullptr, 0); + // Use full resource layout to verify that all required resources are committed + pShaderD3D11->GetResources()->dbgVerifyCommittedResources( + m_CommittedD3D11CBs[ShaderTypeInd], + m_CommittedD3D11SRVs[ShaderTypeInd], + m_CommittedD3D11SRVResources[ShaderTypeInd], + m_CommittedD3D11Samplers[ShaderTypeInd], + m_CommittedD3D11UAVs[ShaderTypeInd], + m_CommittedD3D11UAVResources[ShaderTypeInd], + Cache); } +#endif } } - void DeviceContextD3D11Impl :: SetD3DShadersAndResources() + void DeviceContextD3D11Impl::TransitionShaderResources(IPipelineState *pPipelineState, IShaderResourceBinding *pShaderResourceBinding) { - Uint32 BoundShaderFlags = 0; - // Set shaders - ShaderD3D11Impl* NewShaders[NumShaderTypes] = {}; - for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end(); ++it ) - { - auto *pCurrShader = it->RawPtr(); - if( pCurrShader ) - { - auto ShaderType = pCurrShader->GetDesc().ShaderType; - auto *pShaderD3D11 = static_cast<ShaderD3D11Impl*>(pCurrShader); - auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); - NewShaders[ShaderTypeInd] = pShaderD3D11; + TransitionAndCommitShaderResources<true, false>(pPipelineState, pShaderResourceBinding); + } - if( BoundShaderFlags & ShaderType ) - LOG_ERROR_MESSAGE( "More than one shader of type ", GetShaderTypeLiteralName(ShaderType), " is bound to the context" ) - BoundShaderFlags |= ShaderType; + void DeviceContextD3D11Impl::CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags) + { + if( !DeviceContextBase::CommitShaderResources(pShaderResourceBinding, Flags, 0 /*Dummy*/) ) + return; -#ifdef VERIFY_SHADER_BINDINGS - pShaderD3D11->dbgVerifyBindings(); -#endif + if(Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES) + TransitionAndCommitShaderResources<true, true>(m_pPipelineState, pShaderResourceBinding); + else + TransitionAndCommitShaderResources<false, true>(m_pPipelineState, pShaderResourceBinding); + } - // Set D3D11 shader resources - SetD3DConstantBuffers ( pShaderD3D11 ); - SetD3DSRVs ( pShaderD3D11 ); - SetD3DSamplers ( pShaderD3D11 ); - SetD3DUAVs ( pShaderD3D11 ); - } + void DeviceContextD3D11Impl::SetStencilRef(Uint32 StencilRef) + { + if (TDeviceContextBase::SetStencilRef(StencilRef, 0)) + { + ID3D11DepthStencilState *pd3d11DSS = m_pPipelineState ? ValidatedCast<PipelineStateD3D11Impl>(m_pPipelineState.RawPtr())->GetD3D11DepthStencilState() : nullptr; + m_pd3d11DeviceContext->OMSetDepthStencilState( pd3d11DSS, m_StencilRef ); } - - // There is no need to unbind the compute shader from the context - //if( BoundShaderFlags & SHADER_TYPE_COMPUTE ) - //{ - // LOG_ERROR_MESSAGE( "Bound compute shader will be ignored by the draw command" ) - // BoundShaderFlags &= ~SHADER_TYPE_COMPUTE; - //} + } -#define SET_SHADER(NAME, Name, N) SetD3D11ShaderHelper<ID3D11##Name##Shader>(BoundShaderFlags, NewShaders, SHADER_TYPE_##NAME, &ID3D11DeviceContext::N##SSetShader ) - // These shaders which are not set will be unbound from the D3D11 device context - SET_SHADER( VERTEX, Vertex, V ); - SET_SHADER( PIXEL, Pixel, P ); - SET_SHADER( GEOMETRY, Geometry, G ); - SET_SHADER( DOMAIN, Domain, D ); - SET_SHADER( HULL, Hull, H ); - // There is no need to unbind the compute shader from the context - //SET_SHADER( COMPUTE, Compute, C ); + void DeviceContextD3D11Impl::SetBlendFactors(const float* pBlendFactors) + { + if (TDeviceContextBase::SetBlendFactors(pBlendFactors, 0)) + { + Uint32 SampleMask = 0xFFFFFFFF; + ID3D11BlendState *pd3d11BS = nullptr; + if(m_pPipelineState) + { + SampleMask = m_pPipelineState->GetDesc().GraphicsPipeline.SampleMask; + pd3d11BS = ValidatedCast<PipelineStateD3D11Impl>(m_pPipelineState.RawPtr())->GetD3D11BlendState(); + } + m_pd3d11DeviceContext->OMSetBlendState(pd3d11BS, m_BlendFactors, SampleMask); + } } - void DeviceContextD3D11Impl::SetD3DIndexBuffer(VALUE_TYPE IndexType) + void DeviceContextD3D11Impl::CommitD3D11IndexBuffer(VALUE_TYPE IndexType) { if( !m_pIndexBuffer ) { LOG_ERROR_MESSAGE( "Index buffer is not set up for indexed draw command" ); return; } + BufferD3D11Impl *pBuffD3D11 = static_cast<BufferD3D11Impl *>(m_pIndexBuffer.RawPtr()); - DXGI_FORMAT D3D11IndexFmt = DXGI_FORMAT_UNKNOWN; - if( IndexType == VT_UINT32 ) - D3D11IndexFmt = DXGI_FORMAT_R32_UINT; - else if( IndexType == VT_UINT16 ) - D3D11IndexFmt = DXGI_FORMAT_R16_UINT; - else + if( pBuffD3D11->CheckState( D3D11BufferState::UnorderedAccess ) ) { - LOG_ERROR_MESSAGE( "Unsupported index format. Only R16_UINT and R32_UINT are allowed." ); - return; + UnbindResourceFromUAV(pBuffD3D11, pBuffD3D11->m_pd3d11Buffer); + pBuffD3D11->ClearState( D3D11BufferState::UnorderedAccess ); } - if( m_pIndexBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS ) - UnbindResourceFromUAV(m_pIndexBuffer); - if( m_BoundD3D11IndexBuffer != pBuffD3D11->m_pd3d11Buffer || - m_BoundD3D11IndexFmt != D3D11IndexFmt || - m_BoundD3D11IndexDataStartOffset != m_IndexDataStartOffset ) + if( m_CommittedD3D11IndexBuffer != pBuffD3D11->m_pd3d11Buffer || + m_CommittedIBFormat != IndexType || + m_CommittedD3D11IndexDataStartOffset != m_IndexDataStartOffset ) { - m_BoundD3D11IndexBuffer = pBuffD3D11->m_pd3d11Buffer; - m_BoundD3D11IndexFmt = D3D11IndexFmt; - m_BoundD3D11IndexDataStartOffset = m_IndexDataStartOffset; + DXGI_FORMAT D3D11IndexFmt = DXGI_FORMAT_UNKNOWN; + if( IndexType == VT_UINT32 ) + D3D11IndexFmt = DXGI_FORMAT_R32_UINT; + else if( IndexType == VT_UINT16 ) + D3D11IndexFmt = DXGI_FORMAT_R16_UINT; + else + { + LOG_ERROR_MESSAGE( "Unsupported index format. Only R16_UINT and R32_UINT are allowed." ); + return; + } + + m_CommittedD3D11IndexBuffer = pBuffD3D11->m_pd3d11Buffer; + m_CommittedIBFormat = IndexType; + m_CommittedD3D11IndexDataStartOffset = m_IndexDataStartOffset; m_pd3d11DeviceContext->IASetIndexBuffer( pBuffD3D11->m_pd3d11Buffer, D3D11IndexFmt, m_IndexDataStartOffset ); } + + pBuffD3D11->AddState(D3D11BufferState::IndexBuffer); + m_bCommittedD3D11IBUpToDate = true; } - void DeviceContextD3D11Impl::SetD3DVertexBuffers() + void DeviceContextD3D11Impl::CommitD3D11VertexBuffers(PipelineStateD3D11Impl *pPipelineStateD3D11) { - auto &VertexDescSP = m_pVertexDesc; - if( !VertexDescSP ) - { - // There might be no vertex description if, for instance, full screen quad - // is rendered - m_pd3d11DeviceContext->IASetInputLayout( nullptr ); - return; - } - auto* pVertexDescD3D11 = static_cast<VertexDescD3D11Impl *>(VertexDescSP.RawPtr()); - m_pd3d11DeviceContext->IASetInputLayout( pVertexDescD3D11->m_pd3d11InputLayout ); - - ID3D11Buffer *ppD3D11Buffers[MaxBufferSlots] = { nullptr }; - UINT Strides[MaxBufferSlots] = { 0 }; - UINT Offsets[MaxBufferSlots] = { 0 }; - UINT NumBoundBuffers = static_cast<UINT>(m_VertexStreams.size()); - VERIFY( NumBoundBuffers <= MaxBufferSlots, "Too many buffers are being set" ); - NumBoundBuffers = std::min( NumBoundBuffers, static_cast<UINT>(MaxBufferSlots) ); - const auto *TightStrides = VertexDescSP->GetTightStrides(); - for( UINT Buff = 0; Buff < NumBoundBuffers; ++Buff ) + VERIFY( m_NumVertexStreams <= MaxBufferSlots, "Too many buffers are being set" ); + UINT NumBuffersToSet = std::max(m_NumVertexStreams, m_NumCommittedD3D11VBs ); + + bool BindVBs = m_NumVertexStreams != m_NumCommittedD3D11VBs; + + const auto *TightStrides = pPipelineStateD3D11->GetTightStrides(); + for( UINT Slot = 0; Slot < m_NumVertexStreams; ++Slot ) { - auto &CurrStream = m_VertexStreams[Buff]; + auto &CurrStream = m_VertexStreams[Slot]; VERIFY( CurrStream.pBuffer, "Attempting to bind a null buffer for rendering" ); - ppD3D11Buffers[Buff] = static_cast<BufferD3D11Impl*>(CurrStream.pBuffer.RawPtr())->m_pd3d11Buffer; - Strides[Buff] = CurrStream.Stride ? CurrStream.Stride : TightStrides[Buff]; - Offsets[Buff] = CurrStream.Offset; - if(CurrStream.pBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS) - UnbindResourceFromUAV(CurrStream.pBuffer); - } + auto *pBuffD3D11Impl = ValidatedCast<BufferD3D11Impl>(CurrStream.pBuffer.RawPtr()); + ID3D11Buffer *pd3d11Buffer = pBuffD3D11Impl->m_pd3d11Buffer; + auto Stride = CurrStream.Stride ? CurrStream.Stride : TightStrides[Slot]; + auto Offset = CurrStream.Offset; - UINT NumBuffersToSet = NumBoundBuffers; - bool BindVBs = false; - if( NumBoundBuffers != m_BoundD3D11VertexBuffers.size() ) - { - // If number of currently bound d3d11 buffers is larger than NumBuffersToSet, the - // unused buffers will be unbound - NumBuffersToSet = std::max(NumBuffersToSet, static_cast<UINT>(m_BoundD3D11VertexBuffers.size()) ); - m_BoundD3D11VertexBuffers.resize(NumBoundBuffers); - m_BoundD3D11VBStrides.resize(NumBoundBuffers); - m_BoundD3D11VBOffsets.resize( NumBoundBuffers ); - BindVBs = true; - } + if(pBuffD3D11Impl->CheckState( D3D11BufferState::UnorderedAccess )) + { + UnbindResourceFromUAV(pBuffD3D11Impl, pd3d11Buffer); + pBuffD3D11Impl->ClearState( D3D11BufferState::UnorderedAccess ); + } - for( UINT Slot = 0; Slot < NumBoundBuffers; ++Slot ) - { - if( m_BoundD3D11VertexBuffers[Slot] != ppD3D11Buffers[Slot] || - m_BoundD3D11VBStrides[Slot] != Strides[Slot] || - m_BoundD3D11VBOffsets[Slot] != Offsets[Slot] ) + // It is safe to perform raw pointer check because device context keeps + // all buffers alive. + if (m_CommittedD3D11VertexBuffers[Slot] != pd3d11Buffer || + m_CommittedD3D11VBStrides[Slot] != Stride || + m_CommittedD3D11VBOffsets[Slot] != Offset) { BindVBs = true; - m_BoundD3D11VertexBuffers[Slot] = ppD3D11Buffers[Slot]; - m_BoundD3D11VBStrides[Slot] = Strides[Slot]; - m_BoundD3D11VBOffsets[Slot] = Offsets[Slot]; + m_CommittedD3D11VertexBuffers[Slot] = pd3d11Buffer; + m_CommittedD3D11VBStrides[Slot] = Stride; + m_CommittedD3D11VBOffsets[Slot] = Offset; + + pBuffD3D11Impl->AddState( D3D11BufferState::VertexBuffer ); } } + // Unbind all buffers at the end + for (Uint32 Slot = m_NumVertexStreams; Slot < m_NumCommittedD3D11VBs; ++Slot) + { + m_CommittedD3D11VertexBuffers[Slot] = nullptr; + m_CommittedD3D11VBStrides[Slot] = 0; + m_CommittedD3D11VBOffsets[Slot] = 0; + } + + m_NumCommittedD3D11VBs = m_NumVertexStreams; + if( BindVBs ) { - m_pd3d11DeviceContext->IASetVertexBuffers( 0, NumBuffersToSet, ppD3D11Buffers, Strides, Offsets ); + m_pd3d11DeviceContext->IASetVertexBuffers( 0, NumBuffersToSet, m_CommittedD3D11VertexBuffers, m_CommittedD3D11VBStrides, m_CommittedD3D11VBOffsets ); } + + m_bCommittedD3D11VBsUpToDate = true; } void DeviceContextD3D11Impl::Draw( DrawAttribs &DrawAttribs ) { - m_LastDrawAttribs = DrawAttribs; +#ifdef _DEBUG + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound"); + return; + } +#endif - SetD3DShadersAndResources(); - - SetD3DVertexBuffers(); + auto *pPipelineStateD3D11 = ValidatedCast<PipelineStateD3D11Impl>(m_pPipelineState.RawPtr()); +#ifdef _DEBUG + if (pPipelineStateD3D11->GetDesc().IsComputePipeline) + { + LOG_ERROR("No graphics pipeline state is bound"); + return; + } +#endif + + auto *pd3d11InputLayout = pPipelineStateD3D11->GetD3D11InputLayout(); + // It is safe to perform raw pointer comparison as the device context + // keeps bound input layout alive + if( m_CommittedD3D11InputLayout != pd3d11InputLayout ) + { + m_pd3d11DeviceContext->IASetInputLayout( pd3d11InputLayout ); + m_CommittedD3D11InputLayout = pd3d11InputLayout; + } + + if( pd3d11InputLayout != nullptr && !m_bCommittedD3D11VBsUpToDate ) + { + CommitD3D11VertexBuffers(pPipelineStateD3D11); + } if( DrawAttribs.IsIndexed ) { - SetD3DIndexBuffer(DrawAttribs.IndexType); + if( m_CommittedIBFormat != DrawAttribs.IndexType ) + m_bCommittedD3D11IBUpToDate = false; + if(!m_bCommittedD3D11IBUpToDate) + { + CommitD3D11IndexBuffer(DrawAttribs.IndexType); + } } - // Verify bindings after all resources are set - dbgVerifyContextSRVs(); - dbgVerifyContextUAVs(); - dbgVerifyContextSamplers(); - dbgVerifyContextCBs(); - dbgVerifyVertexBuffers(); - dbgVerifyIndexBuffer(); - dbgVerifyShaders(); - - auto D3D11Topology = TopologyToDX11Topology( DrawAttribs.Topology ); - m_pd3d11DeviceContext->IASetPrimitiveTopology( D3D11Topology ); +#ifdef _DEBUG + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + // Verify bindings after all resources are set + dbgVerifyRenderTargetFormats(); + dbgVerifyCommittedSRVs(); + dbgVerifyCommittedUAVs(); + dbgVerifyCommittedSamplers(); + dbgVerifyCommittedCBs(); + dbgVerifyCommittedVertexBuffers(); + dbgVerifyCommittedIndexBuffer(); + dbgVerifyCommittedShaders(); + } +#endif + + if(m_CommittedPrimitiveTopology != DrawAttribs.Topology) + { + m_CommittedPrimitiveTopology = DrawAttribs.Topology; + m_CommittedD3D11PrimTopology = TopologyToD3D11Topology( DrawAttribs.Topology ); + m_pd3d11DeviceContext->IASetPrimitiveTopology( m_CommittedD3D11PrimTopology ); + } if( DrawAttribs.IsIndirect ) { VERIFY( DrawAttribs.pIndirectDrawAttribs, "Indirect draw command attributes buffer is not set" ); auto *pBufferD3D11 = static_cast<BufferD3D11Impl*>(DrawAttribs.pIndirectDrawAttribs); - ID3D11Buffer *pd3d11ArgsBuff = pBufferD3D11 ? pBufferD3D11->m_pd3d11Buffer.RawPtr() : nullptr; + ID3D11Buffer *pd3d11ArgsBuff = pBufferD3D11 ? pBufferD3D11->m_pd3d11Buffer : nullptr; if( DrawAttribs.IsIndexed ) m_pd3d11DeviceContext->DrawIndexedInstancedIndirect( pd3d11ArgsBuff, DrawAttribs.IndirectDrawArgsOffset ); else @@ -633,44 +745,26 @@ namespace Diligent void DeviceContextD3D11Impl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) { - bool bCSBound = false; - ShaderD3D11Impl* NewShaders[NumShaderTypes] = {}; - for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end() && !bCSBound; ++it ) + if (!m_pPipelineState) { - auto *pCurrShader = it->RawPtr(); - if( pCurrShader && pCurrShader->GetDesc().ShaderType == SHADER_TYPE_COMPUTE ) - { - bCSBound = true; - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>(pCurrShader); - NewShaders[GetShaderTypeIndex(SHADER_TYPE_COMPUTE)] = pShaderD3D11; - SetD3D11ShaderHelper<ID3D11ComputeShader>( SHADER_TYPE_COMPUTE, NewShaders, SHADER_TYPE_COMPUTE, &ID3D11DeviceContext::CSSetShader ); - -#ifdef VERIFY_SHADER_BINDINGS - pShaderD3D11->dbgVerifyBindings(); -#endif - - // Set requried shader resources - SetD3DConstantBuffers ( pShaderD3D11 ); - SetD3DSRVs ( pShaderD3D11 ); - SetD3DSamplers ( pShaderD3D11 ); - SetD3DUAVs ( pShaderD3D11 ); - - break; - } + LOG_ERROR("No pipeline state is bound"); + return; } - - if( !bCSBound ) + if (!m_pPipelineState->GetDesc().IsComputePipeline) { - LOG_ERROR_MESSAGE( "Compute shader is not bound to the pipeline" ); + LOG_ERROR("No compute pipeline state is bound"); return; } - // Verify bindings - dbgVerifyContextSRVs(); - dbgVerifyContextUAVs(); - dbgVerifyContextSamplers(); - dbgVerifyContextCBs(); - dbgVerifyShaders(); + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + // Verify bindings + dbgVerifyCommittedSRVs(); + dbgVerifyCommittedUAVs(); + dbgVerifyCommittedSamplers(); + dbgVerifyCommittedCBs(); + dbgVerifyCommittedShaders(); + } if( DispatchAttrs.pIndirectDispatchAttribs ) { @@ -687,10 +781,11 @@ namespace Diligent ID3D11DepthStencilView *pd3d11DSV = nullptr; if( pView != nullptr ) { +#ifdef _DEBUG const auto& ViewDesc = pView->GetDesc(); VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); - CHECK_DYNAMIC_TYPE( TextureViewD3D11Impl, pView ); - auto *pViewD3D11 = static_cast<TextureViewD3D11Impl*>(pView); +#endif + auto *pViewD3D11 = ValidatedCast<TextureViewD3D11Impl>(pView); pd3d11DSV = static_cast<ID3D11DepthStencilView *>(pViewD3D11->GetD3D11View()); } else @@ -710,10 +805,11 @@ namespace Diligent ID3D11RenderTargetView *pd3d11RTV = nullptr; if( pView != nullptr ) { +#ifdef _DEBUG const auto& ViewDesc = pView->GetDesc(); VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); - CHECK_DYNAMIC_TYPE( TextureViewD3D11Impl, pView ); - auto *pViewD3D11 = static_cast<TextureViewD3D11Impl*>(pView); +#endif + auto *pViewD3D11 = ValidatedCast<TextureViewD3D11Impl>(pView); pd3d11RTV = static_cast<ID3D11RenderTargetView*>(pViewD3D11->GetD3D11View()); } else @@ -738,6 +834,7 @@ namespace Diligent void DeviceContextD3D11Impl::SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) { TDeviceContextBase::SetVertexBuffers( StartSlot, NumBuffersSet, ppBuffers, pStrides, pOffsets, Flags ); + m_bCommittedD3D11VBsUpToDate = false; } void DeviceContextD3D11Impl::ClearState() @@ -746,47 +843,10 @@ namespace Diligent } - void DeviceContextD3D11Impl::SetVertexDescription( IVertexDescription *pVertexDesc ) - { - TDeviceContextBase::SetVertexDescription( pVertexDesc ); - } - void DeviceContextD3D11Impl::SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) { TDeviceContextBase::SetIndexBuffer( pIndexBuffer, ByteOffset ); - } - - void DeviceContextD3D11Impl::SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef ) - { - if( TDeviceContextBase::SetDepthStencilState( pDepthStencilState, StencilRef ) ) - { - CHECK_DYNAMIC_TYPE( DSStateD3D11Impl, pDepthStencilState ); - auto *pDSSD3D11 = static_cast<DSStateD3D11Impl*>(pDepthStencilState); - auto *pd3d11DSS = pDSSD3D11->GetD3D11DepthStencilState(); - m_pd3d11DeviceContext->OMSetDepthStencilState( pd3d11DSS, StencilRef ); - } - } - - void DeviceContextD3D11Impl::SetRasterizerState( IRasterizerState *pRasterizerState ) - { - if( TDeviceContextBase::SetRasterizerState( pRasterizerState ) ) - { - CHECK_DYNAMIC_TYPE( RasterizerStateD3D11Impl, pRasterizerState ); - auto *pRSD3D11 = static_cast<RasterizerStateD3D11Impl*>(pRasterizerState); - auto *pd3d11RS = pRSD3D11->GetD3D11RasterizerState(); - m_pd3d11DeviceContext->RSSetState( pd3d11RS ); - } - } - - void DeviceContextD3D11Impl::SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask ) - { - if( TDeviceContextBase::SetBlendState( pBS, pBlendFactors, SampleMask ) ) - { - CHECK_DYNAMIC_TYPE( BlendStateD3D11Impl, pBS ); - auto *pBSD3D11 = static_cast<BlendStateD3D11Impl*>(pBS); - auto *pd3d11BS = pBSD3D11->GetD3D11BlendState(); - m_pd3d11DeviceContext->OMSetBlendState( pd3d11BS, m_BlendFactors, SampleMask ); - } + m_bCommittedD3D11IBUpToDate = false; } void DeviceContextD3D11Impl::SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight ) @@ -798,8 +858,8 @@ namespace Diligent TDeviceContextBase::SetViewports( NumViewports, pViewports, RTWidth, RTHeight ); D3D11_VIEWPORT d3d11Viewports[MaxViewports]; - VERIFY( NumViewports == m_Viewports.size(), "Unexpected number of viewports" ); - for( Uint32 vp = 0; vp < NumViewports; ++vp ) + VERIFY( NumViewports == m_NumViewports, "Unexpected number of viewports" ); + for( Uint32 vp = 0; vp < m_NumViewports; ++vp ) { d3d11Viewports[vp].TopLeftX = m_Viewports[vp].TopLeftX; d3d11Viewports[vp].TopLeftY = m_Viewports[vp].TopLeftY; @@ -822,7 +882,7 @@ namespace Diligent TDeviceContextBase::SetScissorRects(NumRects, pRects, RTWidth, RTHeight); D3D11_RECT d3d11ScissorRects[MaxScissorRects]; - VERIFY( NumRects == m_ScissorRects.size(), "Unexpected number of scissor rects" ); + VERIFY( NumRects == m_NumScissorRects, "Unexpected number of scissor rects" ); for( Uint32 sr = 0; sr < NumRects; ++sr ) { d3d11ScissorRects[sr].left = m_ScissorRects[sr].left; @@ -839,7 +899,7 @@ namespace Diligent void DeviceContextD3D11Impl::RebindRenderTargets() { const Uint32 MaxD3D11RTs = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; - Uint32 NumRenderTargets = static_cast<Uint32>( m_pBoundRenderTargets.size() ); + Uint32 NumRenderTargets = m_NumBoundRenderTargets; VERIFY( NumRenderTargets <= MaxD3D11RTs, "D3D11 only allows 8 simultaneous render targets" ); NumRenderTargets = std::min( MaxD3D11RTs, NumRenderTargets ); @@ -878,6 +938,7 @@ namespace Diligent m_pd3d11DeviceContext->OMSetRenderTargets(NumRenderTargets, pd3d11RTs, pd3d11DSV); } + void UnbindView( ID3D11DeviceContext *pContext, TSetShaderResourcesType SetSRVMethod, UINT Slot ) { ID3D11ShaderResourceView *ppNullView[] = { nullptr }; @@ -890,36 +951,37 @@ namespace Diligent (pContext->*SetUAVMethod)(Slot, 1, ppNullView, nullptr); } - /// \tparam TBoundResourceType - Type of the struct describing resources associated with the - /// bound entity (ShaderD3D11Impl::BoundCB, ShaderD3D11Impl::BoundSRV, etc.) - /// \tparam TD3D11ResourceType - Type of the D3D11 resource (ID3D11ShaderResourceView or ID3D11UnorderedAccessView) + /// \tparam TD3D11ResourceViewType - Type of the D3D11 resource view (ID3D11ShaderResourceView or ID3D11UnorderedAccessView) /// \tparam TSetD3D11View - Type of the D3D11 device context method used to set the D3D11 view - /// \param BoundResourcesArr - Pointer to the array of strong references to currently bound + /// \param CommittedResourcesArr - Pointer to the array of strong references to currently bound /// shader resources, for each shader stage - /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 + /// \param CommittedD3D11ResourcesArr - Pointer to the array of currently bound D3D11 /// shader resources, for each shader stage /// \param pResToUnbind - Resource to unbind /// \param SetD3D11ViewMethods - Array of pointers to device context methods used to set the view, /// for every shader stage - template<typename TBoundResourceType, - typename TD3D11ResourceType, - typename TSetD3D11View> - void DeviceContextD3D11Impl::UnbindResourceView(std::vector<TBoundResourceType> BoundResourcesArr[], - std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], + template<typename TD3D11ResourceViewType, + typename TSetD3D11View, + size_t NumSlots> + void DeviceContextD3D11Impl::UnbindResourceView( TD3D11ResourceViewType CommittedD3D11ViewsArr[][NumSlots], + ID3D11Resource* CommittedD3D11ResourcesArr[][NumSlots], + Uint8 NumCommittedResourcesArr[], IDeviceObject *pResToUnbind, + ID3D11Resource *pd3d11ResToUndind, TSetD3D11View SetD3D11ViewMethods[]) { for( Int32 ShaderTypeInd = 0; ShaderTypeInd < NumShaderTypes; ++ShaderTypeInd ) { - auto &BoundResources = BoundResourcesArr[ShaderTypeInd]; - auto &BoundD3D11Views = BoundD3D11ResourcesArr[ShaderTypeInd]; - VERIFY( BoundResources.size() == BoundD3D11Views.size(), "Inconsistent shader resource view array sizes" ); - for( Uint32 Slot = 0; Slot < BoundResources.size(); ++Slot ) + auto *CommittedD3D11Views = CommittedD3D11ViewsArr[ShaderTypeInd]; + auto *CommittedD3D11Resources = CommittedD3D11ResourcesArr[ShaderTypeInd]; + auto &NumCommittedSlots = NumCommittedResourcesArr[ShaderTypeInd]; + + for( Uint32 Slot = 0; Slot < NumCommittedSlots; ++Slot ) { - if( BoundResources[Slot].pResource == pResToUnbind ) + if( CommittedD3D11Resources[Slot] == pd3d11ResToUndind ) { - BoundResources[Slot] = TBoundResourceType(); - BoundD3D11Views[Slot] = nullptr; + CommittedD3D11Resources[Slot] = nullptr; + CommittedD3D11Views[Slot] = nullptr; auto SetViewMethod = SetD3D11ViewMethods[ShaderTypeInd]; UnbindView( m_pd3d11DeviceContext, SetViewMethod, Slot ); @@ -927,118 +989,126 @@ namespace Diligent } // Pop null resources from the end of arrays - while( BoundD3D11Views.size() > 0 && BoundD3D11Views.back() == nullptr ) + while( NumCommittedSlots > 0 && CommittedD3D11Resources[NumCommittedSlots-1] == nullptr ) { - BoundD3D11Views.pop_back(); - VERIFY( BoundResources.back().pResource == nullptr, "Unexpected non-null resource detected" ) - VERIFY( BoundResources.back().pView == nullptr, "Unexpected non-null resource view detected" ) - VERIFY( BoundResources.back().pd3d11View == nullptr, "Unexpected non-null D3D11 resource view detected" ) - BoundResources.pop_back(); + VERIFY( CommittedD3D11Views[NumSlots-1] == nullptr, "Unexpected non-null resource view" ) + --NumCommittedSlots; } - VERIFY(BoundResources.size() == BoundD3D11Views.size(), "Inconsistent array size") } } - void DeviceContextD3D11Impl::UnbindTextureFromInput( ITexture *pTexture ) + void DeviceContextD3D11Impl::UnbindTextureFromInput( TextureBaseD3D11 *pTexture, ID3D11Resource *pd3d11Resource ) { VERIFY( pTexture, "Null texture provided" ) if( !pTexture )return; - UnbindResourceView( m_BoundSRVs, m_BoundD3D11SRVs, pTexture, SetSRVMethods ); + UnbindResourceView( m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, pTexture, pd3d11Resource, SetSRVMethods ); + pTexture->ClearState(D3D11TextureState::ShaderResource); } - void DeviceContextD3D11Impl::UnbindBufferFromInput( IBuffer *pBuffer ) + void DeviceContextD3D11Impl::UnbindBufferFromInput( BufferD3D11Impl *pBuffer, ID3D11Resource *pd3d11Buffer ) { VERIFY( pBuffer, "Null buffer provided" ) if( !pBuffer )return; - UnbindResourceView( m_BoundSRVs, m_BoundD3D11SRVs, pBuffer, SetSRVMethods ); + if( pBuffer->CheckState(D3D11BufferState::ShaderResource) ) + { + UnbindResourceView( m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, pBuffer, pd3d11Buffer, SetSRVMethods ); + pBuffer->ClearState( D3D11BufferState::ShaderResource ); + } - auto BuffBindFlags = pBuffer->GetDesc().BindFlags; - - if( (BuffBindFlags & BIND_INDEX_BUFFER) && m_BoundD3D11IndexBuffer ) + if( pBuffer->CheckState(D3D11BufferState::IndexBuffer) ) { auto pd3d11IndBuffer = ValidatedCast<BufferD3D11Impl>( pBuffer )->GetD3D11Buffer(); - if( pd3d11IndBuffer == m_BoundD3D11IndexBuffer ) + if( pd3d11IndBuffer == m_CommittedD3D11IndexBuffer ) { // Only unbind D3D11 buffer from the context! // m_pIndexBuffer.Release(); - m_BoundD3D11IndexBuffer.Release(); - m_BoundD3D11IndexFmt = DXGI_FORMAT_UNKNOWN; - m_BoundD3D11IndexDataStartOffset = 0; - m_pd3d11DeviceContext->IASetIndexBuffer( nullptr, m_BoundD3D11IndexFmt, m_BoundD3D11IndexDataStartOffset ); + m_CommittedD3D11IndexBuffer.Release(); + m_CommittedIBFormat = VT_UNDEFINED; + m_CommittedD3D11IndexDataStartOffset = 0; + m_bCommittedD3D11IBUpToDate = false; + m_pd3d11DeviceContext->IASetIndexBuffer( nullptr, DXGI_FORMAT_R32_UINT, m_CommittedD3D11IndexDataStartOffset ); + } + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedIndexBuffer(); } - dbgVerifyIndexBuffer(); + pBuffer->ClearState( D3D11BufferState::IndexBuffer ); } - if( BuffBindFlags & BIND_VERTEX_BUFFER ) + if( pBuffer->CheckState( D3D11BufferState::VertexBuffer ) ) { auto pd3d11VB = ValidatedCast<BufferD3D11Impl>( pBuffer )->GetD3D11Buffer(); - for( Uint32 Slot = 0; Slot < m_BoundD3D11VertexBuffers.size(); ++Slot ) + for( Uint32 Slot = 0; Slot < m_NumCommittedD3D11VBs; ++Slot ) { - auto &BoundD3D11VB = m_BoundD3D11VertexBuffers[Slot]; - if(BoundD3D11VB == pd3d11VB) + auto &CommittedD3D11VB = m_CommittedD3D11VertexBuffers[Slot]; + if(CommittedD3D11VB == pd3d11VB) { // Unbind only D3D11 buffer //*VertStream = VertexStreamInfo(); ID3D11Buffer *ppNullBuffer[] = { nullptr }; const UINT Zero[] = { 0 }; - m_BoundD3D11VertexBuffers[Slot].Release(); - m_BoundD3D11VBStrides[Slot] = 0; - m_BoundD3D11VBOffsets[Slot] = 0; + m_CommittedD3D11VertexBuffers[Slot] = nullptr; + m_CommittedD3D11VBStrides[Slot] = 0; + m_CommittedD3D11VBOffsets[Slot] = 0; + m_bCommittedD3D11VBsUpToDate = false; m_pd3d11DeviceContext->IASetVertexBuffers( Slot, _countof( ppNullBuffer ), ppNullBuffer, Zero, Zero ); } } - dbgVerifyVertexBuffers(); + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedVertexBuffers(); + } + pBuffer->ClearState( D3D11BufferState::VertexBuffer ); } - if( BuffBindFlags & BIND_UNIFORM_BUFFER ) + if( pBuffer->CheckState( D3D11BufferState::ConstantBuffer ) ) { for( Int32 ShaderTypeInd = 0; ShaderTypeInd < NumShaderTypes; ++ShaderTypeInd ) { - auto &BoundCBs = m_BoundCBs[ShaderTypeInd]; - auto &BoundD3D11CBs = m_BoundD3D11CBs[ShaderTypeInd]; - VERIFY( BoundCBs.size() == BoundD3D11CBs.size(), "Inconsistent constant buffer array sizes" ); - auto NumSlots = std::min( BoundCBs.size(), BoundD3D11CBs.size() ); + auto *CommittedD3D11CBs = m_CommittedD3D11CBs[ShaderTypeInd]; + auto NumSlots = m_NumCommittedCBs[ShaderTypeInd]; for( Uint32 Slot = 0; Slot < NumSlots; ++Slot ) { - if( BoundCBs[Slot].pBuff == pBuffer ) + if( CommittedD3D11CBs[Slot] == pd3d11Buffer ) { - BoundCBs[Slot] = ShaderD3D11Impl::BoundCB(); - BoundD3D11CBs[Slot] = nullptr; + CommittedD3D11CBs[Slot] = nullptr; auto SetCBMethod = SetCBMethods[ShaderTypeInd]; ID3D11Buffer *ppNullBuffer[] = { nullptr }; (m_pd3d11DeviceContext->*SetCBMethod)(Slot, 1, ppNullBuffer); } } } - - dbgVerifyContextCBs(); + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedCBs(); + } + pBuffer->ClearState( D3D11BufferState::ConstantBuffer ); } } - void DeviceContextD3D11Impl::UnbindResourceFromUAV( IDeviceObject *pResource ) + void DeviceContextD3D11Impl::UnbindResourceFromUAV( IDeviceObject *pResource, ID3D11Resource *pd3d11Resource ) { VERIFY( pResource, "Null resource provided" ) if( !pResource )return; - UnbindResourceView( m_BoundUAVs, m_BoundD3D11UAVs, pResource, SetUAVMethods ); + UnbindResourceView( m_CommittedD3D11UAVs, m_CommittedD3D11UAVResources, m_NumCommittedUAVs, pResource, pd3d11Resource, SetUAVMethods ); } - void DeviceContextD3D11Impl::UnbindTextureFromRenderTarget( IDeviceObject *pResource ) + void DeviceContextD3D11Impl::UnbindTextureFromRenderTarget( TextureBaseD3D11 *pTexture ) { - VERIFY( pResource, "Null resource provided" ) - if( !pResource )return; - VERIFY(ValidatedCast<ITexture>( pResource ), "Resource is not a texture") + VERIFY( pTexture, "Null resource provided" ) + if( !pTexture )return; bool bRebindRenderTargets = false; - for( auto rt = m_pBoundRenderTargets.begin(); rt != m_pBoundRenderTargets.end(); ++rt ) + for( Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt ) { - if( auto pTexView = *rt ) + if( auto pTexView = m_pBoundRenderTargets[rt] ) { - if( pTexView->GetTexture() == pResource ) + if( pTexView->GetTexture() == pTexture ) { - (*rt).Release(); + m_pBoundRenderTargets[rt].Release(); bRebindRenderTargets = true; } } @@ -1046,19 +1116,21 @@ namespace Diligent if( bRebindRenderTargets ) RebindRenderTargets(); + + pTexture->ClearState(D3D11TextureState::RenderTarget); } - void DeviceContextD3D11Impl::UnbindTextureFromDepthStencil(IDeviceObject *pResource) + void DeviceContextD3D11Impl::UnbindTextureFromDepthStencil(TextureBaseD3D11 *pTexD3D11) { - VERIFY( pResource, "Null resource provided" ) - if( !pResource )return; - VERIFY(ValidatedCast<ITexture>( pResource ), "Resource is not a texture") - - if( m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture() == pResource ) + VERIFY( pTexD3D11, "Null resource provided" ) + if( !pTexD3D11 )return; + + if( m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture() == pTexD3D11 ) { m_pBoundDepthStencil.Release(); RebindRenderTargets(); } + pTexD3D11->ClearState(D3D11TextureState::DepthStencil); } void DeviceContextD3D11Impl::SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil ) @@ -1068,10 +1140,16 @@ namespace Diligent for( Uint32 RT = 0; RT < NumRenderTargets; ++RT ) if( ppRenderTargets[RT] ) { - UnbindTextureFromInput( ppRenderTargets[RT]->GetTexture() ); + auto *pTex = ValidatedCast<TextureBaseD3D11>(ppRenderTargets[RT]->GetTexture()); + UnbindTextureFromInput( pTex, pTex->GetD3D11Texture() ); + pTex->ResetState(D3D11TextureState::RenderTarget); } if( pDepthStencil ) - UnbindTextureFromInput( pDepthStencil->GetTexture() ); + { + auto *pTex = ValidatedCast<TextureBaseD3D11>(pDepthStencil->GetTexture()); + UnbindTextureFromInput( pTex, pTex->GetD3D11Texture() ); + pTex->ResetState(D3D11TextureState::DepthStencil); + } RebindRenderTargets(); @@ -1079,7 +1157,7 @@ namespace Diligent SetViewports(1, nullptr, 0, 0); } } - + template<typename TD3D11ResourceType, typename TSetD3D11ResMethodType> void SetD3D11ResourcesHelper(ID3D11DeviceContext *pDeviceCtx, TSetD3D11ResMethodType SetD3D11ResMethod, @@ -1098,18 +1176,16 @@ namespace Diligent (pDeviceCtx->*SetD3D11UAVMethod)(StartSlot, NumSlots, ppUAVs, nullptr); } - template<typename TD3D11ResourceType, typename TBoundResourceType, typename TSetD3D11ResMethodType> - void ClearStateCacheInternal(std::vector<TD3D11ResourceType*> &BoundD3D11Res, - std::vector<TBoundResourceType> &BoundRes, + template<typename TD3D11ResourceType, typename TSetD3D11ResMethodType> + void ClearStateCacheInternal(TD3D11ResourceType CommittedD3D11Res[], + Uint8 &NumCommittedResources, TSetD3D11ResMethodType SetD3D11ResMethod, ID3D11DeviceContext *pDeviceCtx) { - if( BoundD3D11Res.size() ) + if( NumCommittedResources > 0) { - memset( BoundD3D11Res.data(), 0, BoundD3D11Res.size() * sizeof( BoundD3D11Res[0] ) ); - SetD3D11ResourcesHelper( pDeviceCtx, SetD3D11ResMethod, 0, static_cast<UINT>(BoundD3D11Res.size()), BoundD3D11Res.data() ); - BoundD3D11Res.clear(); - BoundRes.clear(); + memset( CommittedD3D11Res, 0, NumCommittedResources * sizeof( CommittedD3D11Res[0] ) ); + SetD3D11ResourcesHelper( pDeviceCtx, SetD3D11ResMethod, 0, NumCommittedResources, CommittedD3D11Res ); } } @@ -1117,26 +1193,197 @@ namespace Diligent { for( int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType ) { - ClearStateCacheInternal( m_BoundD3D11CBs [ShaderType], m_BoundCBs [ShaderType], SetCBMethods[ShaderType], m_pd3d11DeviceContext ); - ClearStateCacheInternal( m_BoundD3D11SRVs [ShaderType], m_BoundSRVs [ShaderType], SetSRVMethods[ShaderType], m_pd3d11DeviceContext ); - ClearStateCacheInternal( m_BoundD3D11Samplers[ShaderType], m_BoundSamplers[ShaderType], SetSamplerMethods[ShaderType], m_pd3d11DeviceContext ); - ClearStateCacheInternal( m_BoundD3D11UAVs [ShaderType], m_BoundUAVs [ShaderType], SetUAVMethods[ShaderType], m_pd3d11DeviceContext ); + ClearStateCacheInternal( m_CommittedD3D11CBs [ShaderType], m_NumCommittedCBs [ShaderType], SetCBMethods[ShaderType], m_pd3d11DeviceContext ); + ClearStateCacheInternal( m_CommittedD3D11SRVs [ShaderType], m_NumCommittedSRVs [ShaderType], SetSRVMethods[ShaderType], m_pd3d11DeviceContext ); + ClearStateCacheInternal( m_CommittedD3D11Samplers[ShaderType], m_NumCommittedSamplers[ShaderType], SetSamplerMethods[ShaderType], m_pd3d11DeviceContext ); + ClearStateCacheInternal( m_CommittedD3D11UAVs [ShaderType], m_NumCommittedUAVs [ShaderType], SetUAVMethods[ShaderType], m_pd3d11DeviceContext ); + memset(m_CommittedD3D11SRVResources[ShaderType], 0, sizeof(m_CommittedD3D11SRVResources[ShaderType][0])*m_NumCommittedSRVs[ShaderType] ); + memset(m_CommittedD3D11UAVResources[ShaderType], 0, sizeof(m_CommittedD3D11UAVResources[ShaderType][0])*m_NumCommittedUAVs[ShaderType] ); + m_NumCommittedCBs[ShaderType] = 0; + m_NumCommittedSRVs[ShaderType] = 0; + m_NumCommittedSamplers[ShaderType] = 0; + m_NumCommittedUAVs[ShaderType] = 0; + } + + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + dbgVerifyCommittedSRVs(); + dbgVerifyCommittedUAVs(); + dbgVerifyCommittedSamplers(); + dbgVerifyCommittedCBs(); } - dbgVerifyContextSRVs(); - dbgVerifyContextUAVs(); - dbgVerifyContextSamplers(); - dbgVerifyContextCBs(); - // We do not unbind vertex buffers and index buffer as this can explicitly // be done by the user } + + void DeviceContextD3D11Impl::FinishCommandList(ICommandList **ppCommandList) + { + CComPtr<ID3D11CommandList> pd3d11CmdList; + m_pd3d11DeviceContext->FinishCommandList( + FALSE, // A Boolean flag that determines whether the runtime saves deferred context state before it + // executes FinishCommandList and restores it afterwards. + // * TRUE indicates that the runtime needs to save and restore the state. + // * FALSE indicates that the runtime will not save or restore any state. + // In this case, the deferred context will return to its default state + // after the call to FinishCommandList() completes as if + // ID3D11DeviceContext::ClearState() was called. + &pd3d11CmdList); + + CommandListD3D11Impl *pCmdListD3D11( NEW(m_CmdListAllocator, "CommandListD3D11Impl instance", CommandListD3D11Impl, m_pDevice, pd3d11CmdList) ); + pCmdListD3D11->QueryInterface( IID_CommandList, reinterpret_cast<IObject**>(ppCommandList) ); + + // Device context is now in default state + ClearStateCache(); + + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + // Verify bindings + dbgVerifyCommittedSRVs(); + dbgVerifyCommittedUAVs(); + dbgVerifyCommittedSamplers(); + dbgVerifyCommittedCBs(); + dbgVerifyCommittedVertexBuffers(); + dbgVerifyCommittedIndexBuffer(); + dbgVerifyCommittedShaders(); + } + } + + void DeviceContextD3D11Impl::ExecuteCommandList(ICommandList *pCommandList) + { + if (m_bIsDeferred) + { + LOG_ERROR("Only immediate context can execute command list"); + return; + } + + CommandListD3D11Impl* pCmdListD3D11 = ValidatedCast<CommandListD3D11Impl>(pCommandList); + auto *pd3d11CmdList = pCmdListD3D11->GetD3D11CommandList(); + m_pd3d11DeviceContext->ExecuteCommandList(pd3d11CmdList, + FALSE // A Boolean flag that determines whether the target context state is + // saved prior to and restored after the execution of a command list. + // * TRUE indicates that the runtime needs to save and restore the state. + // * FALSE indicate that no state shall be saved or restored, which causes the + // target context to return to its default state after the command list executes as if + // ID3D11DeviceContext::ClearState() was called. + ); + + // Device context is now in default state + ClearStateCache(); + + if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance) + { + // Verify bindings + dbgVerifyCommittedSRVs(); + dbgVerifyCommittedUAVs(); + dbgVerifyCommittedSamplers(); + dbgVerifyCommittedCBs(); + dbgVerifyCommittedVertexBuffers(); + dbgVerifyCommittedIndexBuffer(); + dbgVerifyCommittedShaders(); + } + } + + void DeviceContextD3D11Impl::ClearStateCache() + { + TDeviceContextBase::ClearStateCache(); + + for( int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType ) + { + memset(m_CommittedD3D11CBs [ShaderType], 0, sizeof(m_CommittedD3D11CBs [ShaderType][0])*m_NumCommittedCBs [ShaderType] ); + memset(m_CommittedD3D11SRVs [ShaderType], 0, sizeof(m_CommittedD3D11SRVs [ShaderType][0])*m_NumCommittedSRVs [ShaderType] ); + memset(m_CommittedD3D11Samplers[ShaderType], 0, sizeof(m_CommittedD3D11Samplers[ShaderType][0])*m_NumCommittedSamplers[ShaderType] ); + memset(m_CommittedD3D11UAVs [ShaderType], 0, sizeof(m_CommittedD3D11UAVs [ShaderType][0])*m_NumCommittedUAVs [ShaderType] ); + memset(m_CommittedD3D11SRVResources[ShaderType], 0, sizeof(m_CommittedD3D11SRVResources[ShaderType][0])*m_NumCommittedSRVs[ShaderType] ); + memset(m_CommittedD3D11UAVResources[ShaderType], 0, sizeof(m_CommittedD3D11UAVResources[ShaderType][0])*m_NumCommittedUAVs[ShaderType] ); + + m_NumCommittedCBs [ShaderType] = 0; + m_NumCommittedSRVs [ShaderType] = 0; + m_NumCommittedSamplers[ShaderType] = 0; + m_NumCommittedUAVs [ShaderType] = 0; + + m_CommittedD3DShaders[ShaderType].Release(); + } + + for(Uint32 vb=0; vb < m_NumCommittedD3D11VBs; ++vb) + { + m_CommittedD3D11VertexBuffers[vb] = nullptr; + m_CommittedD3D11VBStrides [vb] = 0; + m_CommittedD3D11VBOffsets [vb] = 0; + } + m_NumCommittedD3D11VBs = 0; + m_bCommittedD3D11VBsUpToDate = false; + + m_CommittedD3D11InputLayout = nullptr; + + m_CommittedD3D11IndexBuffer.Release(); + m_CommittedIBFormat = VT_UNDEFINED; + m_CommittedD3D11IndexDataStartOffset = 0; + m_bCommittedD3D11IBUpToDate = false; + + m_CommittedD3D11PrimTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + m_CommittedPrimitiveTopology = PRIMITIVE_TOPOLOGY_UNDEFINED; + } + #ifdef VERIFY_CONTEXT_BINDINGS + void DeviceContextD3D11Impl::dbgVerifyRenderTargetFormats() + { + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound"); + return; + } + + TEXTURE_FORMAT BoundRTVFormats[8] = {TEX_FORMAT_UNKNOWN}; + TEXTURE_FORMAT BoundDSVFormat = TEX_FORMAT_UNKNOWN; + Uint32 NumBoundRTVs = 0; + if (m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil == nullptr) + { + BoundRTVFormats[0] = m_pSwapChain->GetDesc().ColorBufferFormat; + BoundDSVFormat = m_pSwapChain->GetDesc().DepthBufferFormat; + NumBoundRTVs = 1; + } + else + { + NumBoundRTVs = m_NumBoundRenderTargets; + for (Uint32 rt = 0; rt < NumBoundRTVs; ++rt) + { + if (auto pRT = m_pBoundRenderTargets[rt]) + BoundRTVFormats[rt] = pRT->GetDesc().Format; + else + BoundRTVFormats[rt] = TEX_FORMAT_UNKNOWN; + } + + BoundDSVFormat = m_pBoundDepthStencil ? m_pBoundDepthStencil->GetDesc().Format : TEX_FORMAT_UNKNOWN; + } + + const auto &PSODesc = m_pPipelineState->GetDesc(); + const auto &GraphicsPipeline = PSODesc.GraphicsPipeline; + if (/*GraphicsPipeline.NumRenderTargets != 0 && */GraphicsPipeline.NumRenderTargets != NumBoundRTVs) + { + LOG_WARNING_MESSAGE("Number of currently bound render targets (", NumBoundRTVs, ") does not match the number of outputs specified by the PSO \"", PSODesc.Name, "\" (", GraphicsPipeline.NumRenderTargets, "). This is OK on D3D11 device, but will most likely be an issue on D3D12." ); + } + + if (GraphicsPipeline.DepthStencilDesc.DepthEnable && BoundDSVFormat != GraphicsPipeline.DSVFormat) + { + LOG_WARNING_MESSAGE("Currently bound depth-stencil buffer format (", GetTextureFormatAttribs(BoundDSVFormat).Name, ") does not match the DSV format specified by the PSO \"", PSODesc.Name, "\" (", GetTextureFormatAttribs(GraphicsPipeline.DSVFormat).Name, "). This is OK on D3D11 device, but will most likely be an issue on D3D12." ); + } + + for (Uint32 rt = 0; rt < NumBoundRTVs; ++rt) + { + auto BoundFmt = BoundRTVFormats[rt]; + auto PSOFmt = GraphicsPipeline.RTVFormats[rt]; + if (BoundFmt != PSOFmt) + { + LOG_WARNING_MESSAGE("Render target bound to slot ", rt, " (", GetTextureFormatAttribs(BoundFmt).Name, ") does not match the RTV format specified by the PSO \"", PSODesc.Name, "\" (", GetTextureFormatAttribs(PSOFmt).Name, "). This is OK on D3D11 device, but will most likely be an issue on D3D12." ); + } + } + } - DEFINE_D3D11CTX_FUNC_POINTERS(GetCBMethods, GetConstantBuffers) - DEFINE_D3D11CTX_FUNC_POINTERS(GetSRVMethods, GetShaderResources) - DEFINE_D3D11CTX_FUNC_POINTERS(GetSamplerMethods, GetSamplers) + DEFINE_D3D11CTX_FUNC_POINTERS(GetCBMethods, GetConstantBuffers) + DEFINE_D3D11CTX_FUNC_POINTERS(GetSRVMethods, GetShaderResources) + DEFINE_D3D11CTX_FUNC_POINTERS(GetSamplerMethods, GetSamplers) typedef decltype (&ID3D11DeviceContext::CSGetUnorderedAccessViews) TGetUnorderedAccessViewsType; static const TGetUnorderedAccessViewsType GetUAVMethods[] = @@ -1154,7 +1401,7 @@ namespace Diligent /// ID3D11UnorderedAccessView, ID3D11Buffer or ID3D11SamplerState). /// \tparam TGetD3D11ResourcesType - Type of the device context method used to get the bound /// resources - /// \param BoundD3D11ResourcesArr - Pointer to the array of currently bound D3D11 + /// \param CommittedD3D11ResourcesArr - Pointer to the array of currently bound D3D11 /// resources, for each shader stage /// \param GetD3D11ResMethods - Pointer to the array of device context methods to get the bound /// resources, for each shader stage @@ -1164,10 +1411,11 @@ namespace Diligent template<UINT MaxResources, typename TD3D11ResourceType, typename TGetD3D11ResourcesType> - void DeviceContextD3D11Impl::dbgVerifyContextResources(std::vector<TD3D11ResourceType> BoundD3D11ResourcesArr[], - TGetD3D11ResourcesType GetD3D11ResMethods[], - const Char *ResourceName, - SHADER_TYPE ShaderType) + void DeviceContextD3D11Impl::dbgVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources], + Uint8 NumCommittedResourcesArr[], + TGetD3D11ResourcesType GetD3D11ResMethods[], + const Char *ResourceName, + SHADER_TYPE ShaderType) { int iStartInd = 0, iEndInd = NumShaderTypes; if( ShaderType != SHADER_TYPE_UNKNOWN ) @@ -1184,17 +1432,18 @@ namespace Diligent { (m_pd3d11DeviceContext->*GetResMethod)(0, _countof( pctxResources ), pctxResources); } - const auto& BoundResources = BoundD3D11ResourcesArr[iShaderTypeInd]; - auto NumBoundResources = BoundResources.size(); + const auto* CommittedResources = CommittedD3D11ResourcesArr[iShaderTypeInd]; + auto NumCommittedResources = NumCommittedResourcesArr[iShaderTypeInd]; for( Uint32 Slot = 0; Slot < _countof( pctxResources ); ++Slot ) { - if( Slot < NumBoundResources ) + if( Slot < NumCommittedResources ) { - VERIFY( BoundResources[Slot] == pctxResources[Slot], ResourceName, " binding mismatch found for ", ShaderName, " shader type at slot ", Slot ) + VERIFY( CommittedResources[Slot] == pctxResources[Slot], ResourceName, " binding mismatch found for ", ShaderName, " shader type at slot ", Slot ) } else { VERIFY( pctxResources[Slot] == nullptr, ResourceName, " binding mismatch found for ", ShaderName, " shader type at slot ", Slot ) + VERIFY( CommittedResources[Slot] == nullptr, ResourceName, " unexpected non-null resource found for ", ShaderName, " shader type at slot ", Slot ) } if( pctxResources[Slot] ) @@ -1203,62 +1452,104 @@ namespace Diligent } } - void DeviceContextD3D11Impl::dbgVerifyContextSRVs(SHADER_TYPE ShaderType) + template<UINT MaxResources, typename TD3D11ViewType> + void DeviceContextD3D11Impl::dbgVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources], + ID3D11Resource* CommittedD3D11ResourcesArr[][MaxResources], + Uint8 NumCommittedResourcesArr[], + const Char *ResourceName, + SHADER_TYPE ShaderType) + { + int iStartInd = 0, iEndInd = NumShaderTypes; + if( ShaderType != SHADER_TYPE_UNKNOWN ) + { + iStartInd = GetShaderTypeIndex(ShaderType); + iEndInd = iStartInd + 1; + } + for( int iShaderTypeInd = iStartInd; iShaderTypeInd < iEndInd; ++iShaderTypeInd ) + { + const auto ShaderName = GetShaderTypeLiteralName( GetShaderTypeFromIndex(iShaderTypeInd) ); + auto* Views = CommittedD3D11ViewArr[iShaderTypeInd]; + auto* Resources = CommittedD3D11ResourcesArr[iShaderTypeInd]; + auto NumCommittedResources = NumCommittedResourcesArr[iShaderTypeInd]; + for( Uint32 Slot = 0; Slot < NumCommittedResources; ++Slot ) + { + if(Views[Slot] != nullptr) + { + CComPtr<ID3D11Resource> pRefRes; + Views[Slot]->GetResource(&pRefRes); + VERIFY( pRefRes == Resources[Slot], "Inconsistent ", ResourceName, " detected at slot ", Slot, " in shader ", ShaderName, ". The resource in the view does not match cached D3D11 resource" ) + } + } + } + } + + void DeviceContextD3D11Impl::dbgVerifyCommittedSRVs(SHADER_TYPE ShaderType) { - dbgVerifyContextResources<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>( m_BoundD3D11SRVs, GetSRVMethods, "SRV", ShaderType ); + dbgVerifyCommittedResources<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>( m_CommittedD3D11SRVs, m_NumCommittedSRVs, GetSRVMethods, "SRV", ShaderType ); + dbgVerifyViewConsistency<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>( m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, "SRV", ShaderType ); } - void DeviceContextD3D11Impl::dbgVerifyContextUAVs(SHADER_TYPE ShaderType) + void DeviceContextD3D11Impl::dbgVerifyCommittedUAVs(SHADER_TYPE ShaderType) { - dbgVerifyContextResources<D3D11_PS_CS_UAV_REGISTER_COUNT>( m_BoundD3D11UAVs, GetUAVMethods, "UAV", ShaderType ); + dbgVerifyCommittedResources<D3D11_PS_CS_UAV_REGISTER_COUNT>( m_CommittedD3D11UAVs, m_NumCommittedUAVs, GetUAVMethods, "UAV", ShaderType ); + dbgVerifyViewConsistency<D3D11_PS_CS_UAV_REGISTER_COUNT>( m_CommittedD3D11UAVs, m_CommittedD3D11UAVResources, m_NumCommittedUAVs, "UAV", ShaderType ); } - void DeviceContextD3D11Impl::dbgVerifyContextSamplers(SHADER_TYPE ShaderType) + void DeviceContextD3D11Impl::dbgVerifyCommittedSamplers(SHADER_TYPE ShaderType) { - dbgVerifyContextResources<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>( m_BoundD3D11Samplers, GetSamplerMethods, "Sampler", ShaderType ); + dbgVerifyCommittedResources<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>( m_CommittedD3D11Samplers, m_NumCommittedSamplers, GetSamplerMethods, "Sampler", ShaderType ); } - void DeviceContextD3D11Impl::dbgVerifyContextCBs(SHADER_TYPE ShaderType) + void DeviceContextD3D11Impl::dbgVerifyCommittedCBs(SHADER_TYPE ShaderType) { - dbgVerifyContextResources<D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>( m_BoundD3D11CBs, GetCBMethods, "Constant buffer", ShaderType ); + dbgVerifyCommittedResources<D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>( m_CommittedD3D11CBs, m_NumCommittedCBs, GetCBMethods, "Constant buffer", ShaderType ); } - void DeviceContextD3D11Impl::dbgVerifyIndexBuffer() + void DeviceContextD3D11Impl::dbgVerifyCommittedIndexBuffer() { RefCntAutoPtr<ID3D11Buffer> pctxIndexBuffer; DXGI_FORMAT Fmt = DXGI_FORMAT_UNKNOWN; UINT Offset = 0; m_pd3d11DeviceContext->IAGetIndexBuffer( &pctxIndexBuffer, &Fmt, &Offset ); - if( m_BoundD3D11IndexBuffer && !pctxIndexBuffer ) + if( m_CommittedD3D11IndexBuffer && !pctxIndexBuffer ) UNEXPECTED( "D3D11 index buffer is not bound to the context" ); - if( !m_BoundD3D11IndexBuffer && pctxIndexBuffer ) + if( !m_CommittedD3D11IndexBuffer && pctxIndexBuffer ) UNEXPECTED( "Unexpected D3D11 index buffer is bound to the context" ); - if( m_BoundD3D11IndexBuffer && pctxIndexBuffer ) + if( m_CommittedD3D11IndexBuffer && pctxIndexBuffer ) { - VERIFY(m_BoundD3D11IndexBuffer == pctxIndexBuffer, "Index buffer binding mismatch detected"); - VERIFY(m_BoundD3D11IndexFmt == Fmt, "Index buffer format mismatch detected"); - VERIFY(m_BoundD3D11IndexDataStartOffset == Offset, "Index buffer offset mismatch detected"); + VERIFY(m_CommittedD3D11IndexBuffer == pctxIndexBuffer, "Index buffer binding mismatch detected"); + if( Fmt==DXGI_FORMAT_R32_UINT ) + { + VERIFY(m_CommittedIBFormat == VT_UINT32, "Index buffer format mismatch detected") + } + else if( Fmt==DXGI_FORMAT_R16_UINT ) + { + VERIFY(m_CommittedIBFormat == VT_UINT16, "Index buffer format mismatch detected"); + } + VERIFY(m_CommittedD3D11IndexDataStartOffset == Offset, "Index buffer offset mismatch detected"); } } - void DeviceContextD3D11Impl::dbgVerifyVertexBuffers() + void DeviceContextD3D11Impl::dbgVerifyCommittedVertexBuffers() { + CComPtr<ID3D11InputLayout> pInputLayout; + m_pd3d11DeviceContext->IAGetInputLayout(&pInputLayout); + VERIFY( pInputLayout == m_CommittedD3D11InputLayout, "Inconsistent input layout" ); + const Uint32 MaxVBs = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ID3D11Buffer *pVBs[MaxVBs]; UINT Strides[MaxVBs]; UINT Offsets[MaxVBs]; m_pd3d11DeviceContext->IAGetVertexBuffers( 0, MaxVBs, pVBs, Strides, Offsets ); - auto NumBoundVBs = m_BoundD3D11VertexBuffers.size(); - VERIFY(m_BoundD3D11VBStrides.size() == NumBoundVBs, "Unexpected bound D3D11 VB stride array size"); - VERIFY(m_BoundD3D11VBOffsets.size() == NumBoundVBs, "Unexpected bound D3D11 VB offset array size"); + auto NumBoundVBs = m_NumCommittedD3D11VBs; for( Uint32 Slot = 0; Slot < MaxVBs; ++Slot ) { if( Slot < NumBoundVBs ) { - const auto &BoundD3D11VB = m_BoundD3D11VertexBuffers[Slot]; - auto BoundVBStride = m_BoundD3D11VBStrides[Slot]; - auto BoundVBOffset = m_BoundD3D11VBOffsets[Slot]; + const auto &BoundD3D11VB = m_CommittedD3D11VertexBuffers[Slot]; + auto BoundVBStride = m_CommittedD3D11VBStrides[Slot]; + auto BoundVBOffset = m_CommittedD3D11VBOffsets[Slot]; if(BoundD3D11VB && !pVBs[Slot] ) VERIFY( pVBs[Slot] == nullptr, "Missing D3D11 buffer detected at slot ", Slot ); if(!BoundD3D11VB && pVBs[Slot] ) @@ -1281,7 +1572,7 @@ namespace Diligent } template<typename TD3D11ShaderType, typename TGetShaderMethodType> - void dbgVerifyShadersHelper(SHADER_TYPE ShaderType, + void dbgVerifyCommittedShadersHelper(SHADER_TYPE ShaderType, const CComPtr<ID3D11DeviceChild> BoundD3DShaders[], ID3D11DeviceContext *pCtx, TGetShaderMethodType GetShaderMethod) @@ -1291,9 +1582,9 @@ namespace Diligent const auto &BoundShader = BoundD3DShaders[GetShaderTypeIndex( ShaderType )]; VERIFY( BoundShader == pctxShader, GetShaderTypeLiteralName(ShaderType), " binding mismatch detected" ); } - void DeviceContextD3D11Impl::dbgVerifyShaders() + void DeviceContextD3D11Impl::dbgVerifyCommittedShaders() { -#define VERIFY_SHADER(NAME, Name, N) dbgVerifyShadersHelper<ID3D11##Name##Shader>(SHADER_TYPE_##NAME, m_BoundD3DShaders, m_pd3d11DeviceContext, &ID3D11DeviceContext::N##SGetShader ) +#define VERIFY_SHADER(NAME, Name, N) dbgVerifyCommittedShadersHelper<ID3D11##Name##Shader>(SHADER_TYPE_##NAME, m_CommittedD3DShaders, m_pd3d11DeviceContext, &ID3D11DeviceContext::N##SGetShader ) // These shaders which are not set will be unbound from the D3D11 device context VERIFY_SHADER( VERTEX, Vertex, V ); VERIFY_SHADER( PIXEL, Pixel, P ); @@ -1304,5 +1595,4 @@ namespace Diligent } #endif - } diff --git a/Graphics/GraphicsEngineD3D11/src/GraphicsEngineD3D11.def b/Graphics/GraphicsEngineD3D11/src/GraphicsEngineD3D11.def index 9414b724..11ba3cd0 100644 --- a/Graphics/GraphicsEngineD3D11/src/GraphicsEngineD3D11.def +++ b/Graphics/GraphicsEngineD3D11/src/GraphicsEngineD3D11.def @@ -1,3 +1,3 @@ EXPORTS - CreateDeviceAndImmediateContextD3D11 + CreateDeviceAndContextsD3D11 CreateSwapChainD3D11
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp new file mode 100644 index 00000000..d6d75f41 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp @@ -0,0 +1,222 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "PipelineStateD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" +#include "ShaderResourceBindingD3D11Impl.h" +#include "EngineMemory.h" + +namespace Diligent +{ + +PipelineStateD3D11Impl::PipelineStateD3D11Impl(FixedBlockMemoryAllocator &PSOAllocator, RenderDeviceD3D11Impl *pRenderDeviceD3D11, const PipelineStateDesc& PipelineDesc) : + TPipelineStateBase(PSOAllocator, pRenderDeviceD3D11, PipelineDesc), + m_pDefaultShaderResBinding( nullptr, STDDeleter<ShaderResourceBindingD3D11Impl, FixedBlockMemoryAllocator>(pRenderDeviceD3D11->GetSRBAllocator()) ), + m_ResourceCacheDataAllocators + { + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity} + }, + m_ShaderResLayoutDataAllocators + { + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity} + }, + m_DummyShaderVar(*this) +{ + if (PipelineDesc.IsComputePipeline) + { + m_pCS = ValidatedCast<ShaderD3D11Impl>( PipelineDesc.ComputePipeline.pCS ); + if (m_pCS == nullptr) + { + LOG_ERROR_AND_THROW("Compute shader is null"); + } + + if (m_pCS && m_pCS->GetDesc().ShaderType != SHADER_TYPE_COMPUTE) + { + LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(SHADER_TYPE_COMPUTE), " shader is expeceted while ", GetShaderTypeLiteralName(m_pCS->GetDesc().ShaderType)," provided" ); + } + } + else + { + +#define INIT_SHADER(ShortName, ExpectedType)\ + { \ + m_p##ShortName = ValidatedCast<ShaderD3D11Impl>( PipelineDesc.GraphicsPipeline.p##ShortName ); \ + if (m_p##ShortName && m_p##ShortName->GetDesc().ShaderType != ExpectedType) \ + { \ + LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(ExpectedType), " shader is expeceted while ", GetShaderTypeLiteralName(m_p##ShortName->GetDesc().ShaderType)," provided" ); \ + } \ + } + + INIT_SHADER(VS, SHADER_TYPE_VERTEX); + INIT_SHADER(PS, SHADER_TYPE_PIXEL); + INIT_SHADER(GS, SHADER_TYPE_GEOMETRY); + INIT_SHADER(DS, SHADER_TYPE_DOMAIN); + INIT_SHADER(HS, SHADER_TYPE_HULL); +#undef INIT_SHADER + + if (m_pVS == nullptr) + { + LOG_ERROR_AND_THROW("Vertex shader is null"); + } + + auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); + D3D11_BLEND_DESC D3D11BSDesc = {}; + BlendStateDesc_To_D3D11_BLEND_DESC(PipelineDesc.GraphicsPipeline.BlendDesc, D3D11BSDesc); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateBlendState( &D3D11BSDesc, &m_pd3d11BlendState ), + "Failed to create D3D11 blend state object" ); + + D3D11_RASTERIZER_DESC D3D11RSDesc = {}; + RasterizerStateDesc_To_D3D11_RASTERIZER_DESC(PipelineDesc.GraphicsPipeline.RasterizerDesc, D3D11RSDesc); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRasterizerState( &D3D11RSDesc, &m_pd3d11RasterizerState ), + "Failed to create D3D11 rasterizer state" ); + + D3D11_DEPTH_STENCIL_DESC D3D11DSSDesc = {}; + DepthStencilStateDesc_To_D3D11_DEPTH_STENCIL_DESC(PipelineDesc.GraphicsPipeline.DepthStencilDesc, D3D11DSSDesc); + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateDepthStencilState( &D3D11DSSDesc, &m_pd3d11DepthStencilState ), + "Failed to create D3D11 depth stencil state" ); + + + // Create input layout + if( m_LayoutElements.size() > 0 ) + { + std::vector<D3D11_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D11_INPUT_ELEMENT_DESC> > d311InputElements(STD_ALLOCATOR_RAW_MEM(D3D11_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector<D3D11_INPUT_ELEMENT_DESC>") ); + LayoutElements_To_D3D11_INPUT_ELEMENT_DESCs(m_LayoutElements, d311InputElements); + + ID3DBlob *pVSByteCode = ValidatedCast<ShaderD3D11Impl>(m_pVS.RawPtr())->GetBytecode(); + if( !pVSByteCode ) + LOG_ERROR_AND_THROW( "Vertex Shader byte code does not exist" ); + + CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateInputLayout(d311InputElements.data(), static_cast<UINT>(d311InputElements.size()), pVSByteCode->GetBufferPointer(), pVSByteCode->GetBufferSize(), &m_pd3d11InputLayout ), + "Failed to create the Direct3D11 input layout"); + } + } + + auto &SRBAllocator = pRenderDeviceD3D11->GetSRBAllocator(); + m_pDefaultShaderResBinding.reset( NEW(SRBAllocator, "ShaderResourceBindingD3D11Impl instance", ShaderResourceBindingD3D11Impl, this, true) ); +} + +PipelineStateD3D11Impl::~PipelineStateD3D11Impl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( PipelineStateD3D11Impl, IID_PipelineStateD3D11, TPipelineStateBase ) + + +ID3D11BlendState* PipelineStateD3D11Impl::GetD3D11BlendState() +{ + return m_pd3d11BlendState; +} + +ID3D11RasterizerState* PipelineStateD3D11Impl::GetD3D11RasterizerState() +{ + return m_pd3d11RasterizerState; +} + +ID3D11DepthStencilState* PipelineStateD3D11Impl::GetD3D11DepthStencilState() +{ + return m_pd3d11DepthStencilState; +} + +ID3D11InputLayout* PipelineStateD3D11Impl::GetD3D11InputLayout() +{ + return m_pd3d11InputLayout; +} + +void PipelineStateD3D11Impl::BindShaderResources(IResourceMapping *pResourceMapping, Uint32 Flags) +{ + if( m_Desc.IsComputePipeline ) + { + if(m_pCS)m_pCS->BindResources(pResourceMapping, Flags); + } + else + { + if(m_pVS)m_pVS->BindResources(pResourceMapping, Flags); + if(m_pPS)m_pPS->BindResources(pResourceMapping, Flags); + if(m_pGS)m_pGS->BindResources(pResourceMapping, Flags); + if(m_pDS)m_pDS->BindResources(pResourceMapping, Flags); + if(m_pHS)m_pHS->BindResources(pResourceMapping, Flags); + } +} + +void PipelineStateD3D11Impl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding) +{ + auto *pRenderDeviceD3D11 = ValidatedCast<RenderDeviceD3D11Impl>( GetDevice() ); + auto &SRBAllocator = pRenderDeviceD3D11->GetSRBAllocator(); + auto pShaderResBinding = NEW(SRBAllocator, "ShaderResourceBindingD3D11Impl instance", ShaderResourceBindingD3D11Impl, this, false); + pShaderResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(static_cast<IShaderResourceBinding**>(ppShaderResourceBinding))); +} + + +ID3D11VertexShader* PipelineStateD3D11Impl::GetD3D11VertexShader() +{ + if(!m_pVS)return nullptr; + auto *pVSD3D11 = ValidatedCast<ShaderD3D11Impl>(m_pVS.RawPtr()); + return static_cast<ID3D11VertexShader*>(pVSD3D11->GetD3D11Shader()); +} + +ID3D11PixelShader* PipelineStateD3D11Impl::GetD3D11PixelShader() +{ + if(!m_pPS)return nullptr; + auto *pPSD3D11 = ValidatedCast<ShaderD3D11Impl>(m_pPS.RawPtr()); + return static_cast<ID3D11PixelShader*>(pPSD3D11->GetD3D11Shader()); +} + +ID3D11GeometryShader* PipelineStateD3D11Impl::GetD3D11GeometryShader() +{ + if(!m_pGS)return nullptr; + auto *pGSD3D11 = ValidatedCast<ShaderD3D11Impl>(m_pGS.RawPtr()); + return static_cast<ID3D11GeometryShader*>(pGSD3D11->GetD3D11Shader()); +} + +ID3D11DomainShader* PipelineStateD3D11Impl::GetD3D11DomainShader() +{ + if(!m_pDS)return nullptr; + auto *pDSD3D11 = ValidatedCast<ShaderD3D11Impl>(m_pDS.RawPtr()); + return static_cast<ID3D11DomainShader*>(pDSD3D11->GetD3D11Shader()); +} + +ID3D11HullShader* PipelineStateD3D11Impl::GetD3D11HullShader() +{ + if(!m_pHS)return nullptr; + auto *pHSD3D11 = ValidatedCast<ShaderD3D11Impl>(m_pHS.RawPtr()); + return static_cast<ID3D11HullShader*>(pHSD3D11->GetD3D11Shader()); +} + +ID3D11ComputeShader* PipelineStateD3D11Impl::GetD3D11ComputeShader() +{ + if(!m_pCS)return nullptr; + auto *pCSD3D11 = ValidatedCast<ShaderD3D11Impl>(m_pCS.RawPtr()); + return static_cast<ID3D11ComputeShader*>(pCSD3D11->GetD3D11Shader()); +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/RasterizerStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RasterizerStateD3D11Impl.cpp deleted file mode 100644 index 90bd9092..00000000 --- a/Graphics/GraphicsEngineD3D11/src/RasterizerStateD3D11Impl.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#include "pch.h" -#include "RasterizerStateD3D11Impl.h" -#include "RenderDeviceD3D11Impl.h" - -namespace Diligent -{ - -D3D11_FILL_MODE FillMode2D3D11FillMode(FILL_MODE FillMode) -{ - static bool bIsInit = false; - static D3D11_FILL_MODE D3D11FillModes[FILL_MODE_NUM_MODES] = {}; - if( !bIsInit ) - { - D3D11FillModes[ FILL_MODE_WIREFRAME ] = D3D11_FILL_WIREFRAME; - D3D11FillModes[ FILL_MODE_SOLID ] = D3D11_FILL_SOLID; - - bIsInit = true; - } - if( FILL_MODE_UNDEFINED < FillMode && FillMode < FILL_MODE_NUM_MODES ) - { - auto D3D11FillMode = D3D11FillModes[FillMode]; - VERIFY( D3D11FillMode != 0, "Incorrect fill mode" ); - return D3D11FillModes[FillMode]; - } - else - { - UNEXPECTED( "Incorrect fill mode (", FillMode, ")" ) - return static_cast<D3D11_FILL_MODE>(0); - } -} - -D3D11_CULL_MODE CullMode2D3D11CullMode( CULL_MODE CullMode ) -{ - static bool bIsInit = false; - static D3D11_CULL_MODE D3D11CullModes[CULL_MODE_NUM_MODES] = {}; - if( !bIsInit ) - { - D3D11CullModes[ CULL_MODE_NONE ] = D3D11_CULL_NONE; - D3D11CullModes[ CULL_MODE_FRONT ] = D3D11_CULL_FRONT; - D3D11CullModes[ CULL_MODE_BACK ] = D3D11_CULL_BACK; - - bIsInit = true; - } - - if( CULL_MODE_UNDEFINED < CullMode && CullMode < CULL_MODE_NUM_MODES ) - { - auto D3D11CullMode = D3D11CullModes[CullMode]; - VERIFY( D3D11CullMode != 0, "Incorrect cull mode" ); - return D3D11CullMode; - } - else - { - UNEXPECTED( "Incorrect cull mode (", CullMode, ")" ) - return static_cast<D3D11_CULL_MODE>(0); - } -} - -RasterizerStateD3D11Impl::RasterizerStateD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, - const RasterizerStateDesc& RasterizerStateDesc) : - TRasterizerStateBase(pRenderDeviceD3D11, RasterizerStateDesc) -{ - D3D11_RASTERIZER_DESC D3D11RSDesc; - - D3D11RSDesc.FillMode = FillMode2D3D11FillMode(RasterizerStateDesc.FillMode); - D3D11RSDesc.CullMode = CullMode2D3D11CullMode(RasterizerStateDesc.CullMode); - D3D11RSDesc.FrontCounterClockwise = RasterizerStateDesc.FrontCounterClockwise ? TRUE : FALSE; - D3D11RSDesc.DepthBias = RasterizerStateDesc.DepthBias; - D3D11RSDesc.DepthBiasClamp = RasterizerStateDesc.DepthBiasClamp; - D3D11RSDesc.SlopeScaledDepthBias = RasterizerStateDesc.SlopeScaledDepthBias; - D3D11RSDesc.DepthClipEnable = RasterizerStateDesc.DepthClipEnable ? TRUE : FALSE; - D3D11RSDesc.ScissorEnable = RasterizerStateDesc.ScissorEnable ? TRUE : FALSE; - D3D11RSDesc.AntialiasedLineEnable = RasterizerStateDesc.AntialiasedLineEnable ? TRUE : FALSE; - D3D11RSDesc.MultisampleEnable = D3D11RSDesc.AntialiasedLineEnable; - - auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); - CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRasterizerState( &D3D11RSDesc, &m_pd3d11RasterizerState ), - "Failed to create D3D11 rasterizer state" ); -} - -RasterizerStateD3D11Impl::~RasterizerStateD3D11Impl() -{ - -} - -IMPLEMENT_QUERY_INTERFACE( RasterizerStateD3D11Impl, IID_RasterizerStateD3D11, TRasterizerStateBase ) - -} diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp index c828493e..867d71d7 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ #include "RenderDeviceD3D11Impl.h" #include "DeviceContextD3D11Impl.h" #include "BufferD3D11Impl.h" -#include "VertexDescD3D11Impl.h" #include "ShaderD3D11Impl.h" #include "Texture1D_D3D11.h" #include "Texture2D_D3D11.h" @@ -33,129 +32,25 @@ #include "SamplerD3D11Impl.h" #include "D3D11TypeConversions.h" #include "TextureViewD3D11Impl.h" -#include "DSStateD3D11Impl.h" -#include "RasterizerStateD3D11Impl.h" -#include "BlendStateD3D11Impl.h" +#include "PipelineStateD3D11Impl.h" +#include "ShaderResourceBindingD3D11Impl.h" +#include "EngineMemory.h" namespace Diligent { -RenderDeviceD3D11Impl :: RenderDeviceD3D11Impl(ID3D11Device *pd3d11Device) : +RenderDeviceD3D11Impl :: RenderDeviceD3D11Impl(IMemoryAllocator &RawMemAllocator, const EngineD3D11Attribs& EngineAttribs, ID3D11Device *pd3d11Device, Uint32 NumDeferredContexts) : + TRenderDeviceBase(RawMemAllocator, NumDeferredContexts, sizeof(TextureBaseD3D11), sizeof(TextureViewD3D11Impl), sizeof(BufferD3D11Impl), sizeof(BufferViewD3D11Impl), sizeof(ShaderD3D11Impl), sizeof(SamplerD3D11Impl), sizeof(PipelineStateD3D11Impl), sizeof(ShaderResourceBindingD3D11Impl)), + m_EngineAttribs(EngineAttribs), m_pd3d11Device(pd3d11Device) { - m_DeviceCaps.DevType = DeviceType::DirectX; + m_DeviceCaps.DevType = DeviceType::D3D11; m_DeviceCaps.MajorVersion = 11; m_DeviceCaps.MinorVersion = 0; - m_DeviceCaps.bSeparableProgramSupported = true; - - FlagSupportedTexFormats(); + m_DeviceCaps.bSeparableProgramSupported = True; + m_DeviceCaps.bMultithreadedResourceCreationSupported = True; } -void RenderDeviceD3D11Impl::FlagSupportedTexFormats() -{ -#define FLAG_FORMAT(Fmt, IsSupported)\ - m_TextureFormatsInfo[Fmt].Supported = IsSupported; - - FLAG_FORMAT(TEX_FORMAT_RGBA32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGBA32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RG32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RG32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RG32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R32G8X24_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_D32_FLOAT_S8X24_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_X32_TYPELESS_G8X24_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGB10A2_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGB10A2_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGB10A2_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R11G11B10_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RG16_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RG16_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RG16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG16_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG16_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG16_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_D32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_R32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_R32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R24G8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_D24_UNORM_S8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R24_UNORM_X8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_X24_TYPELESS_G8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RG8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG8_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG8_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R16_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_R16_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_D16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R16_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R16_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_R16_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_R8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R8_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_R8_SINT, true); - FLAG_FORMAT(TEX_FORMAT_A8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R1_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGB9E5_SHAREDEXP, true); - FLAG_FORMAT(TEX_FORMAT_RG8_B8G8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_G8R8_G8B8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC1_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC1_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC1_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC2_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC2_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC2_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC3_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC3_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC3_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC4_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC4_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC4_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC5_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC5_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC5_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_B5G6R5_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_B5G5R5A1_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BGRA8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BGRX8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC6H_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC6H_UF16, true); - FLAG_FORMAT(TEX_FORMAT_BC6H_SF16, true); - FLAG_FORMAT(TEX_FORMAT_BC7_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC7_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC7_UNORM_SRGB, true); -} bool CreateTestTexture1D(ID3D11Device *pDevice, const D3D11_TEXTURE1D_DESC &TexDesc) { @@ -261,7 +156,8 @@ void RenderDeviceD3D11Impl::TestTextureFormat( TEXTURE_FORMAT TexFormat ) TexFormatInfo.SupportsMS = CreateTestTexture2D( m_pd3d11Device, Tex2DDesc ); } } - else if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED ) + else if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED && + TexFormatInfo.Format != DXGI_FORMAT_R9G9B9E5_SHAREDEXP) { Tex2DDesc.BindFlags = D3D11_BIND_RENDER_TARGET; TexFormatInfo.ColorRenderable = CreateTestTexture2D( m_pd3d11Device, Tex2DDesc ); @@ -303,7 +199,7 @@ void RenderDeviceD3D11Impl :: CreateBuffer(const BufferDesc& BuffDesc, const Buf CreateDeviceObject("buffer", BuffDesc, ppBuffer, [&]() { - BufferD3D11Impl *pBufferD3D11( new BufferD3D11Impl( this, BuffDesc, BuffData ) ); + BufferD3D11Impl *pBufferD3D11( NEW(m_BufObjAllocator, "BufferD3D11Impl instance", BufferD3D11Impl, m_BuffViewObjAllocator, this, BuffDesc, BuffData ) ); pBufferD3D11->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); pBufferD3D11->CreateDefaultViews(); OnCreateDeviceObject( pBufferD3D11 ); @@ -311,25 +207,12 @@ void RenderDeviceD3D11Impl :: CreateBuffer(const BufferDesc& BuffDesc, const Buf ); } -void RenderDeviceD3D11Impl :: CreateVertexDescription(const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc) -{ - CreateDeviceObject( "vertex description", LayoutDesc, ppVertexDesc, - [&]() - { - VertexDescD3D11Impl *pDescD3D11( new VertexDescD3D11Impl( this, LayoutDesc, pVertexShader ) ); - pDescD3D11->QueryInterface( IID_VertexDescription, reinterpret_cast<IObject**>(ppVertexDesc) ); - - OnCreateDeviceObject( pDescD3D11 ); - } - ); -} - void RenderDeviceD3D11Impl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader) { CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, [&]() { - ShaderD3D11Impl *pShaderD3D11( new ShaderD3D11Impl( this, ShaderCreationAttribs ) ); + ShaderD3D11Impl *pShaderD3D11( NEW(m_ShaderObjAllocator, "ShaderD3D11Impl instance", ShaderD3D11Impl, this, ShaderCreationAttribs ) ); pShaderD3D11->QueryInterface( IID_Shader, reinterpret_cast<IObject**>(ppShader) ); OnCreateDeviceObject( pShaderD3D11 ); @@ -345,18 +228,20 @@ void RenderDeviceD3D11Impl :: CreateTexture(const TextureDesc& TexDesc, const Te TextureBaseD3D11 *pTextureD3D11 = nullptr; switch( TexDesc.Type ) { - case TEXTURE_TYPE_1D: - case TEXTURE_TYPE_1D_ARRAY: - pTextureD3D11 = new Texture1D_D3D11( this, TexDesc, Data ); + case RESOURCE_DIM_TEX_1D: + case RESOURCE_DIM_TEX_1D_ARRAY: + pTextureD3D11 = NEW(m_TexObjAllocator, "Texture1D_D3D11 instance", Texture1D_D3D11, m_TexViewObjAllocator, this, TexDesc, Data ); break; - case TEXTURE_TYPE_2D: - case TEXTURE_TYPE_2D_ARRAY: - pTextureD3D11 = new Texture2D_D3D11( this, TexDesc, Data ); + case RESOURCE_DIM_TEX_2D: + case RESOURCE_DIM_TEX_2D_ARRAY: + case RESOURCE_DIM_TEX_CUBE: + case RESOURCE_DIM_TEX_CUBE_ARRAY: + pTextureD3D11 = NEW(m_TexObjAllocator, "Texture2D_D3D11 instance", Texture2D_D3D11, m_TexViewObjAllocator, this, TexDesc, Data ); break; - case TEXTURE_TYPE_3D: - pTextureD3D11 = new Texture3D_D3D11( this, TexDesc, Data ); + case RESOURCE_DIM_TEX_3D: + pTextureD3D11 = NEW(m_TexObjAllocator, "Texture3D_D3D11 instance", Texture3D_D3D11, m_TexViewObjAllocator, this, TexDesc, Data ); break; default: LOG_ERROR_AND_THROW( "Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)" ); @@ -376,7 +261,7 @@ void RenderDeviceD3D11Impl :: CreateSampler(const SamplerDesc& SamplerDesc, ISam m_SamplersRegistry.Find( SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler) ); if( *ppSampler == nullptr ) { - SamplerD3D11Impl *pSamplerD3D11( new SamplerD3D11Impl( this, SamplerDesc ) ); + SamplerD3D11Impl *pSamplerD3D11( NEW(m_SamplerObjAllocator, "SamplerD3D11Impl instance", SamplerD3D11Impl, this, SamplerDesc ) ); pSamplerD3D11->QueryInterface( IID_Sampler, reinterpret_cast<IObject**>(ppSampler) ); OnCreateDeviceObject( pSamplerD3D11 ); m_SamplersRegistry.Add( SamplerDesc, *ppSampler ); @@ -385,54 +270,14 @@ void RenderDeviceD3D11Impl :: CreateSampler(const SamplerDesc& SamplerDesc, ISam ); } -void RenderDeviceD3D11Impl::CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState ) +void RenderDeviceD3D11Impl::CreatePipelineState(const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState) { - CreateDeviceObject( "depth-stencil state", DSSDesc, ppDepthStencilState, + CreateDeviceObject( "Pipeline state", PipelineDesc, ppPipelineState, [&]() { - m_DSSRegistry.Find( DSSDesc, reinterpret_cast<IDeviceObject**>(ppDepthStencilState) ); - if( *ppDepthStencilState == nullptr ) - { - DSStateD3D11Impl *pDepthStencilStateD3D11( new DSStateD3D11Impl( this, DSSDesc ) ); - pDepthStencilStateD3D11->QueryInterface( IID_DepthStencilState, reinterpret_cast<IObject**>(ppDepthStencilState) ); - OnCreateDeviceObject( pDepthStencilStateD3D11 ); - m_DSSRegistry.Add( DSSDesc, *ppDepthStencilState ); - } - } - ); -} - -void RenderDeviceD3D11Impl::CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState ) -{ - CreateDeviceObject( "rasterizer state", RSDesc, ppRasterizerState, - [&]() - { - m_RSRegistry.Find( RSDesc, reinterpret_cast<IDeviceObject**>(ppRasterizerState) ); - if( *ppRasterizerState == nullptr ) - { - RasterizerStateD3D11Impl *pRasterizerStateD3D11( new RasterizerStateD3D11Impl( this, RSDesc ) ); - pRasterizerStateD3D11->QueryInterface( IID_RasterizerState, reinterpret_cast<IObject**>(ppRasterizerState) ); - OnCreateDeviceObject( pRasterizerStateD3D11 ); - m_RSRegistry.Add( RSDesc, *ppRasterizerState ); - } - } - ); -} - - -void RenderDeviceD3D11Impl::CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState ) -{ - CreateDeviceObject( "blend state", BSDesc, ppBlendState, - [&]() - { - m_BSRegistry.Find( BSDesc, reinterpret_cast<IDeviceObject**>(ppBlendState) ); - if( *ppBlendState == nullptr ) - { - BlendStateD3D11Impl *pBlendStateD3D11( new BlendStateD3D11Impl( this, BSDesc ) ); - pBlendStateD3D11->QueryInterface( IID_BlendState, reinterpret_cast<IObject**>(ppBlendState) ); - OnCreateDeviceObject( pBlendStateD3D11 ); - m_BSRegistry.Add( BSDesc, *ppBlendState ); - } + PipelineStateD3D11Impl *pPipelineStateD3D11( NEW(m_PSOAllocator, "PipelineStateD3D11Impl instance", PipelineStateD3D11Impl, this, PipelineDesc ) ); + pPipelineStateD3D11->QueryInterface( IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState) ); + OnCreateDeviceObject( pPipelineStateD3D11 ); } ); } diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp index ee040562..a6f990c2 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,18 +21,19 @@ * of the possibility of such damages. */ +/// \file +/// Routines that initialize D3D11-based engine implementation + #include "pch.h" #include "RenderDeviceFactoryD3D11.h" #include "RenderDeviceD3D11Impl.h" #include "DeviceContextD3D11Impl.h" #include "SwapChainD3D11Impl.h" #include "D3D11TypeConversions.h" +#include "EngineMemory.h" #include <Windows.h> -using namespace Diligent; -using namespace Diligent; - -extern "C" +namespace Diligent { #if defined(_DEBUG) @@ -56,14 +57,29 @@ inline bool SdkLayersAvailable() } #endif -void CreateDeviceAndImmediateContextD3D11( const EngineCreationAttribs& CreationAttribs, IRenderDevice **ppDevice, Diligent::IDeviceContext **ppContext ) +/// Creates render device and device contexts for Direct3D11-based engine implementation + +/// \param [in] EngineAttribs - Engine creation attributes. +/// \param [out] ppDevice - Address of the memory location where pointer to +/// the created device will be written +/// \param [out] ppContexts - Address of the memory location where pointers to +/// the contexts will be written. Pointer to the immediate +/// context goes at position 0. If NumDeferredContexts > 0, +/// pointers to the deferred contexts go afterwards. +/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number +/// of deferred contexts is requested, pointers to the +/// contexts are written to ppContexts array starting +/// at position 1 +void CreateDeviceAndContextsD3D11( const EngineD3D11Attribs& EngineAttribs, IRenderDevice **ppDevice, IDeviceContext **ppContexts, Uint32 NumDeferredContexts ) { - VERIFY( ppDevice && ppContext, "Null pointer is provided" ); - if( !ppDevice || !ppContext ) + VERIFY( ppDevice && ppContexts, "Null pointer is provided" ); + if( !ppDevice || !ppContexts ) return; + SetRawAllocator(EngineAttribs.pRawMemAllocator); + *ppDevice = nullptr; - *ppContext = nullptr; + memset(ppContexts, 0, sizeof(*ppContexts) * (1+NumDeferredContexts)); try { @@ -86,7 +102,7 @@ void CreateDeviceAndImmediateContextD3D11( const EngineCreationAttribs& Creation // description. All applications are assumed to support 9.1 unless otherwise stated. D3D_FEATURE_LEVEL featureLevels[] = { -#ifdef PLATFORM_WINDOWS_STORE +#ifdef PLATFORM_UNIVERSAL_WINDOWS D3D_FEATURE_LEVEL_11_1, #endif D3D_FEATURE_LEVEL_11_0, @@ -98,8 +114,8 @@ void CreateDeviceAndImmediateContextD3D11( const EngineCreationAttribs& Creation }; // Create the Direct3D 11 API device object and a corresponding context. - RefCntAutoPtr<ID3D11Device> pd3d11Device; - RefCntAutoPtr<ID3D11DeviceContext> pd3d11Context; + CComPtr<ID3D11Device> pd3d11Device; + CComPtr<ID3D11DeviceContext> pd3d11Context; D3D_FEATURE_LEVEL d3dFeatureLevel = D3D_FEATURE_LEVEL_11_0; HRESULT hr = D3D11CreateDevice( @@ -135,15 +151,28 @@ void CreateDeviceAndImmediateContextD3D11( const EngineCreationAttribs& Creation CHECK_D3D_RESULT_THROW( hr, "Failed to create D3D11 Device and swap chain" ); } - RenderDeviceD3D11Impl *pRenderDeviceD3D11( new RenderDeviceD3D11Impl( pd3d11Device ) ); + auto &RawAlloctor = GetRawAllocator(); + RenderDeviceD3D11Impl *pRenderDeviceD3D11( NEW(RawAlloctor, "RenderDeviceD3D11Impl instance", RenderDeviceD3D11Impl, EngineAttribs, pd3d11Device, NumDeferredContexts ) ); pRenderDeviceD3D11->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); - RefCntAutoPtr<DeviceContextD3D11Impl> pDeviceContextD3D11( new DeviceContextD3D11Impl( pRenderDeviceD3D11, pd3d11Context) ); + RefCntAutoPtr<DeviceContextD3D11Impl> pDeviceContextD3D11( NEW(RawAlloctor, "DeviceContextD3D11Impl instance", DeviceContextD3D11Impl, pRenderDeviceD3D11, pd3d11Context, EngineAttribs, false) ); // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceD3D11 will // keep a weak reference to the context - pDeviceContextD3D11->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppContext) ); + pDeviceContextD3D11->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppContexts) ); pRenderDeviceD3D11->SetImmediateContext(pDeviceContextD3D11); - pDeviceContextD3D11->CreateDefaultStates(); + + for (Uint32 DeferredCtx = 0; DeferredCtx < NumDeferredContexts; ++DeferredCtx) + { + CComPtr<ID3D11DeviceContext> pd3d11DeferredCtx; + hr = pd3d11Device->CreateDeferredContext(0, &pd3d11DeferredCtx); + CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D11 deferred context") + + RefCntAutoPtr<DeviceContextD3D11Impl> pDeferredCtxD3D11( NEW(RawAlloctor, "DeviceContextD3D11Impl instance", DeviceContextD3D11Impl, pRenderDeviceD3D11, pd3d11DeferredCtx, EngineAttribs, true) ); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceD3D12 will + // keep a weak reference to the context + pDeferredCtxD3D11->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppContexts + 1 + DeferredCtx) ); + pRenderDeviceD3D11->SetDeferredContext(DeferredCtx, pDeferredCtxD3D11); + } } catch( const std::runtime_error & ) { @@ -152,17 +181,34 @@ void CreateDeviceAndImmediateContextD3D11( const EngineCreationAttribs& Creation (*ppDevice)->Release(); *ppDevice = nullptr; } - if( *ppContext ) + for(Uint32 ctx=0; ctx < 1 + NumDeferredContexts; ++ctx) { - (*ppContext)->Release(); - *ppContext = nullptr; + if( ppContexts[ctx] != nullptr ) + { + ppContexts[ctx]->Release(); + ppContexts[ctx] = nullptr; + } } LOG_ERROR( "Failed to create device and immediate context" ); } } -void CreateSwapChainD3D11( IRenderDevice *pDevice, Diligent::IDeviceContext *pImmediateContext, const SwapChainDesc& SwapChainDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) + +/// Creates a swap chain for Direct3D11-based engine implementation + +/// \param [in] pDevice - Pointer to the render device +/// \param [in] pImmediateContext - Pointer to the immediate device context +/// \param [in] SCDesc - Swap chain description +/// \param [in] pNativeWndHandle - Platform-specific native handle of the window +/// the swap chain will be associated with: +/// * On Win32 platform, this should be window handle (HWND) +/// * On Universal Windows Platform, this should be reference to the +/// core window (Windows::UI::Core::CoreWindow) +/// +/// \param [out] ppSwapChain - Address of the memory location where pointer to the new +/// swap chain will be written +void CreateSwapChainD3D11( IRenderDevice *pDevice, Diligent::IDeviceContext *pImmediateContext, const SwapChainDesc& SCDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) { VERIFY( ppSwapChain, "Null pointer is provided" ); if( !ppSwapChain ) @@ -174,7 +220,9 @@ void CreateSwapChainD3D11( IRenderDevice *pDevice, Diligent::IDeviceContext *pIm { auto *pDeviceD3D11 = ValidatedCast<RenderDeviceD3D11Impl>( pDevice ); auto *pDeviceContextD3D11 = ValidatedCast<DeviceContextD3D11Impl>(pImmediateContext); - auto *pSwapChainD3D11 = new SwapChainD3D11Impl(SwapChainDesc, pDeviceD3D11, pDeviceContextD3D11, pNativeWndHandle); + auto &RawMemAllocator = GetRawAllocator(); + + auto *pSwapChainD3D11 = NEW(RawMemAllocator, "SwapChainD3D11Impl instance", SwapChainD3D11Impl, SCDesc, pDeviceD3D11, pDeviceContextD3D11, pNativeWndHandle); pSwapChainD3D11->QueryInterface( IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); pDeviceContextD3D11->SetSwapChain(pSwapChainD3D11); @@ -182,6 +230,20 @@ void CreateSwapChainD3D11( IRenderDevice *pDevice, Diligent::IDeviceContext *pIm pDeviceContextD3D11->SetRenderTargets( 0, nullptr, nullptr ); // Set default viewport pDeviceContextD3D11->SetViewports( 1, nullptr, 0, 0 ); + + auto NumDeferredCtx = pDeviceD3D11->GetNumDeferredContexts(); + for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) + { + if (auto pDeferredCtx = pDeviceD3D11->GetDeferredContext(ctx)) + { + auto *pDeferredCtxD3D11 = ValidatedCast<DeviceContextD3D11Impl>(pDeferredCtx.RawPtr()); + pDeferredCtxD3D11->SetSwapChain(pSwapChainD3D11); + // Bind default render target + pDeferredCtxD3D11->SetRenderTargets( 0, nullptr, nullptr ); + // Set default viewport + pDeferredCtxD3D11->SetViewports( 1, nullptr, 0, 0 ); + } + } } catch( const std::runtime_error & ) { @@ -195,4 +257,39 @@ void CreateSwapChainD3D11( IRenderDevice *pDevice, Diligent::IDeviceContext *pIm } } +#ifdef DOXYGEN +/// Loads Direct3D11-based engine implementation and exports factory functions +/// \param [out] CreateDeviceFunc - Pointer to the function that creates render device and device contexts. +/// See CreateDeviceAndContextsD3D11(). +/// \param [out] CreateSwapChainFunc - Pointer to the function that creates swap chain. +/// See CreateSwapChainD3D11(). +/// \remarks Depending on the configuration and platform, the function loads different dll: +/// Platform\\Configuration | Debug | Release +/// --------------------------|-------------------------------|---------------------------- +/// x86 | GraphicsEngineD3D11_32d.dll | GraphicsEngineD3D11_32r.dll +/// x64 | GraphicsEngineD3D11_64d.dll | GraphicsEngineD3D11_64r.dll +/// +void LoadGraphicsEngineD3D11(CreateDeviceAndContextsD3D11Type &CreateDeviceFunc, CreateSwapChainD3D11Type &CreateSwapChainFunc) +{ + // This function is only required because DoxyGen refuses to generate documentation for a static function when SHOW_FILES==NO + #error This function must never be compiled; +} +#endif + +} + + +using namespace Diligent; +extern "C" +{ + void CreateDeviceAndContextsD3D11(const EngineD3D11Attribs& EngineAttribs, IRenderDevice **ppDevice, IDeviceContext **ppContexts, Uint32 NumDeferredContexts) + { + Diligent::CreateDeviceAndContextsD3D11(EngineAttribs, ppDevice, ppContexts, NumDeferredContexts); + } + + + void CreateSwapChainD3D11(IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SwapChainDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain) + { + Diligent::CreateSwapChainD3D11(pDevice, pImmediateContext, SwapChainDesc, pNativeWndHandle, ppSwapChain); + } } diff --git a/Graphics/GraphicsEngineD3D11/src/SamplerD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SamplerD3D11Impl.cpp index 3aa13c74..29c316a6 100644 --- a/Graphics/GraphicsEngineD3D11/src/SamplerD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/SamplerD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,8 +29,8 @@ namespace Diligent { -SamplerD3D11Impl::SamplerD3D11Impl(class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const SamplerDesc& SamplerDesc) : - TSamplerBase(pRenderDeviceD3D11, SamplerDesc) +SamplerD3D11Impl::SamplerD3D11Impl(FixedBlockMemoryAllocator &SamplerObjAllocator, class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const SamplerDesc& SamplerDesc) : + TSamplerBase(SamplerObjAllocator, pRenderDeviceD3D11, SamplerDesc) { auto *pd3d11Device = pRenderDeviceD3D11->GetD3D11Device(); D3D11_SAMPLER_DESC D3D11SamplerDesc = diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp index 651261ac..83a8c33b 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,354 +23,22 @@ #include "pch.h" -#include <D3Dcompiler.h> - #include "ShaderD3D11Impl.h" #include "RenderDeviceD3D11Impl.h" -#include "StringTools.h" #include "ResourceMapping.h" -#include "BufferD3D11Impl.h" -#include "GraphicsUtilities.h" -#include "TextureViewD3D11Impl.h" -#include "SamplerD3D11Impl.h" -#include "BufferViewD3D11Impl.h" -#include "D3D11DebugUtilities.h" -#include "DataBlobImpl.h" - -using namespace Diligent; namespace Diligent { -const String ShaderD3D11Impl::m_SamplerSuffix = "_sampler"; -const UINT InvalidBindPoint = std::numeric_limits<UINT>::max(); - -static const Char* g_HLSLDefinitions = -{ - #include "HLSLDefinitions_inc.fxh" -}; - - -class D3DIncludeImpl : public ID3DInclude -{ -public: - D3DIncludeImpl(IShaderSourceInputStreamFactory *pStreamFactory) : - m_pStreamFactory(pStreamFactory) - { - - } - - STDMETHOD( Open )(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) - { - RefCntAutoPtr<IFileStream> pSourceStream; - m_pStreamFactory->CreateInputStream( pFileName, &pSourceStream ); - if( pSourceStream == nullptr ) - { - LOG_ERROR( "Failed to open shader include file ", pFileName, ". Check that the file exists" ); - return E_FAIL; - } - - RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl ); - pSourceStream->Read( pFileData ); - *ppData = pFileData->GetDataPtr(); - *pBytes = static_cast<UINT>( pFileData->GetSize() ); - - m_DataBlobs.insert( std::make_pair(*ppData, pFileData) ); - - return S_OK; - } - - STDMETHOD( Close )(THIS_ LPCVOID pData) - { - m_DataBlobs.erase( pData ); - return S_OK; - } - -private: - IShaderSourceInputStreamFactory *m_pStreamFactory; - std::unordered_map< LPCVOID, RefCntAutoPtr<Diligent::IDataBlob> > m_DataBlobs; -}; - -static -HRESULT CompileShader( const char* Source, - LPCSTR strFunctionName, - const D3D_SHADER_MACRO* pDefines, - IShaderSourceInputStreamFactory *pIncludeStreamFactory, - LPCSTR profile, - ID3DBlob **ppBlobOut ) -{ - DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; -#if defined( DEBUG ) || defined( _DEBUG ) - // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders. - // Setting this flag improves the shader debugging experience, but still allows - // the shaders to be optimized and to run exactly the way they will run in - // the release configuration of this program. - dwShaderFlags |= D3DCOMPILE_DEBUG; -#else - // Warning: do not use this flag as it causes shader compiler to fail the compilation and - // report strange errors: - // dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3; -#endif - HRESULT hr; - do - { - CComPtr<ID3DBlob> errors; - auto SourceLen = strlen(Source); - - D3DIncludeImpl IncludeImpl(pIncludeStreamFactory); - hr = D3DCompile( Source, SourceLen, NULL, pDefines, &IncludeImpl, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, &errors ); - - if( FAILED(hr) || errors ) - { - std::wstringstream errorss; - ComErrorDesc ErrDesc(hr); - if( FAILED(hr) ) - Diligent::FormatMsg( errorss, "Failed to compile shader\n" ); - else - Diligent::FormatMsg( errorss, "Shader compiler output:\n" ); - Diligent::FormatMsg( errorss, ErrDesc.Get(), "\n" ); - if( errors ) - Diligent::FormatMsg( errorss, (char*)errors->GetBufferPointer() ); - auto ErrorDesc = errorss.str(); - OutputDebugString( ErrorDesc.c_str() ); - if( FAILED(hr) -#ifdef PLATFORM_WINDOWS - && IDRETRY != MessageBox( NULL, ErrorDesc.c_str() , L"FX Error", MB_ICONERROR | (Source == nullptr ? MB_ABORTRETRYIGNORE : 0) ) -#endif - ) - { - break; - } - } - } while( FAILED(hr) ); - return hr; -} - -const char* DXShaderProfileToString(SHADER_PROFILE DXProfile) -{ - return "5_0"; - //switch(DXProfile) - //{ - // case DX_SHADER_PROFILE_4_0: return "4_0"; - // case DX_SHADER_PROFILE_5_0: return "5_0"; - // default: UNEXPECTED("Unknown DirectX shader profile" ); return ""; - //} -} - -void ShaderD3D11Impl::LoadShaderResources() -{ - CComPtr<ID3D11ShaderReflection> pShaderReflection; - CHECK_D3D_RESULT_THROW( D3DReflect( m_pShaderByteCode->GetBufferPointer(), m_pShaderByteCode->GetBufferSize(), __uuidof(pShaderReflection), reinterpret_cast<void**>(static_cast<ID3D11ShaderReflection**>(&pShaderReflection)) ), - "Failed to get the shader reflection" ); - - struct ResourceBindInfo - { - String Name; - UINT BindPoint; - }; - - std::vector<ResourceBindInfo> Textures; - std::unordered_map<String, ResourceBindInfo> Samplers; - - D3D11_SHADER_DESC shaderDesc; - memset( &shaderDesc, 0, sizeof(shaderDesc) ); - pShaderReflection->GetDesc( &shaderDesc ); - for( UINT Res = 0; Res < shaderDesc.BoundResources; ++Res ) - { - D3D11_SHADER_INPUT_BIND_DESC BindingDesc; - memset( &BindingDesc, 0, sizeof( BindingDesc ) ); - pShaderReflection->GetResourceBindingDesc( Res, &BindingDesc ); - - switch( BindingDesc.Type ) - { - case D3D_SIT_CBUFFER: - { - ConstBuffBindInfo NewCBInfo(this, BindingDesc.Name, BindingDesc.BindPoint); -#ifdef _DEBUG - std::for_each( m_ConstanBuffers.begin(), m_ConstanBuffers.end(), - [&]( const ConstBuffBindInfo &CBInfo ) - { - VERIFY( CBInfo.Name != BindingDesc.Name, "Constant buffer with the same name already exists" ); - } - ); -#endif - m_ConstanBuffers.emplace_back( NewCBInfo ); - break; - } - - case D3D_SIT_TBUFFER: - { - UNSUPPORTED( "TBuffers are not supported" ); - break; - } - - case D3D_SIT_TEXTURE: - { - - if( BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ) - { - m_BuffSRVs.emplace_back( BuffSRVBindInfo(this, BindingDesc.Name, BindingDesc.BindPoint) ); - } - else - { - ResourceBindInfo NewTextureInfo = { BindingDesc.Name, BindingDesc.BindPoint }; - Textures.emplace_back( NewTextureInfo ); - } - break; - } - - case D3D_SIT_SAMPLER: - { - ResourceBindInfo NewSamplerInfo = { BindingDesc.Name, BindingDesc.BindPoint }; - Samplers.emplace( std::make_pair( BindingDesc.Name, NewSamplerInfo ) ); - break; - } - - case D3D_SIT_UAV_RWTYPED: - { - if( BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ) - { - m_BuffUAVs.push_back( BuffUAVBindInfo( this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type ) ); - } - else - { - m_TexUAVs.push_back( TexUAVBindInfo( this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type ) ); - } - break; - } - - case D3D_SIT_STRUCTURED: - { - UNSUPPORTED( "Structured buffers are not supported" ); - break; - } - - case D3D_SIT_UAV_RWSTRUCTURED: - { - m_BuffUAVs.push_back( BuffUAVBindInfo( this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type ) ); - break; - } - - case D3D_SIT_BYTEADDRESS: - { - UNSUPPORTED( "Byte address buffers are not supported" ); - break; - } - - case D3D_SIT_UAV_RWBYTEADDRESS: - { - m_BuffUAVs.push_back( BuffUAVBindInfo(this, BindingDesc.Name, BindingDesc.BindPoint, BindingDesc.Type) ); - break; - } - - case D3D_SIT_UAV_APPEND_STRUCTURED: - { - UNSUPPORTED( "Append structured buffers are not supported" ); - break; - } - - case D3D_SIT_UAV_CONSUME_STRUCTURED: - { - UNSUPPORTED( "Consume structured buffers are not supported" ); - break; - } - - case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: - { - UNSUPPORTED( "RW structured buffers with counter are not supported" ); - break; - } - } - } - - // Merge texture and sampler list - for( auto it = Textures.begin(); it != Textures.end(); ++it ) - { - auto SamplerName = it->Name + m_SamplerSuffix; - auto SamplerIt = Samplers.find(SamplerName); - UINT SamplerBindPoint = InvalidBindPoint; - if( SamplerIt != Samplers.end() ) - { - VERIFY( SamplerIt->second.Name == SamplerName, "Unexpected sampler name" ); - SamplerBindPoint = SamplerIt->second.BindPoint; - } - else - { - SamplerName = ""; - } - TexAndSamplerBindInfo TexAndSamplerInfo(this, it->Name, it->BindPoint, SamplerName, SamplerBindPoint); - m_TexAndSamplers.emplace_back( TexAndSamplerInfo ); - } - // After all resources are loaded, we can populate shader variable hash map. - // The map contains raw pointers, but none of the arrays will ever change. -#define STORE_SHADER_VARIABLES(ResArr)\ - { \ - for( auto it = ResArr.begin(); it != ResArr.end(); ++it ) \ - /* HashMapStringKey will make a copy of the string*/ \ - m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(it->GetName()), &*it ) ); \ - } - - STORE_SHADER_VARIABLES(m_ConstanBuffers) - STORE_SHADER_VARIABLES(m_TexAndSamplers) - STORE_SHADER_VARIABLES(m_TexUAVs) - STORE_SHADER_VARIABLES(m_BuffUAVs) - STORE_SHADER_VARIABLES(m_BuffSRVs) - -#undef STORE_SHADER_VARIABLES -} - -ShaderD3D11Impl::ShaderD3D11Impl(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const ShaderCreationAttribs &ShaderCreationAttribs) : - TShaderBase(pRenderDeviceD3D11, ShaderCreationAttribs.Desc) +ShaderD3D11Impl::ShaderD3D11Impl(FixedBlockMemoryAllocator &ShaderObjAllocator, RenderDeviceD3D11Impl *pRenderDeviceD3D11, const ShaderCreationAttribs &CreationAttribs) : + TShaderBase(ShaderObjAllocator, pRenderDeviceD3D11, CreationAttribs.Desc), + ShaderD3DBase(CreationAttribs), + m_StaticResLayout(*this, GetRawAllocator()), + m_ShaderTypeIndex(Diligent::GetShaderTypeIndex(CreationAttribs.Desc.ShaderType)), + m_DummyShaderVar(*this) { - std::string strShaderProfile; - switch(ShaderCreationAttribs.Desc.ShaderType) - { - case SHADER_TYPE_VERTEX: strShaderProfile="vs"; break; - case SHADER_TYPE_PIXEL: strShaderProfile="ps"; break; - case SHADER_TYPE_GEOMETRY:strShaderProfile="gs"; break; - case SHADER_TYPE_HULL: strShaderProfile="hs"; break; - case SHADER_TYPE_DOMAIN: strShaderProfile="ds"; break; - case SHADER_TYPE_COMPUTE: strShaderProfile="cs"; break; - - default: UNEXPECTED( "Unknown shader type" ); - } - strShaderProfile += "_"; - auto *pProfileSuffix = DXShaderProfileToString(ShaderCreationAttribs.Desc.TargetProfile); - strShaderProfile += pProfileSuffix; - - String ShaderSource(g_HLSLDefinitions); - if( ShaderCreationAttribs.Source ) - ShaderSource.append( ShaderCreationAttribs.Source ); - else - { - VERIFY(ShaderCreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null"); - RefCntAutoPtr<IFileStream> pSourceStream; - ShaderCreationAttribs.pShaderSourceStreamFactory->CreateInputStream( ShaderCreationAttribs.FilePath, &pSourceStream ); - RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl ); - pSourceStream->Read( pFileData ); - // Null terminator is not read from the stream! - auto* FileDataPtr = reinterpret_cast<Char*>( pFileData->GetDataPtr() ); - auto Size = pFileData->GetSize(); - ShaderSource.append( FileDataPtr, FileDataPtr + Size/sizeof(*FileDataPtr) ); - } - - const D3D_SHADER_MACRO *pDefines = nullptr; - std::vector<D3D_SHADER_MACRO> D3DMacros; - if( ShaderCreationAttribs.Macros ) - { - for( auto* pCurrMacro = ShaderCreationAttribs.Macros; pCurrMacro->Name && pCurrMacro->Definition; ++pCurrMacro ) - { - D3DMacros.push_back( {pCurrMacro->Name, pCurrMacro->Definition} ); - } - D3DMacros.push_back( {nullptr, nullptr} ); - pDefines = D3DMacros.data(); - } - - CHECK_D3D_RESULT_THROW( CompileShader( ShaderSource.c_str(), ShaderCreationAttribs.EntryPoint, pDefines, ShaderCreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode ), - "Failed to compile the shader"); - auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); - switch(ShaderCreationAttribs.Desc.ShaderType) + switch(CreationAttribs.Desc.ShaderType) { #define CREATE_SHADER(SHADER_NAME, ShaderName)\ @@ -400,439 +68,43 @@ ShaderD3D11Impl::ShaderD3D11Impl(RenderDeviceD3D11Impl *pRenderDeviceD3D11, cons if(!m_pShader) LOG_ERROR_AND_THROW("Failed to create the shader from the byte code"); - LoadShaderResources(); + // Load shader resources + auto &Allocator = GetRawAllocator(); + auto *pRawMem = ALLOCATE(Allocator, "Allocator for ShaderResources", sizeof(ShaderResourcesD3D11)); + auto *pResources = new (pRawMem) ShaderResourcesD3D11(pRenderDeviceD3D11, m_pShaderByteCode, m_Desc); + m_pShaderResources.reset(pResources, STDDeleterRawMem<ShaderResourcesD3D11>(Allocator)); + + // Clone only static resources that will be set directly in the shader + SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_STATIC}; + // The method will also initialize resource cache to have enough space to hold static variables only! + m_StaticResLayout.Initialize(m_pShaderResources, VarTypes, _countof(VarTypes), m_StaticResCache, GetRawAllocator(), GetRawAllocator()); + + // This is not required, but still... + m_pShaderResources->InitStaticSamplers(m_StaticResCache); // Byte code is only required for the vertex shader to create input layout - if( ShaderCreationAttribs.Desc.ShaderType != SHADER_TYPE_VERTEX ) + if( CreationAttribs.Desc.ShaderType != SHADER_TYPE_VERTEX ) m_pShaderByteCode.Release(); } ShaderD3D11Impl::~ShaderD3D11Impl() { + m_StaticResCache.Destroy(GetRawAllocator()); } -#define LOG_RESORUCE_BINDING_ERROR(ResType, pResource, VarName, ShaderName, ...)\ -{ \ - const auto &ResName = pResource->GetDesc().Name; \ - LOG_ERROR_MESSAGE( "Failed to bind ", ResType, " \"", ResName, "\" to variable \"", VarName, \ - "\" in shader \"", ShaderName, "\". ", __VA_ARGS__ ); \ -} - -void ShaderD3D11Impl::BindConstantBuffers( IResourceMapping* pResourceMapping, Uint32 Flags ) -{ - if( !pResourceMapping ) - { - LOG_ERROR_MESSAGE( "Failed to bind constant buffers in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); - return; - } - // Bind constant buffers - if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) - { - m_BoundCBs.clear(); - } - for( auto it = m_ConstanBuffers.begin(); it != m_ConstanBuffers.end(); ++it ) - { - if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && it->IsBound() ) - continue; - - RefCntAutoPtr<IDeviceObject> pBuffer; - if( pResourceMapping ) - pResourceMapping->GetResource( it->Name.c_str(), &pBuffer ); - if( pBuffer ) - { - it->Set( pBuffer ); - } - else - { - if( (Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED) && !it->IsBound() ) - LOG_ERROR_MESSAGE("Cannot bind resource to shader variable \"", it->Name, "\": resource not found in the resource mapping") - continue; - } - } -} - - -void ShaderD3D11Impl::ConstBuffBindInfo::Set( IDeviceObject *pBuffer ) -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - auto &BoundCBs = pShaderD3D11->m_BoundCBs; - if( BoundCBs.size() <= BindPoint ) - BoundCBs.resize( BindPoint + 1 ); - - if( pBuffer ) - { - RefCntAutoPtr<IBufferD3D11> pBuffD3D11; - pBuffer->QueryInterface( IID_BufferD3D11, reinterpret_cast<IObject**>(static_cast<IBufferD3D11**>(&pBuffD3D11)) ); - if( pBuffD3D11 ) - { - if( pBuffD3D11->GetDesc().BindFlags & BIND_UNIFORM_BUFFER ) - { - BoundCBs[BindPoint].pd3d11Buff = pBuffD3D11->GetD3D11Buffer(); - VERIFY(BoundCBs[BindPoint].pd3d11Buff, "No relevant D3D11 buffer") - BoundCBs[BindPoint].pBuff = pBuffD3D11; - } - else - { - LOG_RESORUCE_BINDING_ERROR("buffer", pBuffer, Name, pShaderD3D11->m_Desc.Name, "Buffer was not created with BIND_UNIFORM_BUFFER flag.") - } - } - else - { - LOG_RESORUCE_BINDING_ERROR("buffer", pBuffer, Name, pShaderD3D11->m_Desc.Name, "Incorrect resource type: buffer is expected.") - } - } - else - { - BoundCBs[BindPoint] = BoundCB(); - } -} - -bool ShaderD3D11Impl::ConstBuffBindInfo::IsBound() -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - auto &BoundCBs = pShaderD3D11->m_BoundCBs; - if( BindPoint < BoundCBs.size() && BoundCBs[BindPoint].pd3d11Buff != nullptr ) - { - VERIFY(BoundCBs[BindPoint].pBuff != nullptr, "No relevant buffer resource") - return true; - } - - return false; -} - -template<typename TResourceViewType> -struct ResourceViewTraits{}; - -template<> -struct ResourceViewTraits<ITextureViewD3D11> -{ - static const Char *Name; -}; -const Char *ResourceViewTraits<ITextureViewD3D11>::Name = "texture view"; - -template<> -struct ResourceViewTraits<IBufferViewD3D11> -{ - static const Char *Name; -}; -const Char *ResourceViewTraits<IBufferViewD3D11>::Name = "buffer view"; - -// Helper template class that facilitates binding SRVs and UAVs -class BindViewHelper -{ -public: - BindViewHelper(IResourceMapping *pRM, Uint32 Fl) : - pResourceMapping(pRM), - Flags(Fl) - {} - - template<typename IterType> - void Bind( IterType &pShaderVar) - { - if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && pShaderVar->IsBound() ) - return; - - const auto& VarName = pShaderVar->GetName(); - RefCntAutoPtr<IDeviceObject> pView; - if( pResourceMapping ) - pResourceMapping->GetResource( VarName.c_str(), &pView ); - if( pView ) - { - pShaderVar->Set(pView); - } - else - { - if( (Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED) && !pShaderVar->IsBound() ) - LOG_ERROR_MESSAGE( "Cannot bind resource to shader variable \"", VarName, "\": resource view not found in the resource mapping" ) - return; - } - } - -private: - IResourceMapping* const pResourceMapping; - const Uint32 Flags; -}; - -// Helper template function to facilitate setting shader variables -// of different types -template<typename TResourceViewType, ///< Type of the view (ITextureViewD3D11 or IBufferViewD3D11) - typename TD3D11ViewType, ///< Type of the D3D11 view (ID3D11ShaderResourceView or ID3D11UnorderedAccessView) - typename TBoundViewType, ///< Type of the bound view data array element (BoundSRV or BoundUAV) - typename TGetResourceMethodType, ///< Type of the method to get resource from the view (ITextureViewD3D11::GetTexture or IBufferViewD3D11::GetBuffer) - typename TBindSamplerProcType, ///< Type of the procedure to set samplers - typename TViewTypeEnum> ///< Type of the expected view enum -void SetShaderVariableHelper(IDeviceObject *pView, - std::vector<TBoundViewType> &ViewArray, - UINT BindPoint, - const String& VarName, - TGetResourceMethodType GetResourceMethod, - const Diligent::INTERFACE_ID ViewID, - typename TViewTypeEnum ExpectedViewType, - const String& ShaderName, - TBindSamplerProcType BindSamplerProc) -{ - if( ViewArray.size() <= BindPoint ) - ViewArray.resize( BindPoint + 1 ); - if( pView ) - { - RefCntAutoPtr<TResourceViewType> pViewD3D11; - pView->QueryInterface( ViewID, reinterpret_cast<IObject**>(static_cast<TResourceViewType**>(&pViewD3D11)) ); - if( pViewD3D11 ) - { - auto ViewType = pViewD3D11->GetDesc().ViewType; - if( ViewType == ExpectedViewType ) - { - auto &BoundView = ViewArray[BindPoint]; - BoundView.pd3d11View = static_cast<TD3D11ViewType*>( pViewD3D11->GetD3D11View() ); - VERIFY(BoundView.pd3d11View, "No relevant D3D11 view") - BoundView.pView = pViewD3D11; - BoundView.pResource = (pViewD3D11->*GetResourceMethod)(); - VERIFY(BoundView.pResource, "No relevant resource") - BindSamplerProc(pViewD3D11); - } - else - { - const auto *ExpectedViewTypeName = GetViewTypeLiteralName( ExpectedViewType ); - const auto *ActualViewTypeName = GetViewTypeLiteralName( ViewType ); - LOG_RESORUCE_BINDING_ERROR(ResourceViewTraits<TResourceViewType>::Name, pViewD3D11, VarName, ShaderName, - "Incorrect view type: ", ExpectedViewTypeName, " is expected, ", ActualViewTypeName, " provided." ); - } - } - else - { - LOG_RESORUCE_BINDING_ERROR("resource", pView, VarName, ShaderName, "Incorect resource type: ", ResourceViewTraits<TResourceViewType>::Name, " is expected.") - } - } - else - { - ViewArray[BindPoint] = TBoundViewType(); - BindSamplerProc(nullptr); - } -} - -void ShaderD3D11Impl::TexAndSamplerBindInfo::Set( IDeviceObject *pView ) -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - SetShaderVariableHelper<ITextureViewD3D11, ID3D11ShaderResourceView>(pView, pShaderD3D11->m_BoundSRVs, BindPoint, Name, - &ITextureViewD3D11::GetTexture, IID_TextureViewD3D11, TEXTURE_VIEW_SHADER_RESOURCE, - pShaderD3D11->m_Desc.Name, - [&]( ITextureViewD3D11 *pTexViewD3D11 ) - { - if( SamplerBindPoint != InvalidBindPoint ) - { - auto &BoundSamplers = pShaderD3D11->m_BoundSamplers; - if( BoundSamplers.size() <= SamplerBindPoint ) - BoundSamplers.resize( SamplerBindPoint + 1 ); - auto &BndSam = BoundSamplers[SamplerBindPoint]; - if( pTexViewD3D11 ) - { - auto pSampler = pTexViewD3D11->GetSampler(); - if( pSampler ) - { - BndSam.pd3d11Sampler = ValidatedCast<SamplerD3D11Impl>(pSampler)->m_pd3dSampler; - VERIFY(BndSam.pd3d11Sampler, "No relevant D3D11 sampler") - BndSam.pSampler = pSampler; - } - else - { - LOG_ERROR_MESSAGE( "Failed to bind sampler to variable \"", SamplerName, ". Sampler is not set in the texture view \"", pTexViewD3D11->GetDesc().Name, "\"" ); - } - } - else - { - BndSam = BoundSampler(); - } - } - } - ); - -} - -void ShaderD3D11Impl::BuffSRVBindInfo::Set( IDeviceObject *pView ) -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - SetShaderVariableHelper<IBufferViewD3D11, ID3D11ShaderResourceView>(pView, pShaderD3D11->m_BoundSRVs, BindPoint, Name, - &IBufferViewD3D11::GetBuffer, IID_BufferViewD3D11, BUFFER_VIEW_SHADER_RESOURCE, - pShaderD3D11->m_Desc.Name, - []( IBufferViewD3D11 * ){} - ); -} - -void ShaderD3D11Impl::TexUAVBindInfo::Set( IDeviceObject *pView ) -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - SetShaderVariableHelper<ITextureViewD3D11, ID3D11UnorderedAccessView>( - pView, pShaderD3D11->m_BoundUAVs, BindPoint, Name, - &ITextureViewD3D11::GetTexture, IID_TextureViewD3D11, TEXTURE_VIEW_UNORDERED_ACCESS, - pShaderD3D11->m_Desc.Name, - []( ITextureViewD3D11 * ){} - ); -} - -void ShaderD3D11Impl::BuffUAVBindInfo::Set( IDeviceObject *pView ) -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - SetShaderVariableHelper<IBufferViewD3D11, ID3D11UnorderedAccessView>(pView, pShaderD3D11->m_BoundUAVs, BindPoint, Name, - &IBufferViewD3D11::GetBuffer, IID_BufferViewD3D11, BUFFER_VIEW_UNORDERED_ACCESS, - pShaderD3D11->m_Desc.Name, - []( IBufferViewD3D11 * ){} - ); -} - -template<typename TBoundViewType> -bool CheckBoundResource(const std::vector<TBoundViewType> &ViewArray, UINT BindPoint) -{ - if( BindPoint < ViewArray.size() && ViewArray[BindPoint].pd3d11View != nullptr ) - { - VERIFY(ViewArray[BindPoint].pResource != nullptr, "No relevant resource") - VERIFY(ViewArray[BindPoint].pView != nullptr, "No relevant resource view") - return true; - } - return false; -} - -bool ShaderD3D11Impl::TexAndSamplerBindInfo::IsBound() -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - return CheckBoundResource( pShaderD3D11->m_BoundSRVs, BindPoint ); -} - -bool ShaderD3D11Impl::BuffSRVBindInfo::IsBound() -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - return CheckBoundResource( pShaderD3D11->m_BoundSRVs, BindPoint ); -} - -bool ShaderD3D11Impl::UAVBindInfoBase::IsBound() -{ - auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( m_pShader ); - return CheckBoundResource( pShaderD3D11->m_BoundUAVs, BindPoint ); -} - -void ShaderD3D11Impl::BindSRVsAndSamplers(IResourceMapping* pResourceMapping, Uint32 Flags ) -{ - if( !pResourceMapping ) - { - LOG_ERROR_MESSAGE( "Failed to bind SRVs and samplers in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); - return; - } - - if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) - { - m_BoundSRVs.clear(); - m_BoundSamplers.clear(); - } - - BindViewHelper BindSRVHelper(pResourceMapping, Flags); - - for( auto it = m_TexAndSamplers.begin(); it != m_TexAndSamplers.end(); ++it ) - { - BindSRVHelper.Bind(it); - } - - for( auto it = m_BuffSRVs.begin(); it != m_BuffSRVs.end(); ++it ) - { - BindSRVHelper.Bind(it); - } -} - -void ShaderD3D11Impl::BindUAVs( IResourceMapping* pResourceMapping, Uint32 Flags ) -{ - if( !pResourceMapping ) - { - LOG_ERROR_MESSAGE( "Failed to bind UAVs in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); - return; - } - - // Bind constant buffers - if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) - { - m_BoundUAVs.clear(); - } - - BindViewHelper BindUAVHelper(pResourceMapping, Flags); - - for( auto it = m_TexUAVs.begin(); it != m_TexUAVs.end(); ++it ) - { - BindUAVHelper.Bind(it); - } - - for( auto it = m_BuffUAVs.begin(); it != m_BuffUAVs.end(); ++it ) - { - BindUAVHelper.Bind(it); - } -} - -void ShaderD3D11Impl::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags ) -{ - if( !pResourceMapping ) - { - LOG_ERROR_MESSAGE( "Failed to bind resources in shader \"", m_Desc.Name ? m_Desc.Name : "", "\": resource mapping is null" ); - return; - } - - BindConstantBuffers( pResourceMapping, Flags ); - BindSRVsAndSamplers( pResourceMapping, Flags ); - BindUAVs(pResourceMapping, Flags ); -} +IMPLEMENT_QUERY_INTERFACE( ShaderD3D11Impl, IID_ShaderD3D11, TShaderBase ) IShaderVariable* ShaderD3D11Impl::GetShaderVariable( const Char* Name ) { - // Name will be implicitly converted to HashMapStringKey without making a copy - auto it = m_VariableHash.find( Name ); - if( it == m_VariableHash.end() ) - { - LOG_ERROR_MESSAGE( "Shader variable \"", Name, "\" is not found in shader \"", m_Desc.Name ? m_Desc.Name : "", "\". Attempts to set the variable will be silently ignored." ); - return &m_DummyShaderVar; - } - return it->second; + auto *pVar = m_StaticResLayout.GetShaderVariable(Name); + if(pVar == nullptr) + pVar = &m_DummyShaderVar; + return pVar; } - - -IMPLEMENT_QUERY_INTERFACE( ShaderD3D11Impl, IID_ShaderD3D11, TShaderBase ) - -#ifdef VERIFY_SHADER_BINDINGS -void ShaderD3D11Impl::dbgVerifyBindings() +void ShaderD3D11Impl::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) { - const auto *ShaderName = m_Desc.Name ? m_Desc.Name : ""; -#define LOG_MISSING_BINDING(VarType, Name)\ - LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", Name, "\" in shader \"", ShaderName, "\"" ); - - for( auto cb = m_ConstanBuffers.begin(); cb != m_ConstanBuffers.end(); ++cb ) - { - if( m_BoundCBs.size() <= cb->BindPoint || m_BoundCBs[cb->BindPoint].pd3d11Buff == nullptr ) - LOG_MISSING_BINDING("constant buffer", cb->Name) - } - - for( auto tex = m_TexAndSamplers.begin(); tex != m_TexAndSamplers.end(); ++tex ) - { - if( m_BoundSRVs.size() <= tex->BindPoint || m_BoundSRVs[tex->BindPoint].pd3d11View == nullptr ) - LOG_MISSING_BINDING("texture", tex->Name) - - if( tex->SamplerBindPoint != InvalidBindPoint && - (m_BoundSamplers.size() <= tex->SamplerBindPoint || m_BoundSamplers[tex->SamplerBindPoint].pd3d11Sampler == nullptr) ) - LOG_MISSING_BINDING("sampler", tex->SamplerName) - } - - for( auto buf = m_BuffSRVs.begin(); buf != m_BuffSRVs.end(); ++buf ) - { - if( m_BoundSRVs.size() <= buf->BindPoint || m_BoundSRVs[buf->BindPoint].pd3d11View == nullptr ) - LOG_MISSING_BINDING("buffer", buf->Name) - } - - for( auto uav = m_TexUAVs.begin(); uav != m_TexUAVs.end(); ++uav ) - { - if( m_BoundUAVs.size() <= uav->BindPoint || m_BoundUAVs[uav->BindPoint].pd3d11View == nullptr ) - LOG_MISSING_BINDING("texture UAV", uav->Name) - } - - for( auto uav = m_BuffUAVs.begin(); uav != m_BuffUAVs.end(); ++uav ) - { - if( m_BoundUAVs.size() <= uav->BindPoint || m_BoundUAVs[uav->BindPoint].pd3d11View == nullptr ) - LOG_MISSING_BINDING("buffer UAV", uav->Name) - } + m_StaticResLayout.BindResources(pResourceMapping, Flags, m_StaticResCache); } -#endif } diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp new file mode 100644 index 00000000..37dd96f8 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp @@ -0,0 +1,168 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "ShaderResourceBindingD3D11Impl.h" +#include "PipelineStateD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" +#include "RenderDeviceD3D11Impl.h" + +namespace Diligent +{ + + +ShaderResourceBindingD3D11Impl::ShaderResourceBindingD3D11Impl( FixedBlockMemoryAllocator &SRBAllocator, PipelineStateD3D11Impl *pPSO, bool IsInternal) : + TBase( SRBAllocator, pPSO, IsInternal ), + m_bIsStaticResourcesBound(false) +{ + for(size_t s=0; s < _countof(m_ResourceLayoutIndex); ++s) + m_ResourceLayoutIndex[s] = -1; + + auto ppShaders = pPSO->GetShaders(); + m_NumActiveShaders = static_cast<Uint8>( pPSO->GetNumShaders() ); + + auto *pResLayoutRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D11", m_NumActiveShaders * sizeof(ShaderResourceLayoutD3D11)); + m_pResourceLayouts = reinterpret_cast<ShaderResourceLayoutD3D11*>(pResLayoutRawMem); + + auto *pResCacheRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheD3D11", m_NumActiveShaders * sizeof(ShaderResourceCacheD3D11)); + m_pBoundResourceCaches = reinterpret_cast<ShaderResourceCacheD3D11*>(pResCacheRawMem); + + // Reserve memory for resource layouts + for (Uint8 s = 0; s < m_NumActiveShaders; ++s) + { + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>(ppShaders[s]); + auto ShaderInd = pShaderD3D11->GetShaderTypeIndex(); + VERIFY_EXPR(static_cast<Int32>(ShaderInd) == GetShaderTypeIndex(pShaderD3D11->GetDesc().ShaderType)); + + SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC}; + + auto &ResCacheDataAllocator = pPSO->GetResourceCacheDataAllocator(s); + auto &ResLayoutDataAllocator = pPSO->GetShaderResLayoutDataAllocators(s); + + // Initialize resource cache to have enough space to contain all shader resources, including static ones + // Static resources are copied before resources are committed + const auto &Resources = *pShaderD3D11->GetResources(); + auto CBCount = Resources.GetMaxCBBindPoint()+1; + auto SRVCount = Resources.GetMaxSRVBindPoint()+1; + auto SamplerCount = Resources.GetMaxSamplerBindPoint()+1; + auto UAVCount = Resources.GetMaxUAVBindPoint()+1; + new (m_pBoundResourceCaches+s) ShaderResourceCacheD3D11; + m_pBoundResourceCaches[s].Initialize(CBCount, SRVCount, SamplerCount, UAVCount, ResCacheDataAllocator); + + new (m_pResourceLayouts + s) ShaderResourceLayoutD3D11(*this, ResLayoutDataAllocator); + m_pResourceLayouts[s].Initialize(pShaderD3D11->GetResources(), VarTypes, _countof(VarTypes), m_pBoundResourceCaches[s], ResCacheDataAllocator, ResLayoutDataAllocator); + + Resources.InitStaticSamplers(m_pBoundResourceCaches[s]); + + m_ResourceLayoutIndex[ShaderInd] = s; + m_ShaderTypeIndex[s] = static_cast<Int8>(ShaderInd); + } +} + +ShaderResourceBindingD3D11Impl::~ShaderResourceBindingD3D11Impl() +{ + auto *pPSOD3D11Impl = ValidatedCast<PipelineStateD3D11Impl>(m_pPSO); + for (Uint32 s = 0; s < m_NumActiveShaders; ++s) + { + auto &Allocator = pPSOD3D11Impl->GetResourceCacheDataAllocator(s); + m_pBoundResourceCaches[s].Destroy(Allocator); + m_pBoundResourceCaches[s].~ShaderResourceCacheD3D11(); + } + GetRawAllocator().Free(m_pBoundResourceCaches); + + for(Int32 l = 0; l < m_NumActiveShaders; ++l) + { + m_pResourceLayouts[l].~ShaderResourceLayoutD3D11(); + } + GetRawAllocator().Free(m_pResourceLayouts); +} + +IMPLEMENT_QUERY_INTERFACE( ShaderResourceBindingD3D11Impl, IID_ShaderResourceBindingD3D11, TBase ) + +void ShaderResourceBindingD3D11Impl::BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags) +{ + for(Uint32 ResLayoutInd = 0; ResLayoutInd < m_NumActiveShaders; ++ResLayoutInd) + { + auto &ResLayout = m_pResourceLayouts[ResLayoutInd]; + if(ShaderFlags & ResLayout.GetShaderType()) + { + ResLayout.BindResources(pResMapping, Flags, m_pBoundResourceCaches[ResLayoutInd]); + } + } +} + +void ShaderResourceBindingD3D11Impl::BindStaticShaderResources() +{ + if (m_bIsStaticResourcesBound) + { + LOG_ERROR("Static resources already bound"); + return; + } + + auto *pPSOD3D11 = ValidatedCast<PipelineStateD3D11Impl>(GetPipelineState()); + auto ppShaders = pPSOD3D11->GetShaders(); + auto NumShaders = pPSOD3D11->GetNumShaders(); + VERIFY_EXPR(NumShaders == m_NumActiveShaders); + + for (Uint32 shader = 0; shader < NumShaders; ++shader) + { + auto *pShaderD3D11 = ValidatedCast<ShaderD3D11Impl>( ppShaders[shader] ); +#ifdef VERIFY_SHADER_BINDINGS + pShaderD3D11->GetStaticResourceLayout().dbgVerifyBindings(); +#endif + +#ifdef _DEBUG + auto ShaderTypeInd = pShaderD3D11->GetShaderTypeIndex(); + auto ResourceLayoutInd = m_ResourceLayoutIndex[ShaderTypeInd]; + VERIFY_EXPR(ResourceLayoutInd == static_cast<Int8>(shader) ); +#endif + pShaderD3D11->GetStaticResourceLayout().CopyResources( m_pBoundResourceCaches[shader] ); + } + + m_bIsStaticResourcesBound = true; +} + +IShaderVariable *ShaderResourceBindingD3D11Impl::GetVariable(SHADER_TYPE ShaderType, const char *Name) +{ + auto Ind = GetShaderTypeIndex(ShaderType); + VERIFY_EXPR(Ind >= 0 && Ind < _countof(m_ResourceLayoutIndex)); + auto ResLayoutIndex = m_ResourceLayoutIndex[Ind]; + if( Ind >= 0 ) + { + auto *pVar = m_pResourceLayouts[ResLayoutIndex].GetShaderVariable(Name); + if(pVar != nullptr) + return pVar; + else + { + auto *pPSOD3D11 = ValidatedCast<PipelineStateD3D11Impl>(GetPipelineState()); + return pPSOD3D11->GetDummyShaderVariable(); + } + } + else + { + LOG_ERROR_MESSAGE("Shader type ", GetShaderTypeLiteralName(ShaderType)," is not active in the resource binding"); + return nullptr; + } +} + +} diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp new file mode 100644 index 00000000..8054bb57 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp @@ -0,0 +1,265 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "ShaderResourceCacheD3D11.h" +#include "ShaderResourceLayoutD3D11.h" +#include "TextureBaseD3D11.h" +#include "BufferD3D11Impl.h" +#include "SamplerD3D11Impl.h" +#include "MemoryAllocator.h" + +namespace Diligent +{ + void ShaderResourceCacheD3D11::Initialize(Int32 CBCount, Int32 SRVCount, Int32 SamplerCount, Int32 UAVCount, IMemoryAllocator &MemAllocator) + { + if (IsInitialized()) + { + LOG_ERROR_MESSAGE("Resource cache is already intialized") + return; + } + + + VERIFY(CBCount <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, "Constant buffer count ", CBCount, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ); + VERIFY(SRVCount <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, "SRV count ", SRVCount, " exceeds D3D11 limit ", D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT ); + VERIFY(SamplerCount <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, "Sampler count ", SamplerCount, " exceeds D3D11 limit ", D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT ); + VERIFY(UAVCount <= D3D11_PS_CS_UAV_REGISTER_COUNT, "UAV count ", UAVCount, " exceeds D3D11 limit ", D3D11_PS_CS_UAV_REGISTER_COUNT ); + + m_ResourceCounts = PackResourceCounts(CBCount, SRVCount, SamplerCount, UAVCount); + VERIFY_EXPR(GetCBCount() == static_cast<Uint32>(CBCount)); + VERIFY_EXPR(GetSRVCount() == static_cast<Uint32>(SRVCount)); + VERIFY_EXPR(GetSamplerCount() == static_cast<Uint32>(SamplerCount)); + VERIFY_EXPR(GetUAVCount() == static_cast<Uint32>(UAVCount)); + + CachedCB* CBs = nullptr; + ID3D11Buffer** d3d11CBs = nullptr; + CachedResource* SRVResources = nullptr; + ID3D11ShaderResourceView** d3d11SRVs = nullptr; + CachedSampler* Samplers = nullptr; + ID3D11SamplerState** d3d11Samplers = nullptr; + CachedResource* UAVResources = nullptr; + ID3D11UnorderedAccessView** d3d11UAVs = nullptr; + GetResourceArrays(CBs, d3d11CBs, SRVResources, d3d11SRVs, Samplers, d3d11Samplers, UAVResources, d3d11UAVs); + + VERIFY_EXPR(m_pResourceData == nullptr); + size_t BufferSize = reinterpret_cast<Uint8*>(d3d11UAVs + UAVCount) - m_pResourceData; + + VERIFY_EXPR( BufferSize == + (sizeof(CBs[0]) + sizeof(d3d11CBs[0])) * CBCount + + (sizeof(SRVResources[0]) + sizeof(d3d11SRVs[0])) * SRVCount + + (sizeof(Samplers[0]) + sizeof(d3d11Samplers[0])) * SamplerCount + + (sizeof(UAVResources[0]) + sizeof(d3d11UAVs[0])) * UAVCount ); + +#ifdef _DEBUG + m_pdbgMemoryAllocator = &MemAllocator; +#endif + if( BufferSize > 0 ) + { + m_pResourceData = reinterpret_cast<Uint8*>(MemAllocator.Allocate(BufferSize, "Shader resource cache data buffer", __FILE__, __LINE__ )); + memset(m_pResourceData, 0, BufferSize); + } + + + GetResourceArrays(CBs, d3d11CBs, SRVResources, d3d11SRVs, Samplers, d3d11Samplers, UAVResources, d3d11UAVs); +#ifdef _DEBUG + { + CachedCB* dbgCBs = nullptr; + ID3D11Buffer** dbgd3d11CBs = nullptr; + GetCBArrays(dbgCBs, dbgd3d11CBs); + VERIFY_EXPR(dbgCBs == CBs && dbgd3d11CBs == d3d11CBs); + } + { + CachedResource* dbgSRVResources = nullptr; + ID3D11ShaderResourceView** dbgd3d11SRVs = nullptr; + GetSRVArrays(dbgSRVResources, dbgd3d11SRVs); + VERIFY_EXPR(dbgSRVResources == SRVResources && dbgd3d11SRVs == d3d11SRVs); + } + { + CachedSampler* dbgSamplers = nullptr; + ID3D11SamplerState** dbgd3d11Samplers = nullptr; + GetSamplerArrays(dbgSamplers, dbgd3d11Samplers); + VERIFY_EXPR(dbgSamplers == Samplers && dbgd3d11Samplers == d3d11Samplers); + } + + { + CachedResource* dbgUAVResources = nullptr; + ID3D11UnorderedAccessView** dbgd3d11UAVs = nullptr; + GetUAVArrays(dbgUAVResources, dbgd3d11UAVs); + VERIFY_EXPR(dbgUAVResources == UAVResources && dbgd3d11UAVs == d3d11UAVs); + } +#endif + + // Explicitly construct all objects + for (Int32 cb = 0; cb < CBCount; ++cb) + new(CBs+cb)CachedCB; + + for (Int32 srv = 0; srv < SRVCount; ++srv) + new(SRVResources+srv)CachedResource; + + for (Int32 sam = 0; sam < SamplerCount; ++sam) + new(Samplers+sam)CachedSampler; + + for (Int32 uav = 0; uav < UAVCount; ++uav) + new(UAVResources+uav)CachedResource; + } + + void ShaderResourceCacheD3D11::Destroy(IMemoryAllocator &MemAllocator) + { + VERIFY( IsInitialized(), "Resource cache is not initialized") + VERIFY( m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources") + + if( IsInitialized() ) + { + CachedCB* CBs = nullptr; + ID3D11Buffer** d3d11CBs = nullptr; + CachedResource* SRVResources = nullptr; + ID3D11ShaderResourceView** d3d11SRVs = nullptr; + CachedSampler* Samplers = nullptr; + ID3D11SamplerState** d3d11Samplers = nullptr; + CachedResource* UAVResources = nullptr; + ID3D11UnorderedAccessView** d3d11UAVs = nullptr; + GetResourceArrays(CBs, d3d11CBs, SRVResources, d3d11SRVs, Samplers, d3d11Samplers, UAVResources, d3d11UAVs); + + // Explicitly destory all objects + auto CBCount = GetCBCount(); + for (size_t cb = 0; cb < CBCount; ++cb) + CBs[cb].~CachedCB(); + auto SRVCount = GetSRVCount(); + for (size_t srv = 0; srv < SRVCount; ++srv) + SRVResources[srv].~CachedResource(); + auto SamplerCount = GetSamplerCount(); + for (size_t sam = 0; sam < SamplerCount; ++sam) + Samplers[sam].~CachedSampler(); + auto UAVCount = GetUAVCount(); + for (size_t uav = 0; uav < UAVCount; ++uav) + UAVResources[uav].~CachedResource(); + m_ResourceCounts = InvalidResourceCounts; + + if(m_pResourceData != nullptr) + MemAllocator.Free(m_pResourceData); + } + } + + ShaderResourceCacheD3D11::~ShaderResourceCacheD3D11() + { + VERIFY( !IsInitialized(), "Shader resource cache memory must be released with ShaderResourceCacheD3D11::Destroy()" ) + } + + void dbgVerifyResource(ShaderResourceCacheD3D11::CachedResource &Res, ID3D11View *pd3d11View, const char *ViewType) + { + if (pd3d11View != nullptr) + { + VERIFY(Res.pView != nullptr, "Resource view is not initialized") + VERIFY(Res.pBuffer==nullptr && Res.pTexture!=nullptr || Res.pBuffer!=nullptr && Res.pTexture==nullptr, "Texture and buffer resources are mutually exclusive") + VERIFY(Res.pd3d11Resource!=nullptr, "D3D11 resource is missing") + + CComPtr<ID3D11Resource> pd3d11ActualResource; + pd3d11View->GetResource(&pd3d11ActualResource); + VERIFY(pd3d11ActualResource == Res.pd3d11Resource, "Inconsistent D3D11 resource") + if (Res.pBuffer) + { + VERIFY(pd3d11ActualResource == Res.pBuffer->GetD3D11Buffer(), "Inconsistent buffer ", ViewType) + if (Res.pView) + { + RefCntAutoPtr<IBufferViewD3D11> pBufView(Res.pView, IID_BufferViewD3D11); + VERIFY(pBufView != nullptr, "Provided resource view is not D3D11 buffer view") + if(pBufView) + VERIFY(pBufView->GetBuffer() == Res.pBuffer, "Provided resource view is not a view of the buffer") + } + } + else if(Res.pTexture) + { + VERIFY(pd3d11ActualResource == Res.pTexture->GetD3D11Texture(), "Inconsistent texture ", ViewType) + if (Res.pView) + { + RefCntAutoPtr<ITextureViewD3D11> pTexView(Res.pView, IID_TextureViewD3D11); + VERIFY(pTexView != nullptr, "Provided resource view is not D3D11 texture view") + if(pTexView) + VERIFY(pTexView->GetTexture() == Res.pTexture, "Provided resource view is not a view of the texture") + } + } + } + else + { + VERIFY(Res.pView==nullptr, "Resource view is unexpected") + VERIFY(Res.pBuffer==nullptr && Res.pTexture==nullptr, "Niether texture nor buffer resource is expected") + VERIFY(Res.pd3d11Resource==nullptr, "Unexepected D3D11 resource") + } + } + + void ShaderResourceCacheD3D11::dbgVerifyCacheConsistency() + { + VERIFY(IsInitialized(), "Cache is not initialized") + + CachedCB* CBs = nullptr; + ID3D11Buffer** d3d11CBs = nullptr; + CachedResource* SRVResources = nullptr; + ID3D11ShaderResourceView** d3d11SRVs = nullptr; + CachedSampler* Samplers = nullptr; + ID3D11SamplerState** d3d11Samplers = nullptr; + CachedResource* UAVResources = nullptr; + ID3D11UnorderedAccessView** d3d11UAVs = nullptr; + GetResourceArrays(CBs, d3d11CBs, SRVResources, d3d11SRVs, Samplers, d3d11Samplers, UAVResources, d3d11UAVs); + + auto CBCount = GetCBCount(); + for (size_t cb = 0; cb < CBCount; ++cb) + { + auto &pBuff = CBs[cb].pBuff; + auto *pd3d11Buff = d3d11CBs[cb]; + VERIFY(pBuff==nullptr && pd3d11Buff==nullptr || pBuff!=nullptr && pd3d11Buff!=nullptr, "CB resource and d3d11 buffer must be set/unset atomically") + if(pBuff != nullptr && pd3d11Buff != nullptr ) + { + VERIFY(pd3d11Buff == pBuff->GetD3D11Buffer(), "Inconsistent D3D11 buffer") + } + } + + auto SRVCount = GetSRVCount(); + for (size_t srv = 0; srv < SRVCount; ++srv) + { + auto &Res = SRVResources[srv]; + auto *pd3d11SRV = d3d11SRVs[srv]; + dbgVerifyResource(Res, pd3d11SRV, "SRV"); + } + + auto UAVCount = GetUAVCount(); + for (size_t uav = 0; uav < UAVCount; ++uav) + { + auto &Res = UAVResources[uav]; + auto *pd3d11UAV = d3d11UAVs[uav]; + dbgVerifyResource(Res, pd3d11UAV, "UAV"); + } + + auto SamplerCount = GetSamplerCount(); + for (size_t sam = 0; sam < SamplerCount; ++sam) + { + auto &pSampler = Samplers[sam].pSampler; + auto *pd3d11Sampler = d3d11Samplers[sam]; + VERIFY(pSampler==nullptr && pd3d11Sampler==nullptr || pSampler!=nullptr && pd3d11Sampler!=nullptr, "CB resource and d3d11 buffer must be set/unset atomically") + if(pSampler!=nullptr && pd3d11Sampler!=nullptr) + { + VERIFY(pd3d11Sampler==pSampler->GetD3D11SamplerState(), "Inconsistent D3D11 sampler") + } + } + } +} diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp new file mode 100644 index 00000000..00fb3549 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp @@ -0,0 +1,783 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include <d3dcompiler.h> + +#include "ShaderResourceLayoutD3D11.h" +#include "ShaderResourceCacheD3D11.h" +#include "BufferD3D11Impl.h" +#include "BufferViewD3D11Impl.h" +#include "TextureBaseD3D11.h" +#include "TextureViewD3D11.h" +#include "SamplerD3D11Impl.h" +#include "D3DShaderResourceLoader.h" +#include "ShaderD3D11Impl.h" + +namespace Diligent +{ + +ShaderResourceLayoutD3D11::ShaderResourceLayoutD3D11(IObject &Owner, IMemoryAllocator& ResLayoutDataAllocator) : + m_Owner(Owner), +#if USE_VARIABLE_HASH_MAP + m_VariableHash(STD_ALLOCATOR_RAW_MEM(VariableHashData, GetRawAllocator(), "Allocator for vector<BuffSRVBindInfo>")), +#endif + m_ResourceBuffer(nullptr, STDDeleterRawMem<void>(ResLayoutDataAllocator)) +{ +} + +ShaderResourceLayoutD3D11::~ShaderResourceLayoutD3D11() +{ + HandleResources( + [&](ConstBuffBindInfo&cb) + { + cb.~ConstBuffBindInfo(); + }, + + [&](TexAndSamplerBindInfo& ts) + { + ts.~TexAndSamplerBindInfo(); + }, + + [&](TexUAVBindInfo& uav) + { + uav.~TexUAVBindInfo(); + }, + + [&](BuffSRVBindInfo& srv) + { + srv.~BuffSRVBindInfo(); + }, + + [&](BuffUAVBindInfo& uav) + { + uav.~BuffUAVBindInfo(); + } + ); +} + +const D3DShaderResourceAttribs ShaderResourceLayoutD3D11::TexAndSamplerBindInfo::InvalidSamplerAttribs(String("Invalid sampler"), D3DShaderResourceAttribs::InvalidBindPoint, 0, D3D_SIT_SAMPLER, SHADER_VARIABLE_TYPE_NUM_TYPES, D3D_SRV_DIMENSION_UNKNOWN, D3DShaderResourceAttribs::InvalidSamplerId, false); + +void ShaderResourceLayoutD3D11::Initialize(const std::shared_ptr<const ShaderResourcesD3D11>& pSrcResources, + const SHADER_VARIABLE_TYPE *VarTypes, + Uint32 NumVarTypes, + ShaderResourceCacheD3D11& ResourceCache, + IMemoryAllocator& ResCacheDataAllocator, + IMemoryAllocator& ResLayoutDataAllocator) +{ + VERIFY(&m_ResourceBuffer.get_deleter().m_Allocator == &ResLayoutDataAllocator, "Incosistent memory alloctor"); + + m_pResources = pSrcResources; + m_pResourceCache = &ResourceCache; + + Uint32 AllowedTypeBits = GetAllowedTypeBits(VarTypes, NumVarTypes); + + Uint32 NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers; + pSrcResources->CountResources(VarTypes, NumVarTypes, NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); + + m_TexAndSamplersOffset = 0 + static_cast<Uint16>( NumCBs * sizeof(ConstBuffBindInfo) ); + m_TexUAVsOffset = m_TexAndSamplersOffset + static_cast<Uint16>( NumTexSRVs * sizeof(TexAndSamplerBindInfo) ); + m_BuffUAVsOffset = m_TexUAVsOffset + static_cast<Uint16>( NumTexUAVs * sizeof(TexUAVBindInfo) ); + m_BuffSRVsOffset = m_BuffUAVsOffset + static_cast<Uint16>( NumBufUAVs * sizeof(BuffUAVBindInfo) ); + auto MemorySize = m_BuffSRVsOffset + NumBufSRVs * sizeof(BuffSRVBindInfo); + + if( MemorySize ) + { + auto *pRawMem = ALLOCATE(ResLayoutDataAllocator, "Raw memory buffer for shader resource layout resources", MemorySize); + m_ResourceBuffer.reset(pRawMem); + } + + VERIFY_EXPR(NumCBs < 255); + VERIFY_EXPR(NumTexSRVs < 255); + VERIFY_EXPR(NumTexUAVs < 255); + VERIFY_EXPR(NumBufSRVs < 255); + VERIFY_EXPR(NumBufUAVs < 255); + m_NumCBs = static_cast<Uint8>(NumCBs); + m_NumTexSRVs = static_cast<Uint8>(NumTexSRVs); + m_NumTexUAVs = static_cast<Uint8>(NumTexUAVs); + m_NumBufSRVs = static_cast<Uint8>(NumBufSRVs); + m_NumBufUAVs = static_cast<Uint8>(NumBufUAVs); + + Uint32 cb = 0; + Uint32 texSrv = 0; + Uint32 texUav = 0; + Uint32 bufSrv = 0; + Uint32 bufUav = 0; + + Int32 MaxCBBindPoint = -1; + Int32 MaxSRVBindPoint = -1; + Int32 MaxSamplerBindPoint = -1; + Int32 MaxUAVBindPoint = -1; + pSrcResources->ProcessResources( + VarTypes, NumVarTypes, + + [&](const D3DShaderResourceAttribs &CB) + { + VERIFY_EXPR( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ); + new (&GetCB(cb++)) ConstBuffBindInfo( CB, *this ); + MaxCBBindPoint = std::max(MaxCBBindPoint, static_cast<Int32>(CB.BindPoint + CB.BindCount-1)); + }, + + [&](const D3DShaderResourceAttribs& TexSRV) + { + VERIFY_EXPR( IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits) ); + + const D3DShaderResourceAttribs& SamplerAttribs = TexSRV.IsValidSampler() ? + pSrcResources->GetSampler(TexSRV.GetSamplerId()) : TexAndSamplerBindInfo::InvalidSamplerAttribs; + new (&GetTexSRV(texSrv++)) TexAndSamplerBindInfo( TexSRV, SamplerAttribs, *this ); + MaxSRVBindPoint = std::max(MaxSRVBindPoint, static_cast<Int32>(TexSRV.BindPoint + TexSRV.BindCount-1)); + if( SamplerAttribs.IsValidBindPoint() ) + MaxSamplerBindPoint = std::max(MaxSamplerBindPoint, static_cast<Int32>(SamplerAttribs.BindPoint + SamplerAttribs.BindCount-1)); + }, + + [&](const D3DShaderResourceAttribs &TexUAV) + { + VERIFY_EXPR( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ); + + new (&GetTexUAV(texUav++)) TexUAVBindInfo( TexUAV, *this ); + MaxUAVBindPoint = std::max(MaxUAVBindPoint, static_cast<Int32>(TexUAV.BindPoint + TexUAV.BindCount-1)); + }, + + [&](const D3DShaderResourceAttribs &BuffSRV) + { + VERIFY_EXPR(IsAllowedType(BuffSRV.GetVariableType(), AllowedTypeBits)); + + new (&GetBufSRV(bufSrv++)) BuffSRVBindInfo( BuffSRV, *this ); + MaxSRVBindPoint = std::max(MaxSRVBindPoint, static_cast<Int32>(BuffSRV.BindPoint + BuffSRV.BindCount-1)); + }, + + [&](const D3DShaderResourceAttribs &BuffUAV) + { + VERIFY_EXPR(IsAllowedType(BuffUAV.GetVariableType(), AllowedTypeBits)); + + new (&GetBufUAV(bufUav++)) BuffUAVBindInfo( BuffUAV, *this ); + MaxUAVBindPoint = std::max(MaxUAVBindPoint, static_cast<Int32>(BuffUAV.BindPoint + BuffUAV.BindCount-1)); + } + ); + + if (!m_pResourceCache->IsInitialized()) + { + // NOTE that here we are using max bind points required to cache only the shader variables of allowed types! + m_pResourceCache->Initialize(MaxCBBindPoint+1, MaxSRVBindPoint+1, MaxSamplerBindPoint+1, MaxUAVBindPoint+1, ResCacheDataAllocator); + } + + VERIFY(cb == m_NumCBs, "Not all CBs are initialized, which will result in a crash when dtor is called"); + VERIFY(texSrv == m_NumTexSRVs, "Not all Tex SRVs are initialized, which will result in a crash when dtor is called"); + VERIFY(texUav == m_NumTexUAVs, "Not all Tex UAVs are initialized, which will result in a crash when dtor is called"); + VERIFY(bufSrv == m_NumBufSRVs, "Not all Buf SRVs are initialized, which will result in a crash when dtor is called"); + VERIFY(bufUav == m_NumBufUAVs, "Not all Buf UAVs are initialized, which will result in a crash when dtor is called"); + + InitVariablesHashMap(); +} + +void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11 &DstCache) +{ + VERIFY(m_pResourceCache, "Resource cache must not be null"); + + VERIFY( DstCache.GetCBCount() >= m_pResourceCache->GetCBCount(), "Dst cache is not large enough to contain all CBs" ) + VERIFY( DstCache.GetSRVCount() >= m_pResourceCache->GetSRVCount(), "Dst cache is not large enough to contain all SRVs" ) + VERIFY( DstCache.GetSamplerCount() >= m_pResourceCache->GetSamplerCount(), "Dst cache is not large enough to contain all samplers" ) + VERIFY( DstCache.GetUAVCount() >= m_pResourceCache->GetUAVCount(), "Dst cache is not large enough to contain all UAVs" ) + + ShaderResourceCacheD3D11::CachedCB* CachedCBs = nullptr; + ID3D11Buffer** d3d11CBs = nullptr; + ShaderResourceCacheD3D11::CachedResource* CachedSRVResources = nullptr; + ID3D11ShaderResourceView** d3d11SRVs = nullptr; + ShaderResourceCacheD3D11::CachedSampler* CachedSamplers = nullptr; + ID3D11SamplerState** d3d11Samplers = nullptr; + ShaderResourceCacheD3D11::CachedResource* CachedUAVResources = nullptr; + ID3D11UnorderedAccessView** d3d11UAVs = nullptr; + m_pResourceCache->GetResourceArrays(CachedCBs, d3d11CBs, CachedSRVResources, d3d11SRVs, CachedSamplers, d3d11Samplers, CachedUAVResources, d3d11UAVs); + + + ShaderResourceCacheD3D11::CachedCB* DstCBs = nullptr; + ID3D11Buffer** DstD3D11CBs = nullptr; + ShaderResourceCacheD3D11::CachedResource* DstSRVResources = nullptr; + ID3D11ShaderResourceView** DstD3D11SRVs = nullptr; + ShaderResourceCacheD3D11::CachedSampler* DstSamplers = nullptr; + ID3D11SamplerState** DstD3D11Samplers = nullptr; + ShaderResourceCacheD3D11::CachedResource* DstUAVResources = nullptr; + ID3D11UnorderedAccessView** DstD3D11UAVs = nullptr; + DstCache.GetResourceArrays(DstCBs, DstD3D11CBs, DstSRVResources, DstD3D11SRVs, DstSamplers, DstD3D11Samplers, DstUAVResources, DstD3D11UAVs); + + HandleResources( + [&](const ConstBuffBindInfo&cb) + { + for(auto CBSlot = cb.Attribs.BindPoint; CBSlot < cb.Attribs.BindPoint+cb.Attribs.BindCount; ++CBSlot) + { + VERIFY_EXPR(CBSlot < m_pResourceCache->GetCBCount() && CBSlot < DstCache.GetCBCount()); + DstCBs[CBSlot] = CachedCBs[CBSlot]; + DstD3D11CBs[CBSlot] = d3d11CBs[CBSlot]; + } + }, + + [&](const TexAndSamplerBindInfo& ts) + { + for(auto SRVSlot = ts.Attribs.BindPoint; SRVSlot < ts.Attribs.BindPoint + ts.Attribs.BindCount; ++SRVSlot) + { + VERIFY_EXPR(SRVSlot < m_pResourceCache->GetSRVCount() && SRVSlot < DstCache.GetSRVCount()); + DstSRVResources[SRVSlot] = CachedSRVResources[SRVSlot]; + DstD3D11SRVs[SRVSlot] = d3d11SRVs[SRVSlot]; + if( ts.SamplerAttribs.IsValidBindPoint() ) + { + VERIFY_EXPR(ts.SamplerAttribs.BindCount == ts.Attribs.BindCount || ts.SamplerAttribs.BindCount == 1); + Uint32 SamplerSlot = ts.SamplerAttribs.BindPoint + (ts.SamplerAttribs.BindCount == 1 ? 0 : (SRVSlot - ts.Attribs.BindPoint)); + if( !ts.SamplerAttribs.IsStaticSampler() ) + { + VERIFY_EXPR( SamplerSlot < m_pResourceCache->GetSamplerCount() && SamplerSlot < DstCache.GetSamplerCount() ); + DstSamplers[SamplerSlot] = CachedSamplers[SamplerSlot]; + DstD3D11Samplers[SamplerSlot] = d3d11Samplers[SamplerSlot]; + } + else + { + VERIFY(DstSamplers[SamplerSlot].pSampler != nullptr && DstD3D11Samplers[SamplerSlot] != nullptr, "Static samplers must be initialized when shader resource cache is created"); + } + } + } + }, + + [&](const TexUAVBindInfo& uav) + { + for(auto UAVSlot = uav.Attribs.BindPoint; UAVSlot < uav.Attribs.BindPoint + uav.Attribs.BindCount; ++UAVSlot) + { + VERIFY_EXPR(UAVSlot < m_pResourceCache->GetUAVCount() && UAVSlot < DstCache.GetUAVCount()); + DstUAVResources[UAVSlot] = CachedUAVResources[UAVSlot]; + DstD3D11UAVs[UAVSlot] = d3d11UAVs[UAVSlot]; + } + }, + + [&](const BuffSRVBindInfo& srv) + { + for(auto SRVSlot = srv.Attribs.BindPoint; SRVSlot < srv.Attribs.BindPoint + srv.Attribs.BindCount; ++SRVSlot) + { + VERIFY_EXPR(SRVSlot < m_pResourceCache->GetSRVCount() && SRVSlot < DstCache.GetSRVCount()); + DstSRVResources[SRVSlot] = CachedSRVResources[SRVSlot]; + DstD3D11SRVs[SRVSlot] = d3d11SRVs[SRVSlot]; + } + }, + + [&](const BuffUAVBindInfo& uav) + { + for(auto UAVSlot = uav.Attribs.BindPoint; UAVSlot < uav.Attribs.BindPoint + uav.Attribs.BindCount; ++UAVSlot) + { + VERIFY_EXPR(UAVSlot < m_pResourceCache->GetUAVCount() && UAVSlot < DstCache.GetUAVCount()); + DstUAVResources[UAVSlot] = CachedUAVResources[UAVSlot]; + DstD3D11UAVs[UAVSlot] = d3d11UAVs[UAVSlot]; + } + } + ); +} + +void ShaderResourceLayoutD3D11::InitVariablesHashMap() +{ +#if USE_VARIABLE_HASH_MAP + // After all resources are loaded, we can populate shader variable hash map. + // The map contains raw pointers, but none of the arrays will ever change. + HandleResources( + [&](ConstBuffBindInfo&cb) + { + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(cb.Attribs.Name), &cb ) ); + }, + + [&](TexAndSamplerBindInfo& ts) + { + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(ts.Attribs.Name), &ts ) ); + }, + + [&](TexUAVBindInfo& uav) + { + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(uav.Attribs.Name), &uav ) ); + }, + + [&](BuffSRVBindInfo& srv) + { + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(srv.Attribs.Name), &srv ) ); + }, + + [&](BuffUAVBindInfo& uav) + { + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(uav.Attribs.Name), &uav ) ); + } + ); +#endif +} + +#define LOG_RESOURCE_BINDING_ERROR(ResType, pResource, Attribs, ArrayInd, ShaderName, ...)\ +{ \ + const auto &ResName = pResource->GetDesc().Name; \ + if(Attribs.BindCount>1) \ + LOG_ERROR_MESSAGE( "Failed to bind ", ResType, " \"", ResName, "\" to variable \"", Attribs.Name,\ + "[", ArrayInd, "]\" in shader \"", ShaderName, "\". ", __VA_ARGS__ ) \ + else \ + LOG_ERROR_MESSAGE( "Failed to bind ", ResType, " \"", ResName, "\" to variable \"", Attribs.Name,\ + "\" in shader \"", ShaderName, "\". ", __VA_ARGS__ ) \ +} + +void ShaderResourceLayoutD3D11::ConstBuffBindInfo::BindResource(IDeviceObject *pBuffer, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY(dbgResLayout == nullptr || pResourceCache == dbgResLayout->m_pResourceCache, "Invalid resource cache"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl; + if( pBuffer ) + { + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + IBufferD3D11 *pBuffD3D11 = nullptr; + pBuffer->QueryInterface(IID_BufferD3D11, reinterpret_cast<IObject**>(&pBuffD3D11)); + if( pBuffD3D11 ) + { + pBuffD3D11Impl.Attach(ValidatedCast<BufferD3D11Impl>(pBuffD3D11)); + if( !(pBuffD3D11Impl->GetDesc().BindFlags & BIND_UNIFORM_BUFFER) ) + { + pBuffD3D11Impl.Release(); + LOG_RESOURCE_BINDING_ERROR("buffer", pBuffer, Attribs, ArrayIndex, m_ParentResLayout.GetShaderName(), "Buffer was not created with BIND_UNIFORM_BUFFER flag.") + } + } + else + { + LOG_RESOURCE_BINDING_ERROR("buffer", pBuffer, Attribs, ArrayIndex, m_ParentResLayout.GetShaderName(), "Incorrect resource type: buffer is expected.") + } + } + + pResourceCache->SetCB(Attribs.BindPoint + ArrayIndex, std::move(pBuffD3D11Impl) ); +} + + + +bool ShaderResourceLayoutD3D11::ConstBuffBindInfo::IsBound(Uint32 ArrayIndex) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + return pResourceCache->IsCBBound(Attribs.BindPoint + ArrayIndex); +} + + + +#ifdef VERIFY_SHADER_BINDINGS +template<typename TResourceViewType, ///< Type of the view (ITextureViewD3D11 or IBufferViewD3D11) + typename TViewTypeEnum> ///< Type of the expected view enum +bool dbgVerifyViewType( const char *ViewTypeName, + TResourceViewType pViewD3D11, + const D3DShaderResourceAttribs& Attribs, + Uint32 ArrayIndex, + TViewTypeEnum dbgExpectedViewType, + const String &ShaderName ) +{ + const auto& ViewDesc = pViewD3D11->GetDesc(); + auto ViewType = ViewDesc.ViewType; + if (ViewType == dbgExpectedViewType) + { + return true; + } + else + { + const auto *ExpectedViewTypeName = GetViewTypeLiteralName( dbgExpectedViewType ); + const auto *ActualViewTypeName = GetViewTypeLiteralName( ViewType ); + LOG_RESOURCE_BINDING_ERROR(ViewTypeName, pViewD3D11, Attribs, ArrayIndex, ShaderName, + "Incorrect view type: ", ExpectedViewTypeName, " is expected, ", ActualViewTypeName, " provided." ); + return false; + } +} +#endif + +void ShaderResourceLayoutD3D11::TexAndSamplerBindInfo::BindResource( IDeviceObject *pView, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout ) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY(dbgResLayout == nullptr || pResourceCache == dbgResLayout->m_pResourceCache, "Invalid resource cache"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11(pView, IID_TextureViewD3D11); +#ifdef VERIFY_SHADER_BINDINGS + if(pView && !pViewD3D11) + LOG_RESOURCE_BINDING_ERROR("resource", pView, Attribs, ArrayIndex, "", "Incorect resource type: texture view is expected.") + if(pViewD3D11 && !dbgVerifyViewType("texture view", pViewD3D11.RawPtr(), Attribs, ArrayIndex, TEXTURE_VIEW_SHADER_RESOURCE, m_ParentResLayout.GetShaderName())) + pViewD3D11.Release(); +#endif + + if( SamplerAttribs.IsValidBindPoint() ) + { + VERIFY_EXPR(SamplerAttribs.BindCount == Attribs.BindCount || SamplerAttribs.BindCount == 1); + auto SamplerBindPoint = SamplerAttribs.BindPoint + (SamplerAttribs.BindCount != 1 ? ArrayIndex : 0); + if( !SamplerAttribs.IsStaticSampler() ) + { + SamplerD3D11Impl *pSamplerD3D11Impl = nullptr; + if( pViewD3D11 ) + { + pSamplerD3D11Impl = ValidatedCast<SamplerD3D11Impl>(pViewD3D11->GetSampler()); +#ifdef VERIFY_SHADER_BINDINGS + if(pSamplerD3D11Impl==nullptr) + { + if(SamplerAttribs.BindCount > 1) + LOG_ERROR_MESSAGE( "Failed to bind sampler to variable \"", SamplerAttribs.Name, "[", ArrayIndex,"]\". Sampler is not set in the texture view \"", pViewD3D11->GetDesc().Name, "\"" ) + else + LOG_ERROR_MESSAGE( "Failed to bind sampler to variable \"", SamplerAttribs.Name, "\". Sampler is not set in the texture view \"", pViewD3D11->GetDesc().Name, "\"" ) + } +#endif + } + + pResourceCache->SetSampler(SamplerBindPoint, pSamplerD3D11Impl); + } + else + { + VERIFY_EXPR(SamplerAttribs.BindCount == Attribs.BindCount || SamplerAttribs.BindCount == 1); + VERIFY( pResourceCache->IsSamplerBound(SamplerBindPoint), "Static samplers must be bound once when shader cache is created" ); + } + } + + pResourceCache->SetTexSRV(Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11)); +} + + +void ShaderResourceLayoutD3D11::BuffSRVBindInfo::BindResource( IDeviceObject *pView, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout ) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY(dbgResLayout == nullptr || pResourceCache == dbgResLayout->m_pResourceCache, "Invalid resource cache"); + VERIFY(ArrayIndex < Attribs.BindCount, "Array index is out of range"); + + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11(pView, IID_BufferViewD3D11); +#ifdef VERIFY_SHADER_BINDINGS + if(pView && !pViewD3D11) + LOG_RESOURCE_BINDING_ERROR("resource", pView, Attribs, ArrayIndex, "", "Incorect resource type: buffer view is expected.") + if(pViewD3D11 && !dbgVerifyViewType("buffer view", pViewD3D11.RawPtr(), Attribs, ArrayIndex, BUFFER_VIEW_SHADER_RESOURCE, m_ParentResLayout.GetShaderName())) + pViewD3D11.Release(); +#endif + + pResourceCache->SetBufSRV(Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11)); +} + + +void ShaderResourceLayoutD3D11::TexUAVBindInfo::BindResource( IDeviceObject *pView, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout ) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY(dbgResLayout == nullptr || pResourceCache == dbgResLayout->m_pResourceCache, "Invalid resource cache"); + VERIFY(ArrayIndex < Attribs.BindCount, "Array index is out of range"); + + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11(pView, IID_TextureViewD3D11); +#ifdef VERIFY_SHADER_BINDINGS + if(pView && !pViewD3D11) + LOG_RESOURCE_BINDING_ERROR("resource", pView, Attribs, ArrayIndex, "", "Incorect resource type: texture view is expected.") + if(pViewD3D11 && !dbgVerifyViewType("texture view", pViewD3D11.RawPtr(), Attribs, ArrayIndex, TEXTURE_VIEW_UNORDERED_ACCESS, m_ParentResLayout.GetShaderName())) + pViewD3D11.Release(); +#endif + + pResourceCache->SetTexUAV(Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11)); +} + + +void ShaderResourceLayoutD3D11::BuffUAVBindInfo::BindResource( IDeviceObject *pView, Uint32 ArrayIndex, const ShaderResourceLayoutD3D11 *dbgResLayout ) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY(dbgResLayout == nullptr || pResourceCache == dbgResLayout->m_pResourceCache, "Invalid resource cache"); + VERIFY(ArrayIndex < Attribs.BindCount, "Array index is out of range"); + + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11(pView, IID_BufferViewD3D11); +#ifdef VERIFY_SHADER_BINDINGS + if(pView && !pViewD3D11) + LOG_RESOURCE_BINDING_ERROR("resource", pView, Attribs, ArrayIndex, "", "Incorect resource type: buffer view is expected.") + if(pViewD3D11 && !dbgVerifyViewType("buffer view", pViewD3D11.RawPtr(), Attribs, ArrayIndex, BUFFER_VIEW_UNORDERED_ACCESS, m_ParentResLayout.GetShaderName()) ) + pViewD3D11.Release(); +#endif + + pResourceCache->SetBufUAV(Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11)); +} + + +bool ShaderResourceLayoutD3D11::TexAndSamplerBindInfo::IsBound(Uint32 ArrayIndex) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + return pResourceCache->IsSRVBound(Attribs.BindPoint + ArrayIndex, true); +} + + +bool ShaderResourceLayoutD3D11::BuffSRVBindInfo::IsBound(Uint32 ArrayIndex) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + return pResourceCache->IsSRVBound(Attribs.BindPoint + ArrayIndex, false); +} + +bool ShaderResourceLayoutD3D11::TexUAVBindInfo::IsBound(Uint32 ArrayIndex) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + return pResourceCache->IsUAVBound(Attribs.BindPoint + ArrayIndex, true); +} + +bool ShaderResourceLayoutD3D11::BuffUAVBindInfo::IsBound(Uint32 ArrayIndex) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + return pResourceCache->IsUAVBound(Attribs.BindPoint + ArrayIndex, false); +} + + + +// Helper template class that facilitates binding CBs, SRVs, and UAVs +class BindResourceHelper +{ +public: + BindResourceHelper(IResourceMapping *pRM, Uint32 Fl, const ShaderResourceLayoutD3D11 *pSRL) : + pResourceMapping(pRM), + Flags(Fl), + pShaderResLayout(pSRL) + { + VERIFY(pResourceMapping != nullptr, "Resource mapping is null"); + VERIFY(pSRL != nullptr, "Shader resource layout is null"); + } + + template<typename ResourceType> + void Bind( ResourceType &Res) + { + for(Uint16 elem=0; elem < Res.Attribs.BindCount; ++elem) + { + if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) + Res.BindResource(nullptr, elem, pShaderResLayout); + + if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && Res.IsBound(elem) ) + return; + + const auto& VarName = Res.Attribs.Name; + RefCntAutoPtr<IDeviceObject> pRes; + VERIFY_EXPR(pResourceMapping != nullptr); + pResourceMapping->GetResource( VarName.c_str(), &pRes, elem ); + if( pRes ) + { + // Call non-virtual function + Res.BindResource(pRes, elem, pShaderResLayout); + } + else + { + if( (Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED) && !Res.IsBound(elem) ) + LOG_ERROR_MESSAGE( "Cannot bind resource to shader variable \"", VarName, "\": resource view not found in the resource mapping" ) + } + } + } + +private: + IResourceMapping* const pResourceMapping; + const Uint32 Flags; + const ShaderResourceLayoutD3D11 *pShaderResLayout; +}; + +void ShaderResourceLayoutD3D11::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D11 &dbgResourceCache ) +{ + VERIFY(&dbgResourceCache == m_pResourceCache, "Resource cache does not match the cache provided at initialization"); + + if( !pResourceMapping ) + { + LOG_ERROR_MESSAGE( "Failed to bind resources in shader \"", GetShaderName(), "\": resource mapping is null" ); + return; + } + + BindResourceHelper BindResHelper(pResourceMapping, Flags, this); + + HandleResources( + [&](ConstBuffBindInfo&cb) + { + BindResHelper.Bind(cb); + }, + + [&](TexAndSamplerBindInfo& ts) + { + BindResHelper.Bind(ts); + }, + + [&](TexUAVBindInfo& uav) + { + BindResHelper.Bind(uav); + }, + + [&](BuffSRVBindInfo& srv) + { + BindResHelper.Bind(srv); + }, + + [&](BuffUAVBindInfo& uav) + { + BindResHelper.Bind(uav); + } + ); +} + +IShaderVariable* ShaderResourceLayoutD3D11::GetShaderVariable(const Char* Name) +{ + IShaderVariable *pVar = nullptr; +#if USE_VARIABLE_HASH_MAP + // Name will be implicitly converted to HashMapStringKey without making a copy + auto it = m_VariableHash.find( Name ); + if( it != m_VariableHash.end() ) + pVar = it->second; +#else + for (Uint32 cb = 0; cb < m_NumCBs; ++cb) + if(GetCB(cb).Attribs.Name.compare(Name) == 0) + return &GetCB(cb); + for (Uint32 t = 0; t < m_NumTexSRVs; ++t) + if(GetTexSRV(t).Attribs.Name.compare(Name) == 0 ) + return &GetTexSRV(t); + for (Uint32 u = 0; u < m_NumTexUAVs; ++u) + if(GetTexUAV(u).Attribs.Name.compare(Name) == 0 ) + return &GetTexUAV(u); + for (Uint32 s = 0; s < m_NumBufSRVs; ++s) + if(GetBufSRV(s).Attribs.Name.compare(Name) == 0 ) + return &GetBufSRV(s); + for (Uint32 u = 0; u < m_NumBufUAVs; ++u) + if(GetBufUAV(u).Attribs.Name.compare(Name) == 0 ) + return &GetBufUAV(u); +#endif + if(pVar == nullptr) + { + LOG_ERROR_MESSAGE( "Shader variable \"", Name, "\" is not found in shader \"", GetShaderName(), "\". Attempts to set the variable will be silently ignored." ); + } + return pVar; +} + +const Char* ShaderResourceLayoutD3D11::GetShaderName()const +{ + return m_pResources->GetShaderName(); +} + +#ifdef VERIFY_SHADER_BINDINGS +void ShaderResourceLayoutD3D11::dbgVerifyBindings()const +{ + +#define LOG_MISSING_BINDING(VarType, Attrs, BindPt)\ +{ \ + if(Attrs.BindCount == 1) \ + LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", Attrs.Name, "\" in shader \"", GetShaderName(), "\"" ) \ + else \ + LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", Attrs.Name, "[", BindPt-Attrs.BindPoint, "]\" in shader \"", GetShaderName(), "\"" ) \ +} + + m_pResourceCache->dbgVerifyCacheConsistency(); + + // Use const_cast to avoid duplication of the HandleResources() function + // The function actually changes nothing + const_cast<ShaderResourceLayoutD3D11*>(this)->HandleResources( + [&](const ConstBuffBindInfo&cb) + { + for(auto BindPoint = cb.Attribs.BindPoint; BindPoint < cb.Attribs.BindPoint + cb.Attribs.BindCount; ++BindPoint) + { + if( !m_pResourceCache->IsCBBound(BindPoint) ) + LOG_MISSING_BINDING("constant buffer", cb.Attribs, BindPoint) + } + }, + + [&](const TexAndSamplerBindInfo& ts) + { + for(auto BindPoint = ts.Attribs.BindPoint; BindPoint < ts.Attribs.BindPoint + ts.Attribs.BindCount; ++BindPoint) + { + if( !m_pResourceCache->IsSRVBound(BindPoint, true) ) + LOG_MISSING_BINDING("texture", ts.Attribs, BindPoint) + + if( ts.SamplerAttribs.IsValidBindPoint() ) + { + VERIFY_EXPR(ts.SamplerAttribs.BindCount == ts.Attribs.BindCount || ts.SamplerAttribs.BindCount == 1); + auto SamBindPoint = ts.SamplerAttribs.BindPoint + ((ts.SamplerAttribs.BindCount == 1) ? 0 : (BindPoint - ts.Attribs.BindPoint) ); + if(!m_pResourceCache->IsSamplerBound(SamBindPoint) ) + LOG_MISSING_BINDING("sampler", ts.SamplerAttribs, SamBindPoint) + + // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent + if (ts.Attribs.BindCount > 1 && ts.SamplerAttribs.BindCount == 1) + { + ShaderResourceCacheD3D11::CachedSampler *pCachedSamplers = nullptr; + ID3D11SamplerState **ppCachedD3D11Samplers = nullptr; + m_pResourceCache->GetSamplerArrays(pCachedSamplers, ppCachedD3D11Samplers); + VERIFY_EXPR(ts.SamplerAttribs.BindPoint < m_pResourceCache->GetSamplerCount()); + const auto &Sampler = pCachedSamplers[ts.SamplerAttribs.BindPoint]; + + ShaderResourceCacheD3D11::CachedResource *pCachedResources = nullptr; + ID3D11ShaderResourceView **ppCachedD3D11Resources = nullptr; + m_pResourceCache->GetSRVArrays(pCachedResources, ppCachedD3D11Resources); + VERIFY_EXPR(BindPoint < m_pResourceCache->GetSRVCount()); + auto &CachedResource = pCachedResources[BindPoint]; + if(CachedResource.pView) + { + auto *pTexView = ValidatedCast<ITextureView>(CachedResource.pView.RawPtr()); + auto *pSampler = pTexView->GetSampler(); + if(pSampler != Sampler.pSampler.RawPtr()) + LOG_ERROR_MESSAGE( "All elements of texture array \"", ts.Attribs.Name, "\" in shader \"", GetShaderName(), "\" share the same sampler. However, the sampler set in view for element ", BindPoint - ts.Attribs.BindPoint, " does not match bound sampler. This may cause incorrect behavior on GL platform." ) + } + } + } + } + }, + + [&](const TexUAVBindInfo& uav) + { + for(auto BindPoint = uav.Attribs.BindPoint; BindPoint < uav.Attribs.BindPoint + uav.Attribs.BindCount; ++BindPoint) + { + if( !m_pResourceCache->IsUAVBound(BindPoint, true) ) + LOG_MISSING_BINDING("texture UAV", uav.Attribs, BindPoint) + } + }, + + [&](const BuffSRVBindInfo& buf) + { + for(auto BindPoint = buf.Attribs.BindPoint; BindPoint < buf.Attribs.BindPoint + buf.Attribs.BindCount; ++BindPoint) + { + if( !m_pResourceCache->IsSRVBound(BindPoint, false) ) + LOG_MISSING_BINDING("buffer", buf.Attribs, BindPoint) + } + }, + + [&](const BuffUAVBindInfo& uav) + { + for(auto BindPoint = uav.Attribs.BindPoint; BindPoint < uav.Attribs.BindPoint + uav.Attribs.BindCount; ++BindPoint) + { + if( !m_pResourceCache->IsUAVBound(BindPoint, false) ) + LOG_MISSING_BINDING("buffer UAV", uav.Attribs, BindPoint) + } + } + ); +#undef LOG_MISSING_BINDING +} + +#endif +} diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp new file mode 100644 index 00000000..d3b4f82d --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp @@ -0,0 +1,435 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include <d3dcompiler.h> +#include "ShaderResourcesD3D11.h" +#include "ShaderBase.h" +#include "D3DShaderResourceLoader.h" +#include "ShaderResourceCacheD3D11.h" +#include "RenderDeviceD3D11Impl.h" + +namespace Diligent +{ + + +ShaderResourcesD3D11::ShaderResourcesD3D11(RenderDeviceD3D11Impl *pDeviceD3D11Impl, ID3DBlob *pShaderBytecode, const ShaderDesc &ShdrDesc) : + ShaderResources(GetRawAllocator(), ShdrDesc.ShaderType), + m_ShaderName(ShdrDesc.Name), + m_StaticSamplers(nullptr, STDDeleterRawMem< void >(GetRawAllocator())) +{ + Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0; + LoadD3DShaderResources<D3D11_SHADER_DESC, D3D11_SHADER_INPUT_BIND_DESC, ID3D11ShaderReflection>( + pShaderBytecode, + + [&](Uint32 NumCBs, Uint32 NumTexSRVs, Uint32 NumTexUAVs, Uint32 NumBufSRVs, Uint32 NumBufUAVs, Uint32 NumSamplers) + { + Initialize(GetRawAllocator(), NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); + }, + + [&](D3DShaderResourceAttribs&& CBAttribs) + { + VERIFY( CBAttribs.BindPoint + CBAttribs.BindCount-1 <= MaxAllowedBindPoint, "CB bind point exceeds supported range" ) + m_MaxCBBindPoint = std::max(m_MaxCBBindPoint, static_cast<MaxBindPointType>(CBAttribs.BindPoint + CBAttribs.BindCount-1)); + + new (&GetCB(CurrCB++)) D3DShaderResourceAttribs(std::move(CBAttribs)); + }, + + [&](D3DShaderResourceAttribs &&TexUAV) + { + VERIFY( TexUAV.BindPoint + TexUAV.BindCount-1 <= MaxAllowedBindPoint, "Tex UAV bind point exceeds supported range" ) + m_MaxUAVBindPoint = std::max(m_MaxUAVBindPoint, static_cast<MaxBindPointType>(TexUAV.BindPoint + TexUAV.BindCount-1)); + + new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs( std::move(TexUAV) ); + }, + + [&](D3DShaderResourceAttribs &&BuffUAV) + { + VERIFY( BuffUAV.BindPoint + BuffUAV.BindCount-1 <= MaxAllowedBindPoint, "Buff UAV bind point exceeds supported range" ) + m_MaxUAVBindPoint = std::max(m_MaxUAVBindPoint, static_cast<MaxBindPointType>(BuffUAV.BindPoint + BuffUAV.BindCount-1)); + + new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs( std::move(BuffUAV) ); + }, + + [&](D3DShaderResourceAttribs &&BuffSRV) + { + VERIFY( BuffSRV.BindPoint + BuffSRV.BindCount-1 <= MaxAllowedBindPoint, "Buff SRV bind point exceeds supported range" ) + m_MaxSRVBindPoint = std::max(m_MaxSRVBindPoint, static_cast<MaxBindPointType>(BuffSRV.BindPoint + BuffSRV.BindCount-1)); + + new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs( std::move(BuffSRV) ); + }, + + [&](D3DShaderResourceAttribs &&SamplerAttribs) + { + VERIFY( SamplerAttribs.BindPoint + SamplerAttribs.BindCount-1 <= MaxAllowedBindPoint, "Sampler bind point exceeds supported range" ) + m_MaxSamplerBindPoint = std::max(m_MaxSamplerBindPoint, static_cast<MaxBindPointType>(SamplerAttribs.BindPoint + SamplerAttribs.BindCount-1)); + m_NumStaticSamplers += SamplerAttribs.IsStaticSampler() ? 1 : 0; + + new (&GetSampler(CurrSampler++)) D3DShaderResourceAttribs( std::move(SamplerAttribs) ); + }, + + [&](D3DShaderResourceAttribs &&TexAttribs) + { + VERIFY(CurrSampler == GetNumSamplers(), "All samplers must be initialized before texture SRVs" ); + + VERIFY( TexAttribs.BindPoint + TexAttribs.BindCount-1 <= MaxAllowedBindPoint, "Tex SRV bind point exceeds supported range" ) + m_MaxSRVBindPoint = std::max(m_MaxSRVBindPoint, static_cast<MaxBindPointType>(TexAttribs.BindPoint + TexAttribs.BindCount-1)); + + auto SamplerId = FindAssignedSamplerId(TexAttribs); + new (&GetTexSRV(CurrTexSRV++)) D3DShaderResourceAttribs( std::move(TexAttribs), SamplerId); + }, + + ShdrDesc, + D3DSamplerSuffix); + + VERIFY(CurrCB == GetNumCBs(), "Not all CBs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called"); + VERIFY(CurrTexSRV == GetNumTexSRV(), "Not all Tex SRVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrTexUAV == GetNumTexUAV(), "Not all Tex UAVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufSRV == GetNumBufSRV(), "Not all Buf SRVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufUAV == GetNumBufUAV(), "Not all Buf UAVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrSampler == GetNumSamplers(), "Not all Samplers are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + + // Create static samplers + if (m_NumStaticSamplers > 0) + { + auto MemSize = m_NumStaticSamplers * sizeof(StaticSamplerAttribs); + auto *pRawMem = ALLOCATE(GetRawAllocator(), "Allocator for array of RefCntAutoPtr<ISampler>", MemSize); + m_StaticSamplers.reset( pRawMem ); + for (Uint32 i = 0; i < m_NumStaticSamplers; ++i) + { + new (&GetStaticSampler(i)) StaticSamplerAttribs; + } + Uint32 CurrStaticSam = 0; + for (Uint32 s = 0; s < GetNumSamplers(); ++s) + { + const auto &Sam = GetSampler(s); + if (Sam.IsStaticSampler()) + { + Uint32 ssd = 0; + for (; ssd < ShdrDesc.NumStaticSamplers; ++ssd) + { + const auto& StaticSamplerDesc = ShdrDesc.StaticSamplers[ssd]; + if ( StrCmpSuff(Sam.Name.c_str(), StaticSamplerDesc.TextureName, D3DSamplerSuffix)) + { + auto &StaticSamplerAttrs = GetStaticSampler(CurrStaticSam++); + StaticSamplerAttrs.first = &Sam; + pDeviceD3D11Impl->CreateSampler(StaticSamplerDesc.Desc, &StaticSamplerAttrs.second); + break; + } + } + VERIFY(ssd < ShdrDesc.NumStaticSamplers, "Static sampler was not found!") + } + } + VERIFY_EXPR(CurrStaticSam == m_NumStaticSamplers); + } +} + +ShaderResourcesD3D11::~ShaderResourcesD3D11() +{ + for(Uint32 ss=0; ss < m_NumStaticSamplers; ++ss) + GetStaticSampler(ss).~StaticSamplerAttribs(); +} + +void ShaderResourcesD3D11::InitStaticSamplers(ShaderResourceCacheD3D11 &ResourceCache)const +{ + auto NumCachedSamplers = ResourceCache.GetSamplerCount(); + for(Uint32 ss=0; ss < m_NumStaticSamplers; ++ss) + { + auto &StaticSampler = const_cast<ShaderResourcesD3D11*>(this)->GetStaticSampler(ss); + const auto *pSamAttribs = StaticSampler.first; + auto EndBindPoint = std::min( static_cast<Uint32>(pSamAttribs->BindPoint) + pSamAttribs->BindCount, NumCachedSamplers); + for(Uint32 BindPoint = pSamAttribs->BindPoint; BindPoint < EndBindPoint; ++BindPoint ) + ResourceCache.SetSampler(BindPoint, ValidatedCast<SamplerD3D11Impl>(StaticSampler.second.RawPtr()) ); + } +} + +#ifdef VERIFY_SHADER_BINDINGS +static String DbgMakeResourceName(const D3DShaderResourceAttribs &Attr, Uint32 BindPoint) +{ + VERIFY( BindPoint >= (Uint32)Attr.BindPoint && BindPoint < (Uint32)Attr.BindPoint + Attr.BindCount, "Bind point is out of allowed range") + if(Attr.BindCount == 1) + return Attr.Name; + else + return String(Attr.Name) + '[' + std::to_string(BindPoint - Attr.BindPoint) + ']'; +} + +void ShaderResourcesD3D11::dbgVerifyCommittedResources(ID3D11Buffer* CommittedD3D11CBs[], + ID3D11ShaderResourceView* CommittedD3D11SRVs[], + ID3D11Resource* CommittedD3D11SRVResources[], + ID3D11SamplerState* CommittedD3D11Samplers[], + ID3D11UnorderedAccessView* CommittedD3D11UAVs[], + ID3D11Resource* CommittedD3D11UAVResources[], + ShaderResourceCacheD3D11 &ResourceCache)const +{ + ShaderResourceCacheD3D11::CachedCB* CachedCBs = nullptr; + ID3D11Buffer** d3d11CBs = nullptr; + ShaderResourceCacheD3D11::CachedResource* CachedSRVResources = nullptr; + ID3D11ShaderResourceView** d3d11SRVs = nullptr; + ShaderResourceCacheD3D11::CachedSampler* CachedSamplers = nullptr; + ID3D11SamplerState** d3d11Samplers = nullptr; + ShaderResourceCacheD3D11::CachedResource* CachedUAVResources = nullptr; + ID3D11UnorderedAccessView** d3d11UAVs = nullptr; + ResourceCache.GetResourceArrays(CachedCBs, d3d11CBs, CachedSRVResources, d3d11SRVs, CachedSamplers, d3d11Samplers, CachedUAVResources, d3d11UAVs); + + ProcessResources( + nullptr, 0, + + [&](const D3DShaderResourceAttribs &cb) + { + for(auto BindPoint = cb.BindPoint; BindPoint < cb.BindPoint + cb.BindCount; ++BindPoint) + { + if (BindPoint >= ResourceCache.GetCBCount()) + { + LOG_ERROR_MESSAGE( "Unable to find constant buffer \"", DbgMakeResourceName(cb,BindPoint), "\" (slot ", BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetCBCount()," CB slots only. This should never happen and may be the result of using wrong resource cache." ); + continue; + } + auto &CB = CachedCBs[BindPoint]; + if(CB.pBuff == nullptr) + { + LOG_ERROR_MESSAGE( "Constant buffer \"", DbgMakeResourceName(cb,BindPoint), "\" (slot ", BindPoint, ") is not initialized in the resource cache." ); + continue; + } + + if (!(CB.pBuff->GetDesc().BindFlags & BIND_UNIFORM_BUFFER)) + { + LOG_ERROR_MESSAGE( "Buffer \"", CB.pBuff->GetDesc().Name, "\" committed in the device context as constant buffer to variable \"", DbgMakeResourceName(cb,BindPoint), "\" (slot ", BindPoint, ") in shader \"", GetShaderName(), "\" does not have BIND_UNIFORM_BUFFER flag" ); + continue; + } + + VERIFY_EXPR(d3d11CBs[BindPoint] == CB.pBuff->GetD3D11Buffer()); + + if(CommittedD3D11CBs[BindPoint] == nullptr ) + { + LOG_ERROR_MESSAGE( "No D3D11 resource committed to constant buffer \"", DbgMakeResourceName(cb,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\"" ); + continue; + } + + if(CommittedD3D11CBs[BindPoint] != d3d11CBs[BindPoint] ) + { + LOG_ERROR_MESSAGE( "D3D11 resource committed to constant buffer \"", DbgMakeResourceName(cb,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\" does not match the resource in the resource cache" ); + continue; + } + } + }, + + [&](const D3DShaderResourceAttribs& tex) + { + for(auto BindPoint = tex.BindPoint; BindPoint < tex.BindPoint + tex.BindCount; ++BindPoint) + { + if (BindPoint >= ResourceCache.GetSRVCount()) + { + LOG_ERROR_MESSAGE( "Unable to find texture SRV \"", DbgMakeResourceName(tex,BindPoint), "\" (slot ", BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetSRVCount()," SRV slots only. This should never happen and may be the result of using wrong resource cache." ); + continue; + } + auto &SRVRes = CachedSRVResources[BindPoint]; + if(SRVRes.pBuffer != nullptr) + { + LOG_ERROR_MESSAGE( "Unexpected buffer bound to variable \"", DbgMakeResourceName(tex,BindPoint), "\" (slot ", BindPoint, "). Texture is expected." ); + continue; + } + if(SRVRes.pTexture == nullptr) + { + LOG_ERROR_MESSAGE( "Texture \"", DbgMakeResourceName(tex,BindPoint), "\" (slot ", BindPoint, ") is not initialized in the resource cache." ); + continue; + } + + if (!(SRVRes.pTexture->GetDesc().BindFlags & BIND_SHADER_RESOURCE)) + { + LOG_ERROR_MESSAGE( "Texture \"", SRVRes.pTexture->GetDesc().Name, "\" committed in the device context as SRV to variable \"", DbgMakeResourceName(tex,BindPoint), "\" (slot ", BindPoint, ") in shader \"", GetShaderName(), "\" does not have BIND_SHADER_RESOURCE flag" ); + } + + if(CommittedD3D11SRVs[BindPoint] == nullptr ) + { + LOG_ERROR_MESSAGE( "No D3D11 resource committed to texture SRV \"", DbgMakeResourceName(tex,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\"" ); + continue; + } + + if(CommittedD3D11SRVs[BindPoint] != d3d11SRVs[BindPoint] ) + { + LOG_ERROR_MESSAGE( "D3D11 resource committed to texture SRV \"", DbgMakeResourceName(tex,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\" does not match the resource in the resource cache" ); + continue; + } + } + + if( tex.IsValidSampler() ) + { + const auto& SamAttribs = GetSampler( tex.GetSamplerId() ); + VERIFY_EXPR(SamAttribs.IsValidBindPoint()); + VERIFY_EXPR(SamAttribs.BindCount == 1 || SamAttribs.BindCount == tex.BindCount); + + for(auto SamBindPoint = SamAttribs.BindPoint; SamBindPoint < SamAttribs.BindPoint + SamAttribs.BindCount; ++SamBindPoint) + { + if (SamBindPoint >= ResourceCache.GetSamplerCount()) + { + LOG_ERROR_MESSAGE( "Unable to find sampler \"", DbgMakeResourceName(SamAttribs,SamBindPoint), "\" (slot ", SamBindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetSamplerCount()," Sampler slots only. This should never happen and may be the result of using wrong resource cache." ); + continue; + } + auto &Sam = CachedSamplers[SamBindPoint]; + if(Sam.pSampler == nullptr) + { + LOG_ERROR_MESSAGE( "Sampler \"", DbgMakeResourceName(SamAttribs,SamBindPoint), "\" (slot ", SamBindPoint, ") is not initialized in the resource cache." ); + continue; + } + VERIFY_EXPR(d3d11Samplers[SamBindPoint] == Sam.pSampler->GetD3D11SamplerState()); + + if(CommittedD3D11Samplers[SamBindPoint] == nullptr ) + { + LOG_ERROR_MESSAGE( "No D3D11 sampler committed to variable \"", DbgMakeResourceName(SamAttribs,SamBindPoint), "\" (slot ", SamBindPoint ,") in shader \"", GetShaderName(), "\"" ); + continue; + } + + if(CommittedD3D11Samplers[SamBindPoint] != d3d11Samplers[SamBindPoint]) + { + LOG_ERROR_MESSAGE( "D3D11 sampler committed to variable \"", DbgMakeResourceName(SamAttribs,SamBindPoint), "\" (slot ", SamBindPoint ,") in shader \"", GetShaderName(), "\" does not match the resource in the resource cache" ); + continue; + } + } + } + }, + + [&](const D3DShaderResourceAttribs &uav) + { + for(auto BindPoint = uav.BindPoint; BindPoint < uav.BindPoint + uav.BindCount; ++BindPoint) + { + if (BindPoint >= ResourceCache.GetUAVCount()) + { + LOG_ERROR_MESSAGE( "Unable to find texture UAV \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetUAVCount()," UAV slots only. This should never happen and may be the result of using wrong resource cache." ); + continue; + } + auto &UAVRes = CachedUAVResources[BindPoint]; + if(UAVRes.pBuffer != nullptr) + { + LOG_ERROR_MESSAGE( "Unexpected buffer bound to variable \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, "). Texture is expected." ); + continue; + } + if(UAVRes.pTexture == nullptr) + { + LOG_ERROR_MESSAGE( "Texture \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, ") is not initialized in the resource cache." ); + continue; + } + + if (!(UAVRes.pTexture->GetDesc().BindFlags & BIND_UNORDERED_ACCESS)) + { + LOG_ERROR_MESSAGE( "Texture \"", UAVRes.pTexture->GetDesc().Name, "\" committed in the device context as UAV to variable \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, ") in shader \"", GetShaderName(), "\" does not have BIND_UNORDERED_ACCESS flag" ); + } + + if(CommittedD3D11UAVs[BindPoint] == nullptr ) + { + LOG_ERROR_MESSAGE( "No D3D11 resource committed to texture UAV \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\"" ); + continue; + } + + if(CommittedD3D11UAVs[BindPoint] != d3d11UAVs[BindPoint] ) + { + LOG_ERROR_MESSAGE( "D3D11 resource committed to texture UAV \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\" does not match the resource in the resource cache" ); + continue; + } + } + }, + + + [&](const D3DShaderResourceAttribs &buf) + { + for(auto BindPoint = buf.BindPoint; BindPoint < buf.BindPoint + buf.BindCount; ++BindPoint) + { + if (BindPoint >= ResourceCache.GetSRVCount()) + { + LOG_ERROR_MESSAGE( "Unable to find buffer SRV \"", DbgMakeResourceName(buf,BindPoint), "\" (slot ", BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetSRVCount()," SRV slots only. This should never happen and may be the result of using wrong resource cache." ); + continue; + } + auto &SRVRes = CachedSRVResources[BindPoint]; + if(SRVRes.pTexture != nullptr) + { + LOG_ERROR_MESSAGE( "Unexpected texture bound to variable \"", DbgMakeResourceName(buf,BindPoint), "\" (slot ", BindPoint, "). Buffer is expected." ); + continue; + } + if(SRVRes.pBuffer == nullptr) + { + LOG_ERROR_MESSAGE( "Buffer \"", DbgMakeResourceName(buf,BindPoint), "\" (slot ", BindPoint ,") is not initialized in the resource cache." ); + continue; + } + + if (!(SRVRes.pBuffer->GetDesc().BindFlags & BIND_SHADER_RESOURCE)) + { + LOG_ERROR_MESSAGE( "Buffer \"", SRVRes.pBuffer->GetDesc().Name, "\" committed in the device context as SRV to variable \"", DbgMakeResourceName(buf,BindPoint), "\" (slot ", BindPoint, ") in shader \"", GetShaderName(), "\" does not have BIND_SHADER_RESOURCE flag" ); + } + + if(CommittedD3D11SRVs[BindPoint] == nullptr ) + { + LOG_ERROR_MESSAGE( "No D3D11 resource committed to buffer SRV \"", DbgMakeResourceName(buf,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\"" ); + continue; + } + + if(CommittedD3D11SRVs[BindPoint] != d3d11SRVs[BindPoint] ) + { + LOG_ERROR_MESSAGE( "D3D11 resource committed to buffer SRV \"", DbgMakeResourceName(buf,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\" does not match the resource in the resource cache" ); + continue; + } + } + }, + + [&](const D3DShaderResourceAttribs &uav) + { + for(auto BindPoint = uav.BindPoint; BindPoint < uav.BindPoint + uav.BindCount; ++BindPoint) + { + if (BindPoint >= ResourceCache.GetUAVCount()) + { + LOG_ERROR_MESSAGE( "Unable to find buffer UAV \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetUAVCount()," UAV slots only. This should never happen and may be the result of using wrong resource cache." ); + continue; + } + auto &UAVRes = CachedUAVResources[BindPoint]; + if(UAVRes.pTexture != nullptr) + { + LOG_ERROR_MESSAGE( "Unexpected texture bound to variable \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, "). Buffer is expected." ); + return; + } + if(UAVRes.pBuffer == nullptr) + { + LOG_ERROR_MESSAGE( "Buffer UAV \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, ") is not initialized in the resource cache." ); + return; + } + + if (!(UAVRes.pBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS)) + { + LOG_ERROR_MESSAGE( "Buffer \"", UAVRes.pBuffer->GetDesc().Name, "\" committed in the device context as UAV to variable \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint, ") in shader \"", GetShaderName(), "\" does not have BIND_UNORDERED_ACCESS flag" ); + } + + if(CommittedD3D11UAVs[BindPoint] == nullptr ) + { + LOG_ERROR_MESSAGE( "No D3D11 resource committed to buffer UAV \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\"" ); + return; + } + + if(CommittedD3D11UAVs[BindPoint] != d3d11UAVs[BindPoint] ) + { + LOG_ERROR_MESSAGE( "D3D11 resource committed to buffer UAV \"", DbgMakeResourceName(uav,BindPoint), "\" (slot ", BindPoint ,") in shader \"", GetShaderName(), "\" does not match the resource in the resource cache" ); + return; + } + } + } + ); +} +#endif + +} diff --git a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp index d2f639a6..85b908f6 100644 --- a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,24 +25,22 @@ #include "SwapChainD3D11Impl.h" #include "RenderDeviceD3D11Impl.h" #include "DeviceContextD3D11Impl.h" +#include <dxgi1_2.h> using namespace Diligent; namespace Diligent { -SwapChainD3D11Impl::SwapChainD3D11Impl(const SwapChainDesc& SCDesc, - RenderDeviceD3D11Impl* pRenderDeviceD3D11, - DeviceContextD3D11Impl* pDeviceContextD3D11, - void* pNativeWndHandle) : - TSwapChainBase(pRenderDeviceD3D11, pDeviceContextD3D11, SCDesc) +SwapChainD3D11Impl::SwapChainD3D11Impl(IMemoryAllocator &Allocator, + const SwapChainDesc& SCDesc, + RenderDeviceD3D11Impl* pRenderDeviceD3D11, + DeviceContextD3D11Impl* pDeviceContextD3D11, + void* pNativeWndHandle) : + TSwapChainBase(Allocator, pRenderDeviceD3D11, pDeviceContextD3D11, SCDesc) { - auto *pDevice = pRenderDeviceD3D11->GetD3D11Device(); - - auto DXGIColorBuffFmt = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat); - -#if defined( PLATFORM_WINDOWS ) +#ifdef PLATFORM_WIN32 auto hWnd = reinterpret_cast<HWND>(pNativeWndHandle); if( m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0 ) @@ -52,50 +50,48 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(const SwapChainDesc& SCDesc, m_SwapChainDesc.Width = rc.right - rc.left; m_SwapChainDesc.Height = rc.bottom - rc.top; } +#endif + + auto *pDevice = pRenderDeviceD3D11->GetD3D11Device(); + + auto DXGIColorBuffFmt = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = m_SwapChainDesc.Width; + swapChainDesc.Height = m_SwapChainDesc.Height; + // Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats: + // - DXGI_FORMAT_R16G16B16A16_FLOAT + // - DXGI_FORMAT_B8G8R8A8_UNORM + // - DXGI_FORMAT_R8G8B8A8_UNORM + // - DXGI_FORMAT_R10G10B10A2_UNORM + // If RGBA8_UNORM_SRGB swap chain is required, we will create RGBA8_UNORM swap chain, but + // create RGBA8_UNORM_SRGB render target view + swapChainDesc.Format = DXGIColorBuffFmt == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGIColorBuffFmt; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = m_SwapChainDesc.BufferCount; + swapChainDesc.Scaling = DXGI_SCALING_NONE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used + swapChainDesc.Flags = 0; + + CComPtr<IDXGISwapChain1> pSwapChain1; +#if defined( PLATFORM_WIN32 ) // This sequence obtains the DXGI factory that was used to create the Direct3D device above. CComPtr<IDXGIDevice> pDXGIDevice; pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>( static_cast<IDXGIDevice**>(&pDXGIDevice) ) ); CComPtr<IDXGIAdapter> pDXGIAdapter; pDXGIDevice->GetAdapter(&pDXGIAdapter); - CComPtr<IDXGIFactory> pDXGIFactory; - pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>( static_cast<IDXGIFactory**>(&pDXGIFactory) )); - - DXGI_SWAP_CHAIN_DESC sd; - ZeroMemory( &sd, sizeof( sd ) ); - sd.BufferCount = 1; - sd.BufferDesc.Width = m_SwapChainDesc.Width; - sd.BufferDesc.Height = m_SwapChainDesc.Height; - sd.BufferDesc.Format = DXGIColorBuffFmt; - sd.BufferDesc.RefreshRate.Numerator = 0; - sd.BufferDesc.RefreshRate.Denominator = 0; - sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - sd.OutputWindow = hWnd; - sd.SampleDesc.Count = m_SwapChainDesc.SamplesCount; - sd.SampleDesc.Quality = 0; - sd.Windowed = TRUE; - sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // Set this flag to enable an application to switch - // modes by calling IDXGISwapChain::ResizeTarget. When switching from windowed to full-screen mode, the - // display mode (or monitor resolution) will be changed to match the dimensions of the application window. - CHECK_D3D_RESULT_THROW( pDXGIFactory->CreateSwapChain(pDevice, &sd, &m_pSwapChain), - "Failed to create DXGI swap chain" ); - -#elif defined( PLATFORM_WINDOWS_STORE ) + CComPtr<IDXGIFactory2> pDXGIFactory; + pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>( static_cast<IDXGIFactory2**>(&pDXGIFactory) )); - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; + CHECK_D3D_RESULT_THROW( pDXGIFactory->CreateSwapChainForHwnd(pDevice, hWnd, &swapChainDesc, nullptr, nullptr, &pSwapChain1), + "Failed to create DXGI swap chain" ); - swapChainDesc.Width = m_SwapChainDesc.Width; - swapChainDesc.Height = m_SwapChainDesc.Height; - swapChainDesc.Format = DXGIColorBuffFmt; - swapChainDesc.Stereo = false; - swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. - swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency. - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. - swapChainDesc.Flags = 0; - swapChainDesc.Scaling = DXGI_SCALING_NONE; - swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; +#elif defined( PLATFORM_UNIVERSAL_WINDOWS ) CComPtr<IDXGIDevice3> pDXGIDevice; pDevice->QueryInterface(__uuidof(IDXGIDevice3), reinterpret_cast<void**>(static_cast<IDXGIDevice3**>(&pDXGIDevice))); @@ -103,8 +99,7 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(const SwapChainDesc& SCDesc, pDXGIDevice->GetAdapter(&pDXGIAdapter); CComPtr<IDXGIFactory2> pDXGIFactory; pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>(static_cast<IDXGIFactory2**>(&pDXGIFactory))); - - CComPtr<IDXGISwapChain1> pSwapChain1; + HRESULT hr = pDXGIFactory->CreateSwapChainForCoreWindow( pDevice, reinterpret_cast<IUnknown*>(pNativeWndHandle), @@ -113,14 +108,14 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(const SwapChainDesc& SCDesc, &pSwapChain1); CHECK_D3D_RESULT_THROW( hr, "Failed to create DXGI swap chain" ); - pSwapChain1->QueryInterface( __uuidof(m_pSwapChain), reinterpret_cast<void**>(static_cast<IDXGISwapChain**>(&m_pSwapChain)) ); - // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and // ensures that the application will only render after each VSync, minimizing power consumption. pDXGIDevice->SetMaximumFrameLatency( 1 ); #endif + pSwapChain1->QueryInterface( __uuidof(m_pSwapChain), reinterpret_cast<void**>(static_cast<IDXGISwapChain**>(&m_pSwapChain)) ); + CreateRTVandDSV(); } @@ -141,7 +136,13 @@ void SwapChainD3D11Impl::CreateRTVandDSV() CHECK_D3D_RESULT_THROW( m_pSwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>( static_cast<ID3D11Texture2D**>(&pBackBuffer) ) ), "Failed to get back buffer from swap chain" ); - CHECK_D3D_RESULT_THROW( pDevice->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderTargetView ), + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc = {}; + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + // We need to explicitly specify RTV format, as we may need to create RGBA8_UNORM_SRGB RTV for + // a RGBA8_UNORM swap chain + RTVDesc.Format = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat); + RTVDesc.Texture2D.MipSlice = 0; + CHECK_D3D_RESULT_THROW( pDevice->CreateRenderTargetView( pBackBuffer, &RTVDesc, &m_pRenderTargetView ), "Failed to get RTV for the back buffer" ); // Create depth buffer @@ -172,7 +173,7 @@ IMPLEMENT_QUERY_INTERFACE( SwapChainD3D11Impl, IID_SwapChainD3D11, TSwapChainBas void SwapChainD3D11Impl::Present() { UINT SyncInterval = 0; -#ifdef PLATFORM_WINDOWS_STORE +#ifdef PLATFORM_UNIVERSAL_WINDOWS SyncInterval = 1; // Interval 0 is not supported on Windows Phone #endif @@ -193,13 +194,11 @@ void SwapChainD3D11Impl::Present() m_pSwapChain->Present( SyncInterval, 0 ); -#ifdef PLATFORM_WINDOWS_STORE // A successful Present call for DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL SwapChains unbinds // backbuffer 0 from all GPU writeable bind points. // We need to rebind all render targets to make sure that // the back buffer is not unbound pImmediateCtxD3D11->RebindRenderTargets(); -#endif } void SwapChainD3D11Impl::Resize( Uint32 NewWidth, Uint32 NewHeight ) diff --git a/Graphics/GraphicsEngineD3D11/src/Texture1D_D3D11.cpp b/Graphics/GraphicsEngineD3D11/src/Texture1D_D3D11.cpp index 75eaab86..7a6cba6e 100644 --- a/Graphics/GraphicsEngineD3D11/src/Texture1D_D3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/Texture1D_D3D11.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,8 +29,12 @@ namespace Diligent { -Texture1D_D3D11 :: Texture1D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : - TextureBaseD3D11(pRenderDeviceD3D11, TexDesc, InitData) +Texture1D_D3D11 :: Texture1D_D3D11(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + RenderDeviceD3D11Impl *pRenderDeviceD3D11, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/) : + TextureBaseD3D11(TexObjAllocator, TexViewObjAllocator, pRenderDeviceD3D11, TexDesc, InitData) { auto D3D11TexFormat = TexFormatToDXGI_Format(m_Desc.Format, m_Desc.BindFlags); auto D3D11BindFlags = BindFlagsToD3D11BindFlags(m_Desc.BindFlags); @@ -51,7 +55,7 @@ Texture1D_D3D11 :: Texture1D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, co MiscFlags }; - std::vector<D3D11_SUBRESOURCE_DATA> D3D11InitData; + std::vector<D3D11_SUBRESOURCE_DATA, STDAllocatorRawMem<D3D11_SUBRESOURCE_DATA>> D3D11InitData( STD_ALLOCATOR_RAW_MEM(D3D11_SUBRESOURCE_DATA, GetRawAllocator(), "Allocator for vector<D3D11_SUBRESOURCE_DATA>") ); PrepareD3D11InitData(InitData, Tex1DDesc.ArraySize * Tex1DDesc.MipLevels, D3D11InitData); ID3D11Texture1D *ptex1D = nullptr; @@ -69,8 +73,8 @@ void Texture1D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceV VERIFY( ppD3D11SRV && *ppD3D11SRV == nullptr, "SRV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( SRVDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); - if( !(SRVDesc.TextureType == TEXTURE_TYPE_1D || SRVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY) ) - LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed" ); + if( !(SRVDesc.TextureDim == RESOURCE_DIM_TEX_1D || SRVDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only RESOURCE_DIM_TEX_1D or RESOURCE_DIM_TEX_1D_ARRAY is allowed" ); if( SRVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -78,27 +82,7 @@ void Texture1D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceV } D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; - memset(&D3D11_SRVDesc, 0, sizeof(D3D11_SRVDesc)); - D3D11_SRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); - - if( SRVDesc.TextureType == TEXTURE_TYPE_1D ) - { - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; - D3D11_SRVDesc.Texture1D.MipLevels = SRVDesc.NumMipLevels; - D3D11_SRVDesc.Texture1D.MostDetailedMip = SRVDesc.MostDetailedMip; - } - else if( SRVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) - { - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - D3D11_SRVDesc.Texture1DArray.ArraySize = SRVDesc.NumArraySlices; - D3D11_SRVDesc.Texture1DArray.FirstArraySlice = SRVDesc.FirstArraySlice; - D3D11_SRVDesc.Texture1DArray.MipLevels = SRVDesc.NumMipLevels; - D3D11_SRVDesc.Texture1DArray.MostDetailedMip = SRVDesc.MostDetailedMip; - } - else - { - UNEXPECTED( "Unexpected view type" ); - } + TextureViewDesc_to_D3D11_SRV_DESC(SRVDesc, D3D11_SRVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Texture, &D3D11_SRVDesc, ppD3D11SRV ), @@ -110,8 +94,8 @@ void Texture1D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetVie VERIFY( ppD3D11RTV && *ppD3D11RTV == nullptr, "RTV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( RTVDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); - if( !(RTVDesc.TextureType == TEXTURE_TYPE_1D || RTVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) ) - LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed" ); + if( !(RTVDesc.TextureDim == RESOURCE_DIM_TEX_1D || RTVDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY ) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only RESOURCE_DIM_TEX_1D or RESOURCE_DIM_TEX_1D_ARRAY is allowed" ); if( RTVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -119,25 +103,7 @@ void Texture1D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetVie } D3D11_RENDER_TARGET_VIEW_DESC D3D11_RTVDesc; - memset(&D3D11_RTVDesc, 0, sizeof(D3D11_RTVDesc)); - D3D11_RTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); - - if( RTVDesc.TextureType == TEXTURE_TYPE_1D ) - { - D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; - D3D11_RTVDesc.Texture1D.MipSlice = RTVDesc.MostDetailedMip; - } - else if( RTVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) - { - D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; - D3D11_RTVDesc.Texture1DArray.ArraySize = RTVDesc.NumArraySlices; - D3D11_RTVDesc.Texture1DArray.FirstArraySlice = RTVDesc.FirstArraySlice; - D3D11_RTVDesc.Texture1DArray.MipSlice = RTVDesc.MostDetailedMip; - } - else - { - UNEXPECTED( "Unexpected view type" ); - } + TextureViewDesc_to_D3D11_RTV_DESC(RTVDesc, D3D11_RTVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRenderTargetView( m_pd3d11Texture, &D3D11_RTVDesc, ppD3D11RTV ), @@ -149,8 +115,8 @@ void Texture1D_D3D11::CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilVie VERIFY( ppD3D11DSV && *ppD3D11DSV == nullptr, "DSV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( DSVDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); - if( !(DSVDesc.TextureType == TEXTURE_TYPE_1D || DSVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY) ) - LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed"); + if( !(DSVDesc.TextureDim == RESOURCE_DIM_TEX_1D || DSVDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only RESOURCE_DIM_TEX_1D or RESOURCE_DIM_TEX_1D_ARRAY is allowed"); if( DSVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -158,25 +124,7 @@ void Texture1D_D3D11::CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilVie } D3D11_DEPTH_STENCIL_VIEW_DESC D3D11_DSVDesc; - memset(&D3D11_DSVDesc, 0, sizeof(D3D11_DSVDesc)); - D3D11_DSVDesc.Format = TexFormatToDXGI_Format(DSVDesc.Format, BIND_DEPTH_STENCIL); - - if( DSVDesc.TextureType == TEXTURE_TYPE_1D ) - { - D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; - D3D11_DSVDesc.Texture1D.MipSlice = DSVDesc.MostDetailedMip; - } - else if( DSVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) - { - D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; - D3D11_DSVDesc.Texture1DArray.ArraySize = DSVDesc.NumArraySlices; - D3D11_DSVDesc.Texture1DArray.FirstArraySlice = DSVDesc.FirstArraySlice; - D3D11_DSVDesc.Texture1DArray.MipSlice = DSVDesc.MostDetailedMip; - } - else - { - UNEXPECTED( "Unexpected view type" ); - } + TextureViewDesc_to_D3D11_DSV_DESC(DSVDesc, D3D11_DSVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateDepthStencilView( m_pd3d11Texture, &D3D11_DSVDesc, ppD3D11DSV ), @@ -188,8 +136,8 @@ void Texture1D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccess VERIFY( ppD3D11UAV && *ppD3D11UAV == nullptr, "UAV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( UAVDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); - if( !(UAVDesc.TextureType == TEXTURE_TYPE_1D || UAVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY) ) - LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_1D or TEXTURE_TYPE_1D_ARRAY is allowed"); + if( !(UAVDesc.TextureDim == RESOURCE_DIM_TEX_1D || UAVDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only RESOURCE_DIM_TEX_1D or RESOURCE_DIM_TEX_1D_ARRAY is allowed"); if( UAVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -197,26 +145,7 @@ void Texture1D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccess } D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; - memset(&D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc)); - D3D11_UAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); - - if( UAVDesc.TextureType == TEXTURE_TYPE_1D ) - { - D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D; - D3D11_UAVDesc.Texture1D.MipSlice = UAVDesc.MostDetailedMip; - } - else if( UAVDesc.TextureType == TEXTURE_TYPE_1D_ARRAY ) - { - D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY; - D3D11_UAVDesc.Texture1DArray.ArraySize = UAVDesc.NumArraySlices; - D3D11_UAVDesc.Texture1DArray.FirstArraySlice = UAVDesc.FirstArraySlice; - D3D11_UAVDesc.Texture1DArray.MipSlice = UAVDesc.MostDetailedMip; - } - else - { - UNEXPECTED( "Unexpected view type" ); - } - + TextureViewDesc_to_D3D11_UAV_DESC(UAVDesc, D3D11_UAVDesc); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Texture, &D3D11_UAVDesc, ppD3D11UAV ), diff --git a/Graphics/GraphicsEngineD3D11/src/Texture2D_D3D11.cpp b/Graphics/GraphicsEngineD3D11/src/Texture2D_D3D11.cpp index fc34d18d..f2fef036 100644 --- a/Graphics/GraphicsEngineD3D11/src/Texture2D_D3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/Texture2D_D3D11.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,14 +29,20 @@ namespace Diligent { -Texture2D_D3D11 :: Texture2D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : - TextureBaseD3D11(pRenderDeviceD3D11, TexDesc, InitData) +Texture2D_D3D11 :: Texture2D_D3D11(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + RenderDeviceD3D11Impl *pRenderDeviceD3D11, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/) : + TextureBaseD3D11(TexObjAllocator, TexViewObjAllocator, pRenderDeviceD3D11, TexDesc, InitData) { auto D3D11TexFormat = TexFormatToDXGI_Format(m_Desc.Format, m_Desc.BindFlags); auto D3D11BindFlags = BindFlagsToD3D11BindFlags(m_Desc.BindFlags); auto D3D11CPUAccessFlags = CPUAccessFlagsToD3D11CPUAccessFlags(m_Desc.CPUAccessFlags); auto D3D11Usage = UsageToD3D11Usage(m_Desc.Usage); UINT MiscFlags = MiscTextureFlagsToD3D11Flags(m_Desc.MiscFlags); + if(m_Desc.Type == RESOURCE_DIM_TEX_CUBE || m_Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) + MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; DXGI_SAMPLE_DESC D3D11SampleDesc = {m_Desc.SampleCount, 0}; auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); @@ -54,7 +60,7 @@ Texture2D_D3D11 :: Texture2D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, co MiscFlags }; - std::vector<D3D11_SUBRESOURCE_DATA> D3D11InitData; + std::vector<D3D11_SUBRESOURCE_DATA, STDAllocatorRawMem<D3D11_SUBRESOURCE_DATA>> D3D11InitData( STD_ALLOCATOR_RAW_MEM(D3D11_SUBRESOURCE_DATA, GetRawAllocator(), "Allocator for vector<D3D11_SUBRESOURCE_DATA>") ); PrepareD3D11InitData(InitData, Tex2DDesc.ArraySize * Tex2DDesc.MipLevels, D3D11InitData); ID3D11Texture2D *ptex2D = nullptr; @@ -72,8 +78,9 @@ void Texture2D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceV VERIFY( ppD3D11SRV && *ppD3D11SRV == nullptr, "SRV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( SRVDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); - if( !(SRVDesc.TextureType == TEXTURE_TYPE_2D || SRVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) - LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed"); + if( !(SRVDesc.TextureDim == RESOURCE_DIM_TEX_2D || SRVDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY || + SRVDesc.TextureDim == RESOURCE_DIM_TEX_CUBE || SRVDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only RESOURCE_DIM_TEX_2D, RESOURCE_DIM_TEX_2D_ARRAY, RESOURCE_DIM_TEX_CUBE, or RESOURCE_DIM_TEX_CUBE_ARRAY is allowed"); if( SRVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -81,45 +88,7 @@ void Texture2D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceV } D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; - memset(&D3D11_SRVDesc, 0, sizeof(D3D11_SRVDesc)); - D3D11_SRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); - - - if( SRVDesc.TextureType == TEXTURE_TYPE_2D ) - { - if( m_Desc.SampleCount > 1 ) - { - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; - D3D11_SRVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; - } - else - { - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - D3D11_SRVDesc.Texture2D.MipLevels = SRVDesc.NumMipLevels; - D3D11_SRVDesc.Texture2D.MostDetailedMip = SRVDesc.MostDetailedMip; - } - } - else if( SRVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) - { - if( m_Desc.SampleCount > 1 ) - { - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - D3D11_SRVDesc.Texture2DMSArray.ArraySize = SRVDesc.NumArraySlices; - D3D11_SRVDesc.Texture2DMSArray.FirstArraySlice = SRVDesc.FirstArraySlice; - } - else - { - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - D3D11_SRVDesc.Texture2DArray.ArraySize = SRVDesc.NumArraySlices; - D3D11_SRVDesc.Texture2DArray.FirstArraySlice = SRVDesc.FirstArraySlice; - D3D11_SRVDesc.Texture2DArray.MipLevels = SRVDesc.NumMipLevels; - D3D11_SRVDesc.Texture2DArray.MostDetailedMip = SRVDesc.MostDetailedMip; - } - } - else - { - UNEXPECTED( "Unexpected view type" ); - } + TextureViewDesc_to_D3D11_SRV_DESC(SRVDesc, D3D11_SRVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Texture, &D3D11_SRVDesc, ppD3D11SRV ), @@ -131,8 +100,8 @@ void Texture2D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetVie VERIFY( ppD3D11RTV && *ppD3D11RTV == nullptr, "RTV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( RTVDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); - if( !(RTVDesc.TextureType == TEXTURE_TYPE_2D || RTVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) - LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed" ); + if( !(RTVDesc.TextureDim == RESOURCE_DIM_TEX_2D || RTVDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only RESOURCE_DIM_TEX_2D or RESOURCE_DIM_TEX_2D_ARRAY is allowed" ); if( RTVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -140,43 +109,7 @@ void Texture2D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetVie } D3D11_RENDER_TARGET_VIEW_DESC D3D11_RTVDesc; - memset(&D3D11_RTVDesc, 0, sizeof(D3D11_RTVDesc)); - D3D11_RTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); - - if( RTVDesc.TextureType == TEXTURE_TYPE_2D ) - { - if( m_Desc.SampleCount > 1 ) - { - D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - D3D11_RTVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; - } - else - { - D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - D3D11_RTVDesc.Texture2D.MipSlice = RTVDesc.MostDetailedMip; - } - } - else if( RTVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) - { - if( m_Desc.SampleCount > 1 ) - { - D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; - D3D11_RTVDesc.Texture2DMSArray.ArraySize = RTVDesc.NumArraySlices; - D3D11_RTVDesc.Texture2DMSArray.FirstArraySlice = RTVDesc.FirstArraySlice; - } - else - { - D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - D3D11_RTVDesc.Texture2DArray.ArraySize = RTVDesc.NumArraySlices; - D3D11_RTVDesc.Texture2DArray.FirstArraySlice = RTVDesc.FirstArraySlice; - D3D11_RTVDesc.Texture2DArray.MipSlice = RTVDesc.MostDetailedMip; - } - } - else - { - UNEXPECTED( "Unexpected view type" ); - } - + TextureViewDesc_to_D3D11_RTV_DESC(RTVDesc, D3D11_RTVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRenderTargetView( m_pd3d11Texture, &D3D11_RTVDesc, ppD3D11RTV ), @@ -188,8 +121,8 @@ void Texture2D_D3D11::CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilVie VERIFY( ppD3D11DSV && *ppD3D11DSV == nullptr, "DSV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( DSVDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); - if( !(DSVDesc.TextureType == TEXTURE_TYPE_2D || DSVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) - LOG_ERROR_AND_THROW("Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed"); + if( !(DSVDesc.TextureDim == RESOURCE_DIM_TEX_2D || DSVDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY) ) + LOG_ERROR_AND_THROW("Unsupported texture type. Only RESOURCE_DIM_TEX_2D or RESOURCE_DIM_TEX_2D_ARRAY is allowed"); if( DSVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -197,42 +130,7 @@ void Texture2D_D3D11::CreateDSV( TextureViewDesc &DSVDesc, ID3D11DepthStencilVie } D3D11_DEPTH_STENCIL_VIEW_DESC D3D11_DSVDesc; - memset(&D3D11_DSVDesc, 0, sizeof(D3D11_DSVDesc)); - D3D11_DSVDesc.Format = TexFormatToDXGI_Format(DSVDesc.Format, BIND_DEPTH_STENCIL); - - if( DSVDesc.TextureType == TEXTURE_TYPE_2D ) - { - if( m_Desc.SampleCount > 1 ) - { - D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; - D3D11_DSVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; - } - else - { - D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - D3D11_DSVDesc.Texture2D.MipSlice = DSVDesc.MostDetailedMip; - } - } - else if( DSVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) - { - if( m_Desc.SampleCount > 1 ) - { - D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; - D3D11_DSVDesc.Texture2DMSArray.ArraySize = DSVDesc.NumArraySlices; - D3D11_DSVDesc.Texture2DMSArray.FirstArraySlice = DSVDesc.FirstArraySlice; - } - else - { - D3D11_DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - D3D11_DSVDesc.Texture2DArray.ArraySize = DSVDesc.NumArraySlices; - D3D11_DSVDesc.Texture2DArray.FirstArraySlice = DSVDesc.FirstArraySlice; - D3D11_DSVDesc.Texture2DArray.MipSlice = DSVDesc.MostDetailedMip; - } - } - else - { - UNEXPECTED( "Unexpected view type" ); - } + TextureViewDesc_to_D3D11_DSV_DESC(DSVDesc, D3D11_DSVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateDepthStencilView( m_pd3d11Texture, &D3D11_DSVDesc, ppD3D11DSV ), @@ -247,8 +145,8 @@ void Texture2D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccess LOG_ERROR_AND_THROW("UAVs are not allowed for multisampled resources"); VERIFY( UAVDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); - if( !(UAVDesc.TextureType == TEXTURE_TYPE_2D || UAVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY) ) - LOG_ERROR_AND_THROW( "Unsupported texture type. Only TEXTURE_TYPE_2D or TEXTURE_TYPE_2D_ARRAY is allowed" ); + if( !(UAVDesc.TextureDim == RESOURCE_DIM_TEX_2D || UAVDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY) ) + LOG_ERROR_AND_THROW( "Unsupported texture type. Only RESOURCE_DIM_TEX_2D or RESOURCE_DIM_TEX_2D_ARRAY is allowed" ); if( UAVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -256,25 +154,7 @@ void Texture2D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccess } D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; - memset(&D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc)); - D3D11_UAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); - - if( UAVDesc.TextureType == TEXTURE_TYPE_2D ) - { - D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; - D3D11_UAVDesc.Texture2D.MipSlice = UAVDesc.MostDetailedMip; - } - else if( UAVDesc.TextureType == TEXTURE_TYPE_2D_ARRAY ) - { - D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; - D3D11_UAVDesc.Texture2DArray.ArraySize = UAVDesc.NumArraySlices; - D3D11_UAVDesc.Texture2DArray.FirstArraySlice = UAVDesc.FirstArraySlice; - D3D11_UAVDesc.Texture2DArray.MipSlice = UAVDesc.MostDetailedMip; - } - else - { - UNEXPECTED( "Unexpected view type" ); - } + TextureViewDesc_to_D3D11_UAV_DESC(UAVDesc, D3D11_UAVDesc); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Texture, &D3D11_UAVDesc, ppD3D11UAV ), diff --git a/Graphics/GraphicsEngineD3D11/src/Texture3D_D3D11.cpp b/Graphics/GraphicsEngineD3D11/src/Texture3D_D3D11.cpp index 9546660e..bb7bd484 100644 --- a/Graphics/GraphicsEngineD3D11/src/Texture3D_D3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/Texture3D_D3D11.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,8 +29,12 @@ namespace Diligent { -Texture3D_D3D11 :: Texture3D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : - TextureBaseD3D11(pRenderDeviceD3D11, TexDesc, InitData) +Texture3D_D3D11 :: Texture3D_D3D11(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + RenderDeviceD3D11Impl *pRenderDeviceD3D11, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/) : + TextureBaseD3D11(TexObjAllocator, TexViewObjAllocator, pRenderDeviceD3D11, TexDesc, InitData) { auto D3D11TexFormat = TexFormatToDXGI_Format(m_Desc.Format, m_Desc.BindFlags); auto D3D11BindFlags = BindFlagsToD3D11BindFlags(m_Desc.BindFlags); @@ -52,7 +56,7 @@ Texture3D_D3D11 :: Texture3D_D3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, co MiscFlags }; - std::vector<D3D11_SUBRESOURCE_DATA> D3D11InitData; + std::vector<D3D11_SUBRESOURCE_DATA, STDAllocatorRawMem<D3D11_SUBRESOURCE_DATA>> D3D11InitData( STD_ALLOCATOR_RAW_MEM(D3D11_SUBRESOURCE_DATA, GetRawAllocator(), "Allocator for vector<D3D11_SUBRESOURCE_DATA>") ); PrepareD3D11InitData(InitData, Tex3DDesc.MipLevels, D3D11InitData); ID3D11Texture3D *ptex3D = nullptr; @@ -66,8 +70,8 @@ void Texture3D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceV VERIFY( ppD3D11SRV && *ppD3D11SRV == nullptr, "SRV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( SRVDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); - if( SRVDesc.TextureType != TEXTURE_TYPE_3D ) - LOG_ERROR_AND_THROW("Unsupported texture view type. Only TEXTURE_TYPE_3D is allowed"); + if( SRVDesc.TextureDim != RESOURCE_DIM_TEX_3D ) + LOG_ERROR_AND_THROW("Unsupported texture view type. Only RESOURCE_DIM_TEX_3D is allowed"); if( SRVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -75,12 +79,7 @@ void Texture3D_D3D11::CreateSRV( TextureViewDesc &SRVDesc, ID3D11ShaderResourceV } D3D11_SHADER_RESOURCE_VIEW_DESC D3D11_SRVDesc; - memset(&D3D11_SRVDesc, 0, sizeof(D3D11_SRVDesc)); - D3D11_SRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); - - D3D11_SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - D3D11_SRVDesc.Texture3D.MipLevels = SRVDesc.NumMipLevels; - D3D11_SRVDesc.Texture3D.MostDetailedMip = SRVDesc.MostDetailedMip; + TextureViewDesc_to_D3D11_SRV_DESC(SRVDesc, D3D11_SRVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateShaderResourceView( m_pd3d11Texture, &D3D11_SRVDesc, ppD3D11SRV ), @@ -92,8 +91,8 @@ void Texture3D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetVie VERIFY( ppD3D11RTV && *ppD3D11RTV == nullptr, "RTV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( RTVDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); - if( RTVDesc.TextureType != TEXTURE_TYPE_3D ) - LOG_ERROR_AND_THROW( "Unsupported texture view type. Only TEXTURE_TYPE_3D is allowed" ); + if( RTVDesc.TextureDim != RESOURCE_DIM_TEX_3D ) + LOG_ERROR_AND_THROW( "Unsupported texture view type. Only RESOURCE_DIM_TEX_3D is allowed" ); if( RTVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -101,13 +100,7 @@ void Texture3D_D3D11::CreateRTV( TextureViewDesc &RTVDesc, ID3D11RenderTargetVie } D3D11_RENDER_TARGET_VIEW_DESC D3D11_RTVDesc; - memset(&D3D11_RTVDesc, 0, sizeof(D3D11_RTVDesc)); - D3D11_RTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); - - D3D11_RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - D3D11_RTVDesc.Texture3D.FirstWSlice = RTVDesc.FirstDepthSlice; - D3D11_RTVDesc.Texture3D.WSize = RTVDesc.NumDepthSlices; - D3D11_RTVDesc.Texture3D.MipSlice = RTVDesc.MostDetailedMip; + TextureViewDesc_to_D3D11_RTV_DESC(RTVDesc, D3D11_RTVDesc, m_Desc.SampleCount); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateRenderTargetView( m_pd3d11Texture, &D3D11_RTVDesc, ppD3D11RTV ), @@ -124,8 +117,8 @@ void Texture3D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccess VERIFY( ppD3D11UAV && *ppD3D11UAV == nullptr, "UAV pointer address is null or contains non-null pointer to an existing object" ); VERIFY( UAVDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); - if( UAVDesc.TextureType != TEXTURE_TYPE_3D ) - LOG_ERROR_AND_THROW("Unsupported texture view type. Only TEXTURE_TYPE_3D is allowed"); + if( UAVDesc.TextureDim != RESOURCE_DIM_TEX_3D ) + LOG_ERROR_AND_THROW("Unsupported texture view type. Only RESOURCE_DIM_TEX_3D is allowed"); if( UAVDesc.Format == TEX_FORMAT_UNKNOWN ) { @@ -133,13 +126,7 @@ void Texture3D_D3D11::CreateUAV( TextureViewDesc &UAVDesc, ID3D11UnorderedAccess } D3D11_UNORDERED_ACCESS_VIEW_DESC D3D11_UAVDesc; - memset(&D3D11_UAVDesc, 0, sizeof(D3D11_UAVDesc)); - D3D11_UAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); - - D3D11_UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; - D3D11_UAVDesc.Texture3D.FirstWSlice = UAVDesc.FirstDepthSlice; - D3D11_UAVDesc.Texture3D.WSize = UAVDesc.NumDepthSlices; - D3D11_UAVDesc.Texture3D.MipSlice = UAVDesc.MostDetailedMip; + TextureViewDesc_to_D3D11_UAV_DESC(UAVDesc, D3D11_UAVDesc); auto *pDeviceD3D11 = static_cast<RenderDeviceD3D11Impl*>(GetDevice())->GetD3D11Device(); CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateUnorderedAccessView( m_pd3d11Texture, &D3D11_UAVDesc, ppD3D11UAV ), diff --git a/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp index 2462bec7..7401a714 100644 --- a/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,14 +27,13 @@ #include "DeviceContextD3D11Impl.h" #include "D3D11TypeConversions.h" #include "TextureViewD3D11Impl.h" - -using namespace Diligent; +#include "EngineMemory.h" namespace Diligent { -TextureBaseD3D11 :: TextureBaseD3D11(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : - TTextureBase(pRenderDeviceD3D11, TexDesc) +TextureBaseD3D11 :: TextureBaseD3D11(FixedBlockMemoryAllocator &TexObjAllocator, FixedBlockMemoryAllocator &TexViewObjAllocator, RenderDeviceD3D11Impl *pRenderDeviceD3D11, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/) : + TTextureBase(TexObjAllocator, TexViewObjAllocator, pRenderDeviceD3D11, TexDesc) { if( TexDesc.Usage == USAGE_STATIC && InitData.pSubResources == nullptr ) LOG_ERROR_AND_THROW("Static Texture must be initialized with data at creation time"); @@ -53,7 +52,6 @@ void TextureBaseD3D11::CreateViewInternal( const struct TextureViewDesc &ViewDes try { auto UpdatedViewDesc = ViewDesc; - CorrectTextureViewDesc( UpdatedViewDesc ); RefCntAutoPtr<ID3D11View> pD3D11View; @@ -98,7 +96,11 @@ void TextureBaseD3D11::CreateViewInternal( const struct TextureViewDesc &ViewDes default: UNEXPECTED( "Unknown view type" ); break; } - auto pViewD3D11 = new TextureViewD3D11Impl( GetDevice(), UpdatedViewDesc, this, pD3D11View, bIsDefaultView ); + auto *pDeviceD3D11Impl = ValidatedCast<RenderDeviceD3D11Impl>(GetDevice()); + auto &TexViewAllocator = pDeviceD3D11Impl->GetTexViewObjAllocator(); + VERIFY( &TexViewAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization" ); + + auto pViewD3D11 = NEW(TexViewAllocator, "TextureViewD3D11Impl instance", TextureViewD3D11Impl, pDeviceD3D11Impl, UpdatedViewDesc, this, pD3D11View, bIsDefaultView ); VERIFY( pViewD3D11->GetDesc().ViewType == ViewDesc.ViewType, "Incorrect view type" ); if( bIsDefaultView ) @@ -113,7 +115,8 @@ void TextureBaseD3D11::CreateViewInternal( const struct TextureViewDesc &ViewDes } } -void TextureBaseD3D11 :: PrepareD3D11InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<D3D11_SUBRESOURCE_DATA> &D3D11InitData) +void TextureBaseD3D11 :: PrepareD3D11InitData(const TextureData &InitData, Uint32 NumSubresources, + std::vector<D3D11_SUBRESOURCE_DATA, STDAllocatorRawMem<D3D11_SUBRESOURCE_DATA> > &D3D11InitData) { if( InitData.pSubResources ) { @@ -205,9 +208,9 @@ void TextureBaseD3D11 :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 //VERIFY( pMappedData, "Map failed" ); } -void TextureBaseD3D11::Unmap( IDeviceContext *pContext ) +void TextureBaseD3D11::Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) { - TTextureBase::Unmap( pContext ); + TTextureBase::Unmap( pContext, MapType ); //auto *pd3d11DeviceContext = static_cast<RenderDeviceD3D11Impl*>( static_cast<CRenderDevice*>(m_pDevice) )->GetD3D11DeviceContext(); //pd3d11DeviceContext->Unmap(m_pd3d11Texture, 0); diff --git a/Graphics/GraphicsEngineD3D11/src/TextureViewD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/TextureViewD3D11Impl.cpp index 1cebd403..9cc8b41d 100644 --- a/Graphics/GraphicsEngineD3D11/src/TextureViewD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/TextureViewD3D11Impl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,21 +28,17 @@ namespace Diligent { -TextureViewD3D11Impl::TextureViewD3D11Impl( IRenderDevice *pDevice, - const TextureViewDesc& ViewDesc, - ITexture *pTexture, - ID3D11View* pD3D11View, - bool bIsDefaultView ) : - TTextureViewBase( pDevice, ViewDesc, pTexture, bIsDefaultView ), +TextureViewD3D11Impl::TextureViewD3D11Impl( FixedBlockMemoryAllocator &TexViewAllocator, + IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + ITexture *pTexture, + ID3D11View* pD3D11View, + bool bIsDefaultView ) : + TTextureViewBase( TexViewAllocator, pDevice, ViewDesc, pTexture, bIsDefaultView ), m_pD3D11View( pD3D11View ) { } -ID3D11View* TextureViewD3D11Impl::GetD3D11View() -{ - return m_pD3D11View; -} - IMPLEMENT_QUERY_INTERFACE( TextureViewD3D11Impl, IID_TextureViewD3D11, TTextureViewBase ) void TextureViewD3D11Impl::GenerateMips( IDeviceContext *pContext ) diff --git a/Graphics/GraphicsEngineD3D11/src/VertexDescD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/VertexDescD3D11Impl.cpp deleted file mode 100644 index 46be4675..00000000 --- a/Graphics/GraphicsEngineD3D11/src/VertexDescD3D11Impl.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#include "pch.h" -#include "VertexDescD3D11Impl.h" -#include "RenderDeviceD3D11Impl.h" -#include "ShaderD3D11Impl.h" -#include "D3D11TypeConversions.h" - -namespace Diligent -{ - -VertexDescD3D11Impl::VertexDescD3D11Impl(RenderDeviceD3D11Impl *pRenderDeviceD3D11, const LayoutDesc &LayoutDesc, IShader *pVertexShader) : - TVertexDescriptionBase( pRenderDeviceD3D11, LayoutDesc ) -{ - // Use m_LayoutDesc as original LayoutDescription might have been corrected - auto *pLayoutElements = m_LayoutElements.data(); - auto NumElements = m_LayoutElements.size(); - - if( pVertexShader->GetDesc().ShaderType != SHADER_TYPE_VERTEX ) - LOG_ERROR_AND_THROW( "Invalid shader type provided for the input layout creation" ); - std::vector<D3D11_INPUT_ELEMENT_DESC> InputElements; - ID3DBlob *pVSByteCode = static_cast<ShaderD3D11Impl*>(pVertexShader)->m_pShaderByteCode; - if( !pVSByteCode ) - LOG_ERROR_AND_THROW( "Vertex Shader byte code does not exist" ); - - InputElements.resize(NumElements); - for(Uint32 iElem=0; iElem < NumElements; ++iElem) - { - const auto &CurrElem = pLayoutElements[iElem]; - auto &D3D11Elem = InputElements[iElem]; - D3D11Elem.SemanticName = "ATTRIB"; - D3D11Elem.SemanticIndex = CurrElem.InputIndex; - D3D11Elem.AlignedByteOffset = CurrElem.RelativeOffset; - D3D11Elem.InputSlot = CurrElem.BufferSlot; - D3D11Elem.Format = TypeToDXGI_Format(CurrElem.ValueType, CurrElem.NumComponents, CurrElem.IsNormalized); - D3D11Elem.InputSlotClass = (CurrElem.Frequency == LayoutElement::FREQUENCY_PER_VERTEX) ? D3D11_INPUT_PER_VERTEX_DATA : D3D11_INPUT_PER_INSTANCE_DATA; - D3D11Elem.InstanceDataStepRate = (CurrElem.Frequency == LayoutElement::FREQUENCY_PER_VERTEX) ? 0 : CurrElem.InstanceDataStepRate; - } - - auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); - CHECK_D3D_RESULT_THROW( pDeviceD3D11->CreateInputLayout(InputElements.data(), static_cast<UINT>(InputElements.size()), pVSByteCode->GetBufferPointer(), pVSByteCode->GetBufferSize(), &m_pd3d11InputLayout), - "Failed to create the Direct3D11 input layout"); -} - -VertexDescD3D11Impl::~VertexDescD3D11Impl() -{ -} - -IMPLEMENT_QUERY_INTERFACE( VertexDescD3D11Impl, IID_VertexDescriptionD3D11, TVertexDescriptionBase ) - -} diff --git a/Graphics/GraphicsEngineD3D11/src/pch.cpp b/Graphics/GraphicsEngineD3D11/src/pch.cpp index c7d1ec78..860c4217 100644 --- a/Graphics/GraphicsEngineD3D11/src/pch.cpp +++ b/Graphics/GraphicsEngineD3D11/src/pch.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj b/Graphics/GraphicsEngineD3D12/build/UWP/GraphicsEngineD3D12.vcxproj index b3f74084..ca0468a5 100644 --- a/Graphics/GraphicsEngine/build/WindowsStore/GraphicsEngine.WindowsPhone/GraphicsEngine.WindowsPhone.vcxproj +++ b/Graphics/GraphicsEngineD3D12/build/UWP/GraphicsEngineD3D12.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|ARM"> <Configuration>Debug</Configuration> @@ -9,6 +9,10 @@ <Configuration>Debug</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> <ProjectConfiguration Include="Release|ARM"> <Configuration>Release</Configuration> <Platform>ARM</Platform> @@ -17,67 +21,95 @@ <Configuration>Release</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{aefba9a8-e16d-4b06-b16d-bc74ac799b4f}</ProjectGuid> - <RootNamespace>GraphicsEngine</RootNamespace> + <ProjectGuid>{1a5a1c1d-c717-4680-a929-40e6324fe048}</ProjectGuid> + <Keyword>StaticLibrary</Keyword> + <RootNamespace>GraphicsEngineD3D12</RootNamespace> <DefaultLanguage>en-US</DefaultLanguage> - <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> <AppContainerApplication>true</AppContainerApplication> - <ApplicationType>Windows Phone</ApplicationType> - <ApplicationTypeRevision>8.1</ApplicationTypeRevision> - <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + <ApplicationType>Windows Store</ApplicationType> + <WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion> + <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion> + <ApplicationTypeRevision>10.0</ApplicationTypeRevision> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120_wp81</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120_wp81</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120_wp81</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120_wp81</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="..\GraphicsEngine.Shared\GraphicsEngine.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.Shared.vcxitems" Label="Shared" /> + </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmDbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsEngine.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmRel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <GenerateManifest>false</GenerateManifest> </PropertyGroup> @@ -90,9 +122,14 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> <GenerateManifest>false</GenerateManifest> </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -104,7 +141,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -116,7 +152,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -128,7 +163,28 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> diff --git a/Graphics/GraphicsEngineD3D12/build/UWP/GraphicsEngineD3D12.vcxproj.filters b/Graphics/GraphicsEngineD3D12/build/UWP/GraphicsEngineD3D12.vcxproj.filters new file mode 100644 index 00000000..c31757ec --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/build/UWP/GraphicsEngineD3D12.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/build/Win32/GraphicsEngineD3D12.vcxproj b/Graphics/GraphicsEngineD3D12/build/Win32/GraphicsEngineD3D12.vcxproj new file mode 100644 index 00000000..b930c993 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/build/Win32/GraphicsEngineD3D12.vcxproj @@ -0,0 +1,286 @@ +<?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="DbgDLL|Win32"> + <Configuration>DbgDLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="DbgDLL|x64"> + <Configuration>DbgDLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="RelDLL|Win32"> + <Configuration>RelDLL</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="RelDLL|x64"> + <Configuration>RelDLL</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FFF8071A-DB82-485B-ADC3-F0B675296869}</ProjectGuid> + <RootNamespace>GraphicsEngineD3D12</RootNamespace> + <WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.Shared.vcxitems" Label="Shared" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3D12.props" /> + <Import Project="..\..\..\Shared\build\Windows\DLLCommon.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D12.def</ModuleDefinitionFile> + <AdditionalDependencies>dxgi.lib;d3d12.lib;d3dcompiler.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DbgDLL|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D12.def</ModuleDefinitionFile> + <AdditionalDependencies>dxgi.lib;d3d12.lib;d3dcompiler.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <DisableSpecificWarnings>4100;4505;4189</DisableSpecificWarnings> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <DisableSpecificWarnings>4100;4505;4189</DisableSpecificWarnings> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D12.def</ModuleDefinitionFile> + <AdditionalDependencies>dxgi.lib;d3d12.lib;d3dcompiler.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <DisableSpecificWarnings>4100;4505;4189</DisableSpecificWarnings> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <DisableSpecificWarnings>4100;4505;4189</DisableSpecificWarnings> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ModuleDefinitionFile>..\..\src\GraphicsEngineD3D12.def</ModuleDefinitionFile> + <AdditionalDependencies>dxgi.lib;d3d12.lib;d3dcompiler.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\..\Common\build\Win32\Common.vcxproj"> + <Project>{7380f7e6-315f-4b4e-92eb-e6aeee865298}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\..\Platforms\Basic\build\Win32\BasicPlatform.vcxproj"> + <Project>{8ada5f93-7a38-4ad8-b8f5-1ffd4d4f630c}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\..\Platforms\Win32\build\Win32\WindowsPlatform.vcxproj"> + <Project>{58f32677-436b-412a-bbf8-2b1310d82cd8}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsEngineD3DBase\build\Win32\GraphicsEngineD3DBase.vcxproj"> + <Project>{40fd58ed-aabc-4cbd-bee4-33116995a626}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsEngine\build\Win32\GraphicsEngine.vcxproj"> + <Project>{052dd700-477c-4512-a7f4-b05ebef5c80e}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\GraphicsTools\build\Win32\GraphicsTools.vcxproj"> + <Project>{c6014499-0cf2-43ec-a773-a4e354fb2d74}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <None Include="..\..\src\GraphicsEngineD3D12.def" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\DLLMain.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/build/Win32/GraphicsEngineD3D12.vcxproj.filters b/Graphics/GraphicsEngineD3D12/build/Win32/GraphicsEngineD3D12.vcxproj.filters new file mode 100644 index 00000000..789137b8 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/build/Win32/GraphicsEngineD3D12.vcxproj.filters @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <None Include="..\..\src\GraphicsEngineD3D12.def" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\DLLMain.cpp" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.Shared.vcxitems b/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.Shared.vcxitems new file mode 100644 index 00000000..c67117a6 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.Shared.vcxitems @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{628cb771-ed9d-4874-a69e-3484343a4890}</ItemsProjectGuid> + <ItemsRootNamespace>ElevationDataSource</ItemsRootNamespace> + <ItemsProjectName>GraphicsEngineD3D12.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferViewD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandContext.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListManager.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12ResourceBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12TypeConversions.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12TypeDefinitions.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12Utils.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\d3dx12_win.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DescriptorHeap.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceContextD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DynamicUploadHeap.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\GenerateMips.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\PipelineStateD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RootSignature.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SamplerD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceBindingD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceCacheD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceLayoutD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourcesD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SwapChainD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureViewD3D12Impl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferViewD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\PipelineStateD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceFactoryD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SamplerD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderResourceBindingD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SwapChainD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureD3D12.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureViewD3D12.h" /> + </ItemGroup> + <ItemGroup> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaOddCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaOddXCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaOddYCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearOddCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearOddXCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearOddYCS.hlsl"> + <ShaderType>Compute</ShaderType> + <ShaderModel>5.0</ShaderModel> + <HeaderFileOutput>$(IntDir)CompiledShaders\GenerateMips\%(Filename).h</HeaderFileOutput> + <ObjectFileOutput> + </ObjectFileOutput> + <VariableName>g_p%(Filename)</VariableName> + </FxCompile> + </ItemGroup> + <ItemGroup> + <None Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsCS.hlsli"> + <FileType>Document</FileType> + </None> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferViewD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\CommandContext.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\CommandListManager.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D12ResourceBase.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D12TypeConversions.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D12Utils.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DescriptorHeap.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DeviceContextD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DynamicUploadHeap.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\GenerateMips.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\PipelineStateD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceFactoryD3D12.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RootSignature.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SamplerD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceBindingD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceCacheD3D12.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceLayoutD3D12.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourcesD3D12.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SwapChainD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureD3D12Impl.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureViewD3D12Impl.cpp" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.Shared.vcxitems.filters b/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.Shared.vcxitems.filters new file mode 100644 index 00000000..30e44dcd --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.Shared.vcxitems.filters @@ -0,0 +1,244 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{cb8a7049-3fb3-490e-a55b-75c8422dbeb5}</UniqueIdentifier> + </Filter> + <Filter Include="interface"> + <UniqueIdentifier>{8852250e-f6e5-48a5-94db-cb8334f9079c}</UniqueIdentifier> + </Filter> + <Filter Include="Shaders"> + <UniqueIdentifier>{65c29537-6d5a-41e1-9454-2a96e01ebad1}</UniqueIdentifier> + </Filter> + <Filter Include="Shaders\GenerateMips"> + <UniqueIdentifier>{b3e2774b-fc99-4266-b197-bc1f10110a39}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{3be622ce-7600-4bd7-9dfe-36521ba36715}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BufferViewD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandContext.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\CommandListManager.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12ResourceBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12TypeConversions.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12TypeDefinitions.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3D12Utils.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\d3dx12_win.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DescriptorHeap.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DeviceContextD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DynamicUploadHeap.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\GenerateMips.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\PipelineStateD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RootSignature.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SamplerD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceBindingD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceCacheD3D12.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourceLayoutD3D12.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResourcesD3D12.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\SwapChainD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\TextureViewD3D12Impl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\BufferViewD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\PipelineStateD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\RenderDeviceFactoryD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SamplerD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\ShaderResourceBindingD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\SwapChainD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\interface\TextureViewD3D12.h"> + <Filter>interface</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaOddCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaOddXCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsGammaOddYCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearOddCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearOddXCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + <FxCompile Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsLinearOddYCS.hlsl"> + <Filter>Shaders\GenerateMips</Filter> + </FxCompile> + </ItemGroup> + <ItemGroup> + <None Include="$(MSBuildThisFileDirectory)..\..\shaders\GenerateMips\GenerateMipsCS.hlsli"> + <Filter>Shaders\GenerateMips</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BufferViewD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\CommandContext.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\CommandListManager.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D12ResourceBase.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D12TypeConversions.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\D3D12Utils.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DescriptorHeap.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DeviceContextD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DynamicUploadHeap.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\GenerateMips.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\PipelineStateD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RenderDeviceFactoryD3D12.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\RootSignature.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SamplerD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceBindingD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceCacheD3D12.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourceLayoutD3D12.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResourcesD3D12.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\SwapChainD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\TextureViewD3D12Impl.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.props b/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.props new file mode 100644 index 00000000..adf13e2d --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/build/Windows.Shared/GraphicsEngineD3D12.props @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..</GraphicsRoot> + <ProjectRoot>..\..</ProjectRoot> + </PropertyGroup> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsEngineD3D12\include;$(GraphicsRoot)\GraphicsEngineD3D12\interface;$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsEngineD3DBase\include;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(IntDir)CompiledShaders;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup /> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + <BuildMacro Include="ProjectRoot"> + <Value>$(ProjectRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h new file mode 100644 index 00000000..9ee4e25d --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h @@ -0,0 +1,114 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::BufferD3D12Impl class + +#include "BufferD3D12.h" +#include "RenderDeviceD3D12.h" +#include "BufferBase.h" +#include "BufferViewD3D12Impl.h" +#include "D3D12ResourceBase.h" +#include "DynamicUploadHeap.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Implementation of the Diligent::IBufferD3D12 interface +class BufferD3D12Impl : public BufferBase<IBufferD3D12, BufferViewD3D12Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator>, public D3D12ResourceBase +{ +public: + typedef BufferBase<IBufferD3D12, BufferViewD3D12Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> TBufferBase; + BufferD3D12Impl(FixedBlockMemoryAllocator &BufferObjMemAllocator, + FixedBlockMemoryAllocator &BuffViewObjMemAllocator, + class RenderDeviceD3D12Impl *pDeviceD3D12, + const BufferDesc& BuffDesc, + const BufferData &BuffData = BufferData()); + ~BufferD3D12Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData )override; + virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override; + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override; + +#ifdef _DEBUG + void DbgVerifyDynamicAllocation(Uint32 ContextId); +#endif + + virtual ID3D12Resource *GetD3D12Buffer(size_t &DataStartByteOffset, Uint32 ContextId)override final + { + if(m_Desc.Usage == USAGE_DYNAMIC) + { +#ifdef _DEBUG + DbgVerifyDynamicAllocation(ContextId); +#endif + DataStartByteOffset = m_DynamicData[ContextId].Offset; + return m_DynamicData[ContextId].pBuffer; + } + else + { + DataStartByteOffset = 0; + return GetD3D12Resource(); + } + } + + D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint32 ContextId) + { + if(m_Desc.Usage == USAGE_DYNAMIC) + { +#ifdef _DEBUG + DbgVerifyDynamicAllocation(ContextId); +#endif + return m_DynamicData[ContextId].GPUAddress; + } + else + { + return GetD3D12Resource()->GetGPUVirtualAddress(); + } + } + + D3D12_CPU_DESCRIPTOR_HANDLE GetCBVHandle(){return m_CBVDescriptorAllocation.GetCpuHandle();} + +private: + virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView )override; + + void CreateUAV( struct BufferViewDesc &UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVDescriptor ); + void CreateSRV( struct BufferViewDesc &SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVDescriptor ); + void CreateCBV( D3D12_CPU_DESCRIPTOR_HANDLE CBVDescriptor ); + DescriptorHeapAllocation m_CBVDescriptorAllocation; + +#ifdef _DEBUG + std::vector<MAP_TYPE, STDAllocatorRawMem<MAP_TYPE> > m_DbgMapType; +#endif + + friend class DeviceContextD3D12Impl; + std::vector<DynamicAllocation, STDAllocatorRawMem<DynamicAllocation> > m_DynamicData; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/DSStateD3D11Impl.h b/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.h index 55aaa2ce..f5aff0ab 100644 --- a/Graphics/GraphicsEngineD3D11/include/DSStateD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,31 +24,36 @@ #pragma once /// \file -/// Declaration of Diligent::DSStateD3D11Impl class +/// Declaration of Diligent::BufferViewD3D12Impl class -#include "DepthStencilStateD3D11.h" -#include "RenderDeviceD3D11.h" -#include "DepthStencilStateBase.h" +#include "BufferViewD3D12.h" +#include "RenderDeviceD3D12.h" +#include "BufferViewBase.h" +#include "DescriptorHeap.h" namespace Diligent { -/// Implementation of the Diligent::IDepthStencilStateD3D11 interface -class DSStateD3D11Impl : public DepthStencilStateBase<IDepthStencilStateD3D11, IRenderDeviceD3D11 > +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::IBufferViewD3D12 interface +class BufferViewD3D12Impl : public BufferViewBase<IBufferViewD3D12, FixedBlockMemoryAllocator> { public: - typedef DepthStencilStateBase<IDepthStencilStateD3D11, IRenderDeviceD3D11 > TDepthStencilStateBase; + typedef BufferViewBase<IBufferViewD3D12, FixedBlockMemoryAllocator> TBufferViewBase; - DSStateD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const DepthStencilStateDesc& BuffDesc); - ~DSStateD3D11Impl(); + BufferViewD3D12Impl( FixedBlockMemoryAllocator &BuffViewAllocator, + IRenderDevice *pDevice, + const BufferViewDesc& ViewDesc, + class IBuffer *pBuffer, + DescriptorHeapAllocation &&HandleAlloc, + bool bIsDefaultView); virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); - ID3D11DepthStencilState *GetD3D11DepthStencilState(){ return m_pd3d11DepthStencilState; } - -private: - /// D3D11 depth-stencil state - Diligent::CComPtr<ID3D11DepthStencilState> m_pd3d11DepthStencilState; + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle()override{return m_DescriptorHandle.GetCpuHandle();} + +protected: + DescriptorHeapAllocation m_DescriptorHandle; }; } diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.h b/Graphics/GraphicsEngineD3D12/include/CommandContext.h new file mode 100644 index 00000000..71482511 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.h @@ -0,0 +1,615 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// +// Adapted to Diligent Engine: Egor Yusov +// + +#pragma once + +#include "pch.h" +#include <vector> + +#include "D3D12ResourceBase.h" +#include "TextureViewD3D12.h" +#include "TextureD3D12.h" +#include "BufferD3D12.h" +#include "DescriptorHeap.h" + +namespace Diligent +{ + + +struct DWParam +{ + DWParam( FLOAT f ) : Float(f) {} + DWParam( UINT u ) : Uint(u) {} + DWParam( INT i ) : Int(i) {} + + void operator= ( FLOAT f ) { Float = f; } + void operator= ( UINT u ) { Uint = u; } + void operator= ( INT i ) { Int = i; } + + union + { + FLOAT Float; + UINT Uint; + INT Int; + }; +}; + + +class CommandContext +{ +public: + + CommandContext( IMemoryAllocator &MemAllocator, + class CommandListManager& CmdListManager, + GPUDescriptorHeap GPUDescriptorHeaps[], + Uint32 DynamicDescriptorAllocationChunkSize[]); + + ~CommandContext(void); + + // Submit the command buffer and reset it. This is encouraged to keep the GPU busy and reduce latency. + // Taking too long to build command lists and submit them can idle the GPU. + // Returns a fence value to verify completion. (Use it with the CommandListManager.) + + ID3D12GraphicsCommandList* Close(ID3D12CommandAllocator **ppAllocator); + void Reset( CommandListManager& CmdListManager ); + + class GraphicsContext& AsGraphicsContext(); + class ComputeContext& AsComputeContext(); + + void ClearUAVFloat( ITextureViewD3D12 *pTexView, const float* Color ); + void ClearUAVUint( ITextureViewD3D12 *pTexView, const UINT *Color ); + + void CopyResource(ID3D12Resource *pDstRes, ID3D12Resource *pSrcRes) + { + m_pCommandList->CopyResource(pDstRes, pSrcRes); + } + + //void CopyBuffer( GpuResource& Dest, GpuResource& Src ); + //void CopyBufferRegion( GpuResource& Dest, size_t DestOffset, GpuResource& Src, size_t SrcOffset, size_t NumBytes ); + //void CopySubresource(GpuResource& Dest, UINT DestSubIndex, GpuResource& Src, UINT SrcSubIndex); + //void CopyCounter(GpuResource& Dest, size_t DestOffset, StructuredBuffer& Src); + //void ResetCounter(StructuredBuffer& Buf, uint32_t Value = 0); + + //static void InitializeTextureArraySlice(GpuResource& Dest, UINT SliceIndex, GpuResource& Src); + + void TransitionResource(ITextureD3D12 *pTexture, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false); + void TransitionResource(IBufferD3D12 *pBuffer, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false); + //void BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false); + void FlushResourceBarriers(); + + //void InsertTimeStamp( ID3D12QueryHeap* pQueryHeap, uint32_t QueryIdx ); + //void ResolveTimeStamps( ID3D12Resource* pReadbackHeap, ID3D12QueryHeap* pQueryHeap, uint32_t NumQueries ); + //void PIXBeginEvent(const wchar_t* label); + //void PIXEndEvent(void); + //void PIXSetMarker(const wchar_t* label); + + struct ShaderDescriptorHeaps + { + ID3D12DescriptorHeap* pSrvCbvUavHeap; + ID3D12DescriptorHeap* pSamplerHeap; + ShaderDescriptorHeaps(ID3D12DescriptorHeap* _pSrvCbvUavHeap = nullptr, ID3D12DescriptorHeap* _pSamplerHeap = nullptr) : + pSrvCbvUavHeap(_pSrvCbvUavHeap), + pSamplerHeap(_pSamplerHeap) + {} + bool operator == (const ShaderDescriptorHeaps& rhs)const + { + return pSrvCbvUavHeap == rhs.pSrvCbvUavHeap && pSamplerHeap == rhs.pSamplerHeap; + } + operator bool()const + { + return pSrvCbvUavHeap != nullptr || pSamplerHeap != nullptr; + } + }; + void SetDescriptorHeaps( ShaderDescriptorHeaps& Heaps ); + + void ExecuteIndirect(ID3D12CommandSignature *pCmdSignature, ID3D12Resource *pBuff, Uint64 ArgsOffset) + { + FlushResourceBarriers(); + m_pCommandList->ExecuteIndirect(pCmdSignature, 1, pBuff, ArgsOffset, nullptr, 0); + } + + void SetID(const Char* ID) { m_ID = ID; } + ID3D12GraphicsCommandList *GetCommandList(){return m_pCommandList;} + + void DiscardUsedDescriptorHeaps(Uint64 FrameNumber); + DescriptorHeapAllocation AllocateDynamicGPUVisibleDescriptor( D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1 ); + + void InsertUAVBarrier(D3D12ResourceBase& Resource, IDeviceObject &Object, bool FlushImmediate = false); + +protected: + void TransitionResource(D3D12ResourceBase& Resource, IDeviceObject &Object, D3D12_RESOURCE_STATES NewState, bool FlushImmediate); + void InsertAliasBarrier(D3D12ResourceBase& Before, D3D12ResourceBase& After, IDeviceObject &BeforeObj, IDeviceObject &AfterObj, bool FlushImmediate = false); + + //void FinishTimeStampQueryBatch(); + //void BindDescriptorHeaps( void ); + + CComPtr<ID3D12GraphicsCommandList> m_pCommandList; + CComPtr<ID3D12CommandAllocator> m_pCurrentAllocator; + + ID3D12RootSignature* m_pCurGraphicsRootSignature; + ID3D12PipelineState* m_pCurGraphicsPipelineState; + ID3D12RootSignature* m_pCurComputeRootSignature; + ID3D12PipelineState* m_pCurComputePipelineState; + + static const int MaxPendingBarriers = 16; + std::vector<D3D12_RESOURCE_BARRIER, STDAllocatorRawMem<D3D12_RESOURCE_BARRIER> > m_PendingResourceBarriers; + // We must make sure that all referenced objects are alive until barriers are executed + // Keeping reference to ID3D12Resource is not sufficient! + // TextureD3D12Impl::~TextureD3D12Impl() and BufferD3D12Impl::~BufferD3D12Impl() + // are responsible for putting the D3D12 resource in the release queue + std::vector< RefCntAutoPtr<IDeviceObject>, STDAllocatorRawMem<RefCntAutoPtr<IDeviceObject>> > m_PendingBarrierObjects; + + ShaderDescriptorHeaps m_BoundDescriptorHeaps; + + // Every context must use its own allocator that maintains individual list of retired descriptor heaps to + // avoid interference with other command contexts + // The heaps can only be discarded after the command list is submitted for execution + DynamicSuballocationsManager m_DynamicGPUDescriptorAllocator[2]; + + String m_ID; + + D3D12_PRIMITIVE_TOPOLOGY m_PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; +}; + + +class GraphicsContext : public CommandContext +{ +public: + void ClearRenderTarget( ITextureViewD3D12 *pRTV, const float *Color ); + void ClearDepthStencil( ITextureViewD3D12 *pDSV, D3D12_CLEAR_FLAGS ClearFlags, float Depth, UINT8 Stencil ); + + void SetRootSignature( ID3D12RootSignature *pRootSig ) + { + if (pRootSig != m_pCurGraphicsRootSignature) + { + m_pCommandList->SetGraphicsRootSignature(m_pCurGraphicsRootSignature = pRootSig); + } + } + + void SetRenderTargets( UINT NumRTVs, ITextureViewD3D12** ppRTVs, ITextureViewD3D12* pDSV ); + + void SetViewports( UINT NumVPs, const D3D12_VIEWPORT* pVPs ) + { + m_pCommandList->RSSetViewports(NumVPs, pVPs); + } + + void SetScissorRects( UINT NumRects, const D3D12_RECT* pRects ) + { + m_pCommandList->RSSetScissorRects(NumRects, pRects); + } + + void SetStencilRef( UINT StencilRef ) + { + m_pCommandList->OMSetStencilRef( StencilRef ); + } + + void SetBlendFactor( const float* BlendFactor ) + { + m_pCommandList->OMSetBlendFactor( BlendFactor ); + } + + void SetPrimitiveTopology( D3D12_PRIMITIVE_TOPOLOGY Topology ) + { + if(m_PrimitiveTopology != Topology) + { + m_PrimitiveTopology = Topology; + m_pCommandList->IASetPrimitiveTopology(Topology); + } + } + + void SetPipelineState( ID3D12PipelineState* pPSO ) + { + if (pPSO != m_pCurGraphicsPipelineState) + { + m_pCommandList->SetPipelineState(m_pCurGraphicsPipelineState = pPSO); + } + } + + void SetConstants( UINT RootIndex, UINT NumConstants, const void* pConstants ) + { + m_pCommandList->SetGraphicsRoot32BitConstants( RootIndex, NumConstants, pConstants, 0 ); + } + + void SetConstants( UINT RootIndex, DWParam X ) + { + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 ); + } + + void SetConstants( UINT RootIndex, DWParam X, DWParam Y ) + { + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 ); + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Y.Uint, 1 ); + } + + void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z ) + { + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 ); + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Y.Uint, 1 ); + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Z.Uint, 2 ); + } + + void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W ) + { + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 ); + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Y.Uint, 1 ); + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Z.Uint, 2 ); + m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, W.Uint, 3 ); + } + + void SetConstantBuffer( UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV ) + { + m_pCommandList->SetGraphicsRootConstantBufferView(RootIndex, CBV); + } + + //void SetDynamicConstantBufferView( UINT RootIndex, size_t BufferSize, const void* BufferData ); + //void SetBufferSRV( UINT RootIndex, const GpuBuffer& SRV ); + //void SetBufferUAV( UINT RootIndex, const GpuBuffer& UAV ); + void SetDescriptorTable( UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle ) + { + m_pCommandList->SetGraphicsRootDescriptorTable( RootIndex, FirstHandle ); + } + + + //void SetDynamicDescriptor( UINT RootIndex, UINT Offset, D3D12_CPU_DESCRIPTOR_HANDLE Handle ); + //void SetDynamicDescriptors( UINT RootIndex, UINT Offset, UINT Count, const D3D12_CPU_DESCRIPTOR_HANDLE Handles[] ); + + void SetIndexBuffer( const D3D12_INDEX_BUFFER_VIEW& IBView ) + { + m_pCommandList->IASetIndexBuffer(&IBView); + } + + void SetVertexBuffers( UINT StartSlot, UINT Count, const D3D12_VERTEX_BUFFER_VIEW VBViews[] ) + { + m_pCommandList->IASetVertexBuffers(StartSlot, Count, VBViews); + } + + //void SetDynamicVB( UINT Slot, size_t NumVertices, size_t VertexStride, const void* VBData ); + //void SetDynamicIB( size_t IndexCount, const uint16_t* IBData ); + //void SetDynamicSRV(UINT RootIndex, size_t BufferSize, const void* BufferData); + + void Draw(UINT VertexCountPerInstance, UINT InstanceCount, + UINT StartVertexLocation, UINT StartInstanceLocation) + { + FlushResourceBarriers(); + m_pCommandList->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); + } + + void DrawIndexed(UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, + INT BaseVertexLocation, UINT StartInstanceLocation) + { + FlushResourceBarriers(); + m_pCommandList->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); + } +}; + +class ComputeContext : public CommandContext +{ +public: + + void SetRootSignature( ID3D12RootSignature *pRootSig ) + { + if (pRootSig != m_pCurComputeRootSignature) + { + m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig); + } + } + + + void SetPipelineState( ID3D12PipelineState* pPSO ) + { + if (pPSO != m_pCurComputePipelineState) + { + m_pCommandList->SetPipelineState(m_pCurComputePipelineState = pPSO); + } + } + + void SetConstants( UINT RootIndex, UINT NumConstants, const void* pConstants ) + { + m_pCommandList->SetComputeRoot32BitConstants( RootIndex, NumConstants, pConstants, 0 ); + } + + void SetConstants( UINT RootIndex, DWParam X ) + { + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 ); + } + + void SetConstants( UINT RootIndex, DWParam X, DWParam Y ) + { + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 ); + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Y.Uint, 1 ); + } + + void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z ) + { + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 ); + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Y.Uint, 1 ); + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Z.Uint, 2 ); + } + + void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W ) + { + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 ); + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Y.Uint, 1 ); + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Z.Uint, 2 ); + m_pCommandList->SetComputeRoot32BitConstant( RootIndex, W.Uint, 3 ); + } + + + void SetConstantBuffer( UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV ) + { + m_pCommandList->SetComputeRootConstantBufferView(RootIndex, CBV); + } + + //void SetDynamicConstantBufferView( UINT RootIndex, size_t BufferSize, const void* BufferData ); + //void SetDynamicSRV( UINT RootIndex, size_t BufferSize, const void* BufferData ); + //void SetBufferSRV( UINT RootIndex, const GpuBuffer& SRV ); + //void SetBufferUAV( UINT RootIndex, const GpuBuffer& UAV ); + void SetDescriptorTable( UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle ) + { + m_pCommandList->SetComputeRootDescriptorTable( RootIndex, FirstHandle ); + } + + + //void SetDynamicDescriptor( UINT RootIndex, UINT Offset, D3D12_CPU_DESCRIPTOR_HANDLE Handle ); + //void SetDynamicDescriptors( UINT RootIndex, UINT Offset, UINT Count, const D3D12_CPU_DESCRIPTOR_HANDLE Handles[] ); + + void Dispatch( size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1 ) + { + FlushResourceBarriers(); + m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ); + } +}; + +inline GraphicsContext& CommandContext::AsGraphicsContext() +{ + return static_cast<GraphicsContext&>(*this); +} + +inline ComputeContext& CommandContext::AsComputeContext() +{ + return static_cast<ComputeContext&>(*this); +} + +#if 0 + +inline void GraphicsContext::SetDynamicConstantBufferView( UINT RootIndex, size_t BufferSize, const void* BufferData ) +{ + ASSERT(BufferData != nullptr && Math::IsAligned(BufferData, 16)); + DynAlloc cb = m_CpuLinearAllocator.Allocate(BufferSize); + //SIMDMemCopy(cb.DataPtr, BufferData, Math::AlignUp(BufferSize, 16) >> 4); + memcpy(cb.DataPtr, BufferData, BufferSize); + m_pCommandList->SetGraphicsRootConstantBufferView(RootIndex, cb.GpuAddress); +} + +inline void ComputeContext::SetDynamicConstantBufferView( UINT RootIndex, size_t BufferSize, const void* BufferData ) +{ + ASSERT(BufferData != nullptr && Math::IsAligned(BufferData, 16)); + DynAlloc cb = m_CpuLinearAllocator.Allocate(BufferSize); + //SIMDMemCopy(cb.DataPtr, BufferData, Math::AlignUp(BufferSize, 16) >> 4); + memcpy(cb.DataPtr, BufferData, BufferSize); + m_pCommandList->SetComputeRootConstantBufferView(RootIndex, cb.GpuAddress); +} + +inline void GraphicsContext::SetDynamicVB( UINT Slot, size_t NumVertices, size_t VertexStride, const void* VertexData ) +{ + ASSERT(VertexData != nullptr && Math::IsAligned(VertexData, 16)); + + size_t BufferSize = Math::AlignUp(NumVertices * VertexStride, 16); + DynAlloc vb = m_CpuLinearAllocator.Allocate(BufferSize); + + SIMDMemCopy(vb.DataPtr, VertexData, BufferSize >> 4); + + D3D12_VERTEX_BUFFER_VIEW VBView; + VBView.BufferLocation = vb.GpuAddress; + VBView.SizeInBytes = (UINT)BufferSize; + VBView.StrideInBytes = (UINT)VertexStride; + + m_pCommandList->IASetVertexBuffers(Slot, 1, &VBView); +} + +inline void GraphicsContext::SetDynamicIB( size_t IndexCount, const uint16_t* IndexData ) +{ + ASSERT(IndexData != nullptr && Math::IsAligned(IndexData, 16)); + + size_t BufferSize = Math::AlignUp(IndexCount * sizeof(uint16_t), 16); + DynAlloc ib = m_CpuLinearAllocator.Allocate(BufferSize); + + SIMDMemCopy(ib.DataPtr, IndexData, BufferSize >> 4); + + D3D12_INDEX_BUFFER_VIEW IBView; + IBView.BufferLocation = ib.GpuAddress; + IBView.SizeInBytes = (UINT)(IndexCount * sizeof(uint16_t)); + IBView.Format = DXGI_FORMAT_R16_UINT; + + m_pCommandList->IASetIndexBuffer(&IBView); +} + +inline void GraphicsContext::SetDynamicSRV(UINT RootIndex, size_t BufferSize, const void* BufferData) +{ + ASSERT(BufferData != nullptr && Math::IsAligned(BufferData, 16)); + DynAlloc cb = m_CpuLinearAllocator.Allocate(BufferSize); + SIMDMemCopy(cb.DataPtr, BufferData, Math::AlignUp(BufferSize, 16) >> 4); + m_pCommandList->SetGraphicsRootShaderResourceView(RootIndex, cb.GpuAddress); +} + +inline void ComputeContext::SetDynamicSRV(UINT RootIndex, size_t BufferSize, const void* BufferData) +{ + ASSERT(BufferData != nullptr && Math::IsAligned(BufferData, 16)); + DynAlloc cb = m_CpuLinearAllocator.Allocate(BufferSize); + SIMDMemCopy(cb.DataPtr, BufferData, Math::AlignUp(BufferSize, 16) >> 4); + m_pCommandList->SetComputeRootShaderResourceView(RootIndex, cb.GpuAddress); +} + +inline void GraphicsContext::SetBufferSRV( UINT RootIndex, const GpuBuffer& SRV ) +{ + ASSERT((SRV.m_UsageState & (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)) != 0); + m_pCommandList->SetGraphicsRootShaderResourceView(RootIndex, SRV.GetGpuVirtualAddress()); +} + +inline void ComputeContext::SetBufferSRV( UINT RootIndex, const GpuBuffer& SRV ) +{ + ASSERT((SRV.m_UsageState & D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) != 0); + m_pCommandList->SetComputeRootShaderResourceView(RootIndex, SRV.GetGpuVirtualAddress()); +} + +inline void GraphicsContext::SetBufferUAV( UINT RootIndex, const GpuBuffer& UAV ) +{ + ASSERT((UAV.m_UsageState & D3D12_RESOURCE_STATE_UNORDERED_ACCESS) != 0); + m_pCommandList->SetGraphicsRootUnorderedAccessView(RootIndex, UAV.GetGpuVirtualAddress()); +} + +inline void ComputeContext::SetBufferUAV( UINT RootIndex, const GpuBuffer& UAV ) +{ + ASSERT((UAV.m_UsageState & D3D12_RESOURCE_STATE_UNORDERED_ACCESS) != 0); + m_pCommandList->SetComputeRootUnorderedAccessView(RootIndex, UAV.GetGpuVirtualAddress()); +} + + + +inline void CommandContext::SetDescriptorHeap( D3D12_DESCRIPTOR_HEAP_TYPE Type, ID3D12DescriptorHeap* HeapPtr ) +{ + if (m_CurrentDescriptorHeaps[Type] != HeapPtr) + { + m_CurrentDescriptorHeaps[Type] = HeapPtr; + BindDescriptorHeaps(); + } +} +#endif + +inline void CommandContext::SetDescriptorHeaps( ShaderDescriptorHeaps& Heaps ) +{ +#ifdef _DEBUG + VERIFY(Heaps.pSrvCbvUavHeap != nullptr || Heaps.pSamplerHeap != nullptr, "At least one heap is expected to be set"); + VERIFY(Heaps.pSrvCbvUavHeap == nullptr || Heaps.pSrvCbvUavHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, "Invalid heap type provided in pSrvCbvUavHeap"); + VERIFY(Heaps.pSamplerHeap == nullptr || Heaps.pSamplerHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type provided in pSamplerHeap"); +#endif + + if (!(Heaps == m_BoundDescriptorHeaps)) + { + m_BoundDescriptorHeaps = Heaps; + + ID3D12DescriptorHeap **ppHeaps = reinterpret_cast<ID3D12DescriptorHeap**>(&Heaps); + UINT NumHeaps = (ppHeaps[0] != nullptr ? 1 : 0) + (ppHeaps[1] != nullptr ? 1 : 0); + if(ppHeaps[0] == nullptr) + ++ppHeaps; + + m_pCommandList->SetDescriptorHeaps(NumHeaps, ppHeaps); + } +} + +#if 0 +inline void GraphicsContext::SetDynamicDescriptor( UINT RootIndex, UINT Offset, D3D12_CPU_DESCRIPTOR_HANDLE Handle ) +{ + SetDynamicDescriptors(RootIndex, Offset, 1, &Handle); +} + +inline void ComputeContext::SetDynamicDescriptor( UINT RootIndex, UINT Offset, D3D12_CPU_DESCRIPTOR_HANDLE Handle ) +{ + SetDynamicDescriptors(RootIndex, Offset, 1, &Handle); +} + +inline void GraphicsContext::SetDynamicDescriptors( UINT RootIndex, UINT Offset, UINT Count, const D3D12_CPU_DESCRIPTOR_HANDLE Handles[] ) +{ + m_DynamicDescriptorHeap.SetGraphicsDescriptorHandles(RootIndex, Offset, Count, Handles); +} + +inline void ComputeContext::SetDynamicDescriptors( UINT RootIndex, UINT Offset, UINT Count, const D3D12_CPU_DESCRIPTOR_HANDLE Handles[] ) +{ + m_DynamicDescriptorHeap.SetComputeDescriptorHandles(RootIndex, Offset, Count, Handles); +} + + +inline void CommandContext::CopyBuffer( GpuResource& Dest, GpuResource& Src ) +{ + TransitionResource(Dest, D3D12_RESOURCE_STATE_COPY_DEST); + TransitionResource(Src, D3D12_RESOURCE_STATE_COPY_SOURCE); + FlushResourceBarriers(); + m_pCommandList->CopyResource(Dest.GetResource(), Src.GetResource()); +} + + +inline void CommandContext::CopyCounter(GpuResource& Dest, size_t DestOffset, StructuredBuffer& Src) +{ + TransitionResource(Dest, D3D12_RESOURCE_STATE_COPY_DEST); + TransitionResource(Src.GetCounterBuffer(), D3D12_RESOURCE_STATE_COPY_SOURCE); + FlushResourceBarriers(); + m_pCommandList->CopyBufferRegion(Dest.GetResource(), DestOffset, Src.GetCounterBuffer().GetResource(), 0, 4); +} + +inline void CommandContext::ResetCounter(StructuredBuffer& Buf, uint32_t Value ) +{ + FillBuffer(Buf.GetCounterBuffer(), 0, Value, sizeof(uint32_t)); + TransitionResource(Buf.GetCounterBuffer(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS); +} + +inline void CommandContext::InsertTimeStamp(ID3D12QueryHeap* pQueryHeap, uint32_t QueryIdx) +{ + m_pCommandList->EndQuery(pQueryHeap, D3D12_QUERY_TYPE_TIMESTAMP, QueryIdx); +} + +inline void CommandContext::ResolveTimeStamps(ID3D12Resource* pReadbackHeap, ID3D12QueryHeap* pQueryHeap, uint32_t NumQueries) +{ + m_pCommandList->ResolveQueryData(pQueryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, NumQueries, pReadbackHeap, 0); +} + +inline void CommandContext::PIXBeginEvent(const wchar_t* label) +{ +#if defined(RELEASE) || _MSC_VER < 1800 + (label); +#else + ::PIXBeginEvent(m_pCommandList, 0, label); +#endif +} + +inline void CommandContext::PIXEndEvent(void) +{ +#if !defined(RELEASE) && _MSC_VER >= 1800 + ::PIXEndEvent(m_pCommandList); +#endif +} + +inline void CommandContext::PIXSetMarker(const wchar_t* label) +{ +#if defined(RELEASE) || _MSC_VER < 1800 + (label); +#else + ::PIXSetMarker(m_pCommandList, 0, label); +#endif +} +#endif +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/include/BlendStateD3D11Impl.h b/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h index 9bfc8af2..00e5fcaa 100644 --- a/Graphics/GraphicsEngineD3D11/include/BlendStateD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,32 +24,38 @@ #pragma once /// \file -/// Declaration of Diligent::BlendStateD3D11Impl class +/// Declaration of Diligent::CommandListD3D12Impl class -#include "BlendStateD3D11.h" -#include "RenderDeviceD3D11.h" -#include "BlendStateBase.h" +#include "CommandListBase.h" namespace Diligent { -/// Implementation of the Diligent::IBlendStateD3D11 interface -class BlendStateD3D11Impl : public BlendStateBase<IBlendStateD3D11, IRenderDeviceD3D11> +/// Implementation of the Diligent::ICommandList interface +class CommandListD3D12Impl : public CommandListBase<ICommandList, FixedBlockMemoryAllocator> { public: - typedef BlendStateBase<IBlendStateD3D11, IRenderDeviceD3D11 > TBlendStateBase; - - BlendStateD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const BlendStateDesc& BuffDesc); - ~BlendStateD3D11Impl(); - - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + typedef CommandListBase<ICommandList, FixedBlockMemoryAllocator> TCommandListBase; + CommandListD3D12Impl(FixedBlockMemoryAllocator &Allocator, IRenderDevice *pDevice, class CommandContext* pCmdContext) : + TCommandListBase(Allocator, pDevice), + m_pCmdContext(pCmdContext) + { + } - /// Implementation of the IBlendStateD3D11::GetD3D11BlendState() method. - ID3D11BlendState *GetD3D11BlendState(){ return m_pd3d11BlendState; } + ~CommandListD3D12Impl() + { + VERIFY(m_pCmdContext == nullptr, "Destroying command list that was never executed"); + } + + CommandContext* Close() + { + CommandContext* pCmdContext = m_pCmdContext; + m_pCmdContext = nullptr; + return pCmdContext; + } private: - /// D3D11 Blend state object - Diligent::CComPtr<ID3D11BlendState> m_pd3d11BlendState; + CommandContext* m_pCmdContext = nullptr; }; } diff --git a/Graphics/GraphicsEngineD3D12/include/CommandListManager.h b/Graphics/GraphicsEngineD3D12/include/CommandListManager.h new file mode 100644 index 00000000..a9b79650 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/CommandListManager.h @@ -0,0 +1,73 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// +// Adapted to Diligent Engine: Egor Yusov + +#pragma once + +#include <vector> +#include <deque> +#include <mutex> +#include <stdint.h> + +namespace Diligent +{ + +class CommandListManager +{ +public: + CommandListManager(class RenderDeviceD3D12Impl *pDeviceD3D12); + ~CommandListManager(); + + CommandListManager(const CommandListManager&) = delete; + CommandListManager(CommandListManager&&) = delete; + CommandListManager& operator = (const CommandListManager&) = delete; + CommandListManager& operator = (CommandListManager&&) = delete; + + void CreateNewCommandList( ID3D12GraphicsCommandList** ppList, ID3D12CommandAllocator** ppAllocator ); + void DiscardAllocator( Uint64 FenceValueForReset, ID3D12CommandAllocator* pAllocator ); + void RequestAllocator(ID3D12CommandAllocator** ppAllocator); + +private: + // Since there is only a "main pool" so far, everything below corresponds to that pool. It should be renamed and/or + // restructured if we add other pools. + typedef std::pair<Uint64, CComPtr<ID3D12CommandAllocator> > DiscardedAllocatorQueueElemType; + std::deque< DiscardedAllocatorQueueElemType, STDAllocatorRawMem<DiscardedAllocatorQueueElemType> > m_DiscardedAllocators; + + std::mutex m_AllocatorMutex; + RenderDeviceD3D12Impl *m_pDeviceD3D12; +}; + +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.h b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.h new file mode 100644 index 00000000..e8faa4a3 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.h @@ -0,0 +1,53 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::D3D12ResourceBase class + +namespace Diligent +{ + +/// Base implementation of a D3D12 resource +class D3D12ResourceBase +{ +public: + D3D12ResourceBase() : + m_UsageState(D3D12_RESOURCE_STATE_COMMON)/*, + m_TransitioningState((D3D12_RESOURCE_STATES)-1)*/ + {} + + D3D12_RESOURCE_STATES GetState()const{return m_UsageState;} + void SetState(D3D12_RESOURCE_STATES UsageState){m_UsageState = UsageState;} + bool CheckAllStates(D3D12_RESOURCE_STATES States)const{return (m_UsageState & States) == States;} + bool CheckAnyState(D3D12_RESOURCE_STATES States)const{return (m_UsageState & States) != 0;} + ID3D12Resource *GetD3D12Resource(){ return m_pd3d12Resource; } + +protected: + D3D12_RESOURCE_STATES m_UsageState; + //D3D12_RESOURCE_STATES m_TransitioningState; + CComPtr<ID3D12Resource> m_pd3d12Resource; ///< D3D12 buffer object +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.h b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.h new file mode 100644 index 00000000..d909bd42 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.h @@ -0,0 +1,56 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Type conversion routines + +#include "GraphicsTypes.h" + +namespace Diligent +{ + +D3D12_COMPARISON_FUNC ComparisonFuncToD3D12ComparisonFunc(COMPARISON_FUNCTION Func); +D3D12_FILTER FilterTypeToD3D12Filter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter); +D3D12_TEXTURE_ADDRESS_MODE TexAddressModeToD3D12AddressMode(TEXTURE_ADDRESS_MODE Mode); +D3D12_PRIMITIVE_TOPOLOGY TopologyToD3D12Topology(PRIMITIVE_TOPOLOGY Topology); + +void DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(const DepthStencilStateDesc &DepthStencilDesc, D3D12_DEPTH_STENCIL_DESC &d3d12DSSDesc); +void RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(const RasterizerStateDesc &RasterizerDesc, D3D12_RASTERIZER_DESC &d3d11RSDesc); +void BlendStateDesc_To_D3D12_BLEND_DESC(const BlendStateDesc &BSDesc, D3D12_BLEND_DESC &d3d12BlendDesc); + +void LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(const std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement>> &LayoutElements, + std::vector<D3D12_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D12_INPUT_ELEMENT_DESC> > &d3d12InputElements); + +void TextureViewDesc_to_D3D12_SRV_DESC(const TextureViewDesc& SRVDesc, D3D12_SHADER_RESOURCE_VIEW_DESC &D3D12SRVDesc, Uint32 SampleCount); +void TextureViewDesc_to_D3D12_RTV_DESC(const TextureViewDesc& RTVDesc, D3D12_RENDER_TARGET_VIEW_DESC &D3D12RTVDesc, Uint32 SampleCount); +void TextureViewDesc_to_D3D12_DSV_DESC(const TextureViewDesc& DSVDesc, D3D12_DEPTH_STENCIL_VIEW_DESC &D3D12DSVDesc, Uint32 SampleCount); +void TextureViewDesc_to_D3D12_UAV_DESC(const TextureViewDesc& UAVDesc, D3D12_UNORDERED_ACCESS_VIEW_DESC &D3D12UAVDesc); + +void BufferViewDesc_to_D3D12_SRV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& SRVDesc, D3D12_SHADER_RESOURCE_VIEW_DESC &D3D12SRVDesc); +void BufferViewDesc_to_D3D12_UAV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& UAVDesc, D3D12_UNORDERED_ACCESS_VIEW_DESC &D3D12UAVDesc); + +D3D12_STATIC_BORDER_COLOR BorderColorToD3D12StaticBorderColor(const Float32 BorderColor[]); + +} diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeDefinitions.h b/Graphics/GraphicsEngineD3D12/include/D3D12TypeDefinitions.h new file mode 100644 index 00000000..892de4aa --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeDefinitions.h @@ -0,0 +1,187 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definitions of D3D12 types + +// Filters +#define D3D_FILTER_MIN_MAG_MIP_POINT D3D12_FILTER_MIN_MAG_MIP_POINT +#define D3D_FILTER_MIN_MAG_POINT_MIP_LINEAR D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MIN_POINT_MAG_MIP_LINEAR D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR +#define D3D_FILTER_MIN_LINEAR_MAG_MIP_POINT D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT +#define D3D_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MIN_MAG_LINEAR_MIP_POINT D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MIN_MAG_MIP_LINEAR D3D12_FILTER_MIN_MAG_MIP_LINEAR +#define D3D_FILTER_ANISOTROPIC D3D12_FILTER_ANISOTROPIC + +#define D3D_FILTER_COMPARISON_MIN_MAG_MIP_POINT D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR D3D12_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT D3D12_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR D3D12_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR +#define D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR +#define D3D_FILTER_COMPARISON_ANISOTROPIC D3D12_FILTER_COMPARISON_ANISOTROPIC + +#define D3D_FILTER_MINIMUM_MIN_MAG_MIP_POINT D3D12_FILTER_MINIMUM_MIN_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR D3D12_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT D3D12_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR D3D12_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR +#define D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT D3D12_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR D3D12_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR +#define D3D_FILTER_MINIMUM_ANISOTROPIC D3D12_FILTER_MINIMUM_ANISOTROPIC + +#define D3D_FILTER_MAXIMUM_MIN_MAG_MIP_POINT D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR D3D12_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR +#define D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR +#define D3D_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT D3D12_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT +#define D3D_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR +#define D3D_FILTER_MAXIMUM_ANISOTROPIC D3D12_FILTER_MAXIMUM_ANISOTROPIC + +// Comparison functions +#define D3D_COMPARISON_FUNC_NEVER D3D12_COMPARISON_FUNC_NEVER +#define D3D_COMPARISON_FUNC_LESS D3D12_COMPARISON_FUNC_LESS +#define D3D_COMPARISON_FUNC_EQUAL D3D12_COMPARISON_FUNC_EQUAL +#define D3D_COMPARISON_FUNC_LESS_EQUAL D3D12_COMPARISON_FUNC_LESS_EQUAL +#define D3D_COMPARISON_FUNC_GREATER D3D12_COMPARISON_FUNC_GREATER +#define D3D_COMPARISON_FUNC_NOT_EQUAL D3D12_COMPARISON_FUNC_NOT_EQUAL +#define D3D_COMPARISON_FUNC_GREATER_EQUAL D3D12_COMPARISON_FUNC_GREATER_EQUAL +#define D3D_COMPARISON_FUNC_ALWAYS D3D12_COMPARISON_FUNC_ALWAYS + +// Stencil operations +#define D3D_STENCIL_OP_KEEP D3D12_STENCIL_OP_KEEP +#define D3D_STENCIL_OP_ZERO D3D12_STENCIL_OP_ZERO +#define D3D_STENCIL_OP_REPLACE D3D12_STENCIL_OP_REPLACE +#define D3D_STENCIL_OP_INCR_SAT D3D12_STENCIL_OP_INCR_SAT +#define D3D_STENCIL_OP_DECR_SAT D3D12_STENCIL_OP_DECR_SAT +#define D3D_STENCIL_OP_INVERT D3D12_STENCIL_OP_INVERT +#define D3D_STENCIL_OP_INCR D3D12_STENCIL_OP_INCR +#define D3D_STENCIL_OP_DECR D3D12_STENCIL_OP_DECR + +// Depth write masks +#define D3D_DEPTH_WRITE_MASK_ALL D3D12_DEPTH_WRITE_MASK_ALL +#define D3D_DEPTH_WRITE_MASK_ZERO D3D12_DEPTH_WRITE_MASK_ZERO + +// Cull modes +#define D3D_CULL_MODE_NONE D3D12_CULL_MODE_NONE +#define D3D_CULL_MODE_FRONT D3D12_CULL_MODE_FRONT +#define D3D_CULL_MODE_BACK D3D12_CULL_MODE_BACK + +// Fill modes +#define D3D_FILL_MODE_WIREFRAME D3D12_FILL_MODE_WIREFRAME +#define D3D_FILL_MODE_SOLID D3D12_FILL_MODE_SOLID + +// Blend sources +#define D3D_BLEND_ZERO D3D12_BLEND_ZERO +#define D3D_BLEND_ONE D3D12_BLEND_ONE +#define D3D_BLEND_SRC_COLOR D3D12_BLEND_SRC_COLOR +#define D3D_BLEND_INV_SRC_COLOR D3D12_BLEND_INV_SRC_COLOR +#define D3D_BLEND_SRC_ALPHA D3D12_BLEND_SRC_ALPHA +#define D3D_BLEND_INV_SRC_ALPHA D3D12_BLEND_INV_SRC_ALPHA +#define D3D_BLEND_DEST_ALPHA D3D12_BLEND_DEST_ALPHA +#define D3D_BLEND_INV_DEST_ALPHA D3D12_BLEND_INV_DEST_ALPHA +#define D3D_BLEND_DEST_COLOR D3D12_BLEND_DEST_COLOR +#define D3D_BLEND_INV_DEST_COLOR D3D12_BLEND_INV_DEST_COLOR +#define D3D_BLEND_SRC_ALPHA_SAT D3D12_BLEND_SRC_ALPHA_SAT +#define D3D_BLEND_BLEND_FACTOR D3D12_BLEND_BLEND_FACTOR +#define D3D_BLEND_INV_BLEND_FACTOR D3D12_BLEND_INV_BLEND_FACTOR +#define D3D_BLEND_SRC1_COLOR D3D12_BLEND_SRC1_COLOR +#define D3D_BLEND_INV_SRC1_COLOR D3D12_BLEND_INV_SRC1_COLOR +#define D3D_BLEND_SRC1_ALPHA D3D12_BLEND_SRC1_ALPHA +#define D3D_BLEND_INV_SRC1_ALPHA D3D12_BLEND_INV_SRC1_ALPHA + +// Blend operations +#define D3D_BLEND_OP_ADD D3D12_BLEND_OP_ADD +#define D3D_BLEND_OP_SUBTRACT D3D12_BLEND_OP_SUBTRACT +#define D3D_BLEND_OP_REV_SUBTRACT D3D12_BLEND_OP_REV_SUBTRACT +#define D3D_BLEND_OP_MIN D3D12_BLEND_OP_MIN +#define D3D_BLEND_OP_MAX D3D12_BLEND_OP_MAX + +// Color masks +#define D3D_COLOR_WRITE_ENABLE_RED D3D12_COLOR_WRITE_ENABLE_RED +#define D3D_COLOR_WRITE_ENABLE_GREEN D3D12_COLOR_WRITE_ENABLE_GREEN +#define D3D_COLOR_WRITE_ENABLE_BLUE D3D12_COLOR_WRITE_ENABLE_BLUE +#define D3D_COLOR_WRITE_ENABLE_ALPHA D3D12_COLOR_WRITE_ENABLE_ALPHA + +// Input classification +#define D3D_INPUT_CLASSIFICATION_PER_VERTEX_DATA D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA +#define D3D_INPUT_CLASSIFICATION_PER_INSTANCE_DATA D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA + +// Texture address modes +#define D3D_TEXTURE_ADDRESS_WRAP D3D12_TEXTURE_ADDRESS_MODE_WRAP +#define D3D_TEXTURE_ADDRESS_MIRROR D3D12_TEXTURE_ADDRESS_MODE_MIRROR +#define D3D_TEXTURE_ADDRESS_CLAMP D3D12_TEXTURE_ADDRESS_MODE_CLAMP +#define D3D_TEXTURE_ADDRESS_BORDER D3D12_TEXTURE_ADDRESS_MODE_BORDER +#define D3D_TEXTURE_ADDRESS_MIRROR_ONCE D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE + +// SRV Dimensions +#define D3D_SRV_DIMENSION_UNKNOWN D3D12_SRV_DIMENSION_UNKNOWN +#define D3D_SRV_DIMENSION_BUFFER D3D12_SRV_DIMENSION_BUFFER +#define D3D_SRV_DIMENSION_TEXTURE1D D3D12_SRV_DIMENSION_TEXTURE1D +#define D3D_SRV_DIMENSION_TEXTURE1DARRAY D3D12_SRV_DIMENSION_TEXTURE1DARRAY +#define D3D_SRV_DIMENSION_TEXTURE2D D3D12_SRV_DIMENSION_TEXTURE2D +#define D3D_SRV_DIMENSION_TEXTURE2DARRAY D3D12_SRV_DIMENSION_TEXTURE2DARRAY +#define D3D_SRV_DIMENSION_TEXTURE2DMS D3D12_SRV_DIMENSION_TEXTURE2DMS +#define D3D_SRV_DIMENSION_TEXTURE2DMSARRAY D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY +#define D3D_SRV_DIMENSION_TEXTURE3D D3D12_SRV_DIMENSION_TEXTURE3D +#define D3D_SRV_DIMENSION_TEXTURECUBE D3D12_SRV_DIMENSION_TEXTURECUBE +#define D3D_SRV_DIMENSION_TEXTURECUBEARRAY D3D12_SRV_DIMENSION_TEXTURECUBEARRAY + +// RTV Dimensions +#define D3D_RTV_DIMENSION_UNKNOWN D3D12_RTV_DIMENSION_UNKNOWN +#define D3D_RTV_DIMENSION_BUFFER D3D12_RTV_DIMENSION_BUFFER +#define D3D_RTV_DIMENSION_TEXTURE1D D3D12_RTV_DIMENSION_TEXTURE1D +#define D3D_RTV_DIMENSION_TEXTURE1DARRAY D3D12_RTV_DIMENSION_TEXTURE1DARRAY +#define D3D_RTV_DIMENSION_TEXTURE2D D3D12_RTV_DIMENSION_TEXTURE2D +#define D3D_RTV_DIMENSION_TEXTURE2DARRAY D3D12_RTV_DIMENSION_TEXTURE2DARRAY +#define D3D_RTV_DIMENSION_TEXTURE2DMS D3D12_RTV_DIMENSION_TEXTURE2DMS +#define D3D_RTV_DIMENSION_TEXTURE2DMSARRAY D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY +#define D3D_RTV_DIMENSION_TEXTURE3D D3D12_RTV_DIMENSION_TEXTURE3D + + +// DSV Dimensions +#define D3D_DSV_DIMENSION_UNKNOWN D3D12_DSV_DIMENSION_UNKNOWN +#define D3D_DSV_DIMENSION_TEXTURE1D D3D12_DSV_DIMENSION_TEXTURE1D +#define D3D_DSV_DIMENSION_TEXTURE1DARRAY D3D12_DSV_DIMENSION_TEXTURE1DARRAY +#define D3D_DSV_DIMENSION_TEXTURE2D D3D12_DSV_DIMENSION_TEXTURE2D +#define D3D_DSV_DIMENSION_TEXTURE2DARRAY D3D12_DSV_DIMENSION_TEXTURE2DARRAY +#define D3D_DSV_DIMENSION_TEXTURE2DMS D3D12_DSV_DIMENSION_TEXTURE2DMS +#define D3D_DSV_DIMENSION_TEXTURE2DMSARRAY D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY + +// UAV Dimensions +#define D3D_UAV_DIMENSION_UNKNOWN D3D12_UAV_DIMENSION_UNKNOWN +#define D3D_UAV_DIMENSION_BUFFER D3D12_UAV_DIMENSION_BUFFER +#define D3D_UAV_DIMENSION_TEXTURE1D D3D12_UAV_DIMENSION_TEXTURE1D +#define D3D_UAV_DIMENSION_TEXTURE1DARRAY D3D12_UAV_DIMENSION_TEXTURE1DARRAY +#define D3D_UAV_DIMENSION_TEXTURE2D D3D12_UAV_DIMENSION_TEXTURE2D +#define D3D_UAV_DIMENSION_TEXTURE2DARRAY D3D12_UAV_DIMENSION_TEXTURE2DARRAY +#define D3D_UAV_DIMENSION_TEXTURE3D D3D12_UAV_DIMENSION_TEXTURE3D
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12Utils.h b/Graphics/GraphicsEngineD3D12/include/D3D12Utils.h new file mode 100644 index 00000000..64ee7c40 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/D3D12Utils.h @@ -0,0 +1,31 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BasicTypes.h" +namespace Diligent +{ + const Char* GetD3D12DescriptorHeapTypeLiteralName(D3D12_DESCRIPTOR_HEAP_TYPE Type); + +} diff --git a/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.h b/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.h new file mode 100644 index 00000000..b96977e6 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.h @@ -0,0 +1,362 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include <mutex> +#include <vector> +#include <queue> +#include <string> +#include <set> +#include "ObjectBase.h" +#include "FreeBlockListManagerGPU.h" + +namespace Diligent +{ + +class DescriptorHeapAllocation; +class DescriptorHeapAllocationManager; +class RenderDeviceD3D12Impl; + +class IDescriptorAllocator +{ +public: + virtual DescriptorHeapAllocation Allocate( uint32_t Count ) = 0; + virtual void Free(DescriptorHeapAllocation&& Allocation) = 0; + virtual Uint32 GetDescriptorSize()const = 0; +}; + +class DescriptorHeapAllocation +{ +public: + DescriptorHeapAllocation() : + m_NumHandles(1), // One null descriptor handle + m_pDescriptorHeap(nullptr), + m_DescriptorSize(0) + { + m_FirstCpuHandle.ptr = 0; + m_FirstGpuHandle.ptr = 0; + } + + DescriptorHeapAllocation( IDescriptorAllocator *pAllocator, ID3D12DescriptorHeap *pHeap, D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, Uint32 NHandles ) : + m_FirstCpuHandle(CpuHandle), + m_pAllocator(pAllocator), + m_pDescriptorHeap(pHeap), + m_NumHandles(NHandles) + { + m_FirstGpuHandle.ptr = 0; + VERIFY_EXPR(m_pAllocator != nullptr && m_pDescriptorHeap != nullptr); + auto DescriptorSize = m_pAllocator->GetDescriptorSize(); + VERIFY(DescriptorSize < std::numeric_limits<Uint16>::max(), "DescriptorSize exceeds allowed limit") + m_DescriptorSize = static_cast<Uint16>( DescriptorSize ); + } + + DescriptorHeapAllocation( IDescriptorAllocator *pAllocator, ID3D12DescriptorHeap *pHeap, D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle, Uint32 NHandles, Uint16 AllocationManagerId = static_cast<Uint16>(-1) ) : + m_FirstCpuHandle(CpuHandle), + m_FirstGpuHandle(GpuHandle), + m_pAllocator(pAllocator), + m_NumHandles(NHandles), + m_pDescriptorHeap(pHeap), + m_AllocationManagerId(AllocationManagerId) + { + VERIFY_EXPR(m_pAllocator != nullptr && m_pDescriptorHeap != nullptr); + auto DescriptorSize = m_pAllocator->GetDescriptorSize(); + VERIFY(DescriptorSize < std::numeric_limits<Uint16>::max(), "DescriptorSize exceeds allowed limit") + m_DescriptorSize = static_cast<Uint16>( DescriptorSize ); + } + + DescriptorHeapAllocation(DescriptorHeapAllocation &&Allocation) : + m_FirstCpuHandle(Allocation.m_FirstCpuHandle), + m_FirstGpuHandle(Allocation.m_FirstGpuHandle), + m_NumHandles(Allocation.m_NumHandles), + m_pAllocator(std::move(Allocation.m_pAllocator)), + m_AllocationManagerId(std::move(Allocation.m_AllocationManagerId)), + m_pDescriptorHeap(std::move(Allocation.m_pDescriptorHeap) ), + m_DescriptorSize(std::move(Allocation.m_DescriptorSize) ) + { + Allocation.m_pAllocator = nullptr; + Allocation.m_FirstCpuHandle.ptr = 0; + Allocation.m_FirstGpuHandle.ptr = 0; + Allocation.m_NumHandles = 0; + Allocation.m_pDescriptorHeap = nullptr; + Allocation.m_DescriptorSize = 0; + Allocation.m_AllocationManagerId = static_cast<Uint16>(-1); + } + + DescriptorHeapAllocation& operator = (DescriptorHeapAllocation &&Allocation) + { + m_FirstCpuHandle = Allocation.m_FirstCpuHandle; + m_FirstGpuHandle = Allocation.m_FirstGpuHandle; + m_NumHandles = Allocation.m_NumHandles; + m_pAllocator = std::move(Allocation.m_pAllocator); + m_AllocationManagerId = std::move(Allocation.m_AllocationManagerId); + m_pDescriptorHeap = std::move(Allocation.m_pDescriptorHeap); + m_DescriptorSize = std::move(Allocation.m_DescriptorSize); + + Allocation.m_FirstCpuHandle.ptr = 0; + Allocation.m_FirstGpuHandle.ptr = 0; + Allocation.m_NumHandles = 0; + Allocation.m_pAllocator = nullptr; + Allocation.m_pDescriptorHeap = nullptr; + Allocation.m_DescriptorSize = 0; + Allocation.m_AllocationManagerId = static_cast<Uint16>(-1); + + return *this; + } + + ~DescriptorHeapAllocation() + { + if(!IsNull() && m_pAllocator) + m_pAllocator->Free(std::move(*this)); + } + + D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Uint32 Offset = 0) const + { + VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles); + + D3D12_CPU_DESCRIPTOR_HANDLE CPUHandle = m_FirstCpuHandle; + if (Offset != 0) + { + CPUHandle.ptr += m_DescriptorSize * Offset; + } + return CPUHandle; + } + + D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Uint32 Offset = 0) const + { + VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles); + D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle = m_FirstGpuHandle; + if (Offset != 0) + { + GPUHandle.ptr += m_DescriptorSize * Offset; + } + return GPUHandle; + } + + ID3D12DescriptorHeap *GetDescriptorHeap(){return m_pDescriptorHeap;} + + size_t GetNumHandles(){return m_NumHandles;} + + bool IsNull() const { return m_FirstCpuHandle.ptr == 0; } + bool IsShaderVisible() const { return m_FirstGpuHandle.ptr != 0; } + size_t GetAllocationManagerId(){return m_AllocationManagerId;} + UINT GetDescriptorSize()const{return m_DescriptorSize;} + +private: + DescriptorHeapAllocation(const DescriptorHeapAllocation&) = delete; + DescriptorHeapAllocation& operator= (const DescriptorHeapAllocation&) = delete; + + D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCpuHandle = {0}; + D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGpuHandle = {0}; + // Keep strong reference to the parent heap to make sure it is alive while allocation is alive + //RefCntAutoPtr<IDescriptorAllocator> m_pAllocator; + IDescriptorAllocator* m_pAllocator = nullptr; + ID3D12DescriptorHeap* m_pDescriptorHeap = nullptr; + Uint32 m_NumHandles = 0; + Uint16 m_AllocationManagerId = static_cast<Uint16>(-1); + Uint16 m_DescriptorSize = 0; +}; + + +class DescriptorHeapAllocationManager +{ +public: + DescriptorHeapAllocationManager(IMemoryAllocator &Allocator, + RenderDeviceD3D12Impl *pDeviceD3D12Impl, + IDescriptorAllocator *pParentAllocator, + size_t ThisManagerId, + const D3D12_DESCRIPTOR_HEAP_DESC &HeapDesc); + DescriptorHeapAllocationManager(IMemoryAllocator &Allocator, + RenderDeviceD3D12Impl *pDeviceD3D12Impl, + IDescriptorAllocator *pParentAllocator, + size_t ThisManagerId, + ID3D12DescriptorHeap *pd3d12DescriptorHeap, + Uint32 FirstDescriptor, + Uint32 NumDescriptors); + + + // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL) + DescriptorHeapAllocationManager(DescriptorHeapAllocationManager&& rhs) : + m_FreeBlockManager(std::move(rhs.m_FreeBlockManager)), + m_HeapDesc(rhs.m_HeapDesc), + m_pd3d12DescriptorHeap(std::move(rhs.m_pd3d12DescriptorHeap)), + m_FirstCPUHandle(rhs.m_FirstCPUHandle), + m_FirstGPUHandle(rhs.m_FirstGPUHandle), + m_DescriptorSize(rhs.m_DescriptorSize), + m_NumDescriptorsInAllocation(rhs.m_NumDescriptorsInAllocation), + // Mutex is not movable + //m_AllocationMutex(std::move(rhs.m_AllocationMutex)) + m_pDeviceD3D12Impl(rhs.m_pDeviceD3D12Impl), + m_pParentAllocator(rhs.m_pParentAllocator), + m_ThisManagerId(rhs.m_ThisManagerId) + { + rhs.m_FirstCPUHandle.ptr = 0; + rhs.m_FirstGPUHandle.ptr = 0; + rhs.m_DescriptorSize = 0; + rhs.m_NumDescriptorsInAllocation = 0; + rhs.m_HeapDesc.NumDescriptors = 0; + rhs.m_pDeviceD3D12Impl = nullptr; + rhs.m_pParentAllocator = nullptr; + rhs.m_ThisManagerId = static_cast<size_t>(-1); + } + + DescriptorHeapAllocationManager& operator = (DescriptorHeapAllocationManager&& rhs) = delete; + DescriptorHeapAllocationManager(const DescriptorHeapAllocationManager&) = delete; + DescriptorHeapAllocationManager& operator = (const DescriptorHeapAllocationManager&) = delete; + + ~DescriptorHeapAllocationManager(); + + DescriptorHeapAllocation Allocate( uint32_t Count ); + void Free(DescriptorHeapAllocation&& Allocation); + void ReleaseStaleAllocations(Uint64 NumCompletedFrames); + size_t GetNumAvailableDescriptors()const{return m_FreeBlockManager.GetFreeSize();} + +private: + FreeBlockListManagerGPU m_FreeBlockManager; + D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; + CComPtr<ID3D12DescriptorHeap> m_pd3d12DescriptorHeap; + D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCPUHandle = {0}; + D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGPUHandle = {0}; + UINT m_DescriptorSize = 0; + Uint32 m_NumDescriptorsInAllocation = 0; + std::mutex m_AllocationMutex; + RenderDeviceD3D12Impl *m_pDeviceD3D12Impl = nullptr; + IDescriptorAllocator *m_pParentAllocator = nullptr; + size_t m_ThisManagerId = static_cast<size_t>(-1); +}; + +// This is an unbounded resource descriptor heap. It is intended to provide space for CPU-visible resource descriptors +// as resources are created as well as for static and mutable shader descriptor tables. +class CPUDescriptorHeap : public IDescriptorAllocator +{ +public: + CPUDescriptorHeap(IMemoryAllocator &Allocator, + RenderDeviceD3D12Impl *pDeviceD3D12Impl, + Uint32 NumDescriptorsInHeap, + D3D12_DESCRIPTOR_HEAP_TYPE Type, + D3D12_DESCRIPTOR_HEAP_FLAGS Flags); + + CPUDescriptorHeap(const CPUDescriptorHeap&) = delete; + CPUDescriptorHeap(CPUDescriptorHeap&&) = delete; + CPUDescriptorHeap& operator = (const CPUDescriptorHeap&) = delete; + CPUDescriptorHeap& operator = (CPUDescriptorHeap&&) = delete; + + ~CPUDescriptorHeap(); + + virtual DescriptorHeapAllocation Allocate( uint32_t Count )override; + virtual void Free(DescriptorHeapAllocation&& Allocation)override; + virtual Uint32 GetDescriptorSize()const override{return m_DescriptorSize;} + + void ReleaseStaleAllocations(Uint64 NumCompletedFrames); + +protected: + + std::vector<DescriptorHeapAllocationManager, STDAllocatorRawMem<DescriptorHeapAllocationManager> > m_HeapPool; + std::set<size_t, std::less<size_t>, STDAllocatorRawMem<size_t> > m_AvailableHeaps; + IMemoryAllocator &m_MemAllocator; + + std::mutex m_AllocationMutex; + + D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; + UINT m_DescriptorSize; + RenderDeviceD3D12Impl *m_pDeviceD3D12Impl; + Uint32 m_MaxHeapSize = 0; + Uint32 m_CurrentSize = 0; // This size does not count stale allocation +}; + + +class GPUDescriptorHeap : public IDescriptorAllocator +{ +public: + GPUDescriptorHeap(IMemoryAllocator &Allocator, + RenderDeviceD3D12Impl *pDevice, + Uint32 NumDescriptorsInHeap, + Uint32 NumDynamicDescriptors, + D3D12_DESCRIPTOR_HEAP_TYPE Type, + D3D12_DESCRIPTOR_HEAP_FLAGS Flags); + + GPUDescriptorHeap(const GPUDescriptorHeap&) = delete; + GPUDescriptorHeap(GPUDescriptorHeap&&) = delete; + GPUDescriptorHeap& operator = (const GPUDescriptorHeap&) = delete; + GPUDescriptorHeap& operator = (GPUDescriptorHeap&&) = delete; + + ~GPUDescriptorHeap(); + + virtual DescriptorHeapAllocation Allocate( uint32_t Count )override; + virtual void Free(DescriptorHeapAllocation&& Allocation)override; + virtual Uint32 GetDescriptorSize()const override{return m_DescriptorSize;} + + DescriptorHeapAllocation AllocateDynamic( uint32_t Count ); + + void ReleaseStaleAllocations(Uint64 NumCompletedFrames); + + D3D12_DESCRIPTOR_HEAP_DESC &GetHeapDesc(){return m_HeapDesc;} + +protected: + + D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; + CComPtr<ID3D12DescriptorHeap> m_pd3d12DescriptorHeap; + + + UINT m_DescriptorSize = 0; + + std::mutex m_Mutex; + DescriptorHeapAllocationManager m_HeapAllocationManager; + DescriptorHeapAllocationManager m_DynamicAllocationsManager; + + RenderDeviceD3D12Impl *m_pDeviceD3D12; + Uint32 m_CurrentSize = 0; + Uint32 m_MaxHeapSize = 0; + Uint32 m_CurrentDynamicSize = 0; + Uint32 m_MaxDynamicSize = 0; +}; + + + +class DynamicSuballocationsManager : public IDescriptorAllocator +{ +public: + DynamicSuballocationsManager(IMemoryAllocator &Allocator, GPUDescriptorHeap& ParentGPUHeap, Uint32 DynamicChunkSize); + + DynamicSuballocationsManager(const DynamicSuballocationsManager&) = delete; + DynamicSuballocationsManager(DynamicSuballocationsManager&&) = delete; + DynamicSuballocationsManager& operator = (const DynamicSuballocationsManager&) = delete; + DynamicSuballocationsManager& operator = (DynamicSuballocationsManager&&) = delete; + + void DiscardAllocations(Uint64 FrameNumber); + + virtual DescriptorHeapAllocation Allocate( Uint32 Count )override; + virtual void Free(DescriptorHeapAllocation&& Allocation)override; + + virtual Uint32 GetDescriptorSize()const override{return m_ParentGPUHeap.GetDescriptorSize();} + +private: + std::vector<DescriptorHeapAllocation, STDAllocatorRawMem<DescriptorHeapAllocation> > m_Suballocations; + + Uint32 m_CurrentSuballocationOffset = 0; + Uint32 m_DynamicChunkSize = 0; + + GPUDescriptorHeap &m_ParentGPUHeap; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h new file mode 100644 index 00000000..ffe8598a --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h @@ -0,0 +1,142 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::DeviceContextD3D12Impl class + +#include "DeviceContext.h" +#include "DeviceContextBase.h" +#include "GenerateMips.h" + +#ifdef _DEBUG +# define VERIFY_CONTEXT_BINDINGS +#endif + +namespace Diligent +{ + +/// Implementation of the Diligent::IDeviceContext interface +class DeviceContextD3D12Impl : public DeviceContextBase<IDeviceContext> +{ +public: + typedef DeviceContextBase<IDeviceContext> TDeviceContextBase; + + DeviceContextD3D12Impl(IMemoryAllocator &RawMemAllocator, class RenderDeviceD3D12Impl *pDevice, bool bIsDeferred, const EngineD3D12Attribs &Attribs, Uint32 ContextId); + ~DeviceContextD3D12Impl(); + //virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + + virtual void SetPipelineState(IPipelineState *pPipelineState)override final; + + virtual void TransitionShaderResources(IPipelineState *pPipelineState, IShaderResourceBinding *pShaderResourceBinding)override final; + + virtual void CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags)override final; + + virtual void SetStencilRef(Uint32 StencilRef)override final; + + virtual void SetBlendFactors(const float* pBlendFactors = nullptr)override final; + + virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override final; + virtual void ClearState()override final; + + virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override final; + + virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )override final; + + virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )override final; + + virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil )override final; + + virtual void Draw( DrawAttribs &DrawAttribs )override final; + + virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )override final; + + virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil)override final; + + virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA )override final; + + virtual void Flush()override final; + + virtual void FinishCommandList(class ICommandList **ppCommandList)override final; + + virtual void ExecuteCommandList(class ICommandList *pCommandList)override final; + + ///// Clears the state caches. This function is called once per frame + ///// (before present) to release all outstanding objects + ///// that are only kept alive by references in the cache + //void ClearShaderStateCache(); + + ///// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute) + //static const int NumShaderTypes = 6; + + void UpdateBufferRegion(class BufferD3D12Impl *pBuffD3D12, const void *pData, Uint64 DstOffset, Uint64 NumBytes); + void CopyBufferRegion(class BufferD3D12Impl *pSrcBuffD3D12, class BufferD3D12Impl *pDstBuffD3D12, Uint64 SrcOffset, Uint64 DstOffset, Uint64 NumBytes); + void CopyTextureRegion(class TextureD3D12Impl *pSrcTexture, Uint32 SrcSubResIndex, const D3D12_BOX *pD3D12SrcBox, + class TextureD3D12Impl *pDstTexture, Uint32 DstSubResIndex, Uint32 DstX, Uint32 DstY, Uint32 DstZ); + + void GenerateMips(class TextureViewD3D12Impl *pTexView); + + struct DynamicAllocation AllocateDynamicSpace(size_t NumBytes); + + Uint32 GetContextId()const{return m_ContextId;} + +private: + void CommitD3D12IndexBuffer(VALUE_TYPE IndexType); + void CommitD3D12VertexBuffers(class GraphicsContext &GraphCtx); + void TransitionD3D12VertexBuffers(class GraphicsContext &GraphCtx); + void RebindRenderTargets(); + void CommitViewports(); + void CommitScissorRects(); + void Flush(bool RequestNewCmdCtx); + + friend class SwapChainD3D12Impl; + inline class CommandContext* RequestCmdContext(){return m_pCurrCmdCtx;} + size_t m_NumCommandsInCurCtx = 0; + const Uint32 m_NumCommandsToFlush = 192; + CommandContext* m_pCurrCmdCtx = nullptr; + + CComPtr<ID3D12Resource> m_CommittedD3D12IndexBuffer; + VALUE_TYPE m_CommittedIBFormat = VT_UNDEFINED; + Uint32 m_CommittedD3D12IndexDataStartOffset = 0; + + CComPtr<ID3D12CommandSignature> m_pDrawIndirectSignature; + CComPtr<ID3D12CommandSignature> m_pDrawIndexedIndirectSignature; + CComPtr<ID3D12CommandSignature> m_pDispatchIndirectSignature; + + GenerateMipsHelper m_MipsGenerator; + class DynamicUploadHeap* m_pUploadHeap = nullptr; + + /// Flag indicating if currently committed D3D12 vertex buffers are up to date + bool m_bCommittedD3D12VBsUpToDate = false; + + /// Flag indicating if currently committed D3D11 index buffer is up to date + bool m_bCommittedD3D12IBUpToDate = false; + + class ShaderResourceCacheD3D12 *m_pCommittedResourceCache = nullptr; + + FixedBlockMemoryAllocator m_CmdListAllocator; + const Uint32 m_ContextId; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/DynamicUploadHeap.h b/Graphics/GraphicsEngineD3D12/include/DynamicUploadHeap.h new file mode 100644 index 00000000..a4799ded --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/DynamicUploadHeap.h @@ -0,0 +1,134 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "RingBuffer.h" + +namespace Diligent +{ + +// Constant blocks must be multiples of 16 constants @ 16 bytes each +#define DEFAULT_ALIGN 256 + +struct DynamicAllocation +{ + DynamicAllocation(ID3D12Resource *pBuff = nullptr, size_t ThisOffset = 0, size_t ThisSize = 0) + : pBuffer(pBuff), Offset(ThisOffset), Size(ThisSize) {} + + //CComPtr<ID3D12Resource> pBuffer; // The D3D buffer associated with this memory. + ID3D12Resource *pBuffer = nullptr; // The D3D buffer associated with this memory. + size_t Offset = 0; // Offset from start of buffer resource + size_t Size = 0; // Reserved size of this allocation + void* CPUAddress = 0; // The CPU-writeable address + D3D12_GPU_VIRTUAL_ADDRESS GPUAddress = 0; // The GPU-visible address +#ifdef _DEBUG + Uint64 FrameNum = static_cast<Uint64>(-1); +#endif +}; + +class GPURingBuffer : public RingBuffer +{ +public: + GPURingBuffer(size_t MaxSize, IMemoryAllocator &Allocator, ID3D12Device *pd3d12Device, bool AllowCPUAccess); + + GPURingBuffer(GPURingBuffer&& rhs) : + RingBuffer(std::move(rhs)), + m_CpuVirtualAddress(rhs.m_CpuVirtualAddress), + m_GpuVirtualAddress(rhs.m_GpuVirtualAddress), + m_pBuffer(std::move(rhs.m_pBuffer)) + { + rhs.m_CpuVirtualAddress = nullptr; + rhs.m_GpuVirtualAddress = 0; + rhs.m_pBuffer.Release(); + } + + GPURingBuffer& operator =(GPURingBuffer&& rhs) + { + Destroy(); + + static_cast<RingBuffer&>(*this) = std::move(rhs); + m_CpuVirtualAddress = rhs.m_CpuVirtualAddress; + m_GpuVirtualAddress = rhs.m_GpuVirtualAddress; + m_pBuffer = std::move(rhs.m_pBuffer); + rhs.m_CpuVirtualAddress = 0; + rhs.m_GpuVirtualAddress = 0; + + return *this; + } + + ~GPURingBuffer(); + + DynamicAllocation Allocate(size_t SizeInBytes) + { + auto Offset = RingBuffer::Allocate(SizeInBytes); + if (Offset != RingBuffer::InvalidOffset) + { + DynamicAllocation DynAlloc(m_pBuffer, Offset, SizeInBytes); + DynAlloc.GPUAddress = m_GpuVirtualAddress + Offset; + DynAlloc.CPUAddress = m_CpuVirtualAddress; + if(DynAlloc.CPUAddress) + DynAlloc.CPUAddress = reinterpret_cast<char*>(DynAlloc.CPUAddress) + Offset; + return DynAlloc; + } + else + { + return DynamicAllocation(nullptr, 0, 0); + } + } + + GPURingBuffer(const GPURingBuffer&) = delete; + GPURingBuffer& operator =(GPURingBuffer&) = delete; + +private: + void Destroy(); + + void* m_CpuVirtualAddress; + D3D12_GPU_VIRTUAL_ADDRESS m_GpuVirtualAddress; + CComPtr<ID3D12Resource> m_pBuffer; +}; + +class DynamicUploadHeap +{ +public: + + DynamicUploadHeap(IMemoryAllocator &Allocator, bool bIsCPUAccessible, class RenderDeviceD3D12Impl* pDevice, size_t InitialSize); + + DynamicUploadHeap(const DynamicUploadHeap&)=delete; + DynamicUploadHeap(DynamicUploadHeap&&)=delete; + DynamicUploadHeap& operator=(const DynamicUploadHeap&)=delete; + DynamicUploadHeap& operator=(DynamicUploadHeap&&)=delete; + + DynamicAllocation Allocate( size_t SizeInBytes, size_t Alignment = DEFAULT_ALIGN ); + + void FinishFrame(Uint64 FrameNum, Uint64 NumCompletedFrames); + +private: + const bool m_bIsCPUAccessible; + std::vector<GPURingBuffer, STDAllocatorRawMem<GPURingBuffer> > m_RingBuffers; + IMemoryAllocator &m_Allocator; + RenderDeviceD3D12Impl* m_pDeviceD3D12 = nullptr; + //std::mutex m_Mutex; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/RasterizerStateD3D11Impl.h b/Graphics/GraphicsEngineD3D12/include/GenerateMips.h index aad6f2ad..22e81589 100644 --- a/Graphics/GraphicsEngineD3D11/include/RasterizerStateD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/GenerateMips.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,34 +21,44 @@ * of the possibility of such damages. */ + +// The source code in this file is derived from ColorBuffer.h and GraphicsCore.h developed by Minigraph +// Original source files header: + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + + #pragma once /// \file -/// Declaration of Diligent::RasterizerStateD3D11Impl class +/// Implementation of mipmap generation routines -#include "RasterizerStateD3D11.h" -#include "RenderDeviceD3D11.h" -#include "RasterizerStateBase.h" namespace Diligent { + class GenerateMipsHelper + { + public: + GenerateMipsHelper(ID3D12Device *pd3d12Device); -/// Implementation of the Diligent::IRasterizerStateD3D11 interface -class RasterizerStateD3D11Impl : public RasterizerStateBase<IRasterizerStateD3D11, IRenderDeviceD3D11> -{ -public: - typedef RasterizerStateBase<IRasterizerStateD3D11, IRenderDeviceD3D11 > TRasterizerStateBase; - - RasterizerStateD3D11Impl(class RenderDeviceD3D11Impl *pDeviceD3D11, const RasterizerStateDesc& BuffDesc); - ~RasterizerStateD3D11Impl(); - - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + void GenerateMips(class RenderDeviceD3D12Impl *pRenderDeviceD3D12, class TextureViewD3D12Impl *pTexView, class CommandContext &Ctx); - ID3D11RasterizerState *GetD3D11RasterizerState(){ return m_pd3d11RasterizerState; } + private: + CComPtr<ID3D12RootSignature> m_pGenerateMipsRS; + CComPtr<ID3D12PipelineState> m_pGenerateMipsLinearPSO[4]; + CComPtr<ID3D12PipelineState> m_pGenerateMipsGammaPSO[4]; + }; -private: - /// D3D11 rasterizer state - Diligent::CComPtr<ID3D11RasterizerState> m_pd3d11RasterizerState; -}; } diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h new file mode 100644 index 00000000..1ac6564f --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h @@ -0,0 +1,93 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::PipelineStateD3D12Impl class + +#include "RenderDeviceD3D12.h" +#include "PipelineStateD3D12.h" +#include "PipelineStateBase.h" +#include "RootSignature.h" +#include "ShaderResourceLayoutD3D12.h" +#include "AdaptiveFixedBlockAllocator.h" + +/// Namespace for the Direct3D11 implementation of the graphics engine +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::IRenderDeviceD3D12 interface +class PipelineStateD3D12Impl : public PipelineStateBase<IPipelineStateD3D12, IRenderDeviceD3D12, FixedBlockMemoryAllocator> +{ +public: + typedef PipelineStateBase<IPipelineStateD3D12, IRenderDeviceD3D12, FixedBlockMemoryAllocator> TPipelineStateBase; + + PipelineStateD3D12Impl( FixedBlockMemoryAllocator &PSOAllocator, class RenderDeviceD3D12Impl *pDeviceD3D12, const PipelineStateDesc &PipelineDesc ); + ~PipelineStateD3D12Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual ID3D12PipelineState *GetD3D12PipelineState()const override final{return m_pd3d12PSO;} + + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override; + + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override; + + virtual ID3D12RootSignature *GetD3D12RootSignature()const override final{return m_RootSig.GetD3D12RootSignature(); } + + ShaderResourceCacheD3D12* CommitAndTransitionShaderResources(IShaderResourceBinding *pShaderResourceBinding, + class CommandContext &Ctx, + bool CommitResources, + bool TransitionResources)const; + + const RootSignature& GetRootSignature()const{return m_RootSig;} + + const ShaderResourceLayoutD3D12& GetShaderResLayout(SHADER_TYPE ShaderType)const; + + bool dbgContainsShaderResources()const; + + IMemoryAllocator &GetResourceCacheDataAllocator(){return m_ResourceCacheDataAllocator;} + IMemoryAllocator &GetShaderResourceLayoutDataAllocator(Uint32 ShaderInd){return m_ShaderResLayoutDataAllocators[ShaderInd];} + + IShaderVariable *GetDummyShaderVar(){return &m_DummyVar;} + +private: + + void ParseShaderResourceLayout(IShader *pShader); + + /// D3D12 device + CComPtr<ID3D12PipelineState> m_pd3d12PSO; + RootSignature m_RootSig; + DummyShaderVariable m_DummyVar; + + AdaptiveFixedBlockAllocator m_ShaderResLayoutDataAllocators[6]; + ShaderResourceLayoutD3D12* m_pShaderResourceLayouts[6] = {}; + AdaptiveFixedBlockAllocator m_ResourceCacheDataAllocator; // Use separate allocator for every shader stage + + // Do not use strong reference to avoid cyclic references + std::unique_ptr<class ShaderResourceBindingD3D12Impl, STDDeleter<ShaderResourceBindingD3D12Impl, FixedBlockMemoryAllocator> > m_pDefaultShaderResBinding; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h new file mode 100644 index 00000000..0294a8b8 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h @@ -0,0 +1,133 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RenderDeviceD3D12Impl class + +#include "RenderDeviceD3D12.h" +#include "RenderDeviceD3DBase.h" +#include "DescriptorHeap.h" +#include "CommandListManager.h" +#include "CommandContext.h" +#include "DynamicUploadHeap.h" + +/// Namespace for the Direct3D11 implementation of the graphics engine +namespace Diligent +{ + +/// Implementation of the Diligent::IRenderDeviceD3D12 interface +class RenderDeviceD3D12Impl : public RenderDeviceD3DBase<IRenderDeviceD3D12> +{ +public: + typedef RenderDeviceD3DBase<IRenderDeviceD3D12> TRenderDeviceBase; + + RenderDeviceD3D12Impl( IMemoryAllocator &RawMemAllocator, const EngineD3D12Attribs &CreationAttribs, ID3D12Device *pD3D12Device, ID3D12CommandQueue *pd3d12CmdQueue, Uint32 NumDeferredContexts ); + ~RenderDeviceD3D12Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void CreatePipelineState( const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState )override; + + virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer); + + virtual void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader); + + virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture); + + void CreateTexture(TextureDesc& TexDesc, ID3D12Resource *pd3d12Texture, class TextureD3D12Impl **ppTexture); + + virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler); + + virtual ID3D12Device* GetD3D12Device()override{return m_pd3d12Device;} + + DescriptorHeapAllocation AllocateDescriptor( D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1 ); + DescriptorHeapAllocation AllocateGPUDescriptors( D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1 ); + + bool IsFenceComplete(Uint64 FenceValue); + bool IsFrameComplete(Uint64 Frame); + + ID3D12CommandQueue *GetCmdQueue(){return m_pd3d12CmdQueue;} + + Uint64 IncrementFence(); + void WaitForFence(Uint64 FenceValue); + void IdleGPU(bool ReleasePendingObjects = false); + CommandContext* AllocateCommandContext(const Char *ID = ""); + Uint64 CloseAndExecuteCommandContext(CommandContext *pCtx); + void DisposeCommandContext(CommandContext*); + + void SafeReleaseD3D12Object(ID3D12Object* pObj); + Uint64 FinishFrame(); + + DynamicUploadHeap* RequestUploadHeap(); + void ReleaseUploadHeap(DynamicUploadHeap* pUploadHeap); + Uint64 GetCurrentFrame()const {return m_CurrentFrame;} + +private: + virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat ); + void ProcessReleaseQueue(bool ForceRelease = false); + + /// D3D12 device + CComPtr<ID3D12Device> m_pd3d12Device; + CComPtr<ID3D12CommandQueue> m_pd3d12CmdQueue; + + EngineD3D12Attribs m_EngineAttribs; + + CPUDescriptorHeap m_CPUDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + GPUDescriptorHeap m_GPUDescriptorHeaps[2]; // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV == 0 + // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER == 1 + + std::mutex m_FenceMutex; + std::mutex m_EventMutex; + + CComPtr<ID3D12Fence> m_pFence; + Uint64 m_NextFenceValue; + Uint64 m_LastCompletedFenceValue; + HANDLE m_FenceEventHandle; + + CComPtr<ID3D12Fence> m_pNumCompletedFramesFence; + Uint64 m_CurrentFrame = 0; + Uint64 m_NumCompletedFrames = 0; + + + CommandListManager m_CmdListManager; + + typedef std::unique_ptr<CommandContext, STDDeleterRawMem<CommandContext> > ContextPoolElemType; + std::vector< ContextPoolElemType, STDAllocatorRawMem<ContextPoolElemType> > m_ContextPool; + + std::deque<CommandContext*, STDAllocatorRawMem<CommandContext*> > m_AvailableContexts; + std::mutex m_ContextAllocationMutex; + + // Object that must be kept alive + std::mutex m_ReleasedObjectsMutex; + // Release queue + typedef std::pair<Uint64, CComPtr<ID3D12Object> > ReleaseQueueElemType; + std::deque< ReleaseQueueElemType, STDAllocatorRawMem<ReleaseQueueElemType> > m_D3D12ObjReleaseQueue; + + std::mutex m_UploadHeapMutex; + typedef std::unique_ptr<DynamicUploadHeap, STDDeleterRawMem<DynamicUploadHeap> > UploadHeapPoolElemType; + std::vector< UploadHeapPoolElemType, STDAllocatorRawMem<UploadHeapPoolElemType> > m_UploadHeaps; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.h b/Graphics/GraphicsEngineD3D12/include/RootSignature.h new file mode 100644 index 00000000..750b2b9d --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.h @@ -0,0 +1,312 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RootSignature class +#include "ShaderD3DBase.h" +#include "ShaderResourceLayoutD3D12.h" + +namespace Diligent +{ + +SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility); +D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType); +D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType); + +class RootParameter +{ +public: + + RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : + m_RootIndex(RootIndex), + m_ShaderVarType(VarType) + { + VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV, "Unexpected parameter type - verify argument list"); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.Descriptor.ShaderRegister = Register; + m_RootParam.Descriptor.RegisterSpace = RegisterSpace; + } + + RootParameter( D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, UINT NumDwords, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : + m_RootIndex(RootIndex), + m_ShaderVarType(VarType) + { + VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, "Unexpected parameter type - verify argument list"); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.Constants.Num32BitValues = NumDwords; + m_RootParam.Constants.ShaderRegister = Register; + m_RootParam.Constants.RegisterSpace = RegisterSpace; + } + + RootParameter( D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT NumRanges, D3D12_DESCRIPTOR_RANGE *pRanges, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : + m_RootIndex(RootIndex), + m_ShaderVarType(VarType) + { + VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Unexpected parameter type - verify argument list"); + VERIFY_EXPR(pRanges != nullptr); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.DescriptorTable.NumDescriptorRanges = NumRanges; + m_RootParam.DescriptorTable.pDescriptorRanges = pRanges; +#ifdef _DEBUG + for(Uint32 r=0; r < NumRanges; ++r) + pRanges[r].RangeType = static_cast<D3D12_DESCRIPTOR_RANGE_TYPE>(-1); +#endif + } + + RootParameter(const RootParameter &RP): + m_RootParam( RP.m_RootParam), + m_DescriptorTableSize(RP.m_DescriptorTableSize), + m_ShaderVarType(RP.m_ShaderVarType), + m_RootIndex(RP.m_RootIndex) + { + VERIFY(m_RootParam.ParameterType != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Use another constructor to copy descriptor table") + } + + RootParameter(const RootParameter &RP, UINT NumRanges, D3D12_DESCRIPTOR_RANGE *pRanges): + m_RootParam( RP.m_RootParam), + m_DescriptorTableSize(RP.m_DescriptorTableSize), + m_ShaderVarType(RP.m_ShaderVarType), + m_RootIndex(RP.m_RootIndex) + { + VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table") + VERIFY(NumRanges >= m_RootParam.DescriptorTable.NumDescriptorRanges, "New table must be larger than source one") + auto &DstTbl = m_RootParam.DescriptorTable; + DstTbl.NumDescriptorRanges = NumRanges; + DstTbl.pDescriptorRanges = pRanges; + const auto &SrcTbl = RP.m_RootParam.DescriptorTable; + memcpy(pRanges, SrcTbl.pDescriptorRanges, SrcTbl.NumDescriptorRanges * sizeof(D3D12_DESCRIPTOR_RANGE)); +#ifdef _DEBUG + { + Uint32 dbgTableSize = 0; + for (Uint32 r = 0; r < SrcTbl.NumDescriptorRanges; ++r) + { + const auto &Range = SrcTbl.pDescriptorRanges[r]; + dbgTableSize = std::max(dbgTableSize, Range.OffsetInDescriptorsFromTableStart + Range.NumDescriptors); + } + VERIFY(dbgTableSize == m_DescriptorTableSize, "Incorrect descriptor table size"); + + for (Uint32 r = SrcTbl.NumDescriptorRanges; r < DstTbl.NumDescriptorRanges; ++r) + pRanges[r].RangeType = static_cast<D3D12_DESCRIPTOR_RANGE_TYPE>(-1); + } +#endif + } + + RootParameter& operator = (const RootParameter &RP) = delete; + RootParameter& operator = (RootParameter &&RP) = delete; + + void SetDescriptorRange( UINT RangeIndex, D3D12_DESCRIPTOR_RANGE_TYPE Type, UINT Register, UINT Count, UINT Space = 0, UINT OffsetFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); + auto &Tbl = m_RootParam.DescriptorTable; + VERIFY(RangeIndex < Tbl.NumDescriptorRanges, "Invalid descriptor range index"); + D3D12_DESCRIPTOR_RANGE &range = const_cast<D3D12_DESCRIPTOR_RANGE &>(Tbl.pDescriptorRanges[RangeIndex]); + VERIFY(range.RangeType == static_cast<D3D12_DESCRIPTOR_RANGE_TYPE>(-1), "Descriptor range has already been initialized. m_DescriptorTableSize may be updated incorrectly"); + range.RangeType = Type; + range.NumDescriptors = Count; + range.BaseShaderRegister = Register; + range.RegisterSpace = Space; + range.OffsetInDescriptorsFromTableStart = OffsetFromTableStart; + m_DescriptorTableSize = std::max(m_DescriptorTableSize, OffsetFromTableStart + Count); + } + + SHADER_VARIABLE_TYPE GetShaderVariableType()const{ return m_ShaderVarType; } + Uint32 GetDescriptorTableSize()const + { + VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); + return m_DescriptorTableSize; + } + D3D12_SHADER_VISIBILITY GetShaderVisibility()const{return m_RootParam.ShaderVisibility;} + D3D12_ROOT_PARAMETER_TYPE GetParameterType()const{return m_RootParam.ParameterType;} + + Uint32 GetRootIndex()const{return m_RootIndex;} + + operator const D3D12_ROOT_PARAMETER&()const{return m_RootParam;} + +private: + + SHADER_VARIABLE_TYPE m_ShaderVarType = static_cast<SHADER_VARIABLE_TYPE>(-1); + D3D12_ROOT_PARAMETER m_RootParam = {}; + Uint32 m_DescriptorTableSize = 0; + Uint32 m_RootIndex = static_cast<Uint32>(-1); +}; + + + +/// Implementation of the Diligent::RootSignature class +class RootSignature +{ +public: + RootSignature(); + + void AllocateStaticSamplers(IShader* const *ppShaders, Uint32 NumShaders); + + void Finalize(ID3D12Device *pd3d12Device); + + ID3D12RootSignature* GetD3D12RootSignature()const{return m_pd3d12RootSignature;} + void InitResourceCache(class RenderDeviceD3D12Impl *pDeviceD3D12Impl, class ShaderResourceCacheD3D12& ResourceCache, IMemoryAllocator &CacheMemAllocator)const; + + void InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &ShaderResAttribs); + + void AllocateResourceSlot(SHADER_TYPE ShaderType, const D3DShaderResourceAttribs &ShaderResAttribs, D3D12_DESCRIPTOR_RANGE_TYPE RangeType, Uint32 &RootIndex, Uint32 &OffsetFromTableStart); + + // This method should be thread-safe as it does not modify any object state + void (RootSignature::*CommitDescriptorHandles)(class RenderDeviceD3D12Impl *pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const = nullptr; + + void (RootSignature::*TransitionAndCommitDescriptorHandles)(class RenderDeviceD3D12Impl *pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const = nullptr; + + void TransitionResources(ShaderResourceCacheD3D12& ResourceCache, + class CommandContext &Ctx)const; + + void CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, + class CommandContext &Ctx, + bool IsCompute, + Uint32 ContextId)const; + + Uint32 GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE VarType)const + { + VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES); + return m_TotalSrvCbvUavSlots[VarType]; + } + Uint32 GetTotalSamplerSlots(SHADER_VARIABLE_TYPE VarType)const + { + VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES); + return m_TotalSamplerSlots[VarType]; + } + +private: +#ifdef _DEBUG + void dbgVerifyRootParameters()const; +#endif + + Uint32 m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_NUM_TYPES]; + Uint32 m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_NUM_TYPES]; + + CComPtr<ID3D12RootSignature> m_pd3d12RootSignature; + + class RootParamsManager + { + public: + RootParamsManager(IMemoryAllocator &MemAllocator); + + RootParamsManager(const RootParamsManager&) = delete; + RootParamsManager& operator= (const RootParamsManager&) = delete; + RootParamsManager(RootParamsManager&&) = delete; + RootParamsManager& operator= (RootParamsManager&&) = delete; + + Uint32 GetNumRootTables()const{return m_NumRootTables;} + Uint32 GetNumRootViews()const{return m_NumRootViews;} + + const RootParameter& GetRootTable(Uint32 TableInd)const + { + VERIFY_EXPR(TableInd < m_NumRootTables); + return m_pRootTables[TableInd]; + } + + RootParameter& GetRootTable(Uint32 TableInd) + { + VERIFY_EXPR(TableInd < m_NumRootTables); + return m_pRootTables[TableInd]; + } + + const RootParameter& GetRootView(Uint32 ViewInd)const + { + VERIFY_EXPR(ViewInd < m_NumRootViews); + return m_pRootViews[ViewInd]; + } + + RootParameter& GetRootView(Uint32 ViewInd) + { + VERIFY_EXPR(ViewInd < m_NumRootViews); + return m_pRootViews[ViewInd]; + } + + void AddRootView(D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType); + void AddRootTable(Uint32 RootIndex, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType, Uint32 NumRangesInNewTable = 1); + void AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges = 1); + + template<class TOperation> + void ProcessRootTables(TOperation)const; + + private: + size_t GetRequiredMemorySize(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges)const; + D3D12_DESCRIPTOR_RANGE* Extend(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges, Uint32 RootTableToAddRanges = static_cast<Uint32>(-1)); + + IMemoryAllocator &m_MemAllocator; + std::unique_ptr<void, STDDeleter<void, IMemoryAllocator>> m_pMemory; + Uint32 m_NumRootTables = 0; + Uint32 m_NumRootViews = 0; + Uint32 m_TotalDescriptorRanges = 0; + RootParameter *m_pRootTables = nullptr; + RootParameter *m_pRootViews = nullptr; + }; + + static const Uint8 InvalidRootTableIndex = static_cast<Uint8>(-1); + Uint8 m_SrvCbvUavRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6]; + Uint8 m_SamplerRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6]; + RootParamsManager m_RootParams; + + struct StaticSamplerAttribs + { + StaticSamplerDesc SamplerDesc; + UINT ShaderRegister = static_cast<UINT>(-1); + UINT ArraySize = 0; + UINT RegisterSpace = 0; + D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast<D3D12_SHADER_VISIBILITY>(-1); + + StaticSamplerAttribs(){} + StaticSamplerAttribs(const StaticSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility) : + SamplerDesc(SamDesc), + ShaderVisibility(Visibility) + {} + }; + // Note: sizeof(m_StaticSamplers) == 56 (MS compiler, release x64) + std::vector<StaticSamplerAttribs, STDAllocatorRawMem<StaticSamplerAttribs> > m_StaticSamplers; + + IMemoryAllocator &m_MemAllocator; + + // Commits descriptor handles for static and mutable variables + template<bool PerformResourceTransitions> + void CommitDescriptorHandlesInternal_SM(class RenderDeviceD3D12Impl *pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const; + template<bool PerformResourceTransitions> + // Commits descriptor handles for static, mutable, and dynamic variables + void CommitDescriptorHandlesInternal_SMD(class RenderDeviceD3D12Impl *pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const; +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/include/VertexDescD3D11Impl.h b/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.h index 84b9ea78..11226b64 100644 --- a/Graphics/GraphicsEngineD3D11/include/VertexDescD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,32 +24,34 @@ #pragma once /// \file -/// Declaration of Diligent::VertexDescD3D11Impl class +/// Declaration of Diligent::SamplerD3D12Impl class -#include "VertexDescriptionD3D11.h" -#include "RenderDeviceD3D11.h" -#include "VertexDescriptionBase.h" +#include "SamplerD3D12.h" +#include "RenderDeviceD3D12.h" +#include "SamplerBase.h" +#include "DescriptorHeap.h" namespace Diligent { -/// Implementation of the Diligent::IVertexDescriptionD3D11 interface -class VertexDescD3D11Impl : public VertexDescriptionBase<IVertexDescriptionD3D11> +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::ISamplerD3D12 interface +class SamplerD3D12Impl : public SamplerBase<ISamplerD3D12, IRenderDeviceD3D12, FixedBlockMemoryAllocator> { public: - typedef VertexDescriptionBase<IVertexDescriptionD3D11> TVertexDescriptionBase; + typedef SamplerBase<ISamplerD3D12, IRenderDeviceD3D12, FixedBlockMemoryAllocator> TSamplerBase; - VertexDescD3D11Impl( class RenderDeviceD3D11Impl *pRenderDeviceD3D11, const LayoutDesc &LayoutDesc, IShader *pVertexShader ); - ~VertexDescD3D11Impl(); + SamplerD3D12Impl(FixedBlockMemoryAllocator &SamplerObjAllocator, class RenderDeviceD3D12Impl *pRenderDeviceD3D12, const SamplerDesc& SamplerDesc); + ~SamplerD3D12Impl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; - virtual ID3D11InputLayout* GetD3D11InputLayout(){ return m_pd3d11InputLayout; } + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle()override{ return m_Descriptor.GetCpuHandle(); } private: - friend class DeviceContextD3D11Impl; - /// D3D11 input layout - Diligent::CComPtr<ID3D11InputLayout> m_pd3d11InputLayout; + friend class ShaderD3D12Impl; + /// D3D12 sampler + DescriptorHeapAllocation m_Descriptor; }; } diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h new file mode 100644 index 00000000..b39c70d6 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h @@ -0,0 +1,79 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderD3D12Impl class + +#include "RenderDeviceD3D12.h" +#include "ShaderD3D12.h" +#include "ShaderBase.h" +#include "ShaderD3DBase.h" +#include "ShaderResourceLayoutD3D12.h" + +#ifdef _DEBUG +# define VERIFY_SHADER_BINDINGS +#endif + +namespace Diligent +{ + +class ResourceMapping; +class FixedBlockMemoryAllocator; + +/// Implementation of the Diligent::IShaderD3D12 interface +class ShaderD3D12Impl : public ShaderBase<IShaderD3D12, IRenderDeviceD3D12, FixedBlockMemoryAllocator>, public ShaderD3DBase +{ +public: + typedef ShaderBase<IShaderD3D12, IRenderDeviceD3D12, FixedBlockMemoryAllocator> TShaderBase; + + ShaderD3D12Impl(FixedBlockMemoryAllocator& ShaderObjAllocator, class RenderDeviceD3D12Impl *pRenderDeviceD3D12, const ShaderCreationAttribs &ShaderCreationAttribs); + ~ShaderD3D12Impl(); + + //virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override; + + virtual IShaderVariable* GetShaderVariable(const Char* Name)override; + + ID3DBlob* GetShaderByteCode(){return m_pShaderByteCode;} + const std::shared_ptr<const ShaderResourcesD3D12>& GetShaderResources()const{return m_pShaderResources;} + const ShaderResourceLayoutD3D12& GetConstResLayout()const{return m_StaticResLayout;} + +#ifdef VERIFY_SHADER_BINDINGS + void DbgVerifyStaticResourceBindings(); +#endif + +private: + + DummyShaderVariable m_DummyShaderVar; ///< Dummy shader variable + + // ShaderResources class instance must be referenced through the shared pointer, because + // it is referenced by ShaderResourceLayoutD3D12 class instances + std::shared_ptr<const ShaderResourcesD3D12> m_pShaderResources; + ShaderResourceLayoutD3D12 m_StaticResLayout; + ShaderResourceCacheD3D12 m_ConstResCache; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h new file mode 100644 index 00000000..025db186 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h @@ -0,0 +1,81 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceBindingD3D12Impl class + +#include "ShaderResourceBindingD3D12.h" +#include "RenderDeviceD3D12.h" +#include "ShaderResourceBindingBase.h" +#include "ShaderBase.h" +#include "ShaderResourceCacheD3D12.h" +#include "ShaderResourceLayoutD3D12.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::IShaderResourceBindingD3D12 interface +class ShaderResourceBindingD3D12Impl : public ShaderResourceBindingBase<IShaderResourceBindingD3D12, FixedBlockMemoryAllocator> +{ +public: + typedef ShaderResourceBindingBase<IShaderResourceBindingD3D12, FixedBlockMemoryAllocator> TBase; + ShaderResourceBindingD3D12Impl(FixedBlockMemoryAllocator &SRBAllocator, class PipelineStateD3D12Impl *pPSO, bool IsPSOInternal); + ~ShaderResourceBindingD3D12Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags)override; + + virtual IShaderVariable *GetVariable(SHADER_TYPE ShaderType, const char *Name)override; + + ShaderResourceLayoutD3D12& GetResourceLayout(SHADER_TYPE ResType) + { + auto ShaderInd = GetShaderTypeIndex(ResType); + auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; + VERIFY(ResLayoutInd >= 0, "Shader resource layout is not initialized"); + VERIFY_EXPR(ResLayoutInd < (Int32)m_NumShaders); + return m_pResourceLayouts[ResLayoutInd]; + } + ShaderResourceCacheD3D12& GetResourceCache(){return m_ShaderResourceCache;} + +#ifdef VERIFY_SHADER_BINDINGS + void dbgVerifyResourceBindings(const PipelineStateD3D12Impl *pPSO); +#endif + + bool StaticResourcesInitialized()const{return m_bStaticResourcesInitialized;} + void InitializeStaticResources(const PipelineStateD3D12Impl *pPSO); + +private: + + ShaderResourceCacheD3D12 m_ShaderResourceCache; + ShaderResourceLayoutD3D12* m_pResourceLayouts = nullptr; + // Resource layout index in m_ResourceLayouts[] array for every shader stage + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; + bool m_bStaticResourcesInitialized = false; + Uint32 m_NumShaders = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h new file mode 100644 index 00000000..aed6d32e --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h @@ -0,0 +1,304 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceCacheD3D12 class + + +// Shader resource cache stores D3D12 resources in a continuous chunk of memory: +// +// +// __________________________________________________________ +// | m_pResources, m_NumResources | +// m_pMemory | | +// | | V +// | RootTable[0] | .... | RootTable[Nrt-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] | +// | A \ +// | | \ +// |________________________________________________| \RefCntAutoPtr +// m_pResources, m_NumResources \_________ +// | Object | +// --------- +// +// Nrt = m_NumTables +// +// +// The cache is also assigned decriptor heap space to store shader visible descriptor handles (for non-dynamic resources). +// +// +// DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV +// | DescrptHndl[0] ... DescrptHndl[n-1] | DescrptHndl[0] ... DescrptHndl[m-1] | +// A A +// | | +// | TableStartOffset | TableStartOffset +// | | +// | RootTable[0] | RootTable[1] | RootTable[2] | .... | RootTable[Nrt] | +// | | +// | TableStartOffset | InvalidDescriptorOffset +// | | +// V V +// | DescrptHndl[0] ... DescrptHndl[n-1] | X +// DESCRIPTOR_HEAP_TYPE_SAMPLER +// +// +// +// The allocation is inexed by the offset from the beginning of the root table +// Each root table is assigned the space to store exactly m_NumResources resources +// Dynamic resources are not assigned space in the descriptor heap allocation. +// +// +// +// | RootTable[i] | Res[0] ... Res[n-1] | +// \ +// TableStartOffset\____ +// \ +// V +// ..... | DescrptHndl[0] ... DescrptHndl[n-1] | .... +// + +#include "DescriptorHeap.h" + +namespace Diligent +{ + +enum class CachedResourceType : Int32 +{ + Unknown = -1, + CBV = 0, + TexSRV, + BufSRV, + TexUAV, + BufUAV, + Sampler, + NumTypes +}; + +class ShaderResourceCacheD3D12 +{ +public: + // This enum is used for debug purposes only + enum DbgCacheContentType + { + StaticShaderResources, + SRBResources + }; + + ShaderResourceCacheD3D12(DbgCacheContentType dbgContentType) +#ifdef _DEBUG + : m_DbgContentType(dbgContentType) +#endif + { + } + + ~ShaderResourceCacheD3D12(); + + void Initialize(IMemoryAllocator &MemAllocator, Uint32 NumTables, Uint32 TableSizes[]); + + static const Uint32 InvalidDescriptorOffset = static_cast<Uint32>(-1); + + struct Resource + { + CachedResourceType Type = CachedResourceType::Unknown; + // CPU descriptor handle of a cached resource in external descriptor heap + // Note that for dynamic resources, this is the only available CPU descriptor handle + D3D12_CPU_DESCRIPTOR_HANDLE CPUDescriptorHandle = {0}; + RefCntAutoPtr<IDeviceObject> pObject; + }; + + class RootTable + { + public: + RootTable(Uint32 NumResources, Resource *pResources) : + m_NumResources(NumResources), + m_pResources(pResources) + {} + + inline Resource& GetResource(Uint32 OffsetFromTableStart, + const D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType, + const SHADER_TYPE dbgRefShaderType) + { + VERIFY(m_dbgHeapType == DescriptorHeapType, "Incosistent descriptor heap type" ) + VERIFY(m_dbgShaderType == dbgRefShaderType, "Incosistent shader type" ) + + VERIFY(OffsetFromTableStart < m_NumResources, "Root table at index is not large enough to store descriptor at offset ", OffsetFromTableStart ); + return m_pResources[OffsetFromTableStart]; + } + + inline Uint32 GetSize()const{return m_NumResources; } + + // Offset from the start of the descriptor heap alloction to the start of the table + Uint32 TableStartOffset = InvalidDescriptorOffset; + +#ifdef _DEBUG + void SetDebugAttribs(Uint32 MaxOffset, + const D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType, + const SHADER_TYPE dbgRefShaderType) + { + VERIFY_EXPR(m_NumResources == MaxOffset); + m_dbgHeapType = DescriptorHeapType; + m_dbgShaderType = dbgRefShaderType; + } + + D3D12_DESCRIPTOR_HEAP_TYPE DbgGetHeapType()const{return m_dbgHeapType;} +#endif + + const Uint32 m_NumResources = 0; + private: + +#ifdef _DEBUG + D3D12_DESCRIPTOR_HEAP_TYPE m_dbgHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; + SHADER_TYPE m_dbgShaderType = SHADER_TYPE_UNKNOWN; +#endif + + Resource* const m_pResources = nullptr; + }; + + inline RootTable& GetRootTable(Uint32 RootIndex) + { + VERIFY_EXPR(RootIndex < m_NumTables); + return reinterpret_cast<RootTable*>(m_pMemory)[RootIndex]; + } + + inline Uint32 GetNumRootTables()const{return m_NumTables; } + + void SetDescriptorHeapSpace(DescriptorHeapAllocation &&CbcSrvUavHeapSpace, DescriptorHeapAllocation &&SamplerHeapSpace) + { + VERIFY(m_SamplerHeapSpace.GetCpuHandle().ptr == 0 && m_CbcSrvUavHeapSpace.GetCpuHandle().ptr == 0, "Space has already been allocated in GPU descriptor heaps"); +#ifdef _DEBUG + Uint32 NumSamplerDescriptors = 0, NumSrvCbvUavDescriptors = 0; + for (Uint32 rt = 0; rt < m_NumTables; ++rt) + { + auto &Tbl = GetRootTable(rt); + if(Tbl.TableStartOffset != InvalidDescriptorOffset) + { + if(Tbl.DbgGetHeapType() == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + VERIFY(Tbl.TableStartOffset == NumSrvCbvUavDescriptors, "Descriptor space allocation is not continuous") + NumSrvCbvUavDescriptors = std::max(NumSrvCbvUavDescriptors, Tbl.TableStartOffset + Tbl.GetSize()); + } + else + { + VERIFY(Tbl.TableStartOffset == NumSamplerDescriptors, "Descriptor space allocation is not continuous") + NumSamplerDescriptors = std::max(NumSamplerDescriptors, Tbl.TableStartOffset + Tbl.GetSize()); + } + } + } + VERIFY(NumSrvCbvUavDescriptors == CbcSrvUavHeapSpace.GetNumHandles() || NumSrvCbvUavDescriptors == 0 && CbcSrvUavHeapSpace.GetCpuHandle(0).ptr == 0, "Unexpected descriptor heap allocation size" ) + VERIFY(NumSamplerDescriptors == SamplerHeapSpace.GetNumHandles() || NumSamplerDescriptors == 0 && SamplerHeapSpace.GetCpuHandle(0).ptr == 0, "Unexpected descriptor heap allocation size" ) +#endif + + m_CbcSrvUavHeapSpace = std::move(CbcSrvUavHeapSpace); + m_SamplerHeapSpace = std::move(SamplerHeapSpace); + } + + ID3D12DescriptorHeap* GetSrvCbvUavDescriptorHeap(){return m_CbcSrvUavHeapSpace.GetDescriptorHeap();} + ID3D12DescriptorHeap* GetSamplerDescriptorHeap(){return m_SamplerHeapSpace.GetDescriptorHeap();} + + // Returns CPU descriptor handle of a shader visible descriptor heap allocation + template<D3D12_DESCRIPTOR_HEAP_TYPE HeapType> + D3D12_CPU_DESCRIPTOR_HANDLE GetShaderVisibleTableCPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) + { + auto &RootParam = GetRootTable(RootParamInd); + VERIFY(HeapType == RootParam.DbgGetHeapType(), "Invalid descriptor heap type"); + + D3D12_CPU_DESCRIPTOR_HANDLE CPUDescriptorHandle = {0}; + // Descriptor heap allocation is not assigned for dynamic resources or + // in a special case when resource cache is used to store static + // variable assignments for a shader + if( RootParam.TableStartOffset != InvalidDescriptorOffset ) + { + VERIFY(RootParam.TableStartOffset + OffsetFromTableStart < RootParam.m_NumResources, "Offset is out of range"); + if( HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ) + { + VERIFY_EXPR(!m_SamplerHeapSpace.IsNull()); + CPUDescriptorHandle = m_SamplerHeapSpace.GetCpuHandle(RootParam.TableStartOffset + OffsetFromTableStart); + } + else if( HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ) + { + VERIFY_EXPR(!m_CbcSrvUavHeapSpace.IsNull()); + CPUDescriptorHandle = m_CbcSrvUavHeapSpace.GetCpuHandle(RootParam.TableStartOffset + OffsetFromTableStart); + } + else + { + UNEXPECTED("Unexpected descriptor heap type"); + } + } + + return CPUDescriptorHandle; + } + + // Returns GPU descriptor handle of a shader visible descriptor table + template<D3D12_DESCRIPTOR_HEAP_TYPE HeapType> + D3D12_GPU_DESCRIPTOR_HANDLE GetShaderVisibleTableGPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) + { + auto &RootParam = GetRootTable(RootParamInd); + VERIFY_EXPR(RootParam.TableStartOffset != InvalidDescriptorOffset); + VERIFY(RootParam.TableStartOffset + OffsetFromTableStart < RootParam.m_NumResources, "Offset is out of range"); + + D3D12_GPU_DESCRIPTOR_HANDLE GPUDescriptorHandle = {0}; + VERIFY( HeapType == RootParam.DbgGetHeapType(), "Invalid descriptor heap type"); + if( HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ) + { + VERIFY_EXPR(!m_SamplerHeapSpace.IsNull()); + GPUDescriptorHandle = m_SamplerHeapSpace.GetGpuHandle(RootParam.TableStartOffset + OffsetFromTableStart); + } + else if( HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ) + { + VERIFY_EXPR(!m_CbcSrvUavHeapSpace.IsNull()); + GPUDescriptorHandle = m_CbcSrvUavHeapSpace.GetGpuHandle(RootParam.TableStartOffset + OffsetFromTableStart); + } + else + { + UNEXPECTED("Unexpected descriptor heap type"); + } + + return GPUDescriptorHandle; + } + +#ifdef _DEBUG + // Only for debug purposes: indicates what types of resources are stored in the cache + DbgCacheContentType DbgGetContentType()const{return m_DbgContentType;} +#endif + +private: + ShaderResourceCacheD3D12(const ShaderResourceCacheD3D12&) = delete; + ShaderResourceCacheD3D12(ShaderResourceCacheD3D12&&) = delete; + ShaderResourceCacheD3D12& operator = (const ShaderResourceCacheD3D12&) = delete; + ShaderResourceCacheD3D12& operator = (ShaderResourceCacheD3D12&&) = delete; + + DescriptorHeapAllocation m_SamplerHeapSpace; + DescriptorHeapAllocation m_CbcSrvUavHeapSpace; + + IMemoryAllocator *m_pAllocator=nullptr; + void *m_pMemory = nullptr; + Uint32 m_NumTables = 0; + +#ifdef _DEBUG + // Only for debug purposes: indicates what types of resources are stored in the cache + const DbgCacheContentType m_DbgContentType; +#endif +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h new file mode 100644 index 00000000..90d1ba27 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h @@ -0,0 +1,396 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceLayoutD3D12 class + + +// All resources are stored in a single continuous chunk of memory using the following layout: +// +// m_ResourceBuffer m_Samplers +// | | +// | SRV_CBV_UAV[0] ... SRV_CBV_UAV[s-1] | SRV_CBV_UAV[s] ... SRV_CBV_UAV[s+m-1] | SRV_CBV_UAV[s+m] ... SRV_CBV_UAV[s+m+d-1] || Sampler[0] ... Sampler[s'-1] | Sampler[s'] ... Sampler[s'+m'-1] | Sampler[s'+m'] ... Sampler[s'+m'+d'-1] || +// | | | || | | || +// | SHADER_VARIABLE_TYPE_STATIC | SHADER_VARIABLE_TYPE_MUTABLE | SHADER_VARIABLE_TYPE_DYNAMIC || SHADER_VARIABLE_TYPE_STATIC | SHADER_VARIABLE_TYPE_MUTABLE | SHADER_VARIABLE_TYPE_DYNAMIC || +// | | | || +// +// s == m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_STATIC] +// m == m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_MUTABLE] +// d == m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_DYNAMIC] +// +// s' == m_NumSamplers[SHADER_VARIABLE_TYPE_STATIC] +// m' == m_NumSamplers[SHADER_VARIABLE_TYPE_MUTABLE] +// d' == m_NumSamplers[SHADER_VARIABLE_TYPE_DYNAMIC] +// +// +// Memory buffer is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block +// memory allocator is used. This ensures that all resources from different shader resource bindings reside in +// continuous memory. If allocation granularity == 1, raw allocator is used. +// +// +// Every SRV_CBV_UAV and Sampler structure holds a reference to D3DShaderResourceAttribs structure from ShaderResources. +// ShaderResourceLayoutD3D12 holds shared pointer to ShaderResources instance. Note that ShaderResources::SamplerId references +// a sampler in ShaderResources, while SRV_CBV_UAV::SamplerId references a sampler in ShaderResourceLayoutD3D12, and the +// two are not the same +// +// +// ________________SamplerId____________________ +// | | +// _________________ ______________|_____________________________________________V________ +// | | unique_ptr | | | | | | | +// | ShaderResources |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | +// |_________________| |________|___________|___________|___________|___________|____________| +// A A A A +// | \ / \ +// |shared_ptr Ref Ref Ref +// ________|__________________ ________\________________________/_________________________\_________________________________________ +// | | unique_ptr | | | | | | | +// | ShaderResourceLayoutD3D12 |--------------->| SRV_CBV_UAV[0] | SRV_CBV_UAV[1] | ... | Sampler[0] | Sampler[1] | ... | +// |___________________________| |___________________|_________________|_______________|__________________|_________________|__________| +// | | | A | / +// | Raw ptr | |___________________SamplerId________________________| | / +// | | / / +// | \ / / +// ________V_________________ ________V_______________________________________________________V____V__ +// | | | | +// | ShaderResourceCacheD3D12 |---------------->| Resources | +// |__________________________| |________________________________________________________________________| +// +// Resources in the resource cache are identified by the root index and offset in the descriptor table +// +// +// ShaderResourceLayoutD3D12 is used by +// - ShaderD3D12Impl class instance to hold static resources of a shader; shader resource +// cache is used to store satatic resource bindings +// - PipelineStateD3D12Impl class instance to hold all kinds of resources. Root indices and +// descriptor table offsets are assigned during the initialization; no shader resource cache is used +// - ShaderResourceBindingD3D12Impl to hold all kind of resources; shader resource cache is assigned +// + + +// Set this define to 1 to use unordered_map to store shader variables. +// Note that sizeof(m_VariableHash)==128 (release mode, MS compiler, x64). +#define USE_VARIABLE_HASH_MAP 0 + +#include "unordered_map" + +#include "ShaderD3DBase.h" +#include "ShaderBase.h" +#include "HashUtils.h" +#include "ShaderResourcesD3D12.h" +#include "ShaderResourceCacheD3D12.h" +#include "ShaderVariableD3DBase.h" + +#ifdef _DEBUG +# define VERIFY_SHADER_BINDINGS +#endif + +namespace Diligent +{ + +/// Diligent::ShaderResourceLayoutD3D12 class +// sizeof(ShaderResourceLayoutD3D12)==80 (MS compiler, x64) +class ShaderResourceLayoutD3D12 +{ +public: + ShaderResourceLayoutD3D12(IObject &Owner, IMemoryAllocator &ResourceLayoutDataAllocator); + + // This constructor is used by ShaderResourceBindingD3D12Impl to clone layout from the reference layout in PipelineStateD3D12Impl. + // Root indices and descriptor table offsets must be correct. Resource cache is not initialized. + ShaderResourceLayoutD3D12(IObject &Owner, + const ShaderResourceLayoutD3D12& SrcLayout, + IMemoryAllocator &ResourceLayoutDataAllocator, + const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12 &ResourceCache); + + ShaderResourceLayoutD3D12(const ShaderResourceLayoutD3D12&) = delete; + ShaderResourceLayoutD3D12(ShaderResourceLayoutD3D12&&) = delete; + ShaderResourceLayoutD3D12& operator =(const ShaderResourceLayoutD3D12&) = delete; + ShaderResourceLayoutD3D12& operator =(ShaderResourceLayoutD3D12&&) = delete; + + ~ShaderResourceLayoutD3D12(); + + // The method is called by + // - ShaderD3D12Impl class instance to initialize static resource layout and initialize shader resource cache + // to hold static resources + // - PipelineStateD3D12Impl class instance to hold all kind of resources. Root indices and + // descriptor table offsets are assigned during the initialization; no shader resource cache is provided + void Initialize(ID3D12Device *pd3d12Device, + const std::shared_ptr<const ShaderResourcesD3D12>& pSrcResources, + IMemoryAllocator &LayoutDataAllocator, + const SHADER_VARIABLE_TYPE *VarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12 *pResourceCache, + class RootSignature *pRootSig); + + // sizeof(SRV_CBV_UAV) == 32 (x64) + struct SRV_CBV_UAV : ShaderVariableD3DBase<ShaderResourceLayoutD3D12> + { + SRV_CBV_UAV(const SRV_CBV_UAV&) = delete; + SRV_CBV_UAV(SRV_CBV_UAV&&) = delete; + SRV_CBV_UAV& operator = (const SRV_CBV_UAV&) = delete; + SRV_CBV_UAV& operator = (SRV_CBV_UAV&&) = delete; + + static const Uint32 ResTypeBits = 3; + static const Uint32 RootIndBits = 16-ResTypeBits; + static const Uint32 RootIndMask = (1 << RootIndBits)-1; + static const Uint32 ResTypeMask = (1 << ResTypeBits)-1; + + static const Uint16 InvalidRootIndex = RootIndMask; + static const Uint16 MaxRootIndex = RootIndMask-1; + + static const Uint32 InvalidSamplerId = 0xFFFF; + static const Uint32 MaxSamplerId = InvalidSamplerId-1; + static const Uint32 InvalidOffset = static_cast<Uint32>(-1); + + static_assert( static_cast<int>(CachedResourceType::NumTypes) <= ResTypeMask, "3 bits is not enough to store CachedResourceType"); + + const Uint32 OffsetFromTableStart; + + SRV_CBV_UAV(ShaderResourceLayoutD3D12 &ParentLayout, const SRV_CBV_UAV &rhs, Uint32 SamId ) : + ResType_RootIndex(rhs.ResType_RootIndex), + SamplerId(static_cast<Uint16>(SamId)), + OffsetFromTableStart(rhs.OffsetFromTableStart), + ShaderVariableD3DBase<ShaderResourceLayoutD3D12>(ParentLayout, rhs.Attribs) + { + VERIFY(SamId == InvalidSamplerId || SamId <= MaxSamplerId, "Sampler id exceeds max allowed value (", MaxSamplerId, ")" ) + VERIFY(rhs.m_ParentResLayout.m_pResources == m_ParentResLayout.m_pResources, "Incosistent resource references"); + VERIFY(IsValidOffset(), "Offset must be valid" ) + VERIFY(IsValidRootIndex(), "Root index must be valid" ) + } + + SRV_CBV_UAV(ShaderResourceLayoutD3D12 &ParentLayout, const D3DShaderResourceAttribs &_Attribs, + CachedResourceType ResType, Uint32 RootIndex, Uint32 _OffsetFromTableStart, Uint32 _SamplerId) : + ResType_RootIndex( (static_cast<Uint16>(ResType) << RootIndBits) | (RootIndex & RootIndMask)), + SamplerId( static_cast<Uint16>(_SamplerId) ), + OffsetFromTableStart(_OffsetFromTableStart), + ShaderVariableD3DBase<ShaderResourceLayoutD3D12>(ParentLayout, _Attribs) + { + VERIFY(RootIndex == InvalidRootIndex || RootIndex <= MaxRootIndex, "Root index exceeds max allowed value (", MaxRootIndex, ")" ) + VERIFY(IsValidOffset(), "Offset must be valid" ) + VERIFY(SamplerId == InvalidSamplerId || SamplerId <= MaxSamplerId, "Sampler id exceeds max allowed value (", MaxSamplerId, ")" ) + } + + bool IsBound(Uint32 ArrayIndex); + + // Non-virtual function + void BindResource(IDeviceObject *pObject, Uint32 ArrayIndex, const ShaderResourceLayoutD3D12 *dbgResLayout); + virtual void Set(IDeviceObject *pObject)override final{ BindResource(pObject, 0, nullptr); } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + for(Uint32 Elem = 0; Elem < NumElements; ++Elem) + BindResource(ppObjects[Elem], FirstElement+Elem, nullptr); + } + + bool IsValidSampler()const{return GetSamplerId() != InvalidSamplerId;} + bool IsValidRootIndex()const{return GetRootIndex() != InvalidRootIndex;} + bool IsValidOffset()const{return OffsetFromTableStart != InvalidOffset;} + + CachedResourceType GetResType()const + { + return static_cast<CachedResourceType>( (ResType_RootIndex >> RootIndBits) & ResTypeMask ); + } + Uint32 GetRootIndex()const + { + return ResType_RootIndex & RootIndMask; + } + + Uint32 GetSamplerId()const + { + return SamplerId; + } + + private: + const Uint16 ResType_RootIndex; // bit + // | 0 1 .... 12 | 13 14 15 | + // | | | + // | Root index | ResType | + const Uint16 SamplerId; + + void CacheCB(IDeviceObject *pBuffer, ShaderResourceCacheD3D12::Resource& DstRes, Uint32 ArrayInd, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle); + + template<typename TResourceViewType, + typename TViewTypeEnum, + typename TBindSamplerProcType> + void CacheResourceView(IDeviceObject *pView, + ShaderResourceCacheD3D12::Resource& DstRes, + Uint32 ArrayIndex, + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, + TViewTypeEnum dbgExpectedViewType, + TBindSamplerProcType BindSamplerProc); + }; + + // sizeof(Sampler) == 24 (x64) + struct Sampler + { + Sampler(const Sampler&) = delete; + Sampler(Sampler&&) = delete; + Sampler& operator = (const Sampler&) = delete; + Sampler& operator = (Sampler&&) = delete; + + const D3DShaderResourceAttribs &Attribs; + ShaderResourceLayoutD3D12 &m_ParentResLayout; + + static const Uint32 InvalidRootIndex = static_cast<Uint32>(-1); + static const Uint32 InvalidOffset = static_cast<Uint32>(-1); + + const Uint32 RootIndex; + const Uint32 OffsetFromTableStart; + + Sampler(ShaderResourceLayoutD3D12 &ParentLayout, const Sampler& Sam): + Attribs(Sam.Attribs), + m_ParentResLayout(ParentLayout), + RootIndex(Sam.RootIndex), + OffsetFromTableStart(Sam.OffsetFromTableStart) + { + VERIFY(Sam.m_ParentResLayout.m_pResources == m_ParentResLayout.m_pResources, "Incosistent resource references"); + VERIFY(IsValidRootIndex(), "Root index must be valid" ) + VERIFY(IsValidOffset(), "Offset must be valid" ) + } + + Sampler(ShaderResourceLayoutD3D12 &ParentResLayout, const D3DShaderResourceAttribs &_Attribs, Uint32 _RootIndex, Uint32 _OffsetFromTableStart) : + RootIndex(_RootIndex), + OffsetFromTableStart(_OffsetFromTableStart), + Attribs(_Attribs), + m_ParentResLayout(ParentResLayout) + { + VERIFY(IsValidRootIndex(), "Root index must be valid" ) + VERIFY(IsValidOffset(), "Offset must be valid" ) + } + + bool IsValidRootIndex()const{return RootIndex != InvalidRootIndex;} + bool IsValidOffset()const{return OffsetFromTableStart != InvalidOffset;} + + void CacheSampler(class ITextureViewD3D12 *pTexViewD3D12, Uint32 ArrayIndex, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle); + }; + + + void CopyStaticResourceDesriptorHandles(const ShaderResourceLayoutD3D12 &SrcLayout); + + // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive + // while Layout is alive + void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D12 *dbgResourceCache ); + + IShaderVariable* GetShaderVariable( const Char* Name ); + +#ifdef VERIFY_SHADER_BINDINGS + void dbgVerifyBindings()const; +#endif + + IObject& GetOwner(){return m_Owner;} + +private: + void InitVariablesHashMap(); + + Sampler &GetAssignedSampler(const SRV_CBV_UAV &TexSrv); + + const Char* GetShaderName()const; + + // There is no need to use shared ptr as referenced resource cache is either part of the + // parent ShaderD3D12Impl object or ShaderResourceBindingD3D12Impl object + ShaderResourceCacheD3D12 *m_pResourceCache; + + std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer; + Sampler* m_Samplers = nullptr; + Uint16 m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_NUM_TYPES] = {0,0,0}; + Uint16 m_NumSamplers[SHADER_VARIABLE_TYPE_NUM_TYPES] = {0,0,0}; + + Uint32 GetSrvCbvUavOffset(SHADER_VARIABLE_TYPE VarType, Uint32 r)const + { + VERIFY_EXPR( r < m_NumCbvSrvUav[VarType] ); + static_assert(SHADER_VARIABLE_TYPE_STATIC == 0, "SHADER_VARIABLE_TYPE_STATIC == 0 expected"); + r += (VarType > SHADER_VARIABLE_TYPE_STATIC) ? m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_STATIC] : 0; + static_assert(SHADER_VARIABLE_TYPE_MUTABLE == 1, "SHADER_VARIABLE_TYPE_MUTABLE == 1 expected"); + r += (VarType > SHADER_VARIABLE_TYPE_MUTABLE) ? m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_MUTABLE] : 0; + return r; + } + SRV_CBV_UAV& GetSrvCbvUav(SHADER_VARIABLE_TYPE VarType, Uint32 r) + { + VERIFY_EXPR( r < m_NumCbvSrvUav[VarType] ); + auto* CbvSrvUav = reinterpret_cast<SRV_CBV_UAV*>(m_ResourceBuffer.get()); + return CbvSrvUav[GetSrvCbvUavOffset(VarType,r)]; + } + const SRV_CBV_UAV& GetSrvCbvUav(SHADER_VARIABLE_TYPE VarType, Uint32 r)const + { + VERIFY_EXPR( r < m_NumCbvSrvUav[VarType] ); + auto* CbvSrvUav = reinterpret_cast<SRV_CBV_UAV*>(m_ResourceBuffer.get()); + return CbvSrvUav[GetSrvCbvUavOffset(VarType,r)]; + } + SRV_CBV_UAV& GetSrvCbvUav(Uint32 r) + { + VERIFY_EXPR( r < GetTotalSrvCbvUavCount() ); + auto* CbvSrvUav = reinterpret_cast<SRV_CBV_UAV*>(m_ResourceBuffer.get()); + return CbvSrvUav[r]; + } + + Uint32 GetSamplerOffset(SHADER_VARIABLE_TYPE VarType, Uint32 s)const + { + VERIFY_EXPR( s < m_NumSamplers[VarType] ); + static_assert(SHADER_VARIABLE_TYPE_STATIC == 0, "SHADER_VARIABLE_TYPE_STATIC == 0 expected"); + s += (VarType > SHADER_VARIABLE_TYPE_STATIC) ? m_NumSamplers[SHADER_VARIABLE_TYPE_STATIC] : 0; + static_assert(SHADER_VARIABLE_TYPE_MUTABLE == 1, "SHADER_VARIABLE_TYPE_MUTABLE == 1 expected"); + s += (VarType > SHADER_VARIABLE_TYPE_MUTABLE) ? m_NumSamplers[SHADER_VARIABLE_TYPE_MUTABLE] : 0; + return s; + } + Sampler& GetSampler(SHADER_VARIABLE_TYPE VarType, Uint32 s) + { + VERIFY_EXPR( s < m_NumSamplers[VarType] ); + return m_Samplers[GetSamplerOffset(VarType,s)]; + } + const Sampler& GetSampler(SHADER_VARIABLE_TYPE VarType, Uint32 s)const + { + VERIFY_EXPR( s < m_NumSamplers[VarType] ); + return m_Samplers[GetSamplerOffset(VarType,s)]; + } + Uint32 GetTotalSrvCbvUavCount()const + { + static_assert(SHADER_VARIABLE_TYPE_NUM_TYPES == 3, "Did you add new variable type?"); + return m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_STATIC] + m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_MUTABLE] + m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_DYNAMIC]; + } + Uint32 GetTotalSamplerCount()const + { + static_assert(SHADER_VARIABLE_TYPE_NUM_TYPES == 3, "Did you add new variable type?"); + return m_NumSamplers[SHADER_VARIABLE_TYPE_STATIC] + m_NumSamplers[SHADER_VARIABLE_TYPE_MUTABLE] + m_NumSamplers[SHADER_VARIABLE_TYPE_DYNAMIC]; + } + + void AllocateMemory(IMemoryAllocator &Allocator); + +#if USE_VARIABLE_HASH_MAP + // Hash map to look up shader variables by name. + // Note that sizeof(m_VariableHash)==128 (release mode, MS compiler, x64). + typedef std::pair<HashMapStringKey, IShaderVariable*> VariableHashElemType; + std::unordered_map<HashMapStringKey, IShaderVariable*, std::hash<HashMapStringKey>, std::equal_to<HashMapStringKey>, STDAllocatorRawMem<VariableHashElemType> > m_VariableHash; +#endif + + CComPtr<ID3D12Device> m_pd3d12Device; + IObject &m_Owner; + // We must use shared_ptr to reference ShaderResources instance, because + // there may be multiple objects referencing the same set of resources + std::shared_ptr<const ShaderResourcesD3D12> m_pResources; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.h new file mode 100644 index 00000000..f58ce20d --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.h @@ -0,0 +1,94 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourcesD3D12 class + +// ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then referenced by ShaderResourceLayoutD3D12 objects, which are in turn +// created by instances of PipelineStatesD3D12Impl and ShaderResourceBindingsD3D12Impl (and ShaderD3D12Impl too) +// +// _________________ +// | | +// | ShaderD3D12Impl | +// |_________________| +// | +// |shared_ptr +// ________V_____________ _____________________________________________________________________ +// | | unique_ptr | | | | | | | +// | ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | +// |______________________| |________|___________|___________|___________|___________|____________| +// A A A A +// | \ / \ +// |shared_ptr Ref Ref Ref +// ________|__________________ ________\________________________/_________________________\_________________________________________ +// | | unique_ptr | | | | | | | +// | ShaderResourceLayoutD3D12 |--------------->| SRV_CBV_UAV[0] | SRV_CBV_UAV[1] | ... | Sampler[0] | Sampler[1] | ... | +// |___________________________| |___________________|_________________|_______________|__________________|_________________|__________| +// A | A +// | |___________________SamplerId________________________| +// | +// __________|_____________ +// | | +// | PipelineStateD3D12Impl | +// |________________________| +// +// +// One ShaderResources instance can be referenced by multiple objects +// +// +// ________________________ _<m_ShaderResourceLayouts>_ ____<m_pResourceLayouts>___ ________________________________ +// | | | | | | | | +// | PipelineStateD3D12Impl |-------->| ShaderResourceLayoutD3D12 | ----| ShaderResourceLayoutD3D12 |<-----| ShaderResourceBindingD3D12Impl | +// |________________________| |___________________________| | |___________________________| |________________________________| +// | | +// | shared_ptr | +// _________________ ___________V__________ | ____<m_pResourceLayouts>___ ________________________________ +// | | shared_ptr | | shared_ptr| | | | | +// | ShaderD3D12Impl |--------------->| ShaderResourcesD3D12 |<---------------| ShaderResourceLayoutD3D12 |<-----| ShaderResourceBindingD3D12Impl | +// |_________________| |______________________| | |___________________________| |________________________________| +// | A | +// V | | +// ____<m_StaticResLayout>____ | | ____<m_pResourceLayouts>___ ________________________________ +// | | shared_ptr | | | | | | +// | ShaderResourceLayoutD3D12 |------------------- ----| ShaderResourceLayoutD3D12 |<-----| ShaderResourceBindingD3D12Impl | +// |___________________________| |___________________________| |________________________________| +// +// + + +#include "ShaderResources.h" + +namespace Diligent +{ + +/// Diligent::ShaderResources class +class ShaderResourcesD3D12 : public ShaderResources +{ +public: + // Loads shader resources from the compiled shader bytecode + ShaderResourcesD3D12(ID3DBlob *pShaderBytecode, const ShaderDesc &ShdrDesc); +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h new file mode 100644 index 00000000..e7e8f312 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h @@ -0,0 +1,69 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::SwapChainD3D12Impl class + +#include "SwapChainD3D12.h" +#include "SwapChainBase.h" +#include <dxgi1_4.h> + +namespace Diligent +{ + +class ITextureViewD3D12; +class IMemoryAllocator; +/// Implementation of the Diligent::ISwapChainD3D12 interface +class SwapChainD3D12Impl : public SwapChainBase<ISwapChainD3D12, IMemoryAllocator> +{ +public: + typedef SwapChainBase<ISwapChainD3D12, IMemoryAllocator> TSwapChainBase; + SwapChainD3D12Impl(IMemoryAllocator &Allocator, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceD3D12Impl* pRenderDeviceD3D12, + class DeviceContextD3D12Impl* pDeviceContextD3D12, + void* pNativeWndHandle); + ~SwapChainD3D12Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + + virtual void Present(); + virtual void Resize( Uint32 NewWidth, Uint32 NewHeight ); + + virtual IDXGISwapChain *GetDXGISwapChain(){ return m_pSwapChain; } + ITextureView *GetCurrentBackBufferRTV(); + ITextureView *GetDepthBufferDSV(){return m_pDepthBufferDSV;} + +private: + void InitBuffersAndViews(); + + /// DXGI swap chain + CComPtr<IDXGISwapChain3> m_pSwapChain; + + std::vector< RefCntAutoPtr<ITextureView>, STDAllocatorRawMem<RefCntAutoPtr<ITextureView>> > m_pBackBufferRTV; + RefCntAutoPtr<ITextureView> m_pDepthBufferDSV; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h new file mode 100644 index 00000000..039de70f --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h @@ -0,0 +1,97 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::TextureD3D12Impl class + +#include "TextureD3D12.h" +#include "RenderDeviceD3D12.h" +#include "TextureBase.h" +#include "TextureViewD3D12Impl.h" +#include "D3D12ResourceBase.h" + + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Base implementation of the Diligent::ITextureD3D12 interface +class TextureD3D12Impl : public TextureBase<ITextureD3D12, TextureViewD3D12Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator>, public D3D12ResourceBase +{ +public: + typedef TextureBase<ITextureD3D12, TextureViewD3D12Impl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> TTextureBase; + + TextureD3D12Impl(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + class RenderDeviceD3D12Impl *pDeviceD3D12, + const TextureDesc& TexDesc, + const TextureData &InitData = TextureData()); + TextureD3D12Impl(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + class RenderDeviceD3D12Impl *pDeviceD3D12, + const TextureDesc& TexDesc, + ID3D12Resource *pTexture); + ~TextureD3D12Impl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override; + + //virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size); + virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override; + + virtual ID3D12Resource* GetD3D12Texture(){ return GetD3D12Resource(); } + + void CopyData(IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ); + + D3D12_CPU_DESCRIPTOR_HANDLE GetUAVDescriptorHandle(Uint32 Mip, Uint32 Slice); + +protected: + void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override; + //void PrepareD3D12InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<D3D12_SUBRESOURCE_DATA> &D3D12InitData); + + void CreateSRV( TextureViewDesc &SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVHandle ); + void CreateRTV( TextureViewDesc &RTVDesc, D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle ); + void CreateDSV( TextureViewDesc &DSVDesc, D3D12_CPU_DESCRIPTOR_HANDLE DSVHandle ); + void CreateUAV( TextureViewDesc &UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVHandle ); + + // UAVs for every subresource to facilitate mipmap generation + DescriptorHeapAllocation m_SubresUAVs; + + friend class RenderDeviceD3D12Impl; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.h new file mode 100644 index 00000000..6256ca0a --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.h @@ -0,0 +1,65 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::TextureViewD3D12Impl class + +#include "TextureViewD3D12.h" +#include "RenderDeviceD3D12.h" +#include "TextureViewBase.h" +#include "DescriptorHeap.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::ITextureViewD3D12 interface +class TextureViewD3D12Impl : public TextureViewBase<ITextureViewD3D12, FixedBlockMemoryAllocator> +{ +public: + typedef TextureViewBase<ITextureViewD3D12, FixedBlockMemoryAllocator> TTextureViewBase; + + TextureViewD3D12Impl( FixedBlockMemoryAllocator &TexViewObjAllocator, + IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + class ITexture *pTexture, + DescriptorHeapAllocation &&HandleAlloc, + bool bIsDefaultView); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + //virtual ID3D12View* GetD3D12View()override; + + void GenerateMips( IDeviceContext *pContext )override; + + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle()override{return m_Descriptor.GetCpuHandle();} + //virtual D3D12_GPU_DESCRIPTOR_HANDLE GetGPUDescriptorHandle()override{return m_Descriptor.GetGpuHandle();} + +protected: + /// D3D12 view descriptor handle + DescriptorHeapAllocation m_Descriptor; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/include/d3dx12_win.h b/Graphics/GraphicsEngineD3D12/include/d3dx12_win.h new file mode 100644 index 00000000..ba59dfc7 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/d3dx12_win.h @@ -0,0 +1,1508 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx12.h +// Content: D3DX12 utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() + {} + explicit CD3DX12_RECT( const D3D12_RECT& o ) : + D3D12_RECT( o ) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } + ~CD3DX12_RECT() {} + operator const D3D12_RECT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() + {} + explicit CD3DX12_BOX( const D3D12_BOX& o ) : + D3D12_BOX( o ) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right ) + { + left = Left; + top = 0; + front = 0; + right = Right; + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + front = 0; + right = Right; + bottom = Bottom; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) + { + left = Left; + top = Top; + front = Front; + right = Right; + bottom = Bottom; + back = Back; + } + ~CD3DX12_BOX() {} + operator const D3D12_BOX&() const { return *this; } +}; +inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } + ~CD3DX12_DEPTH_STENCIL_DESC() {} + operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() + {} + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } + ~CD3DX12_BLEND_DESC() {} + operator const D3D12_BLEND_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() + {} + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } + ~CD3DX12_RASTERIZER_DESC() {} + operator const D3D12_RASTERIZER_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() + {} + explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) : + D3D12_RESOURCE_ALLOCATION_INFO( o ) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment ) + { + SizeInBytes = size; + Alignment = alignment; + } + operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() + {} + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + operator const D3D12_HEAP_PROPERTIES&() const { return *this; } + bool IsCPUAccessible() const + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() + {} + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + operator const D3D12_HEAP_DESC&() const { return *this; } + bool IsCPUAccessible() const + { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } +}; +inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() + {} + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4] ) + { + Format = format; + memcpy( Color, color, sizeof( Color ) ); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil ) + { + Format = format; + /* Use memcpy to preserve NAN values */ + memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); + DepthStencil.Stencil = stencil; + } + operator const D3D12_CLEAR_VALUE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() + {} + explicit CD3DX12_RANGE(const D3D12_RANGE &o) : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end ) + { + Begin = begin; + End = end; + } + operator const D3D12_RANGE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() + {} + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource ) + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } + operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() + {} + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth ) + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } + operator const D3D12_TILE_REGION_SIZE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() + {} + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource ) + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_SUBRESOURCE_TILING&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() + {} + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels ) + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } + operator const D3D12_TILE_SHAPE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() + {} + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } + operator const D3D12_RESOURCE_BARRIER&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() + {} + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource ) + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_PACKED_MIP_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() + {} + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch ) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch ) + { + Format = resDesc.Format; + Width = UINT( resDesc.Width ); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } + operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() + {} + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() { } + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() {} + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() {} + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() {} + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() {} + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() {} + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() {} + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template <typename T, typename U, typename V> +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) +{ + MipSlice = static_cast<T>(Subresource % MipLevels); + ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {Format}; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() + {} + explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) : + D3D12_RESOURCE_DESC( o ) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags ) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags ); + } + inline UINT16 Depth() const + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } + operator const D3D12_RESOURCE_DESC&() const { return *this; } +}; +inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) +{ + for (UINT z = 0; z < NumSlices; ++z) + { + BYTE* pDestSlice = reinterpret_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * z; + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * y, + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) +{ + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); + D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > (SIZE_T)-1 || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast<void**>(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; + MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, NULL); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( pLayouts[0].Offset + pLayouts[0].Footprint.Width ) ); + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc)); + if (pMem == NULL) + { + return 0; + } + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources); + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template <UINT MaxSubresources> +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) +{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } + +//------------------------------------------------------------------------------------------------ +inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp) +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast<ID3D12CommandList * const *>(pp); +} + + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ + + + diff --git a/Graphics/GraphicsEngineD3D12/include/pch.h b/Graphics/GraphicsEngineD3D12/include/pch.h new file mode 100644 index 00000000..f2f0b7f4 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/pch.h @@ -0,0 +1,47 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define NOMINMAX + + +#include <vector> +#include <exception> +#include <algorithm> +#include <d3d12.h> + +#include "PlatformDefinitions.h" +#include "Errors.h" +#include "RefCntAutoPtr.h" +#include "DebugUtilities.h" +#include "D3DErrors.h" +#include "RenderDeviceBase.h" +#include "ValidatedCast.h" +#include <atlcomcli.h>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h b/Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h new file mode 100644 index 00000000..f3e69a13 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/BufferD3D12.h @@ -0,0 +1,56 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBufferD3D12 interface + +#include "Buffer.h" + +namespace Diligent +{ + +// {3E9B15ED-A289-48DC-8214-C6E3E6177378} +static const INTERFACE_ID IID_BufferD3D12 = +{ 0x3e9b15ed, 0xa289, 0x48dc, { 0x82, 0x14, 0xc6, 0xe3, 0xe6, 0x17, 0x73, 0x78 } }; + +/// Interface to the buffer object implemented in D3D12 +class IBufferD3D12 : public Diligent::IBuffer +{ +public: + + /// Returns a pointer to the ID3D12Resource interface of the internal Direct3D12 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + /// \param [in] DataStartByteOffset - Offset from the beginning of the buffer + /// to the start of the data. This parameter + /// is required for dynamic buffers, which are + /// suballocated in a dynamic upload heap + /// \param [in] ContextId - Id of the context within which address of the buffer is requested. + /// + virtual ID3D12Resource *GetD3D12Buffer(size_t &DataStartByteOffset, Uint32 ContextId) = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/interface/BufferViewD3D12.h b/Graphics/GraphicsEngineD3D12/interface/BufferViewD3D12.h new file mode 100644 index 00000000..7d9e45c9 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/BufferViewD3D12.h @@ -0,0 +1,47 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBufferViewD3D12 interface + +#include "BufferView.h" + +namespace Diligent +{ + +// {09643F2F-40D4-4076-B086-9E5CDC2CC4FC} +static const Diligent::INTERFACE_ID IID_BufferViewD3D12 = +{ 0x9643f2f, 0x40d4, 0x4076, { 0xb0, 0x86, 0x9e, 0x5c, 0xdc, 0x2c, 0xc4, 0xfc } }; + +/// Interface to the buffer view object implemented in D3D12 +class IBufferViewD3D12 : public IBufferView +{ +public: + + /// Returns CPU descriptor handle of the internal Direct3D12 object. + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h b/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h new file mode 100644 index 00000000..c31ea4cc --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h @@ -0,0 +1,57 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IPipeplineStateD3D12 interface + +#include "PipelineState.h" + +namespace Diligent +{ + +// {33C9BE4B-6F23-4F83-A665-5AC1836DF35A} +static const INTERFACE_ID IID_PipelineStateD3D12 = +{ 0x33c9be4b, 0x6f23, 0x4f83, { 0xa6, 0x65, 0x5a, 0xc1, 0x83, 0x6d, 0xf3, 0x5a } }; + + +/// Interface to the blend state object implemented in D3D12 +class IPipelineStateD3D12 : public IPipelineState +{ +public: + + /// Returns a pointer to the ID3D12PipelineState interface of the internal Direct3D12 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D12PipelineState *GetD3D12PipelineState()const = 0; + + /// Returns a pointer to the root signature object associated with this pipeline state. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D12RootSignature *GetD3D12RootSignature()const = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h new file mode 100644 index 00000000..309d355e --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h @@ -0,0 +1,49 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IRenderDeviceD3D12 interface + +#include "RenderDevice.h" + +namespace Diligent +{ +// {C7987C98-87FE-4309-AE88-E98F044B00F6} +static const Diligent::INTERFACE_ID IID_RenderDeviceD3D12 = +{ 0xc7987c98, 0x87fe, 0x4309, { 0xae, 0x88, 0xe9, 0x8f, 0x4, 0x4b, 0x0, 0xf6 } }; + +/// Interface to the render device object implemented in D3D12 +class IRenderDeviceD3D12 : public Diligent::IRenderDevice +{ +public: + + /// Returns a pointer to the ID3D12Device interface of the internal Direct3D12 object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + virtual ID3D12Device* GetD3D12Device() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceFactoryD3D12.h b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceFactoryD3D12.h new file mode 100644 index 00000000..f3aa45f4 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceFactoryD3D12.h @@ -0,0 +1,104 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of functions that initialize Direct3D12-based engine implementation + +#include "Errors.h" + +extern "C" +{ +#ifdef ENGINE_DLL + + typedef void (*CreateDeviceAndContextsD3D12Type)( + const Diligent::EngineD3D12Attribs& CreationAttribs, + Diligent::IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppContexts, + Diligent::Uint32 NumDeferredContexts ); + + + typedef void (*CreateSwapChainD3D12Type)( + Diligent::IRenderDevice *pDevice, + Diligent::IDeviceContext *pImmediateContext, + const Diligent::SwapChainDesc& SwapChainDesc, + void* pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ); + + static void LoadGraphicsEngineD3D12(CreateDeviceAndContextsD3D12Type &CreateDeviceFunc, CreateSwapChainD3D12Type &CreateSwapChainFunc) + { + CreateDeviceFunc = nullptr; + CreateSwapChainFunc = nullptr; + std::string LibName = "GraphicsEngineD3D12_"; + +#if _WIN64 + LibName += "64"; +#else + LibName += "32"; +#endif + +#ifdef _DEBUG + LibName += "d"; +#else + LibName += "r"; +#endif + + LibName += ".dll"; + auto hModule = LoadLibraryA( LibName.c_str() ); + if( hModule == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load ", LibName, " library." ); + return; + } + + CreateDeviceFunc = reinterpret_cast<CreateDeviceAndContextsD3D12Type>( GetProcAddress(hModule, "CreateDeviceAndContextsD3D12") ); + if( CreateDeviceFunc == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load CreateDeviceAndContextsD3D12() from ", LibName, " library." ); + FreeLibrary( hModule ); + return; + } + + CreateSwapChainFunc = reinterpret_cast<CreateSwapChainD3D12Type>( GetProcAddress(hModule, "CreateSwapChainD3D12") ); + if( CreateSwapChainFunc == NULL ) + { + LOG_ERROR_MESSAGE( "Failed to load CreateSwapChainD3D12() from ", LibName, " library." ); + FreeLibrary( hModule ); + return; + } + } +#else + + void CreateDeviceAndContextsD3D12( const Diligent::EngineD3D12Attribs& CreationAttribs, + Diligent::IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppContexts, + Diligent::Uint32 NumDeferredContexts); + + void CreateSwapChainD3D12( Diligent::IRenderDevice *pDevice, + Diligent::IDeviceContext *pImmediateContext, + const Diligent::SwapChainDesc& SwapChainDesc, + void* pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ); +#endif +} diff --git a/Graphics/GraphicsEngineD3D11/interface/BlendStateD3D11.h b/Graphics/GraphicsEngineD3D12/interface/SamplerD3D12.h index 8fe1c302..4359fdc5 100644 --- a/Graphics/GraphicsEngineD3D11/interface/BlendStateD3D11.h +++ b/Graphics/GraphicsEngineD3D12/interface/SamplerD3D12.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,27 +24,27 @@ #pragma once /// \file -/// Definition of the Diligent::IBlendStateD3D11 interface +/// Definition of the Diligent::ISamplerD3D12 interface -#include "BlendState.h" +#include "Sampler.h" namespace Diligent { -// {18FEA836-1DD6-4100-9C83-CEF71F8EC8F1} -static const Diligent::INTERFACE_ID IID_BlendStateD3D11 = -{ 0x18fea836, 0x1dd6, 0x4100, { 0x9c, 0x83, 0xce, 0xf7, 0x1f, 0x8e, 0xc8, 0xf1 } }; +// {31A3BFAF-738E-4D8C-AD18-B021C5D948DD} +static const Diligent::INTERFACE_ID IID_SamplerD3D12 = +{ 0x31a3bfaf, 0x738e, 0x4d8c, { 0xad, 0x18, 0xb0, 0x21, 0xc5, 0xd9, 0x48, 0xdd } }; -/// Interface to the blend state object implemented in D3D11 -class IBlendStateD3D11 : public Diligent::IBlendState +/// Interface to the sampler object implemented in D3D12 +class ISamplerD3D12 : public Diligent::ISampler { public: - /// Returns a pointer to the ID3D11BlendState interface of the internal Direct3D11 object. + /// Returns a pointer to the ID3D12SamplerState interface of the internal Direct3D12 object. /// The method does *NOT* call AddRef() on the returned interface, /// so Release() must not be called. - virtual ID3D11BlendState *GetD3D11BlendState() = 0; + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() = 0; }; } diff --git a/Graphics/GraphicsEngineD3D11/interface/RasterizerStateD3D11.h b/Graphics/GraphicsEngineD3D12/interface/ShaderD3D12.h index 7ebb7bf0..50aa22aa 100644 --- a/Graphics/GraphicsEngineD3D11/interface/RasterizerStateD3D11.h +++ b/Graphics/GraphicsEngineD3D12/interface/ShaderD3D12.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,27 +24,27 @@ #pragma once /// \file -/// Definition of the Diligent::IRasterizerStateD3D11 interface +/// Definition of the Diligent::IShaderD3D12 interface -#include "RasterizerState.h" +#include "Shader.h" namespace Diligent { -// {10E96D54-1A17-4AB4-8A87-CD39211B348D} -static const Diligent::INTERFACE_ID IID_RasterizerStateD3D11 = -{ 0x10e96d54, 0x1a17, 0x4ab4, { 0x8a, 0x87, 0xcd, 0x39, 0x21, 0x1b, 0x34, 0x8d } }; +// {C059B160-7F31-4029-943D-0996B98EE79A} +static const Diligent::INTERFACE_ID IID_ShaderD3D12 = +{ 0xc059b160, 0x7f31, 0x4029, { 0x94, 0x3d, 0x9, 0x96, 0xb9, 0x8e, 0xe7, 0x9a } }; -/// Interface to the rasterizer state object implemented in D3D11 -class IRasterizerStateD3D11 : public Diligent::IRasterizerState +/// Interface to the shader object implemented in D3D12 +class IShaderD3D12 : public Diligent::IShader { public: - /// Returns a pointer to the ID3D11RasterizerState interface of the internal Direct3D11 object. + /// Returns a pointer to the ID3D12DeviceChild interface of the internal Direct3D12 object. /// The method does *NOT* call AddRef() on the returned interface, /// so Release() must not be called. - virtual ID3D11RasterizerState *GetD3D11RasterizerState() = 0; + //virtual ID3D12DeviceChild* GetD3D12Shader() = 0; }; } diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderResourceBindingD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderResourceBindingD3D12.h new file mode 100644 index 00000000..6038b88b --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/ShaderResourceBindingD3D12.h @@ -0,0 +1,45 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IShaderResourceBindingD3D12 interface and related data structures + +#include "ShaderResourceBinding.h" + +namespace Diligent +{ + +// {70DD5C7C-81FA-4D9A-942F-D1B91423FAAC} +static const Diligent::INTERFACE_ID IID_ShaderResourceBindingD3D12 = +{ 0x70dd5c7c, 0x81fa, 0x4d9a, { 0x94, 0x2f, 0xd1, 0xb9, 0x14, 0x23, 0xfa, 0xac } }; + +/// Shader resource binding interface +class IShaderResourceBindingD3D12 : public IShaderResourceBinding +{ +public: + +}; + +} diff --git a/Graphics/GraphicsEngineD3D11/interface/VertexDescriptionD3D11.h b/Graphics/GraphicsEngineD3D12/interface/SwapChainD3D12.h index ab75bfba..eacc0ef4 100644 --- a/Graphics/GraphicsEngineD3D11/interface/VertexDescriptionD3D11.h +++ b/Graphics/GraphicsEngineD3D12/interface/SwapChainD3D12.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,27 +24,27 @@ #pragma once /// \file -/// Definition of the Diligent::IVertexDescriptionD3D11 interface +/// Definition of the Diligent::ISwapChainD3D12 interface -#include "VertexDescription.h" +#include "SwapChain.h" namespace Diligent { -// {7BCB2412-60EB-451C-9167-F31B869484C1} -static const Diligent::INTERFACE_ID IID_VertexDescriptionD3D11 = -{ 0x7bcb2412, 0x60eb, 0x451c, { 0x91, 0x67, 0xf3, 0x1b, 0x86, 0x94, 0x84, 0xc1 } }; +// {C9F8384D-A45E-4970-8447-394177E5B0EE} +static const Diligent::INTERFACE_ID IID_SwapChainD3D12 = +{ 0xc9f8384d, 0xa45e, 0x4970, { 0x84, 0x47, 0x39, 0x41, 0x77, 0xe5, 0xb0, 0xee } }; -/// Interface to the vertex description object implemented in D3D11 -class IVertexDescriptionD3D11 : public Diligent::IVertexDescription +/// Interface to the swap chain object implemented in D3D12 +class ISwapChainD3D12 : public Diligent::ISwapChain { public: - /// Returns a pointer to the ID3D11InputLayout interface of the internal Direct3D11 object. + /// Returns a pointer to the IDXGISwapChain interface of the internal DXGI object. /// The method does *NOT* call AddRef() on the returned interface, /// so Release() must not be called. - virtual ID3D11InputLayout* GetD3D11InputLayout() = 0; + virtual IDXGISwapChain *GetDXGISwapChain() = 0; }; } diff --git a/Graphics/GraphicsEngineD3D11/interface/DepthStencilStateD3D11.h b/Graphics/GraphicsEngineD3D12/interface/TextureD3D12.h index 7e8bd567..2fe585ce 100644 --- a/Graphics/GraphicsEngineD3D11/interface/DepthStencilStateD3D11.h +++ b/Graphics/GraphicsEngineD3D12/interface/TextureD3D12.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,27 +24,27 @@ #pragma once /// \file -/// Definition of the Diligent::IDepthStencilStateD3D11 interface +/// Definition of the Diligent::ITextureD3D12 interface -#include "DepthStencilState.h" +#include "Texture.h" namespace Diligent { -// {77EA665B-4D63-4D5F-AD8F-791FE79FC305} -static const Diligent::INTERFACE_ID IID_DepthStencilStateD3D11 = -{ 0x77ea665b, 0x4d63, 0x4d5f, { 0xad, 0x8f, 0x79, 0x1f, 0xe7, 0x9f, 0xc3, 0x5 } }; +// {CF5522EF-8116-4D76-ADF1-5CC8FB31FF66} +static const Diligent::INTERFACE_ID IID_TextureD3D12 = +{ 0xcf5522ef, 0x8116, 0x4d76, { 0xad, 0xf1, 0x5c, 0xc8, 0xfb, 0x31, 0xff, 0x66 } }; -/// Interface to the depth stencil state object implemented in D3D11 -class IDepthStencilStateD3D11 : public Diligent::IDepthStencilState +/// Interface to the texture object implemented in D3D11 +class ITextureD3D12 : public Diligent::ITexture { public: - /// Returns a pointer to the ID3D11DepthStencilState interface of the internal Direct3D11 object. + /// Returns a pointer to the ID3D12Resource interface of the internal Direct3D12 object. /// The method does *NOT* call AddRef() on the returned interface, /// so Release() must not be called. - virtual ID3D11DepthStencilState *GetD3D11DepthStencilState() = 0; + virtual ID3D12Resource* GetD3D12Texture() = 0; }; } diff --git a/Graphics/GraphicsEngineD3D12/interface/TextureViewD3D12.h b/Graphics/GraphicsEngineD3D12/interface/TextureViewD3D12.h new file mode 100644 index 00000000..967d28a1 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/TextureViewD3D12.h @@ -0,0 +1,47 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITextureViewD3D12 interface + +#include "TextureView.h" + +namespace Diligent +{ + +// {BDFBD325-0699-4720-BC0E-BF84086EC033} +static const Diligent::INTERFACE_ID IID_TextureViewD3D12 = +{ 0xbdfbd325, 0x699, 0x4720, { 0xbc, 0xe, 0xbf, 0x84, 0x8, 0x6e, 0xc0, 0x33 } }; + +/// Interface to the texture view object implemented in D3D11 +class ITextureViewD3D12 : public Diligent::ITextureView +{ +public: + + /// Returns CPU descriptor handle of the internal Direct3D12 object. + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() = 0; +}; + +} diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsCS.hlsli b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsCS.hlsli new file mode 100644 index 00000000..3c25ff54 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsCS.hlsli @@ -0,0 +1,206 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define RootSig \ + "RootFlags(0), " \ + "RootConstants(b0, num32BitConstants = 4), " \ + "DescriptorTable(SRV(t0, numDescriptors = 1))," \ + "DescriptorTable(UAV(u0, numDescriptors = 4))," \ + "StaticSampler(s0," \ + "addressU = TEXTURE_ADDRESS_CLAMP," \ + "addressV = TEXTURE_ADDRESS_CLAMP," \ + "addressW = TEXTURE_ADDRESS_CLAMP," \ + "filter = FILTER_MIN_MAG_MIP_LINEAR)" + +#ifndef NON_POWER_OF_TWO +#define NON_POWER_OF_TWO 0 +#endif + +RWTexture2D<float4> OutMip1 : register(u0); +RWTexture2D<float4> OutMip2 : register(u1); +RWTexture2D<float4> OutMip3 : register(u2); +RWTexture2D<float4> OutMip4 : register(u3); +Texture2D<float4> SrcTex : register(t0); +SamplerState BilinearClamp : register(s0); + +cbuffer CB : register(b0) +{ + uint SrcMipLevel; // Texture level of source mip + uint NumMipLevels; // Number of OutMips to write: [1, 4] + float2 TexelSize; // 1.0 / OutMip1.Dimensions +} + +// The reason for separating channels is to reduce bank conflicts in the +// local data memory controller. A large stride will cause more threads +// to collide on the same memory bank. +groupshared float gs_R[64]; +groupshared float gs_G[64]; +groupshared float gs_B[64]; +groupshared float gs_A[64]; + +void StoreColor( uint Index, float4 Color ) +{ + gs_R[Index] = Color.r; + gs_G[Index] = Color.g; + gs_B[Index] = Color.b; + gs_A[Index] = Color.a; +} + +float4 LoadColor( uint Index ) +{ + return float4( gs_R[Index], gs_G[Index], gs_B[Index], gs_A[Index]); +} + +float3 LinearToSRGB(float3 x) +{ + // This is exactly the sRGB curve + //return x < 0.0031308 ? 12.92 * x : 1.055 * pow(abs(x), 1.0 / 2.4) - 0.055; + + // This is cheaper but nearly equivalent + return x < 0.0031308 ? 12.92 * x : 1.13005 * sqrt(abs(x - 0.00228)) - 0.13448 * x + 0.005719; +} + +float4 PackColor(float4 Linear) +{ +#ifdef CONVERT_TO_SRGB + return float4(LinearToSRGB(Linear.rgb), Linear.a); +#else + return Linear; +#endif +} + +[RootSignature(RootSig)] +[numthreads( 8, 8, 1 )] +void main( uint GI : SV_GroupIndex, uint3 DTid : SV_DispatchThreadID ) +{ + uint2 DstMipSize; + SrcTex.GetDimensions(DstMipSize.x, DstMipSize.y); + DstMipSize >>= SrcMipLevel; + bool IsValidThread = all(DTid.xy < DstMipSize); + + float4 Src1 = 0; + if( IsValidThread ) + { + // One bilinear sample is insufficient when scaling down by more than 2x. + // You will slightly undersample in the case where the source dimension + // is odd. This is why it's a really good idea to only generate mips on + // power-of-two sized textures. Trying to handle the undersampling case + // will force this shader to be slower and more complicated as it will + // have to take more source texture samples. +#if NON_POWER_OF_TWO == 0 + float2 UV = TexelSize * (DTid.xy + 0.5); + Src1 = SrcTex.SampleLevel(BilinearClamp, UV, SrcMipLevel); +#elif NON_POWER_OF_TWO == 1 + // > 2:1 in X dimension + // Use 2 bilinear samples to guarantee we don't undersample when downsizing by more than 2x + // horizontally. + float2 UV1 = TexelSize * (DTid.xy + float2(0.25, 0.5)); + float2 Off = TexelSize * float2(0.5, 0.0); + Src1 = 0.5 * (SrcTex.SampleLevel(BilinearClamp, UV1, SrcMipLevel) + + SrcTex.SampleLevel(BilinearClamp, UV1 + Off, SrcMipLevel)); +#elif NON_POWER_OF_TWO == 2 + // > 2:1 in Y dimension + // Use 2 bilinear samples to guarantee we don't undersample when downsizing by more than 2x + // vertically. + float2 UV1 = TexelSize * (DTid.xy + float2(0.5, 0.25)); + float2 Off = TexelSize * float2(0.0, 0.5); + Src1 = 0.5 * (SrcTex.SampleLevel(BilinearClamp, UV1, SrcMipLevel) + + SrcTex.SampleLevel(BilinearClamp, UV1 + Off, SrcMipLevel)); +#elif NON_POWER_OF_TWO == 3 + // > 2:1 in in both dimensions + // Use 4 bilinear samples to guarantee we don't undersample when downsizing by more than 2x + // in both directions. + float2 UV1 = TexelSize * (DTid.xy + float2(0.25, 0.25)); + float2 Off = TexelSize * 0.5; + Src1 += SrcTex.SampleLevel(BilinearClamp, UV1, SrcMipLevel); + Src1 += SrcTex.SampleLevel(BilinearClamp, UV1 + float2(Off.x, 0.0), SrcMipLevel); + Src1 += SrcTex.SampleLevel(BilinearClamp, UV1 + float2(0.0, Off.y), SrcMipLevel); + Src1 += SrcTex.SampleLevel(BilinearClamp, UV1 + float2(Off.x, Off.y), SrcMipLevel); + Src1 *= 0.25; +#endif + + OutMip1[DTid.xy] = PackColor(Src1); + } + + // A scalar (constant) branch can exit all threads coherently. + if (NumMipLevels == 1) + return; + + if( IsValidThread ) + { + // Without lane swizzle operations, the only way to share data with other + // threads is through LDS. + StoreColor(GI, Src1); + } + + // This guarantees all LDS writes are complete and that all threads have + // executed all instructions so far (and therefore have issued their LDS + // write instructions.) + GroupMemoryBarrierWithGroupSync(); + + if( IsValidThread ) + { + // With low three bits for X and high three bits for Y, this bit mask + // (binary: 001001) checks that X and Y are even. + if ((GI & 0x9) == 0) + { + float4 Src2 = LoadColor(GI + 0x01); + float4 Src3 = LoadColor(GI + 0x08); + float4 Src4 = LoadColor(GI + 0x09); + Src1 = 0.25 * (Src1 + Src2 + Src3 + Src4); + + OutMip2[DTid.xy / 2] = PackColor(Src1); + StoreColor(GI, Src1); + } + } + + if (NumMipLevels == 2) + return; + + GroupMemoryBarrierWithGroupSync(); + + if( IsValidThread ) + { + // This bit mask (binary: 011011) checks that X and Y are multiples of four. + if ((GI & 0x1B) == 0) + { + float4 Src2 = LoadColor(GI + 0x02); + float4 Src3 = LoadColor(GI + 0x10); + float4 Src4 = LoadColor(GI + 0x12); + Src1 = 0.25 * (Src1 + Src2 + Src3 + Src4); + + OutMip3[DTid.xy / 4] = PackColor(Src1); + StoreColor(GI, Src1); + } + } + + if (NumMipLevels == 3) + return; + + GroupMemoryBarrierWithGroupSync(); + + if( IsValidThread ) + { + // This bit mask would be 111111 (X & Y multiples of 8), but only one + // thread fits that criteria. + if (GI == 0) + { + float4 Src2 = LoadColor(GI + 0x04); + float4 Src3 = LoadColor(GI + 0x20); + float4 Src4 = LoadColor(GI + 0x24); + Src1 = 0.25 * (Src1 + Src2 + Src3 + Src4); + + OutMip4[DTid.xy / 8] = PackColor(Src1); + } + } +} diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaCS.hlsl new file mode 100644 index 00000000..3ed1ca5f --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaCS.hlsl @@ -0,0 +1,15 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define CONVERT_TO_SRGB +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddCS.hlsl new file mode 100644 index 00000000..4545115f --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddCS.hlsl @@ -0,0 +1,16 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define CONVERT_TO_SRGB +#define NON_POWER_OF_TWO 3 +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddXCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddXCS.hlsl new file mode 100644 index 00000000..010e98d7 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddXCS.hlsl @@ -0,0 +1,16 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define CONVERT_TO_SRGB +#define NON_POWER_OF_TWO 1 +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddYCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddYCS.hlsl new file mode 100644 index 00000000..6bc0d7df --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsGammaOddYCS.hlsl @@ -0,0 +1,16 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define CONVERT_TO_SRGB +#define NON_POWER_OF_TWO 2 +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearCS.hlsl new file mode 100644 index 00000000..19d1d90f --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearCS.hlsl @@ -0,0 +1,14 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddCS.hlsl new file mode 100644 index 00000000..86416514 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddCS.hlsl @@ -0,0 +1,15 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define NON_POWER_OF_TWO 3 +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddXCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddXCS.hlsl new file mode 100644 index 00000000..ede7b445 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddXCS.hlsl @@ -0,0 +1,15 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define NON_POWER_OF_TWO 1 +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddYCS.hlsl b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddYCS.hlsl new file mode 100644 index 00000000..afd17ad2 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/shaders/GenerateMips/GenerateMipsLinearOddYCS.hlsl @@ -0,0 +1,15 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + +#define NON_POWER_OF_TWO 2 +#include "GenerateMipsCS.hlsli" diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp new file mode 100644 index 00000000..c7470492 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp @@ -0,0 +1,373 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BufferD3D12Impl.h" +#include "RenderDeviceD3D12Impl.h" +#include "DeviceContextD3D12Impl.h" +#include "D3D12TypeConversions.h" +#include "BufferViewD3D12Impl.h" +#include "GraphicsUtilities.h" +#include "DXGITypeConversions.h" +#include "EngineMemory.h" + +namespace Diligent +{ + +BufferD3D12Impl :: BufferD3D12Impl(FixedBlockMemoryAllocator &BufferObjMemAllocator, + FixedBlockMemoryAllocator &BuffViewObjMemAllocator, + RenderDeviceD3D12Impl *pRenderDeviceD3D12, + const BufferDesc& BuffDesc, + const BufferData &BuffData /*= BufferData()*/) : + TBufferBase(BufferObjMemAllocator, BuffViewObjMemAllocator, pRenderDeviceD3D12, BuffDesc), +#ifdef _DEBUG + m_DbgMapType(1 + pRenderDeviceD3D12->GetNumDeferredContexts(), static_cast<MAP_TYPE>(-1), STD_ALLOCATOR_RAW_MEM(DynamicAllocation, GetRawAllocator(), "Allocator for vector<MAP_TYPE>")), +#endif + m_DynamicData(BuffDesc.Usage == USAGE_DYNAMIC ? (1 + pRenderDeviceD3D12->GetNumDeferredContexts()) : 0, DynamicAllocation(), STD_ALLOCATOR_RAW_MEM(DynamicAllocation, GetRawAllocator(), "Allocator for vector<DynamicAllocation>")) +{ +#define LOG_BUFFER_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Buffer \"", BuffDesc.Name ? BuffDesc.Name : "", "\": ", ##__VA_ARGS__); + + if( m_Desc.Usage == USAGE_STATIC && BuffData.pData == nullptr ) + LOG_BUFFER_ERROR_AND_THROW("Static buffer must be initialized with data at creation time") + + if( m_Desc.Usage == USAGE_DYNAMIC && BuffData.pData != nullptr ) + LOG_BUFFER_ERROR_AND_THROW("Dynamic buffer must be initialized via Map()") + + if (m_Desc.BindFlags & BIND_UNIFORM_BUFFER) + { + Uint32 AlignmentMask = 255; + m_Desc.uiSizeInBytes = (m_Desc.uiSizeInBytes + AlignmentMask) & (~AlignmentMask); + } + + if(m_Desc.Usage == USAGE_DYNAMIC) + { + // Dynamic buffers are suballocated in the upload heap when Map() is called. + // Dynamic upload heap buffer is always in D3D12_RESOURCE_STATE_GENERIC_READ state + + m_UsageState = D3D12_RESOURCE_STATE_GENERIC_READ; + VERIFY_EXPR(m_DynamicData.size() == 1 + pRenderDeviceD3D12->GetNumDeferredContexts()); + } + else + { + D3D12_RESOURCE_DESC D3D12BuffDesc = {}; + D3D12BuffDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + D3D12BuffDesc.Alignment = 0; + D3D12BuffDesc.Width = m_Desc.uiSizeInBytes; + D3D12BuffDesc.Height = 1; + D3D12BuffDesc.DepthOrArraySize = 1; + D3D12BuffDesc.MipLevels = 1; + D3D12BuffDesc.Format = DXGI_FORMAT_UNKNOWN; + D3D12BuffDesc.SampleDesc.Count = 1; + D3D12BuffDesc.SampleDesc.Quality = 0; + // Layout must be D3D12_TEXTURE_LAYOUT_ROW_MAJOR, as buffer memory layouts are + // understood by applications and row-major texture data is commonly marshaled through buffers. + D3D12BuffDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + D3D12BuffDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + if( m_Desc.BindFlags & BIND_UNORDERED_ACCESS ) + D3D12BuffDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + auto *pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); + + + D3D12_HEAP_PROPERTIES HeapProps; + HeapProps.Type = m_Desc.Usage == USAGE_CPU_ACCESSIBLE ? D3D12_HEAP_TYPE_READBACK : D3D12_HEAP_TYPE_DEFAULT; + if(HeapProps.Type == D3D12_HEAP_TYPE_READBACK) + m_UsageState = D3D12_RESOURCE_STATE_COPY_DEST; + else if(HeapProps.Type == D3D12_HEAP_TYPE_UPLOAD) + m_UsageState = D3D12_RESOURCE_STATE_GENERIC_READ; + HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + HeapProps.CreationNodeMask = 1; + HeapProps.VisibleNodeMask = 1; + + bool bInitializeBuffer = (BuffData.pData != nullptr && BuffData.DataSize > 0); + if(bInitializeBuffer) + m_UsageState = D3D12_RESOURCE_STATE_COPY_DEST; + + auto hr = pd3d12Device->CreateCommittedResource( &HeapProps, D3D12_HEAP_FLAG_NONE, + &D3D12BuffDesc, m_UsageState, nullptr, __uuidof(m_pd3d12Resource), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)) ); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create D3D12 buffer") + + if( bInitializeBuffer ) + { + D3D12_HEAP_PROPERTIES UploadHeapProps; + UploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + UploadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + UploadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + UploadHeapProps.CreationNodeMask = 1; + UploadHeapProps.VisibleNodeMask = 1; + + D3D12BuffDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + CComPtr<ID3D12Resource> UploadBuffer; + hr = pd3d12Device->CreateCommittedResource( &UploadHeapProps, D3D12_HEAP_FLAG_NONE, + &D3D12BuffDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(UploadBuffer), + reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&UploadBuffer)) ); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create uload buffer") + + void* DestAddress = nullptr; + hr = UploadBuffer->Map(0, nullptr, &DestAddress); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to map uload buffer") + memcpy(DestAddress, BuffData.pData, BuffData.DataSize); + UploadBuffer->Unmap(0, nullptr); + + auto *pInitContext = pRenderDeviceD3D12->AllocateCommandContext(); + // copy data to the intermediate upload heap and then schedule a copy from the upload heap to the default buffer + VERIFY_EXPR(m_UsageState == D3D12_RESOURCE_STATE_COPY_DEST); + // We MUST NOT call TransitionResource() from here, because + // it will call AddRef() and potentially Release(), while + // the object is not constructed yet + pInitContext->CopyResource(m_pd3d12Resource, UploadBuffer); + + pRenderDeviceD3D12->CloseAndExecuteCommandContext(pInitContext); + + // Add reference to the object to the release queue to keep it alive + // until copy operation is complete. This must be done after + // submitting command list for execution! + pRenderDeviceD3D12->SafeReleaseD3D12Object(UploadBuffer); + } + + if (m_Desc.BindFlags & BIND_UNIFORM_BUFFER) + { + m_CBVDescriptorAllocation = pRenderDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + CreateCBV(m_CBVDescriptorAllocation.GetCpuHandle()); + } + } +#if 0 + D3D12BuffDesc.BindFlags = BindFlagsToD3D12BindFlags(BuffDesc.BindFlags); + D3D12BuffDesc.ByteWidth = + D3D12BuffDesc.MiscFlags = 0; + if( BuffDesc.BindFlags & BIND_INDIRECT_DRAW_ARGS ) + { + D3D12BuffDesc.MiscFlags |= D3D12_RESOURCE_MISC_DRAWINDIRECT_ARGS; + } + D3D12BuffDesc.Usage = UsageToD3D12Usage(BuffDesc.Usage); + + D3D12BuffDesc.StructureByteStride = 0; + if( (BuffDesc.BindFlags & BIND_UNORDERED_ACCESS) ) + { + if( BuffDesc.Mode == BUFFER_MODE_STRUCTURED ) + { + D3D12BuffDesc.MiscFlags |= D3D12_RESOURCE_MISC_BUFFER_STRUCTURED; + D3D12BuffDesc.StructureByteStride = BuffDesc.ElementByteStride; + } + else if( BuffDesc.Mode == BUFFER_MODE_FORMATED ) + { + auto ElementStride = GetValueSize( BuffDesc.Format.ValueType ) * BuffDesc.Format.NumComponents; + VERIFY( m_Desc.ElementByteStride == 0 || m_Desc.ElementByteStride == ElementStride, "Element byte stride does not match buffer format" ); + m_Desc.ElementByteStride = ElementStride; + if( BuffDesc.Format.ValueType == VT_FLOAT32 || BuffDesc.Format.ValueType == VT_FLOAT16 ) + m_Desc.Format.IsNormalized = false; + } + else + { + UNEXPECTED( "Buffer UAV type is not correct" ); + } + } + + D3D12BuffDesc.CPUAccessFlags = CPUAccessFlagsToD3D12CPUAccessFlags( BuffDesc.CPUAccessFlags ); + + D3D12_SUBRESOURCE_DATA InitData; + InitData.pSysMem = BuffData.pData; + InitData.SysMemPitch = BuffData.DataSize; + InitData.SysMemSlicePitch = 0; + + auto *pDeviceD3D12 = pRenderDeviceD3D12->GetD3D12Device(); + CHECK_D3D_RESULT_THROW( pDeviceD3D12->CreateBuffer(&D3D12BuffDesc, InitData.pSysMem ? &InitData : nullptr, &m_pD3D12Buffer), + "Failed to create the Direct3D11 buffer" ); +#endif +} + +BufferD3D12Impl :: ~BufferD3D12Impl() +{ + // D3D12 object can only be destroyed when it is no longer used by the GPU + auto *pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice()); + pDeviceD3D12Impl->SafeReleaseD3D12Object(m_pd3d12Resource); +} + +IMPLEMENT_QUERY_INTERFACE( BufferD3D12Impl, IID_BufferD3D12, TBufferBase ) + +void BufferD3D12Impl::UpdateData( IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData ) +{ + TBufferBase::UpdateData( pContext, Offset, Size, pData ); + + // We must use cmd context from the device context provided, otherwise there will + // be resource barrier issues in the cmd list in the device context + auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext); + pDeviceContextD3D12->UpdateBufferRegion(this, pData, Offset, Size); +} + +void BufferD3D12Impl :: CopyData(IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size) +{ + TBufferBase::CopyData( pContext, pSrcBuffer, SrcOffset, DstOffset, Size ); + auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext); + pDeviceContextD3D12->CopyBufferRegion(ValidatedCast<BufferD3D12Impl>(pSrcBuffer), this, SrcOffset, DstOffset, Size); +} + +void BufferD3D12Impl :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +{ + TBufferBase::Map( pContext, MapType, MapFlags, pMappedData ); + auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext); +#ifdef _DEBUG + m_DbgMapType[pDeviceContextD3D12->GetContextId()] = MapType; +#endif + if (MapType == MAP_READ ) + { + LOG_WARNING_MESSAGE_ONCE("Mapping CPU buffer for reading on D3D12 currently requires flushing context and idling GPU"); + pDeviceContextD3D12->Flush(); + auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice()); + pDeviceD3D12->IdleGPU(); + + VERIFY(m_Desc.Usage == USAGE_CPU_ACCESSIBLE, "Buffer must be created as USAGE_CPU_ACCESSIBLE to be mapped for reading") + D3D12_RANGE MapRange; + MapRange.Begin = 0; + MapRange.End = m_Desc.uiSizeInBytes; + m_pd3d12Resource->Map(0, &MapRange, &pMappedData); + } + else if(MapType == MAP_WRITE_DISCARD) + { + auto *pCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext); + auto ContextId = pDeviceContextD3D12->GetContextId(); + m_DynamicData[ContextId] = pCtxD3D12->AllocateDynamicSpace(m_Desc.uiSizeInBytes); + pMappedData = m_DynamicData[ContextId].CPUAddress; + } + else if(MapType == MAP_READ_WRITE || MapType == MAP_WRITE) + { + LOG_ERROR("D3D12 allows writing to CPU-readable buffer, but it is not accessable by GPU") + } + else + { + LOG_ERROR("Only MAP_WRITE_DISCARD and MAP_READ are currently implemented in D3D12") + } +} + +void BufferD3D12Impl::Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) +{ + TBufferBase::Unmap( pContext, MapType ); + auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext); + auto CtxId = pDeviceContextD3D12->GetContextId(); +#ifdef _DEBUG + VERIFY(m_DbgMapType[CtxId] == MapType, "Map type provided does not match the type provided to Map()" ); +#endif + + if (MapType == MAP_READ ) + { + D3D12_RANGE MapRange; + // It is valid to specify the CPU didn't write any data by passing a range where End is less than or equal to Begin. + MapRange.Begin = 1; + MapRange.End = 0; + m_pd3d12Resource->Unmap(0, &MapRange); + } + else if(MapType == MAP_WRITE_DISCARD) + { + // Nothing needs to be done. + } +#ifdef _DEBUG + m_DbgMapType[CtxId] = static_cast<MAP_TYPE>(-1); +#endif +} + +void BufferD3D12Impl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBufferView **ppView, bool bIsDefaultView ) +{ + VERIFY( ppView != nullptr, "Null pointer provided" ); + if( !ppView )return; + VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + + *ppView = nullptr; + + try + { + auto *pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice()); + auto &BuffViewAllocator = pDeviceD3D12Impl->GetBuffViewObjAllocator(); + VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" ); + + BufferViewDesc ViewDesc = OrigViewDesc; + if( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS ) + { + auto UAVHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + CreateUAV( ViewDesc, UAVHandleAlloc.GetCpuHandle() ); + *ppView = NEW(BuffViewAllocator, "BufferViewD3D12Impl instance", BufferViewD3D12Impl, GetDevice(), ViewDesc, this, std::move(UAVHandleAlloc), bIsDefaultView ); + } + else if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE ) + { + auto SRVHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + CreateSRV( ViewDesc, SRVHandleAlloc.GetCpuHandle() ); + *ppView = NEW(BuffViewAllocator, "BufferViewD3D12Impl instance", BufferViewD3D12Impl, GetDevice(), ViewDesc, this, std::move(SRVHandleAlloc), bIsDefaultView ); + } + + if( !bIsDefaultView && *ppView ) + (*ppView)->AddRef(); + } + catch( const std::runtime_error & ) + { + const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType); + LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name, "\"" ) + } +} + +void BufferD3D12Impl::CreateUAV( BufferViewDesc &UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVDescriptor ) +{ + CorrectBufferViewDesc( UAVDesc ); + + D3D12_UNORDERED_ACCESS_VIEW_DESC D3D12_UAVDesc; + BufferViewDesc_to_D3D12_UAV_DESC(m_Desc, UAVDesc, D3D12_UAVDesc); + + auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device(); + pDeviceD3D12->CreateUnorderedAccessView( m_pd3d12Resource, nullptr, &D3D12_UAVDesc, UAVDescriptor ); +} + +void BufferD3D12Impl::CreateSRV( struct BufferViewDesc &SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVDescriptor ) +{ + CorrectBufferViewDesc( SRVDesc ); + + D3D12_SHADER_RESOURCE_VIEW_DESC D3D12_SRVDesc; + BufferViewDesc_to_D3D12_SRV_DESC(m_Desc, SRVDesc, D3D12_SRVDesc); + + auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device(); + pDeviceD3D12->CreateShaderResourceView( m_pd3d12Resource, &D3D12_SRVDesc, SRVDescriptor ); +} + +void BufferD3D12Impl::CreateCBV(D3D12_CPU_DESCRIPTOR_HANDLE CBVDescriptor) +{ + D3D12_CONSTANT_BUFFER_VIEW_DESC D3D12_CBVDesc; + D3D12_CBVDesc.BufferLocation = m_pd3d12Resource->GetGPUVirtualAddress(); + D3D12_CBVDesc.SizeInBytes = m_Desc.uiSizeInBytes; + + auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device(); + pDeviceD3D12->CreateConstantBufferView( &D3D12_CBVDesc, CBVDescriptor ); +} + +#ifdef _DEBUG +void BufferD3D12Impl::DbgVerifyDynamicAllocation(Uint32 ContextId) +{ + VERIFY(m_DynamicData[ContextId].GPUAddress != 0, "Dynamic buffer must be mapped before the first use"); + auto CurrentFrame = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice())->GetCurrentFrame(); + VERIFY(m_DynamicData[ContextId].FrameNum == CurrentFrame, "Dynamic allocation is out-of-date. Dynamic buffer must be mapped in the same frame it is used."); + VERIFY(GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers are expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state") +} +#endif + + +} diff --git a/Graphics/GraphicsEngineD3D12/src/BufferViewD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferViewD3D12Impl.cpp new file mode 100644 index 00000000..e27c91ea --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/BufferViewD3D12Impl.cpp @@ -0,0 +1,43 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BufferViewD3D12Impl.h" + +namespace Diligent +{ + +BufferViewD3D12Impl::BufferViewD3D12Impl( FixedBlockMemoryAllocator &BuffViewAllocator, + IRenderDevice *pDevice, + const BufferViewDesc& ViewDesc, + IBuffer *pBuffer, + DescriptorHeapAllocation &&HandleAlloc, + bool bIsDefaultView ) : + TBufferViewBase( BuffViewAllocator, pDevice, ViewDesc, pBuffer, bIsDefaultView ), + m_DescriptorHandle( std::move(HandleAlloc) ) +{ +} + +IMPLEMENT_QUERY_INTERFACE( BufferViewD3D12Impl, IID_BufferViewD3D12, TBufferViewBase ) + +} diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp new file mode 100644 index 00000000..c123993f --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp @@ -0,0 +1,449 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// +// Adapted to Diligent Engine: Egor Yusov +// + +#include "pch.h" +#include "CommandContext.h" +#include "TextureD3D12Impl.h" +#include "BufferD3D12Impl.h" +#include "CommandListManager.h" + +namespace Diligent +{ + +CommandContext::CommandContext( IMemoryAllocator &MemAllocator, + CommandListManager &CmdListManager, + GPUDescriptorHeap GPUDescriptorHeaps[], + Uint32 DynamicDescriptorAllocationChunkSize[]) : + m_pCurGraphicsRootSignature( nullptr), + m_pCurGraphicsPipelineState( nullptr), + m_pCurComputeRootSignature( nullptr), + m_pCurComputePipelineState( nullptr), + m_DynamicGPUDescriptorAllocator + { + {MemAllocator, GPUDescriptorHeaps[0], DynamicDescriptorAllocationChunkSize[0]}, + {MemAllocator, GPUDescriptorHeaps[1], DynamicDescriptorAllocationChunkSize[1]} + }, + m_PendingResourceBarriers( STD_ALLOCATOR_RAW_MEM(D3D12_RESOURCE_BARRIER, GetRawAllocator(), "Allocator for vector<D3D12_RESOURCE_BARRIER>") ), + m_PendingBarrierObjects( STD_ALLOCATOR_RAW_MEM(RefCntAutoPtr<IDeviceObject>, GetRawAllocator(), "Allocator for vector<RefCntAutoPtr<IDeviceObject>>") ) +{ + m_PendingResourceBarriers.reserve(MaxPendingBarriers); + m_PendingBarrierObjects.reserve(MaxPendingBarriers); + + CmdListManager.CreateNewCommandList(&m_pCommandList, &m_pCurrentAllocator); +} + +CommandContext::~CommandContext( void ) +{ +} + + + +void CommandContext::Reset( CommandListManager& CmdListManager ) +{ + // We only call Reset() on previously freed contexts. The command list persists, but we must + // request a new allocator. + VERIFY_EXPR(m_pCommandList != nullptr && m_pCurrentAllocator == nullptr); + m_pCurrentAllocator.Release(); + CmdListManager.RequestAllocator(&m_pCurrentAllocator); + m_pCommandList->Reset(m_pCurrentAllocator, nullptr); + + m_pCurGraphicsRootSignature = nullptr; + m_pCurGraphicsPipelineState = nullptr; + m_pCurComputeRootSignature = nullptr; + m_pCurComputePipelineState = nullptr; + m_PendingResourceBarriers.clear(); + m_PendingBarrierObjects.clear(); + m_BoundDescriptorHeaps = ShaderDescriptorHeaps(); + + m_PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; +#if 0 + BindDescriptorHeaps(); +#endif +} + +ID3D12GraphicsCommandList* CommandContext::Close(ID3D12CommandAllocator **ppAllocator) +{ + FlushResourceBarriers(); + + //if (m_ID.length() > 0) + // EngineProfiling::EndBlock(this); + + VERIFY_EXPR(m_pCurrentAllocator != nullptr); + auto hr = m_pCommandList->Close(); + VERIFY(SUCCEEDED(hr), "Failed to close the command list"); + + *ppAllocator = m_pCurrentAllocator.Detach(); + return m_pCommandList; +} + + +#if 0 +void CommandContext::BindDescriptorHeaps( void ) +{ + UINT NonNullHeaps = 0; + ID3D12DescriptorHeap* HeapsToBind[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + for (UINT i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i) + { + ID3D12DescriptorHeap* HeapIter = m_CurrentDescriptorHeaps[i]; + if (HeapIter != nullptr) + HeapsToBind[NonNullHeaps++] = HeapIter; + } + + if (NonNullHeaps > 0) + m_pCommandList->SetDescriptorHeaps(NonNullHeaps, HeapsToBind); +} +#endif + +void GraphicsContext::SetRenderTargets( UINT NumRTVs, ITextureViewD3D12** ppRTVs, ITextureViewD3D12* pDSV ) +{ + D3D12_CPU_DESCRIPTOR_HANDLE RTVHandles[8]; // Do not waste time initializing array to zero + + for (UINT i = 0; i < NumRTVs; ++i) + { + auto *pRTV = ppRTVs[i]; + if( pRTV ) + { + auto *pTexture = ValidatedCast<TextureD3D12Impl>( pRTV->GetTexture() ); + TransitionResource(pTexture, D3D12_RESOURCE_STATE_RENDER_TARGET); + RTVHandles[i] = pRTV->GetCPUDescriptorHandle(); + } + } + + if (pDSV) + { + auto *pTexture = ValidatedCast<TextureD3D12Impl>( pDSV->GetTexture() ); + //if (bReadOnlyDepth) + //{ + // TransitionResource(*pTexture, D3D12_RESOURCE_STATE_DEPTH_READ); + // m_pCommandList->OMSetRenderTargets( NumRTVs, RTVHandles, FALSE, &DSV->GetDSV_DepthReadOnly() ); + //} + //else + { + TransitionResource(pTexture, D3D12_RESOURCE_STATE_DEPTH_WRITE); + auto DSVHandle = pDSV->GetCPUDescriptorHandle(); + m_pCommandList->OMSetRenderTargets( NumRTVs, RTVHandles, FALSE, &DSVHandle ); + } + } + else + { + m_pCommandList->OMSetRenderTargets( NumRTVs, RTVHandles, FALSE, nullptr ); + } +} + +void CommandContext::ClearUAVFloat( ITextureViewD3D12 *pTexView, const float* Color ) +{ + auto *pTexture = ValidatedCast<TextureD3D12Impl>( pTexView->GetTexture() ); + TransitionResource(pTexture, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, true); + + // After binding a UAV, we can get a GPU handle that is required to clear it as a UAV (because it essentially runs + // a shader to set all of the values). + UNSUPPORTED("Not yet implemented"); + D3D12_GPU_DESCRIPTOR_HANDLE GpuVisibleHandle = {};//m_DynamicDescriptorHeap.UploadDirect(Target.GetUAV()); + m_pCommandList->ClearUnorderedAccessViewFloat(GpuVisibleHandle, pTexView->GetCPUDescriptorHandle(), pTexture->GetD3D12Resource(), Color, 0, nullptr); +} + +void CommandContext::ClearUAVUint( ITextureViewD3D12 *pTexView, const UINT *Color ) +{ + auto *pTexture = ValidatedCast<TextureD3D12Impl>( pTexView->GetTexture() ); + TransitionResource(pTexture, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, true); + + // After binding a UAV, we can get a GPU handle that is required to clear it as a UAV (because it essentially runs + // a shader to set all of the values). + UNSUPPORTED("Not yet implemented"); + D3D12_GPU_DESCRIPTOR_HANDLE GpuVisibleHandle = {};//m_DynamicDescriptorHeap.UploadDirect(Target.GetUAV()); + //CD3DX12_RECT ClearRect(0, 0, (LONG)Target.GetWidth(), (LONG)Target.GetHeight()); + + //TODO: My Nvidia card is not clearing UAVs with either Float or Uint variants. + m_pCommandList->ClearUnorderedAccessViewUint(GpuVisibleHandle, pTexView->GetCPUDescriptorHandle(), pTexture->GetD3D12Resource(), Color, 0, nullptr/*1, &ClearRect*/); +} + + +void GraphicsContext::ClearRenderTarget( ITextureViewD3D12 *pRTV, const float *Color ) +{ + auto *pTexture = ValidatedCast<TextureD3D12Impl>( pRTV->GetTexture() ); + TransitionResource(pTexture, D3D12_RESOURCE_STATE_RENDER_TARGET, true); + m_pCommandList->ClearRenderTargetView(pRTV->GetCPUDescriptorHandle(), Color, 0, nullptr); +} + +void GraphicsContext::ClearDepthStencil( ITextureViewD3D12 *pDSV, D3D12_CLEAR_FLAGS ClearFlags, float Depth, UINT8 Stencil ) +{ + auto *pTexture = ValidatedCast<TextureD3D12Impl>( pDSV->GetTexture() ); + TransitionResource( pTexture, D3D12_RESOURCE_STATE_DEPTH_WRITE, true); + m_pCommandList->ClearDepthStencilView(pDSV->GetCPUDescriptorHandle(), ClearFlags, Depth, Stencil, 0, nullptr); +} + + +void CommandContext::TransitionResource(ITextureD3D12 *pTexture, D3D12_RESOURCE_STATES NewState, bool FlushImmediate) +{ + VERIFY_EXPR( pTexture != nullptr ); + auto *pTexD3D12 = ValidatedCast<TextureD3D12Impl>(pTexture); + TransitionResource(*pTexD3D12, *pTexD3D12, NewState, FlushImmediate); +} + +void CommandContext::TransitionResource(IBufferD3D12 *pBuffer, D3D12_RESOURCE_STATES NewState, bool FlushImmediate) +{ + VERIFY_EXPR( pBuffer != nullptr ); + auto *pBuffD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffer); + +#ifdef _DEBUG + // Dynamic buffers are suballocated in the upload heap when Map() is called + // and must always be in D3D12_RESOURCE_STATE_GENERIC_READ state + if(pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC) + { + VERIFY(pBuffD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers are expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state") + VERIFY( (NewState & D3D12_RESOURCE_STATE_GENERIC_READ) == NewState, "Dynamic buffers can only transition to one of D3D12_RESOURCE_STATE_GENERIC_READ states") + } +#endif + + TransitionResource(*pBuffD3D12, *pBuffD3D12, NewState, FlushImmediate); + +#ifdef _DEBUG + if(pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC) + VERIFY(pBuffD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers are expected to never transition from D3D12_RESOURCE_STATE_GENERIC_READ state") +#endif +} + +void CommandContext::TransitionResource(D3D12ResourceBase& Resource, IDeviceObject &Object, D3D12_RESOURCE_STATES NewState, bool FlushImmediate) +{ + D3D12_RESOURCE_STATES OldState = Resource.GetState(); + + // Check if required state is already set + if ( (OldState & NewState) != NewState ) + { + // If both old state and new state are read-only states, combine the two + if( (OldState & D3D12_RESOURCE_STATE_GENERIC_READ) == OldState && + (NewState & D3D12_RESOURCE_STATE_GENERIC_READ) == NewState ) + NewState |= OldState; + + m_PendingResourceBarriers.emplace_back(); + m_PendingBarrierObjects.emplace_back(&Object); + D3D12_RESOURCE_BARRIER& BarrierDesc = m_PendingResourceBarriers.back(); + + BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + BarrierDesc.Transition.pResource = Resource.GetD3D12Resource(); + BarrierDesc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + BarrierDesc.Transition.StateBefore = OldState; + BarrierDesc.Transition.StateAfter = NewState; + + // Check to see if we already started the transition +#if 0 + if (NewState == Resource.m_TransitioningState) + { + BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_END_ONLY; + Resource.m_TransitioningState = (D3D12_RESOURCE_STATES)-1; + } + else +#endif + BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + + Resource.SetState( NewState ); + } + else if (NewState == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) + InsertUAVBarrier(Resource, Object, FlushImmediate); + + if (FlushImmediate || m_PendingResourceBarriers.size() >= MaxPendingBarriers) + FlushResourceBarriers(); +} + +#if 0 +void CommandContext::BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate) +{ + // If it's already transitioning, finish that transition + if (Resource.m_TransitioningState != (D3D12_RESOURCE_STATES)-1) + TransitionResource(Resource, Resource.m_TransitioningState); + + D3D12_RESOURCE_STATES OldState = Resource.m_UsageState; + + if (OldState != NewState) + { + ASSERT(m_NumBarriersToFlush < 16, "Exceeded arbitrary limit on buffered barriers"); + D3D12_RESOURCE_BARRIER& BarrierDesc = m_ResourceBarrierBuffer[m_NumBarriersToFlush++]; + + BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + BarrierDesc.Transition.pResource = Resource.GetResource(); + BarrierDesc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + BarrierDesc.Transition.StateBefore = OldState; + BarrierDesc.Transition.StateAfter = NewState; + + BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY; + + Resource.m_TransitioningState = NewState; + } + + if (FlushImmediate || m_NumBarriersToFlush == 16) + { + m_pCommandList->ResourceBarrier(m_NumBarriersToFlush, m_ResourceBarrierBuffer); + m_NumBarriersToFlush = 0; + } +} +#endif + +void CommandContext::FlushResourceBarriers() +{ + if (m_PendingResourceBarriers.empty()) + { + VERIFY_EXPR(m_PendingBarrierObjects.empty()); + return; + } + + m_pCommandList->ResourceBarrier(static_cast<UINT>(m_PendingResourceBarriers.size()), m_PendingResourceBarriers.data()); + m_PendingResourceBarriers.clear(); + m_PendingBarrierObjects.clear(); +} + + +void CommandContext::InsertUAVBarrier(D3D12ResourceBase& Resource, IDeviceObject &Object, bool FlushImmediate) +{ + m_PendingResourceBarriers.emplace_back(); + m_PendingBarrierObjects.emplace_back(&Object); + D3D12_RESOURCE_BARRIER& BarrierDesc = m_PendingResourceBarriers.back(); + + BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + BarrierDesc.UAV.pResource = Resource.GetD3D12Resource(); + + if (FlushImmediate) + FlushResourceBarriers(); +} + +void CommandContext::InsertAliasBarrier(D3D12ResourceBase& Before, D3D12ResourceBase& After, IDeviceObject &BeforeObj, IDeviceObject &AfterObj, bool FlushImmediate) +{ + m_PendingResourceBarriers.emplace_back(); + m_PendingBarrierObjects.emplace_back(&BeforeObj); + m_PendingBarrierObjects.emplace_back(&AfterObj); + D3D12_RESOURCE_BARRIER& BarrierDesc = m_PendingResourceBarriers.back(); + + BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + BarrierDesc.Aliasing.pResourceBefore = Before.GetD3D12Resource(); + BarrierDesc.Aliasing.pResourceAfter = After.GetD3D12Resource(); + + if (FlushImmediate) + FlushResourceBarriers(); +} + +void CommandContext::DiscardUsedDescriptorHeaps(Uint64 FrameNumber) +{ + for(size_t HeapType = 0; HeapType < _countof(m_DynamicGPUDescriptorAllocator); ++HeapType) + m_DynamicGPUDescriptorAllocator[HeapType].DiscardAllocations(FrameNumber); +} + +DescriptorHeapAllocation CommandContext::AllocateDynamicGPUVisibleDescriptor( D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count ) +{ + VERIFY(Type >= D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && Type <= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type"); + return m_DynamicGPUDescriptorAllocator[Type].Allocate(Count); +} + +#if 0 + +void CommandContext::FillBuffer( GpuResource& Dest, size_t DestOffset, DWParam Value, size_t NumBytes ) +{ + DynAlloc TempSpace = m_CpuLinearAllocator.Allocate( NumBytes, 512 ); + __m128 VectorValue = _mm_set1_ps(Value.Float); + SIMDMemFill(TempSpace.DataPtr, VectorValue, Math::DivideByMultiple(NumBytes, 16)); + CopyBufferRegion(Dest, DestOffset, TempSpace.Buffer, TempSpace.Offset, NumBytes ); +} + +void CommandContext::CopySubresource(GpuResource& Dest, UINT DestSubIndex, GpuResource& Src, UINT SrcSubIndex) +{ + // TODO: Add a TransitionSubresource()? + TransitionResource(Dest, D3D12_RESOURCE_STATE_COPY_DEST); + TransitionResource(Src, D3D12_RESOURCE_STATE_COPY_SOURCE); + FlushResourceBarriers(); + + D3D12_TEXTURE_COPY_LOCATION DestLocation = + { + Dest.GetResource(), + D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, + DestSubIndex + }; + + D3D12_TEXTURE_COPY_LOCATION SrcLocation = + { + Src.GetResource(), + D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, + SrcSubIndex + }; + + m_pCommandList->CopyTextureRegion(&DestLocation, 0, 0, 0, &SrcLocation, nullptr); +} + +void CommandContext::InitializeTextureArraySlice(GpuResource& Dest, UINT SliceIndex, GpuResource& Src) +{ + CommandContext& Context = CommandContext::Begin(); + + Context.TransitionResource(Dest, D3D12_RESOURCE_STATE_COPY_DEST); + Context.TransitionResource(Src, D3D12_RESOURCE_STATE_COPY_SOURCE); + Context.FlushResourceBarriers(); + + const D3D12_RESOURCE_DESC& DestDesc = Dest.GetResource()->GetDesc(); + const D3D12_RESOURCE_DESC& SrcDesc = Src.GetResource()->GetDesc(); + + ASSERT(SliceIndex < DestDesc.DepthOrArraySize && + SrcDesc.DepthOrArraySize == 1 && + DestDesc.Width == SrcDesc.Width && + DestDesc.Height == SrcDesc.Height && + DestDesc.MipLevels <= SrcDesc.MipLevels + ); + + UINT SubResourceIndex = SliceIndex * DestDesc.MipLevels; + + for (UINT i = 0; i < DestDesc.MipLevels; ++i) + { + D3D12_TEXTURE_COPY_LOCATION destCopyLocation = + { + Dest.GetResource(), + D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, + SubResourceIndex + i + }; + + D3D12_TEXTURE_COPY_LOCATION srcCopyLocation = + { + Src.GetResource(), + D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, + i + }; + + Context.m_pCommandList->CopyTextureRegion(&destCopyLocation, 0, 0, 0, &srcCopyLocation, nullptr); + } + + Context.CloseAndExecute(); +} +#endif + +} diff --git a/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp new file mode 100644 index 00000000..8ffc64ce --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp @@ -0,0 +1,106 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// +// Adapted to Diligent Engine: Egor Yusov + +#include "pch.h" +#include "CommandListManager.h" +#include "RenderDeviceD3D12Impl.h" + +namespace Diligent +{ + +CommandListManager::CommandListManager(RenderDeviceD3D12Impl *pDeviceD3D12) : + m_pDeviceD3D12(pDeviceD3D12), + m_DiscardedAllocators(STD_ALLOCATOR_RAW_MEM(DiscardedAllocatorQueueElemType, GetRawAllocator(), "Allocator for deque<DiscardedAllocatorQueueElemType>")) +{ +} + +CommandListManager::~CommandListManager() +{ +} + + +void CommandListManager::CreateNewCommandList( ID3D12GraphicsCommandList** List, ID3D12CommandAllocator** Allocator ) +{ + RequestAllocator(Allocator); + auto *pd3d12Device = m_pDeviceD3D12->GetD3D12Device(); + auto hr = pd3d12Device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, *Allocator, nullptr, __uuidof(*List), reinterpret_cast<void**>(List) ); + VERIFY(SUCCEEDED(hr), "Failed to create command list"); + (*List)->SetName(L"CommandList"); +} + + +void CommandListManager::RequestAllocator(ID3D12CommandAllocator** ppAllocator) +{ + std::lock_guard<std::mutex> LockGuard(m_AllocatorMutex); + + VERIFY( (*ppAllocator) == nullptr, "Allocator pointer is not null" ); + (*ppAllocator) = nullptr; + + if (!m_DiscardedAllocators.empty()) + { + auto& AllocatorPair = m_DiscardedAllocators.front(); + + if (m_pDeviceD3D12->IsFenceComplete(AllocatorPair.first)) + { + *ppAllocator = AllocatorPair.second.Detach(); + auto hr = (*ppAllocator)->Reset(); + VERIFY_EXPR(SUCCEEDED(hr)); + m_DiscardedAllocators.pop_front(); + } + } + + // If no allocators were ready to be reused, create a new one + if ((*ppAllocator) == nullptr) + { + auto *pd3d12Device = m_pDeviceD3D12->GetD3D12Device(); + auto hr = pd3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(*ppAllocator), reinterpret_cast<void**>(ppAllocator)); + VERIFY(SUCCEEDED(hr), "Failed to create command allocator") + //wchar_t AllocatorName[32]; + //swprintf(AllocatorName, 32, L"CommandAllocator %zu", m_AllocatorPool.size()); + //(*ppAllocator)->SetName(AllocatorName); + } +} + +void CommandListManager::DiscardAllocator( Uint64 FenceValue, ID3D12CommandAllocator* pAllocator ) +{ + std::lock_guard<std::mutex> LockGuard(m_AllocatorMutex); + + // That fence value indicates we are free to reset the allocator + m_DiscardedAllocators.emplace_back( FenceValue, CComPtr<ID3D12CommandAllocator>(pAllocator) ); +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12ResourceBase.cpp index fd0f1734..b2e9f431 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12ResourceBase.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,21 +22,9 @@ */ #include "pch.h" -#include "BlendStateGLImpl.h" -#include "RenderDeviceGLImpl.h" +#include "D3D12ResourceBase.h" namespace Diligent { -BlendStateGLImpl::BlendStateGLImpl(class IRenderDevice *pDeviceGL, const BlendStateDesc& BlendStateDesc, bool bIsDeviceInternal) : - TBlendStateBase(pDeviceGL, BlendStateDesc, bIsDeviceInternal) -{ -} - -BlendStateGLImpl::~BlendStateGLImpl() -{ -} - -IMPLEMENT_QUERY_INTERFACE( BlendStateGLImpl, IID_BlendStateGL, TBlendStateBase ) - } diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp new file mode 100644 index 00000000..738fbc98 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -0,0 +1,295 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "D3D12TypeConversions.h" +#include "DXGITypeConversions.h" + +#include "D3D12TypeDefinitions.h" +#include "D3DTypeConversionImpl.h" +#include "D3DViewDescConversionImpl.h" + +namespace Diligent +{ + +D3D12_COMPARISON_FUNC ComparisonFuncToD3D12ComparisonFunc(COMPARISON_FUNCTION Func) +{ + return ComparisonFuncToD3DComparisonFunc<D3D12_COMPARISON_FUNC>(Func); +} + +D3D12_FILTER FilterTypeToD3D12Filter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter) +{ + return FilterTypeToD3DFilter<D3D12_FILTER>(MinFilter, MagFilter, MipFilter); +} + +D3D12_TEXTURE_ADDRESS_MODE TexAddressModeToD3D12AddressMode(TEXTURE_ADDRESS_MODE Mode) +{ + return TexAddressModeToD3DAddressMode<D3D12_TEXTURE_ADDRESS_MODE>(Mode); +} + +void DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(const DepthStencilStateDesc &DepthStencilDesc, D3D12_DEPTH_STENCIL_DESC &d3d12DSSDesc) +{ + DepthStencilStateDesc_To_D3D_DEPTH_STENCIL_DESC<D3D12_DEPTH_STENCIL_DESC, D3D12_DEPTH_STENCILOP_DESC, D3D12_STENCIL_OP, D3D12_COMPARISON_FUNC>(DepthStencilDesc, d3d12DSSDesc); +} + +void RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(const RasterizerStateDesc &RasterizerDesc, D3D12_RASTERIZER_DESC &d3d12RSDesc) +{ + RasterizerStateDesc_To_D3D_RASTERIZER_DESC<D3D12_RASTERIZER_DESC, D3D12_FILL_MODE, D3D12_CULL_MODE>(RasterizerDesc, d3d12RSDesc); + + // The sample count that is forced while UAV rendering or rasterizing. + // Valid values are 0, 1, 2, 4, 8, and optionally 16. 0 indicates that + // the sample count is not forced. + d3d12RSDesc.ForcedSampleCount = 0; + + d3d12RSDesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; +} + + + +D3D12_LOGIC_OP LogicOperationToD3D12LogicOp( LOGIC_OPERATION lo ) +{ + // Note that this code is safe for multithreaded environments since + // bIsInit is set to true only AFTER the entire map is initialized. + static bool bIsInit = false; + static D3D12_LOGIC_OP D3D12LogicOp[LOGIC_OP_NUM_OPERATIONS] = {}; + if( !bIsInit ) + { + // In a multithreaded environment, several threads can potentially enter + // this block. This is not a problem since they will just initialize the + // memory with the same values more than once + D3D12LogicOp[ D3D12_LOGIC_OP_CLEAR ] = D3D12_LOGIC_OP_CLEAR; + D3D12LogicOp[ D3D12_LOGIC_OP_SET ] = D3D12_LOGIC_OP_SET; + D3D12LogicOp[ D3D12_LOGIC_OP_COPY ] = D3D12_LOGIC_OP_COPY; + D3D12LogicOp[ D3D12_LOGIC_OP_COPY_INVERTED ] = D3D12_LOGIC_OP_COPY_INVERTED; + D3D12LogicOp[ D3D12_LOGIC_OP_NOOP ] = D3D12_LOGIC_OP_NOOP; + D3D12LogicOp[ D3D12_LOGIC_OP_INVERT ] = D3D12_LOGIC_OP_INVERT; + D3D12LogicOp[ D3D12_LOGIC_OP_AND ] = D3D12_LOGIC_OP_AND; + D3D12LogicOp[ D3D12_LOGIC_OP_NAND ] = D3D12_LOGIC_OP_NAND; + D3D12LogicOp[ D3D12_LOGIC_OP_OR ] = D3D12_LOGIC_OP_OR; + D3D12LogicOp[ D3D12_LOGIC_OP_NOR ] = D3D12_LOGIC_OP_NOR; + D3D12LogicOp[ D3D12_LOGIC_OP_XOR ] = D3D12_LOGIC_OP_XOR; + D3D12LogicOp[ D3D12_LOGIC_OP_EQUIV ] = D3D12_LOGIC_OP_EQUIV; + D3D12LogicOp[ D3D12_LOGIC_OP_AND_REVERSE ] = D3D12_LOGIC_OP_AND_REVERSE; + D3D12LogicOp[ D3D12_LOGIC_OP_AND_INVERTED ] = D3D12_LOGIC_OP_AND_INVERTED; + D3D12LogicOp[ D3D12_LOGIC_OP_OR_REVERSE ] = D3D12_LOGIC_OP_OR_REVERSE; + D3D12LogicOp[ D3D12_LOGIC_OP_OR_INVERTED ] = D3D12_LOGIC_OP_OR_INVERTED; + + bIsInit = true; + } + if( lo >= LOGIC_OP_CLEAR && lo < LOGIC_OP_NUM_OPERATIONS ) + { + auto d3dlo = D3D12LogicOp[lo]; + return d3dlo; + } + else + { + UNEXPECTED("Incorrect blend factor (", lo, ")" ) + return static_cast<D3D12_LOGIC_OP>( 0 ); + } +} + + +void BlendStateDesc_To_D3D12_BLEND_DESC(const BlendStateDesc &BSDesc, D3D12_BLEND_DESC &d3d12BlendDesc) +{ + BlendStateDescToD3DBlendDesc<D3D12_BLEND_DESC, D3D12_BLEND, D3D12_BLEND_OP>(BSDesc, d3d12BlendDesc); + + for( int i = 0; i < 8; ++i ) + { + const auto& SrcRTDesc = BSDesc.RenderTargets[i]; + auto &DstRTDesc = d3d12BlendDesc.RenderTarget[i]; + + // The following members only present in D3D_RENDER_TARGET_BLEND_DESC + DstRTDesc.LogicOpEnable = SrcRTDesc.LogicOperationEnable ? TRUE : FALSE; + DstRTDesc.LogicOp = LogicOperationToD3D12LogicOp(SrcRTDesc.LogicOp); + } +} + +void LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(const std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement>> &LayoutElements, + std::vector<D3D12_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D12_INPUT_ELEMENT_DESC> > &d3d12InputElements) +{ + LayoutElements_To_D3D_INPUT_ELEMENT_DESCs<D3D12_INPUT_ELEMENT_DESC>(LayoutElements, d3d12InputElements); +} + +D3D12_PRIMITIVE_TOPOLOGY TopologyToD3D12Topology(PRIMITIVE_TOPOLOGY Topology) +{ + return TopologyToD3DTopology<D3D12_PRIMITIVE_TOPOLOGY>(Topology); +} + + + +void TextureViewDesc_to_D3D12_SRV_DESC(const TextureViewDesc& SRVDesc, D3D12_SHADER_RESOURCE_VIEW_DESC &D3D12SRVDesc, Uint32 SampleCount) +{ + TextureViewDesc_to_D3D_SRV_DESC(SRVDesc, D3D12SRVDesc, SampleCount); + D3D12SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + switch (SRVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + D3D12SRVDesc.Texture1D.ResourceMinLODClamp = 0; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + D3D12SRVDesc.Texture1DArray.ResourceMinLODClamp = 0; + break; + + case RESOURCE_DIM_TEX_2D: + if( SampleCount > 1 ) + { + } + else + { + D3D12SRVDesc.Texture2D.PlaneSlice = 0; + D3D12SRVDesc.Texture2D.ResourceMinLODClamp = 0; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if( SampleCount > 1 ) + { + } + else + { + D3D12SRVDesc.Texture2DArray.PlaneSlice = 0; + D3D12SRVDesc.Texture2DArray.ResourceMinLODClamp = 0; + } + break; + + case RESOURCE_DIM_TEX_3D: + D3D12SRVDesc.Texture3D.ResourceMinLODClamp = 0; + break; + + case RESOURCE_DIM_TEX_CUBE: + D3D12SRVDesc.TextureCube.ResourceMinLODClamp = 0; + break; + + case RESOURCE_DIM_TEX_CUBE_ARRAY: + D3D12SRVDesc.TextureCubeArray.ResourceMinLODClamp = 0; + break; + + default: + UNEXPECTED( "Unexpected view type" ); + } +} + +void TextureViewDesc_to_D3D12_RTV_DESC(const TextureViewDesc& RTVDesc, D3D12_RENDER_TARGET_VIEW_DESC &D3D12RTVDesc, Uint32 SampleCount) +{ + TextureViewDesc_to_D3D_RTV_DESC(RTVDesc, D3D12RTVDesc, SampleCount); + switch (RTVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + break; + + case RESOURCE_DIM_TEX_2D: + if( SampleCount > 1 ) + { + } + else + { + D3D12RTVDesc.Texture2D.PlaneSlice = 0; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if( SampleCount > 1 ) + { + } + else + { + D3D12RTVDesc.Texture2DArray.PlaneSlice = 0; + } + break; + + case RESOURCE_DIM_TEX_3D: + break; + + default: + UNEXPECTED( "Unexpected view type" ); + } +} + +void TextureViewDesc_to_D3D12_DSV_DESC(const TextureViewDesc& DSVDesc, D3D12_DEPTH_STENCIL_VIEW_DESC &D3D12DSVDesc, Uint32 SampleCount) +{ + TextureViewDesc_to_D3D_DSV_DESC(DSVDesc, D3D12DSVDesc, SampleCount); + D3D12DSVDesc.Flags = D3D12_DSV_FLAG_NONE; +} + +void TextureViewDesc_to_D3D12_UAV_DESC(const TextureViewDesc& UAVDesc, D3D12_UNORDERED_ACCESS_VIEW_DESC &D3D12UAVDesc) +{ + TextureViewDesc_to_D3D_UAV_DESC(UAVDesc, D3D12UAVDesc); + switch (UAVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + break; + + case RESOURCE_DIM_TEX_2D: + D3D12UAVDesc.Texture2D.PlaneSlice = 0; + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + D3D12UAVDesc.Texture2DArray.PlaneSlice = 0; + break; + + case RESOURCE_DIM_TEX_3D: + break; + + default: + UNEXPECTED( "Unexpected view type" ); + } +} + + +void BufferViewDesc_to_D3D12_SRV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& SRVDesc, D3D12_SHADER_RESOURCE_VIEW_DESC &D3D12SRVDesc) +{ + BufferViewDesc_to_D3D_SRV_DESC(BuffDesc, SRVDesc, D3D12SRVDesc); + D3D12SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + D3D12SRVDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; +} + +void BufferViewDesc_to_D3D12_UAV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& UAVDesc, D3D12_UNORDERED_ACCESS_VIEW_DESC &D3D12UAVDesc) +{ + BufferViewDesc_to_D3D_UAV_DESC(BuffDesc, UAVDesc, D3D12UAVDesc); + D3D12UAVDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; +} + +D3D12_STATIC_BORDER_COLOR BorderColorToD3D12StaticBorderColor(const Float32 BorderColor[]) +{ + D3D12_STATIC_BORDER_COLOR StaticBorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; + if(BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 0) + StaticBorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; + else if(BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 1) + StaticBorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; + else if(BorderColor[0] == 1 && BorderColor[1] == 1 && BorderColor[2] == 1 && BorderColor[3] == 0) + StaticBorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE; + else + { + LOG_ERROR_MESSAGE("Static samplers only allow transparent black (0,0,0,1), opaque black (0,0,0,0) or opaque white (1,1,1,0) as border colors.") + } + return StaticBorderColor; +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12Utils.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12Utils.cpp new file mode 100644 index 00000000..a1f82e1c --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/D3D12Utils.cpp @@ -0,0 +1,45 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "D3D12Utils.h" + +namespace Diligent +{ + const Char* GetD3D12DescriptorHeapTypeLiteralName(D3D12_DESCRIPTOR_HEAP_TYPE Type) + { + static bool bIsInitialized = false; + static const Char* HeapTypeNames[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + if (!bIsInitialized) + { + HeapTypeNames[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = "D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV"; + HeapTypeNames[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = "D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER"; + HeapTypeNames[D3D12_DESCRIPTOR_HEAP_TYPE_RTV] = "D3D12_DESCRIPTOR_HEAP_TYPE_RTV"; + HeapTypeNames[D3D12_DESCRIPTOR_HEAP_TYPE_DSV] = "D3D12_DESCRIPTOR_HEAP_TYPE_DSV"; + + bIsInitialized = true; + } + VERIFY_EXPR(Type >= 0 && Type < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES); + return HeapTypeNames[Type]; + } +} diff --git a/Graphics/GraphicsEngineD3D12/src/DLLMain.cpp b/Graphics/GraphicsEngineD3D12/src/DLLMain.cpp new file mode 100644 index 00000000..fff890c0 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/DLLMain.cpp @@ -0,0 +1,49 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) +{ + switch( ul_reason_for_call ) + { + case DLL_PROCESS_ATTACH: + #if defined(_DEBUG) || defined(DEBUG) + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + #endif + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +}
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/src/DescriptorHeap.cpp b/Graphics/GraphicsEngineD3D12/src/DescriptorHeap.cpp new file mode 100644 index 00000000..02ea8384 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/DescriptorHeap.cpp @@ -0,0 +1,342 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "DescriptorHeap.h" +#include "RenderDeviceD3D12Impl.h" +#include "D3D12Utils.h" + +namespace Diligent +{ + + +DescriptorHeapAllocationManager::DescriptorHeapAllocationManager(IMemoryAllocator &Allocator, + RenderDeviceD3D12Impl *pDeviceD3D12Impl, + IDescriptorAllocator *pParentAllocator, + size_t ThisManagerId, + const D3D12_DESCRIPTOR_HEAP_DESC &HeapDesc) : + m_FreeBlockManager(HeapDesc.NumDescriptors, Allocator), + m_NumDescriptorsInAllocation(HeapDesc.NumDescriptors), + m_HeapDesc(HeapDesc), + m_pDeviceD3D12Impl(pDeviceD3D12Impl), + m_pParentAllocator(pParentAllocator), + m_ThisManagerId(ThisManagerId) +{ + auto pDevice = pDeviceD3D12Impl->GetD3D12Device(); + + m_FirstCPUHandle.ptr = 0; + m_FirstGPUHandle.ptr = 0; + m_DescriptorSize = pDevice->GetDescriptorHandleIncrementSize(HeapDesc.Type); + + pDevice->CreateDescriptorHeap(&m_HeapDesc, __uuidof(m_pd3d12DescriptorHeap), reinterpret_cast<void**>(static_cast<ID3D12DescriptorHeap**>(&m_pd3d12DescriptorHeap))); + m_FirstCPUHandle = m_pd3d12DescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + if(m_HeapDesc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) + m_FirstGPUHandle = m_pd3d12DescriptorHeap->GetGPUDescriptorHandleForHeapStart(); +} + +DescriptorHeapAllocationManager::DescriptorHeapAllocationManager(IMemoryAllocator &Allocator, + RenderDeviceD3D12Impl *pDeviceD3D12Impl, + IDescriptorAllocator *pParentAllocator, + size_t ThisManagerId, + ID3D12DescriptorHeap *pd3d12DescriptorHeap, + Uint32 FirstDescriptor, + Uint32 NumDescriptors): + m_FreeBlockManager(NumDescriptors, Allocator), + m_NumDescriptorsInAllocation(NumDescriptors), + m_pDeviceD3D12Impl(pDeviceD3D12Impl), + m_pParentAllocator(pParentAllocator), + m_ThisManagerId(ThisManagerId), + m_pd3d12DescriptorHeap(pd3d12DescriptorHeap) +{ + m_HeapDesc = m_pd3d12DescriptorHeap->GetDesc(); + m_DescriptorSize = pDeviceD3D12Impl->GetD3D12Device()->GetDescriptorHandleIncrementSize(m_HeapDesc.Type); + + m_FirstCPUHandle = pd3d12DescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + m_FirstCPUHandle.ptr += m_DescriptorSize * FirstDescriptor; + + if (m_HeapDesc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) + { + m_FirstGPUHandle = pd3d12DescriptorHeap->GetGPUDescriptorHandleForHeapStart(); + m_FirstGPUHandle.ptr += m_DescriptorSize * FirstDescriptor; + } +} + + +DescriptorHeapAllocationManager::~DescriptorHeapAllocationManager() +{ + VERIFY(m_FreeBlockManager.GetFreeSize() == m_NumDescriptorsInAllocation, "Not all descriptors were released"); +} + +DescriptorHeapAllocation DescriptorHeapAllocationManager::Allocate(uint32_t Count) +{ + std::lock_guard<std::mutex> LockGuard(m_AllocationMutex); + + auto DescriptorHandleOffset = m_FreeBlockManager.Allocate(Count); + if (DescriptorHandleOffset == FreeBlockListManagerGPU::InvalidOffset) + { + return DescriptorHeapAllocation(); + } + + auto CPUHandle = m_FirstCPUHandle; + CPUHandle.ptr += DescriptorHandleOffset * m_DescriptorSize; + + auto GPUHandle = m_FirstGPUHandle; + if(m_HeapDesc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) + GPUHandle.ptr += DescriptorHandleOffset * m_DescriptorSize; + + VERIFY(m_ThisManagerId < std::numeric_limits<Uint16>::max(), "ManagerID exceed allowed limit"); + DescriptorHeapAllocation Allocation( m_pParentAllocator, m_pd3d12DescriptorHeap, CPUHandle, GPUHandle, Count, static_cast<Uint16>(m_ThisManagerId)); + + return Allocation; +} + +void DescriptorHeapAllocationManager::Free(DescriptorHeapAllocation&& Allocation) +{ + std::lock_guard<std::mutex> LockGuard(m_AllocationMutex); + + VERIFY(Allocation.GetAllocationManagerId() == m_ThisManagerId, "Invalid descriptor heap manager Id") + + auto DescriptorOffset = (Allocation.GetCpuHandle().ptr - m_FirstCPUHandle.ptr) / m_DescriptorSize; + m_FreeBlockManager.Free(DescriptorOffset, Allocation.GetNumHandles(), m_pDeviceD3D12Impl->GetCurrentFrame()); + Allocation = DescriptorHeapAllocation(); +} + +void DescriptorHeapAllocationManager::ReleaseStaleAllocations(Uint64 NumCompletedFrames) +{ + m_FreeBlockManager.ReleaseCompletedFrames(NumCompletedFrames); +} + + + + +// +// CPUDescriptorHeap implementation +// +CPUDescriptorHeap::CPUDescriptorHeap(IMemoryAllocator &Allocator, RenderDeviceD3D12Impl *pDeviceD3D12Impl, Uint32 NumDescriptorsInHeap, D3D12_DESCRIPTOR_HEAP_TYPE Type, D3D12_DESCRIPTOR_HEAP_FLAGS Flags) : + m_pDeviceD3D12Impl(pDeviceD3D12Impl), + m_MemAllocator(Allocator), + m_HeapPool(STD_ALLOCATOR_RAW_MEM(DescriptorHeapAllocationManager, GetRawAllocator(), "Allocator for vector<DescriptorHeapAllocationManager>")), + m_AvailableHeaps(STD_ALLOCATOR_RAW_MEM(size_t, GetRawAllocator(), "Allocator for set<size_t>")) +{ + m_HeapDesc.Type = Type; + m_HeapDesc.NodeMask = 1; + m_HeapDesc.NumDescriptors = NumDescriptorsInHeap; + m_HeapDesc.Flags = Flags; + + m_DescriptorSize = m_pDeviceD3D12Impl->GetD3D12Device()->GetDescriptorHandleIncrementSize(Type); +} + +CPUDescriptorHeap::~CPUDescriptorHeap() +{ + VERIFY(m_CurrentSize == 0, "Not all allocations released" ); + + VERIFY(m_AvailableHeaps.size() == m_HeapPool.size(), "Not all descriptor heap pools are released"); + for (auto HeapPoolIt = m_HeapPool.begin(); HeapPoolIt != m_HeapPool.end(); ++HeapPoolIt) + { + VERIFY(HeapPoolIt->GetNumAvailableDescriptors() == m_HeapDesc.NumDescriptors, "Not all descriptors in the descriptor pool are released"); + } + + LOG_INFO_MESSAGE("Max ", GetD3D12DescriptorHeapTypeLiteralName(m_HeapDesc.Type), " CPU heap size: ", m_MaxHeapSize); +} + +DescriptorHeapAllocation CPUDescriptorHeap::Allocate( uint32_t Count ) +{ + std::lock_guard<std::mutex> LockGuard(m_AllocationMutex); + DescriptorHeapAllocation Allocation; + for (auto AvailableHeapIt = m_AvailableHeaps.begin(); AvailableHeapIt != m_AvailableHeaps.end(); ++AvailableHeapIt) + { + Allocation = m_HeapPool[*AvailableHeapIt].Allocate(Count); + if(m_HeapPool[*AvailableHeapIt].GetNumAvailableDescriptors() == 0) + m_AvailableHeaps.erase(*AvailableHeapIt); + + if(Allocation.GetCpuHandle().ptr != 0) + break; + } + + if(Allocation.GetCpuHandle().ptr == 0) + { + m_HeapPool.emplace_back(m_MemAllocator, m_pDeviceD3D12Impl, this, m_HeapPool.size(), m_HeapDesc); + auto NewHeapIt = m_AvailableHeaps.insert(m_HeapPool.size()-1); + + Allocation = m_HeapPool[*NewHeapIt.first].Allocate(Count); + } + + m_CurrentSize += (Allocation.GetCpuHandle().ptr != 0) ? Count : 0; + m_MaxHeapSize = std::max(m_MaxHeapSize, m_CurrentSize); + + return Allocation; +} + +void CPUDescriptorHeap::Free(DescriptorHeapAllocation&& Allocation) +{ + std::lock_guard<std::mutex> LockGuard(m_AllocationMutex); + auto ManagerId = Allocation.GetAllocationManagerId(); + m_CurrentSize -= static_cast<Uint32>(Allocation.GetNumHandles()); + m_HeapPool[ManagerId].Free(std::move(Allocation)); +} + +void CPUDescriptorHeap::ReleaseStaleAllocations(Uint64 NumCompletedFrames) +{ + std::lock_guard<std::mutex> LockGuard(m_AllocationMutex); + for (size_t HeapManagerInd = 0; HeapManagerInd < m_HeapPool.size(); ++HeapManagerInd) + { + m_HeapPool[HeapManagerInd].ReleaseStaleAllocations(NumCompletedFrames); + if(m_HeapPool[HeapManagerInd].GetNumAvailableDescriptors() > 0) + m_AvailableHeaps.insert(HeapManagerInd); + } +} + + + + +GPUDescriptorHeap::GPUDescriptorHeap(IMemoryAllocator &Allocator, + RenderDeviceD3D12Impl *pDevice, + Uint32 NumDescriptorsInHeap, + Uint32 NumDynamicDescriptors, + D3D12_DESCRIPTOR_HEAP_TYPE Type, + D3D12_DESCRIPTOR_HEAP_FLAGS Flags) : + m_pDeviceD3D12(pDevice), + m_HeapDesc + { + Type, + NumDescriptorsInHeap + NumDynamicDescriptors, + Flags, + 1 // UINT NodeMask; + }, + m_pd3d12DescriptorHeap([&]{ + CComPtr<ID3D12DescriptorHeap> pHeap; + pDevice->GetD3D12Device()->CreateDescriptorHeap(&m_HeapDesc, __uuidof(pHeap), reinterpret_cast<void**>(&pHeap)); + return pHeap; + }()), + m_DescriptorSize( pDevice->GetD3D12Device()->GetDescriptorHandleIncrementSize(Type) ), + m_HeapAllocationManager(Allocator, pDevice, this, 0, m_pd3d12DescriptorHeap, 0, NumDescriptorsInHeap), + m_DynamicAllocationsManager(Allocator, pDevice, this, 1, m_pd3d12DescriptorHeap, NumDescriptorsInHeap, NumDynamicDescriptors ) +{ +} + +GPUDescriptorHeap::~GPUDescriptorHeap() +{ + LOG_INFO_MESSAGE("Max ", GetD3D12DescriptorHeapTypeLiteralName(m_HeapDesc.Type), " GPU heap static/dynamic size: ", m_MaxHeapSize, "/", m_MaxDynamicSize); +} + +DescriptorHeapAllocation GPUDescriptorHeap::Allocate(uint32_t Count) +{ + std::lock_guard<std::mutex> LockGuard(m_Mutex); + DescriptorHeapAllocation Allocation = m_HeapAllocationManager.Allocate(Count); + + m_CurrentSize += (Allocation.GetCpuHandle().ptr != 0) ? Count : 0; + m_MaxHeapSize = std::max(m_MaxHeapSize, m_CurrentSize); + + return Allocation; +} + +DescriptorHeapAllocation GPUDescriptorHeap::AllocateDynamic(uint32_t Count) +{ + std::lock_guard<std::mutex> LockGuard(m_Mutex); + DescriptorHeapAllocation Allocation = m_DynamicAllocationsManager.Allocate(Count); + + m_CurrentDynamicSize += (Allocation.GetCpuHandle().ptr != 0) ? Count : 0; + m_MaxDynamicSize = std::max(m_MaxDynamicSize, m_CurrentDynamicSize); + + return Allocation; +} + +void GPUDescriptorHeap::Free(DescriptorHeapAllocation&& Allocation) +{ + auto MgrId = Allocation.GetAllocationManagerId(); + VERIFY(MgrId == 0 || MgrId == 1, "Unexpected allocation manager ID"); + + std::lock_guard<std::mutex> LockGuard(m_Mutex); + + if(MgrId == 0) + { + m_CurrentSize -= static_cast<Uint32>(Allocation.GetNumHandles()); + m_HeapAllocationManager.Free(std::move(Allocation)); + } + else + { + m_CurrentDynamicSize -= static_cast<Uint32>(Allocation.GetNumHandles()); + m_DynamicAllocationsManager.Free(std::move(Allocation)); + } +} + +void GPUDescriptorHeap::ReleaseStaleAllocations(Uint64 NumCompletedFrames) +{ + m_HeapAllocationManager.ReleaseStaleAllocations(NumCompletedFrames); + m_DynamicAllocationsManager.ReleaseStaleAllocations(NumCompletedFrames); +} + + + + + +DynamicSuballocationsManager::DynamicSuballocationsManager(IMemoryAllocator &Allocator, GPUDescriptorHeap& ParentGPUHeap, Uint32 DynamicChunkSize) : + m_ParentGPUHeap(ParentGPUHeap), + m_DynamicChunkSize(DynamicChunkSize), + m_Suballocations(STD_ALLOCATOR_RAW_MEM(DescriptorHeapAllocation, GetRawAllocator(), "Allocator for vector<DescriptorHeapAllocation>")) +{ +} + +void DynamicSuballocationsManager::DiscardAllocations(Uint64 FrameNumber) +{ + m_Suballocations.clear(); +} + +DescriptorHeapAllocation DynamicSuballocationsManager::Allocate(Uint32 Count) +{ + if( m_Suballocations.empty() || + m_CurrentSuballocationOffset + Count > m_Suballocations.back().GetNumHandles() ) + { + auto SuballocationSize = std::max(m_DynamicChunkSize, Count); + auto NewDynamicSubAllocation = m_ParentGPUHeap.AllocateDynamic(SuballocationSize); + if (NewDynamicSubAllocation.GetCpuHandle().ptr == 0) + { + LOG_ERROR_MESSAGE("Failed to suballocate region for dynamic descriptors") + return DescriptorHeapAllocation(); + } + m_Suballocations.emplace_back(std::move(NewDynamicSubAllocation)); + m_CurrentSuballocationOffset = 0; + } + + auto &CurrentSuballocation = m_Suballocations.back(); + + auto ManagerId = CurrentSuballocation.GetAllocationManagerId(); + VERIFY(ManagerId < std::numeric_limits<Uint16>::max(), "ManagerID exceed allowed limit"); + DescriptorHeapAllocation Allocation( this, + CurrentSuballocation.GetDescriptorHeap(), + CurrentSuballocation.GetCpuHandle(m_CurrentSuballocationOffset), + CurrentSuballocation.GetGpuHandle(m_CurrentSuballocationOffset), + Count, + static_cast<Uint16>(ManagerId) ); + m_CurrentSuballocationOffset += Count; + + return Allocation; +} + +void DynamicSuballocationsManager::Free(DescriptorHeapAllocation&& Allocation) +{ + // Do nothing + Allocation = DescriptorHeapAllocation(); +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp new file mode 100644 index 00000000..5ebfb4b4 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -0,0 +1,724 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "RenderDeviceD3D12Impl.h" +#include "DeviceContextD3D12Impl.h" +#include "SwapChainD3D12Impl.h" +#include "PipelineStateD3D12Impl.h" +#include "CommandContext.h" +#include "TextureD3D12Impl.h" +#include "BufferD3D12Impl.h" +#include "D3D12TypeConversions.h" +#include "d3dx12_win.h" +#include "DynamicUploadHeap.h" +#include "CommandListD3D12Impl.h" + +namespace Diligent +{ + + DeviceContextD3D12Impl::DeviceContextD3D12Impl( IMemoryAllocator &RawMemAllocator, RenderDeviceD3D12Impl *pDeviceD3D12Impl, bool bIsDeferred, const EngineD3D12Attribs &Attribs, Uint32 ContextId) : + TDeviceContextBase(RawMemAllocator, pDeviceD3D12Impl, bIsDeferred), + m_pUploadHeap(pDeviceD3D12Impl->RequestUploadHeap() ), + m_NumCommandsInCurCtx(0), + m_NumCommandsToFlush(bIsDeferred ? std::numeric_limits<decltype(m_NumCommandsToFlush)>::max() : Attribs.NumCommandsToFlushCmdList), + m_pCurrCmdCtx(pDeviceD3D12Impl->AllocateCommandContext()), + m_CommittedIBFormat(VT_UNDEFINED), + m_CommittedD3D12IndexDataStartOffset(0), + m_MipsGenerator(pDeviceD3D12Impl->GetD3D12Device()), + m_CmdListAllocator(GetRawAllocator(), sizeof(CommandListD3D12Impl), 64 ), + m_ContextId(ContextId) + { + m_NumBoundRenderTargets = 0; + + auto *pd3d12Device = pDeviceD3D12Impl->GetD3D12Device(); + + D3D12_COMMAND_SIGNATURE_DESC CmdSignatureDesc = {}; + D3D12_INDIRECT_ARGUMENT_DESC IndirectArg = {}; + CmdSignatureDesc.NodeMask = 0; + CmdSignatureDesc.NumArgumentDescs = 1; + CmdSignatureDesc.pArgumentDescs = &IndirectArg; + + CmdSignatureDesc.ByteStride = sizeof(UINT)*4; + IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + auto hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDrawIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDrawIndirectSignature)) ); + CHECK_D3D_RESULT_THROW(hr, "Failed to create indirect draw command signature") + + CmdSignatureDesc.ByteStride = sizeof(UINT)*5; + IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED; + hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDrawIndexedIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDrawIndexedIndirectSignature)) ); + CHECK_D3D_RESULT_THROW(hr, "Failed to create draw indexed indirect command signature") + + CmdSignatureDesc.ByteStride = sizeof(UINT)*3; + IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH; + hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDispatchIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDispatchIndirectSignature)) ); + CHECK_D3D_RESULT_THROW(hr, "Failed to create dispatch indirect command signature") + } + + DeviceContextD3D12Impl::~DeviceContextD3D12Impl() + { + if(m_bIsDeferred) + ValidatedCast<RenderDeviceD3D12Impl>(m_pDevice.RawPtr())->DisposeCommandContext(m_pCurrCmdCtx); + else + Flush(false); + } + + //IMPLEMENT_QUERY_INTERFACE( DeviceContextD3D12Impl, IID_DeviceContextD3D12, TDeviceContextBase ) + + const LONG MaxD3D12TexDim = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; + const Uint32 MaxD3D12ScissorRects = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + static const RECT MaxD3D12TexSizeRects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = + { + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim}, + {0,0, MaxD3D12TexDim,MaxD3D12TexDim} + }; + + void DeviceContextD3D12Impl::SetPipelineState(IPipelineState *pPipelineState) + { + if (m_NumCommandsInCurCtx >= m_NumCommandsToFlush) + { + Flush(true); + } + + TDeviceContextBase::SetPipelineState( pPipelineState ); + auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPipelineState); + + auto *pCmdCtx = RequestCmdContext(); + const auto &Desc = pPipelineStateD3D12->GetDesc(); + auto *pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState(); + if (Desc.IsComputePipeline) + { + pCmdCtx->AsComputeContext().SetPipelineState(pd3d12PSO); + } + else + { + auto &GraphicsCtx = pCmdCtx->AsGraphicsContext(); + GraphicsCtx.SetPipelineState(pd3d12PSO); + + if (Desc.GraphicsPipeline.RasterizerDesc.ScissorEnable) + { + // Commit currently set scissor rectangles + D3D12_RECT d3d12ScissorRects[MaxD3D12ScissorRects]; // Do not waste time initializing array with zeroes + for( Uint32 sr = 0; sr < m_NumScissorRects; ++sr ) + { + d3d12ScissorRects[sr].left = m_ScissorRects[sr].left; + d3d12ScissorRects[sr].top = m_ScissorRects[sr].top; + d3d12ScissorRects[sr].right = m_ScissorRects[sr].right; + d3d12ScissorRects[sr].bottom = m_ScissorRects[sr].bottom; + } + GraphicsCtx.SetScissorRects(m_NumScissorRects, d3d12ScissorRects); + } + else + { + // Disable scissor rectangles + static_assert(_countof(MaxD3D12TexSizeRects) == MaxD3D12ScissorRects, "Unexpected array size"); + GraphicsCtx.SetScissorRects(MaxD3D12ScissorRects, MaxD3D12TexSizeRects); + } + + GraphicsCtx.SetStencilRef( m_StencilRef ); + GraphicsCtx.SetBlendFactor( m_BlendFactors ); + m_CommittedD3D12IndexBuffer = nullptr; + m_CommittedD3D12IndexDataStartOffset = 0; + m_CommittedIBFormat = VT_UNDEFINED; + m_bCommittedD3D12VBsUpToDate = false; + m_bCommittedD3D12IBUpToDate = false; + RebindRenderTargets(); + CommitViewports(); + } + m_pCommittedResourceCache = nullptr; + } + + void DeviceContextD3D12Impl::TransitionShaderResources(IPipelineState *pPipelineState, IShaderResourceBinding *pShaderResourceBinding) + { + VERIFY_EXPR(pPipelineState != nullptr); + + auto *pCtx = RequestCmdContext(); + auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPipelineState); + pPipelineStateD3D12->CommitAndTransitionShaderResources(pShaderResourceBinding, *pCtx, false, true); + } + + void DeviceContextD3D12Impl::CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags) + { +#ifdef _DEBUG + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound"); + return; + } +#endif + + auto *pCtx = RequestCmdContext(); + auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(m_pPipelineState.RawPtr()); + + m_pCommittedResourceCache = pPipelineStateD3D12->CommitAndTransitionShaderResources(pShaderResourceBinding, *pCtx, true, (Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES)!=0); + } + + void DeviceContextD3D12Impl::SetStencilRef(Uint32 StencilRef) + { + if (TDeviceContextBase::SetStencilRef(StencilRef, 0)) + { + RequestCmdContext()->AsGraphicsContext().SetStencilRef( m_StencilRef ); + } + } + + void DeviceContextD3D12Impl::SetBlendFactors(const float* pBlendFactors) + { + if (TDeviceContextBase::SetBlendFactors(m_BlendFactors, 0)) + { + RequestCmdContext()->AsGraphicsContext().SetBlendFactor( m_BlendFactors ); + } + } + + void DeviceContextD3D12Impl::CommitD3D12IndexBuffer(VALUE_TYPE IndexType) + { + if( !m_pIndexBuffer ) + { + LOG_ERROR_MESSAGE( "Index buffer is not set up for indexed draw command" ); + return; + } + + D3D12_INDEX_BUFFER_VIEW IBView; + BufferD3D12Impl *pBuffD3D12 = static_cast<BufferD3D12Impl *>(m_pIndexBuffer.RawPtr()); + IBView.BufferLocation = pBuffD3D12->GetGPUAddress(m_ContextId) + m_IndexDataStartOffset; + if( IndexType == VT_UINT32 ) + IBView.Format = DXGI_FORMAT_R32_UINT; + else if( IndexType == VT_UINT16 ) + IBView.Format = DXGI_FORMAT_R16_UINT; + else + { + LOG_ERROR_MESSAGE( "Unsupported index format. Only R16_UINT and R32_UINT are allowed." ); + return; + } + // Note that for a dynamic buffer, what we use here is the size of the buffer itself, not the upload heap buffer! + IBView.SizeInBytes = pBuffD3D12->GetDesc().uiSizeInBytes - m_IndexDataStartOffset; + + // Device context keeps strong reference to bound index buffer. + // When the buffer is unbound, the reference to the D3D12 resource + // is added to the context. There is no need to add reference here + //auto &GraphicsCtx = RequestCmdContext()->AsGraphicsContext(); + //auto *pd3d12Resource = pBuffD3D12->GetD3D12Buffer(); + //GraphicsCtx.AddReferencedObject(pd3d12Resource); + +#ifdef _DEBUG + if(pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC) + pBuffD3D12->DbgVerifyDynamicAllocation(m_ContextId); +#endif + auto &GraphicsCtx = RequestCmdContext()->AsGraphicsContext(); + // Resource transitioning must always be performed! + GraphicsCtx.TransitionResource(pBuffD3D12, D3D12_RESOURCE_STATE_INDEX_BUFFER, true); + + size_t BuffDataStartByteOffset; + auto *pd3d12Buff = pBuffD3D12->GetD3D12Buffer(BuffDataStartByteOffset, m_ContextId); + + if( m_CommittedD3D12IndexBuffer != pd3d12Buff || + m_CommittedIBFormat != IndexType || + m_CommittedD3D12IndexDataStartOffset != m_IndexDataStartOffset + BuffDataStartByteOffset) + { + m_CommittedD3D12IndexBuffer = pd3d12Buff; + m_CommittedIBFormat = IndexType; + m_CommittedD3D12IndexDataStartOffset = m_IndexDataStartOffset + static_cast<Uint32>(BuffDataStartByteOffset); + GraphicsCtx.SetIndexBuffer( IBView ); + } + m_bCommittedD3D12IBUpToDate = true; + } + + void DeviceContextD3D12Impl::TransitionD3D12VertexBuffers(GraphicsContext &GraphCtx) + { + for( UINT Buff = 0; Buff < m_NumVertexStreams; ++Buff ) + { + auto &CurrStream = m_VertexStreams[Buff]; + VERIFY( CurrStream.pBuffer, "Attempting to bind a null buffer for rendering" ); + auto *pBufferD3D12 = static_cast<BufferD3D12Impl*>(CurrStream.pBuffer.RawPtr()); + if(!pBufferD3D12->CheckAllStates(D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)) + GraphCtx.TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); + } + } + + void DeviceContextD3D12Impl::CommitD3D12VertexBuffers(GraphicsContext &GraphCtx) + { + auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(m_pPipelineState.RawPtr()); + + // Do not initialize array with zeroes for performance reasons + D3D12_VERTEX_BUFFER_VIEW VBViews[MaxBufferSlots];// = {} + VERIFY( m_NumVertexStreams <= MaxBufferSlots, "Too many buffers are being set" ); + const auto *TightStrides = pPipelineStateD3D12->GetTightStrides(); + for( UINT Buff = 0; Buff < m_NumVertexStreams; ++Buff ) + { + auto &CurrStream = m_VertexStreams[Buff]; + auto &VBView = VBViews[Buff]; + VERIFY( CurrStream.pBuffer, "Attempting to bind a null buffer for rendering" ); + + auto *pBufferD3D12 = static_cast<BufferD3D12Impl*>(CurrStream.pBuffer.RawPtr()); +#ifdef _DEBUG + if(pBufferD3D12->GetDesc().Usage == USAGE_DYNAMIC) + pBufferD3D12->DbgVerifyDynamicAllocation(m_ContextId); +#endif + + GraphCtx.TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); + + // Device context keeps strong references to all vertex buffers. + // When a buffer is unbound, a reference to D3D12 resource is added to the context, + // so there is no need to reference the resource here + //GraphicsCtx.AddReferencedObject(pd3d12Resource); + + VBView.BufferLocation = pBufferD3D12->GetGPUAddress(m_ContextId) + CurrStream.Offset; + VBView.StrideInBytes = CurrStream.Stride ? CurrStream.Stride : TightStrides[Buff]; + // Note that for a dynamic buffer, what we use here is the size of the buffer itself, not the upload heap buffer! + VBView.SizeInBytes = pBufferD3D12->GetDesc().uiSizeInBytes - CurrStream.Offset; + } + + GraphCtx.FlushResourceBarriers(); + GraphCtx.SetVertexBuffers( 0, m_NumVertexStreams, VBViews ); + + m_bCommittedD3D12VBsUpToDate = true; + } + + void DeviceContextD3D12Impl::Draw( DrawAttribs &DrawAttribs ) + { +#ifdef _DEBUG + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound"); + return; + } + if (m_pPipelineState->GetDesc().IsComputePipeline) + { + LOG_ERROR("No graphics pipeline state is bound"); + return; + } +#endif + + auto &GraphCtx = RequestCmdContext()->AsGraphicsContext(); + if( DrawAttribs.IsIndexed ) + { + if( m_CommittedIBFormat != DrawAttribs.IndexType ) + m_bCommittedD3D12IBUpToDate = false; + + if(m_bCommittedD3D12IBUpToDate) + { + BufferD3D12Impl *pBuffD3D12 = static_cast<BufferD3D12Impl *>(m_pIndexBuffer.RawPtr()); + if(!pBuffD3D12->CheckAllStates(D3D12_RESOURCE_STATE_INDEX_BUFFER)) + GraphCtx.TransitionResource(pBuffD3D12, D3D12_RESOURCE_STATE_INDEX_BUFFER, true); + } + else + CommitD3D12IndexBuffer(DrawAttribs.IndexType); + } + + auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(m_pPipelineState.RawPtr()); + + auto D3D12Topology = TopologyToD3D12Topology( DrawAttribs.Topology ); + GraphCtx.SetPrimitiveTopology(D3D12Topology); + + if(m_bCommittedD3D12VBsUpToDate) + TransitionD3D12VertexBuffers(GraphCtx); + else + CommitD3D12VertexBuffers(GraphCtx); + + GraphCtx.SetRootSignature( pPipelineStateD3D12->GetD3D12RootSignature() ); + + if(m_pCommittedResourceCache != nullptr) + { + pPipelineStateD3D12->GetRootSignature().CommitRootViews(*m_pCommittedResourceCache, GraphCtx, false, m_ContextId); + } +#ifdef _DEBUG + else + { + if( pPipelineStateD3D12->dbgContainsShaderResources() ) + LOG_ERROR_MESSAGE("Pipeline state \"", pPipelineStateD3D12->GetDesc().Name, "\" contains shader resources, but IDeviceContext::CommitShaderResources() was not called" ) + } +#endif + + + if( DrawAttribs.IsIndirect ) + { + if( auto *pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(DrawAttribs.pIndirectDrawAttribs) ) + { +#ifdef _DEBUG + if(pBufferD3D12->GetDesc().Usage == USAGE_DYNAMIC) + pBufferD3D12->DbgVerifyDynamicAllocation(m_ContextId); +#endif + + GraphCtx.TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); + size_t BuffDataStartByteOffset; + ID3D12Resource *pd3d12ArgsBuff = pBufferD3D12->GetD3D12Buffer(BuffDataStartByteOffset, m_ContextId); + GraphCtx.ExecuteIndirect(DrawAttribs.IsIndexed ? m_pDrawIndexedIndirectSignature : m_pDrawIndirectSignature, pd3d12ArgsBuff, DrawAttribs.IndirectDrawArgsOffset + BuffDataStartByteOffset); + } + else + { + LOG_ERROR_MESSAGE("Valid pIndirectDrawAttribs must be provided for indirect draw command") + } + } + else + { + if( DrawAttribs.IsIndexed ) + GraphCtx.DrawIndexed(DrawAttribs.NumIndices, DrawAttribs.NumInstances, DrawAttribs.FirstIndexLocation, DrawAttribs.BaseVertex, DrawAttribs.FirstInstanceLocation); + else + GraphCtx.Draw(DrawAttribs.NumVertices, DrawAttribs.NumInstances, DrawAttribs.StartVertexLocation, DrawAttribs.FirstInstanceLocation ); + } + ++m_NumCommandsInCurCtx; + } + + void DeviceContextD3D12Impl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) + { +#ifdef _DEBUG + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound"); + return; + } + if (!m_pPipelineState->GetDesc().IsComputePipeline) + { + LOG_ERROR("No compute pipeline state is bound"); + return; + } +#endif + + auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(m_pPipelineState.RawPtr()); + + auto &ComputeCtx = RequestCmdContext()->AsComputeContext(); + ComputeCtx.SetRootSignature( pPipelineStateD3D12->GetD3D12RootSignature() ); + + if(m_pCommittedResourceCache != nullptr) + { + pPipelineStateD3D12->GetRootSignature().CommitRootViews(*m_pCommittedResourceCache, ComputeCtx, true, m_ContextId); + } +#ifdef _DEBUG + else + { + if( pPipelineStateD3D12->dbgContainsShaderResources() ) + LOG_ERROR_MESSAGE("Pipeline state \"", pPipelineStateD3D12->GetDesc().Name, "\" contains shader resources, but IDeviceContext::CommitShaderResources() was not called" ) + } +#endif + + if( DispatchAttrs.pIndirectDispatchAttribs ) + { + if( auto *pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(DispatchAttrs.pIndirectDispatchAttribs) ) + { +#ifdef _DEBUG + if(pBufferD3D12->GetDesc().Usage == USAGE_DYNAMIC) + pBufferD3D12->DbgVerifyDynamicAllocation(m_ContextId); +#endif + + ComputeCtx.TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); + size_t BuffDataStartByteOffset; + ID3D12Resource *pd3d12ArgsBuff = pBufferD3D12->GetD3D12Buffer(BuffDataStartByteOffset, m_ContextId); + ComputeCtx.ExecuteIndirect(m_pDispatchIndirectSignature, pd3d12ArgsBuff, DispatchAttrs.DispatchArgsByteOffset + BuffDataStartByteOffset); + } + else + { + LOG_ERROR_MESSAGE("Valid pIndirectDrawAttribs must be provided for indirect dispatch command") + } + } + else + ComputeCtx.Dispatch(DispatchAttrs.ThreadGroupCountX, DispatchAttrs.ThreadGroupCountY, DispatchAttrs.ThreadGroupCountZ); + ++m_NumCommandsInCurCtx; + } + + void DeviceContextD3D12Impl::ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil ) + { + ITextureViewD3D12 *pDSVD3D12 = nullptr; + if( pView != nullptr ) + { + pDSVD3D12 = ValidatedCast<ITextureViewD3D12>(pView); +#ifdef _DEBUG + const auto& ViewDesc = pDSVD3D12->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); +#endif + } + else + { + auto *pDSV = ValidatedCast<SwapChainD3D12Impl>(m_pSwapChain.RawPtr())->GetDepthBufferDSV(); + pDSVD3D12 = ValidatedCast<ITextureViewD3D12>(pDSV); + } + D3D12_CLEAR_FLAGS d3d12ClearFlags = (D3D12_CLEAR_FLAGS)0; + if( ClearFlags & CLEAR_DEPTH_FLAG ) d3d12ClearFlags |= D3D12_CLEAR_FLAG_DEPTH; + if( ClearFlags & CLEAR_STENCIL_FLAG ) d3d12ClearFlags |= D3D12_CLEAR_FLAG_STENCIL; + // The full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied?? + RequestCmdContext()->AsGraphicsContext().ClearDepthStencil( pDSVD3D12, d3d12ClearFlags, fDepth, Stencil ); + ++m_NumCommandsInCurCtx; + } + + void DeviceContextD3D12Impl::ClearRenderTarget( ITextureView *pView, const float *RGBA ) + { + ITextureViewD3D12 *pd3d12RTV = nullptr; + if( pView != nullptr ) + { +#ifdef _DEBUG + const auto& ViewDesc = pView->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); +#endif + pd3d12RTV = ValidatedCast<ITextureViewD3D12>(pView); + } + else + { + auto *pBackBufferRTV = ValidatedCast<SwapChainD3D12Impl>(m_pSwapChain.RawPtr())->GetCurrentBackBufferRTV(); + pd3d12RTV = ValidatedCast<ITextureViewD3D12>(pBackBufferRTV); + } + + static const float Zero[4] = { 0.f, 0.f, 0.f, 0.f }; + if( RGBA == nullptr ) + RGBA = Zero; + + // The full extent of the resource view is always cleared. + // Viewport and scissor settings are not applied?? + RequestCmdContext()->AsGraphicsContext().ClearRenderTarget( pd3d12RTV, RGBA ); + ++m_NumCommandsInCurCtx; + } + + void DeviceContextD3D12Impl::Flush(bool RequestNewCmdCtx) + { + if( m_pCurrCmdCtx ) + { + VERIFY(!m_bIsDeferred, "Deferred contexts cannot executre command lists directly"); + ValidatedCast<RenderDeviceD3D12Impl>(m_pDevice.RawPtr())->CloseAndExecuteCommandContext(m_pCurrCmdCtx); + } + + m_pCurrCmdCtx = RequestNewCmdCtx ? ValidatedCast<RenderDeviceD3D12Impl>(m_pDevice.RawPtr())->AllocateCommandContext() : nullptr; + m_NumCommandsInCurCtx = 0; + + m_pPipelineState.Release(); + } + + void DeviceContextD3D12Impl::Flush() + { + VERIFY(!m_bIsDeferred, "Flush() should only be called for immediate contexts"); + Flush(true); + } + + void DeviceContextD3D12Impl::SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) + { + TDeviceContextBase::SetVertexBuffers( StartSlot, NumBuffersSet, ppBuffers, pStrides, pOffsets, Flags ); + m_bCommittedD3D12VBsUpToDate = false; + } + + void DeviceContextD3D12Impl::ClearState() + { + TDeviceContextBase::ClearState(); + LOG_ERROR_ONCE("DeviceContextD3D12Impl::ClearState() is not implemented"); + } + + void DeviceContextD3D12Impl::SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) + { + TDeviceContextBase::SetIndexBuffer( pIndexBuffer, ByteOffset ); + m_bCommittedD3D12IBUpToDate = false; + } + + void DeviceContextD3D12Impl::CommitViewports() + { + const Uint32 MaxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + D3D12_VIEWPORT d3d12Viewports[MaxViewports]; // Do not waste time initializing array to zero + + for( Uint32 vp = 0; vp < m_NumViewports; ++vp ) + { + d3d12Viewports[vp].TopLeftX = m_Viewports[vp].TopLeftX; + d3d12Viewports[vp].TopLeftY = m_Viewports[vp].TopLeftY; + d3d12Viewports[vp].Width = m_Viewports[vp].Width; + d3d12Viewports[vp].Height = m_Viewports[vp].Height; + d3d12Viewports[vp].MinDepth = m_Viewports[vp].MinDepth; + d3d12Viewports[vp].MaxDepth = m_Viewports[vp].MaxDepth; + } + // All viewports must be set atomically as one operation. + // Any viewports not defined by the call are disabled. + RequestCmdContext()->AsGraphicsContext().SetViewports( m_NumViewports, d3d12Viewports ); + } + + void DeviceContextD3D12Impl::SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight ) + { + const Uint32 MaxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + VERIFY( NumViewports < MaxViewports, "Too many viewports are being set" ); + NumViewports = std::min( NumViewports, MaxViewports ); + + TDeviceContextBase::SetViewports( NumViewports, pViewports, RTWidth, RTHeight ); + VERIFY( NumViewports == m_NumViewports, "Unexpected number of viewports" ); + + CommitViewports(); + } + + void DeviceContextD3D12Impl::SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight ) + { + const Uint32 MaxScissorRects = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + VERIFY( NumRects < MaxScissorRects, "Too many scissor rects are being set" ); + NumRects = std::min( NumRects, MaxScissorRects ); + + TDeviceContextBase::SetScissorRects(NumRects, pRects, RTWidth, RTHeight); + + // Only commit scissor rects if scissor test is enabled in the rasterizer state. + if( !m_pPipelineState || m_pPipelineState->GetDesc().GraphicsPipeline.RasterizerDesc.ScissorEnable ) + { + D3D12_RECT d3d12ScissorRects[MaxScissorRects]; + VERIFY( NumRects == m_NumScissorRects, "Unexpected number of scissor rects" ); + for( Uint32 sr = 0; sr < NumRects; ++sr ) + { + d3d12ScissorRects[sr].left = m_ScissorRects[sr].left; + d3d12ScissorRects[sr].top = m_ScissorRects[sr].top; + d3d12ScissorRects[sr].right = m_ScissorRects[sr].right; + d3d12ScissorRects[sr].bottom = m_ScissorRects[sr].bottom; + } + RequestCmdContext()->AsGraphicsContext().SetScissorRects(NumRects, d3d12ScissorRects); + } + } + + + void DeviceContextD3D12Impl::RebindRenderTargets() + { + const Uint32 MaxD3D12RTs = D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; + Uint32 NumRenderTargets = m_NumBoundRenderTargets; + VERIFY( NumRenderTargets <= MaxD3D12RTs, "D3D12 only allows 8 simultaneous render targets" ); + NumRenderTargets = std::min( MaxD3D12RTs, NumRenderTargets ); + + ITextureViewD3D12 *ppRTVs[MaxD3D12RTs]; // Do not initialize with zeroes! + ITextureViewD3D12 *pDSV = nullptr; + if( NumRenderTargets == 0 && m_pBoundDepthStencil == nullptr ) + { + NumRenderTargets = 1; + auto *pSwapChainD3D12 = ValidatedCast<SwapChainD3D12Impl>( m_pSwapChain.RawPtr() ); + ppRTVs[0] = ValidatedCast<ITextureViewD3D12>(pSwapChainD3D12->GetCurrentBackBufferRTV()); + pDSV = ValidatedCast<ITextureViewD3D12>(pSwapChainD3D12->GetDepthBufferDSV()); + } + else + { + for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + ppRTVs[rt] = ValidatedCast<ITextureViewD3D12>(m_pBoundRenderTargets[rt].RawPtr()); + pDSV = ValidatedCast<ITextureViewD3D12>(m_pBoundDepthStencil.RawPtr()); + } + RequestCmdContext()->AsGraphicsContext().SetRenderTargets(NumRenderTargets, ppRTVs, pDSV); + } + + void DeviceContextD3D12Impl::SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil ) + { + if( TDeviceContextBase::SetRenderTargets( NumRenderTargets, ppRenderTargets, pDepthStencil ) ) + { + RebindRenderTargets(); + + // Set the viewport to match the render target size + SetViewports(1, nullptr, 0, 0); + } + } + + DynamicAllocation DeviceContextD3D12Impl::AllocateDynamicSpace(size_t NumBytes) + { + return m_pUploadHeap->Allocate(NumBytes); + } + + void DeviceContextD3D12Impl::UpdateBufferRegion(BufferD3D12Impl *pBuffD3D12, const void *pData, Uint64 DstOffset, Uint64 NumBytes) + { + VERIFY(pBuffD3D12->GetDesc().Usage != USAGE_DYNAMIC, "Dynamic buffers must be updated via Map()") + + auto pCmdCtx = RequestCmdContext(); +//#if USE_RING_BUFFER + //auto TmpSpace = pCmdCtx->AllocateUploadBuffer(NumBytes); + auto TmpSpace = m_pUploadHeap->Allocate(NumBytes); + memcpy(TmpSpace.CPUAddress, pData, NumBytes); + pCmdCtx->TransitionResource(pBuffD3D12, D3D12_RESOURCE_STATE_COPY_DEST, true); + // Source buffer is already in right state, which cannot be changed + size_t DstBuffDataStartByteOffset; + auto *pd3d12Buff = pBuffD3D12->GetD3D12Buffer(DstBuffDataStartByteOffset, m_ContextId); + VERIFY(DstBuffDataStartByteOffset == 0, "Dst buffer must not be suballocated"); + pCmdCtx->GetCommandList()->CopyBufferRegion( pd3d12Buff, DstOffset + DstBuffDataStartByteOffset, TmpSpace.pBuffer, TmpSpace.Offset, NumBytes); + ++m_NumCommandsInCurCtx; + } + + void DeviceContextD3D12Impl::CopyBufferRegion(BufferD3D12Impl *pSrcBuffD3D12, BufferD3D12Impl *pDstBuffD3D12, Uint64 SrcOffset, Uint64 DstOffset, Uint64 NumBytes) + { + VERIFY(pDstBuffD3D12->GetDesc().Usage != USAGE_DYNAMIC, "Dynamic buffers cannot be copy destinations") + + auto pCmdCtx = RequestCmdContext(); + pCmdCtx->TransitionResource(pSrcBuffD3D12, D3D12_RESOURCE_STATE_COPY_SOURCE); + pCmdCtx->TransitionResource(pDstBuffD3D12, D3D12_RESOURCE_STATE_COPY_DEST, true); + size_t DstDataStartByteOffset; + auto *pd3d12DstBuff = pDstBuffD3D12->GetD3D12Buffer(DstDataStartByteOffset, m_ContextId); + VERIFY(DstDataStartByteOffset == 0, "Dst buffer must not be suballocated"); + + size_t SrcDataStartByteOffset; + auto *pd3d12SrcBuff = pSrcBuffD3D12->GetD3D12Buffer(SrcDataStartByteOffset, m_ContextId); + pCmdCtx->GetCommandList()->CopyBufferRegion( pd3d12DstBuff, DstOffset + DstDataStartByteOffset, pd3d12SrcBuff, SrcOffset+SrcDataStartByteOffset, NumBytes); + ++m_NumCommandsInCurCtx; + } + + void DeviceContextD3D12Impl::CopyTextureRegion(TextureD3D12Impl *pSrcTexture, Uint32 SrcSubResIndex, const D3D12_BOX *pD3D12SrcBox, + TextureD3D12Impl *pDstTexture, Uint32 DstSubResIndex, Uint32 DstX, Uint32 DstY, Uint32 DstZ) + { + auto pCmdCtx = RequestCmdContext(); + pCmdCtx->TransitionResource(pSrcTexture, D3D12_RESOURCE_STATE_COPY_SOURCE); + pCmdCtx->TransitionResource(pDstTexture, D3D12_RESOURCE_STATE_COPY_DEST, true); + + D3D12_TEXTURE_COPY_LOCATION DstLocation = {}, SrcLocation = {}; + + DstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + DstLocation.pResource = pDstTexture->GetD3D12Resource(); + DstLocation.SubresourceIndex = SrcSubResIndex; + + SrcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SrcLocation.pResource = pSrcTexture->GetD3D12Resource(); + SrcLocation.SubresourceIndex = DstSubResIndex; + + pCmdCtx->GetCommandList()->CopyTextureRegion( &DstLocation, DstX, DstY, DstZ, &SrcLocation, pD3D12SrcBox); + ++m_NumCommandsInCurCtx; + } + + void DeviceContextD3D12Impl::GenerateMips(TextureViewD3D12Impl *pTexView) + { + auto *pCtx = RequestCmdContext(); + m_MipsGenerator.GenerateMips(ValidatedCast<RenderDeviceD3D12Impl>(m_pDevice.RawPtr()), pTexView, *pCtx); + } + + void DeviceContextD3D12Impl::FinishCommandList(class ICommandList **ppCommandList) + { + CommandListD3D12Impl *pCmdListD3D12( NEW(m_CmdListAllocator, "CommandListD3D12Impl instance", CommandListD3D12Impl, m_pDevice, m_pCurrCmdCtx) ); + pCmdListD3D12->QueryInterface( IID_CommandList, reinterpret_cast<IObject**>(ppCommandList) ); + m_pCurrCmdCtx = nullptr; + Flush(true); + } + + void DeviceContextD3D12Impl::ExecuteCommandList(class ICommandList *pCommandList) + { + if (m_bIsDeferred) + { + LOG_ERROR("Only immediate context can execute command list"); + return; + } + // First execute commands in this context + Flush(true); + + CommandListD3D12Impl* pCmdListD3D12 = ValidatedCast<CommandListD3D12Impl>(pCommandList); + ValidatedCast<RenderDeviceD3D12Impl>(m_pDevice.RawPtr())->CloseAndExecuteCommandContext(pCmdListD3D12->Close()); + } +} diff --git a/Graphics/GraphicsEngineD3D12/src/DynamicUploadHeap.cpp b/Graphics/GraphicsEngineD3D12/src/DynamicUploadHeap.cpp new file mode 100644 index 00000000..c747a731 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/DynamicUploadHeap.cpp @@ -0,0 +1,152 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "DynamicUploadHeap.h" +#include "RenderDeviceD3D12Impl.h" + +namespace Diligent +{ + GPURingBuffer::GPURingBuffer(size_t MaxSize, IMemoryAllocator &Allocator, ID3D12Device *pd3d12Device, bool AllowCPUAccess) : + RingBuffer(MaxSize, Allocator), + m_CpuVirtualAddress(nullptr), + m_GpuVirtualAddress(0) + { + D3D12_HEAP_PROPERTIES HeapProps; + HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + HeapProps.CreationNodeMask = 1; + HeapProps.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC ResourceDesc; + ResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + ResourceDesc.Alignment = 0; + ResourceDesc.Height = 1; + ResourceDesc.DepthOrArraySize = 1; + ResourceDesc.MipLevels = 1; + ResourceDesc.Format = DXGI_FORMAT_UNKNOWN; + ResourceDesc.SampleDesc.Count = 1; + ResourceDesc.SampleDesc.Quality = 0; + ResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + + D3D12_RESOURCE_STATES DefaultUsage; + if (AllowCPUAccess) + { + HeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + ResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + DefaultUsage = D3D12_RESOURCE_STATE_GENERIC_READ; + } + else + { + HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + ResourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + DefaultUsage = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } + ResourceDesc.Width = MaxSize; + + auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, &ResourceDesc, + DefaultUsage, nullptr, __uuidof(m_pBuffer), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pBuffer)) ); + if(FAILED(hr)) + LOG_ERROR("Failed to create new upload ring buffer") + + m_pBuffer->SetName(L"Upload Ring Buffer"); + + m_GpuVirtualAddress = m_pBuffer->GetGPUVirtualAddress(); + + if (AllowCPUAccess) + { + m_pBuffer->Map(0, nullptr, &m_CpuVirtualAddress); + } + } + + void GPURingBuffer::Destroy() + { + if (m_CpuVirtualAddress) + { + m_pBuffer->Unmap(0, nullptr); + } + m_CpuVirtualAddress = 0; + m_GpuVirtualAddress = 0; + m_pBuffer.Release(); + } + + GPURingBuffer::~GPURingBuffer() + { + Destroy(); + } + + DynamicUploadHeap::DynamicUploadHeap(IMemoryAllocator &Allocator, bool bIsCPUAccessible, class RenderDeviceD3D12Impl* pDevice, size_t InitialSize) : + m_Allocator(Allocator), + m_pDeviceD3D12(pDevice), + m_bIsCPUAccessible(bIsCPUAccessible), + m_RingBuffers(STD_ALLOCATOR_RAW_MEM(GPURingBuffer, GetRawAllocator(), "Allocator for vector<GPURingBuffer>")) + { + m_RingBuffers.emplace_back(InitialSize, Allocator, pDevice->GetD3D12Device(), m_bIsCPUAccessible); + } + + DynamicAllocation DynamicUploadHeap::Allocate(size_t SizeInBytes, size_t Alignment /*= DEFAULT_ALIGN*/) + { + // This is very expensive! Currently other threads cannot allocate dynamic + // data while frame is being finished. + + //std::lock_guard<std::mutex> Lock(m_Mutex); + + const size_t AlignmentMask = Alignment - 1; + // Assert that it's a power of two. + VERIFY_EXPR((AlignmentMask & Alignment) == 0); + // Align the allocation + const size_t AlignedSize = (SizeInBytes + AlignmentMask) & ~AlignmentMask; + auto DynAlloc = m_RingBuffers.back().Allocate(AlignedSize); + if (!DynAlloc.pBuffer) + { + auto NewMaxSize = m_RingBuffers.back().GetMaxSize() * 2; + while(NewMaxSize < SizeInBytes)NewMaxSize*=2; + m_RingBuffers.emplace_back(NewMaxSize, m_Allocator, m_pDeviceD3D12->GetD3D12Device(), m_bIsCPUAccessible); + DynAlloc = m_RingBuffers.back().Allocate(AlignedSize); + } +#ifdef _DEBUG + DynAlloc.FrameNum = m_pDeviceD3D12->GetCurrentFrame(); +#endif + return DynAlloc; + } + + void DynamicUploadHeap::FinishFrame(Uint64 FrameNum, Uint64 NumCompletedFrames) + { + //std::lock_guard<std::mutex> Lock(m_Mutex); + + size_t NumBuffsToDelete = 0; + for(size_t Ind = 0; Ind < m_RingBuffers.size(); ++Ind) + { + auto &RingBuff = m_RingBuffers[Ind]; + RingBuff.FinishCurrentFrame(FrameNum); + RingBuff.ReleaseCompletedFrames(NumCompletedFrames); + if ( NumBuffsToDelete == Ind && Ind < m_RingBuffers.size()-1 && RingBuff.IsEmpty()) + { + ++NumBuffsToDelete; + } + } + + if(NumBuffsToDelete) + m_RingBuffers.erase(m_RingBuffers.begin(), m_RingBuffers.begin()+NumBuffsToDelete); + } +} diff --git a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp new file mode 100644 index 00000000..ee382930 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp @@ -0,0 +1,185 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// The source code in this file is derived from ColorBuffer.cpp and GraphicsCore.cpp developed by Minigraph +// Original source files header: + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + + +#include "pch.h" +#include "d3dx12_win.h" + +#include "RenderDeviceD3D12Impl.h" +#include "GenerateMips.h" +#include "CommandContext.h" +#include "TextureViewD3D12Impl.h" +#include "TextureD3D12Impl.h" + +#include "GenerateMips/GenerateMipsLinearCS.h" +#include "GenerateMips/GenerateMipsLinearOddCS.h" +#include "GenerateMips/GenerateMipsLinearOddXCS.h" +#include "GenerateMips/GenerateMipsLinearOddYCS.h" +#include "GenerateMips/GenerateMipsGammaCS.h" +#include "GenerateMips/GenerateMipsGammaOddCS.h" +#include "GenerateMips/GenerateMipsGammaOddXCS.h" +#include "GenerateMips/GenerateMipsGammaOddYCS.h" + +namespace Diligent +{ + GenerateMipsHelper::GenerateMipsHelper(ID3D12Device *pd3d12Device) + { + CD3DX12_ROOT_PARAMETER Params[3]; + Params[0].InitAsConstants(4, 0); + CD3DX12_DESCRIPTOR_RANGE SRVRange(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); + Params[1].InitAsDescriptorTable(1, &SRVRange); + CD3DX12_DESCRIPTOR_RANGE UAVRange(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 4, 0); + Params[2].InitAsDescriptorTable(1, &UAVRange); + CD3DX12_STATIC_SAMPLER_DESC SamplerLinearClampDesc( + 0, D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP); + CD3DX12_ROOT_SIGNATURE_DESC RootSigDesc; + RootSigDesc.NumParameters = _countof(Params); + RootSigDesc.pParameters = Params; + RootSigDesc.NumStaticSamplers = 1; + RootSigDesc.pStaticSamplers = &SamplerLinearClampDesc; + RootSigDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; + + CComPtr<ID3DBlob> signature; + CComPtr<ID3DBlob> error; + HRESULT hr = D3D12SerializeRootSignature(&RootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); + hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pGenerateMipsRS), reinterpret_cast<void**>( static_cast<ID3D12RootSignature**>(&m_pGenerateMipsRS))); + CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature for mipmap generation") + + D3D12_COMPUTE_PIPELINE_STATE_DESC PSODesc = {}; + PSODesc.pRootSignature = m_pGenerateMipsRS; + PSODesc.NodeMask = 0; + PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + +#define CreatePSO(PSO, ShaderByteCode) \ + PSODesc.CS.pShaderBytecode = ShaderByteCode;\ + PSODesc.CS.BytecodeLength = sizeof(ShaderByteCode);\ + hr = pd3d12Device->CreateComputePipelineState(&PSODesc, __uuidof(PSO), reinterpret_cast<void**>( static_cast<ID3D12PipelineState**>(&PSO))); \ + CHECK_D3D_RESULT_THROW(hr, "Failed to create Pipeline state for mipmap generation") + + CreatePSO(m_pGenerateMipsLinearPSO[0], g_pGenerateMipsLinearCS); + CreatePSO(m_pGenerateMipsLinearPSO[1], g_pGenerateMipsLinearOddXCS); + CreatePSO(m_pGenerateMipsLinearPSO[2], g_pGenerateMipsLinearOddYCS); + CreatePSO(m_pGenerateMipsLinearPSO[3], g_pGenerateMipsLinearOddCS); + CreatePSO(m_pGenerateMipsGammaPSO[0], g_pGenerateMipsGammaCS); + CreatePSO(m_pGenerateMipsGammaPSO[1], g_pGenerateMipsGammaOddXCS); + CreatePSO(m_pGenerateMipsGammaPSO[2], g_pGenerateMipsGammaOddYCS); + CreatePSO(m_pGenerateMipsGammaPSO[3], g_pGenerateMipsGammaOddCS); + } + + void GenerateMipsHelper::GenerateMips(RenderDeviceD3D12Impl *pRenderDeviceD3D12, TextureViewD3D12Impl *pTexView, CommandContext& Ctx) + { + auto &ComputeCtx = Ctx.AsComputeContext(); + ComputeCtx.SetRootSignature(m_pGenerateMipsRS); + auto *pTexture = pTexView->GetTexture(); + auto *pTexD3D12 = ValidatedCast<TextureD3D12Impl>( pTexture ); + auto &TexDesc = pTexture->GetDesc(); + auto *pSRV = pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); + auto *pSRVD3D12Impl = ValidatedCast<TextureViewD3D12Impl>(pSRV); + auto SRVDescriptorHandle = pSRVD3D12Impl->GetCPUDescriptorHandle(); + + Ctx.TransitionResource(pTexD3D12, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + auto *pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); + + for (uint32_t TopMip = 0; TopMip < TexDesc.MipLevels-1; ) + { + uint32_t SrcWidth = TexDesc.Width >> TopMip; + uint32_t SrcHeight = TexDesc.Height >> TopMip; + uint32_t DstWidth = SrcWidth >> 1; + uint32_t DstHeight = SrcHeight >> 1; + + // Determine if the first downsample is more than 2:1. This happens whenever + // the source width or height is odd. + uint32_t NonPowerOfTwo = (SrcWidth & 1) | (SrcHeight & 1) << 1; + if (TexDesc.Format == TEX_FORMAT_RGBA8_UNORM_SRGB) + ComputeCtx.SetPipelineState(m_pGenerateMipsGammaPSO[NonPowerOfTwo]); + else + ComputeCtx.SetPipelineState(m_pGenerateMipsLinearPSO[NonPowerOfTwo]); + + // We can downsample up to four times, but if the ratio between levels is not + // exactly 2:1, we have to shift our blend weights, which gets complicated or + // expensive. Maybe we can update the code later to compute sample weights for + // each successive downsample. We use _BitScanForward to count number of zeros + // in the low bits. Zeros indicate we can divide by two without truncating. + uint32_t AdditionalMips; + _BitScanForward((unsigned long*)&AdditionalMips, DstWidth | DstHeight); + uint32_t NumMips = 1 + (AdditionalMips > 3 ? 3 : AdditionalMips); + if (TopMip + NumMips > TexDesc.MipLevels-1) + NumMips = TexDesc.MipLevels-1 - TopMip; + + // These are clamped to 1 after computing additional mips because clamped + // dimensions should not limit us from downsampling multiple times. (E.g. + // 16x1 -> 8x1 -> 4x1 -> 2x1 -> 1x1.) + if (DstWidth == 0) + DstWidth = 1; + if (DstHeight == 0) + DstHeight = 1; + + D3D12_DESCRIPTOR_HEAP_TYPE HeapType = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + auto DescriptorAlloc = Ctx.AllocateDynamicGPUVisibleDescriptor(HeapType, 5); + CommandContext::ShaderDescriptorHeaps Heaps(DescriptorAlloc.GetDescriptorHeap()); + ComputeCtx.SetDescriptorHeaps(Heaps); + Ctx.GetCommandList()->SetComputeRootDescriptorTable(1, DescriptorAlloc.GetGpuHandle(0)); + Ctx.GetCommandList()->SetComputeRootDescriptorTable(2, DescriptorAlloc.GetGpuHandle(1)); + struct RootCBData + { + Uint32 SrcMipLevel; // Texture level of source mip + Uint32 NumMipLevels; // Number of OutMips to write: [1, 4] + float TexelSize[2]; // 1.0 / OutMip1.Dimensions + }CBData = {TopMip, NumMips, 1.0f / static_cast<float>(DstWidth), 1.0f / static_cast<float>(DstHeight)}; + Ctx.GetCommandList()->SetComputeRoot32BitConstants(0, 4, &CBData, 0); + + // TODO: Shouldn't we transition top mip to shader resource state? + D3D12_CPU_DESCRIPTOR_HANDLE DstDescriptorRange = DescriptorAlloc.GetCpuHandle(); + UINT DstRangeSize = 1+NumMips; + D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRanges[5] = {}; + SrcDescriptorRanges[0] = SRVDescriptorHandle; + UINT SrcRangeSizes[5] = {1,1,1,1,1}; + for(Uint32 u=0; u < NumMips; ++u) + SrcDescriptorRanges[1+u] = pTexD3D12->GetUAVDescriptorHandle(TopMip+u+1, 0); + + pd3d12Device->CopyDescriptors(1, &DstDescriptorRange, &DstRangeSize, 1+NumMips, SrcDescriptorRanges, SrcRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + ComputeCtx.Dispatch((DstWidth+7)/8, (DstHeight+7)/8); + + Ctx.InsertUAVBarrier(*pTexD3D12, *pTexD3D12); + + TopMip += NumMips; + } + } +} diff --git a/Graphics/GraphicsEngineD3D12/src/GraphicsEngineD3D12.def b/Graphics/GraphicsEngineD3D12/src/GraphicsEngineD3D12.def new file mode 100644 index 00000000..79094c73 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/GraphicsEngineD3D12.def @@ -0,0 +1,3 @@ +EXPORTS + CreateDeviceAndContextsD3D12 + CreateSwapChainD3D12
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp new file mode 100644 index 00000000..c2ed2d83 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -0,0 +1,335 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "PipelineStateD3D12Impl.h" +#include "ShaderD3D12Impl.h" +#include "D3D12TypeConversions.h" +#include "RenderDeviceD3D12Impl.h" +#include "DXGITypeConversions.h" +#include "ShaderResourceBindingD3D12Impl.h" +#include "CommandContext.h" +#include "EngineMemory.h" + +namespace Diligent +{ + +D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType_To_D3D12_PRIMITIVE_TOPOLOGY_TYPE( PRIMITIVE_TOPOLOGY_TYPE TopologyType ) +{ + static bool bIsInit = false; + static D3D12_PRIMITIVE_TOPOLOGY_TYPE D3D12TopologyType[PRIMITIVE_TOPOLOGY_TYPE_NUM_TYPES] = {}; + if( !bIsInit ) + { + D3D12TopologyType[ PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED] = D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED; + D3D12TopologyType[ PRIMITIVE_TOPOLOGY_TYPE_POINT ] = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + D3D12TopologyType[ PRIMITIVE_TOPOLOGY_TYPE_LINE ] = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; + D3D12TopologyType[ PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE ] = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + D3D12TopologyType[ PRIMITIVE_TOPOLOGY_TYPE_PATCH ] = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; + + bIsInit = true; + } + + if( TopologyType >= PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED && TopologyType < PRIMITIVE_TOPOLOGY_TYPE_NUM_TYPES ) + { + auto d3d12TopType = D3D12TopologyType[TopologyType]; + return d3d12TopType; + } + else + { + UNEXPECTED( "Incorrect topology type operation (", TopologyType, ")" ) + return static_cast<D3D12_PRIMITIVE_TOPOLOGY_TYPE>(0); + } +} + +void PipelineStateD3D12Impl::ParseShaderResourceLayout(IShader *pShader) +{ + VERIFY_EXPR(pShader); + + auto ShaderType = pShader->GetDesc().ShaderType; + auto ShaderInd = GetShaderTypeIndex(ShaderType); + auto *pShaderD3D12 = ValidatedCast<ShaderD3D12Impl>(pShader); + + VERIFY(m_pShaderResourceLayouts[ShaderInd] == nullptr, "Shader resource layout has already been initialized"); + + auto pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(pShaderD3D12->GetDevice()); + auto &ShaderResLayoutAllocator = GetRawAllocator(); + + auto *pRawMem = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutD3D12", sizeof(ShaderResourceLayoutD3D12)); + m_pShaderResourceLayouts[ShaderInd] = new (pRawMem) ShaderResourceLayoutD3D12(*this, GetRawAllocator()); + m_pShaderResourceLayouts[ShaderInd]->Initialize(pDeviceD3D12Impl->GetD3D12Device(), pShaderD3D12->GetShaderResources(), GetRawAllocator(), nullptr, 0, nullptr, &m_RootSig); +} + +PipelineStateD3D12Impl :: PipelineStateD3D12Impl(FixedBlockMemoryAllocator &PSOAllocator, RenderDeviceD3D12Impl *pDeviceD3D12, const PipelineStateDesc &PipelineDesc) : + TPipelineStateBase(PSOAllocator, pDeviceD3D12, PipelineDesc), + m_DummyVar(*this), + m_ResourceCacheDataAllocator(GetRawAllocator(), PipelineDesc.SRBAllocationGranularity), + m_ShaderResLayoutDataAllocators + { + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + {GetRawAllocator(), PipelineDesc.SRBAllocationGranularity}, + }, + m_pDefaultShaderResBinding(nullptr, STDDeleter<ShaderResourceBindingD3D12Impl, FixedBlockMemoryAllocator>(pDeviceD3D12->GetSRBAllocator()) ) +{ + auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); + if (PipelineDesc.IsComputePipeline) + { + auto &ComputePipeline = PipelineDesc.ComputePipeline; + + if( ComputePipeline.pCS == nullptr ) + LOG_ERROR_AND_THROW("Compute shader is not set in the pipeline desc"); + + D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {}; + d3d12PSODesc.pRootSignature = nullptr; + + auto *pByteCode = ValidatedCast<ShaderD3D12Impl>(ComputePipeline.pCS)->GetShaderByteCode(); + d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer(); + d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize(); + + // For single GPU operation, set this to zero. If there are multiple GPU nodes, + // set bits to identify the nodes (the device's physical adapters) for which the + // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node. + d3d12PSODesc.NodeMask = 0; + + d3d12PSODesc.CachedPSO.pCachedBlob = nullptr; + d3d12PSODesc.CachedPSO.CachedBlobSizeInBytes = 0; + + // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices. + d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + ParseShaderResourceLayout(ComputePipeline.pCS); + m_RootSig.Finalize(pd3d12Device); + d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); + + HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>( static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)) ); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create pipeline state"); + } + else + { + const auto& GraphicsPipeline = PipelineDesc.GraphicsPipeline; + D3D12_GRAPHICS_PIPELINE_STATE_DESC d3d12PSODesc = {}; + + m_RootSig.AllocateStaticSamplers( GetShaders(), GetNumShaders() ); + +#define INIT_SHADER(VarName, ExpectedType)\ + if (GraphicsPipeline.p##VarName) \ + { \ + auto ShaderType = GraphicsPipeline.p##VarName->GetDesc().ShaderType; \ + if( ShaderType != ExpectedType ) \ + LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(ShaderType), " shader is provided while ", GetShaderTypeLiteralName(ExpectedType), " is expected") \ + auto *pByteCode = ValidatedCast<ShaderD3D12Impl>(GraphicsPipeline.p##VarName)->GetShaderByteCode(); \ + d3d12PSODesc.VarName.pShaderBytecode = pByteCode->GetBufferPointer(); \ + d3d12PSODesc.VarName.BytecodeLength = pByteCode->GetBufferSize(); \ + ParseShaderResourceLayout(GraphicsPipeline.p##VarName); \ + } \ + else \ + { \ + d3d12PSODesc.VarName.pShaderBytecode = nullptr; \ + d3d12PSODesc.VarName.BytecodeLength = 0; \ + } + + INIT_SHADER(VS, SHADER_TYPE_VERTEX); + INIT_SHADER(PS, SHADER_TYPE_PIXEL); + INIT_SHADER(GS, SHADER_TYPE_GEOMETRY); + INIT_SHADER(DS, SHADER_TYPE_DOMAIN); + INIT_SHADER(HS, SHADER_TYPE_HULL); +#undef INIT_SHADER + + m_RootSig.Finalize(pd3d12Device); + d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); + + memset(&d3d12PSODesc.StreamOutput, 0, sizeof(d3d12PSODesc.StreamOutput)); + + BlendStateDesc_To_D3D12_BLEND_DESC(GraphicsPipeline.BlendDesc, d3d12PSODesc.BlendState); + // The sample mask for the blend state. + d3d12PSODesc.SampleMask = GraphicsPipeline.SampleMask; + + RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, d3d12PSODesc.RasterizerState); + DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, d3d12PSODesc.DepthStencilState); + + std::vector<D3D12_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D12_INPUT_ELEMENT_DESC>> d312InputElements( STD_ALLOCATOR_RAW_MEM(D3D12_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector<D3D12_INPUT_ELEMENT_DESC>") ); + if (m_LayoutElements.size() > 0) + { + LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(m_LayoutElements, d312InputElements); + d3d12PSODesc.InputLayout.NumElements = static_cast<UINT>(d312InputElements.size()); + d3d12PSODesc.InputLayout.pInputElementDescs = d312InputElements.data(); + } + else + { + d3d12PSODesc.InputLayout.NumElements = 0; + d3d12PSODesc.InputLayout.pInputElementDescs = nullptr; + } + + d3d12PSODesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; + d3d12PSODesc.PrimitiveTopologyType = PrimitiveTopologyType_To_D3D12_PRIMITIVE_TOPOLOGY_TYPE(GraphicsPipeline.PrimitiveTopologyType); + + d3d12PSODesc.NumRenderTargets = GraphicsPipeline.NumRenderTargets; + for (Uint32 rt = 0; rt < GraphicsPipeline.NumRenderTargets; ++rt) + d3d12PSODesc.RTVFormats[rt] = TexFormatToDXGI_Format(GraphicsPipeline.RTVFormats[rt]); + for (Uint32 rt = GraphicsPipeline.NumRenderTargets; rt < 8; ++rt) + d3d12PSODesc.RTVFormats[rt] = TexFormatToDXGI_Format(GraphicsPipeline.RTVFormats[rt]); + d3d12PSODesc.DSVFormat = TexFormatToDXGI_Format(GraphicsPipeline.DSVFormat); + + d3d12PSODesc.SampleDesc.Count = GraphicsPipeline.SmplDesc.Count; + d3d12PSODesc.SampleDesc.Quality = GraphicsPipeline.SmplDesc.Quality; + + // For single GPU operation, set this to zero. If there are multiple GPU nodes, + // set bits to identify the nodes (the device's physical adapters) for which the + // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node. + d3d12PSODesc.NodeMask = 0; + + d3d12PSODesc.CachedPSO.pCachedBlob = nullptr; + d3d12PSODesc.CachedPSO.CachedBlobSizeInBytes = 0; + + // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices. + d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>( static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)) ); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create pipeline state"); + } + + auto &SRBAllocator = pDeviceD3D12->GetSRBAllocator(); + // Default shader resource binding must be initialized after resource layouts are parsed! + m_pDefaultShaderResBinding.reset( NEW(SRBAllocator, "ShaderResourceBindingD3D12Impl instance", ShaderResourceBindingD3D12Impl, this, true) ); +} + +PipelineStateD3D12Impl::~PipelineStateD3D12Impl() +{ + auto &ShaderResLayoutAllocator = GetRawAllocator(); + for(Int32 l = 0; l < _countof(m_pShaderResourceLayouts); ++l) + { + if (m_pShaderResourceLayouts[l] != nullptr) + { + m_pShaderResourceLayouts[l]->~ShaderResourceLayoutD3D12(); + ShaderResLayoutAllocator.Free(m_pShaderResourceLayouts[l]); + } + } + + // D3D12 object can only be destroyed when it is no longer used by the GPU + auto *pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice()); + pDeviceD3D12Impl->SafeReleaseD3D12Object(m_pd3d12PSO); +} + +IMPLEMENT_QUERY_INTERFACE( PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase ) + +void PipelineStateD3D12Impl::BindShaderResources(IResourceMapping *pResourceMapping, Uint32 Flags) +{ + if( m_Desc.IsComputePipeline ) + { + if(m_pCS)m_pCS->BindResources(pResourceMapping, Flags); + } + else + { + if(m_pVS)m_pVS->BindResources(pResourceMapping, Flags); + if(m_pPS)m_pPS->BindResources(pResourceMapping, Flags); + if(m_pGS)m_pGS->BindResources(pResourceMapping, Flags); + if(m_pDS)m_pDS->BindResources(pResourceMapping, Flags); + if(m_pHS)m_pHS->BindResources(pResourceMapping, Flags); + } +} + +void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding) +{ + auto *pRenderDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( GetDevice() ); + auto &SRBAllocator = pRenderDeviceD3D12->GetSRBAllocator(); + auto pResBindingD3D12 = NEW(SRBAllocator, "ShaderResourceBindingD3D12Impl instance", ShaderResourceBindingD3D12Impl, this, false); + pResBindingD3D12->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(ppShaderResourceBinding)); +} + +const ShaderResourceLayoutD3D12& PipelineStateD3D12Impl::GetShaderResLayout(SHADER_TYPE ShaderType)const +{ + auto ShaderInd = GetShaderTypeIndex(ShaderType); + VERIFY_EXPR(m_pShaderResourceLayouts[ShaderInd] != nullptr) + return *m_pShaderResourceLayouts[ShaderInd]; +} + +ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResources(IShaderResourceBinding *pShaderResourceBinding, + CommandContext &Ctx, + bool CommitResources, + bool TransitionResources)const +{ +#ifdef VERIFY_SHADER_BINDINGS + if (pShaderResourceBinding == nullptr && + (m_RootSig.GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE_MUTABLE) != 0 || + m_RootSig.GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE_DYNAMIC) != 0)) + { + LOG_ERROR_MESSAGE("Pipeline state \"", m_Desc.Name, "\" contains mutable/dynamic shader variables and requires shader resource binding to commit all resources, but none is provided.") + } +#endif + + auto *pResBindingD3D12Impl = pShaderResourceBinding ? ValidatedCast<ShaderResourceBindingD3D12Impl>(pShaderResourceBinding) : m_pDefaultShaderResBinding.get(); + +#ifdef VERIFY_SHADER_BINDINGS + { + auto *pRefPSO = pResBindingD3D12Impl->GetPipelineState(); + if (pRefPSO != this) + { + LOG_ERROR_MESSAGE("Shader resource binding does not match the pipeline state \"", m_Desc.Name, "\". Operation will be ignored."); + return nullptr; + } + } +#endif + + if(!pResBindingD3D12Impl->StaticResourcesInitialized()) + pResBindingD3D12Impl->InitializeStaticResources(this); + +#ifdef VERIFY_SHADER_BINDINGS + pResBindingD3D12Impl->dbgVerifyResourceBindings(this); +#endif + + auto *pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>( GetDevice() ); + auto &ResourceCache = pResBindingD3D12Impl->GetResourceCache(); + if(CommitResources) + { + if(m_Desc.IsComputePipeline) + Ctx.AsComputeContext().SetRootSignature( GetD3D12RootSignature() ); + else + Ctx.AsGraphicsContext().SetRootSignature( GetD3D12RootSignature() ); + + if(TransitionResources) + (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(pDeviceD3D12Impl, ResourceCache, Ctx, m_Desc.IsComputePipeline); + else + (m_RootSig.*m_RootSig.CommitDescriptorHandles)(pDeviceD3D12Impl, ResourceCache, Ctx, m_Desc.IsComputePipeline); + } + else + { + VERIFY(TransitionResources, "Resources should be transitioned or committed or both") + m_RootSig.TransitionResources(ResourceCache, Ctx); + } + return &ResourceCache; +} + + +bool PipelineStateD3D12Impl::dbgContainsShaderResources()const +{ + return m_RootSig.GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE_STATIC) != 0 || + m_RootSig.GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE_MUTABLE) != 0 || + m_RootSig.GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE_DYNAMIC) != 0; +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp new file mode 100644 index 00000000..51c89306 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -0,0 +1,509 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "RenderDeviceD3D12Impl.h" +#include "PipelineStateD3D12Impl.h" +#include "ShaderD3D12Impl.h" +#include "TextureD3D12Impl.h" +#include "DXGITypeConversions.h" +#include "SamplerD3D12Impl.h" +#include "BufferD3D12Impl.h" +#include "ShaderResourceBindingD3D12Impl.h" +#include "DeviceContextD3D12Impl.h" + +#include "EngineMemory.h" +namespace Diligent +{ + +RenderDeviceD3D12Impl :: RenderDeviceD3D12Impl(IMemoryAllocator &RawMemAllocator, const EngineD3D12Attribs &CreationAttribs, ID3D12Device *pd3d12Device, ID3D12CommandQueue *pd3d12CmdQueue, Uint32 NumDeferredContexts) : + TRenderDeviceBase(RawMemAllocator, NumDeferredContexts, sizeof(TextureD3D12Impl), sizeof(TextureViewD3D12Impl), sizeof(BufferD3D12Impl), sizeof(BufferViewD3D12Impl), sizeof(ShaderD3D12Impl), sizeof(SamplerD3D12Impl), sizeof(PipelineStateD3D12Impl), sizeof(ShaderResourceBindingD3D12Impl)), + m_pd3d12Device(pd3d12Device), + m_pd3d12CmdQueue(pd3d12CmdQueue), + m_EngineAttribs(CreationAttribs), + m_NextFenceValue(1), + m_LastCompletedFenceValue(0), + m_FenceEventHandle( CreateEvent(nullptr, false, false, nullptr) ), + m_CmdListManager(this), + m_CPUDescriptorHeaps + { + {RawMemAllocator, this, CreationAttribs.CPUDescriptorHeapAllocationSize[0], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_FLAG_NONE}, + {RawMemAllocator, this, CreationAttribs.CPUDescriptorHeapAllocationSize[1], D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_DESCRIPTOR_HEAP_FLAG_NONE}, + {RawMemAllocator, this, CreationAttribs.CPUDescriptorHeapAllocationSize[2], D3D12_DESCRIPTOR_HEAP_TYPE_RTV, D3D12_DESCRIPTOR_HEAP_FLAG_NONE}, + {RawMemAllocator, this, CreationAttribs.CPUDescriptorHeapAllocationSize[3], D3D12_DESCRIPTOR_HEAP_TYPE_DSV, D3D12_DESCRIPTOR_HEAP_FLAG_NONE} + }, + m_GPUDescriptorHeaps + { + {RawMemAllocator, this, CreationAttribs.GPUDescriptorHeapSize[0], CreationAttribs.GPUDescriptorHeapDynamicSize[0], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE}, + {RawMemAllocator, this, CreationAttribs.GPUDescriptorHeapSize[1], CreationAttribs.GPUDescriptorHeapDynamicSize[1], D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE} + }, + m_ContextPool(STD_ALLOCATOR_RAW_MEM(ContextPoolElemType, GetRawAllocator(), "Allocator for vector<unique_ptr<CommandContext>>")), + m_AvailableContexts(STD_ALLOCATOR_RAW_MEM(CommandContext*, GetRawAllocator(), "Allocator for vector<CommandContext*>")), + m_D3D12ObjReleaseQueue(STD_ALLOCATOR_RAW_MEM(ReleaseQueueElemType, GetRawAllocator(), "Allocator for queue<ReleaseQueueElemType>")), + m_UploadHeaps(STD_ALLOCATOR_RAW_MEM(UploadHeapPoolElemType, GetRawAllocator(), "Allocator for vector<unique_ptr<DynamicUploadHeap>>")) +{ + m_DeviceCaps.DevType = DeviceType::D3D12; + m_DeviceCaps.MajorVersion = 12; + m_DeviceCaps.MinorVersion = 0; + m_DeviceCaps.bSeparableProgramSupported = True; + m_DeviceCaps.bMultithreadedResourceCreationSupported = True; + + VERIFY_EXPR(m_FenceEventHandle != INVALID_HANDLE_VALUE); + + auto hr = pd3d12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(m_pFence), reinterpret_cast<void**>(static_cast<ID3D12Fence**>(&m_pFence))); + VERIFY(SUCCEEDED(hr), "Failed to create fence"); + m_pFence->SetName(L"CommandListManager::m_pFence"); + m_pFence->Signal(m_LastCompletedFenceValue); + + hr = pd3d12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(m_pNumCompletedFramesFence), reinterpret_cast<void**>(static_cast<ID3D12Fence**>(&m_pNumCompletedFramesFence))); + VERIFY(SUCCEEDED(hr), "Failed to create fence"); + m_pNumCompletedFramesFence->SetName(L"Last completed frame fence"); + m_pNumCompletedFramesFence->Signal(m_NumCompletedFrames); +} + +RenderDeviceD3D12Impl::~RenderDeviceD3D12Impl() +{ + // Finish current frame. This will release resources taken by previous frames, and + // will signal current frame as completed. If we do not call FinishFrame(), then + // current frame will not be signaled as completed and the second call to FinishFrame() + // will not release current frame's resources. + FinishFrame(); + // Wait for the GPU to complete all its operations + IdleGPU(); + // Call FinishFrame() again to release all resources associated with the current frame + FinishFrame(); + CloseHandle(m_FenceEventHandle); + + //LinearAllocator::DestroyAll(); + //DynamicDescriptorHeap::DestroyAll(); + m_ContextPool.clear(); +} + +void RenderDeviceD3D12Impl::DisposeCommandContext(CommandContext* pCtx) +{ + std::lock_guard<std::mutex> LockGuard(m_ContextAllocationMutex); + m_AvailableContexts.push_back(pCtx); +} + +Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(CommandContext *pCtx) +{ + CComPtr<ID3D12CommandAllocator> pAllocator; + auto *pCmdList = pCtx->Close(&pAllocator); + + uint64_t FenceValue = 0; + { + std::lock_guard<std::mutex> LockGuard(m_FenceMutex); + + // Kickoff the command list + ID3D12CommandList *const ppCmdLists[] = {pCmdList}; + m_pd3d12CmdQueue->ExecuteCommandLists(1, ppCmdLists); + + // Signal the next fence value (with the GPU) + m_pd3d12CmdQueue->Signal(m_pFence, m_NextFenceValue); + + // And increment the fence value. + FenceValue = m_NextFenceValue++; + } + + m_CmdListManager.DiscardAllocator(FenceValue, pAllocator); + pCtx->DiscardUsedDescriptorHeaps(m_CurrentFrame); + + { + std::lock_guard<std::mutex> LockGuard(m_ContextAllocationMutex); + m_AvailableContexts.push_back(pCtx); + } + + return FenceValue; +} + + +Uint64 RenderDeviceD3D12Impl::IncrementFence(void) +{ + std::lock_guard<std::mutex> LockGuard(m_FenceMutex); + m_pd3d12CmdQueue->Signal(m_pFence, m_NextFenceValue); + return m_NextFenceValue++; +} + +void RenderDeviceD3D12Impl::IdleGPU(bool ReleasePendingObjects) +{ + auto FenceValue = IncrementFence(); + WaitForFence(FenceValue); + if(ReleasePendingObjects) + { + // Do not wait until the end of the frame and force deletion. + // This is necessary to release outstanding references to the + // swap chain buffers when it is resized in the middle of the frame. + // Since GPU has been idled, it is safe to do so + ProcessReleaseQueue(true); + } +} + + +bool RenderDeviceD3D12Impl::IsFenceComplete(Uint64 FenceValue) +{ + // Avoid querying the fence value by testing against the last one seen. + // The max() is to protect against an unlikely race condition that could cause the last + // completed fence value to regress. + if (FenceValue > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = std::max(m_LastCompletedFenceValue, m_pFence->GetCompletedValue()); + + return FenceValue <= m_LastCompletedFenceValue; +} + +Uint64 RenderDeviceD3D12Impl::FinishFrame() +{ + m_NumCompletedFrames = std::max(m_NumCompletedFrames, m_pNumCompletedFramesFence->GetCompletedValue()); + for (auto &UploadHeap : m_UploadHeaps) + { + // Currently upload heaps are free-threaded, so other threads must not allocate + // resources at the same time + UploadHeap->FinishFrame(m_CurrentFrame, m_NumCompletedFrames); + } + + for(Uint32 CPUHeap=0; CPUHeap < _countof(m_CPUDescriptorHeaps); ++CPUHeap) + { + m_CPUDescriptorHeaps[CPUHeap].ReleaseStaleAllocations(m_NumCompletedFrames); + } + + for(Uint32 GPUHeap=0; GPUHeap < _countof(m_GPUDescriptorHeaps); ++GPUHeap) + { + m_GPUDescriptorHeaps[GPUHeap].ReleaseStaleAllocations(m_NumCompletedFrames); + } + + + ProcessReleaseQueue(); + + // How does this work in a multi-threaded environment?? + auto CompletedFrame = m_CurrentFrame++; + m_pd3d12CmdQueue->Signal(m_pNumCompletedFramesFence, m_CurrentFrame); + return CompletedFrame; +} + +bool RenderDeviceD3D12Impl::IsFrameComplete(Uint64 Frame) +{ + // Avoid querying the fence value by testing against the last one seen. + // The max() is to protect against an unlikely race condition that could cause the last + // completed fence value to regress. + if (Frame > m_NumCompletedFrames) + m_NumCompletedFrames = std::max(m_NumCompletedFrames, m_pNumCompletedFramesFence->GetCompletedValue()); + + return Frame <= m_NumCompletedFrames; +} + +void RenderDeviceD3D12Impl::WaitForFence(Uint64 FenceValue) +{ + if (IsFenceComplete(FenceValue)) + return; + + // TODO: Think about how this might affect a multi-threaded situation. Suppose thread A + // wants to wait for fence 100, then thread B comes along and wants to wait for 99. If + // the fence can only have one event set on completion, then thread B has to wait for + // 100 before it knows 99 is ready. Maybe insert sequential events? + { + std::lock_guard<std::mutex> LockGuard(m_EventMutex); + + m_pFence->SetEventOnCompletion(FenceValue, m_FenceEventHandle); + WaitForSingleObject(m_FenceEventHandle, INFINITE); + m_LastCompletedFenceValue = FenceValue; + } +} + +DynamicUploadHeap* RenderDeviceD3D12Impl::RequestUploadHeap() +{ + std::lock_guard<std::mutex> LockGuard(m_UploadHeapMutex); + +#ifdef _DEBUG + size_t InitialSize = 1024+64; +#else + size_t InitialSize = 64<<10;//16<<20; +#endif + + auto &UploadHeapAllocator = GetRawAllocator(); + auto *pRawMem = ALLOCATE(UploadHeapAllocator, "DynamicUploadHeap instance", sizeof(DynamicUploadHeap)); + auto *pNewHeap = new (pRawMem) DynamicUploadHeap(GetRawAllocator(), true, this, InitialSize); + m_UploadHeaps.emplace_back( pNewHeap, STDDeleterRawMem<DynamicUploadHeap>(UploadHeapAllocator) ); + return pNewHeap; +} + +void RenderDeviceD3D12Impl::ReleaseUploadHeap(DynamicUploadHeap* pUploadHeap) +{ + +} + +CommandContext* RenderDeviceD3D12Impl::AllocateCommandContext(const Char *ID) +{ + std::lock_guard<std::mutex> LockGuard(m_ContextAllocationMutex); + + CommandContext* ret = nullptr; + if (m_AvailableContexts.empty()) + { + Uint32 DynamicDescriptorAllocationChunkSize[] = {256, 32}; + auto &CmdCtxAllocator = GetRawAllocator(); + auto *pRawMem = ALLOCATE(CmdCtxAllocator, "CommandContext instance", sizeof(CommandContext)); + ret = new (pRawMem) CommandContext( GetRawAllocator(), m_CmdListManager, m_GPUDescriptorHeaps, DynamicDescriptorAllocationChunkSize); + m_ContextPool.emplace_back(ret, STDDeleterRawMem<CommandContext>(CmdCtxAllocator) ); + } + else + { + ret = m_AvailableContexts.front(); + m_AvailableContexts.pop_front(); + ret->Reset(m_CmdListManager); + } + VERIFY_EXPR(ret != nullptr); + ret->SetID(ID); + //if ( ID != nullptr && *ID != 0 ) + // EngineProfiling::BeginBlock(ID, NewContext); + + return ret; +} + +void RenderDeviceD3D12Impl::SafeReleaseD3D12Object(ID3D12Object* pObj) +{ + std::lock_guard<std::mutex> LockGuard(m_ReleasedObjectsMutex); + m_D3D12ObjReleaseQueue.emplace_back( m_CurrentFrame, CComPtr<ID3D12Object>(pObj) ); +} + +void RenderDeviceD3D12Impl::ProcessReleaseQueue(bool ForceRelease) +{ + std::lock_guard<std::mutex> LockGuard(m_ReleasedObjectsMutex); + + // Release all objects whose frame number value < number of completed frames + while (m_D3D12ObjReleaseQueue.size()) + { + auto &FirstObj = m_D3D12ObjReleaseQueue.front(); + // GPU must have been idled when ForceRelease == true + if (FirstObj.first < m_NumCompletedFrames || ForceRelease) + m_D3D12ObjReleaseQueue.pop_front(); + else + break; + } +} + +bool CreateTestResource(ID3D12Device *pDevice, const D3D12_RESOURCE_DESC &ResDesc) +{ + // Set the texture pointer address to nullptr to validate input parameters + // without creating the texture + // https://msdn.microsoft.com/en-us/library/windows/desktop/dn899178(v=vs.85).aspx + + D3D12_HEAP_PROPERTIES HeapProps; + HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + HeapProps.CreationNodeMask = 1; + HeapProps.VisibleNodeMask = 1; + + auto hr = pDevice->CreateCommittedResource( &HeapProps, D3D12_HEAP_FLAG_NONE, &ResDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, __uuidof(ID3D12Resource), nullptr ); + return hr == S_FALSE; // S_FALSE means that input parameters passed validation +} + +void RenderDeviceD3D12Impl::TestTextureFormat( TEXTURE_FORMAT TexFormat ) +{ + auto &TexFormatInfo = m_TextureFormatsInfo[TexFormat]; + VERIFY( TexFormatInfo.Supported, "Texture format is not supported" ); + + auto DXGIFormat = TexFormatToDXGI_Format(TexFormat); + D3D12_RESOURCE_FLAGS DefaultResourceFlags = D3D12_RESOURCE_FLAG_NONE; + if( TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL ) + DefaultResourceFlags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + + const int TestTextureDim = 32; + const int TestTextureDepth = 8; + + D3D12_RESOURCE_DESC ResDesc = + { + D3D12_RESOURCE_DIMENSION_TEXTURE1D, + 0, // Alignment + TestTextureDim, + 1, // Height + 1, // DepthOrArraySize + 1, // MipLevels + DXGIFormat, + {1, 0}, + D3D12_TEXTURE_LAYOUT_UNKNOWN, + DefaultResourceFlags + }; + + // Create test texture 1D + TexFormatInfo.Tex1DFmt = false; + if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED ) + { + TexFormatInfo.Tex1DFmt = CreateTestResource(m_pd3d12Device, ResDesc ); + } + + // Create test texture 2D + TexFormatInfo.Tex2DFmt = false; + TexFormatInfo.TexCubeFmt = false; + TexFormatInfo.ColorRenderable = false; + TexFormatInfo.DepthRenderable = false; + TexFormatInfo.SupportsMS = false; + { + ResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + ResDesc.Height = TestTextureDim; + TexFormatInfo.Tex2DFmt = CreateTestResource( m_pd3d12Device, ResDesc ); + + if( TexFormatInfo.Tex2DFmt ) + { + { + // D3D12_TEXTURE2D_DESC CubeTexDesc = Tex2DDesc; + ResDesc.DepthOrArraySize = 6; + // CubeTexDesc.MiscFlags = D3D12_RESOURCE_MISC_TEXTURECUBE; + TexFormatInfo.TexCubeFmt = CreateTestResource( m_pd3d12Device, ResDesc ); + ResDesc.DepthOrArraySize = 1; + } + + if( TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL ) + { + ResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + ResDesc.SampleDesc.Count = 1; + TexFormatInfo.DepthRenderable = CreateTestResource( m_pd3d12Device, ResDesc ); + + if( TexFormatInfo.DepthRenderable ) + { + ResDesc.SampleDesc.Count = 4; + TexFormatInfo.SupportsMS = CreateTestResource( m_pd3d12Device, ResDesc ); + } + } + else if( TexFormatInfo.ComponentType != COMPONENT_TYPE_COMPRESSED && + TexFormatInfo.Format != DXGI_FORMAT_R9G9B9E5_SHAREDEXP ) + { + ResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + ResDesc.SampleDesc.Count = 1; + TexFormatInfo.ColorRenderable = CreateTestResource( m_pd3d12Device, ResDesc ); + if( TexFormatInfo.ColorRenderable ) + { + ResDesc.SampleDesc.Count = 4; + TexFormatInfo.SupportsMS = CreateTestResource( m_pd3d12Device, ResDesc ); + } + } + } + } + + // Create test texture 3D + TexFormatInfo.Tex3DFmt = false; + // 3D textures do not support depth formats + if( !(TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH || + TexFormatInfo.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL) ) + { + ResDesc.SampleDesc.Count = 1; + ResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; + ResDesc.Flags = DefaultResourceFlags; + ResDesc.DepthOrArraySize = TestTextureDepth; + TexFormatInfo.Tex3DFmt = CreateTestResource( m_pd3d12Device, ResDesc ); + } +} + + +IMPLEMENT_QUERY_INTERFACE( RenderDeviceD3D12Impl, IID_RenderDeviceD3D12, TRenderDeviceBase ) + +void RenderDeviceD3D12Impl::CreatePipelineState(const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState) +{ + CreateDeviceObject("Pipeline State", PipelineDesc, ppPipelineState, + [&]() + { + PipelineStateD3D12Impl *pPipelineStateD3D12( NEW(m_PSOAllocator, "PipelineStateD3D12Impl instance", PipelineStateD3D12Impl, this, PipelineDesc ) ); + pPipelineStateD3D12->QueryInterface( IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState) ); + OnCreateDeviceObject( pPipelineStateD3D12 ); + } + ); +} + + +void RenderDeviceD3D12Impl :: CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBuffer) +{ + CreateDeviceObject("buffer", BuffDesc, ppBuffer, + [&]() + { + BufferD3D12Impl *pBufferD3D12( NEW(m_BufObjAllocator, "BufferD3D12Impl instance", BufferD3D12Impl, m_BuffViewObjAllocator, this, BuffDesc, BuffData ) ); + pBufferD3D12->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); + pBufferD3D12->CreateDefaultViews(); + OnCreateDeviceObject( pBufferD3D12 ); + } + ); +} + + +void RenderDeviceD3D12Impl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader) +{ + CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, + [&]() + { + ShaderD3D12Impl *pShaderD3D12( NEW(m_ShaderObjAllocator, "ShaderD3D12Impl instance", ShaderD3D12Impl, this, ShaderCreationAttribs ) ); + pShaderD3D12->QueryInterface( IID_Shader, reinterpret_cast<IObject**>(ppShader) ); + + OnCreateDeviceObject( pShaderD3D12 ); + } + ); +} + +void RenderDeviceD3D12Impl::CreateTexture(TextureDesc& TexDesc, ID3D12Resource *pd3d12Texture, class TextureD3D12Impl **ppTexture) +{ + TextureD3D12Impl *pTextureD3D12 = NEW(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl, m_TexViewObjAllocator, this, TexDesc, pd3d12Texture ); + pTextureD3D12->QueryInterface( IID_TextureD3D12, reinterpret_cast<IObject**>(ppTexture) ); +} + +void RenderDeviceD3D12Impl :: CreateTexture(const TextureDesc& TexDesc, const TextureData &Data, ITexture **ppTexture) +{ + CreateDeviceObject( "texture", TexDesc, ppTexture, + [&]() + { + TextureD3D12Impl *pTextureD3D12 = NEW(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl, m_TexViewObjAllocator, this, TexDesc, Data ); + + pTextureD3D12->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); + pTextureD3D12->CreateDefaultViews(); + OnCreateDeviceObject( pTextureD3D12 ); + } + ); +} + +void RenderDeviceD3D12Impl :: CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler) +{ + CreateDeviceObject( "sampler", SamplerDesc, ppSampler, + [&]() + { + m_SamplersRegistry.Find( SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler) ); + if( *ppSampler == nullptr ) + { + SamplerD3D12Impl *pSamplerD3D12( NEW(m_SamplerObjAllocator, "SamplerD3D12Impl instance", SamplerD3D12Impl, this, SamplerDesc ) ); + pSamplerD3D12->QueryInterface( IID_Sampler, reinterpret_cast<IObject**>(ppSampler) ); + OnCreateDeviceObject( pSamplerD3D12 ); + m_SamplersRegistry.Add( SamplerDesc, *ppSampler ); + } + } + ); +} + +DescriptorHeapAllocation RenderDeviceD3D12Impl :: AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count /*= 1*/) +{ + VERIFY(Type >= D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && Type < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES, "Invalid heap type"); + return m_CPUDescriptorHeaps[Type].Allocate(Count); +} + +DescriptorHeapAllocation RenderDeviceD3D12Impl :: AllocateGPUDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count /*= 1*/) +{ + VERIFY(Type >= D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && Type <= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type"); + return m_GPUDescriptorHeaps[Type].Allocate(Count); +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp new file mode 100644 index 00000000..762e8a03 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp @@ -0,0 +1,334 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +/// \file +/// Routines that initialize D3D12-based engine implementation + +#include "pch.h" +#include "RenderDeviceFactoryD3D12.h" +#include "RenderDeviceD3D12Impl.h" +#include "DeviceContextD3D12Impl.h" +#include "SwapChainD3D12Impl.h" +#include "D3D12TypeConversions.h" +#include "StringTools.h" +#include "EngineMemory.h" +#include <Windows.h> +#include <dxgi1_4.h> + +namespace Diligent +{ + +void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) +{ + CComPtr<IDXGIAdapter1> adapter; + *ppAdapter = nullptr; + + for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see if the adapter supports Direct3D 12, but don't create the + // actual device yet. + if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) + { + LOG_INFO_MESSAGE("D3D12-capabale hardware found: ", NarrowString(desc.Description), " (", desc.DedicatedVideoMemory>>20, " MB)"); + break; + } + } + + *ppAdapter = adapter.Detach(); +} + +/// Creates render device and device contexts for Direct3D12-based engine implementation + +/// \param [in] CreationAttribs - Engine creation attributes. +/// \param [out] ppDevice - Address of the memory location where pointer to +/// the created device will be written +/// \param [out] ppContexts - Address of the memory location where pointers to +/// the contexts will be written. The new immediate +/// context goes at position 0. If NumDeferredContexts > 0, +/// pointers to the deferred contexts are written afterwards. +/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number +/// of deferred contexts is requested, pointers to the +/// contexts are written to ppContexts array starting +/// at position 1 +void CreateDeviceAndContextsD3D12( const EngineD3D12Attribs& CreationAttribs, + IRenderDevice **ppDevice, + Diligent::IDeviceContext **ppContexts, + Diligent::Uint32 NumDeferredContexts) +{ + VERIFY( ppDevice && ppContexts, "Null pointer is provided" ); + if( !ppDevice || !ppContexts ) + return; + + for(Uint32 Type=D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; Type < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++Type) + { + auto CPUHeapAllocSize = CreationAttribs.CPUDescriptorHeapAllocationSize[Type]; + Uint32 MaxSize = 1 << 20; + if( CPUHeapAllocSize > 1 << 20 ) + { + LOG_ERROR( "CPU Heap allocation size is too large (", CPUHeapAllocSize, "). Max allowed size is ", MaxSize ); + return; + } + + if( (CPUHeapAllocSize % 16) != 0 ) + { + LOG_ERROR( "CPU Heap allocation size (", CPUHeapAllocSize, ") is expected to be multiple of 16" ); + return; + } + } + + SetRawAllocator(CreationAttribs.pRawMemAllocator); + + *ppDevice = nullptr; + memset(ppContexts, 0, sizeof(*ppContexts) * (1+NumDeferredContexts)); + + try + { +#if defined(_DEBUG) + // Enable the D3D12 debug layer. + { + CComPtr<ID3D12Debug> debugController; + if (SUCCEEDED(D3D12GetDebugInterface(__uuidof(debugController), reinterpret_cast<void**>(static_cast<ID3D12Debug**>(&debugController)) ))) + { + debugController->EnableDebugLayer(); + } + } +#endif + + CComPtr<IDXGIFactory4> factory; + HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast<void**>(static_cast<IDXGIFactory4**>(&factory)) ); + CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory") + + CComPtr<IDXGIAdapter1> hardwareAdapter; + GetHardwareAdapter(factory, &hardwareAdapter); + + CComPtr<ID3D12Device> d3d12Device; + hr = D3D12CreateDevice(hardwareAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(d3d12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&d3d12Device)) ); + if( FAILED(hr)) + { + LOG_WARNING_MESSAGE("Failed to create hardware device. Attempting to create WARP device") + + CComPtr<IDXGIAdapter> warpAdapter; + hr = factory->EnumWarpAdapter( __uuidof(warpAdapter), reinterpret_cast<void**>(static_cast<IDXGIAdapter**>(&warpAdapter)) ); + CHECK_D3D_RESULT_THROW(hr, "Failed to enum warp adapter") + + hr = D3D12CreateDevice( warpAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(d3d12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&d3d12Device)) ); + CHECK_D3D_RESULT_THROW(hr, "Failed to crate warp device") + } + +#if _DEBUG + { + CComPtr<ID3D12InfoQueue> pInfoQueue; + hr = d3d12Device->QueryInterface(__uuidof(pInfoQueue), reinterpret_cast<void**>(static_cast<ID3D12InfoQueue**>(&pInfoQueue))); + if( SUCCEEDED(hr) ) + { + // Suppress whole categories of messages + //D3D12_MESSAGE_CATEGORY Categories[] = {}; + + // Suppress messages based on their severity level + D3D12_MESSAGE_SEVERITY Severities[] = + { + D3D12_MESSAGE_SEVERITY_INFO + }; + + // Suppress individual messages by their ID + //D3D12_MESSAGE_ID DenyIds[] = {}; + + D3D12_INFO_QUEUE_FILTER NewFilter = {}; + //NewFilter.DenyList.NumCategories = _countof(Categories); + //NewFilter.DenyList.pCategoryList = Categories; + NewFilter.DenyList.NumSeverities = _countof(Severities); + NewFilter.DenyList.pSeverityList = Severities; + //NewFilter.DenyList.NumIDs = _countof(DenyIds); + //NewFilter.DenyList.pIDList = DenyIds; + + hr = pInfoQueue->PushStorageFilter(&NewFilter); + VERIFY(SUCCEEDED(hr), "Failed to push storage filter"); + } + } +#endif + +#ifndef RELEASE + // Prevent the GPU from overclocking or underclocking to get consistent timings + d3d12Device->SetStablePowerState(TRUE); +#endif + + // Describe and create the command queue. + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + + CComPtr<ID3D12CommandQueue> pd3d12CmdQueue; + hr = d3d12Device->CreateCommandQueue(&queueDesc, __uuidof(pd3d12CmdQueue), reinterpret_cast<void**>(static_cast<ID3D12CommandQueue**>(&pd3d12CmdQueue))); + CHECK_D3D_RESULT_THROW(hr, "Failed to create command queue"); + hr = pd3d12CmdQueue->SetName(L"Main Command Queue"); + VERIFY_EXPR(SUCCEEDED(hr)); + + auto &RawMemAllocator = GetRawAllocator(); + RenderDeviceD3D12Impl *pRenderDeviceD3D12( NEW(RawMemAllocator, "RenderDeviceD3D12Impl instance", RenderDeviceD3D12Impl, CreationAttribs, d3d12Device, pd3d12CmdQueue, NumDeferredContexts ) ); + pRenderDeviceD3D12->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); + + RefCntAutoPtr<DeviceContextD3D12Impl> pImmediateCtxD3D12( NEW(RawMemAllocator, "DeviceContextD3D12Impl instance", DeviceContextD3D12Impl, pRenderDeviceD3D12, false, CreationAttribs, 0) ); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceD3D12 will + // keep a weak reference to the context + pImmediateCtxD3D12->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppContexts) ); + pRenderDeviceD3D12->SetImmediateContext(pImmediateCtxD3D12); + + for (Uint32 DeferredCtx = 0; DeferredCtx < NumDeferredContexts; ++DeferredCtx) + { + RefCntAutoPtr<DeviceContextD3D12Impl> pDeferredCtxD3D12( NEW(RawMemAllocator, "DeviceContextD3D12Impl instance", DeviceContextD3D12Impl, pRenderDeviceD3D12, true, CreationAttribs, 1+DeferredCtx) ); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceD3D12 will + // keep a weak reference to the context + pDeferredCtxD3D12->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppContexts + 1 + DeferredCtx) ); + pRenderDeviceD3D12->SetDeferredContext(DeferredCtx, pDeferredCtxD3D12); + } + } + catch( const std::runtime_error & ) + { + if( *ppDevice ) + { + (*ppDevice)->Release(); + *ppDevice = nullptr; + } + for(Uint32 ctx=0; ctx < 1 + NumDeferredContexts; ++ctx) + { + if( ppContexts[ctx] != nullptr ) + { + ppContexts[ctx]->Release(); + ppContexts[ctx] = nullptr; + } + } + + LOG_ERROR( "Failed to create device and immediate context" ); + } +} + + +/// Creates a swap chain for Direct3D12-based engine implementation + +/// \param [in] pDevice - Pointer to the render device +/// \param [in] pImmediateContext - Pointer to the immediate device context +/// \param [in] SCDesc - Swap chain description +/// \param [in] pNativeWndHandle - Platform-specific native handle of the window +/// the swap chain will be associated with: +/// * On Win32 platform, this should be window handle (HWND) +/// * On Universal Windows Platform, this should be reference to the +/// core window (Windows::UI::Core::CoreWindow) +/// +/// \param [out] ppSwapChain - Address of the memory location where pointer to the new +/// swap chain will be written +void CreateSwapChainD3D12( IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SCDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain ) +{ + VERIFY( ppSwapChain, "Null pointer is provided" ); + if( !ppSwapChain ) + return; + + *ppSwapChain = nullptr; + + try + { + auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pDevice ); + auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pImmediateContext); + auto &RawMemAllocator = GetRawAllocator(); + auto *pSwapChainD3D12 = NEW(RawMemAllocator, "SwapChainD3D12Impl instance", SwapChainD3D12Impl, SCDesc, pDeviceD3D12, pDeviceContextD3D12, pNativeWndHandle); + pSwapChainD3D12->QueryInterface( IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); + + pDeviceContextD3D12->SetSwapChain(pSwapChainD3D12); + // Bind default render target + pDeviceContextD3D12->SetRenderTargets( 0, nullptr, nullptr ); + // Set default viewport + pDeviceContextD3D12->SetViewports( 1, nullptr, 0, 0 ); + + auto NumDeferredCtx = pDeviceD3D12->GetNumDeferredContexts(); + for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) + { + if (auto pDeferredCtx = pDeviceD3D12->GetDeferredContext(ctx)) + { + auto *pDeferredCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pDeferredCtx.RawPtr()); + pDeferredCtxD3D12->SetSwapChain(pSwapChainD3D12); + // Bind default render target + pDeferredCtxD3D12->SetRenderTargets( 0, nullptr, nullptr ); + // Set default viewport + pDeferredCtxD3D12->SetViewports( 1, nullptr, 0, 0 ); + } + } + } + catch( const std::runtime_error & ) + { + if( *ppSwapChain ) + { + (*ppSwapChain)->Release(); + *ppSwapChain = nullptr; + } + + LOG_ERROR( "Failed to create the swap chain" ); + } +} + + +#ifdef DOXYGEN +/// Loads Direct3D12-based engine implementation and exports factory functions +/// \param [out] CreateDeviceFunc - Pointer to the function that creates render device and device contexts. +/// See CreateDeviceAndContextsD3D12(). +/// \param [out] CreateSwapChainFunc - Pointer to the function that creates swap chain. +/// See CreateSwapChainD3D12(). +/// \remarks Depending on the configuration and platform, the function loads different dll: +/// Platform\\Configuration | Debug | Release +/// --------------------------|-------------------------------|---------------------------- +/// x86 | GraphicsEngineD3D12_32d.dll | GraphicsEngineD3D12_32r.dll +/// x64 | GraphicsEngineD3D12_64d.dll | GraphicsEngineD3D12_64r.dll +/// +void LoadGraphicsEngineD3D12(CreateDeviceAndContextsD3D12Type &CreateDeviceFunc, CreateSwapChainD3D12Type &CreateSwapChainFunc) +{ + // This function is only required because DoxyGen refuses to generate documentation for a static function when SHOW_FILES==NO + #error This function must never be compiled; +} +#endif + + +} + + +using namespace Diligent; +extern "C" +{ + void CreateDeviceAndContextsD3D12(const EngineD3D12Attribs& EngineAttribs, IRenderDevice **ppDevice, IDeviceContext **ppContexts, Uint32 NumDeferredContexts) + { + Diligent::CreateDeviceAndContextsD3D12(EngineAttribs, ppDevice, ppContexts, NumDeferredContexts); + } + + + void CreateSwapChainD3D12(IRenderDevice *pDevice, IDeviceContext *pImmediateContext, const SwapChainDesc& SwapChainDesc, void* pNativeWndHandle, ISwapChain **ppSwapChain) + { + Diligent::CreateSwapChainD3D12(pDevice, pImmediateContext, SwapChainDesc, pNativeWndHandle, ppSwapChain); + } +} diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp new file mode 100644 index 00000000..272895af --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -0,0 +1,959 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "RootSignature.h" +#include "ShaderResourceLayoutD3D12.h" +#include "D3DShaderResourceLoader.h" +#include "ShaderD3D12Impl.h" +#include "CommandContext.h" +#include "RenderDeviceD3D12Impl.h" +#include "TextureD3D12Impl.h" +#include "BufferD3D12Impl.h" +#include "D3D12TypeConversions.h" + +namespace Diligent +{ + +RootSignature::RootParamsManager::RootParamsManager(IMemoryAllocator &MemAllocator): + m_MemAllocator(MemAllocator), + m_pMemory(nullptr, STDDeleter<void, IMemoryAllocator>(MemAllocator)) +{} + +size_t RootSignature::RootParamsManager::GetRequiredMemorySize(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges)const +{ + return sizeof(RootParameter) * (m_NumRootTables + NumExtraRootTables + m_NumRootViews + NumExtraRootViews) + sizeof(D3D12_DESCRIPTOR_RANGE) * (m_TotalDescriptorRanges + NumExtraDescriptorRanges); +} + +D3D12_DESCRIPTOR_RANGE* RootSignature::RootParamsManager::Extend(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges, Uint32 RootTableToAddRanges) +{ + VERIFY(NumExtraRootTables > 0 || NumExtraRootViews > 0 || NumExtraDescriptorRanges > 0, "At least one root table, root view or descriptor range must be added" ); + auto MemorySize = GetRequiredMemorySize(NumExtraRootTables, NumExtraRootViews, NumExtraDescriptorRanges); + VERIFY_EXPR(MemorySize > 0); + auto *pNewMemory = ALLOCATE(m_MemAllocator, "Memory buffer for root tables, root views & descriptor ranges", MemorySize); + memset(pNewMemory, 0, MemorySize); + + // Note: this order is more efficient than views->tables->ranges + auto *pNewRootTables = reinterpret_cast<RootParameter*>(pNewMemory); + auto *pNewRootViews = pNewRootTables + (m_NumRootTables + NumExtraRootTables); + auto *pCurrDescriptorRangePtr = reinterpret_cast<D3D12_DESCRIPTOR_RANGE*>(pNewRootViews+m_NumRootViews+NumExtraRootViews); + + // Copy existing root tables to new memory + for (Uint32 rt = 0; rt < m_NumRootTables; ++rt) + { + const auto &SrcTbl = GetRootTable(rt); + auto &D3D12SrcTbl = static_cast<const D3D12_ROOT_PARAMETER&>(SrcTbl).DescriptorTable; + auto NumRanges = D3D12SrcTbl.NumDescriptorRanges; + if(rt == RootTableToAddRanges) + { + VERIFY(NumExtraRootTables == 0 || NumExtraRootTables == 1, "Up to one descriptor table can be extended at a time"); + NumRanges += NumExtraDescriptorRanges; + } + new(pNewRootTables + rt) RootParameter(SrcTbl, NumRanges, pCurrDescriptorRangePtr); + pCurrDescriptorRangePtr += NumRanges; + } + + // Copy existing root view to new memory + for (Uint32 rv = 0; rv < m_NumRootViews; ++rv) + { + const auto &SrcView = GetRootView(rv); + new(pNewRootViews + rv) RootParameter(SrcView); + } + + m_pMemory.reset(pNewMemory); + m_NumRootTables += NumExtraRootTables; + m_NumRootViews += NumExtraRootViews; + m_TotalDescriptorRanges += NumExtraDescriptorRanges; + m_pRootTables = m_NumRootTables != 0 ? pNewRootTables : nullptr; + m_pRootViews = m_NumRootViews != 0 ? pNewRootViews : nullptr; + + return pCurrDescriptorRangePtr; +} + +void RootSignature::RootParamsManager::AddRootView(D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) +{ + auto *pRangePtr = Extend(0, 1, 0); + VERIFY_EXPR((char*)pRangePtr == (char*)m_pMemory.get() + GetRequiredMemorySize(0, 0, 0)); + new(m_pRootViews + m_NumRootViews-1) RootParameter(ParameterType, RootIndex, Register, 0u, Visibility, VarType); +} + +void RootSignature::RootParamsManager::AddRootTable(Uint32 RootIndex, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType, Uint32 NumRangesInNewTable) +{ + auto *pRangePtr = Extend(1, 0, NumRangesInNewTable); + VERIFY_EXPR( (char*)(pRangePtr + NumRangesInNewTable) == (char*)m_pMemory.get() + GetRequiredMemorySize(0, 0, 0)); + new(m_pRootTables + m_NumRootTables-1) RootParameter(D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, RootIndex, NumRangesInNewTable, pRangePtr, Visibility, VarType); +} + +void RootSignature::RootParamsManager::AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges) +{ + auto *pRangePtr = Extend(0, 0, NumExtraRanges, RootTableInd); + VERIFY_EXPR( (char*)pRangePtr == (char*)m_pMemory.get() + GetRequiredMemorySize(0, 0, 0)); +} + + +RootSignature::RootSignature() : + m_RootParams(GetRawAllocator()), + m_MemAllocator(GetRawAllocator()), + m_StaticSamplers( STD_ALLOCATOR_RAW_MEM(StaticSamplerAttribs, GetRawAllocator(), "Allocator for vector<StaticSamplerAttribs>") ) +{ + for(size_t s=0; s < SHADER_VARIABLE_TYPE_NUM_TYPES; ++s) + { + m_TotalSrvCbvUavSlots[s] = 0; + m_TotalSamplerSlots[s] = 0; + } + + for(size_t i=0; i < _countof(m_SrvCbvUavRootTablesMap); ++i) + m_SrvCbvUavRootTablesMap[i] = InvalidRootTableIndex; + for(size_t i=0; i < _countof(m_SamplerRootTablesMap); ++i) + m_SamplerRootTablesMap[i] = InvalidRootTableIndex; + +} + +static D3D12_SHADER_VISIBILITY ShaderTypeInd2ShaderVisibilityMap[] +{ + D3D12_SHADER_VISIBILITY_VERTEX, // 0 + D3D12_SHADER_VISIBILITY_PIXEL, // 1 + D3D12_SHADER_VISIBILITY_GEOMETRY, // 2 + D3D12_SHADER_VISIBILITY_HULL, // 3 + D3D12_SHADER_VISIBILITY_DOMAIN, // 4 + D3D12_SHADER_VISIBILITY_ALL // 5 +}; +D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType) +{ + auto ShaderInd = GetShaderTypeIndex(ShaderType); + auto ShaderVisibility = ShaderTypeInd2ShaderVisibilityMap[ShaderInd]; +#ifdef _DEBUG + switch (ShaderType) + { + case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX); break; + case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL); break; + case SHADER_TYPE_GEOMETRY: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY); break; + case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break; + case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break; + case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; + default: LOG_ERROR("Unknown shader type (", ShaderType, ")"); break; + } +#endif + return ShaderVisibility; +} + +static SHADER_TYPE ShaderVisibility2ShaderTypeMap[] = +{ + SHADER_TYPE_COMPUTE, // D3D12_SHADER_VISIBILITY_ALL = 0 + SHADER_TYPE_VERTEX, // D3D12_SHADER_VISIBILITY_VERTEX = 1 + SHADER_TYPE_HULL, // D3D12_SHADER_VISIBILITY_HULL = 2 + SHADER_TYPE_DOMAIN, // D3D12_SHADER_VISIBILITY_DOMAIN = 3 + SHADER_TYPE_GEOMETRY, // D3D12_SHADER_VISIBILITY_GEOMETRY = 4 + SHADER_TYPE_PIXEL // D3D12_SHADER_VISIBILITY_PIXEL = 5 +}; +SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility) +{ + VERIFY_EXPR(ShaderVisibility >= D3D12_SHADER_VISIBILITY_ALL && ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL ); + auto ShaderType = ShaderVisibility2ShaderTypeMap[ShaderVisibility]; +#ifdef _DEBUG + switch (ShaderVisibility) + { + case D3D12_SHADER_VISIBILITY_VERTEX: VERIFY_EXPR(ShaderType == SHADER_TYPE_VERTEX); break; + case D3D12_SHADER_VISIBILITY_PIXEL: VERIFY_EXPR(ShaderType == SHADER_TYPE_PIXEL); break; + case D3D12_SHADER_VISIBILITY_GEOMETRY: VERIFY_EXPR(ShaderType == SHADER_TYPE_GEOMETRY); break; + case D3D12_SHADER_VISIBILITY_HULL: VERIFY_EXPR(ShaderType == SHADER_TYPE_HULL); break; + case D3D12_SHADER_VISIBILITY_DOMAIN: VERIFY_EXPR(ShaderType == SHADER_TYPE_DOMAIN); break; + case D3D12_SHADER_VISIBILITY_ALL: VERIFY_EXPR(ShaderType == SHADER_TYPE_COMPUTE); break; + default: LOG_ERROR("Unknown shader visibility (", ShaderVisibility, ")"); break; + } +#endif + return ShaderType; +} + + +static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] +{ + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_UAV = ( D3D12_DESCRIPTOR_RANGE_TYPE_SRV + 1 ) , + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_CBV = ( D3D12_DESCRIPTOR_RANGE_TYPE_UAV + 1 ) , + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER //D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = ( D3D12_DESCRIPTOR_RANGE_TYPE_CBV + 1 ) +}; +D3D12_DESCRIPTOR_HEAP_TYPE HeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +{ + VERIFY_EXPR(RangeType >= D3D12_DESCRIPTOR_RANGE_TYPE_SRV && RangeType <= D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER); + auto HeapType = RangeType2HeapTypeMap[RangeType]; + +#ifdef _DEBUG + switch (RangeType) + { + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); break; + default: UNEXPECTED("Unexpected descriptor range type"); break; + } +#endif + return HeapType; +} + + +void RootSignature::InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &SamplerAttribs) +{ + auto ShaderVisibility = GetShaderVisibility(ShaderType); + auto SamplerFound = false; + for (auto &StSmplr : m_StaticSamplers) + { + if (StSmplr.ShaderVisibility == ShaderVisibility && + TextureName.compare(StSmplr.SamplerDesc.TextureName) == 0) + { + StSmplr.ShaderRegister = SamplerAttribs.BindPoint; + StSmplr.ArraySize = SamplerAttribs.BindCount; + StSmplr.RegisterSpace = 0; + SamplerFound = true; + break; + } + } + + if (!SamplerFound) + { + LOG_ERROR("Failed to find static sampler for variable \"", TextureName, '\"') + } +} + +void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderType, const D3DShaderResourceAttribs &ShaderResAttribs, D3D12_DESCRIPTOR_RANGE_TYPE RangeType, Uint32 &RootIndex, Uint32 &OffsetFromTableStart) +{ + auto ShaderInd = GetShaderTypeIndex(ShaderType); + auto ShaderVisibility = GetShaderVisibility(ShaderType); + if (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && ShaderResAttribs.BindCount == 1) + { + // Allocate CBV directly in the root signature + RootIndex = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); + OffsetFromTableStart = 0; + + m_RootParams.AddRootView(D3D12_ROOT_PARAMETER_TYPE_CBV, RootIndex, ShaderResAttribs.BindPoint, ShaderVisibility, ShaderResAttribs.GetVariableType()); + } + else + { + // Use the same table for static and mutable resources. Mark table type as static (mutable is an equivalent option) + auto RootTableType = (ShaderResAttribs.GetVariableType() == SHADER_VARIABLE_TYPE_DYNAMIC) ? SHADER_VARIABLE_TYPE_DYNAMIC : SHADER_VARIABLE_TYPE_STATIC; + auto TableIndKey = ShaderInd * SHADER_VARIABLE_TYPE_NUM_TYPES + RootTableType; + auto &RootTableInd = (( RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER ) ? m_SamplerRootTablesMap : m_SrvCbvUavRootTablesMap)[ TableIndKey ]; + if (RootTableInd == InvalidRootTableIndex) + { + RootIndex = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); + VERIFY_EXPR(m_RootParams.GetNumRootTables() < 255); + RootTableInd = static_cast<Uint8>( m_RootParams.GetNumRootTables() ); + m_RootParams.AddRootTable(RootIndex, ShaderVisibility, RootTableType, 1); + } + else + { + m_RootParams.AddDescriptorRanges(RootTableInd, 1); + } + + auto &CurrParam = m_RootParams.GetRootTable(RootTableInd); + RootIndex = CurrParam.GetRootIndex(); + + const auto& d3d12RootParam = static_cast<const D3D12_ROOT_PARAMETER&>(CurrParam); + + VERIFY( d3d12RootParam.ShaderVisibility == ShaderVisibility, "Shader visibility is not correct" ); + + OffsetFromTableStart = CurrParam.GetDescriptorTableSize(); + + Uint32 NewDescriptorRangeIndex = d3d12RootParam.DescriptorTable.NumDescriptorRanges-1; + CurrParam.SetDescriptorRange(NewDescriptorRangeIndex, RangeType, ShaderResAttribs.BindPoint, ShaderResAttribs.BindCount, 0, OffsetFromTableStart); + } +} + + +#ifdef _DEBUG +void RootSignature::dbgVerifyRootParameters()const +{ + Uint32 dbgTotalSrvCbvUavSlots = 0; + Uint32 dbgTotalSamplerSlots = 0; + for(Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + { + auto &RootTable = m_RootParams.GetRootTable(rt); + auto &Param = static_cast<const D3D12_ROOT_PARAMETER&>( RootTable ); + VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); + auto &Table = Param.DescriptorTable; + VERIFY(Table.NumDescriptorRanges > 0, "Descriptor table is expected to be non-empty"); + VERIFY(Table.pDescriptorRanges[0].OffsetInDescriptorsFromTableStart == 0, "Descriptor table is expected to start at 0 offset"); + bool IsResourceTable = Table.pDescriptorRanges[0].RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + for (Uint32 r = 0; r < Table.NumDescriptorRanges; ++r) + { + const auto &range = Table.pDescriptorRanges[r]; + if(IsResourceTable) + { + VERIFY( range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV || + range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV || + range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Resource type is expected to be SRV, CBV or UAV") + dbgTotalSrvCbvUavSlots += range.NumDescriptors; + } + else + { + VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Resource type is expected to be sampler") + dbgTotalSamplerSlots += range.NumDescriptors; + } + + if(r>0) + { + VERIFY(Table.pDescriptorRanges[r].OffsetInDescriptorsFromTableStart == Table.pDescriptorRanges[r-1].OffsetInDescriptorsFromTableStart+Table.pDescriptorRanges[r-1].NumDescriptors, "Ranges in a descriptor table are expected to be consequtive"); + } + } + } + + for(Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + { + auto &RootView = m_RootParams.GetRootView(rv); + auto &Param = static_cast<const D3D12_ROOT_PARAMETER&>( RootView ); + VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root parameter is expected to be a CBV"); + } + + VERIFY(dbgTotalSrvCbvUavSlots == + m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_STATIC] + + m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_MUTABLE] + + m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_DYNAMIC], "Unexpected number of SRV CBV UAV resource slots") + VERIFY(dbgTotalSamplerSlots == + m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_STATIC] + + m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_MUTABLE] + + m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_DYNAMIC], "Unexpected number of sampler slots") +} +#endif + +void RootSignature::AllocateStaticSamplers(IShader* const*ppShaders, Uint32 NumShaders) +{ + Uint32 TotalSamplers = 0; + for(Uint32 s=0;s < NumShaders; ++s) + TotalSamplers += ppShaders[s]->GetDesc().NumStaticSamplers; + if (TotalSamplers > 0) + { + m_StaticSamplers.reserve(TotalSamplers); + for(Uint32 sh=0;sh < NumShaders; ++sh) + { + const auto &Desc = ppShaders[sh]->GetDesc(); + for(Uint32 sam=0; sam < Desc.NumStaticSamplers; ++sam) + { + m_StaticSamplers.emplace_back(Desc.StaticSamplers[sam], GetShaderVisibility(Desc.ShaderType)); + } + } + VERIFY_EXPR(m_StaticSamplers.size() == TotalSamplers); + } +} + +void RootSignature::Finalize(ID3D12Device *pd3d12Device) +{ + for(Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + { + auto &RootTbl = m_RootParams.GetRootTable(rt); + auto &d3d12RootParam = static_cast<const D3D12_ROOT_PARAMETER&>(RootTbl); + VERIFY_EXPR(d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE); + + auto TableSize = RootTbl.GetDescriptorTableSize(); + VERIFY(d3d12RootParam.DescriptorTable.NumDescriptorRanges > 0 && TableSize > 0, "Unexpected empty descriptor table"); + auto IsSamplerTable = d3d12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + auto VarType = RootTbl.GetShaderVariableType(); + (IsSamplerTable ? m_TotalSamplerSlots : m_TotalSrvCbvUavSlots)[VarType] += TableSize; + } + +#ifdef _DEBUG + dbgVerifyRootParameters(); +#endif + + D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc; + rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + + auto TotalParams = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); + std::vector<D3D12_ROOT_PARAMETER, STDAllocatorRawMem<D3D12_ROOT_PARAMETER> > D3D12Parameters( TotalParams, D3D12_ROOT_PARAMETER(), STD_ALLOCATOR_RAW_MEM(D3D12_ROOT_PARAMETER, GetRawAllocator(), "Allocator for vector<D3D12_ROOT_PARAMETER>") ); + for(Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + { + auto &RootTable = m_RootParams.GetRootTable(rt); + const D3D12_ROOT_PARAMETER &SrcParam = RootTable; + VERIFY( SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && SrcParam.DescriptorTable.NumDescriptorRanges > 0, "Non-empty descriptor table is expected" ) + D3D12Parameters[RootTable.GetRootIndex()] = SrcParam; + } + for(Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + { + auto &RootView = m_RootParams.GetRootView(rv); + const D3D12_ROOT_PARAMETER &SrcParam = RootView; + VERIFY( SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root CBV is expected" ) + D3D12Parameters[RootView.GetRootIndex()] = SrcParam; + } + + + rootSignatureDesc.NumParameters = static_cast<UINT>(D3D12Parameters.size()); + rootSignatureDesc.pParameters = D3D12Parameters.size() ? D3D12Parameters.data() : nullptr; + + UINT TotalD3D12StaticSamplers = 0; + for(const auto &StSam : m_StaticSamplers) + TotalD3D12StaticSamplers += StSam.ArraySize; + rootSignatureDesc.NumStaticSamplers = TotalD3D12StaticSamplers; + rootSignatureDesc.pStaticSamplers = nullptr; + std::vector<D3D12_STATIC_SAMPLER_DESC, STDAllocatorRawMem<D3D12_STATIC_SAMPLER_DESC> > D3D12StaticSamplers( STD_ALLOCATOR_RAW_MEM(D3D12_STATIC_SAMPLER_DESC, GetRawAllocator(), "Allocator for vector<D3D12_STATIC_SAMPLER_DESC>") ); + D3D12StaticSamplers.reserve(TotalD3D12StaticSamplers); + if ( !m_StaticSamplers.empty() ) + { + for(size_t s=0; s < m_StaticSamplers.size(); ++s) + { + const auto &StSmplrDesc = m_StaticSamplers[s]; + const auto &SamDesc = StSmplrDesc.SamplerDesc.Desc; + for(UINT ArrInd = 0; ArrInd < StSmplrDesc.ArraySize; ++ArrInd) + { + D3D12StaticSamplers.emplace_back( + D3D12_STATIC_SAMPLER_DESC{ + FilterTypeToD3D12Filter(SamDesc.MinFilter, SamDesc.MagFilter, SamDesc.MipFilter), + TexAddressModeToD3D12AddressMode(SamDesc.AddressU), + TexAddressModeToD3D12AddressMode(SamDesc.AddressV), + TexAddressModeToD3D12AddressMode(SamDesc.AddressW), + SamDesc.MipLODBias, + SamDesc.MaxAnisotropy, + ComparisonFuncToD3D12ComparisonFunc(SamDesc.ComparisonFunc), + BorderColorToD3D12StaticBorderColor(SamDesc.BorderColor), + SamDesc.MinLOD, + SamDesc.MaxLOD, + StSmplrDesc.ShaderRegister + ArrInd, + StSmplrDesc.RegisterSpace, + StSmplrDesc.ShaderVisibility + } + ); + } + } + rootSignatureDesc.pStaticSamplers = D3D12StaticSamplers.data(); + + // Release static samplers array, we no longer need it + std::vector<StaticSamplerAttribs, STDAllocatorRawMem<StaticSamplerAttribs> > EmptySamplers( STD_ALLOCATOR_RAW_MEM(StaticSamplerAttribs, GetRawAllocator(), "Allocator for vector<StaticSamplerAttribs>") ); + m_StaticSamplers.swap( EmptySamplers ); + + VERIFY_EXPR(D3D12StaticSamplers.size() == TotalD3D12StaticSamplers); + } + + + CComPtr<ID3DBlob> signature; + CComPtr<ID3DBlob> error; + HRESULT hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); + hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pd3d12RootSignature), reinterpret_cast<void**>( static_cast<ID3D12RootSignature**>(&m_pd3d12RootSignature))); + CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature") + + + bool bHasDynamicResources = m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_DYNAMIC]!=0 || m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_DYNAMIC]!=0; + if(bHasDynamicResources) + { + CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<false>; + TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<true>; + } + else + { + CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<false>; + TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<true>; + } +} + +void RootSignature::InitResourceCache(RenderDeviceD3D12Impl *pDeviceD3D12Impl, ShaderResourceCacheD3D12& ResourceCache, IMemoryAllocator &CacheMemAllocator)const +{ + std::vector<Uint32, STDAllocatorRawMem<Uint32> > CacheTableSizes(m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(), 0, STD_ALLOCATOR_RAW_MEM(Uint32, GetRawAllocator(), "Allocator for vector<Uint32>") ); + for(Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + { + auto &RootParam = m_RootParams.GetRootTable(rt); + CacheTableSizes[RootParam.GetRootIndex()] = RootParam.GetDescriptorTableSize(); + } + + for(Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + { + auto &RootParam = m_RootParams.GetRootView(rv); + CacheTableSizes[RootParam.GetRootIndex()] = 1; + } + ResourceCache.Initialize(CacheMemAllocator, static_cast<Uint32>(CacheTableSizes.size()), CacheTableSizes.data()); + + Uint32 TotalSrvCbvUavDescriptors = + m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_STATIC] + + m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_MUTABLE]; + Uint32 TotalSamplerDescriptors = + m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_STATIC] + + m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_MUTABLE]; + + DescriptorHeapAllocation CbcSrvUavHeapSpace, SamplerHeapSpace; + if(TotalSrvCbvUavDescriptors) + CbcSrvUavHeapSpace = pDeviceD3D12Impl->AllocateGPUDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, TotalSrvCbvUavDescriptors); + + if(TotalSamplerDescriptors) + SamplerHeapSpace = pDeviceD3D12Impl->AllocateGPUDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, TotalSamplerDescriptors); + + Uint32 SrvCbvUavTblStartOffset = 0; + Uint32 SamplerTblStartOffset = 0; + for(Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + { + auto &RootParam = m_RootParams.GetRootTable(rt); + const auto& D3D12RootParam = static_cast<const D3D12_ROOT_PARAMETER&>(RootParam); + auto &RootTableCache = ResourceCache.GetRootTable(RootParam.GetRootIndex()); + + SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; +#ifdef _DEBUG + dbgShaderType = ShaderTypeFromShaderVisibility(D3D12RootParam.ShaderVisibility); +#endif + VERIFY_EXPR( D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE ) + + auto TableSize = RootParam.GetDescriptorTableSize(); + VERIFY(TableSize > 0, "Unexpected empty descriptor table"); + + auto HeapType = HeapTypeFromRangeType(D3D12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType); + +#ifdef _DEBUG + RootTableCache.SetDebugAttribs( TableSize, HeapType, dbgShaderType ); +#endif + + // Space for dynamic variables is allocated at every draw call + if( RootParam.GetShaderVariableType() != SHADER_VARIABLE_TYPE_DYNAMIC ) + { + if( HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ) + { + RootTableCache.TableStartOffset = SrvCbvUavTblStartOffset; + SrvCbvUavTblStartOffset += TableSize; + } + else + { + RootTableCache.TableStartOffset = SamplerTblStartOffset; + SamplerTblStartOffset += TableSize; + } + } + else + { + VERIFY_EXPR(RootTableCache.TableStartOffset == ShaderResourceCacheD3D12::InvalidDescriptorOffset) + } + } + +#ifdef _DEBUG + for(Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + { + auto &RootParam = m_RootParams.GetRootView(rv); + const auto& D3D12RootParam = static_cast<const D3D12_ROOT_PARAMETER&>(RootParam); + auto &RootTableCache = ResourceCache.GetRootTable(RootParam.GetRootIndex()); + VERIFY_EXPR(RootTableCache.TableStartOffset == ShaderResourceCacheD3D12::InvalidDescriptorOffset) + + SHADER_TYPE dbgShaderType = ShaderTypeFromShaderVisibility(D3D12RootParam.ShaderVisibility); + VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); + RootTableCache.SetDebugAttribs( 1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType ); + } +#endif + + VERIFY_EXPR(SrvCbvUavTblStartOffset == SrvCbvUavTblStartOffset); + VERIFY_EXPR(SamplerTblStartOffset == SamplerTblStartOffset); + + ResourceCache.SetDescriptorHeapSpace(std::move(CbcSrvUavHeapSpace), std::move(SamplerHeapSpace)); +} + +const D3D12_RESOURCE_STATES D3D12_RESOURCE_STATE_SHADER_RESOURCE = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + +__forceinline +void TransitionResource(CommandContext &Ctx, + ShaderResourceCacheD3D12::Resource &Res, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +{ + switch (Res.Type) + { + case CachedResourceType::CBV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV, "Unexpected descriptor range type"); + // Not using QueryInterface() for the sake of efficiency + auto *pBuffToTransition = ValidatedCast<BufferD3D12Impl>(Res.pObject.RawPtr()); + if( !pBuffToTransition->CheckAllStates(D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER) ) + Ctx.TransitionResource(pBuffToTransition, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER ); + } + break; + + case CachedResourceType::BufSRV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); + auto *pBuffViewD3D12 = ValidatedCast<BufferViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pBuffToTransition = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + if( !pBuffToTransition->CheckAllStates(D3D12_RESOURCE_STATE_SHADER_RESOURCE) ) + Ctx.TransitionResource(pBuffToTransition, D3D12_RESOURCE_STATE_SHADER_RESOURCE ); + } + break; + + case CachedResourceType::BufUAV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); + auto *pBuffViewD3D12 = ValidatedCast<BufferViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pBuffToTransition = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + if( !pBuffToTransition->CheckAllStates(D3D12_RESOURCE_STATE_UNORDERED_ACCESS) ) + Ctx.TransitionResource(pBuffToTransition, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); + } + break; + + case CachedResourceType::TexSRV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); + auto *pTexViewD3D12 = ValidatedCast<TextureViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pTexToTransition = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + if( !pTexToTransition->CheckAllStates(D3D12_RESOURCE_STATE_SHADER_RESOURCE) ) + Ctx.TransitionResource(pTexToTransition, D3D12_RESOURCE_STATE_SHADER_RESOURCE ); + } + break; + + case CachedResourceType::TexUAV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); + auto *pTexViewD3D12 = ValidatedCast<TextureViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pTexToTransition = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + if( !pTexToTransition->CheckAllStates(D3D12_RESOURCE_STATE_UNORDERED_ACCESS) ) + Ctx.TransitionResource(pTexToTransition, D3D12_RESOURCE_STATE_UNORDERED_ACCESS ); + } + break; + + case CachedResourceType::Sampler: + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Unexpected descriptor range type"); + break; + + default: + // Resource not bound + VERIFY(Res.Type == CachedResourceType::Unknown, "Unexpected resource type") + VERIFY(Res.pObject == nullptr && Res.CPUDescriptorHandle.ptr == 0, "Bound resource is unexpected") + } +} + + +#ifdef _DEBUG +void DbgVerifyResourceState(ShaderResourceCacheD3D12::Resource &Res, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +{ + switch (Res.Type) + { + case CachedResourceType::CBV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV, "Unexpected descriptor range type"); + // Not using QueryInterface() for the sake of efficiency + auto *pBuffToTransition = ValidatedCast<BufferD3D12Impl>(Res.pObject.RawPtr()); + auto State = pBuffToTransition->GetState(); + if( (State & D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER) != D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER ) + LOG_ERROR_MESSAGE("Resource \"", pBuffToTransition->GetDesc().Name, "\" is not in D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + } + break; + + case CachedResourceType::BufSRV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); + auto *pBuffViewD3D12 = ValidatedCast<BufferViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pBuffToTransition = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + auto State = pBuffToTransition->GetState(); + if( (State & D3D12_RESOURCE_STATE_SHADER_RESOURCE) != D3D12_RESOURCE_STATE_SHADER_RESOURCE ) + LOG_ERROR_MESSAGE("Resource \"", pBuffToTransition->GetDesc().Name, "\" is not in correct state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + } + break; + + case CachedResourceType::BufUAV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); + auto *pBuffViewD3D12 = ValidatedCast<BufferViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pBuffToTransition = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + auto State = pBuffToTransition->GetState(); + if( (State & D3D12_RESOURCE_STATE_UNORDERED_ACCESS) != D3D12_RESOURCE_STATE_UNORDERED_ACCESS ) + LOG_ERROR_MESSAGE("Resource \"", pBuffToTransition->GetDesc().Name, "\" is not in D3D12_RESOURCE_STATE_UNORDERED_ACCESS state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + } + break; + + case CachedResourceType::TexSRV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); + auto *pTexViewD3D12 = ValidatedCast<TextureViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pTexToTransition = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + auto State = pTexToTransition->GetState(); + if( (State & D3D12_RESOURCE_STATE_SHADER_RESOURCE) != D3D12_RESOURCE_STATE_SHADER_RESOURCE ) + LOG_ERROR_MESSAGE("Resource \"", pTexToTransition->GetDesc().Name, "\" is not in correct state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + } + break; + + case CachedResourceType::TexUAV: + { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); + auto *pTexViewD3D12 = ValidatedCast<TextureViewD3D12Impl>(Res.pObject.RawPtr()); + auto *pTexToTransition = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + auto State = pTexToTransition->GetState(); + if( (State & D3D12_RESOURCE_STATE_UNORDERED_ACCESS) != D3D12_RESOURCE_STATE_UNORDERED_ACCESS ) + LOG_ERROR_MESSAGE("Resource \"", pTexToTransition->GetDesc().Name, "\" is not in D3D12_RESOURCE_STATE_UNORDERED_ACCESS state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + } + break; + + case CachedResourceType::Sampler: + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Unexpected descriptor range type"); + break; + + default: + // Resource not bound + VERIFY(Res.Type == CachedResourceType::Unknown, "Unexpected resource type") + VERIFY(Res.pObject == nullptr && Res.CPUDescriptorHandle.ptr == 0, "Bound resource is unexpected") + } +} +#endif + +template<class TOperation> +__forceinline void RootSignature::RootParamsManager::ProcessRootTables(TOperation Operation)const +{ + for(Uint32 rt = 0; rt < m_NumRootTables; ++rt) + { + auto &RootTable = GetRootTable(rt); + auto RootInd = RootTable.GetRootIndex(); + const D3D12_ROOT_PARAMETER& D3D12Param = RootTable; + + VERIFY_EXPR(D3D12Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE); + + auto &d3d12Table = D3D12Param.DescriptorTable; + VERIFY(d3d12Table.NumDescriptorRanges > 0 && RootTable.GetDescriptorTableSize() > 0, "Unexepected empty descriptor table"); + bool IsResourceTable = d3d12Table.pDescriptorRanges[0].RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; +#ifdef _DEBUG + dbgHeapType = IsResourceTable ? D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV : D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; +#endif + Operation(RootInd, RootTable, D3D12Param, IsResourceTable, dbgHeapType); + } +} + +template<class TOperation> +__forceinline void ProcessCachedTableResources(Uint32 RootInd, + const D3D12_ROOT_PARAMETER& D3D12Param, + ShaderResourceCacheD3D12& ResourceCache, + D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType, + TOperation Operation) +{ + for (UINT r = 0; r < D3D12Param.DescriptorTable.NumDescriptorRanges; ++r) + { + const auto &range = D3D12Param.DescriptorTable.pDescriptorRanges[r]; + for (UINT d = 0; d < range.NumDescriptors; ++d) + { + SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; +#ifdef _DEBUG + dbgShaderType = ShaderTypeFromShaderVisibility(D3D12Param.ShaderVisibility); + VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type"); +#endif + auto OffsetFromTableStart = range.OffsetInDescriptorsFromTableStart + d; + auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, dbgShaderType); + + Operation(OffsetFromTableStart, range, Res); + } + } +} + + +template<bool PerformResourceTransitions> +void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceD3D12Impl *pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + CommandContext &Ctx, + bool IsCompute)const +{ + auto *pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); + + Uint32 NumDynamicCbvSrvUavDescriptors = m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_DYNAMIC]; + Uint32 NumDynamicSamplerDescriptors = m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_DYNAMIC]; + VERIFY_EXPR(NumDynamicCbvSrvUavDescriptors > 0 || NumDynamicSamplerDescriptors > 0); + + DescriptorHeapAllocation DynamicCbvSrvUavDescriptors, DynamicSamplerDescriptors; + if(NumDynamicCbvSrvUavDescriptors) + DynamicCbvSrvUavDescriptors = Ctx.AllocateDynamicGPUVisibleDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, NumDynamicCbvSrvUavDescriptors); + if(NumDynamicSamplerDescriptors) + DynamicSamplerDescriptors = Ctx.AllocateDynamicGPUVisibleDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, NumDynamicSamplerDescriptors); + + CommandContext::ShaderDescriptorHeaps Heaps(ResourceCache.GetSrvCbvUavDescriptorHeap(), ResourceCache.GetSamplerDescriptorHeap()); + if(Heaps.pSamplerHeap == nullptr) + Heaps.pSamplerHeap = DynamicSamplerDescriptors.GetDescriptorHeap(); + + if(Heaps.pSrvCbvUavHeap == nullptr) + Heaps.pSrvCbvUavHeap = DynamicCbvSrvUavDescriptors.GetDescriptorHeap(); + + if(NumDynamicCbvSrvUavDescriptors) + VERIFY(DynamicCbvSrvUavDescriptors.GetDescriptorHeap() == Heaps.pSrvCbvUavHeap, "Inconsistent CbvSrvUav descriptor heaps" ) + if(NumDynamicSamplerDescriptors) + VERIFY(DynamicSamplerDescriptors.GetDescriptorHeap() == Heaps.pSamplerHeap, "Inconsistent Sampler descriptor heaps" ) + + if(Heaps) + Ctx.SetDescriptorHeaps(Heaps); + + // Offset to the beginning of the current dynamic CBV_SRV_UAV/SAMPLER table from + // the start of the allocation + Uint32 DynamicCbvSrvUavTblOffset = 0; + Uint32 DynamicSamplerTblOffset = 0; + + m_RootParams.ProcessRootTables( + [&](Uint32 RootInd, const RootParameter &RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) + { + D3D12_GPU_DESCRIPTOR_HANDLE RootTableGPUDescriptorHandle; + bool IsDynamicTable = RootTable.GetShaderVariableType() == SHADER_VARIABLE_TYPE_DYNAMIC; + if (IsDynamicTable) + { + if( IsResourceTable ) + RootTableGPUDescriptorHandle = DynamicCbvSrvUavDescriptors.GetGpuHandle(DynamicCbvSrvUavTblOffset); + else + RootTableGPUDescriptorHandle = DynamicSamplerDescriptors.GetGpuHandle(DynamicSamplerTblOffset); + } + else + { + RootTableGPUDescriptorHandle = IsResourceTable ? + ResourceCache.GetShaderVisibleTableGPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV>(RootInd) : + ResourceCache.GetShaderVisibleTableGPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(RootInd); + VERIFY(RootTableGPUDescriptorHandle.ptr != 0, "Unexpected null GPU descriptor handle") + } + + if(IsCompute) + Ctx.GetCommandList()->SetComputeRootDescriptorTable(RootInd, RootTableGPUDescriptorHandle); + else + Ctx.GetCommandList()->SetGraphicsRootDescriptorTable(RootInd, RootTableGPUDescriptorHandle); + + ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, + [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) + { + if(PerformResourceTransitions) + { + TransitionResource(Ctx, Res, range.RangeType); + } +#ifdef _DEBUG + else + { + DbgVerifyResourceState(Res, range.RangeType); + } +#endif + + if(IsDynamicTable) + { + if (IsResourceTable) + { + if( Res.CPUDescriptorHandle.ptr == 0 ) + LOG_ERROR_MESSAGE("No valid CbvSrvUav descriptor handle found for root parameter ", RootInd, ", descriptor slot ", OffsetFromTableStart) + + VERIFY( DynamicCbvSrvUavTblOffset < NumDynamicCbvSrvUavDescriptors, "Not enough space in the descriptor heap allocation") + + pd3d12Device->CopyDescriptorsSimple(1, DynamicCbvSrvUavDescriptors.GetCpuHandle(DynamicCbvSrvUavTblOffset), Res.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + ++DynamicCbvSrvUavTblOffset; + } + else + { + if( Res.CPUDescriptorHandle.ptr == 0 ) + LOG_ERROR_MESSAGE("No valid sampler descriptor handle found for root parameter ", RootInd, ", descriptor slot ", OffsetFromTableStart) + + VERIFY( DynamicSamplerTblOffset < NumDynamicSamplerDescriptors, "Not enough space in the descriptor heap allocation") + + pd3d12Device->CopyDescriptorsSimple(1, DynamicSamplerDescriptors.GetCpuHandle(DynamicSamplerTblOffset), Res.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + ++DynamicSamplerTblOffset; + } + } + } + ); + } + ); + + VERIFY_EXPR( DynamicCbvSrvUavTblOffset == NumDynamicCbvSrvUavDescriptors ); + VERIFY_EXPR( DynamicSamplerTblOffset == NumDynamicSamplerDescriptors ); +} + +template<bool PerformResourceTransitions> +void RootSignature::CommitDescriptorHandlesInternal_SM(RenderDeviceD3D12Impl *pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + CommandContext &Ctx, + bool IsCompute)const +{ + VERIFY_EXPR(m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_DYNAMIC] == 0 && m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_DYNAMIC] == 0); + + CommandContext::ShaderDescriptorHeaps Heaps(ResourceCache.GetSrvCbvUavDescriptorHeap(), ResourceCache.GetSamplerDescriptorHeap()); + if(Heaps) + Ctx.SetDescriptorHeaps(Heaps); + + m_RootParams.ProcessRootTables( + [&](Uint32 RootInd, const RootParameter &RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) + { + VERIFY(RootTable.GetShaderVariableType() != SHADER_VARIABLE_TYPE_DYNAMIC, "Unexpected dynamic resource"); + + D3D12_GPU_DESCRIPTOR_HANDLE RootTableGPUDescriptorHandle = IsResourceTable ? + ResourceCache.GetShaderVisibleTableGPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV>(RootInd) : + ResourceCache.GetShaderVisibleTableGPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(RootInd); + VERIFY(RootTableGPUDescriptorHandle.ptr != 0, "Unexpected null GPU descriptor handle") + + if(IsCompute) + Ctx.GetCommandList()->SetComputeRootDescriptorTable(RootInd, RootTableGPUDescriptorHandle); + else + Ctx.GetCommandList()->SetGraphicsRootDescriptorTable(RootInd, RootTableGPUDescriptorHandle); + + if(PerformResourceTransitions) + { + ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, + [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) + { + TransitionResource(Ctx, Res, range.RangeType); + } + ); + } +#ifdef _DEBUG + else + { + ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, + [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) + { + DbgVerifyResourceState(Res, range.RangeType); + } + ); + } +#endif + } + ); +} + + +void RootSignature::TransitionResources(ShaderResourceCacheD3D12& ResourceCache, + class CommandContext &Ctx)const +{ + m_RootParams.ProcessRootTables( + [&](Uint32 RootInd, const RootParameter &RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) + { + ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, + [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) + { + TransitionResource(Ctx, Res, range.RangeType); + } + ); + } + ); +} + + +void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, + CommandContext &Ctx, + bool IsCompute, + Uint32 ContextId)const +{ + for(Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + { + auto &RootView = m_RootParams.GetRootView(rv); + auto RootInd = RootView.GetRootIndex(); + + SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; +#ifdef _DEBUG + auto &Param = static_cast<const D3D12_ROOT_PARAMETER&>( RootView ); + VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); + dbgShaderType = ShaderTypeFromShaderVisibility(Param.ShaderVisibility); +#endif + + auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); + auto *pBuffToTransition = ValidatedCast<BufferD3D12Impl>(Res.pObject.RawPtr()); + if( !pBuffToTransition->CheckAllStates(D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER) ) + Ctx.TransitionResource(pBuffToTransition, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); + + D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(ContextId); + if(IsCompute) + Ctx.GetCommandList()->SetComputeRootConstantBufferView(RootInd, CBVAddress); + else + Ctx.GetCommandList()->SetGraphicsRootConstantBufferView(RootInd, CBVAddress); + } +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp new file mode 100644 index 00000000..e6e95bac --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp @@ -0,0 +1,62 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "SamplerD3D12Impl.h" +#include "RenderDeviceD3D12Impl.h" +#include "D3D12TypeConversions.h" + +namespace Diligent +{ + +SamplerD3D12Impl::SamplerD3D12Impl(FixedBlockMemoryAllocator &SamplerObjAllocator, class RenderDeviceD3D12Impl *pRenderDeviceD3D12, const SamplerDesc& SamplerDesc) : + TSamplerBase(SamplerObjAllocator, pRenderDeviceD3D12, SamplerDesc) +{ + auto *pD3D12Device = pRenderDeviceD3D12->GetD3D12Device(); + D3D12_SAMPLER_DESC D3D12SamplerDesc = + { + FilterTypeToD3D12Filter(SamplerDesc.MinFilter, SamplerDesc.MagFilter, SamplerDesc.MipFilter), + TexAddressModeToD3D12AddressMode(SamplerDesc.AddressU), + TexAddressModeToD3D12AddressMode(SamplerDesc.AddressV), + TexAddressModeToD3D12AddressMode(SamplerDesc.AddressW), + SamplerDesc.MipLODBias, + SamplerDesc.MaxAnisotropy, + ComparisonFuncToD3D12ComparisonFunc(SamplerDesc.ComparisonFunc), + {SamplerDesc.BorderColor[0], SamplerDesc.BorderColor[1], SamplerDesc.BorderColor[2], SamplerDesc.BorderColor[3]}, + SamplerDesc.MinLOD, + SamplerDesc.MaxLOD + }; + + auto CPUDescriptorAlloc = pRenderDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + m_Descriptor = std::move(CPUDescriptorAlloc); + pD3D12Device->CreateSampler(&D3D12SamplerDesc, m_Descriptor.GetCpuHandle()); +} + +SamplerD3D12Impl::~SamplerD3D12Impl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( SamplerD3D12Impl, IID_SamplerD3D12, TSamplerBase ) + +} diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp new file mode 100644 index 00000000..fd43fa49 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -0,0 +1,81 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include <D3Dcompiler.h> + +#include "ShaderD3D12Impl.h" +#include "RenderDeviceD3D12Impl.h" +#include "DataBlobImpl.h" +#include "D3DShaderResourceLoader.h" + +using namespace Diligent; + +namespace Diligent +{ + + +ShaderD3D12Impl::ShaderD3D12Impl(FixedBlockMemoryAllocator& ShaderObjAllocator, RenderDeviceD3D12Impl *pRenderDeviceD3D12, const ShaderCreationAttribs &ShaderCreationAttribs) : + TShaderBase(ShaderObjAllocator, pRenderDeviceD3D12, ShaderCreationAttribs.Desc), + ShaderD3DBase(ShaderCreationAttribs), + m_StaticResLayout(*this, GetRawAllocator()), + m_DummyShaderVar(*this), + m_ConstResCache(ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) +{ + // Load shader resources + auto &Allocator = GetRawAllocator(); + auto *pRawMem = ALLOCATE(Allocator, "Allocator for ShaderResources", sizeof(ShaderResourcesD3D12)); + auto *pResources = new (pRawMem) ShaderResourcesD3D12(m_pShaderByteCode, m_Desc); + m_pShaderResources.reset(pResources, STDDeleterRawMem<ShaderResourcesD3D12>(Allocator)); + + // Clone only static resources that will be set directly in the shader + SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_STATIC}; + m_StaticResLayout.Initialize(pRenderDeviceD3D12->GetD3D12Device(), m_pShaderResources, GetRawAllocator(), VarTypes, _countof(VarTypes), &m_ConstResCache, nullptr); +} + +ShaderD3D12Impl::~ShaderD3D12Impl() +{ +} + +void ShaderD3D12Impl::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) +{ + m_StaticResLayout.BindResources(pResourceMapping, Flags, &m_ConstResCache); +} + +IShaderVariable* ShaderD3D12Impl::GetShaderVariable(const Char* Name) +{ + auto *pVar = m_StaticResLayout.GetShaderVariable(Name); + if(pVar == nullptr) + pVar = &m_DummyShaderVar; + return pVar; +} + +#ifdef VERIFY_SHADER_BINDINGS +void ShaderD3D12Impl::DbgVerifyStaticResourceBindings() +{ + m_StaticResLayout.dbgVerifyBindings(); +} +#endif + +} diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp new file mode 100644 index 00000000..118707a2 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -0,0 +1,139 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "ShaderResourceBindingD3D12Impl.h" +#include "PipelineStateD3D12Impl.h" +#include "ShaderD3D12Impl.h" +#include "RenderDeviceD3D12Impl.h" + +namespace Diligent +{ + +ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl( FixedBlockMemoryAllocator &SRBAllocator, PipelineStateD3D12Impl *pPSO, bool IsPSOInternal) : + TBase( SRBAllocator, pPSO, IsPSOInternal ), + m_ShaderResourceCache(ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) +{ + auto *ppShaders = pPSO->GetShaders(); + m_NumShaders = pPSO->GetNumShaders(); + + auto *pRenderDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(pPSO->GetDevice()); + pPSO->GetRootSignature().InitResourceCache(pRenderDeviceD3D12Impl, m_ShaderResourceCache, pPSO->GetResourceCacheDataAllocator()); + + auto *pResLayoutRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D12", m_NumShaders * sizeof(ShaderResourceLayoutD3D12)); + m_pResourceLayouts = reinterpret_cast<ShaderResourceLayoutD3D12*>(pResLayoutRawMem); + + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + auto *pShader = ppShaders[s]; + auto ShaderType = pShader->GetDesc().ShaderType; + auto ShaderInd = GetShaderTypeIndex(ShaderType); + + auto &ShaderResLayoutDataAllocator = pPSO->GetShaderResourceLayoutDataAllocator(ShaderInd); + + SHADER_VARIABLE_TYPE Types[] = {SHADER_VARIABLE_TYPE_STATIC, SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC}; + const auto &SrcLayout = pPSO->GetShaderResLayout(ShaderType); + new (m_pResourceLayouts + s) ShaderResourceLayoutD3D12(*this, SrcLayout, ShaderResLayoutDataAllocator, Types, _countof(Types), m_ShaderResourceCache); + + m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s); + } +} + +ShaderResourceBindingD3D12Impl::~ShaderResourceBindingD3D12Impl() +{ + for(Uint32 l = 0; l < m_NumShaders; ++l) + m_pResourceLayouts[l].~ShaderResourceLayoutD3D12(); + + GetRawAllocator().Free(m_pResourceLayouts); +} + +IMPLEMENT_QUERY_INTERFACE( ShaderResourceBindingD3D12Impl, IID_ShaderResourceBindingD3D12, TBase ) + +void ShaderResourceBindingD3D12Impl::BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags) +{ + for (auto ShaderInd = 0; ShaderInd <= CSInd; ++ShaderInd ) + { + if (ShaderFlags & GetShaderTypeFromIndex(ShaderInd)) + { + auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; + if(ResLayoutInd >= 0) + { + m_pResourceLayouts[ResLayoutInd].BindResources(pResMapping, Flags, &m_ShaderResourceCache); + } + } + } +} + +IShaderVariable *ShaderResourceBindingD3D12Impl::GetVariable(SHADER_TYPE ShaderType, const char *Name) +{ + auto ShaderInd = GetShaderTypeIndex(ShaderType); + auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; + if (ResLayoutInd < 0) + { + LOG_ERROR_MESSAGE("Failed to find shader variable \"", Name,"\" in shader resource binding: shader type ", GetShaderTypeLiteralName(ShaderType), " is not initialized"); + return ValidatedCast<PipelineStateD3D12Impl>(GetPipelineState())->GetDummyShaderVar(); + } + auto *pVar = m_pResourceLayouts[ResLayoutInd].GetShaderVariable(Name); + if(pVar == nullptr) + pVar = ValidatedCast<PipelineStateD3D12Impl>(GetPipelineState())->GetDummyShaderVar(); + + return pVar; +} + +#ifdef VERIFY_SHADER_BINDINGS +void ShaderResourceBindingD3D12Impl::dbgVerifyResourceBindings(const PipelineStateD3D12Impl *pPSO) +{ + auto *pRefPSO = GetPipelineState(); + if (pRefPSO != pPSO) + { + LOG_ERROR("Shader resource binding does not match the pipeline state \"", pPSO->GetDesc().Name, '\"'); + return; + } + for(Uint32 l = 0; l < m_NumShaders; ++l) + m_pResourceLayouts[l].dbgVerifyBindings(); +} +#endif + + +void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const PipelineStateD3D12Impl *pPSO) +{ + VERIFY(!StaticResourcesInitialized(), "Static resources have already been initialized") + VERIFY(pPSO == GetPipelineState(), "Invalid pipeline state provided") + + auto NumShaders = pPSO->GetNumShaders(); + auto ppShaders = pPSO->GetShaders(); + // Copy static resources + for (Uint32 s = 0; s < NumShaders; ++s) + { + auto *pShader = ValidatedCast<ShaderD3D12Impl>( ppShaders[s] ); +#ifdef VERIFY_SHADER_BINDINGS + pShader->DbgVerifyStaticResourceBindings(); +#endif + auto &ConstResLayout = pShader->GetConstResLayout(); + GetResourceLayout(pShader->GetDesc().ShaderType).CopyStaticResourceDesriptorHandles(ConstResLayout); + } + + m_bStaticResourcesInitialized = true; +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp new file mode 100644 index 00000000..700b49b5 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp @@ -0,0 +1,84 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "ShaderResourceCacheD3D12.h" + +namespace Diligent +{ + void ShaderResourceCacheD3D12::Initialize(IMemoryAllocator &MemAllocator, Uint32 NumTables, Uint32 TableSizes[]) + { + // Memory layout: + // __________________________________________________________ + // | m_pResources, m_NumResources | + // m_pMemory | | + // | | V + // | RootTable[0] | .... | RootTable[Nrt-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] | + // | A + // | | + // |________________________________________________| + // m_pResources, m_NumResources + // + + VERIFY(m_pAllocator == nullptr && m_pMemory == nullptr, "Cache already initialized") + m_pAllocator = &MemAllocator; + m_NumTables = NumTables; + Uint32 TotalResources = 0; + for(Uint32 t=0; t < NumTables; ++t) + TotalResources += TableSizes[t]; + auto MemorySize = NumTables * sizeof(RootTable) + TotalResources * sizeof(Resource); + if(MemorySize > 0) + { + m_pMemory = ALLOCATE( *m_pAllocator, "Memory for shader resource cache data", MemorySize); + auto *pTables = reinterpret_cast<RootTable*>(m_pMemory); + auto *pCurrResPtr = reinterpret_cast<Resource*>(pTables + m_NumTables); + for(Uint32 res=0; res < TotalResources; ++res) + new(pCurrResPtr + res) Resource(); + + for (Uint32 t = 0; t < NumTables; ++t) + { + new(&GetRootTable(t)) RootTable(TableSizes[t], TableSizes[t] > 0 ? pCurrResPtr : nullptr); + pCurrResPtr += TableSizes[t]; + } + VERIFY_EXPR((char*)pCurrResPtr == (char*)m_pMemory + MemorySize); + } + } + + ShaderResourceCacheD3D12::~ShaderResourceCacheD3D12() + { + if (m_pMemory) + { + Uint32 TotalResources = 0; + for (Uint32 t = 0; t < m_NumTables; ++t) + TotalResources += GetRootTable(t).GetSize(); + auto *pResources = reinterpret_cast<Resource*>( reinterpret_cast<RootTable*>(m_pMemory) + m_NumTables); + for(Uint32 res=0; res < TotalResources; ++res) + pResources[res].~Resource(); + for (Uint32 t = 0; t < m_NumTables; ++t) + GetRootTable(t).~RootTable(); + + m_pAllocator->Free(m_pMemory); + } + } +} diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp new file mode 100644 index 00000000..e0121db7 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -0,0 +1,1038 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "ShaderResourceLayoutD3D12.h" +#include "ShaderResourceCacheD3D12.h" +#include "D3DShaderResourceLoader.h" +#include "BufferD3D12Impl.h" +#include "BufferViewD3D12.h" +#include "TextureD3D12Impl.h" +#include "TextureViewD3D12Impl.h" +#include "SamplerD3D12Impl.h" +#include "ShaderD3D12Impl.h" +#include "RootSignature.h" +#include "PipelineStateD3D12Impl.h" + +namespace Diligent +{ + +ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject &Owner, + IMemoryAllocator &ResourceLayoutDataAllocator) : + m_Owner(Owner), +#if USE_VARIABLE_HASH_MAP + m_VariableHash(STD_ALLOCATOR_RAW_MEM(VariableHashElemType, GetRawAllocator(), "Allocator for unordered_map<HashMapStringKey, IShaderVariable*>")), +#endif + m_ResourceBuffer(nullptr, STDDeleterRawMem<void>(ResourceLayoutDataAllocator)) +{ +} + +ShaderResourceLayoutD3D12::~ShaderResourceLayoutD3D12() +{ + auto* CbvSrvUav = reinterpret_cast<SRV_CBV_UAV*>(m_ResourceBuffer.get()); + for(Uint32 r=0; r < GetTotalSrvCbvUavCount(); ++r) + CbvSrvUav[r].~SRV_CBV_UAV(); + + for(Uint32 s=0; s < GetTotalSamplerCount(); ++s) + m_Samplers[s].~Sampler(); +} + +D3D12_DESCRIPTOR_RANGE_TYPE GetDescriptorRangeType(CachedResourceType ResType) +{ + static D3D12_DESCRIPTOR_RANGE_TYPE RangeTypes[(size_t)CachedResourceType::NumTypes] = {}; + static bool Initialized = false; + if (!Initialized) + { + RangeTypes[(size_t)CachedResourceType::CBV] = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + RangeTypes[(size_t)CachedResourceType::TexSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + RangeTypes[(size_t)CachedResourceType::BufSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + RangeTypes[(size_t)CachedResourceType::TexUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + RangeTypes[(size_t)CachedResourceType::BufUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + RangeTypes[(size_t)CachedResourceType::Sampler] = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + Initialized = true; + } + auto Ind = static_cast<size_t>(ResType); + VERIFY(Ind >= 0 && Ind < (size_t)CachedResourceType::NumTypes, "Unexpected resource type") + return RangeTypes[Ind]; +} + +void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator &Allocator) +{ + VERIFY( &m_ResourceBuffer.get_deleter().m_Allocator == &Allocator, "Inconsistent memory allocators" ) + Uint32 TotalSrvCbvUav = GetTotalSrvCbvUavCount(); + Uint32 TotalSamplers = GetTotalSamplerCount(); + size_t MemSize = TotalSrvCbvUav * sizeof(SRV_CBV_UAV) + TotalSamplers * sizeof(Sampler); + if(MemSize == 0) + return; + + auto *pRawMem = ALLOCATE(Allocator, "Raw memory buffer for shader resource layout resources", MemSize); + m_ResourceBuffer.reset(pRawMem); + if(TotalSamplers) + m_Samplers = reinterpret_cast<Sampler*>(reinterpret_cast<SRV_CBV_UAV*>(pRawMem) + TotalSrvCbvUav); +} + +// Clones layout from the reference layout +// Root indices and descriptor table offsets must be correct +// Resource cache is not initialized. +ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject &Owner, + const ShaderResourceLayoutD3D12& SrcLayout, + IMemoryAllocator &ResourceLayoutDataAllocator, + const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12 &ResourceCache) : + ShaderResourceLayoutD3D12(Owner, ResourceLayoutDataAllocator) +{ + m_pd3d12Device = SrcLayout.m_pd3d12Device; + m_pResources = SrcLayout.m_pResources; + m_pResourceCache = &ResourceCache; + + Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_VARIABLE_TYPE>(VarType+1)) + { + if( !IsAllowedType(VarType, AllowedTypeBits)) + continue; + + m_NumCbvSrvUav[VarType] = SrcLayout.m_NumCbvSrvUav[VarType]; + m_NumSamplers[VarType] = SrcLayout.m_NumSamplers[VarType]; + } + + AllocateMemory(ResourceLayoutDataAllocator); + + Uint32 CurrCbvSrvUav[SHADER_VARIABLE_TYPE_NUM_TYPES] = {0,0,0}; + Uint32 CurrSampler[SHADER_VARIABLE_TYPE_NUM_TYPES] = {0,0,0}; + + for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_VARIABLE_TYPE>(VarType+1)) + { + if( !IsAllowedType(VarType, AllowedTypeBits)) + continue; + + Uint32 NumSrcCbvSrvUav = SrcLayout.m_NumCbvSrvUav[VarType]; + VERIFY_EXPR(NumSrcCbvSrvUav == m_NumCbvSrvUav[VarType]); + for( Uint32 r=0; r < NumSrcCbvSrvUav; ++r ) + { + const auto &SrcRes = SrcLayout.GetSrvCbvUav(VarType, r); + Uint32 SamplerId = SRV_CBV_UAV::InvalidSamplerId; + if (SrcRes.IsValidSampler()) + { + const auto &SrcSamplerAttribs = SrcLayout.GetSampler(VarType, SrcRes.GetSamplerId()); + VERIFY(!SrcSamplerAttribs.Attribs.IsStaticSampler(), "Only non-static samplers can be assigned space in shader cache") + VERIFY(SrcSamplerAttribs.Attribs.GetVariableType() == SrcRes.Attribs.GetVariableType(), "Inconsistent texture and sampler variable types" ); + VERIFY(SrcSamplerAttribs.IsValidRootIndex(), "Root index must be valid") + VERIFY(SrcSamplerAttribs.IsValidOffset(), "Offset must be valid") + VERIFY_EXPR(SrcSamplerAttribs.Attribs.BindCount == SrcRes.Attribs.BindCount || SrcSamplerAttribs.Attribs.BindCount == 1); + + SamplerId = CurrSampler[VarType]; + VERIFY(SamplerId <= SRV_CBV_UAV::MaxSamplerId, "SamplerId exceeds maximum allowed value (", SRV_CBV_UAV::MaxSamplerId, ")"); + VERIFY_EXPR(SamplerId == SrcRes.GetSamplerId()); + ::new (&GetSampler(VarType, CurrSampler[VarType]++)) Sampler( *this, SrcSamplerAttribs ); + } + + VERIFY(SrcRes.IsValidRootIndex(), "Root index must be valid") + VERIFY(SrcRes.IsValidOffset(), "Offset must be valid") + ::new (&GetSrvCbvUav(VarType, CurrCbvSrvUav[VarType]++)) SRV_CBV_UAV( *this, SrcRes, SamplerId ); + } + } + +#ifdef _DEBUG + for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_VARIABLE_TYPE>(VarType+1)) + { + VERIFY_EXPR( CurrCbvSrvUav[VarType] == m_NumCbvSrvUav[VarType] ); + VERIFY_EXPR( CurrSampler[VarType] == m_NumSamplers[VarType] ); + } +#endif +} + +void ShaderResourceLayoutD3D12::Initialize(ID3D12Device *pd3d12Device, + const std::shared_ptr<const ShaderResourcesD3D12>& pSrcResources, + IMemoryAllocator &LayoutDataAllocator, + const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12* pResourceCache, + RootSignature *pRootSig) +{ + m_pResources = pSrcResources; + m_pResourceCache = pResourceCache; + m_pd3d12Device = pd3d12Device; + + VERIFY_EXPR( (pResourceCache != nullptr) ^ (pRootSig != nullptr) ); + + Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + m_pResources->ProcessResources( + AllowedVarTypes, NumAllowedTypes, + + [&](const D3DShaderResourceAttribs &CB) + { + VERIFY_EXPR(IsAllowedType(CB.GetVariableType(), AllowedTypeBits)); + ++m_NumCbvSrvUav[CB.GetVariableType()]; + }, + [&](const D3DShaderResourceAttribs& TexSRV) + { + auto VarType = TexSRV.GetVariableType(); + VERIFY_EXPR(IsAllowedType(VarType, AllowedTypeBits)); + ++m_NumCbvSrvUav[VarType]; + if(TexSRV.IsValidSampler()) + { + auto SamplerId = TexSRV.GetSamplerId(); + const auto &SamplerAttribs = m_pResources->GetSampler(SamplerId); + VERIFY(SamplerAttribs.GetVariableType() == VarType, "Texture and sampler variable types are not conistent"); + if(!SamplerAttribs.IsStaticSampler()) + { + ++m_NumSamplers[VarType]; + } + } + }, + [&](const D3DShaderResourceAttribs &TexUAV) + { + VERIFY_EXPR(IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits)); + ++m_NumCbvSrvUav[TexUAV.GetVariableType()]; + }, + [&](const D3DShaderResourceAttribs &BufSRV) + { + VERIFY_EXPR(IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits)); + ++m_NumCbvSrvUav[BufSRV.GetVariableType()]; + }, + [&](const D3DShaderResourceAttribs &BufUAV) + { + VERIFY_EXPR(IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits)); + ++m_NumCbvSrvUav[BufUAV.GetVariableType()]; + } + ); + + + AllocateMemory(LayoutDataAllocator); + + Uint32 CurrCbvSrvUav[SHADER_VARIABLE_TYPE_NUM_TYPES] = {0,0,0}; + Uint32 CurrSampler[SHADER_VARIABLE_TYPE_NUM_TYPES] = {0,0,0}; + int MaxBindPoint[4] = {-1, -1, -1, -1}; + + auto AddResource = [&](const D3DShaderResourceAttribs &Attribs, CachedResourceType ResType, Uint32 SamplerId = SRV_CBV_UAV::InvalidSamplerId) + { + Uint32 RootIndex = SRV_CBV_UAV::InvalidRootIndex; + Uint32 Offset = SRV_CBV_UAV::InvalidOffset; + D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType); + if (pRootSig) + { + pRootSig->AllocateResourceSlot(m_pResources->GetShaderType(), Attribs, DescriptorRangeType, RootIndex, Offset ); + VERIFY(RootIndex <= SRV_CBV_UAV::MaxRootIndex, "Root index excceeds allowed limit"); + } + else + { + // If root signature is not provided - use artifial root signature to store + // static shader resources + VERIFY_EXPR(m_pResourceCache != nullptr); + + RootIndex = DescriptorRangeType; + Offset = Attribs.BindPoint; + // Resources in the static resource cache are indexed by the bind point + MaxBindPoint[RootIndex] = std::max(MaxBindPoint[RootIndex], static_cast<int>(Offset + Attribs.BindCount)); + } + VERIFY(RootIndex != SRV_CBV_UAV::InvalidRootIndex, "Root index must be valid") + VERIFY(Offset != SRV_CBV_UAV::InvalidOffset, "Offset must be valid") + + // Static samplers are never copied, and SamplerId == InvalidSamplerId + ::new (&GetSrvCbvUav(Attribs.GetVariableType(), CurrCbvSrvUav[Attribs.GetVariableType()]++)) SRV_CBV_UAV( *this, Attribs, ResType, RootIndex, Offset, SamplerId); + }; + + + + m_pResources->ProcessResources( + AllowedVarTypes, NumAllowedTypes, + + [&](const D3DShaderResourceAttribs &CB) + { + VERIFY_EXPR( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ); + AddResource(CB, CachedResourceType::CBV); + }, + [&](const D3DShaderResourceAttribs& TexSRV) + { + auto VarType = TexSRV.GetVariableType(); + VERIFY_EXPR(IsAllowedType(VarType, AllowedTypeBits) ) + + Uint32 SamplerId = SRV_CBV_UAV::InvalidSamplerId; + if(TexSRV.IsValidSampler()) + { + const auto &SrcSamplerAttribs = m_pResources->GetSampler(TexSRV.GetSamplerId()); + VERIFY(SrcSamplerAttribs.GetVariableType() == VarType, "Inconsistent texture and sampler variable types" ); + + if (SrcSamplerAttribs.IsStaticSampler()) + { + if(pRootSig != nullptr) + pRootSig->InitStaticSampler(m_pResources->GetShaderType(), TexSRV.Name, SrcSamplerAttribs); + + // Static samplers are never copied, and SamplerId == InvalidSamplerId + } + else + { + Uint32 SamplerRootIndex = Sampler::InvalidRootIndex; + Uint32 SamplerOffset = Sampler::InvalidOffset; + if (pRootSig) + { + pRootSig->AllocateResourceSlot(m_pResources->GetShaderType(), SrcSamplerAttribs, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, SamplerRootIndex, SamplerOffset ); + } + else + { + // If root signature is not provided, we are initializing resource cache to store + // static shader resources. + VERIFY_EXPR(m_pResourceCache != nullptr); + + // We use the following artifial root signature: + // CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV, + // SRVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_SRV, + // UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV, and + // Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + // Every resource is stored at offset that equals its bind point + SamplerRootIndex = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + SamplerOffset = SrcSamplerAttribs.BindPoint; + // Resources in the static resource cache are indexed by the bind point + MaxBindPoint[SamplerRootIndex] = std::max(MaxBindPoint[SamplerRootIndex], static_cast<int>(SamplerOffset + SrcSamplerAttribs.BindCount)); + } + VERIFY(SamplerRootIndex != Sampler::InvalidRootIndex, "Sampler root index must be valid") + VERIFY(SamplerOffset != Sampler::InvalidOffset, "Sampler offset must be valid") + + SamplerId = CurrSampler[VarType]; + VERIFY(SamplerId <= SRV_CBV_UAV::MaxSamplerId, "Sampler index excceeds allowed limit"); + ::new (&GetSampler(VarType, CurrSampler[VarType]++)) Sampler( *this, SrcSamplerAttribs, SamplerRootIndex, SamplerOffset ); + } + } + AddResource(TexSRV, CachedResourceType::TexSRV, SamplerId); + }, + [&](const D3DShaderResourceAttribs &TexUAV) + { + VERIFY_EXPR( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ); + AddResource(TexUAV, CachedResourceType::TexUAV); + }, + [&](const D3DShaderResourceAttribs &BufSRV) + { + VERIFY_EXPR( IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits) ); + AddResource(BufSRV, CachedResourceType::BufSRV); + }, + [&](const D3DShaderResourceAttribs &BufUAV) + { + VERIFY_EXPR( IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits) ); + AddResource(BufUAV, CachedResourceType::BufUAV); + } + ); + +#ifdef _DEBUG + for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_VARIABLE_TYPE>(VarType+1)) + { + VERIFY( CurrCbvSrvUav[VarType] == m_NumCbvSrvUav[VarType], "Not all Srv/Cbv/Uavs are initialized, which result in a crash when dtor is called" ); + VERIFY( CurrSampler[VarType] == m_NumSamplers[VarType], "Not all Samplers are initialized, which result in a crash when dtor is called" ); + } +#endif + + if(m_pResourceCache) + { + VERIFY_EXPR(pRootSig == nullptr); + Uint32 CachedTblSizes[4] = + { + static_cast<Uint32>(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_SRV] + 1), + static_cast<Uint32>(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_UAV] + 1), + static_cast<Uint32>(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_CBV] + 1), + static_cast<Uint32>(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER] + 1) + }; + m_pResourceCache->Initialize(GetRawAllocator(), _countof(CachedTblSizes), CachedTblSizes); +#ifdef _DEBUG + m_pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SRV).SetDebugAttribs(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_SRV] + 1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + m_pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_UAV).SetDebugAttribs(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_UAV] + 1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + m_pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_CBV).SetDebugAttribs(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_CBV] + 1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + m_pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).SetDebugAttribs(MaxBindPoint[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER] + 1, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); +#endif + } + + InitVariablesHashMap(); +} + + +void ShaderResourceLayoutD3D12::InitVariablesHashMap() +{ +#if USE_VARIABLE_HASH_MAP + Uint32 TotalResources = GetTotalSrvCbvUavCount(); + for(Uint32 r=0; r < TotalResources; ++r) + { + auto &Res = GetSrvCbvUav(r); + /* HashMapStringKey will make a copy of the string*/ + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(Res.Name), &Res ) ); + } +#endif +} + + +#define LOG_RESOURCE_BINDING_ERROR(ResType, pResource, VarName, ShaderName, ...)\ +{ \ + const auto &ResName = pResource->GetDesc().Name; \ + LOG_ERROR_MESSAGE( "Failed to bind ", ResType, " \"", ResName, "\" to variable \"", VarName, \ + "\" in shader \"", ShaderName, "\". ", __VA_ARGS__ ); \ +} + + + +void ShaderResourceLayoutD3D12::SRV_CBV_UAV::CacheCB(IDeviceObject *pBuffer, ShaderResourceCacheD3D12::Resource& DstRes, Uint32 ArrayInd, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) +{ + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr<BufferD3D12Impl> pBuffD3D12(pBuffer, IID_BufferD3D12); + if( pBuffD3D12 ) + { + if( pBuffD3D12->GetDesc().BindFlags & BIND_UNIFORM_BUFFER ) + { + if( Attribs.GetVariableType() != SHADER_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr && DstRes.pObject != pBuffD3D12) + { + auto VarTypeStr = GetShaderVariableTypeLiteralName(Attribs.GetVariableType()); + LOG_ERROR_MESSAGE( "Non-null constant buffer is already bound to ", VarTypeStr, " shader variable \"", Attribs.GetPrintName(ArrayInd), "\" in shader \"", m_ParentResLayout.GetShaderName(), "\". Attempring to bind another constant buffer is an error and may cause unpredicted behavior. Use another shader resource binding instance or mark shader variable as dynamic." ) + } + + DstRes.Type = GetResType(); + DstRes.CPUDescriptorHandle = pBuffD3D12->GetCBVHandle(); + VERIFY(DstRes.CPUDescriptorHandle.ptr != 0 || pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC, "No relevant CBV CPU descriptor handle") + + if(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0 ) + { + ID3D12Device *pd3d12Device = m_ParentResLayout.m_pd3d12Device; + pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, DstRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + DstRes.pObject = pBuffD3D12; + } + else + { + LOG_RESOURCE_BINDING_ERROR("buffer", pBuffer, Attribs.GetPrintName(ArrayInd), m_ParentResLayout.GetShaderName(), "Buffer was not created with BIND_UNIFORM_BUFFER flag.") + } + } + else + { + LOG_RESOURCE_BINDING_ERROR("buffer", pBuffer, Attribs.GetPrintName(ArrayInd), m_ParentResLayout.GetShaderName(), "Incorrect resource type: buffer is expected.") + } +} + + +template<typename TResourceViewType> +struct ResourceViewTraits{}; + +template<> +struct ResourceViewTraits<ITextureViewD3D12> +{ + static const Char *Name; + static const INTERFACE_ID &IID; +}; +const Char *ResourceViewTraits<ITextureViewD3D12>::Name = "texture view"; +const INTERFACE_ID& ResourceViewTraits<ITextureViewD3D12>::IID = IID_TextureViewD3D12; + +template<> +struct ResourceViewTraits<IBufferViewD3D12> +{ + static const Char *Name; + static const INTERFACE_ID &IID; +}; +const Char *ResourceViewTraits<IBufferViewD3D12>::Name = "buffer view"; +const INTERFACE_ID& ResourceViewTraits<IBufferViewD3D12>::IID = IID_BufferViewD3D12; + +template<typename TResourceViewType, ///< ResType of the view (ITextureViewD3D12 or IBufferViewD3D12) + typename TViewTypeEnum, ///< ResType of the expected view type enum (TEXTURE_VIEW_TYPE or BUFFER_VIEW_TYPE) + typename TBindSamplerProcType> ///< ResType of the procedure to set sampler +void ShaderResourceLayoutD3D12::SRV_CBV_UAV::CacheResourceView(IDeviceObject *pView, + ShaderResourceCacheD3D12::Resource& DstRes, + Uint32 ArrayIndex, + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, + TViewTypeEnum dbgExpectedViewType, + TBindSamplerProcType BindSamplerProc) +{ + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr<TResourceViewType> pViewD3D12(pView, ResourceViewTraits<TResourceViewType>::IID); + if( pViewD3D12 ) + { +#ifdef VERIFY_SHADER_BINDINGS + const auto& ViewDesc = pViewD3D12->GetDesc(); + auto ViewType = ViewDesc.ViewType; + if( ViewType != dbgExpectedViewType ) + { + const auto *ExpectedViewTypeName = GetViewTypeLiteralName( dbgExpectedViewType ); + const auto *ActualViewTypeName = GetViewTypeLiteralName( ViewType ); + LOG_RESOURCE_BINDING_ERROR(ResourceViewTraits<TResourceViewType>::Name, pViewD3D12, Attribs.GetPrintName(ArrayIndex), m_ParentResLayout.GetShaderName(), + "Incorrect view type: ", ExpectedViewTypeName, " is expected, ", ActualViewTypeName, " provided." ); + return; + } +#endif + if( Attribs.GetVariableType() != SHADER_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr && DstRes.pObject != pViewD3D12) + { + auto VarTypeStr = GetShaderVariableTypeLiteralName(Attribs.GetVariableType()); + LOG_ERROR_MESSAGE( "Non-null resource is already bound to ", VarTypeStr, " shader variable \"", Attribs.GetPrintName(ArrayIndex), "\" in shader \"", m_ParentResLayout.GetShaderName(), "\". Attempting to bind another resource is an error and may cause unpredicted behavior. Use another shader resource binding instance or mark shader variable as dynamic." ); + } + + DstRes.Type = GetResType(); + DstRes.pObject = pViewD3D12; + DstRes.CPUDescriptorHandle = pViewD3D12->GetCPUDescriptorHandle(); + VERIFY(DstRes.CPUDescriptorHandle.ptr != 0, "No relevant D3D12 view") + + if(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0) + { + ID3D12Device *pd3d12Device = m_ParentResLayout.m_pd3d12Device; + pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, DstRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + BindSamplerProc(pViewD3D12); + } + else + { + LOG_RESOURCE_BINDING_ERROR("resource", pView, Attribs.GetPrintName(ArrayIndex), m_ParentResLayout.GetShaderName(), "Incorect resource type: ", ResourceViewTraits<TResourceViewType>::Name, " is expected.") + } +} + +void ShaderResourceLayoutD3D12::Sampler::CacheSampler(ITextureViewD3D12 *pTexViewD3D12, Uint32 ArrayIndex, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + auto &DstSam = pResourceCache->GetRootTable(RootIndex).GetResource(OffsetFromTableStart + ArrayIndex, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_ParentResLayout.m_pResources->GetShaderType()); + +#ifdef _DEBUG + { + if (pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) + { + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Static shader resources of a shader should not be assigned shader visible descriptor space") + } + else if (pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) + { + if(Attribs.GetVariableType() == SHADER_VARIABLE_TYPE_DYNAMIC) + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Dynamic resources of a shader resource binding should be assigned shader visible descriptor space at every draw call") + else + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0 || pTexViewD3D12 == nullptr, "Non-dynamics resources of a shader resource binding must be assigned shader visible descriptor space") + } + else + { + UNEXPECTED("Unknown content type") + } + } +#endif + + if( pTexViewD3D12 ) + { + auto pSampler = pTexViewD3D12->GetSampler(); + if( pSampler ) + { + if( Attribs.GetVariableType() != SHADER_VARIABLE_TYPE_DYNAMIC && DstSam.pObject != nullptr && DstSam.pObject != pSampler) + { + auto VarTypeStr = GetShaderVariableTypeLiteralName(Attribs.GetVariableType()); + LOG_ERROR_MESSAGE( "Non-null sampler is already bound to ", VarTypeStr, " shader variable \"", Attribs.GetPrintName(ArrayIndex), "\" in shader \"", m_ParentResLayout.GetShaderName(), "\". Attempting to bind another sampler is an error and may cause unpredicted behavior. Use another shader resource binding instance or mark shader variable as dynamic." ) + } + + DstSam.Type = CachedResourceType::Sampler; + + auto *pSamplerD3D12 = ValidatedCast<SamplerD3D12Impl>(pSampler); + DstSam.CPUDescriptorHandle = pSamplerD3D12->GetCPUDescriptorHandle(); + VERIFY(DstSam.CPUDescriptorHandle.ptr != 0, "No relevant D3D12 sampler descriptor handle") + + if(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0) + { + ID3D12Device *pd3d12Device = m_ParentResLayout.m_pd3d12Device; + pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, DstSam.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + } + + DstSam.pObject = pSampler; + } + else + { + LOG_ERROR_MESSAGE( "Failed to bind sampler to variable \"", Attribs.Name, ". Sampler is not set in the texture view \"", pTexViewD3D12->GetDesc().Name, "\"" ); + } + } + else + { + DstSam = ShaderResourceCacheD3D12::Resource(); + } +} + + +ShaderResourceLayoutD3D12::Sampler &ShaderResourceLayoutD3D12::GetAssignedSampler(const SRV_CBV_UAV &TexSrv) +{ + VERIFY(TexSrv.GetResType() == CachedResourceType::TexSRV, "Unexpected resource type: texture SRV is expected") + VERIFY(TexSrv.IsValidSampler(), "Texture SRV has no associated sampler") + auto &SamInfo = GetSampler(TexSrv.Attribs.GetVariableType(), TexSrv.GetSamplerId()); + VERIFY(SamInfo.Attribs.GetVariableType() == TexSrv.Attribs.GetVariableType(), "Inconsistent texture and sampler variable types") + VERIFY(SamInfo.Attribs.Name == TexSrv.Attribs.Name + D3DSamplerSuffix, "Sampler name \"", SamInfo.Attribs.Name, "\" does not match texture name \"", TexSrv.Attribs.Name, '\"'); + return SamInfo; +} + + +void ShaderResourceLayoutD3D12::SRV_CBV_UAV::BindResource(IDeviceObject *pObj, Uint32 ArrayIndex, const ShaderResourceLayoutD3D12 *dbgResLayout) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY(dbgResLayout == nullptr || pResourceCache == dbgResLayout->m_pResourceCache, "Invalid resource cache"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + auto &DstRes = pResourceCache->GetRootTable(GetRootIndex()).GetResource(OffsetFromTableStart + ArrayIndex, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_ParentResLayout.m_pResources->GetShaderType()); + auto ShdrVisibleHeapCPUDescriptorHandle = pResourceCache->GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV>(GetRootIndex(), OffsetFromTableStart+ArrayIndex); + +#ifdef _DEBUG + { + if (pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) + { + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Static shader resources of a shader should not be assigned shader visible descriptor space") + } + else if (pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) + { + if (GetResType() == CachedResourceType::CBV) + { + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Constant buffers are bound as root views and should not be assigned shader visible descriptor space") + } + else + { + if(Attribs.GetVariableType() == SHADER_VARIABLE_TYPE_DYNAMIC) + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Dynamic resources of a shader resource binding should be assigned shader visible descriptor space at every draw call") + else + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0, "Non-dynamics resources of a shader resource binding must be assigned shader visible descriptor space") + } + } + else + { + UNEXPECTED("Unknown content type") + } + } +#endif + + if( pObj ) + { + switch (GetResType()) + { + case CachedResourceType::CBV: + CacheCB(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle); + break; + + case CachedResourceType::TexSRV: + CacheResourceView<ITextureViewD3D12>(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, TEXTURE_VIEW_SHADER_RESOURCE, [&](ITextureViewD3D12* pTexView) + { + if(IsValidSampler()) + { + auto &Sam = m_ParentResLayout.GetAssignedSampler(*this); + VERIFY( !Sam.Attribs.IsStaticSampler(), "Static samplers should never be assigned space in the cache" ) + VERIFY_EXPR(Attribs.BindCount == Sam.Attribs.BindCount || Sam.Attribs.BindCount == 1); + auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; + auto ShdrVisibleSamplerHeapCPUDescriptorHandle = pResourceCache->GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(Sam.RootIndex, Sam.OffsetFromTableStart + SamplerArrInd); + Sam.CacheSampler(pTexView, SamplerArrInd, ShdrVisibleSamplerHeapCPUDescriptorHandle); + } + }); + break; + + case CachedResourceType::TexUAV: + CacheResourceView<ITextureViewD3D12>(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, TEXTURE_VIEW_UNORDERED_ACCESS, [](ITextureViewD3D12*){}); + break; + + case CachedResourceType::BufSRV: + CacheResourceView<IBufferViewD3D12>(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, BUFFER_VIEW_SHADER_RESOURCE, [](IBufferViewD3D12*){}); + break; + + case CachedResourceType::BufUAV: + CacheResourceView<IBufferViewD3D12>( pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, BUFFER_VIEW_UNORDERED_ACCESS, [](IBufferViewD3D12*){}); + break; + + default: UNEXPECTED("Unknown resource type ", static_cast<Int32>(GetResType())) + } + } + else + { + if (DstRes.pObject && Attribs.GetVariableType() != SHADER_VARIABLE_TYPE_DYNAMIC) + { + LOG_ERROR_MESSAGE( "Shader variable \"", Attribs.Name, "\" in shader \"", m_ParentResLayout.GetShaderName(), "\" is not dynamic but being unbound. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or mark shader variable as dynamic if you need to bind another resource." ); + } + + DstRes = ShaderResourceCacheD3D12::Resource(); + if(IsValidSampler()) + { + auto &Sam = m_ParentResLayout.GetAssignedSampler(*this); + D3D12_CPU_DESCRIPTOR_HANDLE NullHandle = {0}; + auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; + Sam.CacheSampler(nullptr, SamplerArrInd, NullHandle); + } + } +} + +bool ShaderResourceLayoutD3D12::SRV_CBV_UAV::IsBound(Uint32 ArrayIndex) +{ + auto &pResourceCache = m_ParentResLayout.m_pResourceCache; + VERIFY(pResourceCache, "Resource cache is null"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + auto RootIndex = GetRootIndex(); + if( RootIndex < pResourceCache->GetNumRootTables() ) + { + auto &RootTable = pResourceCache->GetRootTable(RootIndex); + if(OffsetFromTableStart + ArrayIndex < RootTable.GetSize()) + { + auto &CachedRes = RootTable.GetResource(OffsetFromTableStart + ArrayIndex, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_ParentResLayout.m_pResources->GetShaderType()); + if( CachedRes.pObject != nullptr ) + { + VERIFY(CachedRes.CPUDescriptorHandle.ptr != 0 || ValidatedCast<BufferD3D12Impl>(CachedRes.pObject.RawPtr())->GetDesc().Usage == USAGE_DYNAMIC, "No relevant descriptor handle") + return true; + } + } + } + + return false; +} + + + +void ShaderResourceLayoutD3D12::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D12 *dbgResourceCache ) +{ + VERIFY(dbgResourceCache == m_pResourceCache, "Resource cache does not match the cache provided at initialization"); + + if( !pResourceMapping ) + { + LOG_ERROR_MESSAGE( "Failed to bind resources in shader \"", GetShaderName(), "\": resource mapping is null" ); + return; + } + + // Bind constant buffers + Uint32 TotalResources = GetTotalSrvCbvUavCount(); + for(Uint32 r=0; r < TotalResources; ++r) + { + auto &Res = GetSrvCbvUav(r); + for(Uint32 ArrInd = 0; ArrInd < Res.Attribs.BindCount; ++ArrInd) + { + if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) + Res.BindResource(nullptr, ArrInd, this); + + if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && Res.IsBound(ArrInd) ) + return; + + const auto& VarName = Res.Attribs.Name; + RefCntAutoPtr<IDeviceObject> pObj; + VERIFY_EXPR(pResourceMapping != nullptr); + pResourceMapping->GetResource( VarName.c_str(), &pObj, ArrInd ); + if( pObj ) + { + // Call non-virtual function + Res.BindResource(pObj, ArrInd, this); + } + else + { + if( (Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED) && !Res.IsBound(ArrInd) ) + LOG_ERROR_MESSAGE( "Cannot bind resource to shader variable \"", Res.Attribs.GetPrintName(ArrInd), "\": resource view not found in the resource mapping" ) + } + } + } +} + + +IShaderVariable* ShaderResourceLayoutD3D12::GetShaderVariable(const Char* Name) +{ + IShaderVariable* pVar = nullptr; +#if USE_VARIABLE_HASH_MAP + // Name will be implicitly converted to HashMapStringKey without making a copy + auto it = m_VariableHash.find( Name ); + if( it != m_VariableHash.end() ) + pVar = it->second; +#else + Uint32 TotalResources = GetTotalSrvCbvUavCount(); + for(Uint32 r=0; r < TotalResources; ++r) + { + auto &Res = GetSrvCbvUav(r); + if(Res.Attribs.Name.compare(Name) == 0) + { + pVar = &Res; + break; + } + } +#endif + + if(pVar == nullptr) + { + LOG_ERROR_MESSAGE( "Shader variable \"", Name, "\" is not found in shader \"", GetShaderName(), "\" (", GetShaderTypeLiteralName(m_pResources->GetShaderType()), "). Attempts to set the variable will be silently ignored." ); + } + return pVar; +} + + + +void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderResourceLayoutD3D12 &SrcLayout) +{ + if (!m_pResourceCache) + { + LOG_ERROR("Resource layout has no resource cache"); + return; + } + + if (!SrcLayout.m_pResourceCache) + { + LOG_ERROR("Dst layout has no resource cache"); + return; + } + + // Static shader resources are stored as follows: + // CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV, + // SRVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_SRV, + // UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV, and + // Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + // Every resource is stored at offset that equals resource bind point + + for(Uint32 r=0; r < m_NumCbvSrvUav[SHADER_VARIABLE_TYPE_STATIC]; ++r) + { + const auto &res = GetSrvCbvUav(SHADER_VARIABLE_TYPE_STATIC, r); + VERIFY(SrcLayout.m_pResources->GetShaderType() == m_pResources->GetShaderType(), "Incosistent shader types") + auto RangeType = GetDescriptorRangeType(res.GetResType()); + for(Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) + { + auto BindPoint = res.Attribs.BindPoint + ArrInd; + // Static resources are indexed in the resource cache by its bind point + const auto &SrcRes = SrcLayout.m_pResourceCache->GetRootTable(RangeType).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, SrcLayout.m_pResources->GetShaderType()); + if( !SrcRes.pObject ) + LOG_ERROR_MESSAGE( "No resource assigned to static shader variable \"", res.Attribs.GetPrintName(ArrInd), "\" in shader \"", GetShaderName(), "\"." ); + auto &DstRes = m_pResourceCache->GetRootTable(res.GetRootIndex()).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + + if(DstRes.pObject != SrcRes.pObject) + { + VERIFY(DstRes.pObject == nullptr, "Static resource has already been initialized, and the resource to be assigned from the shader does not match previously assigned resource"); + + DstRes.pObject = SrcRes.pObject; + DstRes.Type = SrcRes.Type; + DstRes.CPUDescriptorHandle = SrcRes.CPUDescriptorHandle; + + auto ShdrVisibleHeapCPUDescriptorHandle = m_pResourceCache->GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV>(res.GetRootIndex(), res.OffsetFromTableStart + ArrInd); + VERIFY_EXPR(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0 || DstRes.Type == CachedResourceType::CBV); + if (ShdrVisibleHeapCPUDescriptorHandle.ptr != 0) + { + m_pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, SrcRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + } + else + { + VERIFY_EXPR(DstRes.pObject == SrcRes.pObject); + VERIFY_EXPR(DstRes.Type == SrcRes.Type); + VERIFY_EXPR(DstRes.CPUDescriptorHandle.ptr == SrcRes.CPUDescriptorHandle.ptr); + } + } + + if(res.IsValidSampler()) + { + auto &SamInfo = GetAssignedSampler(res); + + VERIFY(!SamInfo.Attribs.IsStaticSampler(), "Static samplers should never be assigned space in the cache") + + VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid") + VERIFY_EXPR(SamInfo.Attribs.BindCount == res.Attribs.BindCount || SamInfo.Attribs.BindCount == 1); + + for(Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) + { + auto BindPoint = SamInfo.Attribs.BindPoint + ArrInd; + // Static resources are indexed by the bind point in the resource cache + auto& SrcSampler = SrcLayout.m_pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, SrcLayout.m_pResources->GetShaderType()); + if( !SrcSampler.pObject ) + LOG_ERROR_MESSAGE( "No sampler assigned to static shader variable \"", res.Attribs.GetPrintName(ArrInd), "\" in shader \"", GetShaderName(), "\"." ); + auto &DstSampler = m_pResourceCache->GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + + if(DstSampler.pObject != SrcSampler.pObject) + { + VERIFY(DstSampler.pObject == nullptr, "Static sampler resource has already been initialized, and the resource to be assigned from the shader does not match previously assigned resource"); + + DstSampler.pObject = SrcSampler.pObject; + DstSampler.Type = SrcSampler.Type; + DstSampler.CPUDescriptorHandle = SrcSampler.CPUDescriptorHandle; + + auto ShdrVisibleSamplerHeapCPUDescriptorHandle = m_pResourceCache->GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(SamInfo.RootIndex, SamInfo.OffsetFromTableStart + ArrInd); + VERIFY_EXPR(ShdrVisibleSamplerHeapCPUDescriptorHandle.ptr != 0); + if (ShdrVisibleSamplerHeapCPUDescriptorHandle.ptr != 0) + { + m_pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleSamplerHeapCPUDescriptorHandle, SrcSampler.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + } + } + else + { + VERIFY_EXPR(DstSampler.pObject == SrcSampler.pObject); + VERIFY_EXPR(DstSampler.Type == SrcSampler.Type); + VERIFY_EXPR(DstSampler.CPUDescriptorHandle.ptr == SrcSampler.CPUDescriptorHandle.ptr); + } + } + } + } +} + + +#ifdef VERIFY_SHADER_BINDINGS +void ShaderResourceLayoutD3D12::dbgVerifyBindings()const +{ + VERIFY(m_pResourceCache, "Resource cache is null") + + for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_VARIABLE_TYPE>(VarType+1)) + { + for(Uint32 r=0; r < m_NumCbvSrvUav[VarType]; ++r) + { + const auto &res = GetSrvCbvUav(VarType, r); + VERIFY(res.Attribs.GetVariableType() == VarType, "Unexpected variable type") + + for(Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) + { + const auto &CachedRes = m_pResourceCache->GetRootTable(res.GetRootIndex()).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + if(CachedRes.pObject) + VERIFY(CachedRes.Type == res.GetResType(), "Inconsistent cached resource types") + else + VERIFY(CachedRes.Type == CachedResourceType::Unknown, "Unexpected cached resource types") + + if( !CachedRes.pObject || + (CachedRes.CPUDescriptorHandle.ptr == 0 && ValidatedCast<const BufferD3D12Impl>(CachedRes.pObject.RawPtr())->GetDesc().Usage != USAGE_DYNAMIC) ) + LOG_ERROR_MESSAGE( "No resource is bound to ", GetShaderVariableTypeLiteralName(res.Attribs.GetVariableType()), " variable \"", res.Attribs.GetPrintName(ArrInd), "\" in shader \"", GetShaderName(), "\"" ) + + if (res.Attribs.BindCount > 1 && res.IsValidSampler()) + { + // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent + const auto &SamInfo = const_cast<ShaderResourceLayoutD3D12*>(this)->GetAssignedSampler(res); + if(SamInfo.Attribs.BindCount == 1) + { + const auto &CachedSampler = m_pResourceCache->GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + if( auto *pTexView = ValidatedCast<const ITextureView>(CachedRes.pObject.RawPtr()) ) + { + auto *pSampler = const_cast<ITextureView*>(pTexView)->GetSampler(); + if (CachedSampler.pObject != pSampler) + LOG_ERROR_MESSAGE( "All elements of texture array \"", res.Attribs.Name, "\" in shader \"", GetShaderName(), "\" share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform." ) + } + } + } + +#ifdef _DEBUG + { + auto ShdrVisibleHeapCPUDescriptorHandle = m_pResourceCache->GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV>(res.GetRootIndex(), res.OffsetFromTableStart + ArrInd); + if (m_pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) + { + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Static shader resources of a shader should not be assigned shader visible descriptor space") + } + else if (m_pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) + { + if (res.GetResType() == CachedResourceType::CBV) + { + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Constant buffers are bound as root views and should not be assigned shader visible descriptor space") + } + else + { + if(res.Attribs.GetVariableType() == SHADER_VARIABLE_TYPE_DYNAMIC) + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Dynamic resources of a shader resource binding should be assigned shader visible descriptor space at every draw call") + else + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0, "Non-dynamics resources of a shader resource binding must be assigned shader visible descriptor space") + } + } + else + { + UNEXPECTED("Unknown content type") + } + } +#endif + } + + if (res.IsValidSampler()) + { + VERIFY(res.GetResType() == CachedResourceType::TexSRV, "Sampler can only be assigned to texture SRV" ); + const auto &SamInfo = const_cast<ShaderResourceLayoutD3D12*>(this)->GetAssignedSampler(res); + VERIFY( !SamInfo.Attribs.IsStaticSampler(), "Static samplers should never be assigned space in the cache" ) + VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid") + + for(Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) + { + const auto &CachedSampler = m_pResourceCache->GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + if( CachedSampler.pObject ) + VERIFY(CachedSampler.Type == CachedResourceType::Sampler, "Incorrect cached sampler type") + else + VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type") + if( !CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0 ) + LOG_ERROR_MESSAGE("No sampler is assigned to texture variable \"", res.Attribs.GetPrintName(ArrInd), "\" in shader \"", GetShaderName(), "\"") + + #ifdef _DEBUG + { + auto ShdrVisibleHeapCPUDescriptorHandle = m_pResourceCache->GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(SamInfo.RootIndex, SamInfo.OffsetFromTableStart + ArrInd); + if (m_pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) + { + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Static shader resources of a shader should not be assigned shader visible descriptor space") + } + else if (m_pResourceCache->DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) + { + if(SamInfo.Attribs.GetVariableType() == SHADER_VARIABLE_TYPE_DYNAMIC) + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Dynamic resources of a shader resource binding should be assigned shader visible descriptor space at every draw call") + else + VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0, "Non-dynamics resources of a shader resource binding must be assigned shader visible descriptor space") + } + else + { + UNEXPECTED("Unknown content type") + } + } + #endif + } + } + } + + for(Uint32 s=0; s < m_NumSamplers[VarType]; ++s) + { + const auto &sam = GetSampler(VarType, s); + VERIFY(sam.Attribs.GetVariableType() == VarType, "Unexpected sampler variable type") + + for(Uint32 ArrInd = 0; ArrInd < sam.Attribs.BindCount; ++ArrInd) + { + const auto &CachedSampler = m_pResourceCache->GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + if( CachedSampler.pObject ) + VERIFY(CachedSampler.Type == CachedResourceType::Sampler, "Incorrect cached sampler type") + else + VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type") + if( !CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0 ) + LOG_ERROR_MESSAGE( "No sampler is bound to sampler variable \"", sam.Attribs.GetPrintName(ArrInd), "\" in shader \"", GetShaderName(), "\"" ) + } + } + } +} +#endif + +const Char* ShaderResourceLayoutD3D12::GetShaderName()const +{ + RefCntAutoPtr<IShader> pShader(&m_Owner, IID_Shader); + if (pShader) + { + return pShader->GetDesc().Name; + } + else + { + RefCntAutoPtr<IShaderResourceBinding> pSRB(&m_Owner, IID_ShaderResourceBinding); + if(pSRB) + { + auto *pPSO = pSRB->GetPipelineState(); + auto *pPSOD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPSO); + auto *ppShaders = pPSOD3D12->GetShaders(); + auto NumShaders = pPSOD3D12->GetNumShaders(); + for (Uint32 s = 0; s < NumShaders; ++s) + { + const auto &ShaderDesc = ppShaders[s]->GetDesc(); + if(ShaderDesc.ShaderType == m_pResources->GetShaderType()) + return ShaderDesc.Name; + } + UNEXPECTED("Shader not found") + } + else + { + UNEXPECTED("Owner is expected to be a shader or a shader resource binding") + } + } + return ""; +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp new file mode 100644 index 00000000..e7543ce6 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp @@ -0,0 +1,93 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include <d3dcompiler.h> +#include "ShaderResourcesD3D12.h" +#include "ShaderD3DBase.h" +#include "ShaderBase.h" +#include "D3DShaderResourceLoader.h" + + +namespace Diligent +{ + + +ShaderResourcesD3D12::ShaderResourcesD3D12(ID3DBlob *pShaderBytecode, const ShaderDesc &ShdrDesc) : + ShaderResources(GetRawAllocator(), ShdrDesc.ShaderType) +{ + Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0; + LoadD3DShaderResources<D3D12_SHADER_DESC, D3D12_SHADER_INPUT_BIND_DESC, ID3D12ShaderReflection>( + pShaderBytecode, + + [&](Uint32 NumCBs, Uint32 NumTexSRVs, Uint32 NumTexUAVs, Uint32 NumBufSRVs, Uint32 NumBufUAVs, Uint32 NumSamplers) + { + Initialize(GetRawAllocator(), NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); + }, + + [&](D3DShaderResourceAttribs&& CBAttribs) + { + new (&GetCB(CurrCB++)) D3DShaderResourceAttribs(std::move(CBAttribs)); + }, + + [&](D3DShaderResourceAttribs &&TexUAV) + { + new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs( std::move(TexUAV) ); + }, + + [&](D3DShaderResourceAttribs &&BuffUAV) + { + new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs( std::move(BuffUAV) ); + }, + + [&](D3DShaderResourceAttribs &&BuffSRV) + { + new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs( std::move(BuffSRV) ); + }, + + [&](D3DShaderResourceAttribs &&SamplerAttribs) + { + new (&GetSampler(CurrSampler++)) D3DShaderResourceAttribs( std::move(SamplerAttribs) ); + }, + + [&](D3DShaderResourceAttribs &&TexAttribs) + { + VERIFY(CurrSampler == GetNumSamplers(), "All samplers must be initialized before texture SRVs" ); + + auto SamplerId = FindAssignedSamplerId(TexAttribs); + new (&GetTexSRV(CurrTexSRV++)) D3DShaderResourceAttribs( std::move(TexAttribs), SamplerId); + }, + + ShdrDesc, + D3DSamplerSuffix); + + VERIFY(CurrCB == GetNumCBs(), "Not all CBs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called"); + VERIFY(CurrTexSRV == GetNumTexSRV(), "Not all Tex SRVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrTexUAV == GetNumTexUAV(), "Not all Tex UAVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufSRV == GetNumBufSRV(), "Not all Buf SRVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufUAV == GetNumBufUAV(), "Not all Buf UAVs are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrSampler == GetNumSamplers(), "Not all Samplers are initialized, which will result in a crash when ~D3DShaderResourceAttribs() is called" ); +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp new file mode 100644 index 00000000..e1be6145 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp @@ -0,0 +1,262 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "SwapChainD3D12Impl.h" +#include "RenderDeviceD3D12Impl.h" +#include "DeviceContextD3D12Impl.h" +#include "DXGITypeConversions.h" +#include "TextureD3D12Impl.h" +#include "EngineMemory.h" + +namespace Diligent +{ + +SwapChainD3D12Impl::SwapChainD3D12Impl(IMemoryAllocator &Allocator, + const SwapChainDesc& SCDesc, + RenderDeviceD3D12Impl* pRenderDeviceD3D12, + DeviceContextD3D12Impl* pDeviceContextD3D12, + void* pNativeWndHandle) : + TSwapChainBase(Allocator, pRenderDeviceD3D12, pDeviceContextD3D12, SCDesc), + m_pBackBufferRTV(STD_ALLOCATOR_RAW_MEM(RefCntAutoPtr<ITextureView>, GetRawAllocator(), "Allocator for vector<RefCntAutoPtr<ITextureView>>")) +{ + +#ifdef PLATFORM_WIN32 + auto hWnd = reinterpret_cast<HWND>(pNativeWndHandle); + + if( m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0 ) + { + RECT rc; + GetClientRect( hWnd, &rc ); + m_SwapChainDesc.Width = rc.right - rc.left; + m_SwapChainDesc.Height = rc.bottom - rc.top; + } +#endif + + auto DXGIColorBuffFmt = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = m_SwapChainDesc.Width; + swapChainDesc.Height = m_SwapChainDesc.Height; + // Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats: + // - DXGI_FORMAT_R16G16B16A16_FLOAT + // - DXGI_FORMAT_B8G8R8A8_UNORM + // - DXGI_FORMAT_R8G8B8A8_UNORM + // - DXGI_FORMAT_R10G10B10A2_UNORM + // If RGBA8_UNORM_SRGB swap chain is required, we will create RGBA8_UNORM swap chain, but + // create RGBA8_UNORM_SRGB render target view + swapChainDesc.Format = DXGIColorBuffFmt == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGIColorBuffFmt; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = m_SwapChainDesc.BufferCount; + swapChainDesc.Scaling = DXGI_SCALING_NONE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used + swapChainDesc.Flags = 0; + + CComPtr<IDXGISwapChain1> pSwapChain1; + CComPtr<IDXGIFactory4> factory; + HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast<void**>(static_cast<IDXGIFactory4**>(&factory)) ); + CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory") + + auto *pd3d12CmdQueue = pRenderDeviceD3D12->GetCmdQueue(); +#if defined( PLATFORM_WIN32 ) + hr = factory->CreateSwapChainForHwnd(pd3d12CmdQueue, hWnd, &swapChainDesc, nullptr, nullptr, &pSwapChain1); + CHECK_D3D_RESULT_THROW( hr, "Failed to create Swap Chain" ); + + // This sample does not support fullscreen transitions. + hr = factory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER); + +#elif defined( PLATFORM_UNIVERSAL_WINDOWS ) + + hr = factory->CreateSwapChainForCoreWindow( + pd3d12CmdQueue, + reinterpret_cast<IUnknown*>(pNativeWndHandle), + &swapChainDesc, + nullptr, + &pSwapChain1); + CHECK_D3D_RESULT_THROW( hr, "Failed to create DXGI swap chain" ); + + // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and + // ensures that the application will only render after each VSync, minimizing power consumption. + //pDXGIDevice->SetMaximumFrameLatency( 1 ); + +#endif + + pSwapChain1->QueryInterface(__uuidof(m_pSwapChain), reinterpret_cast<void**>( static_cast<IDXGISwapChain3**>(&m_pSwapChain) )); + + InitBuffersAndViews(); +} + +SwapChainD3D12Impl::~SwapChainD3D12Impl() +{ + +} + +void SwapChainD3D12Impl::InitBuffersAndViews() +{ + m_pBackBufferRTV.resize(m_SwapChainDesc.BufferCount); + for(Uint32 backbuff = 0; backbuff < m_SwapChainDesc.BufferCount; ++backbuff) + { + CComPtr<ID3D12Resource> pBackBuffer; + auto hr = m_pSwapChain->GetBuffer(backbuff, __uuidof(pBackBuffer), reinterpret_cast<void**>( static_cast<ID3D12Resource**>(&pBackBuffer) )); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to get back buffer ", backbuff," from the swap chain"); + + TextureDesc BackBufferDesc; + BackBufferDesc.Format = m_SwapChainDesc.ColorBufferFormat; + String Name = "Main back buffer "; + Name += std::to_string(backbuff); + BackBufferDesc.Name = Name.c_str(); + + RefCntAutoPtr<TextureD3D12Impl> pBackBufferTex; + ValidatedCast<RenderDeviceD3D12Impl>(m_pRenderDevice.RawPtr())->CreateTexture(BackBufferDesc, pBackBuffer, &pBackBufferTex); + TextureViewDesc RTVDesc; + RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + RefCntAutoPtr<ITextureView> pRTV; + pBackBufferTex->CreateView(RTVDesc, &pRTV); + m_pBackBufferRTV[backbuff] = pRTV; + } + + TextureDesc DepthBufferDesc; + DepthBufferDesc.Type = RESOURCE_DIM_TEX_2D; + DepthBufferDesc.Width = m_SwapChainDesc.Width; + DepthBufferDesc.Height = m_SwapChainDesc.Height; + DepthBufferDesc.Format = m_SwapChainDesc.DepthBufferFormat; + DepthBufferDesc.SampleCount = m_SwapChainDesc.SamplesCount; + DepthBufferDesc.Usage = USAGE_DEFAULT; + DepthBufferDesc.BindFlags = BIND_DEPTH_STENCIL; + + DepthBufferDesc.ClearValue.Format = DepthBufferDesc.Format; + DepthBufferDesc.ClearValue.DepthStencil.Depth = m_SwapChainDesc.DefaultDepthValue; + DepthBufferDesc.ClearValue.DepthStencil.Stencil = m_SwapChainDesc.DefaultStencilValue; + String Name = "Main depth buffer"; + RefCntAutoPtr<ITexture> pDepthBufferTex; + m_pRenderDevice->CreateTexture(DepthBufferDesc, TextureData(), static_cast<ITexture**>(&pDepthBufferTex) ); + m_pDepthBufferDSV = pDepthBufferTex->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL); +} + +IMPLEMENT_QUERY_INTERFACE( SwapChainD3D12Impl, IID_SwapChainD3D12, TSwapChainBase ) + + +void SwapChainD3D12Impl::Present() +{ + UINT SyncInterval = 0; +#ifdef PLATFORM_UNIVERSAL_WINDOWS + SyncInterval = 1; // Interval 0 is not supported on Windows Phone +#endif + + auto pDeviceContext = m_wpDeviceContext.Lock(); + if( !pDeviceContext ) + { + LOG_ERROR_MESSAGE( "Immediate context has been released" ); + return; + } + + auto *pImmediateCtx = pDeviceContext.RawPtr(); + auto *pImmediateCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>( pImmediateCtx ); + + auto *pCmdCtx = pImmediateCtxD3D12->RequestCmdContext(); + auto *pBackBuffer = ValidatedCast<TextureD3D12Impl>( GetCurrentBackBufferRTV()->GetTexture() ); + pCmdCtx->TransitionResource( pBackBuffer, D3D12_RESOURCE_STATE_PRESENT); + + pImmediateCtxD3D12->Flush(); + + auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pImmediateCtxD3D12->GetDevice() ); + + auto hr = m_pSwapChain->Present( SyncInterval, 0 ); + VERIFY(SUCCEEDED(hr), "Present failed"); + + pDeviceD3D12->FinishFrame(); + +#if 0 +#ifdef PLATFORM_UNIVERSAL_WINDOWS + // A successful Present call for DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL SwapChains unbinds + // backbuffer 0 from all GPU writeable bind points. + // We need to rebind all render targets to make sure that + // the back buffer is not unbound + pImmediateCtxD3D12->RebindRenderTargets(); +#endif +#endif +} + +void SwapChainD3D12Impl::Resize( Uint32 NewWidth, Uint32 NewHeight ) +{ + if( TSwapChainBase::Resize(NewWidth, NewHeight) ) + { + auto pDeviceContext = m_wpDeviceContext.Lock(); + VERIFY( pDeviceContext, "Immediate context has been released" ); + if( pDeviceContext ) + { + RenderDeviceD3D12Impl *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>(m_pRenderDevice.RawPtr()); + pDeviceContext->Flush(); + + try + { + auto *pImmediateCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pDeviceContext.RawPtr()); + bool bIsDefaultFBBound = pImmediateCtxD3D12->IsDefaultFBBound(); + + // All references to the swap chain must be released before it can be resized + m_pBackBufferRTV.clear(); + m_pDepthBufferDSV.Release(); + + // This will release references to D3D12 swap chain buffers hold by + // m_pBackBufferRTV[] + pDeviceD3D12->IdleGPU(true); + + DXGI_SWAP_CHAIN_DESC SCDes; + memset( &SCDes, 0, sizeof( SCDes ) ); + m_pSwapChain->GetDesc( &SCDes ); + CHECK_D3D_RESULT_THROW( m_pSwapChain->ResizeBuffers(SCDes.BufferCount, m_SwapChainDesc.Width, + m_SwapChainDesc.Height, SCDes.BufferDesc.Format, + SCDes.Flags), + "Failed to resize the DXGI swap chain" ); + + + InitBuffersAndViews(); + + if( bIsDefaultFBBound ) + { + // Set default render target and viewport + pDeviceContext->SetRenderTargets( 0, nullptr, nullptr ); + pDeviceContext->SetViewports( 1, nullptr, 0, 0 ); + } + } + catch( const std::runtime_error & ) + { + LOG_ERROR( "Failed to resize the swap chain" ); + } + } + } +} + +ITextureView *SwapChainD3D12Impl::GetCurrentBackBufferRTV() +{ + auto CurrentBackBufferIndex = m_pSwapChain->GetCurrentBackBufferIndex(); + VERIFY_EXPR(CurrentBackBufferIndex>=0 && CurrentBackBufferIndex < m_SwapChainDesc.BufferCount); + return m_pBackBufferRTV[CurrentBackBufferIndex]; +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp new file mode 100644 index 00000000..d59f1947 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp @@ -0,0 +1,511 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "TextureD3D12Impl.h" +#include "RenderDeviceD3D12Impl.h" +#include "DeviceContextD3D12Impl.h" +#include "D3D12TypeConversions.h" +#include "TextureViewD3D12Impl.h" +#include "DXGITypeConversions.h" +#include "d3dx12_win.h" +#include "EngineMemory.h" + +using namespace Diligent; + +namespace Diligent +{ + +DXGI_FORMAT GetClearFormat(DXGI_FORMAT Fmt, D3D12_RESOURCE_FLAGS Flags) +{ + if( Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL ) + { + switch (Fmt) + { + case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_D32_FLOAT; + case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_D16_UNORM; + case DXGI_FORMAT_R24G8_TYPELESS: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R32G8X24_TYPELESS: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + } + } + else if (Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + { + + } + return Fmt; +} + +TextureD3D12Impl :: TextureD3D12Impl(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + RenderDeviceD3D12Impl *pRenderDeviceD3D12, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/) : + TTextureBase(TexObjAllocator, TexViewObjAllocator, pRenderDeviceD3D12, TexDesc) +{ + if( m_Desc.Usage == USAGE_STATIC && InitData.pSubResources == nullptr ) + LOG_ERROR_AND_THROW("Static Texture must be initialized with data at creation time"); + + D3D12_RESOURCE_DESC Desc = {}; + Desc.Alignment = 0; + if(m_Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY || m_Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || m_Desc.Type == RESOURCE_DIM_TEX_CUBE || m_Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) + Desc.DepthOrArraySize = (UINT16)m_Desc.ArraySize; + else if(m_Desc.Type == RESOURCE_DIM_TEX_3D ) + Desc.DepthOrArraySize = (UINT16)m_Desc.Depth; + else + Desc.DepthOrArraySize = 1; + + if( m_Desc.Type == RESOURCE_DIM_TEX_1D || m_Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) + Desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D; + else if( m_Desc.Type == RESOURCE_DIM_TEX_2D || m_Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || m_Desc.Type == RESOURCE_DIM_TEX_CUBE || m_Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) + Desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + else if( m_Desc.Type == RESOURCE_DIM_TEX_3D ) + Desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; + else + { + LOG_ERROR_AND_THROW("Unknown texture type"); + } + + + Desc.Flags = D3D12_RESOURCE_FLAG_NONE; + if( m_Desc.BindFlags & BIND_RENDER_TARGET ) + Desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + if( m_Desc.BindFlags & BIND_DEPTH_STENCIL ) + Desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + if( (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || (m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) ) + Desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + Desc.Format = TexFormatToDXGI_Format(m_Desc.Format, m_Desc.BindFlags);; + Desc.Height = (UINT)m_Desc.Height; + Desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + Desc.MipLevels = static_cast<Uint16>(m_Desc.MipLevels); + Desc.SampleDesc.Count = m_Desc.SampleCount; + Desc.SampleDesc.Quality = 0; + Desc.Width = (UINT64)m_Desc.Width; + + + D3D12_HEAP_PROPERTIES HeapProps; + HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + HeapProps.CreationNodeMask = 1; + HeapProps.VisibleNodeMask = 1; + + auto *pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); + D3D12_CLEAR_VALUE ClearValue; + D3D12_CLEAR_VALUE *pClearValue = nullptr; + if( Desc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) ) + { + if(m_Desc.ClearValue.Format != TEX_FORMAT_UNKNOWN) + ClearValue.Format = TexFormatToDXGI_Format(m_Desc.ClearValue.Format); + else + ClearValue.Format = GetClearFormat(Desc.Format, Desc.Flags); + + if (Desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + { + for(int i=0; i < 4; ++i) + ClearValue.Color[i] = m_Desc.ClearValue.Color[i]; + } + else if(Desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + { + ClearValue.DepthStencil.Depth = m_Desc.ClearValue.DepthStencil.Depth; + ClearValue.DepthStencil.Stencil = m_Desc.ClearValue.DepthStencil.Stencil; + } + pClearValue = &ClearValue; + } + + bool bInitializeTexture = (InitData.pSubResources != nullptr && InitData.NumSubresources > 0); + if(bInitializeTexture) + m_UsageState = D3D12_RESOURCE_STATE_COPY_DEST; + + auto hr = pd3d12Device->CreateCommittedResource( &HeapProps, D3D12_HEAP_FLAG_NONE, + &Desc, m_UsageState, pClearValue, __uuidof(m_pd3d12Resource), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)) ); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create D3D12 texture") + + if(bInitializeTexture) + { + Uint32 ExpectedNumSubresources = static_cast<Uint32>(Desc.MipLevels * (Desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? 1 : Desc.DepthOrArraySize) ); + if( InitData.NumSubresources != ExpectedNumSubresources ) + LOG_ERROR_AND_THROW("Incorrect number of subresources in init data. ", ExpectedNumSubresources, " expected, while ", InitData.NumSubresources, " provided") + + UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_pd3d12Resource, 0, InitData.NumSubresources); + + D3D12_HEAP_PROPERTIES UploadHeapProps; + UploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + UploadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + UploadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + UploadHeapProps.CreationNodeMask = 1; + UploadHeapProps.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC BufferDesc; + BufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + BufferDesc.Alignment = 0; + BufferDesc.Width = uploadBufferSize; + BufferDesc.Height = 1; + BufferDesc.DepthOrArraySize = 1; + BufferDesc.MipLevels = 1; + BufferDesc.Format = DXGI_FORMAT_UNKNOWN; + BufferDesc.SampleDesc.Count = 1; + BufferDesc.SampleDesc.Quality = 0; + BufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + BufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + CComPtr<ID3D12Resource> UploadBuffer; + hr = pd3d12Device->CreateCommittedResource( &UploadHeapProps, D3D12_HEAP_FLAG_NONE, + &BufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, __uuidof(UploadBuffer), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&UploadBuffer))); + if(FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create committed resource in an upload heap") + + auto *pInitContext = pRenderDeviceD3D12->AllocateCommandContext(); + // copy data to the intermediate upload heap and then schedule a copy from the upload heap to the default texture + VERIFY_EXPR(m_UsageState == D3D12_RESOURCE_STATE_COPY_DEST); + std::vector<D3D12_SUBRESOURCE_DATA, STDAllocatorRawMem<D3D12_SUBRESOURCE_DATA> > D3D12SubResData(InitData.NumSubresources, D3D12_SUBRESOURCE_DATA(), STD_ALLOCATOR_RAW_MEM(D3D12_SUBRESOURCE_DATA, GetRawAllocator(), "Allocator for vector<D3D12_SUBRESOURCE_DATA>") ); + for(size_t subres=0; subres < D3D12SubResData.size(); ++subres) + { + D3D12SubResData[subres].pData = InitData.pSubResources[subres].pData; + D3D12SubResData[subres].RowPitch = InitData.pSubResources[subres].Stride; + D3D12SubResData[subres].SlicePitch = InitData.pSubResources[subres].DepthStride; + } + auto UploadedSize = UpdateSubresources(pInitContext->GetCommandList(), m_pd3d12Resource, UploadBuffer, 0, 0, InitData.NumSubresources, D3D12SubResData.data()); + VERIFY(UploadedSize == uploadBufferSize, "Incorrect uploaded data size (", UploadedSize, "). ", uploadBufferSize, " is expected"); + + pRenderDeviceD3D12->CloseAndExecuteCommandContext(pInitContext); + + // We MUST NOT call TransitionResource() from here, because + // it will call AddRef() and potentially Release(), while + // the object is not constructed yet + // Add reference to the object to the release queue to keep it alive + // until copy operation is complete. This must be done after + // submitting command list for execution! + pRenderDeviceD3D12->SafeReleaseD3D12Object(UploadBuffer); + } + + if(m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) + { + auto NumSubresources = m_Desc.MipLevels * m_Desc.ArraySize; + m_SubresUAVs = pRenderDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, NumSubresources); + for(Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) + for (Uint32 MipLevel = 0; MipLevel < m_Desc.MipLevels; ++MipLevel) + { + auto SubResInd = D3D12CalcSubresource(MipLevel, Slice, 0, m_Desc.MipLevels, m_Desc.ArraySize); + VERIFY_EXPR(SubResInd < m_SubresUAVs.GetNumHandles()); + + TextureViewDesc UAVDesc; + if( m_Desc.Type == RESOURCE_DIM_TEX_2D ) + UAVDesc.TextureDim = RESOURCE_DIM_TEX_2D; + else + { + LOG_ERROR("Mipmap generation is only supported for 2D textures and texture arrays") + } + UAVDesc.ViewType = TEXTURE_VIEW_UNORDERED_ACCESS; + UAVDesc.FirstArraySlice = Slice; + UAVDesc.MostDetailedMip = MipLevel; + CreateUAV( UAVDesc, m_SubresUAVs.GetCpuHandle(SubResInd) ); + } + } +} + + +static TextureDesc InitTexDescFromD3D12Resource(ID3D12Resource *pTexture, const TextureDesc& SrcTexDesc) +{ + auto ResourceDesc = pTexture->GetDesc(); + + TextureDesc TexDesc = SrcTexDesc; + if( TexDesc.Width != 0 && TexDesc.Width != ResourceDesc.Width) + LOG_WARNING_MESSAGE("Provided texture width (", TexDesc.Width, ") does not match the actual D3D12 resource width (", ResourceDesc.Width, ")"); + if( TexDesc.Height != 0 && TexDesc.Height != ResourceDesc.Height) + LOG_WARNING_MESSAGE("Provided texture height (", TexDesc.Height, ") does not match the actual D3D12 resource height (", ResourceDesc.Height, ")"); + if( TexDesc.ArraySize != 0 && TexDesc.ArraySize != ResourceDesc.DepthOrArraySize) + LOG_WARNING_MESSAGE("Provided texture depth or array size (", TexDesc.ArraySize, ") does not match the actual D3D12 resource depth or array size (", ResourceDesc.DepthOrArraySize, ")"); + if( TexDesc.MipLevels != 0 && TexDesc.MipLevels != ResourceDesc.MipLevels) + LOG_WARNING_MESSAGE("Provided number of mip levels (", TexDesc.MipLevels, ") does not match the actual number of mip levels in D3D12 resource (", ResourceDesc.MipLevels, ")"); + auto RefDXGIFormat = TexFormatToDXGI_Format(TexDesc.Format); + if( RefDXGIFormat != TexDesc.Format) + LOG_ERROR_AND_THROW("Incorrect texture format (", GetTextureFormatAttribs(TexDesc.Format).Name, ")"); + + TexDesc.Width = static_cast<Uint32>(ResourceDesc.Width); + TexDesc.Height = static_cast<Uint32>(ResourceDesc.Height); + TexDesc.ArraySize = ResourceDesc.DepthOrArraySize; + TexDesc.MipLevels = ResourceDesc.MipLevels; + switch(ResourceDesc.Dimension) + { + case D3D12_RESOURCE_DIMENSION_TEXTURE1D: TexDesc.Type = TexDesc.ArraySize == 1 ? RESOURCE_DIM_TEX_1D : RESOURCE_DIM_TEX_1D_ARRAY; break; + case D3D12_RESOURCE_DIMENSION_TEXTURE2D: TexDesc.Type = TexDesc.ArraySize == 1 ? RESOURCE_DIM_TEX_2D : RESOURCE_DIM_TEX_2D_ARRAY; break; + case D3D12_RESOURCE_DIMENSION_TEXTURE3D: TexDesc.Type = RESOURCE_DIM_TEX_3D; break; + } + + TexDesc.SampleCount = ResourceDesc.SampleDesc.Count; + + TexDesc.Usage = USAGE_DEFAULT; + TexDesc.BindFlags = 0; + if( ResourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET ) + TexDesc.BindFlags |= BIND_RENDER_TARGET; + if( ResourceDesc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL ) + TexDesc.BindFlags |= BIND_DEPTH_STENCIL; + if( ResourceDesc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS ) + TexDesc.BindFlags |= BIND_UNORDERED_ACCESS; + return TexDesc; +} + +TextureD3D12Impl::TextureD3D12Impl(FixedBlockMemoryAllocator &TexObjAllocator, + FixedBlockMemoryAllocator &TexViewObjAllocator, + RenderDeviceD3D12Impl *pDeviceD3D12, + const TextureDesc& TexDesc, + ID3D12Resource *pTexture) : + TTextureBase(TexObjAllocator, TexViewObjAllocator, pDeviceD3D12, InitTexDescFromD3D12Resource(pTexture, TexDesc)) +{ + m_pd3d12Resource = pTexture; +} +IMPLEMENT_QUERY_INTERFACE( TextureD3D12Impl, IID_TextureD3D12, TTextureBase ) + +void TextureD3D12Impl::CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView ) +{ + VERIFY( ppView != nullptr, "View pointer address is null" ); + if( !ppView )return; + VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" ); + + *ppView = nullptr; + + try + { + auto *pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice()); + auto &TexViewAllocator = pDeviceD3D12Impl->GetTexViewObjAllocator(); + VERIFY( &TexViewAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization" ); + + auto UpdatedViewDesc = ViewDesc; + CorrectTextureViewDesc( UpdatedViewDesc ); + + DescriptorHeapAllocation ViewHandleAlloc; + switch( ViewDesc.ViewType ) + { + case TEXTURE_VIEW_SHADER_RESOURCE: + { + VERIFY( m_Desc.BindFlags & BIND_SHADER_RESOURCE, "BIND_SHADER_RESOURCE flag is not set" ); + ViewHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + CreateSRV( UpdatedViewDesc, ViewHandleAlloc.GetCpuHandle() ); + } + break; + + case TEXTURE_VIEW_RENDER_TARGET: + { + VERIFY( m_Desc.BindFlags & BIND_RENDER_TARGET, "BIND_RENDER_TARGET flag is not set" ); + ViewHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + CreateRTV( UpdatedViewDesc, ViewHandleAlloc.GetCpuHandle() ); + } + break; + + case TEXTURE_VIEW_DEPTH_STENCIL: + { + VERIFY( m_Desc.BindFlags & BIND_DEPTH_STENCIL, "BIND_DEPTH_STENCIL is not set" ); + ViewHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + CreateDSV( UpdatedViewDesc, ViewHandleAlloc.GetCpuHandle() ); + } + break; + + case TEXTURE_VIEW_UNORDERED_ACCESS: + { + VERIFY( m_Desc.BindFlags & BIND_UNORDERED_ACCESS, "BIND_UNORDERED_ACCESS flag is not set" ); + ViewHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + CreateUAV( UpdatedViewDesc, ViewHandleAlloc.GetCpuHandle() ); + } + break; + + default: UNEXPECTED( "Unknown view type" ); break; + } + + auto pViewD3D12 = NEW(TexViewAllocator, "TextureViewD3D12Impl instance", TextureViewD3D12Impl, GetDevice(), UpdatedViewDesc, this, std::move(ViewHandleAlloc), bIsDefaultView ); + VERIFY( pViewD3D12->GetDesc().ViewType == ViewDesc.ViewType, "Incorrect view type" ); + + if( bIsDefaultView ) + *ppView = pViewD3D12; + else + pViewD3D12->QueryInterface(IID_TextureView, reinterpret_cast<IObject**>(ppView) ); + } + catch( const std::runtime_error & ) + { + const auto *ViewTypeName = GetTexViewTypeLiteralName(ViewDesc.ViewType); + LOG_ERROR("Failed to create view \"", ViewDesc.Name ? ViewDesc.Name : "", "\" (", ViewTypeName, ") for texture \"", m_Desc.Name ? m_Desc.Name : "", "\"" ) + } +} + +TextureD3D12Impl :: ~TextureD3D12Impl() +{ + // D3D12 object can only be destroyed when it is no longer used by the GPU + auto *pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice()); + pDeviceD3D12Impl->SafeReleaseD3D12Object(m_pd3d12Resource); +} + +void TextureD3D12Impl::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + TTextureBase::UpdateData( pContext, MipLevel, Slice, DstBox, SubresData ); + VERIFY( m_Desc.Usage == USAGE_DEFAULT, "Only default usage resiurces can be updated with UpdateData()" ); + + LOG_ERROR_ONCE("TextureD3D12Impl::UpdateData() is not implemented"); +#if 0 + auto *pD3D12DeviceContext = static_cast<DeviceContextD3D12Impl*>(pContext)->GetD3D12DeviceContext(); + + D3D12_BOX D3D12Box; + D3D12Box.left = DstBox.MinX; + D3D12Box.right = DstBox.MaxX; + D3D12Box.top = DstBox.MinY; + D3D12Box.bottom = DstBox.MaxY; + D3D12Box.front = DstBox.MinZ; + D3D12Box.back = DstBox.MaxZ; + auto SubresIndex = D3D12CalcSubresource(MipLevel, Slice, m_Desc.MipLevels); + pD3D12DeviceContext->UpdateSubresource(m_pd3d12Resource, SubresIndex, &D3D12Box, SubresData.pData, SubresData.Stride, SubresData.DepthStride); +#endif +} + +void TextureD3D12Impl :: CopyData(IDeviceContext *pContext, + ITexture *pSrcTexture, + Uint32 SrcMipLevel, + Uint32 SrcSlice, + const Box *pSrcBox, + Uint32 DstMipLevel, + Uint32 DstSlice, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ) +{ + TTextureBase::CopyData( pContext, pSrcTexture, SrcMipLevel, SrcSlice, pSrcBox, + DstMipLevel, DstSlice, DstX, DstY, DstZ ); + + auto *pCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pContext); + auto *pSrcTexD3D12 = ValidatedCast<TextureD3D12Impl>( pSrcTexture ); + + D3D12_BOX D3D12SrcBox, *pD3D12SrcBox = nullptr; + if( pSrcBox ) + { + D3D12SrcBox.left = pSrcBox->MinX; + D3D12SrcBox.right = pSrcBox->MaxX; + D3D12SrcBox.top = pSrcBox->MinY; + D3D12SrcBox.bottom = pSrcBox->MaxY; + D3D12SrcBox.front = pSrcBox->MinZ; + D3D12SrcBox.back = pSrcBox->MaxZ; + pD3D12SrcBox = &D3D12SrcBox; + } + + auto DstSubResIndex = D3D12CalcSubresource(DstMipLevel, DstSlice, 0, m_Desc.MipLevels, m_Desc.ArraySize); + auto SrcSubResIndex = D3D12CalcSubresource(SrcMipLevel, SrcSlice, 0, pSrcTexD3D12->m_Desc.MipLevels, pSrcTexD3D12->m_Desc.ArraySize); + pCtxD3D12->CopyTextureRegion(pSrcTexD3D12, SrcSubResIndex, pD3D12SrcBox, this, DstSubResIndex, DstX, DstY, DstZ); +} + +void TextureD3D12Impl :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) +{ + TTextureBase::Map( pContext, MapType, MapFlags, pMappedData ); + LOG_ERROR_ONCE("TextureD3D12Impl::Map() is not implemented"); + + static char TmpDummyBuffer[1024*1024*64]; + pMappedData = TmpDummyBuffer; + + //auto *pD3D12DeviceContext = static_cast<RenderDeviceD3D12Impl*>( static_cast<CRenderDevice*>(m_pDevice) )->GetD3D12DeviceContext(); + //auto D3D12MapType = MapTypeToD3D12MapType(MapType); + //auto D3D12MapFlags = MapFlagsToD3D12MapFlags(MapFlags); + + //D3D12_MAPPED_SUBRESOURCE MappedBuff; + //pD3D12DeviceContext->Map(m_pd3d12Resource, 0, D3D12MapType, D3D12MapFlags, &MappedBuff); + + //pMappedData = MappedBuff.pData; + + //VERIFY( pMappedData, "Map failed" ); +} + +void TextureD3D12Impl::Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) +{ + TTextureBase::Unmap( pContext, MapType ); + LOG_ERROR_ONCE("TextureD3D12Impl::Unmap() is not implemented"); + //auto *pD3D12DeviceContext = static_cast<RenderDeviceD3D12Impl*>( static_cast<CRenderDevice*>(m_pDevice) )->GetD3D12DeviceContext(); + //pD3D12DeviceContext->Unmap(m_pd3d12Resource, 0); +} + + +void TextureD3D12Impl::CreateSRV( TextureViewDesc &SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVHandle ) +{ + VERIFY( SRVDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); + + if( SRVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + SRVDesc.Format = m_Desc.Format; + } + D3D12_SHADER_RESOURCE_VIEW_DESC D3D12_SRVDesc; + TextureViewDesc_to_D3D12_SRV_DESC(SRVDesc, D3D12_SRVDesc, m_Desc.SampleCount); + + auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device(); + pDeviceD3D12->CreateShaderResourceView(m_pd3d12Resource, &D3D12_SRVDesc, SRVHandle); +} + +void TextureD3D12Impl::CreateRTV( TextureViewDesc &RTVDesc, D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle ) +{ + VERIFY( RTVDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); + + if( RTVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + RTVDesc.Format = m_Desc.Format; + } + + D3D12_RENDER_TARGET_VIEW_DESC D3D12_RTVDesc; + TextureViewDesc_to_D3D12_RTV_DESC(RTVDesc, D3D12_RTVDesc, m_Desc.SampleCount); + + auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device(); + pDeviceD3D12->CreateRenderTargetView( m_pd3d12Resource, &D3D12_RTVDesc, RTVHandle ); +} + +void TextureD3D12Impl::CreateDSV( TextureViewDesc &DSVDesc, D3D12_CPU_DESCRIPTOR_HANDLE DSVHandle ) +{ + VERIFY( DSVDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Incorrect view type: depth stencil is expected" ); + + if( DSVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + DSVDesc.Format = m_Desc.Format; + } + + D3D12_DEPTH_STENCIL_VIEW_DESC D3D12_DSVDesc; + TextureViewDesc_to_D3D12_DSV_DESC(DSVDesc, D3D12_DSVDesc, m_Desc.SampleCount); + + auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device(); + pDeviceD3D12->CreateDepthStencilView( m_pd3d12Resource, &D3D12_DSVDesc, DSVHandle ); +} + +void TextureD3D12Impl::CreateUAV( TextureViewDesc &UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVHandle ) +{ + VERIFY( UAVDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); + + if( UAVDesc.Format == TEX_FORMAT_UNKNOWN ) + { + UAVDesc.Format = m_Desc.Format; + } + + D3D12_UNORDERED_ACCESS_VIEW_DESC D3D12_UAVDesc; + TextureViewDesc_to_D3D12_UAV_DESC(UAVDesc, D3D12_UAVDesc); + + auto *pDeviceD3D12 = static_cast<RenderDeviceD3D12Impl*>(GetDevice())->GetD3D12Device(); + pDeviceD3D12->CreateUnorderedAccessView( m_pd3d12Resource, nullptr, &D3D12_UAVDesc, UAVHandle ); +} + +D3D12_CPU_DESCRIPTOR_HANDLE TextureD3D12Impl::GetUAVDescriptorHandle(Uint32 Mip, Uint32 Slice) +{ + return m_SubresUAVs.GetCpuHandle(D3D12CalcSubresource(Mip, Slice, 0, m_Desc.MipLevels, m_Desc.ArraySize)); +} + +} diff --git a/Graphics/GraphicsEngineD3D12/src/TextureViewD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureViewD3D12Impl.cpp new file mode 100644 index 00000000..0b93926b --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/TextureViewD3D12Impl.cpp @@ -0,0 +1,61 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "TextureViewD3D12Impl.h" +#include "DeviceContextD3D12Impl.h" + +namespace Diligent +{ + +TextureViewD3D12Impl::TextureViewD3D12Impl( FixedBlockMemoryAllocator &TexViewObjAllocator, + IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + ITexture *pTexture, + DescriptorHeapAllocation &&HandleAlloc, + bool bIsDefaultView ) : + TTextureViewBase( TexViewObjAllocator, pDevice, ViewDesc, pTexture, bIsDefaultView ), + m_Descriptor(std::move(HandleAlloc)) +{ +} +// +//ID3D12View* TextureViewD3D12Impl::GetD3D12View() +//{ +// return m_pD3D12View; +//} + +IMPLEMENT_QUERY_INTERFACE( TextureViewD3D12Impl, IID_TextureViewD3D12, TTextureViewBase ) + +void TextureViewD3D12Impl::GenerateMips( IDeviceContext *pContext ) +{ + VERIFY( m_Desc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "GenerateMips() is allowed for shader resource views only, ", GetTexViewTypeLiteralName(m_Desc.ViewType), " is not allowed." ); + if( m_Desc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE ) + { + LOG_ERROR("GenerateMips() is allowed for shader resource views only, ", GetTexViewTypeLiteralName(m_Desc.ViewType), " is not allowed."); + return; + } + auto *pDeviceCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>( pContext ); + pDeviceCtxD3D12->GenerateMips(this); +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/RasterizerStateGLImpl.cpp b/Graphics/GraphicsEngineD3D12/src/pch.cpp index 191253f5..997e0f4a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RasterizerStateGLImpl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/pch.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,22 +22,3 @@ */ #include "pch.h" -#include "RasterizerStateGLImpl.h" -#include "RenderDeviceGLImpl.h" - -namespace Diligent -{ - -RasterizerStateGLImpl::RasterizerStateGLImpl(class IRenderDevice *pDeviceGL, const RasterizerStateDesc& RasterizerStateDesc, bool bIsDeviceInternal) : - TRasterizerStateBase(pDeviceGL, RasterizerStateDesc, bIsDeviceInternal) -{ -} - -RasterizerStateGLImpl::~RasterizerStateGLImpl() -{ - -} - -IMPLEMENT_QUERY_INTERFACE( RasterizerStateGLImpl, IID_RasterizerStateGL, TRasterizerStateBase ) - -} diff --git a/Graphics/GraphicsEngineD3DBase/build/UWP/GraphicsEngineD3DBase.vcxproj b/Graphics/GraphicsEngineD3DBase/build/UWP/GraphicsEngineD3DBase.vcxproj new file mode 100644 index 00000000..d2cbe9fc --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/build/UWP/GraphicsEngineD3DBase.vcxproj @@ -0,0 +1,200 @@ +<?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|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <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|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</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>{acd6f956-ff3b-4fe9-8be3-c0eecfdbbf93}</ProjectGuid> + <Keyword>StaticLibrary</Keyword> + <RootNamespace>GraphicsEngineD3DBase</RootNamespace> + <DefaultLanguage>en-US</DefaultLanguage> + <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> + <AppContainerApplication>true</AppContainerApplication> + <ApplicationType>Windows Store</ApplicationType> + <WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion> + <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion> + <ApplicationTypeRevision>10.0</ApplicationTypeRevision> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.Shared.vcxitems" Label="Shared" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmDbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmRel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> + </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" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ClCompile> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ClCompile> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <CompileAsWinRT>false</CompileAsWinRT> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3DBase/build/UWP/GraphicsEngineD3DBase.vcxproj.filters b/Graphics/GraphicsEngineD3DBase/build/UWP/GraphicsEngineD3DBase.vcxproj.filters new file mode 100644 index 00000000..c31757ec --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/build/UWP/GraphicsEngineD3DBase.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj b/Graphics/GraphicsEngineD3DBase/build/Win32/GraphicsEngineD3DBase.vcxproj index e99bf6b4..02bf1cb3 100644 --- a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj +++ b/Graphics/GraphicsEngineD3DBase/build/Win32/GraphicsEngineD3DBase.vcxproj @@ -1,141 +1,125 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> <ProjectConfiguration Include="Release|Win32"> <Configuration>Release</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{2f340c0e-43b2-471f-b4f3-7cdce69f6e1f}</ProjectGuid> - <RootNamespace>GraphicsTools</RootNamespace> - <DefaultLanguage>en-US</DefaultLanguage> - <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> - <AppContainerApplication>true</AppContainerApplication> - <ApplicationType>Windows Phone</ApplicationType> - <ApplicationTypeRevision>8.1</ApplicationTypeRevision> - <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + <ProjectGuid>{40FD58ED-AABC-4CBD-BEE4-33116995A626}</ProjectGuid> + <RootNamespace>GraphicsEngineD3DBase</RootNamespace> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120_wp81</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120_wp81</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120_wp81</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120_wp81</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="..\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.Shared.vcxitems" Label="Shared" /> + </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> + <Import Project="..\Windows.Shared\GraphicsEngineD3DBase.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> - <GenerateManifest>false</GenerateManifest> - </PropertyGroup> + <PropertyGroup /> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> + <Optimization>Disabled</Optimization> <SDLCheck>true</SDLCheck> </ClCompile> <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> </Link> </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> + <Optimization>Disabled</Optimization> <SDLCheck>true</SDLCheck> </ClCompile> <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> </Link> </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> <SDLCheck>true</SDLCheck> </ClCompile> <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> </Link> </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <CompileAsWinRT>false</CompileAsWinRT> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> <SDLCheck>true</SDLCheck> </ClCompile> <Link> - <SubSystem>Console</SubSystem> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <GenerateWindowsMetadata>false</GenerateWindowsMetadata> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> </Link> </ItemDefinitionGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj.filters b/Graphics/GraphicsEngineD3DBase/build/Win32/GraphicsEngineD3DBase.vcxproj.filters index 9cd85105..9cd85105 100644 --- a/Graphics/GraphicsEngineD3D11/build/Windows/GraphicsEngineD3D11.vcxproj.filters +++ b/Graphics/GraphicsEngineD3DBase/build/Win32/GraphicsEngineD3DBase.vcxproj.filters diff --git a/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.Shared.vcxitems b/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.Shared.vcxitems new file mode 100644 index 00000000..ec2067e5 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.Shared.vcxitems @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{9e0110fc-5339-4196-8397-ba4fa34a4b84}</ItemsProjectGuid> + <ItemsRootNamespace>ArithmeticCodec</ItemsRootNamespace> + <ItemsProjectName>GraphicsEngineD3DBase.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DErrors.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DShaderResourceLoader.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DTypeConversionImpl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DViewDescConversionImpl.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DXGITypeConversions.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceD3DBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderD3DBase.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResources.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderVariableD3DBase.h" /> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="$(MSBuildThisFileDirectory)..\..\include\HLSLDefinitions.fxh"> + <FileType>Document</FileType> + <Command>$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.fxh</Command> + <Outputs>$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> + <Message>Processing HLSLDefinitions.fxh...</Message> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DXGITypeConversions.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderD3DBase.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResources.cpp" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.Shared.vcxitems.filters b/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.Shared.vcxitems.filters new file mode 100644 index 00000000..8d4bb64f --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.Shared.vcxitems.filters @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{8a08aac0-0c0c-460e-997b-e2a2480f9348}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{f03946b0-f3aa-4358-845a-1f1d9c13056d}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DErrors.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DShaderResourceLoader.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DViewDescConversionImpl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DXGITypeConversions.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\D3DTypeConversionImpl.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RenderDeviceD3DBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderD3DBase.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderResources.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderVariableD3DBase.h"> + <Filter>include</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="$(MSBuildThisFileDirectory)..\..\include\HLSLDefinitions.fxh"> + <Filter>include</Filter> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DXGITypeConversions.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderD3DBase.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\ShaderResources.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.props b/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.props new file mode 100644 index 00000000..38b91f11 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/build/Windows.Shared/GraphicsEngineD3DBase.props @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros"> + <EngineRoot>..\..\..\..</EngineRoot> + <GraphicsRoot>..\..\..</GraphicsRoot> + <ProjectRoot>..\..</ProjectRoot> + </PropertyGroup> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsEngineD3DBase\include;$(GraphicsRoot)\GraphicsEngine\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\GraphicsTools\include;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <BuildMacro Include="EngineRoot"> + <Value>$(EngineRoot)</Value> + </BuildMacro> + <BuildMacro Include="GraphicsRoot"> + <Value>$(GraphicsRoot)</Value> + </BuildMacro> + <BuildMacro Include="ProjectRoot"> + <Value>$(ProjectRoot)</Value> + </BuildMacro> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineD3D11/include/D3DErrors.h b/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h index 00029230..5280820f 100644 --- a/Graphics/GraphicsEngineD3D11/include/D3DErrors.h +++ b/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h new file mode 100644 index 00000000..7e58c910 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h @@ -0,0 +1,335 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Shader.h" +#include "StringTools.h" + +/// \file +/// D3D shader resource loading + +namespace Diligent +{ + template<typename D3D_SHADER_DESC, + typename D3D_SHADER_INPUT_BIND_DESC, + typename TShaderReflection, + + typename TOnResourcesCounted, + typename TOnNewCB, + typename TOnNewTexUAV, + typename TOnNewBuffUAV, + typename TOnNewBuffSRV, + typename TOnNewSampler, + typename TOnNewTexSRV> + void LoadD3DShaderResources(ID3DBlob *pShaderByteCode, + + TOnResourcesCounted OnResourcesCounted, + TOnNewCB OnNewCB, + TOnNewTexUAV OnNewTexUAV, + TOnNewBuffUAV OnNewBuffUAV, + TOnNewBuffSRV OnNewBuffSRV, + TOnNewSampler OnNewSampler, + TOnNewTexSRV OnNewTexSRV, + + const ShaderDesc &ShdrDesc, + const Char *SamplerSuffix) + { + CComPtr<TShaderReflection> pShaderReflection; + CHECK_D3D_RESULT_THROW( D3DReflect( pShaderByteCode->GetBufferPointer(), pShaderByteCode->GetBufferSize(), __uuidof(pShaderReflection), reinterpret_cast<void**>(static_cast<TShaderReflection**>(&pShaderReflection)) ), + "Failed to get the shader reflection" ); + + D3D_SHADER_DESC shaderDesc = {}; + pShaderReflection->GetDesc( &shaderDesc ); + + std::vector<D3DShaderResourceAttribs, STDAllocatorRawMem<D3DShaderResourceAttribs> > Resources( STD_ALLOCATOR_RAW_MEM(D3DShaderResourceAttribs, GetRawAllocator(), "Allocator for vector<D3DShaderResourceAttribs>") ); + Resources.reserve(shaderDesc.BoundResources); + + Uint32 NumCBs = 0, NumTexSRVs = 0, NumTexUAVs = 0, NumBufSRVs = 0, NumBufUAVs = 0, NumSamplers = 0; + // Number of resources to skip (used for array resources) + UINT SkipCount = 1; + for( UINT Res = 0; Res < shaderDesc.BoundResources; Res += SkipCount ) + { + D3D_SHADER_INPUT_BIND_DESC BindingDesc = {}; + pShaderReflection->GetResourceBindingDesc( Res, &BindingDesc ); + + String Name(BindingDesc.Name); + + SkipCount = 1; + + UINT BindCount = BindingDesc.BindCount; + + // Handle arrays + // For shader models 5_0 and before, every resource array element is enumerated individually. + // For instance, if the following texture array is defined in the shader: + // + // Texture2D<float3> g_tex2DDiffuse[4]; + // + // The reflection system will enumerate 4 resources with the following names: + // "g_tex2DDiffuse[0]" + // "g_tex2DDiffuse[1]" + // "g_tex2DDiffuse[2]" + // "g_tex2DDiffuse[3]" + // + // Notice that if some array element is not used by the shader, it will not be enumerated + + auto OpenBracketPos = Name.find('['); + if (String::npos != OpenBracketPos) + { + VERIFY(BindCount == 1, "When array elements are enumerated individually, BindCount is expected to always be 1") + + // Name == "g_tex2DDiffuse[0]" + // ^ + // OpenBracketPos + Name.erase(OpenBracketPos, Name.length() - OpenBracketPos); + // Name == "g_tex2DDiffuse" + VERIFY_EXPR(Name.length() == OpenBracketPos); +#ifdef _DEBUG + for (const auto &ExistingRes : Resources) + { + VERIFY(ExistingRes.Name != Name, "Resource with the same name has already been enumerated. All array elements are expected to be enumerated one after another") + } +#endif + for( UINT ArrElem = Res+1; ArrElem < shaderDesc.BoundResources; ++ArrElem) + { + D3D_SHADER_INPUT_BIND_DESC ArrElemBindingDesc = {}; + pShaderReflection->GetResourceBindingDesc( ArrElem, &ArrElemBindingDesc ); + + // Make sure this case is handled correctly: + // "g_tex2DDiffuse[.]" != "g_tex2DDiffuse2[.]" + if ( strncmp(Name.c_str(), ArrElemBindingDesc.Name, OpenBracketPos) == 0 && ArrElemBindingDesc.Name[OpenBracketPos] == '[') + { + //g_tex2DDiffuse[2] + // ^ + UINT Ind = atoi(ArrElemBindingDesc.Name+OpenBracketPos+1); + BindCount = std::max(BindCount, Ind+1); + VERIFY(ArrElemBindingDesc.BindPoint == BindingDesc.BindPoint + Ind, + "Array elements are expected to use contigous bind points.\n", + BindingDesc.Name, " uses slot ", BindingDesc.BindPoint, ", so ", ArrElemBindingDesc.Name, " is expected to use slot ", BindingDesc.BindPoint + Ind, " while ", ArrElemBindingDesc.BindPoint, " is actually used" ); + + // Note that skip count may not necessarily be the same as BindCount. + // If some array elements are not used by the shader, the reflection system skips them + ++SkipCount; + } + else + { + break; + } + } + } + + + SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_NUM_TYPES; + bool IsStaticSampler = false; + if (BindingDesc.Type == D3D_SIT_SAMPLER) + { + for (Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s) + { + if( StrCmpSuff(Name.c_str(), ShdrDesc.StaticSamplers[s].TextureName, SamplerSuffix) ) + { + IsStaticSampler = true; + break; + } + } + // Use texture name to derive sampler type + VarType = GetShaderVariableType(ShdrDesc.DefaultVariableType, ShdrDesc.VariableDesc, ShdrDesc.NumVariables, + [&](const char *TexName) + { + return StrCmpSuff(Name.c_str(), TexName, SamplerSuffix); + } + ); + } + else + { + VarType = GetShaderVariableType(Name.c_str(), ShdrDesc.DefaultVariableType, ShdrDesc.VariableDesc, ShdrDesc.NumVariables); + } + + + switch( BindingDesc.Type ) + { + case D3D_SIT_CBUFFER: ++NumCBs; break; + case D3D_SIT_TBUFFER: UNSUPPORTED( "TBuffers are not supported" ); break; + case D3D_SIT_TEXTURE: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? NumBufSRVs : NumTexSRVs); break; + case D3D_SIT_SAMPLER: ++NumSamplers; break; + case D3D_SIT_UAV_RWTYPED: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? NumBufUAVs : NumTexUAVs); break; + case D3D_SIT_STRUCTURED: UNSUPPORTED( "Structured buffers are not supported" ); break; + case D3D_SIT_UAV_RWSTRUCTURED: ++NumBufUAVs; break; + case D3D_SIT_BYTEADDRESS: UNSUPPORTED( "Byte address buffers are not supported" ); break; + case D3D_SIT_UAV_RWBYTEADDRESS: ++NumBufUAVs; break; + case D3D_SIT_UAV_APPEND_STRUCTURED: UNSUPPORTED( "Append structured buffers are not supported" ); break; + case D3D_SIT_UAV_CONSUME_STRUCTURED: UNSUPPORTED( "Consume structured buffers are not supported" ); break; + case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: UNSUPPORTED( "RW structured buffers with counter are not supported" ); break; + default: UNEXPECTED("Unexpected resource type") + } + Resources.emplace_back(std::move(Name), BindingDesc.BindPoint, BindCount, BindingDesc.Type, VarType, BindingDesc.Dimension, D3DShaderResourceAttribs::InvalidSamplerId, IsStaticSampler); + } + + +#ifdef _DEBUG + if(ShdrDesc.NumVariables != 0 || ShdrDesc.NumStaticSamplers != 0 ) + { + for (Uint32 v = 0; v < ShdrDesc.NumVariables; ++v) + { + bool VariableFound = false; + const auto *VarName = ShdrDesc.VariableDesc[v].Name; + + for (const auto& Res : Resources) + { + // Skip samplers as they are not handled as independent variables + if (Res.GetInputType() != D3D_SIT_SAMPLER && Res.Name.compare(VarName) == 0) + { + VariableFound = true; + break; + } + } + if(!VariableFound) + { + LOG_WARNING_MESSAGE("Variable \"", VarName, "\" not found in shader \"", ShdrDesc.Name, '\"'); + } + } + + for (Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s) + { + bool TextureFound = false; + const auto *TexName = ShdrDesc.StaticSamplers[s].TextureName; + + for (const auto& Res : Resources) + { + if ( Res.GetInputType() == D3D_SIT_TEXTURE && Res.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER && Res.Name.compare(TexName) == 0) + { + TextureFound = true; + break; + } + } + if(!TextureFound) + { + LOG_WARNING_MESSAGE("Static sampler specifies a texture \"", TexName, "\" that is not found in shader \"", ShdrDesc.Name, '\"'); + } + } + } +#endif + + OnResourcesCounted(NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); + + std::vector<D3DShaderResourceAttribs, STDAllocatorRawMem<D3DShaderResourceAttribs> > TextureSRVs( STD_ALLOCATOR_RAW_MEM(D3DShaderResourceAttribs, GetRawAllocator(), "Allocator for vector<D3DShaderResourceAttribs>") ); + TextureSRVs.reserve(NumTexSRVs); + + for(auto &Res : Resources) + { + switch( Res.GetInputType() ) + { + case D3D_SIT_CBUFFER: + { + OnNewCB( std::move(Res) ); + break; + } + + case D3D_SIT_TBUFFER: + { + UNSUPPORTED( "TBuffers are not supported" ); + break; + } + + case D3D_SIT_TEXTURE: + { + if( Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ) + { + OnNewBuffSRV( std::move(Res) ); + } + else + { + TextureSRVs.emplace_back( std::move(Res) ); + } + break; + } + + case D3D_SIT_SAMPLER: + { + OnNewSampler( std::move(Res) ); + break; + } + + case D3D_SIT_UAV_RWTYPED: + { + if( Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ) + { + OnNewBuffUAV( std::move(Res) ); + } + else + { + OnNewTexUAV( std::move(Res) ); + } + break; + } + + case D3D_SIT_STRUCTURED: + { + UNSUPPORTED( "Structured buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_RWSTRUCTURED: + { + OnNewBuffUAV( std::move(Res) ); + break; + } + + case D3D_SIT_BYTEADDRESS: + { + UNSUPPORTED( "Byte address buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_RWBYTEADDRESS: + { + OnNewBuffUAV( std::move(Res) ); + break; + } + + case D3D_SIT_UAV_APPEND_STRUCTURED: + { + UNSUPPORTED( "Append structured buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_CONSUME_STRUCTURED: + { + UNSUPPORTED( "Consume structured buffers are not supported" ); + break; + } + + case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: + { + UNSUPPORTED( "RW structured buffers with counter are not supported" ); + break; + } + } + } + + // Process texture SRVs. We need to do this after all samplers are initialized + for( auto &Tex : TextureSRVs ) + { + OnNewTexSRV( std::move(Tex) ); + } + } +} diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h b/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h new file mode 100644 index 00000000..ebb8825b --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h @@ -0,0 +1,538 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of D3D type conversions + +/// This file must be included after D3D11TypeDefinitions.h or D3D12TypeDefinitions.h + +namespace Diligent +{ + + template<typename D3D_COMPARISON_FUNC> + inline D3D_COMPARISON_FUNC ComparisonFuncToD3DComparisonFunc(COMPARISON_FUNCTION Func) + { + // D3D12_COMPARISON_FUNC is equal to D3D11_COMPARISON_FUNC + switch(Func) + { + case COMPARISON_FUNC_UNKNOWN: UNEXPECTED("Comparison function is not specified" ); return D3D_COMPARISON_FUNC_ALWAYS; + case COMPARISON_FUNC_NEVER: return D3D_COMPARISON_FUNC_NEVER; + case COMPARISON_FUNC_LESS: return D3D_COMPARISON_FUNC_LESS; + case COMPARISON_FUNC_EQUAL: return D3D_COMPARISON_FUNC_EQUAL; + case COMPARISON_FUNC_LESS_EQUAL: return D3D_COMPARISON_FUNC_LESS_EQUAL; + case COMPARISON_FUNC_GREATER: return D3D_COMPARISON_FUNC_GREATER; + case COMPARISON_FUNC_NOT_EQUAL: return D3D_COMPARISON_FUNC_NOT_EQUAL; + case COMPARISON_FUNC_GREATER_EQUAL: return D3D_COMPARISON_FUNC_GREATER_EQUAL; + case COMPARISON_FUNC_ALWAYS: return D3D_COMPARISON_FUNC_ALWAYS; + default: UNEXPECTED("Unknown comparison function" ); return D3D_COMPARISON_FUNC_ALWAYS; + } + } + + + template<typename D3D_TEXTURE_ADDRESS_MODE> + D3D_TEXTURE_ADDRESS_MODE TexAddressModeToD3DAddressMode(TEXTURE_ADDRESS_MODE Mode) + { + switch(Mode) + { + case TEXTURE_ADDRESS_UNKNOWN: UNEXPECTED("Texture address mode is not specified" ); return D3D_TEXTURE_ADDRESS_CLAMP; + case TEXTURE_ADDRESS_WRAP: return D3D_TEXTURE_ADDRESS_WRAP; + case TEXTURE_ADDRESS_MIRROR: return D3D_TEXTURE_ADDRESS_MIRROR; + case TEXTURE_ADDRESS_CLAMP: return D3D_TEXTURE_ADDRESS_CLAMP; + case TEXTURE_ADDRESS_BORDER: return D3D_TEXTURE_ADDRESS_BORDER; + case TEXTURE_ADDRESS_MIRROR_ONCE: return D3D_TEXTURE_ADDRESS_MIRROR_ONCE; + default: UNEXPECTED("Unknown texture address mode" ); return D3D_TEXTURE_ADDRESS_CLAMP; + } + } + + template<typename D3D_PRIM_TOPOLOGY> + D3D_PRIM_TOPOLOGY TopologyToD3DTopology(PRIMITIVE_TOPOLOGY Topology) + { + static bool bIsInit = false; + static D3D_PRIM_TOPOLOGY d3dPrimTopology[PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES] = {}; + if( !bIsInit ) + { + d3dPrimTopology[PRIMITIVE_TOPOLOGY_UNDEFINED] = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_POINT_LIST] = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_LINE_LIST] = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + + bIsInit = true; + } + + VERIFY_EXPR(Topology >= PRIMITIVE_TOPOLOGY_UNDEFINED && Topology<PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES); + return d3dPrimTopology[Topology]; + } + + + // ================= Rasterizer state attributes conversion functions ================= + + template<typename D3D_FILL_MODE> + D3D_FILL_MODE FillModeToD3DFillMode(FILL_MODE FillMode) + { + // D3D12_FILL_MODE is identical tp D3D11_FILL_MODE + static bool bIsInit = false; + static D3D_FILL_MODE d3dFillModes[FILL_MODE_NUM_MODES] = {}; + if( !bIsInit ) + { + d3dFillModes[ FILL_MODE_WIREFRAME ] = D3D_FILL_MODE_WIREFRAME; + d3dFillModes[ FILL_MODE_SOLID ] = D3D_FILL_MODE_SOLID; + + bIsInit = true; + } + if( FILL_MODE_UNDEFINED < FillMode && FillMode < FILL_MODE_NUM_MODES ) + { + auto d3dFillMode = d3dFillModes[FillMode]; + VERIFY( d3dFillMode != 0, "Incorrect fill mode" ); + return d3dFillMode; + } + else + { + UNEXPECTED( "Incorrect fill mode (", FillMode, ")" ) + return static_cast<D3D_FILL_MODE>(0); + } + } + + template<typename D3D_CULL_MODE> + D3D_CULL_MODE CullModeToD3DCullMode( CULL_MODE CullMode ) + { + // D3D_CULL_MODE is identical to D3D11_CULL_MODE + static bool bIsInit = false; + static D3D_CULL_MODE d3dCullModes[CULL_MODE_NUM_MODES] = {}; + if( !bIsInit ) + { + d3dCullModes[ CULL_MODE_NONE ] = D3D_CULL_MODE_NONE; + d3dCullModes[ CULL_MODE_FRONT ] = D3D_CULL_MODE_FRONT; + d3dCullModes[ CULL_MODE_BACK ] = D3D_CULL_MODE_BACK; + + bIsInit = true; + } + + if( CULL_MODE_UNDEFINED < CullMode && CullMode < CULL_MODE_NUM_MODES ) + { + auto d3dCullMode = d3dCullModes[CullMode]; + VERIFY( d3dCullMode != 0, "Incorrect cull mode" ); + return d3dCullMode; + } + else + { + UNEXPECTED( "Incorrect cull mode (", CullMode, ")" ) + return static_cast<D3D_CULL_MODE>(0); + } + } + + template<typename D3D_RASTERIZER_DESC, typename D3D_FILL_MODE, typename D3D_CULL_MODE> + void RasterizerStateDesc_To_D3D_RASTERIZER_DESC(const RasterizerStateDesc &RasterizerDesc, D3D_RASTERIZER_DESC &d3dRSDesc) + { + d3dRSDesc.FillMode = FillModeToD3DFillMode<D3D_FILL_MODE>(RasterizerDesc.FillMode); + d3dRSDesc.CullMode = CullModeToD3DCullMode<D3D_CULL_MODE>(RasterizerDesc.CullMode); + d3dRSDesc.FrontCounterClockwise = RasterizerDesc.FrontCounterClockwise ? TRUE : FALSE; + d3dRSDesc.DepthBias = RasterizerDesc.DepthBias; + d3dRSDesc.DepthBiasClamp = RasterizerDesc.DepthBiasClamp; + d3dRSDesc.SlopeScaledDepthBias = RasterizerDesc.SlopeScaledDepthBias; + d3dRSDesc.DepthClipEnable = RasterizerDesc.DepthClipEnable ? TRUE : FALSE; + + //d3d12RSDesc.ScissorEnable = RSDesc.ScissorEnable ? TRUE : FALSE; + + d3dRSDesc.AntialiasedLineEnable = RasterizerDesc.AntialiasedLineEnable ? TRUE : FALSE; + d3dRSDesc.MultisampleEnable = d3dRSDesc.AntialiasedLineEnable; + } + + + + // ================= Blend state attributes conversion functions ================= + + template<typename D3D_BLEND> + D3D_BLEND BlendFactorToD3DBlend( BLEND_FACTOR bf ) + { + // D3D11_BLEND and D3D12_BLEND are identical + + // Note that this code is safe for multithreaded environments since + // bIsInit is set to true only AFTER the entire map is initialized. + static bool bIsInit = false; + static D3D_BLEND D3DBlend[BLEND_FACTOR_NUM_FACTORS] = {}; + if( !bIsInit ) + { + // In a multithreaded environment, several threads can potentially enter + // this block. This is not a problem since they will just initialize the + // memory with the same values more than once + D3DBlend[ BLEND_FACTOR_ZERO ] = D3D_BLEND_ZERO; + D3DBlend[ BLEND_FACTOR_ONE ] = D3D_BLEND_ONE; + D3DBlend[ BLEND_FACTOR_SRC_COLOR ] = D3D_BLEND_SRC_COLOR; + D3DBlend[ BLEND_FACTOR_INV_SRC_COLOR ] = D3D_BLEND_INV_SRC_COLOR; + D3DBlend[ BLEND_FACTOR_SRC_ALPHA ] = D3D_BLEND_SRC_ALPHA; + D3DBlend[ BLEND_FACTOR_INV_SRC_ALPHA ] = D3D_BLEND_INV_SRC_ALPHA; + D3DBlend[ BLEND_FACTOR_DEST_ALPHA ] = D3D_BLEND_DEST_ALPHA; + D3DBlend[ BLEND_FACTOR_INV_DEST_ALPHA ] = D3D_BLEND_INV_DEST_ALPHA; + D3DBlend[ BLEND_FACTOR_DEST_COLOR ] = D3D_BLEND_DEST_COLOR; + D3DBlend[ BLEND_FACTOR_INV_DEST_COLOR ] = D3D_BLEND_INV_DEST_COLOR; + D3DBlend[ BLEND_FACTOR_SRC_ALPHA_SAT ] = D3D_BLEND_SRC_ALPHA_SAT; + D3DBlend[ BLEND_FACTOR_BLEND_FACTOR ] = D3D_BLEND_BLEND_FACTOR; + D3DBlend[ BLEND_FACTOR_INV_BLEND_FACTOR ] = D3D_BLEND_INV_BLEND_FACTOR; + D3DBlend[ BLEND_FACTOR_SRC1_COLOR ] = D3D_BLEND_SRC1_COLOR; + D3DBlend[ BLEND_FACTOR_INV_SRC1_COLOR ] = D3D_BLEND_INV_SRC1_COLOR; + D3DBlend[ BLEND_FACTOR_SRC1_ALPHA ] = D3D_BLEND_SRC1_ALPHA; + D3DBlend[ BLEND_FACTOR_INV_SRC1_ALPHA ] = D3D_BLEND_INV_SRC1_ALPHA; + + bIsInit = true; + } + if( bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS ) + { + auto d3dbf = D3DBlend[bf]; + VERIFY( d3dbf != 0, "Incorrect blend factor" ); + return d3dbf; + } + else + { + UNEXPECTED("Incorrect blend factor (", bf, ")" ) + return static_cast<D3D_BLEND>( 0 ); + } + } + + template<typename D3D_BLEND_OP> + D3D_BLEND_OP BlendOperationToD3DBlendOp( BLEND_OPERATION BlendOp ) + { + // D3D12_BLEND_OP and D3D11_BLEND_OP are identical + + static bool bIsInit = false; + static D3D_BLEND_OP D3DBlendOp[BLEND_OPERATION_NUM_OPERATIONS] = {}; + if( !bIsInit ) + { + D3DBlendOp[ BLEND_OPERATION_ADD ] = D3D_BLEND_OP_ADD; + D3DBlendOp[ BLEND_OPERATION_SUBTRACT ] = D3D_BLEND_OP_SUBTRACT; + D3DBlendOp[ BLEND_OPERATION_REV_SUBTRACT ] = D3D_BLEND_OP_REV_SUBTRACT; + D3DBlendOp[ BLEND_OPERATION_MIN ] = D3D_BLEND_OP_MIN; + D3DBlendOp[ BLEND_OPERATION_MAX ] = D3D_BLEND_OP_MAX; + + bIsInit = true; + } + + if( BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS ) + { + auto d3dbop = D3DBlendOp[BlendOp]; + VERIFY( d3dbop != 0, "Incorrect blend operation" ); + return d3dbop; + } + else + { + UNEXPECTED( "Incorrect blend operation (", BlendOp, ")" ) + return static_cast<D3D_BLEND_OP>(0); + } + } + + template<typename D3D_BLEND_DESC, typename D3D_BLEND, typename D3D_BLEND_OP> + void BlendStateDescToD3DBlendDesc(const BlendStateDesc &BSDesc, D3D_BLEND_DESC &d3d12BlendDesc) + { + // D3D_BLEND_DESC and D3D11_BLEND_DESC structures are identical + d3d12BlendDesc.AlphaToCoverageEnable = BSDesc.AlphaToCoverageEnable ? TRUE : FALSE; + d3d12BlendDesc.IndependentBlendEnable = BSDesc.IndependentBlendEnable ? TRUE : FALSE; + VERIFY( BSDesc.MaxRenderTargets >= 8, "Number of render targets is expected to be at least 8" ); + for( int i = 0; i < 8; ++i ) + { + const auto& SrcRTDesc = BSDesc.RenderTargets[i]; + auto &DstRTDesc = d3d12BlendDesc.RenderTarget[i]; + DstRTDesc.BlendEnable = SrcRTDesc.BlendEnable ? TRUE : FALSE; + + DstRTDesc.SrcBlend = BlendFactorToD3DBlend<D3D_BLEND>(SrcRTDesc.SrcBlend); + DstRTDesc.DestBlend = BlendFactorToD3DBlend<D3D_BLEND>(SrcRTDesc.DestBlend); + DstRTDesc.BlendOp = BlendOperationToD3DBlendOp<D3D_BLEND_OP>(SrcRTDesc.BlendOp); + + DstRTDesc.SrcBlendAlpha = BlendFactorToD3DBlend<D3D_BLEND>(SrcRTDesc.SrcBlendAlpha); + DstRTDesc.DestBlendAlpha = BlendFactorToD3DBlend<D3D_BLEND>(SrcRTDesc.DestBlendAlpha); + DstRTDesc.BlendOpAlpha = BlendOperationToD3DBlendOp<D3D_BLEND_OP>(SrcRTDesc.BlendOpAlpha); + + DstRTDesc.RenderTargetWriteMask = + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_RED) ? D3D_COLOR_WRITE_ENABLE_RED : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_GREEN) ? D3D_COLOR_WRITE_ENABLE_GREEN : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_BLUE) ? D3D_COLOR_WRITE_ENABLE_BLUE : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_ALPHA) ? D3D_COLOR_WRITE_ENABLE_ALPHA : 0); + } + } + + + + // ====================== Depth-stencil state attributes conversion functions ====================== + + template<typename D3D_STENCIL_OP> + D3D_STENCIL_OP StencilOpToD3DStencilOp( STENCIL_OP StencilOp ) + { + static bool bIsInit = false; + static D3D_STENCIL_OP StOpToD3DStOpMap[STENCIL_OP_NUM_OPS] = {}; + if( !bIsInit ) + { + StOpToD3DStOpMap[ STENCIL_OP_KEEP ] = D3D_STENCIL_OP_KEEP; + StOpToD3DStOpMap[ STENCIL_OP_ZERO ] = D3D_STENCIL_OP_ZERO; + StOpToD3DStOpMap[ STENCIL_OP_REPLACE ] = D3D_STENCIL_OP_REPLACE; + StOpToD3DStOpMap[ STENCIL_OP_INCR_SAT ] = D3D_STENCIL_OP_INCR_SAT; + StOpToD3DStOpMap[ STENCIL_OP_DECR_SAT ] = D3D_STENCIL_OP_DECR_SAT; + StOpToD3DStOpMap[ STENCIL_OP_INVERT ] = D3D_STENCIL_OP_INVERT; + StOpToD3DStOpMap[ STENCIL_OP_INCR_WRAP] = D3D_STENCIL_OP_INCR; + StOpToD3DStOpMap[ STENCIL_OP_DECR_WRAP] = D3D_STENCIL_OP_DECR; + + bIsInit = true; + } + + if( StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS ) + { + auto d3dStencilOp = StOpToD3DStOpMap[StencilOp]; + VERIFY( d3dStencilOp != 0, "Unexpected stencil op" ); + return d3dStencilOp; + } + else + { + UNEXPECTED( "Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS - 1, "]" ) + return static_cast<D3D_STENCIL_OP>(0); + } + } + + template<typename D3D_DEPTH_STENCILOP_DESC, typename D3D_STENCIL_OP, typename D3D_COMPARISON_FUNC> + D3D_DEPTH_STENCILOP_DESC StencilOpDescToD3DStencilOpDesc(const StencilOpDesc &StOpDesc) + { + // D3D12_DEPTH_STENCILOP_DESC is identical to D3D11_DEPTH_STENCILOP_DESC + D3D_DEPTH_STENCILOP_DESC D3DStOpDesc; + D3DStOpDesc.StencilFailOp = StencilOpToD3DStencilOp<D3D_STENCIL_OP>( StOpDesc.StencilFailOp ); + D3DStOpDesc.StencilDepthFailOp = StencilOpToD3DStencilOp<D3D_STENCIL_OP>( StOpDesc.StencilDepthFailOp ); + D3DStOpDesc.StencilPassOp = StencilOpToD3DStencilOp<D3D_STENCIL_OP>( StOpDesc.StencilPassOp ); + D3DStOpDesc.StencilFunc = ComparisonFuncToD3DComparisonFunc<D3D_COMPARISON_FUNC>( StOpDesc.StencilFunc ); + return D3DStOpDesc; + } + + template<typename D3D_DEPTH_STENCIL_DESC, typename D3D_DEPTH_STENCILOP_DESC, typename D3D_STENCIL_OP, typename D3D_COMPARISON_FUNC> + void DepthStencilStateDesc_To_D3D_DEPTH_STENCIL_DESC(const DepthStencilStateDesc &DepthStencilDesc, D3D_DEPTH_STENCIL_DESC &d3dDSSDesc) + { + // D3D_DEPTH_STENCIL_DESC is identical to D3D11_DEPTH_STENCIL_DESC + d3dDSSDesc.DepthEnable = DepthStencilDesc.DepthEnable ? TRUE : FALSE; + d3dDSSDesc.DepthWriteMask = DepthStencilDesc.DepthWriteEnable ? D3D_DEPTH_WRITE_MASK_ALL : D3D_DEPTH_WRITE_MASK_ZERO; + d3dDSSDesc.DepthFunc = ComparisonFuncToD3DComparisonFunc<D3D_COMPARISON_FUNC>( DepthStencilDesc.DepthFunc ); + d3dDSSDesc.StencilEnable = DepthStencilDesc.StencilEnable ? TRUE : FALSE; + d3dDSSDesc.StencilReadMask = DepthStencilDesc.StencilReadMask; + d3dDSSDesc.StencilWriteMask = DepthStencilDesc.StencilWriteMask; + d3dDSSDesc.FrontFace = StencilOpDescToD3DStencilOpDesc<D3D_DEPTH_STENCILOP_DESC, D3D_STENCIL_OP, D3D_COMPARISON_FUNC>( DepthStencilDesc.FrontFace ); + d3dDSSDesc.BackFace = StencilOpDescToD3DStencilOpDesc<D3D_DEPTH_STENCILOP_DESC, D3D_STENCIL_OP, D3D_COMPARISON_FUNC>( DepthStencilDesc.BackFace ); + } + + + + template<typename D3D_INPUT_ELEMENT_DESC> + void LayoutElements_To_D3D_INPUT_ELEMENT_DESCs(const std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement> > &LayoutElements, std::vector<D3D_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D_INPUT_ELEMENT_DESC>> &D3DInputElements) + { + // D3D12_INPUT_ELEMENT_DESC and D3D11_INPUT_ELEMENT_DESC are identical + auto NumElements = LayoutElements.size(); + D3DInputElements.resize(NumElements); + for(Uint32 iElem=0; iElem < NumElements; ++iElem) + { + const auto &CurrElem = LayoutElements[iElem]; + auto &D3DElem = D3DInputElements[iElem]; + D3DElem.SemanticName = "ATTRIB"; + D3DElem.SemanticIndex = CurrElem.InputIndex; + D3DElem.AlignedByteOffset = CurrElem.RelativeOffset; + D3DElem.InputSlot = CurrElem.BufferSlot; + D3DElem.Format = TypeToDXGI_Format(CurrElem.ValueType, CurrElem.NumComponents, CurrElem.IsNormalized); + D3DElem.InputSlotClass = (CurrElem.Frequency == LayoutElement::FREQUENCY_PER_VERTEX) ? D3D_INPUT_CLASSIFICATION_PER_VERTEX_DATA : D3D_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; + D3DElem.InstanceDataStepRate = (CurrElem.Frequency == LayoutElement::FREQUENCY_PER_VERTEX) ? 0 : CurrElem.InstanceDataStepRate; + } + } + + + template<typename D3D_FILTER> + D3D_FILTER FilterTypeToD3DFilter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter) + { + switch( MinFilter ) + { + // Regular filters + case FILTER_TYPE_POINT: + if( MagFilter == FILTER_TYPE_POINT ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D_FILTER_MIN_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D_FILTER_MIN_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_LINEAR ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D_FILTER_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_LINEAR: + if( MagFilter == FILTER_TYPE_POINT ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D_FILTER_MIN_LINEAR_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_LINEAR ) + { + if( MipFilter == FILTER_TYPE_POINT ) + return D3D_FILTER_MIN_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_LINEAR ) + return D3D_FILTER_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_ANISOTROPIC: + VERIFY( MagFilter == FILTER_TYPE_ANISOTROPIC && MipFilter == FILTER_TYPE_ANISOTROPIC, + "For anistropic filtering, all filters must be anisotropic" ); + return D3D_FILTER_ANISOTROPIC; + break; + + + + // Comparison filters + case FILTER_TYPE_COMPARISON_POINT: + if( MagFilter == FILTER_TYPE_COMPARISON_POINT ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D_FILTER_COMPARISON_MIN_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_COMPARISON_LINEAR ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_COMPARISON_LINEAR: + if( MagFilter == FILTER_TYPE_COMPARISON_POINT ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_COMPARISON_LINEAR ) + { + if( MipFilter == FILTER_TYPE_COMPARISON_POINT ) + return D3D_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_COMPARISON_LINEAR ) + return D3D_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_COMPARISON_ANISOTROPIC: + VERIFY( MagFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC && MipFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC, + "For comparison anistropic filtering, all filters must be anisotropic" ); + return D3D_FILTER_COMPARISON_ANISOTROPIC; + break; + + + + // Minimum filters + case FILTER_TYPE_MINIMUM_POINT: + if( MagFilter == FILTER_TYPE_MINIMUM_POINT ) + { + if( MipFilter == FILTER_TYPE_MINIMUM_POINT ) + return D3D_FILTER_MINIMUM_MIN_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MINIMUM_LINEAR ) + return D3D_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_MINIMUM_LINEAR ) + { + if( MipFilter == FILTER_TYPE_MINIMUM_POINT ) + return D3D_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MINIMUM_LINEAR ) + return D3D_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MINIMUM_LINEAR: + if( MagFilter == FILTER_TYPE_MINIMUM_POINT ) + { + if( MipFilter == FILTER_TYPE_MINIMUM_POINT ) + return D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MINIMUM_LINEAR ) + return D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_MINIMUM_LINEAR ) + { + if( MipFilter == FILTER_TYPE_MINIMUM_POINT ) + return D3D_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MINIMUM_LINEAR ) + return D3D_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MINIMUM_ANISOTROPIC: + VERIFY( MagFilter == FILTER_TYPE_MINIMUM_ANISOTROPIC && MipFilter == FILTER_TYPE_MINIMUM_ANISOTROPIC, + "For minimum anistropic filtering, all filters must be anisotropic" ); + return D3D_FILTER_MINIMUM_ANISOTROPIC; + break; + + + + // Maximum filters + case FILTER_TYPE_MAXIMUM_POINT: + if( MagFilter == FILTER_TYPE_MAXIMUM_POINT ) + { + if( MipFilter == FILTER_TYPE_MAXIMUM_POINT ) + return D3D_FILTER_MAXIMUM_MIN_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MAXIMUM_LINEAR ) + return D3D_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_MAXIMUM_LINEAR ) + { + if( MipFilter == FILTER_TYPE_MAXIMUM_POINT ) + return D3D_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MAXIMUM_LINEAR ) + return D3D_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MAXIMUM_LINEAR: + if( MagFilter == FILTER_TYPE_MAXIMUM_POINT ) + { + if( MipFilter == FILTER_TYPE_MAXIMUM_POINT ) + return D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MAXIMUM_LINEAR ) + return D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if( MagFilter == FILTER_TYPE_MAXIMUM_LINEAR ) + { + if( MipFilter == FILTER_TYPE_MAXIMUM_POINT ) + return D3D_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT; + else if( MipFilter == FILTER_TYPE_MAXIMUM_LINEAR ) + return D3D_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MAXIMUM_ANISOTROPIC: + VERIFY( MagFilter == FILTER_TYPE_MAXIMUM_ANISOTROPIC && MipFilter == FILTER_TYPE_MAXIMUM_ANISOTROPIC, + "For maximum anistropic filtering, all filters must be anisotropic" ); + return D3D_FILTER_MAXIMUM_ANISOTROPIC; + break; + } + + UNEXPECTED( "Unsupported filter combination" ); + return D3D_FILTER_MIN_MAG_MIP_POINT; + } +} diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.h b/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.h new file mode 100644 index 00000000..baa0a3ab --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.h @@ -0,0 +1,319 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of D3D type conversions + +/// This file must be included after D3D11TypeDefinitions.h or D3D12TypeDefinitions.h + +#include "DXGITypeConversions.h" + +namespace Diligent +{ + template<typename D3D_SHADER_RESOURCE_VIEW_DESC> + void TextureViewDesc_to_D3D_SRV_DESC(const TextureViewDesc& SRVDesc, D3D_SHADER_RESOURCE_VIEW_DESC &d3dSRVDesc, Uint32 SampleCount) + { + memset(&d3dSRVDesc, 0, sizeof(d3dSRVDesc)); + d3dSRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); + + switch (SRVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D; + d3dSRVDesc.Texture1D.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture1D.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1DARRAY; + d3dSRVDesc.Texture1DArray.ArraySize = SRVDesc.NumArraySlices; + d3dSRVDesc.Texture1DArray.FirstArraySlice = SRVDesc.FirstArraySlice; + d3dSRVDesc.Texture1DArray.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture1DArray.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_2D: + if( SampleCount > 1 ) + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DMS; + d3dSRVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; + d3dSRVDesc.Texture2D.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture2D.MostDetailedMip = SRVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if( SampleCount > 1 ) + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY; + d3dSRVDesc.Texture2DMSArray.ArraySize = SRVDesc.NumArraySlices; + d3dSRVDesc.Texture2DMSArray.FirstArraySlice = SRVDesc.FirstArraySlice; + } + else + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY; + d3dSRVDesc.Texture2DArray.ArraySize = SRVDesc.NumArraySlices; + d3dSRVDesc.Texture2DArray.FirstArraySlice = SRVDesc.FirstArraySlice; + d3dSRVDesc.Texture2DArray.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture2DArray.MostDetailedMip = SRVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_3D: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE3D; + d3dSRVDesc.Texture3D.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture3D.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_CUBE: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBE; + d3dSRVDesc.TextureCube.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.TextureCube.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_CUBE_ARRAY: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBEARRAY; + d3dSRVDesc.TextureCubeArray.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.TextureCubeArray.MostDetailedMip = SRVDesc.MostDetailedMip; + d3dSRVDesc.TextureCubeArray.First2DArrayFace = SRVDesc.FirstArraySlice; + d3dSRVDesc.TextureCubeArray.NumCubes = SRVDesc.NumArraySlices / 6; + break; + + default: + UNEXPECTED( "Unexpected view type" ); + } + } + + template<typename D3D_RENDER_TARGET_VIEW_DESC> + void TextureViewDesc_to_D3D_RTV_DESC(const TextureViewDesc& RTVDesc, D3D_RENDER_TARGET_VIEW_DESC &d3dRTVDesc, Uint32 SampleCount) + { + memset(&d3dRTVDesc, 0, sizeof(d3dRTVDesc)); + d3dRTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); + + switch(RTVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE1D; + d3dRTVDesc.Texture1D.MipSlice = RTVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE1DARRAY; + d3dRTVDesc.Texture1DArray.ArraySize = RTVDesc.NumArraySlices; + d3dRTVDesc.Texture1DArray.FirstArraySlice = RTVDesc.FirstArraySlice; + d3dRTVDesc.Texture1DArray.MipSlice = RTVDesc.MostDetailedMip; + break; + + + case RESOURCE_DIM_TEX_2D: + if( SampleCount > 1 ) + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMS; + d3dRTVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2D; + d3dRTVDesc.Texture2D.MipSlice = RTVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if( SampleCount > 1 ) + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMSARRAY; + d3dRTVDesc.Texture2DMSArray.ArraySize = RTVDesc.NumArraySlices; + d3dRTVDesc.Texture2DMSArray.FirstArraySlice = RTVDesc.FirstArraySlice; + } + else + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DARRAY; + d3dRTVDesc.Texture2DArray.ArraySize = RTVDesc.NumArraySlices; + d3dRTVDesc.Texture2DArray.FirstArraySlice = RTVDesc.FirstArraySlice; + d3dRTVDesc.Texture2DArray.MipSlice = RTVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_3D: + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE3D; + d3dRTVDesc.Texture3D.FirstWSlice = RTVDesc.FirstDepthSlice; + d3dRTVDesc.Texture3D.WSize = RTVDesc.NumDepthSlices; + d3dRTVDesc.Texture3D.MipSlice = RTVDesc.MostDetailedMip; + break; + + default: + UNEXPECTED( "Unexpected view type" ); + } + } + + template<typename D3D_DEPTH_STENCIL_VIEW_DESC> + void TextureViewDesc_to_D3D_DSV_DESC(const TextureViewDesc& DSVDesc, D3D_DEPTH_STENCIL_VIEW_DESC &d3dDSVDesc, Uint32 SampleCount) + { + memset(&d3dDSVDesc, 0, sizeof(d3dDSVDesc)); + d3dDSVDesc.Format = TexFormatToDXGI_Format(DSVDesc.Format, BIND_DEPTH_STENCIL); + + switch(DSVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE1D; + d3dDSVDesc.Texture1D.MipSlice = DSVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE1DARRAY; + d3dDSVDesc.Texture1DArray.ArraySize = DSVDesc.NumArraySlices; + d3dDSVDesc.Texture1DArray.FirstArraySlice = DSVDesc.FirstArraySlice; + d3dDSVDesc.Texture1DArray.MipSlice = DSVDesc.MostDetailedMip; + break; + + + case RESOURCE_DIM_TEX_2D: + if( SampleCount > 1 ) + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMS; + d3dDSVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2D; + d3dDSVDesc.Texture2D.MipSlice = DSVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if( SampleCount > 1 ) + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMSARRAY; + d3dDSVDesc.Texture2DMSArray.ArraySize = DSVDesc.NumArraySlices; + d3dDSVDesc.Texture2DMSArray.FirstArraySlice = DSVDesc.FirstArraySlice; + } + else + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DARRAY; + d3dDSVDesc.Texture2DArray.ArraySize = DSVDesc.NumArraySlices; + d3dDSVDesc.Texture2DArray.FirstArraySlice = DSVDesc.FirstArraySlice; + d3dDSVDesc.Texture2DArray.MipSlice = DSVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_3D: + LOG_ERROR_AND_THROW("Depth stencil views are not supported for 3D textures"); + break; + + default: + UNEXPECTED( "Unexpected view type" ); + } + } + + template<typename D3D_UNORDERED_ACCESS_VIEW_DESC> + void TextureViewDesc_to_D3D_UAV_DESC(const TextureViewDesc& UAVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC &d3dUAVDesc) + { + memset(&d3dUAVDesc, 0, sizeof(d3dUAVDesc)); + d3dUAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); + + switch(UAVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE1D; + d3dUAVDesc.Texture1D.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE1DARRAY; + d3dUAVDesc.Texture1DArray.ArraySize = UAVDesc.NumArraySlices; + d3dUAVDesc.Texture1DArray.FirstArraySlice = UAVDesc.FirstArraySlice; + d3dUAVDesc.Texture1DArray.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_2D: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE2D; + d3dUAVDesc.Texture2D.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE2DARRAY; + d3dUAVDesc.Texture2DArray.ArraySize = UAVDesc.NumArraySlices; + d3dUAVDesc.Texture2DArray.FirstArraySlice = UAVDesc.FirstArraySlice; + d3dUAVDesc.Texture2DArray.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_3D: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE3D; + d3dUAVDesc.Texture3D.FirstWSlice = UAVDesc.FirstDepthSlice; + d3dUAVDesc.Texture3D.WSize = UAVDesc.NumDepthSlices; + d3dUAVDesc.Texture3D.MipSlice = UAVDesc.MostDetailedMip; + break; + + default: + UNEXPECTED( "Unexpected view type" ); + } + } + + template<typename D3D_UNORDERED_ACCESS_VIEW_DESC> + void BufferViewDesc_to_D3D_SRV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& SRVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC &d3dSRVDesc) + { + if( SRVDesc.ByteOffset != 0 ) + { + VERIFY( BuffDesc.Mode == BUFFER_MODE_STRUCTURED, "Non-zero byte offset is only supported for structured buffers" ); + } + + memset( &d3dSRVDesc, 0, sizeof( d3dSRVDesc ) ); + const auto &BuffFmt = BuffDesc.Format; + if( BuffDesc.Mode == BUFFER_MODE_FORMATED ) + d3dSRVDesc.Format = TypeToDXGI_Format( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); + + VERIFY( SRVDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected" ); + VERIFY( (SRVDesc.ByteOffset % BuffDesc.ElementByteStride) == 0, "Byte offest is not multiple of element byte stride" ); + VERIFY( (SRVDesc.ByteWidth % BuffDesc.ElementByteStride) == 0, "Byte width is not multiple of element byte stride" ); + d3dSRVDesc.Buffer.FirstElement = SRVDesc.ByteOffset / BuffDesc.ElementByteStride; + d3dSRVDesc.Buffer.NumElements = SRVDesc.ByteWidth / BuffDesc.ElementByteStride; + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_BUFFER; + } + + template<typename D3D_UNORDERED_ACCESS_VIEW_DESC> + void BufferViewDesc_to_D3D_UAV_DESC(const BufferDesc &BuffDesc, const BufferViewDesc& UAVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC &d3dUAVDesc) + { + if( UAVDesc.ByteOffset != 0 ) + { + VERIFY( BuffDesc.Mode == BUFFER_MODE_STRUCTURED, "Non-zero byte offset is only supported for structured buffers" ); + } + + memset( &d3dUAVDesc, 0, sizeof(d3dUAVDesc) ); + const auto &BuffFmt = BuffDesc.Format; + if( BuffDesc.Mode == BUFFER_MODE_FORMATED ) + d3dUAVDesc.Format = TypeToDXGI_Format( BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized ); + + VERIFY( UAVDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected" ); + VERIFY( (UAVDesc.ByteOffset % BuffDesc.ElementByteStride) == 0, "Byte offest is not multiple of element byte stride" ); + VERIFY( (UAVDesc.ByteWidth % BuffDesc.ElementByteStride) == 0, "Byte width is not multiple of element byte stride" ); + d3dUAVDesc.Buffer.FirstElement = UAVDesc.ByteOffset / BuffDesc.ElementByteStride; + d3dUAVDesc.Buffer.NumElements = UAVDesc.ByteWidth / BuffDesc.ElementByteStride; + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_BUFFER; + } +} diff --git a/Graphics/GraphicsEngineOpenGL/src/DSStateGLImpl.cpp b/Graphics/GraphicsEngineD3DBase/include/DXGITypeConversions.h index 1b9929b6..1f0889d8 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DSStateGLImpl.cpp +++ b/Graphics/GraphicsEngineD3DBase/include/DXGITypeConversions.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,23 +21,17 @@ * of the possibility of such damages. */ -#include "pch.h" -#include "DSStateGLImpl.h" -#include "RenderDeviceGLImpl.h" +#pragma once -namespace Diligent -{ +/// \file +/// Common D3D type conversion utilities -DSStateGLImpl::DSStateGLImpl(class IRenderDevice *pDeviceGL, const DepthStencilStateDesc& DepthStencilStateDesc, bool bIsDeviceInternal) : - TDSStateBase(pDeviceGL, DepthStencilStateDesc, bIsDeviceInternal) -{ -} +#include <dxgi.h> +#include "GraphicsTypes.h" -DSStateGLImpl::~DSStateGLImpl() +namespace Diligent { - + DXGI_FORMAT TexFormatToDXGI_Format(TEXTURE_FORMAT TexFormat, Uint32 BindFlags = 0); + DXGI_FORMAT TypeToDXGI_Format(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized); } -IMPLEMENT_QUERY_INTERFACE( DSStateGLImpl, IID_DepthStencilStateGL, TDSStateBase ) - -} diff --git a/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions.fxh b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh index fd19be08..fd19be08 100644 --- a/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions.fxh +++ b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions.fxh diff --git a/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions_inc.fxh b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh index 84012ff1..84012ff1 100644 --- a/Graphics/GraphicsEngineD3D11/include/HLSLDefinitions_inc.fxh +++ b/Graphics/GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh diff --git a/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.h new file mode 100644 index 00000000..be7e940d --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.h @@ -0,0 +1,159 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::RenderDeviceBase template class and related structures + +#include "RenderDeviceBase.h" + +namespace Diligent +{ + +/// Base implementation of a D3D render device + +template<typename BaseInterface> +class RenderDeviceD3DBase : public RenderDeviceBase<BaseInterface> +{ +public: + RenderDeviceD3DBase(IMemoryAllocator &RawMemAllocator, + Uint32 NumDeferredContexts, + size_t TextureObjSize, + size_t TexViewObjSize, + size_t BufferObjSize, + size_t BuffViewObjSize, + size_t ShaderObjSize, + size_t SamplerObjSize, + size_t PSOSize, + size_t SRBSize) : + RenderDeviceBase<BaseInterface>(RawMemAllocator, NumDeferredContexts, TextureObjSize, TexViewObjSize, BufferObjSize, BuffViewObjSize, ShaderObjSize, SamplerObjSize, PSOSize, SRBSize) + { + // Flag texture formats always supported in D3D11 and D3D12 + +#define FLAG_FORMAT(Fmt, IsSupported) m_TextureFormatsInfo[Fmt].Supported=IsSupported + + FLAG_FORMAT(TEX_FORMAT_RGBA32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R32G8X24_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT_S8X24_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_X32_TYPELESS_G8X24_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R11G11B10_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_R32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R24G8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D24_UNORM_S8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R24_UNORM_X8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_X24_TYPELESS_G8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_R16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_D16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_R8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_R8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_A8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGB9E5_SHAREDEXP, true); + FLAG_FORMAT(TEX_FORMAT_RG8_B8G8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_G8R8_G8B8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC1_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC2_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC3_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC4_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC4_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC4_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC5_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC5_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC5_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_B5G6R5_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_B5G5R5A1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_UF16, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_SF16, true); + FLAG_FORMAT(TEX_FORMAT_BC7_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM_SRGB, true); +#undef FLAG_FORMAT + } +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/interface/BlendStateGL.h b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h index 8923adf5..0fd007fa 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BlendStateGL.h +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,23 +23,23 @@ #pragma once -/// \file -/// Definition of the Diligent::IBlendStateGL interface - -#include "BlendState.h" +#include <d3dcommon.h> -namespace Diligent -{ +#include "Shader.h" -// {B543F4DC-000F-4EE6-AC06-E6642BBC3560} -static const Diligent::INTERFACE_ID IID_BlendStateGL = -{ 0xb543f4dc, 0xf, 0x4ee6, { 0xac, 0x6, 0xe6, 0x64, 0x2b, 0xbc, 0x35, 0x60 } }; +/// \file +/// Base implementation of a D3D shader -/// Interface to the blend state object implemented in OpenGL -class IBlendStateGL : public Diligent::IBlendState +namespace Diligent { -public: + /// Base implementation of a D3D shader + class ShaderD3DBase + { + public: + ShaderD3DBase(const ShaderCreationAttribs &CreationAttribs); -}; + protected: + CComPtr<ID3DBlob> m_pShaderByteCode; + }; } diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h new file mode 100644 index 00000000..ad63d64b --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h @@ -0,0 +1,396 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResources class + +// ShaderResources class uses continuous chunk of memory to store all resources, as follows: +// +// +// m_MemoryBuffer m_TexSRVOffset m_TexUAVOffset m_BufSRVOffset m_BufUAVOffset m_SamplersOffset m_MemorySize +// | | | | | | | +// | CB[0] ... CB[Ncb-1] | TexSRV[0] ... TexSRV[Ntsrv-1] | TexUAV[0] ... TexUAV[Ntuav-1] | BufSRV[0] ... BufSRV[Nbsrv-1] | BufUAV[0] ... BufUAV[Nbuav-1] | Sam[0] ... Sam[Nsam-1] | +// +// Ncb - number of constant buffers +// Ntsrv - number of texture SRVs +// Ntuav - number of texture UAVs +// Nbsrv - number of buffer SRVs +// Nbuav - number of buffer UAVs +// Nsam - number of samplers +// +// +// If texture SRV is assigned a sampler, it is referenced through SamplerId: +// +// _________________________SamplerId_______________________ +// | | +// | V +// | CBs | ... TexSRV[n] ... | TexUAVs | BufSRVs | BufUAVs | Sam[0] ... Sam[SamplerId] ... | +// +// + +#define NOMINMAX +#include <d3dcommon.h> + +namespace Diligent +{ + +static const Char* D3DSamplerSuffix = "_sampler"; + +inline bool IsAllowedType(SHADER_VARIABLE_TYPE VarType, Uint32 AllowedTypeBits)noexcept +{ + return ((1 << VarType) & AllowedTypeBits) != 0; +} + +inline Uint32 GetAllowedTypeBits(const SHADER_VARIABLE_TYPE *AllowedVarTypes, Uint32 NumAllowedTypes)noexcept +{ + if(AllowedVarTypes == nullptr) + return 0xFFFFFFFF; + + Uint32 AllowedTypeBits = 0; + for(Uint32 i=0; i < NumAllowedTypes; ++i) + AllowedTypeBits |= 1 << AllowedVarTypes[i]; + return AllowedTypeBits; +} + + +struct D3DShaderResourceAttribs +{ + D3DShaderResourceAttribs(String &&_Name, + UINT _BindPoint, + UINT _BindCount, + D3D_SHADER_INPUT_TYPE _InputType, + SHADER_VARIABLE_TYPE _VariableType, + D3D_SRV_DIMENSION SRVDimension, + Uint32 SamplerId, + bool _IsStaticSampler) : + Name(std::move(_Name)), + BindPoint(static_cast<Uint16>(_BindPoint)), + BindCount(static_cast<Uint16>(_BindCount)), + PackedAttribs( PackAttribs(_InputType, _VariableType, SRVDimension, SamplerId, _IsStaticSampler) ) + { + VERIFY( static_cast<Uint32>(_InputType) <= ShaderInputTypeMask, "Shader input type is out of expected range"); + VERIFY( static_cast<Uint32>(_VariableType) <= VariableTypeMask, "Variable type is out of expected range"); + VERIFY( static_cast<Uint32>(SRVDimension) <= SRVDimMask, "SRV dimensions is out of expected range"); + VERIFY(SamplerId <= SamplerIdMask, "Sampler Id is out of allowed range" ); + VERIFY_EXPR(GetInputType() == _InputType); + VERIFY_EXPR(GetVariableType() == _VariableType); + VERIFY(_BindPoint <= MaxBindPoint || _BindPoint == InvalidBindPoint, "Bind Point is out of allowed range" ); + VERIFY(_BindCount <= MaxBindCount, "Bind Count is out of allowed range" ); +#ifdef _DEBUG + if(_InputType==D3D_SIT_SAMPLER) + { + VERIFY_EXPR(IsStaticSampler() == _IsStaticSampler); + } + else + { + VERIFY(!_IsStaticSampler, "Only samplers can be marked as static"); + } + + if (_InputType == D3D_SIT_TEXTURE) + { + VERIFY_EXPR(GetSamplerId() == SamplerId); + } + else + { + VERIFY(SamplerId == InvalidSamplerId, "Only textures can be assigned valid texture sampler") + } + + if(_IsStaticSampler) + { + VERIFY( _InputType == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected" ); + } +#endif + } + + D3DShaderResourceAttribs(const D3DShaderResourceAttribs& rhs) = default; + + D3DShaderResourceAttribs(const D3DShaderResourceAttribs& rhs, Uint32 SamplerId)noexcept : + Name(rhs.Name), + BindPoint(rhs.BindPoint), + BindCount(rhs.BindCount), + PackedAttribs( PackAttribs(rhs.GetInputType(), rhs.GetVariableType(), rhs.GetSRVDimension(), SamplerId, false) ) + { + VERIFY(GetInputType() == D3D_SIT_TEXTURE, "Only textures can be assigned a texture sampler"); + + VERIFY_EXPR(GetInputType() == rhs.GetInputType()); + VERIFY_EXPR(GetVariableType() == rhs.GetVariableType()); + VERIFY_EXPR(GetSamplerId() == SamplerId); + } + + D3DShaderResourceAttribs(D3DShaderResourceAttribs&& rhs, Uint32 SamplerId)noexcept : + Name(std::move(rhs.Name)), + BindPoint(rhs.BindPoint), + BindCount(rhs.BindCount), + PackedAttribs( PackAttribs(rhs.GetInputType(), rhs.GetVariableType(), rhs.GetSRVDimension(), SamplerId, false) ) + { + VERIFY(GetInputType() == D3D_SIT_TEXTURE, "Only textures can be assigned a texture sampler"); + + VERIFY_EXPR(GetInputType() == rhs.GetInputType()); + VERIFY_EXPR(GetVariableType() == rhs.GetVariableType()); + VERIFY_EXPR(GetSamplerId() == SamplerId); + } + + D3DShaderResourceAttribs(D3DShaderResourceAttribs&& rhs)noexcept : + Name(std::move(rhs.Name)), + BindPoint(rhs.BindPoint), + BindCount(rhs.BindCount), + PackedAttribs( rhs.PackedAttribs ) + { + } + + D3D_SHADER_INPUT_TYPE GetInputType()const + { + return static_cast<D3D_SHADER_INPUT_TYPE>( (PackedAttribs >> ShaderInputTypeBitOffset) & ShaderInputTypeMask ); + } + + SHADER_VARIABLE_TYPE GetVariableType()const + { + return static_cast<SHADER_VARIABLE_TYPE>( (PackedAttribs >> VariableTypeBitOffset) & VariableTypeMask ); + } + + D3D_SRV_DIMENSION GetSRVDimension()const + { + return static_cast<D3D_SRV_DIMENSION>( (PackedAttribs >> SRVDimBitOffset) & SRVDimMask ); + } + + Uint32 GetSamplerId()const + { + VERIFY( GetInputType() == D3D_SIT_TEXTURE, "Invalid input type: D3D_SIT_TEXTURE is expected" ); + return (PackedAttribs >> SamplerIdBitOffset) & SamplerIdMask; + } + + bool IsStaticSampler()const + { + VERIFY( GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected" ); + return (PackedAttribs & (1 << IsStaticSamplerFlagBitOffset)) != 0; + } + + bool IsValidSampler()const + { + VERIFY( GetInputType() == D3D_SIT_TEXTURE, "Invalid input type: D3D_SIT_TEXTURE is expected" ); + return GetSamplerId() != InvalidSamplerId; + } + + bool IsValidBindPoint()const + { + return BindPoint != InvalidBindPoint; + } + + static const Uint16 InvalidBindPoint = std::numeric_limits<Uint16>::max(); + + String Name; // Move ctor will not work if it is const + const Uint16 BindPoint; + const Uint16 BindCount; + + String GetPrintName(Uint32 ArrayInd)const + { + VERIFY_EXPR(ArrayInd < BindCount); + if(BindCount > 1) + return String(Name) + '[' + std::to_string(ArrayInd) + ']'; + else + return Name; + } +private: + static const Uint16 MaxBindPoint = InvalidBindPoint-1; + static const Uint16 MaxBindCount = std::numeric_limits<Uint16>::max(); + + static const Uint32 ShaderInputTypeBits = 4; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER==11 + static const Uint32 ShaderInputTypeMask = (1 << ShaderInputTypeBits)-1; + static const Uint32 ShaderInputTypeBitOffset = 0; + static_assert( D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER <= ShaderInputTypeMask, "Not enough bits to represent D3D_SHADER_INPUT_TYPE" ); + + static const Uint32 VariableTypeBits = 3; // Max value: SHADER_VARIABLE_TYPE_DYNAMIC == 2 + static const Uint32 VariableTypeMask = (1<<VariableTypeBits)-1; + static const Uint32 VariableTypeBitOffset = ShaderInputTypeBitOffset + ShaderInputTypeBits; + static_assert( SHADER_VARIABLE_TYPE_NUM_TYPES-1 <= VariableTypeMask, "Not enough bits to represent SHADER_VARIABLE_TYPE" ); + + static const Uint32 SRVDimBits = 4; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11 + static const Uint32 SRVDimMask = (1<<SRVDimBits)-1; + static const Uint32 SRVDimBitOffset = VariableTypeBitOffset + VariableTypeBits; + static_assert( D3D_SRV_DIMENSION_BUFFEREX <= SRVDimMask, "Not enough bits to represent D3D_SRV_DIMENSION" ); + + static const Uint32 SamplerIdBits = 32 - 1 - ShaderInputTypeBits - VariableTypeBits - SRVDimBits; + static const Uint32 SamplerIdMask = (1 << SamplerIdBits) - 1; + static const Uint32 SamplerIdBitOffset = SRVDimBitOffset + SRVDimBits; +public: + static const Uint32 InvalidSamplerId = SamplerIdMask; +private: + + static const Uint32 IsStaticSamplerFlagBits = 1; + static const Uint32 IsStaticSamplerFlagMask = (1 << IsStaticSamplerFlagBits) - 1; + static const Uint32 IsStaticSamplerFlagBitOffset = SamplerIdBitOffset + SamplerIdBits; + static_assert(IsStaticSamplerFlagBitOffset == 31, "Unexpected static sampler flag offset"); + + static Uint32 PackAttribs(D3D_SHADER_INPUT_TYPE _InputType, SHADER_VARIABLE_TYPE _VariableType, D3D_SRV_DIMENSION SRVDimension, Uint32 SamplerId, bool _IsStaticSampler) + { + return ((static_cast<Uint32>(_InputType) & ShaderInputTypeMask) << ShaderInputTypeBitOffset) | + ((static_cast<Uint32>(_VariableType) & VariableTypeMask) << VariableTypeBitOffset ) | + ((static_cast<Uint32>(SRVDimension) & SRVDimMask) << SRVDimBitOffset) | + ((SamplerId & SamplerIdMask) << SamplerIdBitOffset) | + ((_IsStaticSampler ? 1 : 0) << IsStaticSamplerFlagBitOffset); + } + + // 4 3 4 20 1 + // bit | 0 1 2 3 | 4 5 6 | 7 8 9 10 | 11 12 ... 30 | 31 | + // | | | | | | + // | InputType | VariableType | SRV Dim | SamplerId | StaticSamplerFlag | + const Uint32 PackedAttribs; +}; + +/// Diligent::ShaderResources class +class ShaderResources +{ +public: + ShaderResources(IMemoryAllocator &Allocator, SHADER_TYPE ShaderType); + + // Copies specified types of resources from another ShaderResources objects + ShaderResources(IMemoryAllocator &Allocator, + const ShaderResources& SrcResources, + const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes); + + ShaderResources (const ShaderResources&) = delete; + ShaderResources (ShaderResources&&) = delete; + ShaderResources& operator = (const ShaderResources&) = delete; + ShaderResources& operator = (ShaderResources&&) = delete; + + ~ShaderResources(); + + Uint32 GetNumCBs() const noexcept{ return (m_TexSRVOffset - 0); } + Uint32 GetNumTexSRV() const noexcept{ return (m_TexUAVOffset - m_TexSRVOffset); } + Uint32 GetNumTexUAV() const noexcept{ return (m_BufSRVOffset - m_TexUAVOffset); } + Uint32 GetNumBufSRV() const noexcept{ return (m_BufUAVOffset - m_BufSRVOffset); } + Uint32 GetNumBufUAV() const noexcept{ return (m_SamplersOffset - m_BufUAVOffset); } + Uint32 GetNumSamplers()const noexcept{ return (m_BufferEndOffset- m_SamplersOffset); } + + const D3DShaderResourceAttribs& GetCB (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumCBs(), 0); } + const D3DShaderResourceAttribs& GetTexSRV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } + const D3DShaderResourceAttribs& GetTexUAV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } + const D3DShaderResourceAttribs& GetBufSRV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } + const D3DShaderResourceAttribs& GetBufUAV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } + const D3DShaderResourceAttribs& GetSampler(Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } + + + void CountResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes, Uint32 NumAllowedTypes, + Uint32& NumCBs, Uint32& NumTexSRVs, Uint32& NumTexUAVs, + Uint32& NumBufSRVs, Uint32& NumBufUAVs, Uint32& NumSamplers)const noexcept; + + SHADER_TYPE GetShaderType()const noexcept{return m_ShaderType;} + + template<typename THandleCB, + typename THandleTexSRV, + typename THandleTexUAV, + typename THandleBufSRV, + typename THandleBufUAV> + void ProcessResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes, + THandleCB HandleCB, + THandleTexSRV HandleTexSRV, + THandleTexUAV HandleTexUAV, + THandleBufSRV HandleBufSRV, + THandleBufUAV HandleBufUAV)const + { + Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + for(Uint32 n=0; n < GetNumCBs(); ++n) + { + const auto& CB = GetCB(n); + if( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ) + HandleCB(CB); + } + + for(Uint32 n=0; n < GetNumTexSRV(); ++n) + { + const auto &TexSRV = GetTexSRV(n); + if( IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits) ) + HandleTexSRV(TexSRV); + } + + for(Uint32 n=0; n < GetNumTexUAV(); ++n) + { + const auto &TexUAV = GetTexUAV(n); + if( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ) + HandleTexUAV(TexUAV); + } + + for(Uint32 n=0; n < GetNumBufSRV(); ++n) + { + const auto &BufSRV = GetBufSRV(n); + if( IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits) ) + HandleBufSRV(BufSRV); + } + + for(Uint32 n=0; n < GetNumBufUAV(); ++n) + { + const auto& BufUAV = GetBufUAV(n); + if( IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits) ) + HandleBufUAV(BufUAV); + } + } + +protected: + void Initialize(IMemoryAllocator &Allocator, Uint32 NumCBs, Uint32 NumTexSRVs, Uint32 NumTexUAVs, Uint32 NumBufSRVs, Uint32 NumBufUAVs, Uint32 NumSamplers); + + __forceinline D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset)noexcept + { + VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Max allowed index: ", NumResources-1); + VERIFY_EXPR(Offset + n < m_BufferEndOffset); + return reinterpret_cast<D3DShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n]; + } + + __forceinline const D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset)const noexcept + { + VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Max allowed index: ", NumResources-1); + VERIFY_EXPR(Offset + n < m_BufferEndOffset); + return reinterpret_cast<D3DShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n]; + } + + D3DShaderResourceAttribs& GetCB (Uint32 n)noexcept{ return GetResAttribs(n, GetNumCBs(), 0); } + D3DShaderResourceAttribs& GetTexSRV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } + D3DShaderResourceAttribs& GetTexUAV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } + D3DShaderResourceAttribs& GetBufSRV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } + D3DShaderResourceAttribs& GetBufUAV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } + D3DShaderResourceAttribs& GetSampler(Uint32 n)noexcept{ return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } + + Uint32 FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV)const; + +private: + // Memory buffer that holds all resources as continuous chunk of memory: + // | CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | + std::unique_ptr< void, STDDeleterRawMem<void> > m_MemoryBuffer; + + // Offsets in elements of D3DShaderResourceAttribs + typedef Uint16 OffsetType; + OffsetType m_TexSRVOffset = 0; + OffsetType m_TexUAVOffset = 0; + OffsetType m_BufSRVOffset = 0; + OffsetType m_BufUAVOffset = 0; + OffsetType m_SamplersOffset = 0; + OffsetType m_BufferEndOffset = 0; + + SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; +}; + +} diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.h new file mode 100644 index 00000000..6a8372bb --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.h @@ -0,0 +1,75 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Shader.h" + +/// \file +/// Declaration of Diligent::ShaderVariableD3DBase class + +namespace Diligent +{ + template<typename TShaderResourceLayout> + struct ShaderVariableD3DBase : public IShaderVariable + { + ShaderVariableD3DBase(TShaderResourceLayout &ParentResLayout, const D3DShaderResourceAttribs &ResourcesAttribs) : + m_ParentResLayout(ParentResLayout), + Attribs(ResourcesAttribs) + { + } + + virtual IReferenceCounters* GetReferenceCounters()const override final + { + return m_ParentResLayout.GetOwner().GetReferenceCounters(); + } + + virtual Atomics::Long AddRef()override final + { + return m_ParentResLayout.GetOwner().AddRef(); + } + + virtual Atomics::Long Release()override final + { + return m_ParentResLayout.GetOwner().Release(); + } + + void QueryInterface( const INTERFACE_ID &IID, IObject **ppInterface )override final + { + if( ppInterface == nullptr ) + return; + + *ppInterface = nullptr; + if( IID == IID_ShaderVariable || IID == IID_Unknown ) + { + *ppInterface = this; + (*ppInterface)->AddRef(); + } + } + + const D3DShaderResourceAttribs &Attribs; + + protected: + TShaderResourceLayout &m_ParentResLayout; + }; +} diff --git a/Graphics/GraphicsEngineD3DBase/src/DXGITypeConversions.cpp b/Graphics/GraphicsEngineD3DBase/src/DXGITypeConversions.cpp new file mode 100644 index 00000000..39c92997 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/src/DXGITypeConversions.cpp @@ -0,0 +1,406 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "DXGITypeConversions.h" +#include "BasicTypes.h" +#include "DebugUtilities.h" + +namespace Diligent +{ + +DXGI_FORMAT TypeToDXGI_Format(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized) +{ + switch(ValType) + { + case VT_FLOAT16: + { + VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_FLOAT; + case 2: return DXGI_FORMAT_R16G16_FLOAT; + case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT; + default: UNEXPECTED("Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_FLOAT32: + { + VERIFY( !bIsNormalized, "Floating point formats cannot be normalized" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R32_FLOAT; + case 2: return DXGI_FORMAT_R32G32_FLOAT; + case 3: return DXGI_FORMAT_R32G32B32_FLOAT; + case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_INT32: + { + VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R32_SINT; + case 2: return DXGI_FORMAT_R32G32_SINT; + case 3: return DXGI_FORMAT_R32G32B32_SINT; + case 4: return DXGI_FORMAT_R32G32B32A32_SINT; + default: UNEXPECTED("Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_UINT32: + { + VERIFY( !bIsNormalized, "32-bit UNORM formats are not supported. Use R32_FLOAT instead" ); + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R32_UINT; + case 2: return DXGI_FORMAT_R32G32_UINT; + case 3: return DXGI_FORMAT_R32G32B32_UINT; + case 4: return DXGI_FORMAT_R32G32B32A32_UINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + + case VT_INT16: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_SNORM; + case 2: return DXGI_FORMAT_R16G16_SNORM; + case 4: return DXGI_FORMAT_R16G16B16A16_SNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_SINT; + case 2: return DXGI_FORMAT_R16G16_SINT; + case 4: return DXGI_FORMAT_R16G16B16A16_SINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + case VT_UINT16: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_UNORM; + case 2: return DXGI_FORMAT_R16G16_UNORM; + case 4: return DXGI_FORMAT_R16G16B16A16_UNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R16_UINT; + case 2: return DXGI_FORMAT_R16G16_UINT; + case 4: return DXGI_FORMAT_R16G16B16A16_UINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + case VT_INT8: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_SNORM; + case 2: return DXGI_FORMAT_R8G8_SNORM; + case 4: return DXGI_FORMAT_R8G8B8A8_SNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_SINT; + case 2: return DXGI_FORMAT_R8G8_SINT; + case 4: return DXGI_FORMAT_R8G8B8A8_SINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + case VT_UINT8: + { + if( bIsNormalized ) + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_UNORM; + case 2: return DXGI_FORMAT_R8G8_UNORM; + case 4: return DXGI_FORMAT_R8G8B8A8_UNORM; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + else + { + switch(NumComponents) + { + case 1: return DXGI_FORMAT_R8_UINT; + case 2: return DXGI_FORMAT_R8G8_UINT; + case 4: return DXGI_FORMAT_R8G8B8A8_UINT; + default: UNEXPECTED( "Unusupported number of components" ); return DXGI_FORMAT_UNKNOWN; + } + } + } + + default: UNEXPECTED( "Unusupported format" ); return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT CorrectDXGIFormat( DXGI_FORMAT DXGIFormat, Uint32 BindFlags ) +{ + if( (BindFlags & BIND_DEPTH_STENCIL) && (BindFlags != BIND_DEPTH_STENCIL) ) + { + switch( DXGIFormat ) + { + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_D32_FLOAT: + DXGIFormat = DXGI_FORMAT_R32_TYPELESS; + break; + + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + DXGIFormat = DXGI_FORMAT_R24G8_TYPELESS; + break; + + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_D16_UNORM: + DXGIFormat = DXGI_FORMAT_R16_TYPELESS; + break; + + default: + UNEXPECTED( "Unsupported format" ); + break; + } + } + + if( BindFlags == BIND_DEPTH_STENCIL ) + { + switch( DXGIFormat ) + { + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_R32_FLOAT: + DXGIFormat = DXGI_FORMAT_D32_FLOAT; + break; + + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + DXGIFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; + break; + + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_UNORM: + DXGIFormat = DXGI_FORMAT_D16_UNORM; + break; + } + } + + if( BindFlags == BIND_SHADER_RESOURCE || BindFlags == BIND_UNORDERED_ACCESS ) + { + switch( DXGIFormat ) + { + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + DXGIFormat = DXGI_FORMAT_R32_FLOAT; + break; + + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + DXGIFormat = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + break; + + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_D16_UNORM: + DXGIFormat = DXGI_FORMAT_R16_UNORM; + break; + } + } + + return DXGIFormat; +} + +DXGI_FORMAT TexFormatToDXGI_Format(TEXTURE_FORMAT TexFormat, Uint32 BindFlags) +{ + static Bool bFormatMapIntialized = false; + static DXGI_FORMAT FmtToDXGIFmtMap[TEX_FORMAT_NUM_FORMATS] = {DXGI_FORMAT_UNKNOWN}; + if( !bFormatMapIntialized ) + { + FmtToDXGIFmtMap[ TEX_FORMAT_UNKNOWN ] = DXGI_FORMAT_UNKNOWN; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_TYPELESS ] = DXGI_FORMAT_R32G32B32A32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_FLOAT ] = DXGI_FORMAT_R32G32B32A32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_UINT ] = DXGI_FORMAT_R32G32B32A32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA32_SINT ] = DXGI_FORMAT_R32G32B32A32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_TYPELESS ] = DXGI_FORMAT_R32G32B32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_FLOAT ] = DXGI_FORMAT_R32G32B32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_UINT ] = DXGI_FORMAT_R32G32B32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB32_SINT ] = DXGI_FORMAT_R32G32B32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_TYPELESS ] = DXGI_FORMAT_R16G16B16A16_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_FLOAT ] = DXGI_FORMAT_R16G16B16A16_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_UNORM ] = DXGI_FORMAT_R16G16B16A16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_UINT ] = DXGI_FORMAT_R16G16B16A16_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_SNORM ] = DXGI_FORMAT_R16G16B16A16_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA16_SINT ] = DXGI_FORMAT_R16G16B16A16_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_TYPELESS ] = DXGI_FORMAT_R32G32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_FLOAT ] = DXGI_FORMAT_R32G32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_UINT ] = DXGI_FORMAT_R32G32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG32_SINT ] = DXGI_FORMAT_R32G32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R32G8X24_TYPELESS ] = DXGI_FORMAT_R32G8X24_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_D32_FLOAT_S8X24_UINT ] = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS ]= DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_X32_TYPELESS_G8X24_UINT ]= DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_TYPELESS ] = DXGI_FORMAT_R10G10B10A2_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_UNORM ] = DXGI_FORMAT_R10G10B10A2_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB10A2_UINT ] = DXGI_FORMAT_R10G10B10A2_UINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R11G11B10_FLOAT ] = DXGI_FORMAT_R11G11B10_FLOAT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_TYPELESS ] = DXGI_FORMAT_R8G8B8A8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UNORM ] = DXGI_FORMAT_R8G8B8A8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UNORM_SRGB ] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_UINT ] = DXGI_FORMAT_R8G8B8A8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_SNORM ] = DXGI_FORMAT_R8G8B8A8_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RGBA8_SINT ] = DXGI_FORMAT_R8G8B8A8_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_TYPELESS ] = DXGI_FORMAT_R16G16_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_FLOAT ] = DXGI_FORMAT_R16G16_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_UNORM ] = DXGI_FORMAT_R16G16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_UINT ] = DXGI_FORMAT_R16G16_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_SNORM ] = DXGI_FORMAT_R16G16_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG16_SINT ] = DXGI_FORMAT_R16G16_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R32_TYPELESS ] = DXGI_FORMAT_R32_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_D32_FLOAT ] = DXGI_FORMAT_D32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_FLOAT ] = DXGI_FORMAT_R32_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_UINT ] = DXGI_FORMAT_R32_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R32_SINT ] = DXGI_FORMAT_R32_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R24G8_TYPELESS ] = DXGI_FORMAT_R24G8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_D24_UNORM_S8_UINT ] = DXGI_FORMAT_D24_UNORM_S8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R24_UNORM_X8_TYPELESS ] = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_X24_TYPELESS_G8_UINT ] = DXGI_FORMAT_X24_TYPELESS_G8_UINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_TYPELESS ] = DXGI_FORMAT_R8G8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_UNORM ] = DXGI_FORMAT_R8G8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_UINT ] = DXGI_FORMAT_R8G8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_SNORM ] = DXGI_FORMAT_R8G8_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_SINT ] = DXGI_FORMAT_R8G8_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R16_TYPELESS ] = DXGI_FORMAT_R16_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_FLOAT ] = DXGI_FORMAT_R16_FLOAT; + FmtToDXGIFmtMap[ TEX_FORMAT_D16_UNORM ] = DXGI_FORMAT_D16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_UNORM ] = DXGI_FORMAT_R16_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_UINT ] = DXGI_FORMAT_R16_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_SNORM ] = DXGI_FORMAT_R16_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R16_SINT ] = DXGI_FORMAT_R16_SINT; + + FmtToDXGIFmtMap[ TEX_FORMAT_R8_TYPELESS ] = DXGI_FORMAT_R8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_UNORM ] = DXGI_FORMAT_R8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_UINT ] = DXGI_FORMAT_R8_UINT; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_SNORM ] = DXGI_FORMAT_R8_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_R8_SINT ] = DXGI_FORMAT_R8_SINT; + FmtToDXGIFmtMap[ TEX_FORMAT_A8_UNORM ] = DXGI_FORMAT_A8_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_R1_UNORM ] = DXGI_FORMAT_R1_UNORM ; + FmtToDXGIFmtMap[ TEX_FORMAT_RGB9E5_SHAREDEXP ] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; + FmtToDXGIFmtMap[ TEX_FORMAT_RG8_B8G8_UNORM ] = DXGI_FORMAT_R8G8_B8G8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_G8R8_G8B8_UNORM ] = DXGI_FORMAT_G8R8_G8B8_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_BC1_TYPELESS ] = DXGI_FORMAT_BC1_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC1_UNORM ] = DXGI_FORMAT_BC1_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC1_UNORM_SRGB ] = DXGI_FORMAT_BC1_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BC2_TYPELESS ] = DXGI_FORMAT_BC2_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC2_UNORM ] = DXGI_FORMAT_BC2_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC2_UNORM_SRGB ] = DXGI_FORMAT_BC2_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BC3_TYPELESS ] = DXGI_FORMAT_BC3_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC3_UNORM ] = DXGI_FORMAT_BC3_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC3_UNORM_SRGB ] = DXGI_FORMAT_BC3_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BC4_TYPELESS ] = DXGI_FORMAT_BC4_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC4_UNORM ] = DXGI_FORMAT_BC4_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC4_SNORM ] = DXGI_FORMAT_BC4_SNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC5_TYPELESS ] = DXGI_FORMAT_BC5_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC5_UNORM ] = DXGI_FORMAT_BC5_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC5_SNORM ] = DXGI_FORMAT_BC5_SNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_B5G6R5_UNORM ] = DXGI_FORMAT_B5G6R5_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_B5G5R5A1_UNORM ] = DXGI_FORMAT_B5G5R5A1_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_UNORM ] = DXGI_FORMAT_B8G8R8A8_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_UNORM ] = DXGI_FORMAT_B8G8R8X8_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ]= DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM; + + FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_TYPELESS ] = DXGI_FORMAT_B8G8R8A8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRA8_UNORM_SRGB ] = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_TYPELESS ] = DXGI_FORMAT_B8G8R8X8_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BGRX8_UNORM_SRGB ] = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_TYPELESS ] = DXGI_FORMAT_BC6H_TYPELESS; + FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_UF16 ] = DXGI_FORMAT_BC6H_UF16; + FmtToDXGIFmtMap[ TEX_FORMAT_BC6H_SF16 ] = DXGI_FORMAT_BC6H_SF16; + FmtToDXGIFmtMap[ TEX_FORMAT_BC7_TYPELESS ] = DXGI_FORMAT_BC7_TYPELESS ; + FmtToDXGIFmtMap[ TEX_FORMAT_BC7_UNORM ] = DXGI_FORMAT_BC7_UNORM; + FmtToDXGIFmtMap[ TEX_FORMAT_BC7_UNORM_SRGB ] = DXGI_FORMAT_BC7_UNORM_SRGB; + + bFormatMapIntialized = true; + } + + if( TexFormat >= TEX_FORMAT_UNKNOWN && TexFormat < TEX_FORMAT_NUM_FORMATS ) + { + auto DXGIFormat = FmtToDXGIFmtMap[TexFormat]; + VERIFY( TexFormat == TEX_FORMAT_UNKNOWN || DXGIFormat != DXGI_FORMAT_UNKNOWN, "Unsupported texture format" ); + if( BindFlags != 0 ) + DXGIFormat = CorrectDXGIFormat( DXGIFormat, BindFlags ); + return DXGIFormat; + } + else + { + UNEXPECTED( "Texture format (", TexFormat, ") is out of allowed range [0, ", TEX_FORMAT_NUM_FORMATS-1, "]" ); + return DXGI_FORMAT_UNKNOWN; + } +} + +} diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp new file mode 100644 index 00000000..9650fba3 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp @@ -0,0 +1,198 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include <unordered_map> +#include <D3Dcompiler.h> + +#include "D3DErrors.h" +#include "DataBlobImpl.h" +#include "RefCntAutoPtr.h" +#include <atlcomcli.h> +#include "ShaderD3DBase.h" + +namespace Diligent +{ + +const Char* g_HLSLDefinitions = +{ + #include "HLSLDefinitions_inc.fxh" +}; + +class D3DIncludeImpl : public ID3DInclude +{ +public: + D3DIncludeImpl(IShaderSourceInputStreamFactory *pStreamFactory) : + m_pStreamFactory(pStreamFactory) + { + + } + + STDMETHOD( Open )(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) + { + RefCntAutoPtr<IFileStream> pSourceStream; + m_pStreamFactory->CreateInputStream( pFileName, &pSourceStream ); + if( pSourceStream == nullptr ) + { + LOG_ERROR( "Failed to open shader include file ", pFileName, ". Check that the file exists" ); + return E_FAIL; + } + + RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl ); + pSourceStream->Read( pFileData ); + *ppData = pFileData->GetDataPtr(); + *pBytes = static_cast<UINT>( pFileData->GetSize() ); + + m_DataBlobs.insert( std::make_pair(*ppData, pFileData) ); + + return S_OK; + } + + STDMETHOD( Close )(THIS_ LPCVOID pData) + { + m_DataBlobs.erase( pData ); + return S_OK; + } + +private: + IShaderSourceInputStreamFactory *m_pStreamFactory; + std::unordered_map< LPCVOID, RefCntAutoPtr<Diligent::IDataBlob> > m_DataBlobs; +}; + +HRESULT CompileShader( const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + IShaderSourceInputStreamFactory *pIncludeStreamFactory, + LPCSTR profile, + ID3DBlob **ppBlobOut ) +{ + DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; +#if defined( DEBUG ) || defined( _DEBUG ) + // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders. + // Setting this flag improves the shader debugging experience, but still allows + // the shaders to be optimized and to run exactly the way they will run in + // the release configuration of this program. + dwShaderFlags |= D3DCOMPILE_DEBUG; +#else + // Warning: do not use this flag as it causes shader compiler to fail the compilation and + // report strange errors: + // dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3; +#endif + HRESULT hr; + do + { + CComPtr<ID3DBlob> errors; + auto SourceLen = strlen(Source); + + D3DIncludeImpl IncludeImpl(pIncludeStreamFactory); + hr = D3DCompile( Source, SourceLen, NULL, pDefines, &IncludeImpl, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, &errors ); + + if( FAILED(hr) || errors ) + { + std::wstringstream errorss; + ComErrorDesc ErrDesc(hr); + if( FAILED(hr) ) + Diligent::FormatMsg( errorss, "Failed to compile shader\n" ); + else + Diligent::FormatMsg( errorss, "Shader compiler output:\n" ); + Diligent::FormatMsg( errorss, ErrDesc.Get(), "\n" ); + if( errors ) + Diligent::FormatMsg( errorss, (char*)errors->GetBufferPointer() ); + auto ErrorDesc = errorss.str(); + OutputDebugStringW( ErrorDesc.c_str() ); + if( FAILED(hr) +#ifdef PLATFORM_WIN32 + && IDRETRY != MessageBoxW( NULL, ErrorDesc.c_str() , L"FX Error", MB_ICONERROR | (Source == nullptr ? MB_ABORTRETRYIGNORE : 0) ) +#endif + ) + { + break; + } + } + } while( FAILED(hr) ); + return hr; +} + +const char* DXShaderProfileToString(SHADER_PROFILE DXProfile) +{ + switch(DXProfile) + { + case SHADER_PROFILE_DX_4_0: return "4_0"; + case SHADER_PROFILE_DX_5_0: return "5_0"; + case SHADER_PROFILE_DX_5_1: return "5_1"; + //default: UNEXPECTED("Unknown DirectX shader profile" ); return ""; + default: return "5_0"; + } +} + +ShaderD3DBase::ShaderD3DBase(const ShaderCreationAttribs &CreationAttribs) +{ + std::string strShaderProfile; + switch(CreationAttribs.Desc.ShaderType) + { + case SHADER_TYPE_VERTEX: strShaderProfile="vs"; break; + case SHADER_TYPE_PIXEL: strShaderProfile="ps"; break; + case SHADER_TYPE_GEOMETRY:strShaderProfile="gs"; break; + case SHADER_TYPE_HULL: strShaderProfile="hs"; break; + case SHADER_TYPE_DOMAIN: strShaderProfile="ds"; break; + case SHADER_TYPE_COMPUTE: strShaderProfile="cs"; break; + + default: UNEXPECTED( "Unknown shader type" ); + } + strShaderProfile += "_"; + auto *pProfileSuffix = DXShaderProfileToString(CreationAttribs.Desc.TargetProfile); + strShaderProfile += pProfileSuffix; + + String ShaderSource(g_HLSLDefinitions); + if( CreationAttribs.Source ) + ShaderSource.append( CreationAttribs.Source ); + else + { + VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null"); + VERIFY(CreationAttribs.FilePath, "File path is null. Either shader source or source file path must be specified."); + RefCntAutoPtr<IFileStream> pSourceStream; + CreationAttribs.pShaderSourceStreamFactory->CreateInputStream( CreationAttribs.FilePath, &pSourceStream ); + RefCntAutoPtr<Diligent::IDataBlob> pFileData( new Diligent::DataBlobImpl ); + pSourceStream->Read( pFileData ); + // Null terminator is not read from the stream! + auto* FileDataPtr = reinterpret_cast<Char*>( pFileData->GetDataPtr() ); + auto Size = pFileData->GetSize(); + ShaderSource.append( FileDataPtr, FileDataPtr + Size/sizeof(*FileDataPtr) ); + } + + const D3D_SHADER_MACRO *pDefines = nullptr; + std::vector<D3D_SHADER_MACRO> D3DMacros; + if( CreationAttribs.Macros ) + { + for( auto* pCurrMacro = CreationAttribs.Macros; pCurrMacro->Name && pCurrMacro->Definition; ++pCurrMacro ) + { + D3DMacros.push_back( {pCurrMacro->Name, pCurrMacro->Definition} ); + } + D3DMacros.push_back( {nullptr, nullptr} ); + pDefines = D3DMacros.data(); + } + + CHECK_D3D_RESULT_THROW( CompileShader( ShaderSource.c_str(), CreationAttribs.EntryPoint, pDefines, CreationAttribs.pShaderSourceStreamFactory, strShaderProfile.c_str(), &m_pShaderByteCode ), + "Failed to compile the shader"); +} + +} diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp new file mode 100644 index 00000000..dd3b691c --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp @@ -0,0 +1,219 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "StringTools.h" +#include "ShaderResources.h" + +namespace Diligent +{ + +ShaderResources::~ShaderResources() +{ + for(Uint32 n=0; n < GetNumCBs(); ++n) + GetCB(n).~D3DShaderResourceAttribs(); + + for(Uint32 n=0; n < GetNumTexSRV(); ++n) + GetTexSRV(n).~D3DShaderResourceAttribs(); + + for(Uint32 n=0; n < GetNumTexUAV(); ++n) + GetTexUAV(n).~D3DShaderResourceAttribs(); + + for(Uint32 n=0; n < GetNumBufSRV(); ++n) + GetBufSRV(n).~D3DShaderResourceAttribs(); + + for(Uint32 n=0; n < GetNumBufUAV(); ++n) + GetBufUAV(n).~D3DShaderResourceAttribs(); + + for(Uint32 n=0; n < GetNumSamplers(); ++n) + GetSampler(n).~D3DShaderResourceAttribs(); +} + +void ShaderResources::Initialize(IMemoryAllocator &Allocator, Uint32 NumCBs, Uint32 NumTexSRVs, Uint32 NumTexUAVs, Uint32 NumBufSRVs, Uint32 NumBufUAVs, Uint32 NumSamplers) +{ + VERIFY( &m_MemoryBuffer.get_deleter().m_Allocator == &Allocator, "Incosistent allocators provided"); + + const auto MaxOffset = static_cast<Uint32>(std::numeric_limits<OffsetType>::max()); + VERIFY(NumCBs <= MaxOffset, "Max offset exceeded"); + m_TexSRVOffset = 0 + static_cast<OffsetType>(NumCBs); + + VERIFY(m_TexSRVOffset + NumTexSRVs <= MaxOffset, "Max offset exceeded"); + m_TexUAVOffset = m_TexSRVOffset + static_cast<OffsetType>(NumTexSRVs); + + VERIFY(m_TexUAVOffset + NumTexUAVs <= MaxOffset, "Max offset exceeded"); + m_BufSRVOffset = m_TexUAVOffset + static_cast<OffsetType>(NumTexUAVs); + + VERIFY(m_BufSRVOffset + NumBufSRVs <= MaxOffset, "Max offset exceeded"); + m_BufUAVOffset = m_BufSRVOffset + static_cast<OffsetType>(NumBufSRVs); + + VERIFY(m_BufUAVOffset + NumBufUAVs <= MaxOffset, "Max offset exceeded"); + m_SamplersOffset = m_BufUAVOffset + static_cast<OffsetType>(NumBufUAVs); + + VERIFY(m_SamplersOffset + NumSamplers<= MaxOffset, "Max offset exceeded"); + m_BufferEndOffset = m_SamplersOffset + static_cast<OffsetType>(NumSamplers); + + auto MemorySize = m_BufferEndOffset * sizeof(D3DShaderResourceAttribs); + + VERIFY_EXPR(GetNumCBs() == NumCBs); + VERIFY_EXPR(GetNumTexSRV() == NumTexSRVs); + VERIFY_EXPR(GetNumTexUAV() == NumTexUAVs); + VERIFY_EXPR(GetNumBufSRV() == NumBufSRVs); + VERIFY_EXPR(GetNumBufUAV() == NumBufUAVs); + VERIFY_EXPR(GetNumSamplers()== NumSamplers); + + if( MemorySize ) + { + auto *pRawMem = ALLOCATE(Allocator, "Allocator for shader resources", MemorySize ); + m_MemoryBuffer.reset(pRawMem); + } +} + +ShaderResources::ShaderResources(IMemoryAllocator &Allocator, SHADER_TYPE ShaderType): + m_MemoryBuffer(nullptr, STDDeleterRawMem<void>(Allocator)), + m_ShaderType(ShaderType) +{ +} + +void ShaderResources::CountResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes, Uint32 NumAllowedTypes, + Uint32& NumCBs, Uint32& NumTexSRVs, Uint32& NumTexUAVs, + Uint32& NumBufSRVs, Uint32& NumBufUAVs, Uint32& NumSamplers)const noexcept +{ + Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + NumCBs = 0; + NumTexSRVs = 0; + NumTexUAVs = 0; + NumBufSRVs = 0; + NumBufUAVs = 0; + NumSamplers = 0; + ProcessResources( + AllowedVarTypes, NumAllowedTypes, + + [&](const D3DShaderResourceAttribs &CB) + { + VERIFY_EXPR(IsAllowedType(CB.GetVariableType(), AllowedTypeBits)); + ++NumCBs; + }, + [&](const D3DShaderResourceAttribs& TexSRV) + { + VERIFY_EXPR(IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits)); + ++NumTexSRVs; + NumSamplers += TexSRV.IsValidSampler() ? 1 : 0; + }, + [&](const D3DShaderResourceAttribs &TexUAV) + { + VERIFY_EXPR(IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits)); + ++NumTexUAVs; + }, + [&](const D3DShaderResourceAttribs &BufSRV) + { + VERIFY_EXPR(IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits)); + ++NumBufSRVs; + }, + [&](const D3DShaderResourceAttribs &BufUAV) + { + VERIFY_EXPR(IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits)); + ++NumBufUAVs; + } + ); +} + +ShaderResources::ShaderResources(IMemoryAllocator &Allocator, + const ShaderResources& SrcResources, + const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes) : + m_MemoryBuffer(nullptr, STDDeleterRawMem<void>(Allocator)), + m_ShaderType(SrcResources.m_ShaderType) +{ + Uint32 NumCBs = 0, NumTexSRVs = 0, NumTexUAVs = 0, NumBufSRVs = 0, NumBufUAVs = 0, NumSamplers = 0; + SrcResources.CountResources(AllowedVarTypes, NumAllowedTypes, NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); + + Initialize(Allocator, NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); + + Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0; + ProcessResources( + AllowedVarTypes, NumAllowedTypes, + + [&](const D3DShaderResourceAttribs &CB) + { + VERIFY_EXPR( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ); + new (&GetCB(CurrCB++)) D3DShaderResourceAttribs(CB); + }, + [&](const D3DShaderResourceAttribs& TexSRV) + { + VERIFY_EXPR(IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits)); + + auto SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; + if (TexSRV.IsValidSampler()) + { + SamplerId = CurrSampler; + new (&GetSampler(CurrSampler++)) D3DShaderResourceAttribs(SrcResources.GetSampler(TexSRV.GetSamplerId())); + } + + new (&GetTexSRV(CurrTexSRV++)) D3DShaderResourceAttribs(TexSRV, SamplerId); + }, + [&](const D3DShaderResourceAttribs &TexUAV) + { + VERIFY_EXPR( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ); + new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs(TexUAV); + }, + [&](const D3DShaderResourceAttribs &BufSRV) + { + VERIFY_EXPR( IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits) ); + new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs(BufSRV); + }, + [&](const D3DShaderResourceAttribs &BufUAV) + { + VERIFY_EXPR( IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits) ); + new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs(BufUAV); + } + ); + + VERIFY_EXPR(CurrCB == NumCBs); + VERIFY_EXPR(CurrTexSRV == NumTexSRVs ); + VERIFY_EXPR(CurrTexUAV == NumTexUAVs ); + VERIFY_EXPR(CurrBufSRV == NumBufSRVs ); + VERIFY_EXPR(CurrBufUAV == NumBufUAVs ); + VERIFY_EXPR(CurrSampler == NumSamplers ); +} + +Uint32 ShaderResources::FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV)const +{ + VERIFY_EXPR(TexSRV.GetInputType() == D3D_SIT_TEXTURE); + auto NumSamplers = GetNumSamplers(); + for (Uint32 s = 0; s < NumSamplers; ++s) + { + const auto &Sampler = GetSampler(s); + if( StrCmpSuff(Sampler.Name.c_str(), TexSRV.Name.c_str(), D3DSamplerSuffix) ) + { + VERIFY(Sampler.GetVariableType() == TexSRV.GetVariableType(), "Inconsistent texture and sampler variable types") + VERIFY(Sampler.BindCount == TexSRV.BindCount || Sampler.BindCount == 1, "Sampler assigned to array \"", TexSRV.Name, "\" is expected to be scalar or have the same dimension (",TexSRV.BindCount,"). Actual sampler array dimension : ", Sampler.BindCount) + return s; + } + } + return D3DShaderResourceAttribs::InvalidSamplerId; +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Debug.h b/Graphics/GraphicsEngineOpenGL/build/Win32/Android/gcc_Debug.h index b46f53e0..b46f53e0 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Debug.h +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/Android/gcc_Debug.h diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Release.h b/Graphics/GraphicsEngineOpenGL/build/Win32/Android/gcc_Release.h index 6ca2abab..6ca2abab 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/Android/gcc_Release.h +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/Android/gcc_Release.h diff --git a/Graphics/GraphicsEngineD3D11/build/Windows/EngineRoot.props b/Graphics/GraphicsEngineOpenGL/build/Win32/EngineRoot.props index 02287e9c..02287e9c 100644 --- a/Graphics/GraphicsEngineD3D11/build/Windows/EngineRoot.props +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/EngineRoot.props diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Debug.vgdbsettings b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL-Debug.vgdbsettings index 3f5b24b1..3f5b24b1 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Debug.vgdbsettings +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL-Debug.vgdbsettings diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Release.vgdbsettings b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL-Release.vgdbsettings index 669691f2..669691f2 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL-Release.vgdbsettings +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL-Release.vgdbsettings diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.props b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL.props index 783f8a0f..783f8a0f 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.props +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL.props diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL.vcxproj index 34fbeeba..f2c1836a 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL.vcxproj @@ -337,11 +337,9 @@ </Lib> </ItemDefinitionGroup> <ItemGroup> - <ClInclude Include="..\..\include\BlendStateGLImpl.h" /> <ClInclude Include="..\..\include\BufferGLImpl.h" /> <ClInclude Include="..\..\include\BufferViewGLImpl.h" /> <ClInclude Include="..\..\include\DeviceContextGLImpl.h" /> - <ClInclude Include="..\..\include\DSStateGLImpl.h" /> <ClInclude Include="..\..\include\FBOCache.h" /> <ClInclude Include="..\..\include\GLContextAndroid.h" /> <ClInclude Include="..\..\include\GLContextState.h" /> @@ -366,15 +364,16 @@ <Command Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">$(EngineRoot)\Utilities\File2Include\File2String.exe %(FullPath) $(ProjectRoot)\include\%(Filename)_inc.h</Command> <Outputs Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">$(ProjectRoot)\include\%(Filename)_inc.h</Outputs> </CustomBuild> + <ClInclude Include="..\..\include\GLProgramResources.h" /> <ClInclude Include="..\..\include\GLStubs.h" /> <ClInclude Include="..\..\include\GLTypeConversions.h" /> <ClInclude Include="..\..\include\HLSL2GLSLConverter.h" /> - <ClInclude Include="..\..\include\RasterizerStateGLImpl.h" /> + <ClInclude Include="..\..\include\PipelineStateGLImpl.h" /> <ClInclude Include="..\..\include\RenderDeviceGLImpl.h" /> <ClInclude Include="..\..\include\RenderDeviceGLESImpl.h" /> <ClInclude Include="..\..\include\AsyncWritableResource.h" /> - <ClInclude Include="..\..\include\ProgramPipelineCache.h" /> <ClInclude Include="..\..\include\SamplerGLImpl.h" /> + <ClInclude Include="..\..\include\ShaderResourceBindingGLImpl.h" /> <ClInclude Include="..\..\include\SwapChainGLImpl.h" /> <ClInclude Include="..\..\include\TexRegionRender.h" /> <ClInclude Include="..\..\include\Texture1DArray_OGL.h" /> @@ -383,30 +382,28 @@ <ClInclude Include="..\..\include\Texture2D_OGL.h" /> <ClInclude Include="..\..\include\Texture3D_OGL.h" /> <ClInclude Include="..\..\include\TextureBaseGL.h" /> + <ClInclude Include="..\..\include\TextureCubeArray_OGL.h" /> + <ClInclude Include="..\..\include\TextureCube_OGL.h" /> <ClInclude Include="..\..\include\TextureViewGLImpl.h" /> <ClInclude Include="..\..\include\VAOCache.h" /> - <ClInclude Include="..\..\include\VertexDescGLImpl.h" /> <ClInclude Include="..\..\include\ShaderGLImpl.h" /> <ClInclude Include="..\..\include\pch.h" /> - <ClInclude Include="..\..\interface\BlendStateGL.h" /> <ClInclude Include="..\..\interface\BufferGL.h" /> <ClInclude Include="..\..\interface\BufferViewGL.h" /> - <ClInclude Include="..\..\interface\DepthStencilStateGL.h" /> <ClInclude Include="..\..\interface\DeviceContextGL.h" /> - <ClInclude Include="..\..\interface\RasterizerStateGL.h" /> + <ClInclude Include="..\..\interface\PipelineStateGL.h" /> <ClInclude Include="..\..\interface\RenderDeviceFactoryOpenGL.h" /> <ClInclude Include="..\..\interface\RenderDeviceGL.h" /> <ClInclude Include="..\..\interface\RenderDeviceGLES.h" /> <ClInclude Include="..\..\interface\BaseInterfacesGL.h" /> <ClInclude Include="..\..\interface\SamplerGL.h" /> <ClInclude Include="..\..\interface\ShaderGL.h" /> + <ClInclude Include="..\..\interface\ShaderResourceBindingGL.h" /> <ClInclude Include="..\..\interface\SwapChainGL.h" /> <ClInclude Include="..\..\interface\TextureGL.h" /> <ClInclude Include="..\..\interface\TextureViewGL.h" /> - <ClInclude Include="..\..\interface\VertexDescriptionGL.h" /> </ItemGroup> <ItemGroup> - <ClCompile Include="..\..\src\BlendStateGLImpl.cpp" /> <ClCompile Include="..\..\src\BufferGLImpl.cpp" /> <ClCompile Include="..\..\src\BufferViewGLImpl.cpp" /> <ClCompile Include="..\..\src\DeviceContextGLImpl.cpp" /> @@ -415,8 +412,11 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|ARM'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\src\DSStateGLImpl.cpp" /> <ClCompile Include="..\..\src\FBOCache.cpp" /> <ClCompile Include="..\..\src\GLContextAndroid.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> @@ -437,6 +437,7 @@ </ClCompile> <ClCompile Include="..\..\src\GLObjectWrapper.cpp" /> <ClCompile Include="..\..\src\GLProgram.cpp" /> + <ClCompile Include="..\..\src\GLProgramResources.cpp" /> <ClCompile Include="..\..\src\GLStubs.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DbgDLL|Win32'">true</ExcludedFromBuild> @@ -449,7 +450,7 @@ </ClCompile> <ClCompile Include="..\..\src\GLTypeConversions.cpp" /> <ClCompile Include="..\..\src\HLSL2GLSLConverter.cpp" /> - <ClCompile Include="..\..\src\RasterizerStateGLImpl.cpp" /> + <ClCompile Include="..\..\src\PipelineStateGLImpl.cpp" /> <ClCompile Include="..\..\src\RenderDeviceGLImpl.cpp" /> <ClCompile Include="..\..\src\RenderDeviceGLESImpl.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> @@ -461,8 +462,8 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='RelDLL|x64'">true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\src\ProgramPipelineCache.cpp" /> <ClCompile Include="..\..\src\SamplerGLImpl.cpp" /> + <ClCompile Include="..\..\src\ShaderResourceBindingGLImpl.cpp" /> <ClCompile Include="..\..\src\SwapChainGLImpl.cpp" /> <ClCompile Include="..\..\src\TexRegionRender.cpp" /> <ClCompile Include="..\..\src\Texture1DArray_OGL.cpp" /> @@ -471,9 +472,10 @@ <ClCompile Include="..\..\src\Texture2D_OGL.cpp" /> <ClCompile Include="..\..\src\Texture3D_OGL.cpp" /> <ClCompile Include="..\..\src\TextureBaseGL.cpp" /> + <ClCompile Include="..\..\src\TextureCubeArray_OGL.cpp" /> + <ClCompile Include="..\..\src\TextureCube_OGL.cpp" /> <ClCompile Include="..\..\src\TextureViewGLImpl.cpp" /> <ClCompile Include="..\..\src\VAOCache.cpp" /> - <ClCompile Include="..\..\src\VertexDescGLImpl.cpp" /> <ClCompile Include="..\..\src\RenderDeviceFactoryOpenGL.cpp" /> <ClCompile Include="..\..\src\ShaderGLImpl.cpp" /> <ClCompile Include="..\..\src\pch.cpp"> @@ -493,45 +495,28 @@ <None Include="jni\Application.mk" /> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\..\..\..\Common\build\Windows\Common.vcxproj"> + <ProjectReference Include="..\..\..\..\Common\build\Win32\Common.vcxproj"> <Project>{7380f7e6-315f-4b4e-92eb-e6aeee865298}</Project> - <Private>false</Private> - <ReferenceOutputAssembly>true</ReferenceOutputAssembly> - <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> - <LinkLibraryDependencies>true</LinkLibraryDependencies> - <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> </ProjectReference> - <ProjectReference Include="..\..\..\..\External\glew-1.10.0\build\Windows\glew_static.vcxproj"> + <ProjectReference Include="..\..\..\..\External\glew-1.10.0\build\Win32\glew_static.vcxproj"> <Project>{664e6f0d-6784-4760-9565-d54f8eb1edf4}</Project> </ProjectReference> - <ProjectReference Include="..\..\..\..\Platforms\Basic\build\Windows\BasicPlatform.vcxproj"> + <ProjectReference Include="..\..\..\..\Platforms\Basic\build\Win32\BasicPlatform.vcxproj"> <Project>{8ada5f93-7a38-4ad8-b8f5-1ffd4d4f630c}</Project> - <Private>false</Private> - <ReferenceOutputAssembly>true</ReferenceOutputAssembly> - <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> - <LinkLibraryDependencies>true</LinkLibraryDependencies> - <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> </ProjectReference> - <ProjectReference Include="..\..\..\..\Platforms\Windows\build\Windows\WindowsPlatform.vcxproj"> + <ProjectReference Include="..\..\..\..\Platforms\Win32\build\Win32\WindowsPlatform.vcxproj"> <Project>{58f32677-436b-412a-bbf8-2b1310d82cd8}</Project> - <Private>false</Private> - <ReferenceOutputAssembly>true</ReferenceOutputAssembly> - <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> - <LinkLibraryDependencies>true</LinkLibraryDependencies> - <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> </ProjectReference> - <ProjectReference Include="..\..\..\GraphicsEngine\build\Windows\GraphicsEngine.vcxproj"> + <ProjectReference Include="..\..\..\GraphicsEngine\build\Win32\GraphicsEngine.vcxproj"> <Project>{052dd700-477c-4512-a7f4-b05ebef5c80e}</Project> - <Private>false</Private> - <ReferenceOutputAssembly>true</ReferenceOutputAssembly> - <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> - <LinkLibraryDependencies>true</LinkLibraryDependencies> - <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> </ProjectReference> - <ProjectReference Include="..\..\..\GraphicsTools\build\Windows\GraphicsTools.vcxproj"> + <ProjectReference Include="..\..\..\GraphicsTools\build\Win32\GraphicsTools.vcxproj"> <Project>{c6014499-0cf2-43ec-a773-a4e354fb2d74}</Project> </ProjectReference> </ItemGroup> + <ItemGroup> + <Text Include="..\..\CMakeLists.txt" /> + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj.filters b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL.vcxproj.filters index 03c80428..cac09c45 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/GraphicsEngineOpenGL.vcxproj.filters +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/GraphicsEngineOpenGL.vcxproj.filters @@ -41,9 +41,6 @@ <ClInclude Include="..\..\include\GLObjectWrapper.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\include\ProgramPipelineCache.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\include\GLTypeConversions.h"> <Filter>Header Files</Filter> </ClInclude> @@ -83,9 +80,6 @@ <ClInclude Include="..\..\include\BufferViewGLImpl.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\include\DSStateGLImpl.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\include\SamplerGLImpl.h"> <Filter>Header Files</Filter> </ClInclude> @@ -95,9 +89,6 @@ <ClInclude Include="..\..\include\TextureBaseGL.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\include\VertexDescGLImpl.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\include\RenderDeviceGLImpl.h"> <Filter>Header Files</Filter> </ClInclude> @@ -119,9 +110,6 @@ <ClInclude Include="..\..\interface\BufferViewGL.h"> <Filter>Interface</Filter> </ClInclude> - <ClInclude Include="..\..\interface\DepthStencilStateGL.h"> - <Filter>Interface</Filter> - </ClInclude> <ClInclude Include="..\..\interface\SamplerGL.h"> <Filter>Interface</Filter> </ClInclude> @@ -137,27 +125,12 @@ <ClInclude Include="..\..\include\TextureViewGLImpl.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\interface\VertexDescriptionGL.h"> - <Filter>Interface</Filter> - </ClInclude> <ClInclude Include="..\..\interface\DeviceContextGL.h"> <Filter>Interface</Filter> </ClInclude> <ClInclude Include="..\..\include\DeviceContextGLImpl.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\include\RasterizerStateGLImpl.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\interface\RasterizerStateGL.h"> - <Filter>Interface</Filter> - </ClInclude> - <ClInclude Include="..\..\interface\BlendStateGL.h"> - <Filter>Interface</Filter> - </ClInclude> - <ClInclude Include="..\..\include\BlendStateGLImpl.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\include\FBOCache.h"> <Filter>Header Files</Filter> </ClInclude> @@ -182,6 +155,27 @@ <ClInclude Include="..\..\include\TexRegionRender.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\interface\PipelineStateGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\include\PipelineStateGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\interface\ShaderResourceBindingGL.h"> + <Filter>Interface</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ShaderResourceBindingGLImpl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\GLProgramResources.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\TextureCube_OGL.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\TextureCubeArray_OGL.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\src\VAOCache.cpp"> @@ -190,9 +184,6 @@ <ClCompile Include="..\..\src\GLObjectWrapper.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\src\ProgramPipelineCache.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\src\GLTypeConversions.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -232,9 +223,6 @@ <ClCompile Include="..\..\src\BufferViewGLImpl.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\src\DSStateGLImpl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\src\SamplerGLImpl.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -244,9 +232,6 @@ <ClCompile Include="..\..\src\TextureBaseGL.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\src\VertexDescGLImpl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\src\RenderDeviceGLImpl.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -259,12 +244,6 @@ <ClCompile Include="..\..\src\DeviceContextGLImpl.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\src\RasterizerStateGLImpl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\src\BlendStateGLImpl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\src\FBOCache.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -286,6 +265,21 @@ <ClCompile Include="..\..\src\TexRegionRender.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\src\PipelineStateGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\ShaderResourceBindingGLImpl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\GLProgramResources.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\TextureCube_OGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\src\TextureCubeArray_OGL.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="jni\Application.mk"> @@ -303,4 +297,7 @@ <Filter>Header Files</Filter> </CustomBuild> </ItemGroup> + <ItemGroup> + <Text Include="..\..\CMakeLists.txt" /> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Android.mk b/Graphics/GraphicsEngineOpenGL/build/Win32/jni/Android.mk index 521821b3..fd7b718a 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Android.mk +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/jni/Android.mk @@ -19,7 +19,7 @@ LOCAL_C_INCLUDES := $(PROJECT_ROOT)/include $(PROJECT_ROOT)/interface $(SOLUTION # Source files #VisualGDBAndroid: AutoUpdateSourcesInNextLine -LOCAL_SRC_FILES := ../../../src/BlendStateGLImpl.cpp ../../../src/BufferGLImpl.cpp ../../../src/BufferViewGLImpl.cpp ../../../src/DeviceContextGLImpl.cpp ../../../src/DLLMain.cpp ../../../src/DSStateGLImpl.cpp ../../../src/FBOCache.cpp ../../../src/GLContextAndroid.cpp ../../../src/GLContextState.cpp ../../../src/GLContextWindows.cpp ../../../src/GLObjectWrapper.cpp ../../../src/GLProgram.cpp ../../../src/GLStubs.cpp ../../../src/GLTypeConversions.cpp ../../../src/HLSL2GLSLConverter.cpp ../../../src/RasterizerStateGLImpl.cpp ../../../src/RenderDeviceGLImpl.cpp ../../../src/RenderDeviceGLESImpl.cpp ../../../src/ProgramPipelineCache.cpp ../../../src/SamplerGLImpl.cpp ../../../src/SwapChainGLImpl.cpp ../../../src/TexRegionRender.cpp ../../../src/Texture1DArray_OGL.cpp ../../../src/Texture1D_OGL.cpp ../../../src/Texture2DArray_OGL.cpp ../../../src/Texture2D_OGL.cpp ../../../src/Texture3D_OGL.cpp ../../../src/TextureBaseGL.cpp ../../../src/TextureViewGLImpl.cpp ../../../src/VAOCache.cpp ../../../src/VertexDescGLImpl.cpp ../../../src/RenderDeviceFactoryOpenGL.cpp ../../../src/ShaderGLImpl.cpp ../../../src/pch.cpp +LOCAL_SRC_FILES := ../../../src/BufferGLImpl.cpp ../../../src/BufferViewGLImpl.cpp ../../../src/DeviceContextGLImpl.cpp ../../../src/DLLMain.cpp ../../../src/FBOCache.cpp ../../../src/GLContextAndroid.cpp ../../../src/GLContextState.cpp ../../../src/GLContextWindows.cpp ../../../src/GLObjectWrapper.cpp ../../../src/GLProgram.cpp ../../../src/GLProgramResources.cpp ../../../src/GLStubs.cpp ../../../src/GLTypeConversions.cpp ../../../src/HLSL2GLSLConverter.cpp ../../../src/PipelineStateGLImpl.cpp ../../../src/RenderDeviceGLImpl.cpp ../../../src/RenderDeviceGLESImpl.cpp ../../../src/SamplerGLImpl.cpp ../../../src/ShaderResourceBindingGLImpl.cpp ../../../src/SwapChainGLImpl.cpp ../../../src/TexRegionRender.cpp ../../../src/Texture1DArray_OGL.cpp ../../../src/Texture1D_OGL.cpp ../../../src/Texture2DArray_OGL.cpp ../../../src/Texture2D_OGL.cpp ../../../src/Texture3D_OGL.cpp ../../../src/TextureBaseGL.cpp ../../../src/TextureCubeArray_OGL.cpp ../../../src/TextureCube_OGL.cpp ../../../src/TextureViewGLImpl.cpp ../../../src/VAOCache.cpp ../../../src/RenderDeviceFactoryOpenGL.cpp ../../../src/ShaderGLImpl.cpp ../../../src/pch.cpp #VisualGDBAndroid: VSExcludeListLocation VISUALGDB_VS_EXCLUDED_FILES_Release := ../../../src/DLLMain.cpp ../../../src/GLContextWindows.cpp @@ -32,7 +32,7 @@ include $(CLEAR_VARS) # Declare pre-built Common library LOCAL_MODULE := Common-prebuilt LOCAL_EXPORT_C_INCLUDES := $(SOLUTION_ROOT)/Common/include $(SOLUTION_ROOT)/Common/interface -LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Common/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libCommon.a +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Common/build/Win32/obj/local/$(TARGET_ARCH_ABI)/libCommon.a include $(PREBUILT_STATIC_LIBRARY) @@ -46,21 +46,21 @@ include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) # Declare pre-built BasicPlatform library LOCAL_MODULE := BasicPlatform-prebuilt -LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Platforms/Basic/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libBasicPlatform.a +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Platforms/Basic/build/Win32/obj/local/$(TARGET_ARCH_ABI)/libBasicPlatform.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) # Declare pre-built GraphicsEngine library LOCAL_MODULE := GraphicsEngine-prebuilt -LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Graphics/GraphicsEngine/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libGraphicsEngine.a +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Graphics/GraphicsEngine/build/Win32/obj/local/$(TARGET_ARCH_ABI)/libGraphicsEngine.a LOCAL_EXPORT_C_INCLUDES := $(SOLUTION_ROOT)/Graphics/GraphicsEngine/include $(SOLUTION_ROOT)/Graphics/GraphicsEngine/interface include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) # Declare pre-built Graphics Tools library LOCAL_MODULE := GraphicsTools-prebuilt -LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Graphics/GraphicsTools/build/Windows/obj/local/$(TARGET_ARCH_ABI)/libGraphicsTools.a +LOCAL_SRC_FILES := $(SOLUTION_ROOT)/Graphics/GraphicsTools/build/Win32/obj/local/$(TARGET_ARCH_ABI)/libGraphicsTools.a LOCAL_EXPORT_C_INCLUDES := $(SOLUTION_ROOT)/Graphics/GraphicsTools/include include $(PREBUILT_STATIC_LIBRARY) diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Application.mk b/Graphics/GraphicsEngineOpenGL/build/Win32/jni/Application.mk index c7e241e8..c7e241e8 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/jni/Application.mk +++ b/Graphics/GraphicsEngineOpenGL/build/Win32/jni/Application.mk diff --git a/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h b/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h index 89547eb8..27e53f9d 100644 --- a/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h +++ b/Graphics/GraphicsEngineOpenGL/include/AsyncWritableResource.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h index 342dec4d..65c2b9f2 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,16 +30,24 @@ #include "BaseInterfacesGL.h" #include "BufferViewGLImpl.h" + namespace Diligent { +class FixedBlockMemoryAllocator; + /// Implementation of the Diligent::IBufferGL interface -class BufferGLImpl : public BufferBase<IBufferGL, BufferViewGLImpl>, public AsyncWritableResource +class BufferGLImpl : public BufferBase<IBufferGL, BufferViewGLImpl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator>, public AsyncWritableResource { public: - typedef BufferBase<IBufferGL, BufferViewGLImpl> TBufferBase; + typedef BufferBase<IBufferGL, BufferViewGLImpl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> TBufferBase; - BufferGLImpl(class RenderDeviceGLImpl *pDeviceGL, const BufferDesc& BuffDesc, const BufferData &BuffData = BufferData(), bool IsDeviceInternal = false); + BufferGLImpl(FixedBlockMemoryAllocator &BufferObjMemAllocator, + FixedBlockMemoryAllocator &BuffViewObjMemAllocator, + class RenderDeviceGLImpl *pDeviceGL, + const BufferDesc& BuffDesc, + const BufferData &BuffData = BufferData(), + bool IsDeviceInternal = false); ~BufferGLImpl(); /// Queries the specific interface, see IObject::QueryInterface() for details @@ -48,7 +56,7 @@ public: virtual void UpdateData(IDeviceContext *pContext, Uint32 Offset, Uint32 Size, const PVoid pData)override; virtual void CopyData( IDeviceContext *pContext, IBuffer *pSrcBuffer, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size )override; virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; - virtual void Unmap( IDeviceContext *pContext )override; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override; void BufferMemoryBarrier( Uint32 RequiredBarriers, class GLContextState &GLContextState ); diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h index 2f7ed835..330ddf23 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,17 +32,19 @@ namespace Diligent { +class FixedBlockMemoryAllocator; /// Implementation of the Diligent::IBufferViewGL interface -class BufferViewGLImpl : public BufferViewBase<IBufferViewGL> +class BufferViewGLImpl : public BufferViewBase<IBufferViewGL, FixedBlockMemoryAllocator> { public: - typedef BufferViewBase<IBufferViewGL> TBuffViewBase; + typedef BufferViewBase<IBufferViewGL, FixedBlockMemoryAllocator> TBuffViewBase; - BufferViewGLImpl( class IRenderDevice *pDevice, - class IDeviceContext *pContext, - const struct BufferViewDesc& ViewDesc, - class BufferGLImpl *pBuffer, - bool bIsDefaultView); + BufferViewGLImpl( FixedBlockMemoryAllocator& BuffViewObjAllocator, + class IRenderDevice *pDevice, + class IDeviceContext *pContext, + const struct BufferViewDesc& ViewDesc, + class BufferGLImpl *pBuffer, + bool bIsDefaultView); /// Queries the specific interface, see IObject::QueryInterface() for details virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); diff --git a/Graphics/GraphicsEngineOpenGL/include/DSStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DSStateGLImpl.h deleted file mode 100644 index 38f8eaff..00000000 --- a/Graphics/GraphicsEngineOpenGL/include/DSStateGLImpl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "BaseInterfacesGL.h" -#include "DepthStencilStateGL.h" -#include "DepthStencilStateBase.h" -#include "RenderDevice.h" - -namespace Diligent -{ - -/// Implementation of the Diligent::IDepthStencilStateGL interface -class DSStateGLImpl : public DepthStencilStateBase<IDepthStencilStateGL, IGLDeviceBaseInterface> -{ -public: - typedef DepthStencilStateBase<IDepthStencilStateGL, IGLDeviceBaseInterface> TDSStateBase; - - DSStateGLImpl(class IRenderDevice *pDeviceGL, const DepthStencilStateDesc& DepthStencilStateDesc, bool bIsDeviceInternal = false); - ~DSStateGLImpl(); - - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); -}; - -} diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 08694a9f..95a87c60 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,45 +37,47 @@ class DeviceContextGLImpl : public DeviceContextBase<IDeviceContextGL> public: typedef DeviceContextBase<IDeviceContextGL> TDeviceContextBase; - DeviceContextGLImpl( class RenderDeviceGLImpl *pDeviceGL ); + DeviceContextGLImpl( IMemoryAllocator &RawMemAllocator, class RenderDeviceGLImpl *pDeviceGL, bool bIsDeferred ); /// Queries the specific interface, see IObject::QueryInterface() for details. - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual void SetShaders( IShader **ppShaders, Uint32 NumShadersToSet )override; + virtual void SetPipelineState(IPipelineState *pPipelineState)override final; - virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override; + virtual void TransitionShaderResources(IPipelineState *pPipelineState, IShaderResourceBinding *pShaderResourceBinding)override final; - virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override; - virtual void ClearState()override; + virtual void CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags)override final; - virtual void SetVertexDescription( IVertexDescription *pVertexDesc )override; + virtual void SetStencilRef(Uint32 StencilRef)override final; - virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override; + virtual void SetBlendFactors(const float* pBlendFactors = nullptr)override final; - virtual void SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef = 0 )override; + virtual void SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )override final; + virtual void ClearState()override final; - virtual void SetRasterizerState( IRasterizerState *pRS )override; + virtual void SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset )override final; - virtual void SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask )override; + virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )override final; - virtual void SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )override; + virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )override final; - virtual void SetScissorRects( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )override; + virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil )override final; - virtual void SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil )override; + virtual void Draw( DrawAttribs &DrawAttribs )override final; - virtual void Draw( DrawAttribs &DrawAttribs )override; + virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )override final; - virtual void DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )override; + virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil)override final; - virtual void ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil)override; + virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA )override final; - virtual void ClearRenderTarget( ITextureView *pView, const float *RGBA )override; + virtual void Flush()override final; - virtual void Flush()override; + virtual void FinishCommandList(class ICommandList **ppCommandList)override final; - void BindProgramResources( Uint32 &NewMemoryBarriers ); + virtual void ExecuteCommandList(class ICommandList *pCommandList)override final; + + void BindProgramResources( Uint32 &NewMemoryBarriers, IShaderResourceBinding *pResBinding ); GLContextState &GetContextState(){return m_ContextState;} @@ -84,14 +86,17 @@ public: protected: friend class BufferGLImpl; friend class TextureBaseGL; - friend class VertexDescGLImpl; friend class ShaderGLImpl; GLContextState m_ContextState; private: + Uint32 m_CommitedResourcesTentativeBarriers; + std::vector<class TextureBaseGL*> m_BoundWritableTextures; std::vector<class BufferGLImpl*> m_BoundWritableBuffers; + + bool m_bVAOIsUpToDate = false; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/FBOCache.h b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h index c1e601d8..717b1772 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FBOCache.h +++ b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h index 63299daf..10085b2e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h index cda952e1..2de6619c 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,6 +51,7 @@ public: void SetDepthFunc(COMPARISON_FUNCTION CmpFunc); void EnableStencilTest( Bool bEnable ); void SetStencilWriteMask( Uint8 StencilWriteMask ); + void SetStencilRef( GLenum Face, Int32 Ref ); void SetStencilFunc( GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask ); void SetStencilOp( GLenum Face, STENCIL_OP StencilFailOp, STENCIL_OP StencilDepthFailOp, STENCIL_OP StencilPassOp ); @@ -61,7 +62,8 @@ public: void SetDepthClamp( Bool bEnableDepthClamp ); void EnableScissorTest( Bool bEnableScissorTest ); - void SetBlendState(const BlendStateDesc &BSDsc, const float *BlendFactors, Uint32 SampleMask); + void SetBlendFactors(const float *BlendFactors); + void SetBlendState(const BlendStateDesc &BSDsc, Uint32 SampleMask); Bool GetDepthWritesEnabled(){ return m_DepthWritesEnableState; } Bool GetScissorTestEnabled(){ return m_RSState.ScissorTestEnable; } @@ -168,7 +170,7 @@ private: Int32 Ref; Uint32 Mask; StencilOpState() : - Func( COMPARISON_FUNC_UNKNOW ), + Func( COMPARISON_FUNC_UNKNOWN ), StencilFailOp(STENCIL_OP_UNDEFINED), StencilDepthFailOp( STENCIL_OP_UNDEFINED ), StencilPassOp( STENCIL_OP_UNDEFINED ), diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h index a134d831..641b18c6 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h index 21710d4f..4fa03ac0 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h index 96206374..b0bff833 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,92 +23,42 @@ #pragma once #include "GLObjectWrapper.h" - -#ifdef _DEBUG -# define VERIFY_RESOURCE_BINDINGS -#endif +#include "GLProgramResources.h" namespace Diligent { - class GLProgram : public GLObjectWrappers::GLProgramObj { public: GLProgram( bool CreateObject ); GLProgram( GLProgram&& Program ); - void LoadUniforms(); - - struct GLProgramVariableBase - { - GLProgramVariableBase( const Char* _Name ) : - Name( _Name ) - {} - - String Name; - RefCntAutoPtr<IDeviceObject> pResource; - }; - - struct UniformBufferInfo : GLProgramVariableBase - { - UniformBufferInfo(const Char* _Name, GLint _Index) : - GLProgramVariableBase(_Name), - Index(_Index) - {} + void InitResources(RenderDeviceGLImpl* pDeviceGLImpl, + SHADER_VARIABLE_TYPE DefaultVariableType, + const ShaderVariableDesc *VariableDesc, + Uint32 NumVars, + const StaticSamplerDesc *StaticSamplers, + Uint32 NumStaticSamplers, + IObject &Owner); - GLuint Index; - }; - std::vector<UniformBufferInfo>& GetUniformBlocks(){ return m_UniformBlocks; } + void BindConstantResources(IResourceMapping *pResourceMapping, Uint32 Flags); - struct SamplerInfo : GLProgramVariableBase - { - SamplerInfo(const Char* _Name, GLint _Location, GLenum _Type) : - GLProgramVariableBase(_Name), - Location(_Location), - Type(_Type) - {} - GLint Location; - GLenum Type; - }; - std::vector<SamplerInfo>& GetSamplers(){ return m_Samplers; } + const GLProgramResources& GetAllResources(){return m_AllResources;} + GLProgramResources& GetConstantResources(){return m_ConstantResources;} - struct ImageInfo : GLProgramVariableBase - { - ImageInfo(const Char* _Name, GLint _BindingPoint, GLenum _Type) : - GLProgramVariableBase(_Name), - BindingPoint(_BindingPoint), - Type(_Type) - {} - - GLint BindingPoint; - GLenum Type; - }; - std::vector<ImageInfo>& GetImages(){ return m_Images; } - - struct StorageBlockInfo : GLProgramVariableBase - { - StorageBlockInfo(const Char* _Name, GLint _Binding) : - GLProgramVariableBase(_Name), - Binding(_Binding) - {} - - GLint Binding; - }; - std::vector<StorageBlockInfo>& GetStorageBlocks(){ return m_StorageBlocks; } - - void BindResources(IResourceMapping *pResourceMapping, Uint32 Flags); #ifdef VERIFY_RESOURCE_BINDINGS - void dbgVerifyResourceBindings(); + template<typename TResArrayType> + void dbgVerifyBindingCompletenessHelper(TResArrayType &ResArr, GLProgramResources *pDynamicResources); + void dbgVerifyBindingCompleteness(GLProgramResources *pDynamicResources, class PipelineStateGLImpl *pPSO); #endif private: GLProgram( const GLProgram& Program ); const GLProgram& operator = (const GLProgram& Program); - std::vector<UniformBufferInfo> m_UniformBlocks; - std::vector< SamplerInfo > m_Samplers; - std::vector< ImageInfo > m_Images; - std::vector< StorageBlockInfo > m_StorageBlocks; + + GLProgramResources m_AllResources; + GLProgramResources m_ConstantResources; // When adding new member DO NOT FORGET TO UPDATE GLProgram( GLProgram&& Program )!!! }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h new file mode 100644 index 00000000..edb0890d --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h @@ -0,0 +1,166 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once +#include "GLObjectWrapper.h" +#include "HashUtils.h" +#include "ShaderBase.h" +#include "SamplerGLImpl.h" + +#ifdef _DEBUG +# define VERIFY_RESOURCE_BINDINGS +#endif + +namespace Diligent +{ + class GLProgramResources + { + public: + GLProgramResources(); + GLProgramResources( GLProgramResources&& Program ); + + void LoadUniforms(class RenderDeviceGLImpl *pDeviceGLImpl, + GLuint GLProgram, + const SHADER_VARIABLE_TYPE DefaultVariableType, + const ShaderVariableDesc *VariableDesc, + Uint32 NumVars, + const StaticSamplerDesc *StaticSamplers, + Uint32 NumStaticSamplers); + + void Clone(const GLProgramResources& SrcLayout, + SHADER_VARIABLE_TYPE *VarTypes, + Uint32 NumVarTypes, + IObject &Owner); + + struct GLProgramVariableBase + { + GLProgramVariableBase( const Char* _Name, size_t _ArraySize, SHADER_VARIABLE_TYPE _VarType) : + Name( _Name ), + VarType(_VarType), + pResources(_ArraySize) + { + VERIFY_EXPR(_ArraySize >= 1); + } + + String Name; + std::vector< RefCntAutoPtr<IDeviceObject> > pResources; + SHADER_VARIABLE_TYPE VarType; + }; + + struct UniformBufferInfo : GLProgramVariableBase + { + UniformBufferInfo(const Char* _Name, size_t _ArraySize, SHADER_VARIABLE_TYPE _VarType, GLint _Index) : + GLProgramVariableBase(_Name, _ArraySize, _VarType), + Index(_Index) + {} + + GLuint Index; + }; + std::vector<UniformBufferInfo>& GetUniformBlocks(){ return m_UniformBlocks; } + + struct SamplerInfo : GLProgramVariableBase + { + SamplerInfo(const Char* _Name, size_t _ArraySize, SHADER_VARIABLE_TYPE _VarType, GLint _Location, GLenum _Type, class SamplerGLImpl *_pStaticSampler) : + GLProgramVariableBase(_Name, _ArraySize, _VarType), + Location(_Location), + Type(_Type), + pStaticSampler(_pStaticSampler) + {} + GLint Location; + GLenum Type; + RefCntAutoPtr<class SamplerGLImpl> pStaticSampler; + }; + std::vector<SamplerInfo>& GetSamplers(){ return m_Samplers; } + + struct ImageInfo : GLProgramVariableBase + { + ImageInfo(const Char* _Name, size_t _ArraySize, SHADER_VARIABLE_TYPE _VarType, GLint _BindingPoint, GLenum _Type) : + GLProgramVariableBase(_Name, _ArraySize, _VarType), + BindingPoint(_BindingPoint), + Type(_Type) + {} + + GLint BindingPoint; + GLenum Type; + }; + std::vector<ImageInfo>& GetImages(){ return m_Images; } + + struct StorageBlockInfo : GLProgramVariableBase + { + StorageBlockInfo(const Char* _Name, size_t _ArraySize, SHADER_VARIABLE_TYPE _VarType, GLint _Binding) : + GLProgramVariableBase(_Name, _ArraySize, _VarType), + Binding(_Binding) + {} + + GLint Binding; + }; + std::vector<StorageBlockInfo>& GetStorageBlocks(){ return m_StorageBlocks; } + + + struct CGLShaderVariable : ShaderVariableBase + { + CGLShaderVariable( IObject &Owner, GLProgramResources::GLProgramVariableBase &ProgVar ) : + ShaderVariableBase( Owner ), + ProgramVar(ProgVar) + {} + + virtual void Set( IDeviceObject *pObject )override final + { + ProgramVar.pResources[0] = pObject; + } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + for(Uint32 i=0; i < NumElements; ++i) + ProgramVar.pResources[FirstElement + i] = ppObjects[i]; + } + + private: + GLProgramVariableBase &ProgramVar; + }; + + void BindResources(IResourceMapping *pResourceMapping, Uint32 Flags); + +#ifdef VERIFY_RESOURCE_BINDINGS + void dbgVerifyResourceBindings(); +#endif + + IShaderVariable* GetShaderVariable( const Char* Name ); + + const std::unordered_map<HashMapStringKey, CGLShaderVariable>& GetVariables(){return m_VariableHash;} + + private: + const GLProgramResources& operator = (const GLProgramResources& Program); + + void InitVariables(IObject &Owner); + + std::vector<UniformBufferInfo> m_UniformBlocks; + std::vector< SamplerInfo > m_Samplers; + std::vector< ImageInfo > m_Images; + std::vector< StorageBlockInfo > m_StorageBlocks; + + /// Hash map to look up shader variables by name. + std::unordered_map<HashMapStringKey, CGLShaderVariable> m_VariableHash; + // When adding new member DO NOT FORGET TO UPDATE GLProgramResources( GLProgramResources&& ProgramResources )!!! + }; +} diff --git a/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions.h b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions.h index b83c29b2..cb2fde6f 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions_inc.h b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions_inc.h index bacbdb29..8bde9043 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions_inc.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLSLDefinitions_inc.h @@ -1,4 +1,4 @@ -"/* Copyright 2015 Egor Yusov\n" +"/* Copyright 2015-2016 Egor Yusov\n" " * \n" " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" " * you may not use this file except in compliance with the License.\n" diff --git a/Graphics/GraphicsEngineOpenGL/include/GLStubs.h b/Graphics/GraphicsEngineOpenGL/include/GLStubs.h index f5308af8..8d38827e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLStubs.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLStubs.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -183,6 +183,14 @@ # define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 #endif +#ifndef GL_TEXTURE_CUBE_MAP_ARRAY +# define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#endif + +#ifndef GL_TEXTURE_BINDING_CUBE_MAP_ARRAY +# define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#endif + #ifndef GL_TEXTURE_BUFFER # define GL_TEXTURE_BUFFER 0x8C2A #endif diff --git a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h index a5b381f8..929251fa 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,31 +26,64 @@ namespace Diligent { +static const GLenum PrimTopologyToGLTopologyMap[] = +{ + 0, //PRIMITIVE_TOPOLOGY_UNDEFINED = 0 + GL_TRIANGLES, //PRIMITIVE_TOPOLOGY_TRIANGLE_LIST + GL_TRIANGLE_STRIP, //PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + GL_POINTS, //PRIMITIVE_TOPOLOGY_POINT_LIST + GL_LINES //PRIMITIVE_TOPOLOGY_LINE_LIST +}; + inline GLenum PrimitiveTopologyToGLTopology(PRIMITIVE_TOPOLOGY PrimTopology) { + VERIFY_EXPR(PrimTopology < _countof(PrimTopologyToGLTopologyMap)); + auto GLTopology = PrimTopologyToGLTopologyMap[PrimTopology]; +#ifdef _DEBUG switch(PrimTopology) { - case PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return GL_TRIANGLES; break; - case PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP; break; - case PRIMITIVE_TOPOLOGY_POINT_LIST: return GL_POINTS; break; - case PRIMITIVE_TOPOLOGY_LINE_LIST: return GL_LINES; break; - default: return 0; + case PRIMITIVE_TOPOLOGY_UNDEFINED: VERIFY_EXPR(GLTopology == 0); break; + case PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: VERIFY_EXPR(GLTopology == GL_TRIANGLES); break; + case PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: VERIFY_EXPR(GLTopology == GL_TRIANGLE_STRIP); break; + case PRIMITIVE_TOPOLOGY_POINT_LIST: VERIFY_EXPR(GLTopology == GL_POINTS); break; + case PRIMITIVE_TOPOLOGY_LINE_LIST: VERIFY_EXPR(GLTopology == GL_LINES); break; + default: UNEXPECTED("Unexpected primitive topology"); } +#endif + return GLTopology; } +static const GLenum TypeToGLTypeMap[] = +{ + 0, //VT_UNDEFINED = 0 + GL_BYTE, //VT_INT8 + GL_SHORT, //VT_INT16 + GL_INT, //VT_INT32 + GL_UNSIGNED_BYTE, //VT_UINT8 + GL_UNSIGNED_SHORT, //VT_UINT16 + GL_UNSIGNED_INT, //VT_UINT32 + 0, //VT_FLOAT16 + GL_FLOAT //VT_FLOAT32 +}; + inline GLenum TypeToGLType(VALUE_TYPE Value) { + VERIFY_EXPR(Value < _countof(TypeToGLTypeMap)); + auto GLType = TypeToGLTypeMap[Value]; +#ifdef _DEBUG switch(Value) { - case VT_INT8: return GL_BYTE; break; - case VT_INT16: return GL_SHORT; break; - case VT_INT32: return GL_INT; break; - case VT_UINT8: return GL_UNSIGNED_BYTE; break; - case VT_UINT16: return GL_UNSIGNED_SHORT; break; - case VT_UINT32: return GL_UNSIGNED_INT; break; - case VT_FLOAT32: return GL_FLOAT; break; - default: return 0; + case VT_INT8: VERIFY_EXPR(GLType == GL_BYTE); break; + case VT_INT16: VERIFY_EXPR(GLType == GL_SHORT); break; + case VT_INT32: VERIFY_EXPR(GLType == GL_INT); break; + case VT_UINT8: VERIFY_EXPR(GLType == GL_UNSIGNED_BYTE); break; + case VT_UINT16: VERIFY_EXPR(GLType == GL_UNSIGNED_SHORT); break; + case VT_UINT32: VERIFY_EXPR(GLType == GL_UNSIGNED_INT); break; + case VT_FLOAT32: VERIFY_EXPR(GLType == GL_FLOAT); break; + default: UNEXPECTED("Unexpected value type"); } +#endif + return GLType; } inline GLenum UsageToGLUsage(USAGE Usage) @@ -148,7 +181,7 @@ inline GLenum CompareFuncToGLCompareFunc(COMPARISON_FUNCTION Func) { switch(Func) { - case COMPARISON_FUNC_UNKNOW: UNEXPECTED( "Comparison function is not specified" ); return GL_ALWAYS; + case COMPARISON_FUNC_UNKNOWN: UNEXPECTED( "Comparison function is not specified" ); return GL_ALWAYS; case COMPARISON_FUNC_NEVER: return GL_NEVER; case COMPARISON_FUNC_LESS: return GL_LESS; case COMPARISON_FUNC_EQUAL: return GL_EQUAL; diff --git a/Graphics/GraphicsEngineOpenGL/include/HLSL2GLSLConverter.h b/Graphics/GraphicsEngineOpenGL/include/HLSL2GLSLConverter.h index 6877cc47..5e5429fe 100644 --- a/Graphics/GraphicsEngineOpenGL/include/HLSL2GLSLConverter.h +++ b/Graphics/GraphicsEngineOpenGL/include/HLSL2GLSLConverter.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/include/BlendStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h index 62874e60..507334bf 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BlendStateGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,25 +23,40 @@ #pragma once -#include "BaseInterfacesGL.h" -#include "BlendStateGL.h" -#include "BlendStateBase.h" +#include "PipelineStateGL.h" +#include "PipelineStateBase.h" #include "RenderDevice.h" +#include "GLProgram.h" +#include "GLObjectWrapper.h" namespace Diligent { -/// Implementation of the Diligent::IBlendStateGL interface -class BlendStateGLImpl : public BlendStateBase<IBlendStateGL, IGLDeviceBaseInterface> +class FixedBlockMemoryAllocator; + +/// Implementation of the Diligent::IPipelineStateGL interface +class PipelineStateGLImpl : public PipelineStateBase<IPipelineStateGL, IGLDeviceBaseInterface, FixedBlockMemoryAllocator> { public: - typedef BlendStateBase<IBlendStateGL, IGLDeviceBaseInterface> TBlendStateBase; - - BlendStateGLImpl(class IRenderDevice *pDeviceGL, const BlendStateDesc& BlendStateDesc, bool bIsDeviceInternal = false); - ~BlendStateGLImpl(); + typedef PipelineStateBase<IPipelineStateGL, IGLDeviceBaseInterface, FixedBlockMemoryAllocator> TPipelineStateBase; + PipelineStateGLImpl(FixedBlockMemoryAllocator &PSOAllocator, class RenderDeviceGLImpl *pDeviceGL, const PipelineStateDesc& PipelineDesc, bool IsDeviceInternal = false); + ~PipelineStateGLImpl(); + /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override; + + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override; + + GLProgram &GetGLProgram(){return m_GLProgram;} + GLObjectWrappers::GLPipelineObj &GetGLProgramPipeline(){return m_GLProgPipeline;} +private: + void LinkGLProgram(bool bIsProgramPipelineSupported); + + GLProgram m_GLProgram; + GLObjectWrappers::GLPipelineObj m_GLProgPipeline; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/ProgramPipelineCache.h b/Graphics/GraphicsEngineOpenGL/include/ProgramPipelineCache.h deleted file mode 100644 index a7b62f49..00000000 --- a/Graphics/GraphicsEngineOpenGL/include/ProgramPipelineCache.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "RenderDevice.h" -#include "HashUtils.h" -#include "GLProgram.h" - -namespace Diligent -{ - -class ProgramPipelineCache -{ -public: - ProgramPipelineCache( class RenderDeviceGLImpl *pRenderDeviceOpenGL ); - ~ProgramPipelineCache(); - - struct CacheElementType - { - GLObjectWrappers::GLPipelineObj Pipeline; - GLProgram Program; - CacheElementType() : - Pipeline( false ), - Program( false ) - {} - CacheElementType( CacheElementType &&Elem ) : - Pipeline( std::move( Elem.Pipeline ) ), - Program( std::move( Elem.Program ) ) - {} - }; - - CacheElementType &GetProgramPipeline( RefCntAutoPtr<IShader> *ppShaders, Uint32 NumShadersToSet ); - void OnDestroyShader(IShader *pShader); - -private: - friend class RenderDeviceGLImpl; - ThreadingTools::LockFlag m_CacheLockFlag; - - // This structure is used as the key to find VAO - struct PipelineCacheKey - { - IShader *pVS; - IShader *pGS; - IShader *pPS; - IShader *pDS; - IShader *pHS; - IShader *pCS; - - bool operator == (const PipelineCacheKey &Key)const - { - return pVS == Key.pVS && - pGS == Key.pGS && - pPS == Key.pPS && - pDS == Key.pDS && - pHS == Key.pHS && - pCS == Key.pCS; - } - }; - - struct PipelineCacheHashFunc - { - std::size_t operator() ( const PipelineCacheKey& Key )const - { - std::size_t Seed = 0; - if(Key.pVS)HashCombine(Seed, Key.pVS); - if(Key.pGS)HashCombine(Seed, Key.pGS); - if(Key.pPS)HashCombine(Seed, Key.pPS); - if(Key.pDS)HashCombine(Seed, Key.pDS); - if(Key.pHS)HashCombine(Seed, Key.pHS); - if(Key.pCS)HashCombine(Seed, Key.pCS); - return Seed; - } - }; - - bool m_bIsProgramPipelineSupported; - - std::unordered_map<PipelineCacheKey, CacheElementType, PipelineCacheHashFunc> m_Cache; - std::unordered_multimap<IShader*, PipelineCacheKey> m_ShaderToKey; -}; - -} diff --git a/Graphics/GraphicsEngineOpenGL/include/RasterizerStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/RasterizerStateGLImpl.h deleted file mode 100644 index 6e28893a..00000000 --- a/Graphics/GraphicsEngineOpenGL/include/RasterizerStateGLImpl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "BaseInterfacesGL.h" -#include "RasterizerStateGL.h" -#include "RasterizerStateBase.h" -#include "RenderDevice.h" - -namespace Diligent -{ - -/// Implementation of the Diligent::IRasterizerStateGL interface -class RasterizerStateGLImpl : public RasterizerStateBase<IRasterizerStateGL, IGLDeviceBaseInterface> -{ -public: - typedef RasterizerStateBase<IRasterizerStateGL, IGLDeviceBaseInterface> TRasterizerStateBase; - - RasterizerStateGLImpl(class IRenderDevice *pDeviceGL, const RasterizerStateDesc& RasterizerStateDesc, bool bIsDeviceInternal = false ); - ~RasterizerStateGLImpl(); - - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); -}; - -} diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h index eddcf0b6..0a054e24 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLESImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ namespace Diligent class RenderDeviceGLESImpl : public RenderDeviceGLImpl { public: - RenderDeviceGLESImpl( const ContextInitInfo &InitInfo ); + RenderDeviceGLESImpl( IMemoryAllocator &RawMemAllocator, const ContextInitInfo &InitInfo ); virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h index 411df027..2ae32545 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ #include "RenderDeviceBase.h" -#ifdef _WINDOWS +#ifdef PLATFORM_WIN32 #include "GLContextWindows.h" #endif @@ -34,7 +34,6 @@ #endif #include "VAOCache.h" -#include "ProgramPipelineCache.h" #include "BaseInterfacesGL.h" #include "FBOCache.h" #include "TexRegionRender.h" @@ -64,16 +63,13 @@ class RenderDeviceGLImpl : public RenderDeviceBase<IGLDeviceBaseInterface> public: typedef RenderDeviceBase<IGLDeviceBaseInterface> TRenderDeviceBase; - RenderDeviceGLImpl( const ContextInitInfo &InitInfo ); + RenderDeviceGLImpl( IMemoryAllocator &RawMemAllocator, const ContextInitInfo &InitInfo ); ~RenderDeviceGLImpl(); virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBufferLayout, bool bIsDeviceInternal); virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData &BuffData, IBuffer **ppBufferLayout)override; - void CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc, bool bIsDeviceInternal ); - virtual void CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc )override; - void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader, bool bIsDeviceInternal ); virtual void CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader)override; @@ -83,21 +79,15 @@ public: void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler, bool bIsDeviceInternal); virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler)override; - void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState, bool bIsDeviceInternal ); - virtual void CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState )override; - - void CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState, bool bIsDeviceInternal); - virtual void CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState )override; - - void CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState, bool bIsDeviceInternal ); - virtual void CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState )override; - + void CreatePipelineState( const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState, bool bIsDeviceInternal); + virtual void CreatePipelineState( const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState )override; + const GPUInfo& GetGPUInfo(){ return m_GPUInfo; } protected: friend class DeviceContextGLImpl; friend class TextureBaseGL; - friend class VertexDescGLImpl; + friend class PipelineStateGLImpl; friend class ShaderGLImpl; friend class BufferGLImpl; friend class TextureViewGLImpl; @@ -110,7 +100,6 @@ protected: VAOCache m_VAOCache; FBOCache m_FBOCache; - ProgramPipelineCache m_PipelineCache; GPUInfo m_GPUInfo; diff --git a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h index 20b9f505..dfddb3f7 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,13 +32,14 @@ namespace Diligent { +class FixedBlockMemoryAllocator; /// Implementation of the Diligent::ISamplerGL interface -class SamplerGLImpl : public SamplerBase<ISamplerGL, IGLDeviceBaseInterface> +class SamplerGLImpl : public SamplerBase<ISamplerGL, IGLDeviceBaseInterface, FixedBlockMemoryAllocator> { public: - typedef SamplerBase<ISamplerGL, IGLDeviceBaseInterface> TSamplerBase; + typedef SamplerBase<ISamplerGL, IGLDeviceBaseInterface, FixedBlockMemoryAllocator> TSamplerBase; - SamplerGLImpl( class RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal = false ); + SamplerGLImpl( FixedBlockMemoryAllocator &SamplerObjAllocator, class RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal = false ); ~SamplerGLImpl(); virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h index b4f20f21..cb17a1ce 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,11 +29,12 @@ #include "RenderDevice.h" #include "GLObjectWrapper.h" #include "GLProgram.h" -#include "HashUtils.h" namespace Diligent { - + +class FixedBlockMemoryAllocator; + inline GLenum GetGLShaderType(SHADER_TYPE ShaderType) { switch(ShaderType) @@ -63,12 +64,12 @@ inline GLenum ShaderTypeToGLShaderBit(SHADER_TYPE ShaderType) } /// Implementation of the Diligent::IShaderGL interface -class ShaderGLImpl : public ShaderBase<IShaderGL, IGLDeviceBaseInterface> +class ShaderGLImpl : public ShaderBase<IShaderGL, IGLDeviceBaseInterface, FixedBlockMemoryAllocator> { public: - typedef ShaderBase<IShaderGL, IGLDeviceBaseInterface> TShaderBase; + typedef ShaderBase<IShaderGL, IGLDeviceBaseInterface, FixedBlockMemoryAllocator> TShaderBase; - ShaderGLImpl( class RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal = false ); + ShaderGLImpl( FixedBlockMemoryAllocator& ShaderObjAllocator, class RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal = false ); ~ShaderGLImpl(); virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override; @@ -77,29 +78,15 @@ public: virtual IShaderVariable* GetShaderVariable( const Char* Name )override; + GLProgram& GetGlProgram(){return m_GlProgObj;} + private: - struct CGLShaderVariable : ShaderVariableBase - { - CGLShaderVariable( ShaderGLImpl *pShader, GLProgram::GLProgramVariableBase &ProgVar ) : - ShaderVariableBase( pShader ), - ProgramVar(ProgVar) - {} - - virtual void Set( IDeviceObject *pObject )override - { - ProgramVar.pResource = pObject; - } - private: - GLProgram::GLProgramVariableBase &ProgramVar; - }; - - friend class ProgramPipelineCache; + + friend class PipelineStateGLImpl; friend class DeviceContextGLImpl; + GLProgram m_GlProgObj; // Used if program pipeline supported GLObjectWrappers::GLShaderObj m_GLShaderObj; // Used if program pipelines are not supported - - /// Hash map to look up shader variables by name. - std::unordered_map<Diligent::HashMapStringKey, CGLShaderVariable> m_VariableHash; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h new file mode 100644 index 00000000..1ba6ec43 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h @@ -0,0 +1,61 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceBindingGLImpl class + +#include "ShaderResourceBindingGL.h" +#include "RenderDeviceGL.h" +#include "ShaderResourceBindingBase.h" +#include "GLProgramResources.h" +#include "ShaderBase.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::IShaderResourceBindingGL interface +class ShaderResourceBindingGLImpl : public ShaderResourceBindingBase<IShaderResourceBindingGL, FixedBlockMemoryAllocator> +{ +public: + typedef ShaderResourceBindingBase<IShaderResourceBindingGL, FixedBlockMemoryAllocator> TBase; + ShaderResourceBindingGLImpl(FixedBlockMemoryAllocator& SRBAllocator, class PipelineStateGLImpl *pPSO); + ~ShaderResourceBindingGLImpl(); + + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags)override; + + virtual IShaderVariable *GetVariable(SHADER_TYPE ShaderType, const char *Name)override; + + GLProgramResources &GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl *pdbgPSO); + +private: + GLProgramResources m_DynamicProgResources[6]; + DummyShaderVariable m_DummyShaderVar; ///< Dummy shader variable + RefCntWeakPtr<PipelineStateGLImpl> m_wpPSO; +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h index 582a80d3..32c678e4 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,15 +29,17 @@ namespace Diligent { +class IMemoryAllocator; /// Implementation of the Diligent::ISwapChainGL interface -class SwapChainGLImpl : public SwapChainBase<ISwapChainGL> +class SwapChainGLImpl : public SwapChainBase<ISwapChainGL, IMemoryAllocator> { public: - typedef SwapChainBase<ISwapChainGL> TSwapChainBase; + typedef SwapChainBase<ISwapChainGL, IMemoryAllocator> TSwapChainBase; - SwapChainGLImpl(const SwapChainDesc& SwapChainDesc, - class RenderDeviceGLImpl* pRenderDeviceGL, - class DeviceContextGLImpl* pImmediateContextGL); + SwapChainGLImpl(IMemoryAllocator &Allocator, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceGLImpl* pRenderDeviceGL, + class DeviceContextGLImpl* pImmediateContextGL); ~SwapChainGLImpl(); virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); diff --git a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h index a16ea719..93534c92 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h +++ b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public: void RestoreStates(class DeviceContextGLImpl *pCtxGL); void Render(class DeviceContextGLImpl *pCtxGL, ITextureView *pSrcSRV, - TEXTURE_TYPE TexType, + RESOURCE_DIMENSION TexType, TEXTURE_FORMAT TexFormat, Int32 DstToSrcXOffset, Int32 DstToSrcYOffset, @@ -44,22 +44,16 @@ public: private: Diligent::RefCntAutoPtr<IShader> m_pVertexShader; - Diligent::RefCntAutoPtr<IShader> m_pFragmentShaders[TEXTURE_TYPE_NUM_TYPES * 3]; + Diligent::RefCntAutoPtr<IShader> m_pFragmentShaders[RESOURCE_DIM_NUM_DIMENSIONS * 3]; Diligent::RefCntAutoPtr<IBuffer> m_pConstantBuffer; - Diligent::RefCntAutoPtr<IRasterizerState> m_pSolidFillNoCullRS; - Diligent::RefCntAutoPtr<IDepthStencilState> m_pDisableDetphDS; - Diligent::RefCntAutoPtr<IBlendState> m_pDefaultBS; + Diligent::RefCntAutoPtr<IPipelineState> m_pPSO[RESOURCE_DIM_NUM_DIMENSIONS * 3]; - Diligent::RefCntAutoPtr<IRasterizerState> m_pOrigRS; - Diligent::RefCntAutoPtr<IDepthStencilState> m_pOrigDS; + Diligent::RefCntAutoPtr<IPipelineState> m_pOrigPSO; Uint32 m_OrigStencilRef; - Diligent::RefCntAutoPtr<IBlendState> m_pOrigBS; float m_OrigBlendFactors[4]; - Uint32 m_OrigSamplesBlendMask; Uint32 m_NumRenderTargets; ITextureView *m_pOrigRTVs[MaxRenderTargets]; Diligent::RefCntAutoPtr<ITextureView> m_pOrigDSV; - std::vector<IShader*> m_pOrigShaders; std::vector<Viewport> m_OrigViewports; }; diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h index 707d91c3..36ca0529 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture1DArray_OGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,11 +31,13 @@ namespace Diligent class Texture1DArray_OGL : public TextureBaseGL { public: - Texture1DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, - class DeviceContextGLImpl *pDeviceContext, - const TextureDesc& BuffDesc, - const TextureData &InitData = TextureData(), - bool bIsDeviceInternal = false); + Texture1DArray_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); ~Texture1DArray_OGL(); virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h index 33b9a780..022e5b40 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture1D_OGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,11 +31,13 @@ namespace Diligent class Texture1D_OGL : public TextureBaseGL { public: - Texture1D_OGL( class RenderDeviceGLImpl *pDeviceGL, - class DeviceContextGLImpl *pDeviceContext, - const TextureDesc& BuffDesc, - const TextureData &InitData = TextureData(), - bool bIsDeviceInternal = false); + Texture1D_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); ~Texture1D_OGL(); virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h index 9c7c896f..7dbd6518 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture2DArray_OGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,9 @@ namespace Diligent class Texture2DArray_OGL : public TextureBaseGL { public: - Texture2DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, + Texture2DArray_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, class DeviceContextGLImpl *pDeviceContext, const TextureDesc& BuffDesc, const TextureData &InitData = TextureData(), diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h index ab9225b9..67b4f741 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,11 +31,13 @@ namespace Diligent class Texture2D_OGL : public TextureBaseGL { public: - Texture2D_OGL( class RenderDeviceGLImpl *pDeviceGL, - class DeviceContextGLImpl *pDeviceContext, - const TextureDesc& BuffDesc, - const TextureData &InitData = TextureData(), - bool bIsDeviceInternal = false); + Texture2D_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); ~Texture2D_OGL(); virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h index 83e9a257..734830ab 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture3D_OGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,11 +31,13 @@ namespace Diligent class Texture3D_OGL : public TextureBaseGL { public: - Texture3D_OGL( class RenderDeviceGLImpl *pDeviceGL, - class DeviceContextGLImpl *pDeviceContext, - const TextureDesc& BuffDesc, - const TextureData &InitData = TextureData(), - bool bIsDeviceInternal = false ); + Texture3D_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false ); ~Texture3D_OGL(); virtual void UpdateData(IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData); diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h index 0cc49ac1..a2af9c09 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,25 +31,34 @@ #include "TextureViewGLImpl.h" #include "AsyncWritableResource.h" + namespace Diligent { +class FixedBlockMemoryAllocator; + /// Base implementation of the Diligent::ITextureGL interface -class TextureBaseGL : public TextureBase<ITextureGL, TextureViewGLImpl>, public AsyncWritableResource +class TextureBaseGL : public TextureBase<ITextureGL, TextureViewGLImpl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator>, public AsyncWritableResource { public: - typedef TextureBase<ITextureGL, TextureViewGLImpl> TTextureBase; + typedef TextureBase<ITextureGL, TextureViewGLImpl, FixedBlockMemoryAllocator, FixedBlockMemoryAllocator> TTextureBase; - TextureBaseGL(class RenderDeviceGLImpl *pDeviceGL, const TextureDesc& BuffDesc, const TextureData &InitData = TextureData(), bool bIsDeviceInternal = false); + TextureBaseGL(FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + const TextureDesc &TexDesc, + GLenum BindTarget, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); ~TextureBaseGL(); virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; - virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData )override; + virtual void UpdateData( class GLContextState &CtxState, IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); //virtual void CopyData(CTexture *pSrcTexture, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size); virtual void Map( IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData )override; - virtual void Unmap( IDeviceContext *pContext )override; + virtual void Unmap( IDeviceContext *pContext, MAP_TYPE MapType )override; const GLObjectWrappers::GLTextureObj& GetGLHandle()const{ return m_GlTexture; } GLenum GetBindTarget()const{return m_BindTarget;} @@ -75,8 +84,8 @@ protected: void SetDefaultGLParameters(); GLObjectWrappers::GLTextureObj m_GlTexture; - GLenum m_BindTarget; - GLenum m_GLTexFormat; + const GLenum m_BindTarget; + const GLenum m_GLTexFormat; //Uint32 m_uiMapTarget; }; diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h new file mode 100644 index 00000000..7b2ff823 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h @@ -0,0 +1,50 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TextureBaseGL.h" + +namespace Diligent +{ + +class TextureCubeArray_OGL : public TextureBaseGL +{ +public: + TextureCubeArray_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false ); + ~TextureCubeArray_OGL(); + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); + virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint ); + +private: + +}; + +} diff --git a/Graphics/GraphicsEngineOpenGL/include/VertexDescGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/TextureCube_OGL.h index 1953e044..a5ff2917 100644 --- a/Graphics/GraphicsEngineOpenGL/include/VertexDescGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureCube_OGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,28 +23,28 @@ #pragma once -#include "BaseInterfacesGL.h" -#include "VertexDescriptionGL.h" -#include "VertexDescriptionBase.h" -#include "BaseInterfacesGL.h" -#include "RenderDevice.h" +#include "TextureBaseGL.h" namespace Diligent { -/// Implementation of the Diligent::IVertexDescriptionGL interface -class VertexDescGLImpl : public VertexDescriptionBase<IVertexDescriptionGL> +class TextureCube_OGL : public TextureBaseGL { public: - typedef VertexDescriptionBase<IVertexDescriptionGL> TVertexDescriptionBase; - - VertexDescGLImpl( class RenderDeviceGLImpl *pDeviceGL, const LayoutDesc &LayoutDesc, bool bIsDeviceInternal = false ); - ~VertexDescGLImpl(); - - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + TextureCube_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false); + ~TextureCube_OGL(); + + virtual void UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ); + virtual void AttachToFramebuffer( const struct TextureViewDesc& ViewDesc, GLenum AttachmentPoint ); private: - + }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h index 4284eaaf..f2634e0e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,13 +32,15 @@ namespace Diligent { +class FixedBlockMemoryAllocator; /// Implementation of the Diligent::ITextureViewGL interface -class TextureViewGLImpl : public TextureViewBase<ITextureViewGL> +class TextureViewGLImpl : public TextureViewBase<ITextureViewGL, FixedBlockMemoryAllocator> { public: - typedef TextureViewBase<ITextureViewGL> TTextureViewBase; + typedef TextureViewBase<ITextureViewGL, FixedBlockMemoryAllocator> TTextureViewBase; - TextureViewGLImpl( class IRenderDevice *pDevice, + TextureViewGLImpl( FixedBlockMemoryAllocator &TexViewObjAllocator, + class IRenderDevice *pDevice, const struct TextureViewDesc& ViewDesc, class TextureBaseGL *pTexture, bool bCreateGLViewTex, diff --git a/Graphics/GraphicsEngineOpenGL/include/VAOCache.h b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h index 2604fbcc..85e69a5f 100644 --- a/Graphics/GraphicsEngineOpenGL/include/VAOCache.h +++ b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ #include "GraphicsTypes.h" #include "Buffer.h" -#include "VertexDescription.h" +#include "InputLayout.h" #include "LockHelper.h" #include "HashUtils.h" #include "DeviceContextBase.h" @@ -40,12 +40,13 @@ public: VAOCache(); ~VAOCache(); - const GLObjectWrappers::GLVertexArrayObj& GetVAO( IVertexDescription &VertexDesc, + const GLObjectWrappers::GLVertexArrayObj& GetVAO( IPipelineState *pPSO, IBuffer *pIndexBuffer, - vector< VertexStreamInfo > &VertexStreams, + VertexStreamInfo VertexStreams[], + Uint32 NumVertexStreams, class GLContextState &GLContextState); void OnDestroyBuffer(IBuffer *pBuffer); - void OnDestroyVertexDesc(IVertexDescription *pVertexDesc); + void OnDestroyPSO(IPipelineState *pPSO); private: // This structure is used as the key to find VAO @@ -53,7 +54,7 @@ private: { // Note that the the pointers are used for ordering only // They are not used to access the objects - IVertexDescription* pVertexDesc; + IPipelineState* pPSO; IBuffer* pIndexBuffer; struct StreamAttribs { @@ -64,7 +65,7 @@ private: bool operator == (const VAOCacheKey &Key)const { - return (pVertexDesc == Key.pVertexDesc) && + return (pPSO == Key.pPSO) && (pIndexBuffer == Key.pIndexBuffer) && (memcmp(Streams, Key.Streams, sizeof(Streams)) == 0); } @@ -75,7 +76,7 @@ private: std::size_t operator() ( const VAOCacheKey& Key )const { std::size_t Seed = 0; - HashCombine(Seed, Key.pVertexDesc); + HashCombine(Seed, Key.pPSO); if(Key.pIndexBuffer) HashCombine(Seed, Key.pIndexBuffer); for(int iStream = 0; iStream < _countof(Key.Streams); ++iStream ) @@ -96,7 +97,7 @@ private: friend class RenderDeviceGLImpl; ThreadingTools::LockFlag m_CacheLockFlag; std::unordered_map<VAOCacheKey, GLObjectWrappers::GLVertexArrayObj, VAOCacheKeyHashFunc> m_Cache; - std::unordered_multimap<IVertexDescription*, VAOCacheKey> m_VertexDescToKey; + std::unordered_multimap<IPipelineState*, VAOCacheKey> m_PSOToKey; std::unordered_multimap<IBuffer*, VAOCacheKey> m_BuffToKey; }; diff --git a/Graphics/GraphicsEngineOpenGL/include/pch.h b/Graphics/GraphicsEngineOpenGL/include/pch.h index e4530e99..f1fcf923 100644 --- a/Graphics/GraphicsEngineOpenGL/include/pch.h +++ b/Graphics/GraphicsEngineOpenGL/include/pch.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ #include <algorithm> // Must be defined to use static version of glew -#ifdef _WINDOWS +#ifdef PLATFORM_WIN32 #define GLEW_STATIC #include "glew.h" // Glew includes <windows.h> diff --git a/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h b/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h index 01c0996c..90b55f4b 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/BaseInterfacesGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ } #endif -#ifdef _WINDOWS +#ifdef PLATFORM_WIN32 #include "RenderDeviceGL.h" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h b/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h index 33ed7c2b..4d675853 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/BufferGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h b/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h index 3124a545..7c1d7380 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/BufferViewGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h index 12f6f01a..111f5cae 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/PipelineStateGL.h index 685dff08..0d5601fa 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/PipelineStateGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,22 +24,22 @@ #pragma once /// \file -/// Definition of the Diligent::IRasterizerStateGL interface +/// Definition of the Diligent::IPipelineStateGL interface -#include "RasterizerState.h" +#include "PipelineState.h" namespace Diligent { -// {B546E86A-E68D-4FC5-A7DC-04F8151941D2} -static const Diligent::INTERFACE_ID IID_RasterizerStateGL = -{ 0xb546e86a, 0xe68d, 0x4fc5, { 0xa7, 0xdc, 0x4, 0xf8, 0x15, 0x19, 0x41, 0xd2 } }; +// {80666BE3-318A-4403-AEE1-6E61A5B7A0F9} +static const Diligent::INTERFACE_ID IID_PipelineStateGL = +{ 0x80666be3, 0x318a, 0x4403, { 0xae, 0xe1, 0x6e, 0x61, 0xa5, 0xb7, 0xa0, 0xf9 } }; -/// Interface to the rasterizer state object implemented in OpenGL -class IRasterizerStateGL : public Diligent::IRasterizerState -{ -public: +/// Interface to the PipelineState object implemented in OpenGL +class IPipelineStateGL : public Diligent::IPipelineState +{ + }; } diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h index 59654ce2..698607a9 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,13 @@ #pragma once +/// \file +/// Declaration of functions that create OpenGL-based engine implementation + #include "RenderDevice.h" #include "SwapChain.h" -#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_WINDOWS_STORE) +#if defined(PLATFORM_WIN32) || defined(PLATFORM_UNIVERSAL_WINDOWS) # define API_QUALIFIER @@ -49,12 +52,12 @@ extern "C" { -#if defined(ENGINE_DLL) && (defined(PLATFORM_WINDOWS) || defined(PLATFORM_WINDOWS_STORE)) +#if defined(ENGINE_DLL) && (defined(PLATFORM_WIN32) || defined(PLATFORM_UNIVERSAL_WINDOWS)) typedef void (*CreateDeviceAndSwapChainGLType)( const Diligent::EngineCreationAttribs& CreationAttribs, Diligent::IRenderDevice **ppDevice, Diligent::IDeviceContext **ppImmediateContext, - const Diligent::SwapChainDesc& SwapChainDesc, + const Diligent::SwapChainDesc& SCDesc, void *pNativeWndHandle, Diligent::ISwapChain **ppSwapChain ); @@ -99,7 +102,7 @@ extern "C" void CreateDeviceAndSwapChainGL( const Diligent::EngineCreationAttribs& CreationAttribs, Diligent::IRenderDevice **ppDevice, Diligent::IDeviceContext **ppImmediateContext, - const Diligent::SwapChainDesc& SwapChainDesc, + const Diligent::SwapChainDesc& SCDesc, void *pNativeWndHandle, Diligent::ISwapChain **ppSwapChain ); #endif diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h index 6413c7e5..30fcbf62 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h index 97c82301..bdb7792d 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h +++ b/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceGLES.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h b/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h index 572cd2c2..4508b0db 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/SamplerGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h b/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h index c6a5cf40..462ab137 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/ShaderGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/DepthStencilStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/ShaderResourceBindingGL.h index 70f568e5..6ff7da92 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/DepthStencilStateGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/ShaderResourceBindingGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,19 +24,20 @@ #pragma once /// \file -/// Definition of the Diligent::IDepthStencilStateGL interface +/// Definition of the Diligent::IShaderResourceBindingD3D11 interface and related data structures -#include "DepthStencilState.h" +#include "ShaderResourceBinding.h" namespace Diligent { -// {96946955-33A3-46CA-BB83-207332AFB2A9} -static const Diligent::INTERFACE_ID IID_DepthStencilStateGL = -{ 0x96946955, 0x33a3, 0x46ca, { 0xbb, 0x83, 0x20, 0x73, 0x32, 0xaf, 0xb2, 0xa9 } }; +// {41DB0329-B6D2-4470-9A58-D44CF4695FC6} +static const Diligent::INTERFACE_ID IID_ShaderResourceBindingGL = +{ 0x41db0329, 0xb6d2, 0x4470, { 0x9a, 0x58, 0xd4, 0x4c, 0xf4, 0x69, 0x5f, 0xc6 } }; -/// Interface to the depth stencil state object implemented in OpenGL -class IDepthStencilStateGL : public Diligent::IDepthStencilState +/// Shader resource binding interface + +class IShaderResourceBindingGL : public IShaderResourceBinding { public: diff --git a/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h b/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h index 240586ac..260bb375 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/SwapChainGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h b/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h index 7424b4d0..b7c67811 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/TextureGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h b/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h index 15389154..c91eb81f 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/TextureViewGL.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp index 27bce444..1e3639da 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,12 +28,18 @@ #include "GLTypeConversions.h" #include "BufferViewGLImpl.h" #include "DeviceContextGLImpl.h" +#include "EngineMemory.h" namespace Diligent { -BufferGLImpl::BufferGLImpl(class RenderDeviceGLImpl *pDeviceGL, const BufferDesc& BuffDesc, const BufferData &BuffData /*= BufferData()*/, bool IsDeviceInternal /*= false*/) : - TBufferBase( pDeviceGL, BuffDesc, IsDeviceInternal ), +BufferGLImpl::BufferGLImpl(FixedBlockMemoryAllocator &BufferObjMemAllocator, + FixedBlockMemoryAllocator &BuffViewObjMemAllocator, + class RenderDeviceGLImpl *pDeviceGL, + const BufferDesc& BuffDesc, + const BufferData &BuffData /*= BufferData()*/, + bool IsDeviceInternal /*= false*/) : + TBufferBase( BufferObjMemAllocator, BuffViewObjMemAllocator, pDeviceGL, BuffDesc, IsDeviceInternal), m_GlBuffer(true), // Create buffer immediately m_uiMapTarget(0), m_GLUsageHint(0), @@ -245,9 +251,9 @@ void BufferGLImpl :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 MapF glBindBuffer(m_uiMapTarget, 0); } -void BufferGLImpl::Unmap( IDeviceContext *pContext ) +void BufferGLImpl::Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) { - TBufferBase::Unmap(pContext); + TBufferBase::Unmap(pContext, MapType); glBindBuffer(m_uiMapTarget, m_GlBuffer); auto Result = glUnmapBuffer(m_uiMapTarget); @@ -294,9 +300,14 @@ void BufferGLImpl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, class auto ViewDesc = OrigViewDesc; CorrectBufferViewDesc( ViewDesc ); - auto pContext = ValidatedCast<RenderDeviceGLImpl>( GetDevice() )->GetImmediateContext(); + auto *pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); + auto &BuffViewAllocator = pDeviceGLImpl->GetBuffViewObjAllocator(); + VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" ); + + auto pContext = pDeviceGLImpl->GetImmediateContext(); VERIFY( pContext, "Immediate context has been released" ); - *ppView = new BufferViewGLImpl( GetDevice(), pContext, ViewDesc, this, bIsDefaultView ); + + *ppView = NEW(BuffViewAllocator, "BufferViewGLImpl instance", BufferViewGLImpl, pDeviceGLImpl, pContext, ViewDesc, this, bIsDefaultView ); if( !bIsDefaultView ) (*ppView)->AddRef(); diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp index 6c185749..05388c2c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,12 +31,13 @@ namespace Diligent { - BufferViewGLImpl::BufferViewGLImpl( IRenderDevice *pDevice, - IDeviceContext *pContext, - const BufferViewDesc& ViewDesc, - BufferGLImpl* pBuffer, - bool bIsDefaultView) : - TBuffViewBase(pDevice, ViewDesc, pBuffer, bIsDefaultView ), + BufferViewGLImpl::BufferViewGLImpl( FixedBlockMemoryAllocator& BuffViewObjAllocator, + IRenderDevice *pDevice, + IDeviceContext *pContext, + const BufferViewDesc& ViewDesc, + BufferGLImpl* pBuffer, + bool bIsDefaultView) : + TBuffViewBase(BuffViewObjAllocator, pDevice, ViewDesc, pBuffer, bIsDefaultView ), m_GLTexBuffer(false) { if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE ) diff --git a/Graphics/GraphicsEngineOpenGL/src/DLLMain.cpp b/Graphics/GraphicsEngineOpenGL/src/DLLMain.cpp index 373d1570..fff890c0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DLLMain.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DLLMain.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 832a5eb8..bf369989 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,10 +31,8 @@ #include <string> #include "BufferGLImpl.h" -#include "VertexDescGLImpl.h" #include "ShaderGLImpl.h" #include "VAOCache.h" -#include "ProgramPipelineCache.h" #include "Texture1D_OGL.h" #include "Texture1DArray_OGL.h" #include "Texture2D_OGL.h" @@ -43,17 +41,17 @@ #include "SamplerGLImpl.h" #include "GraphicsUtilities.h" #include "BufferViewGLImpl.h" -#include "DSStateGLImpl.h" -#include "BlendStateGLImpl.h" -#include "RasterizerStateGLImpl.h" +#include "PipelineStateGLImpl.h" +#include "ShaderResourceBindingGLImpl.h" using namespace std; namespace Diligent { - DeviceContextGLImpl::DeviceContextGLImpl( class RenderDeviceGLImpl *pDeviceGL ) : - TDeviceContextBase(pDeviceGL), - m_ContextState(pDeviceGL) + DeviceContextGLImpl::DeviceContextGLImpl( IMemoryAllocator &RawMemAllocator, class RenderDeviceGLImpl *pDeviceGL, bool bIsDeferred ) : + TDeviceContextBase(RawMemAllocator, pDeviceGL, bIsDeferred), + m_ContextState(pDeviceGL), + m_CommitedResourcesTentativeBarriers(0) { m_BoundWritableTextures.reserve( 16 ); m_BoundWritableBuffers.reserve( 16 ); @@ -71,122 +69,128 @@ namespace Diligent IMPLEMENT_QUERY_INTERFACE( DeviceContextGLImpl, IID_DeviceContextGL, TDeviceContextBase ) - void DeviceContextGLImpl::SetShaders( IShader **ppShaders, Uint32 NumShadersToSet ) + void DeviceContextGLImpl::SetPipelineState(IPipelineState *pPipelineState) { - TDeviceContextBase::SetShaders( ppShaders, NumShadersToSet ); + TDeviceContextBase::SetPipelineState(pPipelineState); - } - - void DeviceContextGLImpl::BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags ) - { - TDeviceContextBase::BindShaderResources( pResourceMapping, Flags ); - if( m_pDevice->GetDeviceCaps().bSeparableProgramSupported ) + const auto &Desc = pPipelineState->GetDesc(); + auto *pPipelineStateGL = ValidatedCast<PipelineStateGLImpl>(pPipelineState); + if (Desc.IsComputePipeline) { - for( auto it = m_pBoundShaders.begin(); it != m_pBoundShaders.end(); ++it ) - { - (*it)->BindResources( pResourceMapping, Flags ); - } } else { - auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); - auto &PipelineCache = pRenderDeviceGL->m_PipelineCache; - auto &PipelineOrProg = PipelineCache.GetProgramPipeline( m_pBoundShaders.data(), (Uint32)m_pBoundShaders.size() ); - if( PipelineOrProg.Program ) - PipelineOrProg.Program.BindResources( pResourceMapping, Flags ); - } - } + const auto& GraphicsPipeline = Desc.GraphicsPipeline; + // Set rasterizer state + { + const auto &RasterizerDesc = GraphicsPipeline.RasterizerDesc; + + m_ContextState.SetFillMode(RasterizerDesc.FillMode); + m_ContextState.SetCullMode(RasterizerDesc.CullMode); + m_ContextState.SetFrontFace(RasterizerDesc.FrontCounterClockwise); + m_ContextState.SetDepthBias( static_cast<Float32>( RasterizerDesc.DepthBias ), RasterizerDesc.SlopeScaledDepthBias ); + if( RasterizerDesc.DepthBiasClamp != 0 ) + LOG_WARNING_MESSAGE( "Depth bias clamp is not supported on OpenGL" ); + m_ContextState.SetDepthClamp( RasterizerDesc.DepthClipEnable ); + m_ContextState.EnableScissorTest( RasterizerDesc.ScissorEnable ); + if( RasterizerDesc.AntialiasedLineEnable ) + LOG_WARNING_MESSAGE( "Line antialiasing is not supported on OpenGL" ); + } - void DeviceContextGLImpl::SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) - { - TDeviceContextBase::SetVertexBuffers( StartSlot, NumBuffersSet, ppBuffers, pStrides, pOffsets, Flags ); + // Set blend state + { + const auto &BSDsc = GraphicsPipeline.BlendDesc; + m_ContextState.SetBlendState(BSDsc, GraphicsPipeline.SampleMask); + } - } + // Set depth-stencil state + { + const auto &DepthStencilDesc = GraphicsPipeline.DepthStencilDesc; - void DeviceContextGLImpl::ClearState() - { - TDeviceContextBase::ClearState(); + m_ContextState.EnableDepthTest( DepthStencilDesc.DepthEnable ); + m_ContextState.EnableDepthWrites( DepthStencilDesc.DepthWriteEnable ); + m_ContextState.SetDepthFunc( DepthStencilDesc.DepthFunc ); - } + m_ContextState.EnableStencilTest( DepthStencilDesc.StencilEnable ); - void DeviceContextGLImpl::SetVertexDescription( IVertexDescription *pVertexDesc ) - { - TDeviceContextBase::SetVertexDescription( pVertexDesc ); + m_ContextState.SetStencilWriteMask( DepthStencilDesc.StencilWriteMask ); + + { + const auto &FrontFace = DepthStencilDesc.FrontFace; + m_ContextState.SetStencilFunc( GL_FRONT, FrontFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask ); + m_ContextState.SetStencilOp( GL_FRONT, FrontFace.StencilFailOp, FrontFace.StencilDepthFailOp, FrontFace.StencilPassOp ); + } + + { + const auto &BackFace = DepthStencilDesc.BackFace; + m_ContextState.SetStencilFunc( GL_BACK, BackFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask ); + m_ContextState.SetStencilOp( GL_BACK, BackFace.StencilFailOp, BackFace.StencilDepthFailOp, BackFace.StencilPassOp ); + } + } + m_bVAOIsUpToDate = false; + } } - void DeviceContextGLImpl::SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) + void DeviceContextGLImpl::TransitionShaderResources(IPipelineState *pPipelineState, IShaderResourceBinding *pShaderResourceBinding) { - TDeviceContextBase::SetIndexBuffer( pIndexBuffer, ByteOffset ); + } - void DeviceContextGLImpl::SetDepthStencilState( IDepthStencilState *pDepthStencilState, Uint32 StencilRef ) + void DeviceContextGLImpl::CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags) { - if( TDeviceContextBase::SetDepthStencilState( pDepthStencilState, StencilRef ) ) - { - CHECK_DYNAMIC_TYPE( DSStateGLImpl, pDepthStencilState ); - auto *pDSSGL = static_cast<DSStateGLImpl*>(pDepthStencilState); - const auto &DSSDesc = pDepthStencilState->GetDesc(); - - m_ContextState.EnableDepthTest( DSSDesc.DepthEnable ); - m_ContextState.EnableDepthWrites( DSSDesc.DepthWriteEnable ); - m_ContextState.SetDepthFunc( DSSDesc.DepthFunc ); + if(!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, Flags, 0)) + return; - m_ContextState.EnableStencilTest( DSSDesc.StencilEnable ); - m_ContextState.SetStencilWriteMask( DSSDesc.StencilWriteMask ); + if(m_CommitedResourcesTentativeBarriers != 0) + LOG_INFO_MESSAGE("Not all tentative resource barriers have been executed since the last call to CommitShaderResources(). Did you forget to call Draw()/DispatchCompute() ?"); - { - const auto &FrontFace = DSSDesc.FrontFace; - m_ContextState.SetStencilFunc( GL_FRONT, FrontFace.StencilFunc, StencilRef, DSSDesc.StencilReadMask ); - m_ContextState.SetStencilOp( GL_FRONT, FrontFace.StencilFailOp, FrontFace.StencilDepthFailOp, FrontFace.StencilPassOp ); - } + m_CommitedResourcesTentativeBarriers = 0; + BindProgramResources( m_CommitedResourcesTentativeBarriers, pShaderResourceBinding ); + // m_CommitedResourcesTentativeBarriers will contain memory barriers that will be required + // AFTER the actual draw/dispatch command is executed. Before that they have no meaning + } - { - const auto &BackFace = DSSDesc.BackFace; - m_ContextState.SetStencilFunc( GL_BACK, BackFace.StencilFunc, StencilRef, DSSDesc.StencilReadMask ); - m_ContextState.SetStencilOp( GL_BACK, BackFace.StencilFailOp, BackFace.StencilDepthFailOp, BackFace.StencilPassOp ); - } + void DeviceContextGLImpl::SetStencilRef(Uint32 StencilRef) + { + if (TDeviceContextBase::SetStencilRef(StencilRef, 0)) + { + m_ContextState.SetStencilRef(GL_FRONT, StencilRef); + m_ContextState.SetStencilRef(GL_BACK, StencilRef); } } - void DeviceContextGLImpl::SetRasterizerState( IRasterizerState *pRasterizerState ) + void DeviceContextGLImpl::SetBlendFactors(const float* pBlendFactors) { - if( TDeviceContextBase::SetRasterizerState( pRasterizerState ) ) + if (TDeviceContextBase::SetBlendFactors(pBlendFactors, 0)) { - CHECK_DYNAMIC_TYPE( RasterizerStateGLImpl, pRasterizerState ); - auto *pRSGL = static_cast<RasterizerStateGLImpl*>(pRasterizerState); - const auto &RSDesc = pRasterizerState->GetDesc(); - - m_ContextState.SetFillMode(RSDesc.FillMode); - m_ContextState.SetCullMode(RSDesc.CullMode); - m_ContextState.SetFrontFace(RSDesc.FrontCounterClockwise); - m_ContextState.SetDepthBias( static_cast<Float32>( RSDesc.DepthBias ), RSDesc.SlopeScaledDepthBias ); - if( RSDesc.DepthBiasClamp != 0 ) - LOG_WARNING_MESSAGE( "Depth bias clamp is not supported on OpenGL" ); - m_ContextState.SetDepthClamp( RSDesc.DepthClipEnable ); - m_ContextState.EnableScissorTest( RSDesc.ScissorEnable ); - if( RSDesc.AntialiasedLineEnable ) - LOG_WARNING_MESSAGE( "Line antialiasing is not supported on OpenGL" ); + m_ContextState.SetBlendFactors(m_BlendFactors); } } + void DeviceContextGLImpl::SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags ) + { + TDeviceContextBase::SetVertexBuffers( StartSlot, NumBuffersSet, ppBuffers, pStrides, pOffsets, Flags ); + m_bVAOIsUpToDate = false; + } - void DeviceContextGLImpl::SetBlendState( IBlendState *pBS, const float* pBlendFactors, Uint32 SampleMask ) + void DeviceContextGLImpl::ClearState() { - if( TDeviceContextBase::SetBlendState( pBS, pBlendFactors, SampleMask ) ) - { - CHECK_DYNAMIC_TYPE( BlendStateGLImpl, pBS ); - auto *pBSGL = static_cast<BlendStateGLImpl*>(pBS); - const auto BSDsc = pBS->GetDesc(); - m_ContextState.SetBlendState(BSDsc, m_BlendFactors, SampleMask); - } + TDeviceContextBase::ClearState(); + + } + + void DeviceContextGLImpl::SetIndexBuffer( IBuffer *pIndexBuffer, Uint32 ByteOffset ) + { + TDeviceContextBase::SetIndexBuffer( pIndexBuffer, ByteOffset ); + m_bVAOIsUpToDate = false; } void DeviceContextGLImpl::SetViewports( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight ) { TDeviceContextBase::SetViewports( NumViewports, pViewports, RTWidth, RTHeight ); - VERIFY( NumViewports == m_Viewports.size(), "Unexpected number of viewports" ); + VERIFY( NumViewports == m_NumViewports, "Unexpected number of viewports" ); if( NumViewports == 1 ) { const auto &vp = m_Viewports[0]; @@ -245,7 +249,7 @@ namespace Diligent { TDeviceContextBase::SetScissorRects(NumRects, pRects, RTWidth, RTHeight); - VERIFY( NumRects == m_ScissorRects.size(), "Unexpected number of scissor rects" ); + VERIFY( NumRects == m_NumScissorRects, "Unexpected number of scissor rects" ); if( NumRects == 1 ) { const auto &Rect = m_ScissorRects[0]; @@ -285,7 +289,7 @@ namespace Diligent void DeviceContextGLImpl::RebindRenderTargets() { - Uint32 NumRenderTargets = static_cast<Uint32>( m_pBoundRenderTargets.size() ); + Uint32 NumRenderTargets = m_NumBoundRenderTargets; VERIFY( NumRenderTargets < MaxRenderTargets, "Too many render targets (", NumRenderTargets, ") are being set" ); NumRenderTargets = std::min( NumRenderTargets, MaxRenderTargets ); @@ -311,15 +315,20 @@ namespace Diligent RebindRenderTargets(); } - void DeviceContextGLImpl::BindProgramResources( Uint32 &NewMemoryBarriers ) + void DeviceContextGLImpl::BindProgramResources( Uint32 &NewMemoryBarriers, IShaderResourceBinding *pResBinding ) { auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); - auto &PipelineCache = pRenderDeviceGL->m_PipelineCache; - auto &PipelineOrProg = PipelineCache.GetProgramPipeline( m_pBoundShaders.data(), (Uint32)m_pBoundShaders.size() ); + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound") + return; + } + auto *pPipelineStateGL = ValidatedCast<PipelineStateGLImpl>(m_pPipelineState.RawPtr()); + auto *pShaderResBindingGL = ValidatedCast<ShaderResourceBindingGLImpl>(pResBinding); const auto &DeviceCaps = pRenderDeviceGL->GetDeviceCaps(); - GLuint Prog = PipelineOrProg.Program; - GLuint Pipeline = PipelineOrProg.Pipeline; + auto &Prog = pPipelineStateGL->GetGLProgram(); + auto &Pipeline = pPipelineStateGL->GetGLProgramPipeline(); VERIFY( Prog ^ Pipeline, "Only one of program or pipeline can be specified" ); if( !(Prog || Pipeline) ) { @@ -331,213 +340,246 @@ namespace Diligent // WARNING: glUseProgram() overrides glBindProgramPipeline(). That is, if you have a program in use and // a program pipeline bound, all rendering will use the program that is in use, not the pipeline programs!!! // So make sure that glUseProgram(0) has been called if pipeline is in use - m_ContextState.SetProgram( PipelineOrProg.Program ); + m_ContextState.SetProgram( Prog ); if( ProgramPipelineSupported ) - m_ContextState.SetPipeline( PipelineOrProg.Pipeline ); + m_ContextState.SetPipeline( Pipeline ); - size_t NumPrograms = ProgramPipelineSupported ? m_pBoundShaders.size() : 1; + size_t NumPrograms = ProgramPipelineSupported ? pPipelineStateGL->GetNumShaders() : 1; GLuint UniformBuffBindPoint = 0; GLuint TextureIndex = 0; m_BoundWritableTextures.clear(); m_BoundWritableBuffers.clear(); for( size_t ProgNum = 0; ProgNum < NumPrograms; ++ProgNum ) { - auto *pShaderGL = static_cast<ShaderGLImpl*>(m_pBoundShaders[ProgNum].RawPtr()); - auto &GLProgramObj = ProgramPipelineSupported ? pShaderGL->m_GlProgObj : PipelineOrProg.Program; + auto *pShaderGL = static_cast<ShaderGLImpl*>(pPipelineStateGL->GetShaders()[ProgNum]); + auto &GLProgramObj = ProgramPipelineSupported ? pShaderGL->m_GlProgObj : Prog; + GLProgramResources *pDynamicResources = pShaderResBindingGL ? &pShaderResBindingGL->GetProgramResources(pShaderGL->GetDesc().ShaderType, pPipelineStateGL) : nullptr; #ifdef VERIFY_RESOURCE_BINDINGS - GLProgramObj.dbgVerifyResourceBindings(); + GLProgramObj.dbgVerifyBindingCompleteness(pDynamicResources, pPipelineStateGL); #endif - GLuint GLProgID = GLProgramObj; - auto &UniformBlocks = GLProgramObj.GetUniformBlocks(); - for( auto it = UniformBlocks.begin(); it != UniformBlocks.end(); ++it ) + for(int BindDynamicResources = 0; BindDynamicResources < (pShaderResBindingGL ? 2 : 1); ++BindDynamicResources) { - auto& pResource = it->pResource; - if( pResource ) + GLProgramResources &ProgResources = BindDynamicResources ? *pDynamicResources : GLProgramObj.GetConstantResources(); + +#ifdef VERIFY_RESOURCE_BINDINGS + ProgResources.dbgVerifyResourceBindings(); +#endif + + GLuint GLProgID = GLProgramObj; + auto &UniformBlocks = ProgResources.GetUniformBlocks(); + for( auto it = UniformBlocks.begin(); it != UniformBlocks.end(); ++it ) { - CHECK_DYNAMIC_TYPE( BufferGLImpl, pResource.RawPtr() ); - auto *pBufferOGL = static_cast<BufferGLImpl*>(pResource.RawPtr()); - pBufferOGL->BufferMemoryBarrier( - GL_UNIFORM_BARRIER_BIT,// Shader uniforms sourced from buffer objects after the barrier - // will reflect data written by shaders prior to the barrier - m_ContextState); + for(Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) + { + auto& Resource = it->pResources[ArrInd]; + if( Resource ) + { + auto *pBufferOGL = ValidatedCast<BufferGLImpl>(Resource.RawPtr()); + pBufferOGL->BufferMemoryBarrier( + GL_UNIFORM_BARRIER_BIT,// Shader uniforms sourced from buffer objects after the barrier + // will reflect data written by shaders prior to the barrier + m_ContextState); - glBindBufferBase( GL_UNIFORM_BUFFER, UniformBuffBindPoint, pBufferOGL->m_GlBuffer ); - CHECK_GL_ERROR( "Failed to bind uniform buffer" ); - //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferOGL->m_GlBuffer, 0, pBufferOGL->GetDesc().uiSizeInBytes); + glBindBufferBase( GL_UNIFORM_BUFFER, UniformBuffBindPoint, pBufferOGL->m_GlBuffer ); + CHECK_GL_ERROR( "Failed to bind uniform buffer" ); + //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferOGL->m_GlBuffer, 0, pBufferOGL->GetDesc().uiSizeInBytes); - glUniformBlockBinding( GLProgID, it->Index, UniformBuffBindPoint ); - CHECK_GL_ERROR( "glUniformBlockBinding() failed" ); + glUniformBlockBinding( GLProgID, it->Index + ArrInd, UniformBuffBindPoint ); + CHECK_GL_ERROR( "glUniformBlockBinding() failed" ); - ++UniformBuffBindPoint; - } - else - { -#define LOG_MISSING_BINDING(VarType, VarName) LOG_ERROR_MESSAGE( "No ", VarType, " is bound to \"", VarName, "\" variable in shader \"", pShaderGL->GetDesc().Name, "\"" ); - LOG_MISSING_BINDING("uniform buffer", it->Name) + ++UniformBuffBindPoint; + } + else + { + #define LOG_MISSING_BINDING(VarType, Res, ArrInd)\ + { \ + if(Res->pResources.size()>1) \ + LOG_ERROR_MESSAGE( "No ", VarType, " is bound to \"", Res->Name, '[', ArrInd, "]\" variable in shader \"", pShaderGL->GetDesc().Name, "\"" )\ + else \ + LOG_ERROR_MESSAGE( "No ", VarType, " is bound to \"", Res->Name, "\" variable in shader \"", pShaderGL->GetDesc().Name, "\"" )\ + } + + LOG_MISSING_BINDING("uniform buffer", it, ArrInd) + } + } } - } - auto &Samplers = GLProgramObj.GetSamplers(); - for( auto it = Samplers.begin(); it != Samplers.end(); ++it ) - { - auto &pResource = it->pResource; - if( pResource ) + auto &Samplers = ProgResources.GetSamplers(); + for( auto it = Samplers.begin(); it != Samplers.end(); ++it ) { - if( it->Type == GL_SAMPLER_BUFFER || - it->Type == GL_INT_SAMPLER_BUFFER || - it->Type == GL_UNSIGNED_INT_SAMPLER_BUFFER ) - { - CHECK_DYNAMIC_TYPE( BufferViewGLImpl, pResource.RawPtr() ); - auto *pBufViewOGL = static_cast<BufferViewGLImpl*>(pResource.RawPtr()); - auto *pBuffer = pBufViewOGL->GetBuffer(); - - m_ContextState.BindTexture( TextureIndex, GL_TEXTURE_BUFFER, pBufViewOGL->GetTexBufferHandle() ); - m_ContextState.BindSampler( TextureIndex, GLObjectWrappers::GLSamplerObj(false) ); // Use default texture sampling parameters - - CHECK_DYNAMIC_TYPE( BufferGLImpl, pBuffer ); - static_cast<BufferGLImpl*>(pBuffer)->BufferMemoryBarrier( - GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object - // memory via buffer textures, after the barrier will reflect data - // written by shaders prior to the barrier - m_ContextState); - } - else + for(Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) { - CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pResource.RawPtr() ); - auto *pTexViewOGL = static_cast<TextureViewGLImpl*>(pResource.RawPtr()); - m_ContextState.BindTexture( TextureIndex, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle() ); - - auto *pTexture = pTexViewOGL->GetTexture(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); - static_cast<TextureBaseGL*>(pTexture)->TextureMemoryBarrier( - GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object - // memory via buffer textures, after the barrier will reflect data - // written by shaders prior to the barrier - m_ContextState); - - auto pSampler = pTexViewOGL->GetSampler(); - if( pSampler ) + auto &Resource = it->pResources[ArrInd]; + if( Resource ) { - auto *pSamplerGL = ValidatedCast<SamplerGLImpl>( pSampler ); - m_ContextState.BindSampler( TextureIndex, pSamplerGL->GetHandle() ); + if( it->Type == GL_SAMPLER_BUFFER || + it->Type == GL_INT_SAMPLER_BUFFER || + it->Type == GL_UNSIGNED_INT_SAMPLER_BUFFER ) + { + auto *pBufViewOGL = ValidatedCast<BufferViewGLImpl>(Resource.RawPtr()); + auto *pBuffer = pBufViewOGL->GetBuffer(); + + m_ContextState.BindTexture( TextureIndex, GL_TEXTURE_BUFFER, pBufViewOGL->GetTexBufferHandle() ); + m_ContextState.BindSampler( TextureIndex, GLObjectWrappers::GLSamplerObj(false) ); // Use default texture sampling parameters + + CHECK_DYNAMIC_TYPE( BufferGLImpl, pBuffer ); + static_cast<BufferGLImpl*>(pBuffer)->BufferMemoryBarrier( + GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier + m_ContextState); + } + else + { + auto *pTexViewOGL = ValidatedCast<TextureViewGLImpl>(Resource.RawPtr()); + m_ContextState.BindTexture( TextureIndex, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle() ); + + auto *pTexture = pTexViewOGL->GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); + static_cast<TextureBaseGL*>(pTexture)->TextureMemoryBarrier( + GL_TEXTURE_FETCH_BARRIER_BIT, // Texture fetches from shaders, including fetches from buffer object + // memory via buffer textures, after the barrier will reflect data + // written by shaders prior to the barrier + m_ContextState); + + SamplerGLImpl *pSamplerGL = nullptr; + if (it->pStaticSampler) + { + pSamplerGL = it->pStaticSampler; + } + else + { + auto pSampler = pTexViewOGL->GetSampler(); + pSamplerGL = ValidatedCast<SamplerGLImpl>( pSampler ); + } + + if( pSamplerGL ) + { + m_ContextState.BindSampler( TextureIndex, pSamplerGL->GetHandle() ); + } + } + + // Texture is now bound to texture slot TextureIndex. + // We now need to set the program uniform to use that slot + if( ProgramPipelineSupported ) + { + // glProgramUniform1i does not require program to be bound to the pipeline + glProgramUniform1i( GLProgramObj, it->Location + ArrInd, TextureIndex ); + } + else + { + // glUniform1i requires program to be bound to the pipeline + glUniform1i( it->Location + ArrInd, TextureIndex ); + } + CHECK_GL_ERROR( "Failed to bind sampler uniform to texture slot" ); + + ++TextureIndex; + } + else + { + LOG_MISSING_BINDING("texture sampler", it, ArrInd) } } - - // Texture is now bound to texture slot TextureIndex. - // We now need to set the program uniform to use that slot - if( ProgramPipelineSupported ) - { - // glProgramUniform1i does not require program to be bound to the pipeline - glProgramUniform1i( GLProgramObj, it->Location, TextureIndex ); - } - else - { - // glUniform1i requires program to be bound to the pipeline - glUniform1i( it->Location, TextureIndex ); - } - CHECK_GL_ERROR( "Failed to bind sampler uniform to texture slot" ); - - ++TextureIndex; } - else - { - LOG_MISSING_BINDING("texture sampler", it->Name) - } - } - auto &Images = GLProgramObj.GetImages(); - for( auto it = Images.begin(); it != Images.end(); ++it ) - { - auto &pResource = it->pResource; - if( pResource ) + auto &Images = ProgResources.GetImages(); + for( auto it = Images.begin(); it != Images.end(); ++it ) { - CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pResource.RawPtr() ); - auto *pTexViewOGL = static_cast<TextureViewGLImpl*>(pResource.RawPtr()); - const auto &ViewDesc = pTexViewOGL->GetDesc(); - - if( ViewDesc.AccessFlags & UAV_ACCESS_FLAG_WRITE ) + for(Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) { - auto *pTex = pTexViewOGL->GetTexture(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTex ); - auto *pTexGL = static_cast<TextureBaseGL*>(pTex); - - pTexGL->TextureMemoryBarrier( - GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,// Memory accesses using shader image load, store, and atomic built-in - // functions issued after the barrier will reflect data written by shaders - // prior to the barrier. Additionally, image stores and atomics issued after - // the barrier will not execute until all memory accesses (e.g., loads, - // stores, texture fetches, vertex fetches) initiated prior to the barrier - // complete. - m_ContextState); - // We cannot set pending memory barriers here, because - // if some texture is bound twice, the logic will fail - m_BoundWritableTextures.push_back( pTexGL ); - } - -#ifdef _DEBUG - // Check that the texure being bound has immutable storage - { - m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle() ); - GLint IsImmutable = 0; - glGetTexParameteriv( pTexViewOGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable ); - CHECK_GL_ERROR( "glGetTexParameteriv() failed" ); - VERIFY( IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()" ); - m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), GLObjectWrappers::GLTextureObj(false) ); + auto &Resource = it->pResources[ArrInd]; + if( Resource ) + { + auto *pTexViewOGL = ValidatedCast<TextureViewGLImpl>(Resource.RawPtr()); + const auto &ViewDesc = pTexViewOGL->GetDesc(); + + if( ViewDesc.AccessFlags & UAV_ACCESS_FLAG_WRITE ) + { + auto *pTex = pTexViewOGL->GetTexture(); + CHECK_DYNAMIC_TYPE( TextureBaseGL, pTex ); + auto *pTexGL = static_cast<TextureBaseGL*>(pTex); + + pTexGL->TextureMemoryBarrier( + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,// Memory accesses using shader image load, store, and atomic built-in + // functions issued after the barrier will reflect data written by shaders + // prior to the barrier. Additionally, image stores and atomics issued after + // the barrier will not execute until all memory accesses (e.g., loads, + // stores, texture fetches, vertex fetches) initiated prior to the barrier + // complete. + m_ContextState); + // We cannot set pending memory barriers here, because + // if some texture is bound twice, the logic will fail + m_BoundWritableTextures.push_back( pTexGL ); + } + + #ifdef _DEBUG + // Check that the texure being bound has immutable storage + { + m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle() ); + GLint IsImmutable = 0; + glGetTexParameteriv( pTexViewOGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable ); + CHECK_GL_ERROR( "glGetTexParameteriv() failed" ); + VERIFY( IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()" ); + m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), GLObjectWrappers::GLTextureObj(false) ); + } + #endif + auto GlTexFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format ); + // Note that if a format qulifier is specified in the shader, the format + // must match it + + GLboolean Layered = ViewDesc.NumArraySlices > 1 && ViewDesc.FirstArraySlice == 0; + // If "layered" is TRUE, the entire Mip level is bound. Layer parameter is ignored in this + // case. If "layered" is FALSE, only the single layer identified by "layer" will + // be bound. When "layered" is FALSE, the single bound layer is treated as a 2D texture. + GLint Layer = ViewDesc.FirstArraySlice; + + auto GLAccess = AccessFlags2GLAccess( ViewDesc.AccessFlags ); + // WARNING: Texture being bound to the image unit must be complete + // That means that if an integer texture is being bound, its + // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, + // otherwise it will be incomplete + m_ContextState.BindImage( it->BindingPoint + ArrInd, pTexViewOGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat ); + } + else + { + LOG_MISSING_BINDING("image", it, ArrInd) + } } -#endif - auto GlTexFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format ); - // Note that if a format qulifier is specified in the shader, the format - // must match it - - GLboolean Layered = ViewDesc.NumArraySlices > 1 && ViewDesc.FirstArraySlice == 0; - // If "layered" is TRUE, the entire Mip level is bound. Layer parameter is ignored in this - // case. If "layered" is FALSE, only the single layer identified by "layer" will - // be bound. When "layered" is FALSE, the single bound layer is treated as a 2D texture. - GLint Layer = ViewDesc.FirstArraySlice; - - auto GLAccess = AccessFlags2GLAccess( ViewDesc.AccessFlags ); - // WARNING: Texture being bound to the image unit must be complete - // That means that if an integer texture is being bound, its - // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, - // otherwise it will be incomplete - m_ContextState.BindImage( it->BindingPoint, pTexViewOGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat ); } - else - { - LOG_MISSING_BINDING("image", it->Name) - } - } - auto &StorageBlocks = GLProgramObj.GetStorageBlocks(); - for( auto it = StorageBlocks.begin(); it != StorageBlocks.end(); ++it ) - { - auto &pResource = it->pResource; - if( pResource ) + auto &StorageBlocks = ProgResources.GetStorageBlocks(); + for( auto it = StorageBlocks.begin(); it != StorageBlocks.end(); ++it ) { - CHECK_DYNAMIC_TYPE( BufferViewGLImpl, pResource.RawPtr() ); - auto *pBufferViewOGL = static_cast<BufferViewGLImpl*>(pResource.RawPtr()); - const auto &ViewDesc = pBufferViewOGL->GetDesc(); - VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect buffer view type" ); + for(Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) + { + auto &Resource = it->pResources[ArrInd]; + if( Resource ) + { + auto *pBufferViewOGL = ValidatedCast<BufferViewGLImpl>(Resource.RawPtr()); + const auto &ViewDesc = pBufferViewOGL->GetDesc(); + VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect buffer view type" ); - auto *pBuffer = pBufferViewOGL->GetBuffer(); - CHECK_DYNAMIC_TYPE( BufferGLImpl, pBuffer ); - auto *pBufferOGL = static_cast<BufferGLImpl*>(pBuffer); + auto *pBuffer = pBufferViewOGL->GetBuffer(); + CHECK_DYNAMIC_TYPE( BufferGLImpl, pBuffer ); + auto *pBufferOGL = static_cast<BufferGLImpl*>(pBuffer); - pBufferOGL->BufferMemoryBarrier( - GL_SHADER_STORAGE_BARRIER_BIT,// Accesses to shader storage blocks after the barrier - // will reflect writes prior to the barrier - m_ContextState); + pBufferOGL->BufferMemoryBarrier( + GL_SHADER_STORAGE_BARRIER_BIT,// Accesses to shader storage blocks after the barrier + // will reflect writes prior to the barrier + m_ContextState); - glBindBufferRange( GL_SHADER_STORAGE_BUFFER, it->Binding, pBufferOGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth ); - CHECK_GL_ERROR( "Failed to bind shader storage buffer" ); + glBindBufferRange( GL_SHADER_STORAGE_BUFFER, it->Binding + ArrInd, pBufferOGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth ); + CHECK_GL_ERROR( "Failed to bind shader storage buffer" ); - m_BoundWritableBuffers.push_back( pBufferOGL ); - } - else - { - LOG_MISSING_BINDING("shader storage block", it->Name ) + m_BoundWritableBuffers.push_back( pBufferOGL ); + } + else + { + LOG_MISSING_BINDING("shader storage block", it, ArrInd ) + } + } } } } @@ -598,26 +640,30 @@ namespace Diligent return; } - RefCntWeakPtr<IBuffer> pIndexBuffer; - if( DrawAttribs.IsIndexed ) - pIndexBuffer = m_pIndexBuffer; - - // Obtain strong reference to the vertex description object and index buffer - auto &spVertexDesc = m_pVertexDesc; - auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); - if( spVertexDesc ) + if (!m_pPipelineState) { - auto &VAOCache = pRenderDeviceGL->m_VAOCache; - auto spIndexBuff = pIndexBuffer.Lock(); - const auto& VAO = VAOCache.GetVAO( *spVertexDesc, spIndexBuff, m_VertexStreams, m_ContextState ); - m_ContextState.BindVAO( VAO ); + LOG_ERROR("No pipeline state is bound.") + return; } - else + + if(!m_bVAOIsUpToDate) { - // Draw command will fail if no VAO is bound. If no vertex description is set - // (which is the case if, for instance, the command only inputs VertexID), - // use empty VAO - m_ContextState.BindVAO( pRenderDeviceGL->m_EmptyVAO ); + auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(m_pDevice.RawPtr()); + if( m_pPipelineState->GetDesc().GraphicsPipeline.InputLayout.NumElements > 0 ) + { + IBuffer *pIndexBuffer = DrawAttribs.IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr; + auto &VAOCache = pRenderDeviceGL->m_VAOCache; + const auto& VAO = VAOCache.GetVAO( m_pPipelineState.RawPtr(), pIndexBuffer, m_VertexStreams, m_NumVertexStreams, m_ContextState ); + m_ContextState.BindVAO( VAO ); + } + else + { + // Draw command will fail if no VAO is bound. If no vertex description is set + // (which is the case if, for instance, the command only inputs VertexID), + // use empty VAO + m_ContextState.BindVAO( pRenderDeviceGL->m_EmptyVAO ); + } + m_bVAOIsUpToDate = true; } auto GlTopology = PrimitiveTopologyToGLTopology( DrawAttribs.Topology ); @@ -632,9 +678,6 @@ namespace Diligent FirstIndexByteOffset = static_cast<Uint32>(GetValueSize( DrawAttribs.IndexType )) * DrawAttribs.FirstIndexLocation + m_IndexDataStartOffset; } - Uint32 NewMemoryBarriers = 0; - BindProgramResources( NewMemoryBarriers ); - // NOTE: Base Vertex and Base Instance versions are not supported even in OpenGL ES 3.1 // This functionality can be emulated by adjusting stream offsets. This, however may cause // errors in case instance data is read from the same stream as vertex data. Thus handling @@ -735,15 +778,15 @@ namespace Diligent } // IMPORTANT: new pending memory barriers in the context must be set - // after all previous barriers were executed. - m_ContextState.SetPendingMemoryBarriers( NewMemoryBarriers ); + // after all previous barriers have been executed. + // m_CommitedResourcesTentativeBarriers contains memory barriers that will be required + // AFTER the actual draw/dispatch command is executed. + m_ContextState.SetPendingMemoryBarriers( m_CommitedResourcesTentativeBarriers ); + m_CommitedResourcesTentativeBarriers = 0; } void DeviceContextGLImpl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) { - Uint32 NewMemoryBarriers = 0; - BindProgramResources( NewMemoryBarriers ); - if( DispatchAttrs.pIndirectDispatchAttribs ) { CHECK_DYNAMIC_TYPE( BufferGLImpl, DispatchAttrs.pIndirectDispatchAttribs ); @@ -771,8 +814,11 @@ namespace Diligent } // IMPORTANT: new pending memory barriers in the context must be set - // after all previous barriers were executed. - m_ContextState.SetPendingMemoryBarriers( NewMemoryBarriers ); + // after all previous barriers have been executed. + // m_CommitedResourcesTentativeBarriers contains memory barriers that will be required + // AFTER the actual draw/dispatch command is executed. + m_ContextState.SetPendingMemoryBarriers( m_CommitedResourcesTentativeBarriers ); + m_CommitedResourcesTentativeBarriers = 0; } void DeviceContextGLImpl::ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil ) @@ -793,7 +839,7 @@ namespace Diligent } else { - if( !(nullptr == m_pBoundDepthStencil && m_pBoundRenderTargets.size() == 0) ) + if( !(nullptr == m_pBoundDepthStencil && m_NumBoundRenderTargets == 0) ) { UNEXPECTED( "Default depth stencil buffer being cleared is not bound to the pipeline" ); LOG_ERROR_MESSAGE( "Default depth stencil buffer must be bound to the pipeline to be cleared" ); @@ -831,7 +877,7 @@ namespace Diligent VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected" ); CHECK_DYNAMIC_TYPE( TextureViewGLImpl, pView ); auto *pViewGL = static_cast<TextureViewGLImpl*>(pView); - for( Uint32 rt = 0; rt < m_pBoundRenderTargets.size(); ++rt ) + for( Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt ) if( m_pBoundRenderTargets[rt] == pView ) { RTIndex = rt; @@ -846,7 +892,7 @@ namespace Diligent } else { - if( m_pBoundRenderTargets.size() == 0 && m_pBoundDepthStencil == nullptr ) + if( m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil == nullptr ) RTIndex = 0; else { @@ -886,4 +932,14 @@ namespace Diligent glFlush(); } + void DeviceContextGLImpl::FinishCommandList(class ICommandList **ppCommandList) + { + LOG_ERROR("Deferred contexts are not supported in OpenGL mode"); + } + + void DeviceContextGLImpl::ExecuteCommandList(class ICommandList *pCommandList) + { + LOG_ERROR("Deferred contexts are not supported in OpenGL mode"); + } + } diff --git a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp index d3f50635..4ad5cb20 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp index 99ad25d0..a0277b5c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -395,5 +395,7 @@ namespace Diligent TexCaps.bTexture2DMSSupported = IsGLES31OrAbove; TexCaps.bTexture2DMSArraySupported = False; // Not supported in GLES 3.1 TexCaps.bTextureViewSupported = False; // Not supported in GLES 3.1 + TexCaps.bCubemapArraysSupported = False; // Not supported in GLES 3.1 + DeviceCaps.bMultithreadedResourceCreationSupported = False; } } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp index 065f3a16..cc007610 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ namespace Diligent { GLContextState::GLContextState( RenderDeviceGLImpl *pDeviceGL ) : m_PendingMemoryBarriers( 0 ), - m_DepthCmpFunc( COMPARISON_FUNC_UNKNOW ), + m_DepthCmpFunc( COMPARISON_FUNC_UNKNOWN ), m_StencilReadMask( 0xFF ), m_StencilWriteMask( 0xFF ), m_GLProgId( 0 ), @@ -336,6 +336,14 @@ namespace Diligent } } + void GLContextState::SetStencilRef(GLenum Face, Int32 Ref) + { + auto& FaceStencilOp = m_StencilOpState[Face == GL_FRONT ? 0 : 1]; + auto GlStencilFunc = CompareFuncToGLCompareFunc( FaceStencilOp.Func ); + glStencilFuncSeparate( Face, GlStencilFunc, Ref, FaceStencilOp.Mask ); + CHECK_GL_ERROR( "Failed to set stencil function" ); + } + void GLContextState::SetStencilFunc( GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask ) { auto& FaceStencilOp = m_StencilOpState[Face == GL_FRONT ? 0 : 1]; @@ -343,13 +351,11 @@ namespace Diligent FaceStencilOp.Ref != Ref || FaceStencilOp.Mask != Mask ) { - auto GlStencilFunc = CompareFuncToGLCompareFunc( Func ); - glStencilFuncSeparate( Face, GlStencilFunc, Ref, Mask ); - CHECK_GL_ERROR( "Failed to set stencil function" ); - FaceStencilOp.Func = Func; FaceStencilOp.Ref = Ref; FaceStencilOp.Mask = Mask; + + SetStencilRef(Face, Ref); } } @@ -501,8 +507,16 @@ namespace Diligent } } - void GLContextState::SetBlendState( const BlendStateDesc &BSDsc, const float *BlendFactors, Uint32 SampleMask ) + void GLContextState::SetBlendFactors(const float *BlendFactors) { + glBlendColor( BlendFactors[0], BlendFactors[1], BlendFactors[2], BlendFactors[3] ); + CHECK_GL_ERROR( "Failed to set blend color" ); + } + + void GLContextState::SetBlendState( const BlendStateDesc &BSDsc, Uint32 SampleMask ) + { + VERIFY(SampleMask = 0xFFFFFFFF, "Sample mask is not currently implemented in GL"); + bool bEnableBlend = false; if( BSDsc.IndependentBlendEnable ) { @@ -528,9 +542,6 @@ namespace Diligent glEnable( GL_BLEND ); CHECK_GL_ERROR( "Failed to enable alpha blending" ); - glBlendColor( BlendFactors[0], BlendFactors[1], BlendFactors[2], BlendFactors[3] ); - CHECK_GL_ERROR( "Failed to set blend color" ); - if( BSDsc.AlphaToCoverageEnable ) { glEnable( GL_SAMPLE_ALPHA_TO_COVERAGE ); diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp index a0e7bf0b..5826f827 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -134,8 +134,8 @@ namespace Diligent if( wglewIsSupported( "WGL_ARB_create_context" ) == 1 ) { MajorVersion = 4; - MinorVersion = 2; - // Setup attributes for a new OpenGL 4.2 rendering context + MinorVersion = 4; + // Setup attributes for a new OpenGL rendering context int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion, @@ -206,6 +206,15 @@ namespace Diligent &unusedIds, true ); } + + // Under the standard filtering rules for cubemaps, filtering does not work across faces of the cubemap. + // This results in a seam across the faces of a cubemap. This was a hardware limitation in the past, but + // modern hardware is capable of interpolating across a cube face boundary. + // GL_TEXTURE_CUBE_MAP_SEAMLESS is not defined in OpenGLES + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + if( glGetError() != GL_NO_ERROR ) + LOG_ERROR_MESSAGE("Failed to enable seamless cubemap filtering"); + DeviceCaps.DevType = DeviceType::OpenGL; DeviceCaps.MajorVersion = MajorVersion; DeviceCaps.MinorVersion = MinorVersion; @@ -214,6 +223,8 @@ namespace Diligent TexCaps.bTexture2DMSSupported = IsGL43OrAbove; TexCaps.bTexture2DMSArraySupported = IsGL43OrAbove; TexCaps.bTextureViewSupported = IsGL43OrAbove; + TexCaps.bCubemapArraysSupported = IsGL43OrAbove; + DeviceCaps.bMultithreadedResourceCreationSupported = False; } GLContext::~GLContext() diff --git a/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp index 5793e469..68589a2b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp index 808fcc12..5c8ff350 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ #include "pch.h" #include "GLProgram.h" +#include "ShaderBase.h" +#include "ShaderResourceBindingGLImpl.h" namespace Diligent { @@ -32,274 +34,66 @@ namespace Diligent GLProgram::GLProgram( GLProgram&& Program ): GLObjectWrappers::GLProgramObj( std::move( Program ) ), - m_UniformBlocks( std::move( Program.m_UniformBlocks ) ), - m_Samplers( std::move( Program.m_Samplers ) ), - m_Images( std::move( Program.m_Images ) ), - m_StorageBlocks( std::move( Program.m_StorageBlocks ) ) + m_AllResources( std::move( Program.m_AllResources) ), + m_ConstantResources( std::move( Program.m_ConstantResources) ) {} - void GLProgram::LoadUniforms() + void GLProgram::InitResources(RenderDeviceGLImpl* pDeviceGLImpl, + const SHADER_VARIABLE_TYPE DefaultVariableType, + const ShaderVariableDesc *VariableDesc, + Uint32 NumVars, + const StaticSamplerDesc *StaticSamplers, + Uint32 NumStaticSamplers, + IObject &Owner) { GLuint GLProgram = static_cast<GLuint>(*this); + m_AllResources.LoadUniforms(pDeviceGLImpl, GLProgram, DefaultVariableType, VariableDesc, NumVars, StaticSamplers, NumStaticSamplers); - GLint numActiveUniforms = 0; - glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORMS, &numActiveUniforms ); - CHECK_GL_ERROR_AND_THROW( "Unable to get number of active uniforms\n" ); - - // Query the maximum name length of the active uniform (including null terminator) - GLint activeUniformMaxLength = 0; - glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformMaxLength ); - CHECK_GL_ERROR_AND_THROW( "Unable to get maximum uniform name length\n" ); - - GLint numActiveUniformBlocks = 0; - glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numActiveUniformBlocks ); - CHECK_GL_ERROR_AND_THROW( "Unable to get the number of active uniform blocks\n" ); - - // - // #### This parameter is currently unsupported by Intel OGL drivers. - // - // Query the maximum name length of the active uniform block (including null terminator) - GLint activeUniformBlockMaxLength = 0; - // On Intel driver, this call might fail: - glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &activeUniformBlockMaxLength ); - //CHECK_GL_ERROR_AND_THROW("Unable to get the maximum uniform block name length\n"); - if( GL_NO_ERROR != glGetError() ) - { - LOG_WARNING_MESSAGE( "Unable to get the maximum uniform block name length. Using 1024 as a workaround\n" ); - activeUniformBlockMaxLength = 1024; - } - - - GLint numActiveShaderStorageBlocks = 0; - glGetProgramInterfaceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numActiveShaderStorageBlocks ); - CHECK_GL_ERROR_AND_THROW( "Unable to get the number of shader storage blocks blocks\n" ); - - // Query the maximum name length of the active shader storage block (including null terminator) - GLint MaxShaderStorageBlockNameLen = 0; - glGetProgramInterfaceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &MaxShaderStorageBlockNameLen ); - CHECK_GL_ERROR_AND_THROW( "Unable to get the maximum shader storage block name length\n" ); - - auto MaxNameLength = std::max( activeUniformMaxLength, activeUniformBlockMaxLength ); - MaxNameLength = std::max( MaxNameLength, MaxShaderStorageBlockNameLen ); - - MaxNameLength = std::max( MaxNameLength, 512 ); - std::vector<GLchar> Name( MaxNameLength + 1 ); - for( int i = 0; i < numActiveUniforms; i++ ) - { - GLenum dataType = 0; - GLint size = 0; - GLint NameLen = 0; - glGetActiveUniform( GLProgram, i, MaxNameLength, &NameLen, &size, &dataType, Name.data() ); - CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform\n" ); - VERIFY( NameLen < MaxNameLength && NameLen == strlen( Name.data() ), "Incorrect uniform name" ); - // Note that - // glGetActiveUniform( program, index, bufSize, length, size, type, name ); - // - // is equivalent to - // - // const enum props[] = { ARRAY_SIZE, TYPE }; - // glGetProgramResourceName( program, UNIFORM, index, bufSize, length, name ); - // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[0], 1, NULL, size ); - // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[1], 1, NULL, (int *)type ); - // - // The latter is only available in GL 4.4 and GLES 3.1 - - switch( dataType ) - { - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - - case GL_SAMPLER_CUBE_MAP_ARRAY: - case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: - case GL_INT_SAMPLER_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: - - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - - case GL_SAMPLER_BUFFER: - case GL_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - { - auto UniformLocation = glGetUniformLocation( GLProgram, Name.data() ); - // Note that glGetUniformLocation(program, name) is equivalent to - // glGetProgramResourceLocation( program, GL_UNIFORM, name ); - // The latter is only available in GL 4.4 and GLES 3.1 - m_Samplers.emplace_back( SamplerInfo( Name.data(), UniformLocation, dataType) ); - break; - } - - case GL_IMAGE_1D: - case GL_IMAGE_2D: - case GL_IMAGE_3D: - case GL_IMAGE_2D_RECT: - case GL_IMAGE_CUBE: - case GL_IMAGE_BUFFER: - case GL_IMAGE_1D_ARRAY: - case GL_IMAGE_2D_ARRAY: - case GL_IMAGE_CUBE_MAP_ARRAY: - case GL_IMAGE_2D_MULTISAMPLE: - case GL_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_INT_IMAGE_1D: - case GL_INT_IMAGE_2D: - case GL_INT_IMAGE_3D: - case GL_INT_IMAGE_2D_RECT: - case GL_INT_IMAGE_CUBE: - case GL_INT_IMAGE_BUFFER: - case GL_INT_IMAGE_1D_ARRAY: - case GL_INT_IMAGE_2D_ARRAY: - case GL_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_INT_IMAGE_2D_MULTISAMPLE: - case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_IMAGE_1D: - case GL_UNSIGNED_INT_IMAGE_2D: - case GL_UNSIGNED_INT_IMAGE_3D: - case GL_UNSIGNED_INT_IMAGE_2D_RECT: - case GL_UNSIGNED_INT_IMAGE_CUBE: - case GL_UNSIGNED_INT_IMAGE_BUFFER: - case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: - { - auto UniformLocation = glGetUniformLocation( GLProgram, Name.data() ); - - GLint BindingPoint = -1; - // The value of an image uniform is an integer specifying the image unit accessed - glGetUniformiv( GLProgram, UniformLocation, &BindingPoint ); - CHECK_GL_ERROR_AND_THROW("Failed to get image binding point"); - VERIFY( BindingPoint >= 0, "Incorrect binding point" ); - - m_Images.emplace_back( ImageInfo(Name.data(), BindingPoint, dataType) ); - break; - } - - default: - // Some other uniform type like scalar, matrix etc. - break; - } - } - - for( int i = 0; i < numActiveUniformBlocks; i++ ) - { - GLsizei NameLen = 0; - glGetActiveUniformBlockName( GLProgram, i, MaxNameLength, &NameLen, Name.data() ); - CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform block name\n" ); - VERIFY( NameLen < MaxNameLength && NameLen == strlen( Name.data() ), "Incorrect uniform block name" ); - - // glGetActiveUniformBlockName( program, uniformBlockIndex, bufSize, length, uniformBlockName ); - // is equivalent to - // glGetProgramResourceName(program, GL_UNIFORM_BLOCK, uniformBlockIndex, bufSize, length, uniformBlockName); - - auto UniformBlockIndex = glGetUniformBlockIndex( GLProgram, Name.data() ); - CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform block index\n" ); - // glGetUniformBlockIndex( program, uniformBlockName ); - // is equivalent to - // glGetProgramResourceIndex( program, GL_UNIFORM_BLOCK, uniformBlockName ); - m_UniformBlocks.emplace_back(UniformBufferInfo(Name.data(), UniformBlockIndex)); - } - - for( int i = 0; i < numActiveShaderStorageBlocks; ++i ) - { - GLsizei Length = 0; - glGetProgramResourceName( GLProgram, GL_SHADER_STORAGE_BLOCK, i, MaxNameLength, &Length, Name.data() ); - CHECK_GL_ERROR_AND_THROW( "Unable to get shader storage block name\n" ); - VERIFY( Length < MaxNameLength && Length == strlen( Name.data() ), "Incorrect shader storage block name" ); - - GLenum Prop = GL_BUFFER_BINDING; - GLint Binding = -1; - GLint ValuesWritten = 0; - glGetProgramResourceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, i, 1, &Prop, 1, &ValuesWritten, &Binding ); - CHECK_GL_ERROR_AND_THROW( "Unable to get shader storage block binding\n" ); - VERIFY( ValuesWritten == 1 && Binding >= 0, "Incorrect shader storage block binding" ); - - m_StorageBlocks.emplace_back( StorageBlockInfo(Name.data(), Binding) ); - } - } - - template<typename TResArrayType> - void BindResourcesHelper(TResArrayType &ResArr, IResourceMapping *pResourceMapping, Uint32 Flags) - { - for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) - { - auto &Name = res->Name; - if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) - res->pResource.Release(); - - if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && res->pResource ) - continue; // Skip already resolved resources - - RefCntAutoPtr<IDeviceObject> pNewRes; - pResourceMapping->GetResource( Name.c_str(), static_cast<IDeviceObject**>(&pNewRes) ); - - if( !pNewRes ) - { - if( Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED ) - LOG_ERROR_MESSAGE( "Resource \"", Name, "\" is not found in the resource mapping" ); - continue; - } - res->pResource = pNewRes; - } + SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_STATIC}; + m_ConstantResources.Clone(m_AllResources, VarTypes, _countof(VarTypes), Owner); } - void GLProgram::BindResources( IResourceMapping *pResourceMapping, Uint32 Flags ) + void GLProgram::BindConstantResources( IResourceMapping *pResourceMapping, Uint32 Flags ) { if( !pResourceMapping ) return; - BindResourcesHelper( m_UniformBlocks, pResourceMapping, Flags ); - BindResourcesHelper( m_Samplers, pResourceMapping, Flags ); - BindResourcesHelper( m_Images, pResourceMapping, Flags ); - BindResourcesHelper( m_StorageBlocks, pResourceMapping, Flags ); + m_ConstantResources.BindResources(pResourceMapping, Flags); } + #ifdef VERIFY_RESOURCE_BINDINGS template<typename TResArrayType> - void dbgVerifyResourceBindingsHelper(TResArrayType &ResArr, const Char *VarType) + void GLProgram::dbgVerifyBindingCompletenessHelper(TResArrayType &ResArr, GLProgramResources *pDynamicResources) { + const auto &ConstVariables = m_ConstantResources.GetVariables(); for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) { - auto &Name = res->Name; - if( !res->pResource ) - LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", res->Name, "\"" ); + auto ConstRes = ConstVariables.find(HashMapStringKey(res->Name.c_str())); + if (ConstRes == ConstVariables.end()) + { + bool bVarFound = false; + if( pDynamicResources) + { + const auto &DynamicVariables = pDynamicResources->GetVariables(); + auto DynRes = DynamicVariables.find(HashMapStringKey(res->Name.c_str())); + bVarFound = (DynRes != DynamicVariables.end()); + } + + if(!bVarFound) + { + LOG_ERROR_MESSAGE( "Incomplete binding: non-static shader variable \"", res->Name, "\" not found" ); + } + } } } - void GLProgram::dbgVerifyResourceBindings() + void GLProgram::dbgVerifyBindingCompleteness(GLProgramResources *pDynamicResources, PipelineStateGLImpl *pPSO) { - dbgVerifyResourceBindingsHelper( m_UniformBlocks, "uniform block" ); - dbgVerifyResourceBindingsHelper( m_Samplers, "sampler" ); - dbgVerifyResourceBindingsHelper( m_Images, "image" ); - dbgVerifyResourceBindingsHelper( m_StorageBlocks, "shader storage block" ); + dbgVerifyBindingCompletenessHelper(m_AllResources.GetUniformBlocks(), pDynamicResources); + dbgVerifyBindingCompletenessHelper(m_AllResources.GetSamplers(), pDynamicResources); + dbgVerifyBindingCompletenessHelper(m_AllResources.GetImages(), pDynamicResources); + dbgVerifyBindingCompletenessHelper(m_AllResources.GetStorageBlocks(), pDynamicResources); } #endif - } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp new file mode 100644 index 00000000..5b525bff --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp @@ -0,0 +1,486 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "GLProgramResources.h" +#include "RenderDeviceGLImpl.h" + +namespace Diligent +{ + GLProgramResources::GLProgramResources() + { + } + + GLProgramResources::GLProgramResources( GLProgramResources&& Program ): + m_UniformBlocks( std::move( Program.m_UniformBlocks ) ), + m_Samplers( std::move( Program.m_Samplers ) ), + m_Images( std::move( Program.m_Images ) ), + m_StorageBlocks( std::move( Program.m_StorageBlocks ) ), + m_VariableHash(std::move( Program.m_VariableHash)) + { + } + + inline void RemoveArrayBrackets(char *Str) + { + auto* OpenBacketPtr = strchr(Str, '['); + if ( OpenBacketPtr != nullptr ) + *OpenBacketPtr = 0; + } + + void GLProgramResources::LoadUniforms(RenderDeviceGLImpl *pDeviceGLImpl, + GLuint GLProgram, + const SHADER_VARIABLE_TYPE DefaultVariableType, + const ShaderVariableDesc *VariableDesc, + Uint32 NumVars, + const StaticSamplerDesc *StaticSamplers, + Uint32 NumStaticSamplers) + { + VERIFY(GLProgram != 0, "Null GL program") + + GLint numActiveUniforms = 0; + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORMS, &numActiveUniforms ); + CHECK_GL_ERROR_AND_THROW( "Unable to get number of active uniforms\n" ); + + // Query the maximum name length of the active uniform (including null terminator) + GLint activeUniformMaxLength = 0; + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformMaxLength ); + CHECK_GL_ERROR_AND_THROW( "Unable to get maximum uniform name length\n" ); + + GLint numActiveUniformBlocks = 0; + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numActiveUniformBlocks ); + CHECK_GL_ERROR_AND_THROW( "Unable to get the number of active uniform blocks\n" ); + + // + // #### This parameter is currently unsupported by Intel OGL drivers. + // + // Query the maximum name length of the active uniform block (including null terminator) + GLint activeUniformBlockMaxLength = 0; + // On Intel driver, this call might fail: + glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &activeUniformBlockMaxLength ); + //CHECK_GL_ERROR_AND_THROW("Unable to get the maximum uniform block name length\n"); + if( GL_NO_ERROR != glGetError() ) + { + LOG_WARNING_MESSAGE( "Unable to get the maximum uniform block name length. Using 1024 as a workaround\n" ); + activeUniformBlockMaxLength = 1024; + } + + + GLint numActiveShaderStorageBlocks = 0; + glGetProgramInterfaceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numActiveShaderStorageBlocks ); + CHECK_GL_ERROR_AND_THROW( "Unable to get the number of shader storage blocks blocks\n" ); + + // Query the maximum name length of the active shader storage block (including null terminator) + GLint MaxShaderStorageBlockNameLen = 0; + glGetProgramInterfaceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &MaxShaderStorageBlockNameLen ); + CHECK_GL_ERROR_AND_THROW( "Unable to get the maximum shader storage block name length\n" ); + + auto MaxNameLength = std::max( activeUniformMaxLength, activeUniformBlockMaxLength ); + MaxNameLength = std::max( MaxNameLength, MaxShaderStorageBlockNameLen ); + + MaxNameLength = std::max( MaxNameLength, 512 ); + std::vector<GLchar> Name( MaxNameLength + 1 ); + for( int i = 0; i < numActiveUniforms; i++ ) + { + GLenum dataType = 0; + GLint size = 0; + GLint NameLen = 0; + // If one or more elements of an array are active, the name of the array is returned in name?, + // the type is returned in type?, and the size? parameter returns the highest array element index used, + // plus one, as determined by the compiler and/or linker. + // Only one active uniform variable will be reported for a uniform array. + // Uniform variables other than arrays will have a size of 1 + glGetActiveUniform( GLProgram, i, MaxNameLength, &NameLen, &size, &dataType, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform\n" ); + VERIFY( NameLen < MaxNameLength && NameLen == strlen( Name.data() ), "Incorrect uniform name" ); + VERIFY( size >= 1, "Size is expected to be at least 1" ); + // Note that + // glGetActiveUniform( program, index, bufSize, length, size, type, name ); + // + // is equivalent to + // + // const enum props[] = { ARRAY_SIZE, TYPE }; + // glGetProgramResourceName( program, UNIFORM, index, bufSize, length, name ); + // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[0], 1, NULL, size ); + // glGetProgramResourceiv( program, GL_UNIFORM, index, 1, &props[1], 1, NULL, (int *)type ); + // + // The latter is only available in GL 4.4 and GLES 3.1 + + switch( dataType ) + { + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_1D_ARRAY_SHADOW: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_CUBE_SHADOW: + + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + + case GL_SAMPLER_CUBE_MAP_ARRAY: + case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: + case GL_INT_SAMPLER_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: + + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + + case GL_SAMPLER_BUFFER: + case GL_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + { + auto UniformLocation = glGetUniformLocation( GLProgram, Name.data() ); + // Note that glGetUniformLocation(program, name) is equivalent to + // glGetProgramResourceLocation( program, GL_UNIFORM, name ); + // The latter is only available in GL 4.4 and GLES 3.1 + + RemoveArrayBrackets(Name.data()); + auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); + + RefCntAutoPtr<SamplerGLImpl> pStaticSampler; + for (Uint32 s = 0; s < NumStaticSamplers; ++s) + { + if (strcmp(Name.data(), StaticSamplers[s].TextureName) == 0) + { + pDeviceGLImpl->CreateSampler(StaticSamplers[s].Desc, reinterpret_cast<ISampler**>(static_cast<SamplerGLImpl**>(&pStaticSampler)) ); + break; + } + } + m_Samplers.emplace_back( Name.data(), size, VarType, UniformLocation, dataType, pStaticSampler ); + break; + } + + case GL_IMAGE_1D: + case GL_IMAGE_2D: + case GL_IMAGE_3D: + case GL_IMAGE_2D_RECT: + case GL_IMAGE_CUBE: + case GL_IMAGE_BUFFER: + case GL_IMAGE_1D_ARRAY: + case GL_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_IMAGE_2D_MULTISAMPLE: + case GL_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_INT_IMAGE_1D: + case GL_INT_IMAGE_2D: + case GL_INT_IMAGE_3D: + case GL_INT_IMAGE_2D_RECT: + case GL_INT_IMAGE_CUBE: + case GL_INT_IMAGE_BUFFER: + case GL_INT_IMAGE_1D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_2D_MULTISAMPLE: + case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_IMAGE_1D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_2D_RECT: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + { + auto UniformLocation = glGetUniformLocation( GLProgram, Name.data() ); + + GLint BindingPoint = -1; + // The value of an image uniform is an integer specifying the image unit accessed + glGetUniformiv( GLProgram, UniformLocation, &BindingPoint ); + CHECK_GL_ERROR_AND_THROW("Failed to get image binding point"); + VERIFY( BindingPoint >= 0, "Incorrect binding point" ); + + RemoveArrayBrackets(Name.data()); + auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); + m_Images.emplace_back( Name.data(), size, VarType, BindingPoint, dataType ); + break; + } + + default: + // Some other uniform type like scalar, matrix etc. + break; + } + } + + for( int i = 0; i < numActiveUniformBlocks; i++ ) + { + // In contrast to shader uniforms, every element in uniform block array is enumerated individually + GLsizei NameLen = 0; + glGetActiveUniformBlockName( GLProgram, i, MaxNameLength, &NameLen, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform block name\n" ); + VERIFY( NameLen < MaxNameLength && NameLen == strlen( Name.data() ), "Incorrect uniform block name" ); + + // glGetActiveUniformBlockName( program, uniformBlockIndex, bufSize, length, uniformBlockName ); + // is equivalent to + // glGetProgramResourceName(program, GL_UNIFORM_BLOCK, uniformBlockIndex, bufSize, length, uniformBlockName); + + auto UniformBlockIndex = glGetUniformBlockIndex( GLProgram, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get active uniform block index\n" ); + // glGetUniformBlockIndex( program, uniformBlockName ); + // is equivalent to + // glGetProgramResourceIndex( program, GL_UNIFORM_BLOCK, uniformBlockName ); + + GLint ArraySize = 1; + auto* OpenBacketPtr = strchr(Name.data(), '['); + if(OpenBacketPtr != nullptr) + { + auto Ind = atoi(OpenBacketPtr+1); + ArraySize = std::max(ArraySize, Ind+1); + *OpenBacketPtr = 0; + if (m_UniformBlocks.size() > 0) + { + // Look at previous uniform block to check if it is the same array + auto &LastBlock = m_UniformBlocks.back(); + if (LastBlock.Name.compare(Name.data()) == 0) + { + ArraySize = std::max(ArraySize, static_cast<GLint>(LastBlock.pResources.size())); + VERIFY(UniformBlockIndex == LastBlock.Index + Ind, "Uniform block indices are expected to be continuous"); + LastBlock.pResources.resize(ArraySize); + continue; + } + else + { +#ifdef _DEBUG + for(const auto &ub : m_UniformBlocks) + VERIFY(ub.Name.compare(Name.data()) != 0, "Uniform block with the name \"", ub.Name, "\" has already been enumerated") +#endif + } + } + } + + + auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); + m_UniformBlocks.emplace_back( Name.data(), ArraySize, VarType, UniformBlockIndex ); + } + + for( int i = 0; i < numActiveShaderStorageBlocks; ++i ) + { + GLsizei Length = 0; + glGetProgramResourceName( GLProgram, GL_SHADER_STORAGE_BLOCK, i, MaxNameLength, &Length, Name.data() ); + CHECK_GL_ERROR_AND_THROW( "Unable to get shader storage block name\n" ); + VERIFY( Length < MaxNameLength && Length == strlen( Name.data() ), "Incorrect shader storage block name" ); + + GLenum Props[] = {GL_BUFFER_BINDING}; + GLint Binding = -1; + GLint ValuesWritten = 0; + glGetProgramResourceiv( GLProgram, GL_SHADER_STORAGE_BLOCK, i, _countof(Props), Props, 1, &ValuesWritten, &Binding ); + CHECK_GL_ERROR_AND_THROW( "Unable to get shader storage block binding & array size\n" ); + VERIFY( ValuesWritten == _countof(Props), "Unexpected number of values written" ); + VERIFY( Binding >= 0, "Incorrect shader storage block binding" ); + + Int32 ArraySize = 1; + auto* OpenBacketPtr = strchr(Name.data(), '['); + if(OpenBacketPtr != nullptr) + { + auto Ind = atoi(OpenBacketPtr+1); + ArraySize = std::max(ArraySize, Ind+1); + *OpenBacketPtr = 0; + if (m_StorageBlocks.size() > 0) + { + // Look at previous storage block to check if it is the same array + auto &LastBlock = m_StorageBlocks.back(); + if (LastBlock.Name.compare(Name.data()) == 0) + { + ArraySize = std::max(ArraySize, static_cast<GLint>(LastBlock.pResources.size())); + VERIFY(Binding == LastBlock.Binding + Ind, "Storage block bindings are expected to be continuous"); + LastBlock.pResources.resize(ArraySize); + continue; + } + else + { +#ifdef _DEBUG + for(const auto &sb : m_StorageBlocks) + VERIFY(sb.Name.compare(Name.data()) != 0, "Storage block with the name \"", sb.Name, "\" has already been enumerated") +#endif + } + } + } + + auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); + m_StorageBlocks.emplace_back( Name.data(), ArraySize, VarType, Binding ); + } + } + + static bool CheckType(SHADER_VARIABLE_TYPE Type, SHADER_VARIABLE_TYPE* AllowedTypes, Uint32 NumAllowedTypes) + { + for(Uint32 i=0; i < NumAllowedTypes; ++i) + if(Type == AllowedTypes[i]) + return true; + + return false; + } + + void GLProgramResources::Clone(const GLProgramResources& SrcLayout, + SHADER_VARIABLE_TYPE *VarTypes, + Uint32 NumVarTypes, + IObject &Owner) + { + for (auto ub = SrcLayout.m_UniformBlocks.begin(); ub != SrcLayout.m_UniformBlocks.end(); ++ub) + { + if(CheckType(ub->VarType, VarTypes, NumVarTypes)) + m_UniformBlocks.emplace_back( ub->Name.c_str(), ub->pResources.size(), ub->VarType, ub->Index ); + } + + for (auto sam = SrcLayout.m_Samplers.begin(); sam != SrcLayout.m_Samplers.end(); ++sam) + { + if(CheckType(sam->VarType, VarTypes, NumVarTypes)) + m_Samplers.emplace_back( sam->Name.c_str(), sam->pResources.size(), sam->VarType, sam->Location, sam->Type, const_cast<SamplerGLImpl*>(sam->pStaticSampler.RawPtr()) ); + } + + for (auto img = SrcLayout.m_Images.begin(); img != SrcLayout.m_Images.end(); ++img) + { + if(CheckType(img->VarType, VarTypes, NumVarTypes)) + m_Images.emplace_back( img->Name.c_str(), img->pResources.size(), img->VarType, img->BindingPoint, img->Type ); + } + + for (auto sb = SrcLayout.m_StorageBlocks.begin(); sb != SrcLayout.m_StorageBlocks.end(); ++sb) + { + if(CheckType(sb->VarType, VarTypes, NumVarTypes)) + m_StorageBlocks.emplace_back( sb->Name.c_str(), sb->pResources.size(), sb->VarType, sb->Binding ); + } + + InitVariables(Owner); + } + + void GLProgramResources::InitVariables(IObject &Owner) + { + // After all program resources are loaded, we can populate shader variable hash map. + // The map contains raw pointers, but none of the arrays will ever change. +#define STORE_SHADER_VARIABLES(ResArr)\ + { \ + auto& Arr = ResArr; \ + for( auto it = Arr.begin(); it != Arr.end(); ++it ) \ + /* HashMapStringKey will make a copy of the string*/ \ + m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(it->Name), CGLShaderVariable(Owner, *it) ) ); \ + } + + STORE_SHADER_VARIABLES(m_UniformBlocks) + STORE_SHADER_VARIABLES(m_Samplers) + STORE_SHADER_VARIABLES(m_Images) + STORE_SHADER_VARIABLES(m_StorageBlocks) +#undef STORE_SHADER_VARIABLES + } + + IShaderVariable* GLProgramResources::GetShaderVariable( const Char* Name ) + { + // Name will be implicitly converted to HashMapStringKey without making a copy + auto it = m_VariableHash.find( Name ); + if( it == m_VariableHash.end() ) + { + return nullptr; + } + return &it->second; + } + + template<typename TResArrayType> + void BindResourcesHelper(TResArrayType &ResArr, IResourceMapping *pResourceMapping, Uint32 Flags) + { + for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) + { + auto &Name = res->Name; + for(Uint32 ArrInd = 0; ArrInd < res->pResources.size(); ++ArrInd) + { + auto &CurrResource = res->pResources[ArrInd]; + if( Flags & BIND_SHADER_RESOURCES_RESET_BINDINGS ) + CurrResource.Release(); + + if( (Flags & BIND_SHADER_RESOURCES_UPDATE_UNRESOLVED) && CurrResource ) + continue; // Skip already resolved resources + + RefCntAutoPtr<IDeviceObject> pNewRes; + pResourceMapping->GetResource( Name.c_str(), static_cast<IDeviceObject**>(&pNewRes), ArrInd ); + + if( !pNewRes ) + { + if( Flags & BIND_SHADER_RESOURCES_ALL_RESOLVED ) + LOG_ERROR_MESSAGE( "Resource \"", Name, "\" is not found in the resource mapping" ); + continue; + } + CurrResource = pNewRes; + } + } + } + + void GLProgramResources::BindResources( IResourceMapping *pResourceMapping, Uint32 Flags ) + { + if( !pResourceMapping ) + return; + + BindResourcesHelper( m_UniformBlocks, pResourceMapping, Flags ); + BindResourcesHelper( m_Samplers, pResourceMapping, Flags ); + BindResourcesHelper( m_Images, pResourceMapping, Flags ); + BindResourcesHelper( m_StorageBlocks, pResourceMapping, Flags ); + } + +#ifdef VERIFY_RESOURCE_BINDINGS + template<typename TResArrayType> + void dbgVerifyResourceBindingsHelper(TResArrayType &ResArr, const Char *VarType) + { + for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) + { + auto &Name = res->Name; + for(Uint32 ArrInd = 0; ArrInd < res->pResources.size(); ++ArrInd) + { + if( !res->pResources[ArrInd] ) + { + if( res->pResources.size() > 1) + LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", res->Name, "[", ArrInd, "]\"" ) + else + LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", res->Name, "\"" ) + } + } + } + } + + void GLProgramResources::dbgVerifyResourceBindings() + { + dbgVerifyResourceBindingsHelper( m_UniformBlocks, "uniform block" ); + dbgVerifyResourceBindingsHelper( m_Samplers, "sampler" ); + dbgVerifyResourceBindingsHelper( m_Images, "image" ); + dbgVerifyResourceBindingsHelper( m_StorageBlocks, "shader storage block" ); + } +#endif + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/GLStubs.cpp b/Graphics/GraphicsEngineOpenGL/src/GLStubs.cpp index d200bc33..585d79cd 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLStubs.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLStubs.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp b/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp index 27e3e81a..2fe7950b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLTypeConversions.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsEngineOpenGL/src/HLSL2GLSLConverter.cpp b/Graphics/GraphicsEngineOpenGL/src/HLSL2GLSLConverter.cpp index 252383ba..bade1f8b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/HLSL2GLSLConverter.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/HLSL2GLSLConverter.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1631,15 +1631,15 @@ void HLSL2GLSLConverter::ProcessTextureDeclaration( TokenListType::iterator &Tok ObjectsTypeHashType &Objects ) { auto TexDeclToken = Token; - auto TextureType = TexDeclToken->Type; + auto TextureDim = TexDeclToken->Type; // Texture2D < float > ... ; // ^ bool IsRWTexture = - TextureType == TokenType::RWTexture1D || - TextureType == TokenType::RWTexture1DArray || - TextureType == TokenType::RWTexture2D || - TextureType == TokenType::RWTexture2DArray || - TextureType == TokenType::RWTexture3D; + TextureDim == TokenType::RWTexture1D || + TextureDim == TokenType::RWTexture1DArray || + TextureDim == TokenType::RWTexture2D || + TextureDim == TokenType::RWTexture2DArray || + TextureDim == TokenType::RWTexture3D; ++Token; // Texture2D < float > ... ; @@ -1700,8 +1700,8 @@ void HLSL2GLSLConverter::ProcessTextureDeclaration( TokenListType::iterator &Tok CHECK_EOF(); // Texture2D < float > ... ; // ^ - if( (TextureType == TokenType::Texture2DMS || - TextureType == TokenType::Texture2DMSArray ) && + if( (TextureDim == TokenType::Texture2DMS || + TextureDim == TokenType::Texture2DMSArray ) && Token->Literal == "," ) { // Texture2DMS < float, 4 > ... ; @@ -1754,7 +1754,7 @@ void HLSL2GLSLConverter::ProcessTextureDeclaration( TokenListType::iterator &Tok else GLSLSampler.append( "sampler" ); - switch( TextureType ) + switch( TextureDim ) { case TokenType::RWTexture1D: case TokenType::Texture1D: GLSLSampler += "1D"; break; @@ -1864,7 +1864,7 @@ void HLSL2GLSLConverter::ProcessTextureDeclaration( TokenListType::iterator &Tok // ^ // Insert empty token that will contain next sampler/image declaration - TexDeclToken = m_Tokens.insert( Token, TokenInfo(TextureType, "", "\n") ); + TexDeclToken = m_Tokens.insert( Token, TokenInfo(TextureDim, "", "\n") ); // Texture2D TexName; // <Texture Declaration TBD> TexName2 ; // ^ ^ diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp new file mode 100644 index 00000000..9701a47a --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -0,0 +1,169 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "PipelineStateGLImpl.h" +#include "RenderDeviceGLImpl.h" +#include "ShaderGLImpl.h" +#include "ShaderResourceBindingGLImpl.h" +#include "EngineMemory.h" + +namespace Diligent +{ + +PipelineStateGLImpl::PipelineStateGLImpl(FixedBlockMemoryAllocator &PSOAllocator, class RenderDeviceGLImpl *pDeviceGL, const PipelineStateDesc& PipelineDesc, bool bIsDeviceInternal) : + TPipelineStateBase(PSOAllocator, pDeviceGL, PipelineDesc, bIsDeviceInternal), + m_GLProgram(false), + m_GLProgPipeline(false) +{ + + auto &DeviceCaps = pDeviceGL->GetDeviceCaps(); + VERIFY( DeviceCaps.DevType != DeviceType::Undefined, "Device caps are not initialized" ); + bool bIsProgramPipelineSupported = DeviceCaps.bSeparableProgramSupported; + + LinkGLProgram(bIsProgramPipelineSupported); +} + +void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported) +{ + if( bIsProgramPipelineSupported ) + { + // Create new progam pipeline + m_GLProgPipeline.Create(); + for( Uint32 Shader = 0; Shader < m_NumShaders; ++Shader ) + { + auto *pCurrShader = static_cast<ShaderGLImpl*>(m_ppShaders[Shader]); + auto GLShaderBit = ShaderTypeToGLShaderBit( pCurrShader->GetDesc().ShaderType ); + // If the program has an active code for each stage mentioned in set flags, + // then that code will be used by the pipeline. If program is 0, then the given + // stages are cleared from the pipeline. + glUseProgramStages( m_GLProgPipeline, GLShaderBit, pCurrShader->m_GlProgObj ); + CHECK_GL_ERROR( "glUseProgramStages() failed" ); + } + } + else + { + // Create new progam + m_GLProgram.Create(); + for( Uint32 Shader = 0; Shader < m_NumShaders; ++Shader ) + { + auto *pCurrShader = static_cast<ShaderGLImpl*>(m_ppShaders[Shader]); + glAttachShader( m_GLProgram, pCurrShader->m_GLShaderObj ); + CHECK_GL_ERROR( "glAttachShader() failed" ); + } + glLinkProgram( m_GLProgram ); + CHECK_GL_ERROR( "glLinkProgram() failed" ); + int IsLinked = GL_FALSE; + glGetProgramiv( m_GLProgram, GL_LINK_STATUS, (int *)&IsLinked ); + CHECK_GL_ERROR( "glGetProgramiv() failed" ); + if( !IsLinked ) + { + int LengthWithNull = 0, Length = 0; + // Notice that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. + // The length of the info log includes a null terminator. + glGetProgramiv( m_GLProgram, GL_INFO_LOG_LENGTH, &LengthWithNull ); + + // The maxLength includes the NULL character + std::vector<char> shaderProgramInfoLog( LengthWithNull ); + + // Notice that glGetProgramInfoLog is used, not glGetShaderInfoLog. + glGetProgramInfoLog( m_GLProgram, LengthWithNull, &Length, &shaderProgramInfoLog[0] ); + VERIFY( Length == LengthWithNull-1, "Incorrect program info log len" ); + LOG_ERROR_MESSAGE( "Failed to link shader program:\n", &shaderProgramInfoLog[0], '\n'); + UNEXPECTED( "glLinkProgram failed" ); + } + + // Detach shaders from the program object + for( Uint32 Shader = 0; Shader < m_NumShaders; ++Shader ) + { + auto *pCurrShader = static_cast<ShaderGLImpl*>(m_ppShaders[Shader]); + glDetachShader( m_GLProgram, pCurrShader->m_GLShaderObj ); + CHECK_GL_ERROR( "glDetachShader() failed" ); + } + + std::vector<ShaderVariableDesc> MergedVarTypesArray; + std::vector<StaticSamplerDesc> MergedStSamArray; + SHADER_VARIABLE_TYPE DefaultVarType = SHADER_VARIABLE_TYPE_STATIC; + for( Uint32 Shader = 0; Shader < m_NumShaders; ++Shader ) + { + auto *pCurrShader = static_cast<ShaderGLImpl*>(m_ppShaders[Shader]); + const auto& Desc = pCurrShader->GetDesc(); + if (Shader == 0) + { + DefaultVarType = Desc.DefaultVariableType; + for (Uint32 v = 0; v < Desc.NumVariables; ++v) + { + MergedVarTypesArray.push_back(Desc.VariableDesc[v]); + } + for (Uint32 s = 0; s < Desc.NumStaticSamplers; ++s) + { + MergedStSamArray.push_back(Desc.StaticSamplers[s]); + } + } + else + { + if (DefaultVarType != Desc.DefaultVariableType) + { + LOG_ERROR("Inconsistent default variable types for shaders in one program"); + } + } + } + + auto pDeviceGL = static_cast<RenderDeviceGLImpl*>( GetDevice() ); + m_GLProgram.InitResources(pDeviceGL, DefaultVarType, MergedVarTypesArray.data(), static_cast<Uint32>(MergedVarTypesArray.size()), MergedStSamArray.data(), static_cast<Uint32>(MergedStSamArray.size()), *this); + } +} + + +PipelineStateGLImpl::~PipelineStateGLImpl() +{ + static_cast<RenderDeviceGLImpl*>( GetDevice() )->m_VAOCache.OnDestroyPSO(this); +} + +IMPLEMENT_QUERY_INTERFACE( PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase ) + +void PipelineStateGLImpl::BindShaderResources(IResourceMapping *pResourceMapping, Uint32 Flags) +{ + if( GetDevice()->GetDeviceCaps().bSeparableProgramSupported ) + { + for( Uint32 s = 0; s < m_NumShaders; ++s ) + { + m_ppShaders[s]->BindResources( pResourceMapping, Flags ); + } + } + else + { + if( m_GLProgram ) + m_GLProgram.BindConstantResources( pResourceMapping, Flags ); + } +} + +void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding) +{ + auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>( GetDevice() ); + auto &SRBAllocator = pRenderDeviceGL->GetSRBAllocator(); + auto pResBinding = NEW( SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl, this); + pResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(ppShaderResourceBinding)); +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/ProgramPipelineCache.cpp b/Graphics/GraphicsEngineOpenGL/src/ProgramPipelineCache.cpp deleted file mode 100644 index 4d5b3902..00000000 --- a/Graphics/GraphicsEngineOpenGL/src/ProgramPipelineCache.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright 2015 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#include "pch.h" - -#include "ProgramPipelineCache.h" -#include "ShaderGLImpl.h" -#include "RenderDeviceGLImpl.h" - -namespace Diligent -{ - -ProgramPipelineCache::ProgramPipelineCache( RenderDeviceGLImpl *pRenderDeviceOpenGL ) -{ - auto &DeviceCaps = pRenderDeviceOpenGL->GetDeviceCaps(); - VERIFY( DeviceCaps.DevType != DeviceType::Undefined, "Device caps are not initialized" ); - m_bIsProgramPipelineSupported = DeviceCaps.bSeparableProgramSupported; - - m_Cache.max_load_factor(0.5f); - m_ShaderToKey.max_load_factor(0.5f); -} - -ProgramPipelineCache::~ProgramPipelineCache() -{ - VERIFY( m_Cache.empty(), "Program pipeline cache is not empty" ); - VERIFY( m_ShaderToKey.empty(), "Not all shaders that use the program pipleine are released" ); -} - -ProgramPipelineCache::CacheElementType &ProgramPipelineCache::GetProgramPipeline( RefCntAutoPtr<IShader> *ppShaders, Uint32 NumShadersToSet ) -{ - ThreadingTools::LockHelper LockHelper(m_CacheLockFlag); - - PipelineCacheKey Key = {0}; - // Create a key for the look-up - for(Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader) - { - auto *pCurrShader = static_cast<IShader*>(ppShaders[Shader].RawPtr()); - switch(pCurrShader->GetDesc().ShaderType) - { - case SHADER_TYPE_VERTEX: Key.pVS = pCurrShader; break; - case SHADER_TYPE_PIXEL: Key.pPS = pCurrShader; break; - case SHADER_TYPE_GEOMETRY:Key.pGS = pCurrShader; break; - case SHADER_TYPE_HULL: Key.pHS = pCurrShader; break; - case SHADER_TYPE_DOMAIN: Key.pDS = pCurrShader; break; - case SHADER_TYPE_COMPUTE: Key.pCS = pCurrShader; break; - default: UNEXPECTED( "Unknown shader type" ); - } - } - - // Try to find the Pipeline in the map - auto It = m_Cache.find(Key); - if( It != m_Cache.end() ) - { - return It->second; - } - else - { - CacheElementType NewPipelineOrProg; - - if( m_bIsProgramPipelineSupported ) - { - // Create new progam pipeline - NewPipelineOrProg.Pipeline.Create(); - for( Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader ) - { - auto *pCurrShader = static_cast<ShaderGLImpl*>(ppShaders[Shader].RawPtr()); - auto GLShaderBit = ShaderTypeToGLShaderBit( pCurrShader->GetDesc().ShaderType ); - // If the program has an active code for each stage mentioned in set flags, - // then that code will be used by the pipeline. If program is 0, then the given - // stages are cleared from the pipeline. - glUseProgramStages( NewPipelineOrProg.Pipeline, GLShaderBit, pCurrShader->m_GlProgObj ); - CHECK_GL_ERROR( "glUseProgramStages() failed" ); - } - } - else - { - // Create new progam - NewPipelineOrProg.Program.Create(); - GLuint GLProgram = NewPipelineOrProg.Program; - for( Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader ) - { - auto *pCurrShader = static_cast<ShaderGLImpl*>(ppShaders[Shader].RawPtr()); - glAttachShader( GLProgram, pCurrShader->m_GLShaderObj ); - CHECK_GL_ERROR( "glAttachShader() failed" ); - } - glLinkProgram( GLProgram ); - CHECK_GL_ERROR( "glLinkProgram() failed" ); - int IsLinked = GL_FALSE; - glGetProgramiv( GLProgram, GL_LINK_STATUS, (int *)&IsLinked ); - CHECK_GL_ERROR( "glGetProgramiv() failed" ); - if( !IsLinked ) - { - int LengthWithNull = 0, Length = 0; - // Notice that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. - // The length of the info log includes a null terminator. - glGetProgramiv( GLProgram, GL_INFO_LOG_LENGTH, &LengthWithNull ); - - // The maxLength includes the NULL character - std::vector<char> shaderProgramInfoLog( LengthWithNull ); - - // Notice that glGetProgramInfoLog is used, not glGetShaderInfoLog. - glGetProgramInfoLog( GLProgram, LengthWithNull, &Length, &shaderProgramInfoLog[0] ); - VERIFY( Length == LengthWithNull-1, "Incorrect program info log len" ); - LOG_ERROR_MESSAGE( "Failed to link shader program:\n", &shaderProgramInfoLog[0], '\n'); - UNEXPECTED( "glLinkProgram failed" ); - } - - // Detach shaders from the program object - for( Uint32 Shader = 0; Shader < NumShadersToSet; ++Shader ) - { - auto *pCurrShader = static_cast<ShaderGLImpl*>(ppShaders[Shader].RawPtr()); - glDetachShader( GLProgram, pCurrShader->m_GLShaderObj ); - CHECK_GL_ERROR( "glDetachShader() failed" ); - } - - NewPipelineOrProg.Program.LoadUniforms(); - } - - auto NewElems = m_Cache.emplace( make_pair( Key, std::move( NewPipelineOrProg ) ) ); - // New element must be actually inserted - VERIFY( NewElems.second, "Element was not inserted into the hash" ); - if( Key.pVS )m_ShaderToKey.insert( make_pair(Key.pVS, Key) ); - if( Key.pGS )m_ShaderToKey.insert( make_pair(Key.pGS, Key) ); - if( Key.pPS )m_ShaderToKey.insert( make_pair(Key.pPS, Key) ); - if( Key.pDS )m_ShaderToKey.insert( make_pair(Key.pDS, Key) ); - if( Key.pHS )m_ShaderToKey.insert( make_pair(Key.pHS, Key) ); - if( Key.pCS )m_ShaderToKey.insert( make_pair(Key.pCS, Key) ); - - return NewElems.first->second; - } -} - -void ProgramPipelineCache::OnDestroyShader(IShader *pShader) -{ - ThreadingTools::LockHelper LockHelper(m_CacheLockFlag); - auto EqualRange = m_ShaderToKey.equal_range(pShader); - for(auto It = EqualRange.first; It != EqualRange.second; ++It) - { - m_Cache.erase(It->second); - } - m_ShaderToKey.erase(EqualRange.first, EqualRange.second); -} - -} diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp index d7efc211..fefecf2a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,33 +21,48 @@ * of the possibility of such damages. */ +/// \file +/// Routines that initialize OpenGL/GLES-based engine implementation + #include "pch.h" #include "RenderDeviceFactoryOpenGL.h" #include "RenderDeviceGLImpl.h" #include "DeviceContextGLImpl.h" #include "SwapChainGLImpl.h" +#include "EngineMemory.h" #ifdef PLATFORM_ANDROID #include "RenderDeviceGLESImpl.h" #endif -using namespace Diligent; -using namespace Diligent; - -extern "C" +namespace Diligent { -#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_WINDOWS_STORE) +#if defined(PLATFORM_WIN32) || defined(PLATFORM_UNIVERSAL_WINDOWS) typedef RenderDeviceGLImpl TRenderDeviceGLImpl; #elif defined(PLATFORM_ANDROID) typedef RenderDeviceGLESImpl TRenderDeviceGLImpl; #endif -API_QUALIFIER + +/// Creates render device, device context and swap chain for OpenGL/GLES-based engine implementation + +/// \param [in] CreationAttribs - Engine creation attributes. +/// \param [out] ppDevice - Address of the memory location where pointer to +/// the created device will be written. +/// \param [out] ppImmediateContext - Address of the memory location where pointers to +/// the immediate context will be written. +/// \param [in] SCDesc - Swap chain description. +/// \param [in] pNativeWndHandle - Platform-specific native handle of the window +/// the swap chain will be associated with: +/// * On Win32 platform, this should be window handle (HWND) +/// * On Android platform, this should be a pointer to the native window (ANativeWindow*) +/// \param [out] ppSwapChain - Address of the memory location where pointer to the new +/// swap chain will be written. void CreateDeviceAndSwapChainGL( const EngineCreationAttribs& CreationAttribs, IRenderDevice **ppDevice, IDeviceContext **ppImmediateContext, - const SwapChainDesc& SwapChainDesc, + const SwapChainDesc& SCDesc, void *pNativeWndHandle, Diligent::ISwapChain **ppSwapChain ) { @@ -55,33 +70,35 @@ void CreateDeviceAndSwapChainGL( const EngineCreationAttribs& CreationAttribs, if( !ppDevice || !ppImmediateContext || !ppSwapChain ) return; + SetRawAllocator(CreationAttribs.pRawMemAllocator); + *ppDevice = nullptr; *ppImmediateContext = nullptr; *ppSwapChain = nullptr; try { + auto &RawMemAllocator = GetRawAllocator(); + ContextInitInfo InitInfo; InitInfo.pNativeWndHandle = pNativeWndHandle; - InitInfo.SwapChainAttribs = SwapChainDesc; - RenderDeviceGLImpl *pRenderDeviceOpenGL( new TRenderDeviceGLImpl( InitInfo ) ); + InitInfo.SwapChainAttribs = SCDesc; + RenderDeviceGLImpl *pRenderDeviceOpenGL( NEW(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl, InitInfo ) ); pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); - DeviceContextGLImpl *pDeviceContextOpenGL( new DeviceContextGLImpl( pRenderDeviceOpenGL ) ); + DeviceContextGLImpl *pDeviceContextOpenGL( NEW(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl, pRenderDeviceOpenGL, false ) ); // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceOpenGL will // keep a weak reference to the context pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext) ); pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); - SwapChainGLImpl *pSwapChainGL = new SwapChainGLImpl(SwapChainDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); + SwapChainGLImpl *pSwapChainGL = NEW(RawMemAllocator, "SwapChainGLImpl instance", SwapChainGLImpl, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); pDeviceContextOpenGL->SetSwapChain(pSwapChainGL); // Bind default framebuffer and viewport pDeviceContextOpenGL->SetRenderTargets( 0, nullptr, nullptr ); pDeviceContextOpenGL->SetViewports( 1, nullptr, 0, 0 ); - - pDeviceContextOpenGL->CreateDefaultStates(); } catch( const std::runtime_error & ) { @@ -107,4 +124,37 @@ void CreateDeviceAndSwapChainGL( const EngineCreationAttribs& CreationAttribs, } } +#ifdef DOXYGEN +/// Loads OpenGL-based engine implementation and exports factory functions +/// \param [out] CreateDeviceFunc - Pointer to the function that creates render device, device context and swap chain. +/// See CreateDeviceAndSwapChainGL(). +/// \remarks Depending on the configuration and platform, the function loads different dll: +/// Platform\\Configuration | Debug | Release +/// --------------------------|------------------------------|---------------------------- +/// Win32/x86 | GraphicsEngineOpenGL_32d.dll | GraphicsEngineOpenGL_32r.dll +/// Win32/x64 | GraphicsEngineOpenGL_64d.dll | GraphicsEngineOpenGL_64r.dll +/// +/// To load the library on Android, it is necessary to call System.loadLibrary("GraphicsEngineOpenGL") from Java. +void LoadGraphicsEngineOpenGL(CreateDeviceAndSwapChainGLType &CreateDeviceFunc) +{ + // This function is only required because DoxyGen refuses to generate documentation for a static function when SHOW_FILES==NO + #error This function must never be compiled; +} +#endif + +} + +extern "C" +{ +API_QUALIFIER +void CreateDeviceAndSwapChainGL( const EngineCreationAttribs& CreationAttribs, + IRenderDevice **ppDevice, + IDeviceContext **ppImmediateContext, + const SwapChainDesc& SwapChainDesc, + void *pNativeWndHandle, + Diligent::ISwapChain **ppSwapChain ) +{ + Diligent::CreateDeviceAndSwapChainGL( CreationAttribs, ppDevice, ppImmediateContext, SwapChainDesc, pNativeWndHandle, ppSwapChain ); +} + } diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp index 932cd4d6..400cf697 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLESImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,8 +27,8 @@ namespace Diligent { - RenderDeviceGLESImpl::RenderDeviceGLESImpl( const ContextInitInfo &InitInfo ) : - RenderDeviceGLImpl( InitInfo ) + RenderDeviceGLESImpl::RenderDeviceGLESImpl( IMemoryAllocator &RawMemAllocator, const ContextInitInfo &InitInfo ) : + RenderDeviceGLImpl( RawMemAllocator, InitInfo ) { } diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index fafa7f51..ad5f8d4c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,29 +26,29 @@ #include "RenderDeviceGLImpl.h" #include "BufferGLImpl.h" -#include "VertexDescGLImpl.h" #include "ShaderGLImpl.h" #include "VAOCache.h" -#include "ProgramPipelineCache.h" #include "Texture1D_OGL.h" #include "Texture1DArray_OGL.h" #include "Texture2D_OGL.h" #include "Texture2DArray_OGL.h" #include "Texture3D_OGL.h" +#include "TextureCube_OGL.h" +#include "TextureCubeArray_OGL.h" #include "SamplerGLImpl.h" -#include "DSStateGLImpl.h" -#include "RasterizerStateGLImpl.h" -#include "BlendStateGLImpl.h" #include "DeviceContextGLImpl.h" #include "GLTypeConversions.h" +#include "PipelineStateGLImpl.h" +#include "ShaderResourceBindingGLImpl.h" +#include "EngineMemory.h" namespace Diligent { -RenderDeviceGLImpl :: RenderDeviceGLImpl(const ContextInitInfo &InitInfo): +RenderDeviceGLImpl :: RenderDeviceGLImpl(IMemoryAllocator &RawMemAllocator, const ContextInitInfo &InitInfo): + TRenderDeviceBase(RawMemAllocator, 0, sizeof(TextureBaseGL), sizeof(TextureViewGLImpl), sizeof(BufferGLImpl), sizeof(BufferViewGLImpl), sizeof(ShaderGLImpl), sizeof(SamplerGLImpl), sizeof(PipelineStateGLImpl), sizeof(ShaderResourceBindingGLImpl)), // Device caps must be filled in before the constructor of Pipeline Cache is called! m_GLContext(InitInfo, m_DeviceCaps), - m_PipelineCache(this), m_EmptyVAO(true), m_TexRegionRender(this) { @@ -89,7 +89,7 @@ void RenderDeviceGLImpl :: CreateBuffer(const BufferDesc& BuffDesc, const Buffer CreateDeviceObject( "buffer", BuffDesc, ppBuffer, [&]() { - BufferGLImpl *pBufferOGL( new BufferGLImpl( this, BuffDesc, BuffData, bIsDeviceInternal ) ); + BufferGLImpl *pBufferOGL( NEW(m_BufObjAllocator, "BufferGLImpl instance", BufferGLImpl, m_BuffViewObjAllocator, this, BuffDesc, BuffData, bIsDeviceInternal ) ); pBufferOGL->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) ); pBufferOGL->CreateDefaultViews(); OnCreateDeviceObject( pBufferOGL ); @@ -102,30 +102,13 @@ void RenderDeviceGLImpl :: CreateBuffer(const BufferDesc& BuffDesc, const Buffer CreateBuffer(BuffDesc, BuffData, ppBuffer, false); } -void RenderDeviceGLImpl::CreateVertexDescription( const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc, bool bIsDeviceInternal ) -{ - CreateDeviceObject( "vertex description", LayoutDesc, ppVertexDesc, - [&]() - { - VertexDescGLImpl *pDescOGL( new VertexDescGLImpl( this, LayoutDesc, bIsDeviceInternal ) ); - pDescOGL->QueryInterface(IID_VertexDescription, reinterpret_cast<IObject**>(ppVertexDesc) ); - - OnCreateDeviceObject( pDescOGL ); - } - ); -} -void RenderDeviceGLImpl::CreateVertexDescription(const LayoutDesc& LayoutDesc, IShader *pVertexShader, IVertexDescription **ppVertexDesc) -{ - CreateVertexDescription(LayoutDesc, pVertexShader, ppVertexDesc, false); -} - void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader, bool bIsDeviceInternal) { CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, [&]() { - ShaderGLImpl *pShaderOGL(new ShaderGLImpl(this, ShaderCreationAttribs, bIsDeviceInternal)); + ShaderGLImpl *pShaderOGL(NEW(m_ShaderObjAllocator, "ShaderGLImpl instance", ShaderGLImpl, this, ShaderCreationAttribs, bIsDeviceInternal)); pShaderOGL->QueryInterface(IID_Shader, reinterpret_cast<IObject**>(ppShader) ); OnCreateDeviceObject( pShaderOGL ); @@ -155,24 +138,32 @@ void RenderDeviceGLImpl :: CreateTexture(const TextureDesc& TexDesc, const Textu TextureBaseGL *pTextureOGL = nullptr; switch(TexDesc.Type) { - case TEXTURE_TYPE_1D: - pTextureOGL = new Texture1D_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + case RESOURCE_DIM_TEX_1D: + pTextureOGL = NEW(m_TexObjAllocator, "Texture1D_OGL instance", Texture1D_OGL, m_TexViewObjAllocator, this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); break; - case TEXTURE_TYPE_1D_ARRAY: - pTextureOGL = new Texture1DArray_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + case RESOURCE_DIM_TEX_1D_ARRAY: + pTextureOGL = NEW(m_TexObjAllocator, "Texture1DArray_OGL instance", Texture1DArray_OGL, m_TexViewObjAllocator, this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); break; - case TEXTURE_TYPE_2D: - pTextureOGL = new Texture2D_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + case RESOURCE_DIM_TEX_2D: + pTextureOGL = NEW(m_TexObjAllocator, "Texture2D_OGL instance", Texture2D_OGL, m_TexViewObjAllocator, this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); break; - case TEXTURE_TYPE_2D_ARRAY: - pTextureOGL = new Texture2DArray_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + case RESOURCE_DIM_TEX_2D_ARRAY: + pTextureOGL = NEW(m_TexObjAllocator, "Texture2DArray_OGL instance", Texture2DArray_OGL, m_TexViewObjAllocator, this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + break; + + case RESOURCE_DIM_TEX_3D: + pTextureOGL = NEW(m_TexObjAllocator, "Texture3D_OGL instance", Texture3D_OGL, m_TexViewObjAllocator, this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + break; + + case RESOURCE_DIM_TEX_CUBE: + pTextureOGL = NEW(m_TexObjAllocator, "TextureCube_OGL instance", TextureCube_OGL, m_TexViewObjAllocator, this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); break; - case TEXTURE_TYPE_3D: - pTextureOGL = new Texture3D_OGL(this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); + case RESOURCE_DIM_TEX_CUBE_ARRAY: + pTextureOGL = NEW(m_TexObjAllocator, "TextureCubeArray_OGL instance", TextureCubeArray_OGL, m_TexViewObjAllocator, this, pDeviceContext, TexDesc, Data, bIsDeviceInternal); break; default: LOG_ERROR_AND_THROW( "Unknown texture type. (Did you forget to initialize the Type member of TextureDesc structure?)" ); @@ -198,7 +189,7 @@ void RenderDeviceGLImpl :: CreateSampler(const SamplerDesc& SamplerDesc, ISample m_SamplersRegistry.Find( SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler) ); if( *ppSampler == nullptr ) { - SamplerGLImpl *pSamplerOGL( new SamplerGLImpl( this, SamplerDesc, bIsDeviceInternal ) ); + SamplerGLImpl *pSamplerOGL( NEW(m_SamplerObjAllocator, "SamplerGLImpl instance", SamplerGLImpl, this, SamplerDesc, bIsDeviceInternal ) ); pSamplerOGL->QueryInterface( IID_Sampler, reinterpret_cast<IObject**>(ppSampler) ); OnCreateDeviceObject( pSamplerOGL ); m_SamplersRegistry.Add( SamplerDesc, *ppSampler ); @@ -212,69 +203,24 @@ void RenderDeviceGLImpl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler CreateSampler(SamplerDesc, ppSampler, false); } -void RenderDeviceGLImpl::CreateDepthStencilState( const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState, bool bIsDeviceInternal ) -{ - CreateDeviceObject( "depth-stencil state", DSSDesc, ppDepthStencilState, - [&]() - { - m_DSSRegistry.Find( DSSDesc, reinterpret_cast<IDeviceObject**>(ppDepthStencilState) ); - if( *ppDepthStencilState == nullptr ) - { - DSStateGLImpl *pDSSOGL( new DSStateGLImpl( this, DSSDesc, bIsDeviceInternal ) ); - pDSSOGL->QueryInterface( IID_DepthStencilState, reinterpret_cast<IObject**>(ppDepthStencilState) ); - OnCreateDeviceObject( pDSSOGL ); - m_DSSRegistry.Add( DSSDesc, pDSSOGL ); - } - } - ); -} -void RenderDeviceGLImpl::CreateDepthStencilState(const DepthStencilStateDesc &DSSDesc, IDepthStencilState **ppDepthStencilState) +void RenderDeviceGLImpl::CreatePipelineState( const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState) { - CreateDepthStencilState( DSSDesc, ppDepthStencilState, false ); + CreatePipelineState(PipelineDesc, ppPipelineState, false); } -void RenderDeviceGLImpl::CreateRasterizerState( const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState, bool bIsDeviceInternal ) +void RenderDeviceGLImpl::CreatePipelineState(const PipelineStateDesc &PipelineDesc, IPipelineState **ppPipelineState, bool bIsDeviceInternal) { - CreateDeviceObject( "rasterizer state", RSDesc, ppRasterizerState, + CreateDeviceObject( "Pipeline state", PipelineDesc, ppPipelineState, [&]() { - m_RSRegistry.Find( RSDesc, reinterpret_cast<IDeviceObject**>(ppRasterizerState) ); - if( *ppRasterizerState == nullptr ) - { - RasterizerStateGLImpl *pRSOGL( new RasterizerStateGLImpl( this, RSDesc, bIsDeviceInternal ) ); - pRSOGL->QueryInterface( IID_RasterizerState, reinterpret_cast<IObject**>(ppRasterizerState) ); - OnCreateDeviceObject( pRSOGL ); - m_RSRegistry.Add( RSDesc, pRSOGL ); - } + PipelineStateGLImpl *pPipelineStateOGL( NEW(m_PSOAllocator, "PipelineStateGLImpl instance", PipelineStateGLImpl, this, PipelineDesc, bIsDeviceInternal ) ); + pPipelineStateOGL->QueryInterface( IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState) ); + OnCreateDeviceObject( pPipelineStateOGL ); } ); } -void RenderDeviceGLImpl::CreateRasterizerState(const RasterizerStateDesc &RSDesc, IRasterizerState **ppRasterizerState) -{ - CreateRasterizerState( RSDesc, ppRasterizerState, false ); -} -void RenderDeviceGLImpl::CreateBlendState( const BlendStateDesc &BSDesc, IBlendState **ppBlendState, bool bIsDeviceInternal ) -{ - CreateDeviceObject( "blend state", BSDesc, ppBlendState, - [&]() - { - m_BSRegistry.Find( BSDesc, reinterpret_cast<IDeviceObject**>(ppBlendState) ); - if( *ppBlendState == nullptr ) - { - BlendStateGLImpl *pBSOGL( new BlendStateGLImpl( this, BSDesc, bIsDeviceInternal ) ); - pBSOGL->QueryInterface( IID_BlendState, reinterpret_cast<IObject**>(ppBlendState) ); - OnCreateDeviceObject( pBSOGL ); - m_BSRegistry.Add( BSDesc, pBSOGL ); - } - } - ); -} -void RenderDeviceGLImpl::CreateBlendState(const BlendStateDesc &BSDesc, IBlendState **ppBlendState) -{ - CreateBlendState( BSDesc, ppBlendState, false ); -} bool RenderDeviceGLImpl::CheckExtension( const Char *ExtensionString ) { diff --git a/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp index c26a6a80..146caa60 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SamplerGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,8 +29,8 @@ namespace Diligent { -SamplerGLImpl::SamplerGLImpl(class RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal) : - TSamplerBase( pDeviceGL, SamplerDesc, bIsDeviceInternal ), +SamplerGLImpl::SamplerGLImpl(FixedBlockMemoryAllocator &SamplerObjAllocator, class RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal) : + TSamplerBase( SamplerObjAllocator, pDeviceGL, SamplerDesc, bIsDeviceInternal ), m_GlSampler(true) { const auto& SamCaps = pDeviceGL->GetDeviceCaps().SamCaps; diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index 0f650bdd..37551e5b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,8 +38,8 @@ static const Char* g_GLSLDefinitions = #include "GLSLDefinitions_inc.h" }; -ShaderGLImpl::ShaderGLImpl(RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal) : - TShaderBase( pDeviceGL, ShaderCreationAttribs.Desc, bIsDeviceInternal ), +ShaderGLImpl::ShaderGLImpl(FixedBlockMemoryAllocator& ShaderObjAllocator, RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal) : + TShaderBase( ShaderObjAllocator, pDeviceGL, ShaderCreationAttribs.Desc, bIsDeviceInternal ), m_GlProgObj(false), m_GLShaderObj( false, GLObjectWrappers::GLShaderObjCreateReleaseHelper( GetGLShaderType( m_Desc.ShaderType ) ) ) { @@ -51,7 +51,7 @@ ShaderGLImpl::ShaderGLImpl(RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAt std::vector<GLint> Lenghts; ShaderStrings.push_back( -#if defined(_WINDOWS) +#if defined(PLATFORM_WIN32) "#version 430 core\n" "#define DESKTOP_GL 1\n" #elif defined(ANDROID) @@ -209,7 +209,7 @@ ShaderGLImpl::ShaderGLImpl(RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAt if(!compiled) { std::stringstream ErrorMsgSS; - ErrorMsgSS << "Failed to compile shader file \""<< ShaderCreationAttribs.FilePath << '\"' << std::endl; + ErrorMsgSS << "Failed to compile shader file \""<< (ShaderCreationAttribs.FilePath != nullptr ? ShaderCreationAttribs.FilePath : "") << '\"' << std::endl; int infoLogLen = 0; // The function glGetShaderiv() tells how many bytes to allocate; the length includes the NULL terminator. glGetShaderiv(ShaderObj, GL_INFO_LOG_LENGTH, &infoLogLen); @@ -275,24 +275,7 @@ ShaderGLImpl::ShaderGLImpl(RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAt // boolean status bit DELETE_STATUS is set to true ShaderObj.Release(); - m_GlProgObj.LoadUniforms(); - - // After all program resources are loaded, we can populate shader variable hash map. - // The map contains raw pointers, but none of the arrays will ever change. -#define STORE_SHADER_VARIABLES(ResArr)\ - { \ - auto& Arr = ResArr; \ - for( auto it = Arr.begin(); it != Arr.end(); ++it ) \ - /* HashMapStringKey will make a copy of the string*/ \ - m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(it->Name), CGLShaderVariable(this, *it) ) ); \ - } - - STORE_SHADER_VARIABLES(m_GlProgObj.GetUniformBlocks()) - STORE_SHADER_VARIABLES(m_GlProgObj.GetSamplers()) - STORE_SHADER_VARIABLES(m_GlProgObj.GetImages()) - STORE_SHADER_VARIABLES(m_GlProgObj.GetStorageBlocks()) -#undef STORE_SHADER_VARIABLES - + m_GlProgObj.InitResources(pDeviceGL, m_Desc.DefaultVariableType, m_Desc.VariableDesc, m_Desc.NumVariables, m_Desc.StaticSamplers, m_Desc.NumStaticSamplers, *this); } else { @@ -302,15 +285,16 @@ ShaderGLImpl::ShaderGLImpl(RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAt ShaderGLImpl::~ShaderGLImpl() { - static_cast<RenderDeviceGLImpl*>( GetDevice() )->m_PipelineCache.OnDestroyShader(this); } IMPLEMENT_QUERY_INTERFACE( ShaderGLImpl, IID_ShaderGL, TShaderBase ) void ShaderGLImpl::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags ) { - if( m_GlProgObj ) - m_GlProgObj.BindResources( pResourceMapping, Flags ); + if( static_cast<GLuint>(m_GlProgObj) ) + { + m_GlProgObj.BindConstantResources( pResourceMapping, Flags ); + } else { static bool FirstTime = true; @@ -329,14 +313,13 @@ IShaderVariable* ShaderGLImpl::GetShaderVariable( const Char* Name ) UNSUPPORTED( "Shader variable queries are currently supported for separable programs only" ); } - // Name will be implicitly converted to HashMapStringKey without making a copy - auto it = m_VariableHash.find( Name ); - if( it == m_VariableHash.end() ) + auto *pShaderVar = m_GlProgObj.GetConstantResources().GetShaderVariable(Name); + if(!pShaderVar) { - LOG_ERROR_MESSAGE( "Shader variable \"", Name, "\" is not found in shader \"", m_Desc.Name ? m_Desc.Name : "", "\". Attempts to set the variable will be silently ignored." ); - return &m_DummyShaderVar; + LOG_ERROR_MESSAGE( "Static shader variable \"", Name, "\" is not found in shader \"", m_Desc.Name ? m_Desc.Name : "", "\". Attempts to set the variable will be silently ignored." ); + pShaderVar = &m_DummyShaderVar; } - return &it->second; + return pShaderVar; } } diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp new file mode 100644 index 00000000..c5bd0f75 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp @@ -0,0 +1,111 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "ShaderResourceBindingGLImpl.h" +#include "PipelineStateGLImpl.h" +#include "ShaderGLImpl.h" +#include "FixedBlockMemoryAllocator.h" + +namespace Diligent +{ + +ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl( FixedBlockMemoryAllocator& SRBAllocator, PipelineStateGLImpl *pPSO) : + TBase( SRBAllocator, pPSO ), + m_DummyShaderVar(*this), + m_wpPSO(pPSO) +{ + SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC}; + if ( static_cast<GLuint>( pPSO->GetGLProgram() ) ) + { + m_DynamicProgResources[0].Clone(pPSO->GetGLProgram().GetAllResources(), VarTypes, _countof(VarTypes), *this); + } + else + { +#define INIT_SHADER(SN)\ + if(auto p##SN = ValidatedCast<ShaderGLImpl>( pPSO->Get##SN() )) \ + { \ + auto &GLProg = p##SN->GetGlProgram(); \ + m_DynamicProgResources[SN##Ind].Clone(GLProg.GetAllResources(), VarTypes, _countof(VarTypes), *this); \ + } + + INIT_SHADER(VS) + INIT_SHADER(PS) + INIT_SHADER(GS) + INIT_SHADER(HS) + INIT_SHADER(DS) + INIT_SHADER(CS) +#undef INIT_SHADER + } +} + +ShaderResourceBindingGLImpl::~ShaderResourceBindingGLImpl() +{ + +} + +IMPLEMENT_QUERY_INTERFACE( ShaderResourceBindingGLImpl, IID_ShaderResourceBindingGL, TBase ) + +void ShaderResourceBindingGLImpl::BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags) +{ + if(ShaderFlags & SHADER_TYPE_VERTEX) + m_DynamicProgResources[VSInd].BindResources(pResMapping, Flags); + if(ShaderFlags & SHADER_TYPE_PIXEL) + m_DynamicProgResources[PSInd].BindResources(pResMapping, Flags); + if(ShaderFlags & SHADER_TYPE_GEOMETRY) + m_DynamicProgResources[GSInd].BindResources(pResMapping, Flags); + if(ShaderFlags & SHADER_TYPE_HULL) + m_DynamicProgResources[HSInd].BindResources(pResMapping, Flags); + if(ShaderFlags & SHADER_TYPE_DOMAIN) + m_DynamicProgResources[DSInd].BindResources(pResMapping, Flags); + if(ShaderFlags & SHADER_TYPE_COMPUTE) + m_DynamicProgResources[CSInd].BindResources(pResMapping, Flags); +} + +IShaderVariable *ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, const char *Name) +{ + auto ShaderInd = GetShaderTypeIndex(ShaderType); + IShaderVariable *pVar = m_DynamicProgResources[ShaderInd].GetShaderVariable(Name); + if( !pVar ) + { + LOG_ERROR_MESSAGE( "Shader variable \"", Name, "\" is not found in the shader resource mapping. Attempts to set the variable will be silently ignored." ); + pVar = &m_DummyShaderVar; + } + return pVar; +} + +static GLProgramResources NullProgramResources; +GLProgramResources &ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl *pdbgPSO) +{ +#ifdef _DEBUG + auto pPSO = m_wpPSO.Lock(); + if (pPSO != pdbgPSO) + { + LOG_ERROR("Shader resource binding does not match the currently bound pipeline state."); + } +#endif + auto ShaderInd = GetShaderTypeIndex(ShaderType); + return m_DynamicProgResources[ShaderInd]; +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp index 42f128df..c70ce61a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +28,11 @@ namespace Diligent { -SwapChainGLImpl::SwapChainGLImpl(const SwapChainDesc& SCDesc, - RenderDeviceGLImpl* pRenderDeviceGL, - DeviceContextGLImpl* pImmediateContextGL) : - TSwapChainBase( pRenderDeviceGL, pImmediateContextGL, pRenderDeviceGL->m_GLContext.GetSwapChainDesc() ) +SwapChainGLImpl::SwapChainGLImpl(IMemoryAllocator &Allocator, + const SwapChainDesc& SCDesc, + RenderDeviceGLImpl* pRenderDeviceGL, + DeviceContextGLImpl* pImmediateContextGL) : + TSwapChainBase( Allocator, pRenderDeviceGL, pImmediateContextGL, pRenderDeviceGL->m_GLContext.GetSwapChainDesc() ) { } diff --git a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp index a853c7ee..64da6934 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,6 @@ namespace Diligent TexRegionRender::TexRegionRender( class RenderDeviceGLImpl *pDeviceGL ) : m_OrigStencilRef(0), - m_OrigSamplesBlendMask(0), m_NumRenderTargets(0) { memset( m_OrigBlendFactors, 0, sizeof(m_OrigBlendFactors) ); @@ -74,25 +73,25 @@ namespace Diligent true // We must indicate the shader is internal device object ); - static const char* SamplerType[TEXTURE_TYPE_NUM_TYPES] = {}; - SamplerType[TEXTURE_TYPE_1D] = "sampler1D"; - SamplerType[TEXTURE_TYPE_1D_ARRAY] = "sampler1DArray"; - SamplerType[TEXTURE_TYPE_2D] = "sampler2D"; - SamplerType[TEXTURE_TYPE_2D_ARRAY] = "sampler2DArray", - SamplerType[TEXTURE_TYPE_3D] = "sampler3D"; + static const char* SamplerType[RESOURCE_DIM_NUM_DIMENSIONS] = {}; + SamplerType[RESOURCE_DIM_TEX_1D] = "sampler1D"; + SamplerType[RESOURCE_DIM_TEX_1D_ARRAY] = "sampler1DArray"; + SamplerType[RESOURCE_DIM_TEX_2D] = "sampler2D"; + SamplerType[RESOURCE_DIM_TEX_2D_ARRAY] = "sampler2DArray", + SamplerType[RESOURCE_DIM_TEX_3D] = "sampler3D"; // There is no texelFetch() for texture cube [array] - //SamplerType[TEXTURE_TYPE_CUBE] = "samplerCube"; - //SamplerType[TEXTURE_TYPE_CUBE_ARRAY] = "smaplerCubeArray"; - - static const char* SrcLocations[TEXTURE_TYPE_NUM_TYPES] = {}; - SrcLocations[TEXTURE_TYPE_1D] = "int(gl_FragCoord.x) + Constants.x"; - SrcLocations[TEXTURE_TYPE_1D_ARRAY] = "ivec2(int(gl_FragCoord.x) + Constants.x, Constants.z)"; - SrcLocations[TEXTURE_TYPE_2D] = "ivec2(gl_FragCoord.xy) + Constants.xy"; - SrcLocations[TEXTURE_TYPE_2D_ARRAY] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)", - SrcLocations[TEXTURE_TYPE_3D] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)"; + //SamplerType[RESOURCE_DIM_TEX_CUBE] = "samplerCube"; + //SamplerType[RESOURCE_DIM_TEX_CUBE_ARRAY] = "smaplerCubeArray"; + + static const char* SrcLocations[RESOURCE_DIM_NUM_DIMENSIONS] = {}; + SrcLocations[RESOURCE_DIM_TEX_1D] = "int(gl_FragCoord.x) + Constants.x"; + SrcLocations[RESOURCE_DIM_TEX_1D_ARRAY] = "ivec2(int(gl_FragCoord.x) + Constants.x, Constants.z)"; + SrcLocations[RESOURCE_DIM_TEX_2D] = "ivec2(gl_FragCoord.xy) + Constants.xy"; + SrcLocations[RESOURCE_DIM_TEX_2D_ARRAY] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)", + SrcLocations[RESOURCE_DIM_TEX_3D] = "ivec3(ivec2(gl_FragCoord.xy) + Constants.xy, Constants.z)"; // There is no texelFetch() for texture cube [array] - //CoordDim[TEXTURE_TYPE_CUBE] = "ivec2(gl_FragCoord.xy)"; - //CoordDim[TEXTURE_TYPE_CUBE_ARRAY] = "ivec2(gl_FragCoord.xy)"; + //CoordDim[RESOURCE_DIM_TEX_CUBE] = "ivec2(gl_FragCoord.xy)"; + //CoordDim[RESOURCE_DIM_TEX_CUBE_ARRAY] = "ivec2(gl_FragCoord.xy)"; BufferDesc CBDesc; CBDesc.uiSizeInBytes = sizeof(Int32)*4; @@ -103,8 +102,17 @@ namespace Diligent true // We must indicate the buffer is internal device object ); + PipelineStateDesc PSODesc; + auto &GraphicsPipeline = PSODesc.GraphicsPipeline; + GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE; + GraphicsPipeline.RasterizerDesc.FillMode = FILL_MODE_SOLID; + + GraphicsPipeline.DepthStencilDesc.DepthEnable = false; + GraphicsPipeline.DepthStencilDesc.DepthWriteEnable = false; + GraphicsPipeline.pVS = m_pVertexShader; + static const char* CmpTypePrefix[3] = { "", "i", "u" }; - for( Int32 Dim = TEXTURE_TYPE_2D; Dim <= TEXTURE_TYPE_3D; ++Dim ) + for( Int32 Dim = RESOURCE_DIM_TEX_2D; Dim <= RESOURCE_DIM_TEX_3D; ++Dim ) { const auto *SamplerDim = SamplerType[Dim]; const auto *SrcLocation = SrcLocations[Dim]; @@ -133,42 +141,20 @@ namespace Diligent ShaderAttrs.Source = Source.c_str(); auto &FragmetShader = m_pFragmentShaders[Dim*3 + Fmt]; pDeviceGL->CreateShader( ShaderAttrs, &FragmetShader, - true // We must indicate the shader is internal device object + true // We must indicate the shader is an internal device object ); + GraphicsPipeline.pPS = FragmetShader; + pDeviceGL->CreatePipelineState( PSODesc, &m_pPSO[Dim*3 + Fmt], + true // We must indicate the PSO is an internal device object + ); + FragmetShader->GetShaderVariable( "cbConstants" )->Set( m_pConstantBuffer ); } } - - RasterizerStateDesc RSDesc; - RSDesc.CullMode = CULL_MODE_NONE; - RSDesc.FillMode = FILL_MODE_SOLID; - RSDesc.Name = "TexRegionRender : Solid fill no cull RS"; - pDeviceGL->CreateRasterizerState( RSDesc, &m_pSolidFillNoCullRS, - true // We must indicate the RS state is internal device object - ); - - DepthStencilStateDesc DSSDesc; - DSSDesc.Name = "TexRegionRender : disable depth DSS"; - DSSDesc.DepthEnable = false; - DSSDesc.DepthWriteEnable = false; - pDeviceGL->CreateDepthStencilState( DSSDesc, &m_pDisableDetphDS, - true // We must indicate the DSS state is internal device object - ); - - BlendStateDesc BSDesc; - BSDesc.Name = "TexRegionRender : default BS"; - pDeviceGL->CreateBlendState(BSDesc, &m_pDefaultBS, - true // We must indicate the BS state is internal device object - ); } void TexRegionRender::SetStates( DeviceContextGLImpl *pCtxGL ) { - Uint32 NumShaders = 0; - pCtxGL->GetShaders( nullptr, NumShaders ); - m_pOrigShaders.resize( NumShaders ); - pCtxGL->GetShaders( m_pOrigShaders.data(), NumShaders ); - pCtxGL->GetRenderTargets( m_NumRenderTargets, m_pOrigRTVs, &m_pOrigDSV ); Uint32 NumViewports = 0; @@ -176,28 +162,11 @@ namespace Diligent m_OrigViewports.resize(NumViewports); pCtxGL->GetViewports( NumViewports, m_OrigViewports.data() ); - pCtxGL->GetDepthStencilState(&m_pOrigDS, m_OrigStencilRef); - VERIFY( m_pOrigDS, "At least default depth-stencil state must be bound" ); - - pCtxGL->GetBlendState(&m_pOrigBS, m_OrigBlendFactors, m_OrigSamplesBlendMask); - VERIFY( m_pOrigBS, "At least default blend state must be bound" ); - - pCtxGL->GetRasterizerState(&m_pOrigRS); - VERIFY( m_pOrigRS, "At least default rasterizer state must be bound" ); - - pCtxGL->SetDepthStencilState( m_pDisableDetphDS, m_OrigStencilRef ); - pCtxGL->SetBlendState(m_pDefaultBS, m_OrigBlendFactors, m_OrigSamplesBlendMask); - pCtxGL->SetRasterizerState(m_pSolidFillNoCullRS); - + pCtxGL->GetPipelineState(&m_pOrigPSO, m_OrigBlendFactors, m_OrigStencilRef); } void TexRegionRender::RestoreStates( DeviceContextGLImpl *pCtxGL ) { - pCtxGL->SetShaders( m_pOrigShaders.data(), (Uint32)m_pOrigShaders.size() ); - for( auto pSh = m_pOrigShaders.begin(); pSh != m_pOrigShaders.end(); ++pSh ) - (*pSh)->Release(); - m_pOrigShaders.clear(); - pCtxGL->SetRenderTargets( m_NumRenderTargets, m_pOrigRTVs, m_pOrigDSV ); for( Uint32 rt = 0; rt < _countof( m_pOrigRTVs ); ++rt ) { @@ -209,19 +178,15 @@ namespace Diligent pCtxGL->SetViewports( (Uint32)m_OrigViewports.size(), m_OrigViewports.data(), 0, 0 ); - pCtxGL->SetDepthStencilState( m_pOrigDS, m_OrigStencilRef ); - m_pOrigDS.Release(); - - pCtxGL->SetBlendState(m_pOrigBS, m_OrigBlendFactors, m_OrigSamplesBlendMask); - m_pOrigBS.Release(); - - pCtxGL->SetRasterizerState(m_pOrigRS); - m_pOrigRS.Release(); + pCtxGL->SetPipelineState( m_pOrigPSO ); + m_pOrigPSO.Release(); + pCtxGL->SetStencilRef(m_OrigStencilRef); + pCtxGL->SetBlendFactors(m_OrigBlendFactors); } void TexRegionRender::Render( DeviceContextGLImpl *pCtxGL, ITextureView *pSrcSRV, - TEXTURE_TYPE TexType, + RESOURCE_DIMENSION TexType, TEXTURE_FORMAT TexFormat, Int32 DstToSrcXOffset, Int32 DstToSrcYOffset, @@ -249,11 +214,10 @@ namespace Diligent "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.") } - IShader *ppShaders[2] = { m_pVertexShader, m_pFragmentShaders[FSInd] }; - auto SrcTexVar = ppShaders[1]->GetShaderVariable( "gSourceTex" ); + pCtxGL->SetPipelineState(m_pPSO[FSInd]); + auto SrcTexVar = m_pFragmentShaders[FSInd]->GetShaderVariable( "gSourceTex" ); SrcTexVar->Set( pSrcSRV ); - pCtxGL->SetShaders( ppShaders, _countof(ppShaders) ); DrawAttribs DrawAttrs; DrawAttrs.NumVertices = 4; DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp index 8680f788..5ef553d0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,16 +32,17 @@ namespace Diligent { -Texture1DArray_OGL::Texture1DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, +Texture1DArray_OGL::Texture1DArray_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, class DeviceContextGLImpl *pDeviceContext, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : - TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) + TextureBaseGL(TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, GL_TEXTURE_1D_ARRAY, InitData, bIsDeviceInternal) { auto &ContextState = pDeviceContext->GetContextState(); - m_BindTarget = GL_TEXTURE_1D_ARRAY; ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // levels format width height @@ -89,18 +90,8 @@ Texture1DArray_OGL::~Texture1DArray_OGL() void Texture1DArray_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { - TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); - - auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); - auto &ContextState = pDeviceContextGL->GetContextState(); - - // GL_TEXTURE_UPDATE_BARRIER_BIT: - // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, - // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect - // data written by shaders prior to the barrier. Additionally, texture writes from these - // commands issued after the barrier will not execute until all shader writes initiated prior - // to the barrier complete - TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + auto &ContextState = ValidatedCast<DeviceContextGLImpl>(pContext)->GetContextState(); + TextureBaseGL::UpdateData(ContextState, pContext, MipLevel, Slice, DstBox, SubresData); ContextState.BindTexture( -1, m_BindTarget, m_GlTexture ); diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp index 5b9a0b9a..37cf920a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,17 +31,18 @@ namespace Diligent { -Texture1D_OGL::Texture1D_OGL( class RenderDeviceGLImpl *pDeviceGL, +Texture1D_OGL::Texture1D_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, class DeviceContextGLImpl *pDeviceContext, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : - TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) + TextureBaseGL(TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, GL_TEXTURE_1D, InitData, bIsDeviceInternal) { auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pDeviceContext); auto &ContextState = pDeviceContextGL->GetContextState(); - m_BindTarget = GL_TEXTURE_1D; ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // levels format width @@ -86,19 +87,9 @@ Texture1D_OGL::~Texture1D_OGL() void Texture1D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { - TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); + auto &ContextState = ValidatedCast<DeviceContextGLImpl>(pContext)->GetContextState(); + TextureBaseGL::UpdateData(ContextState, pContext, MipLevel, Slice, DstBox, SubresData); - auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); - auto &ContextState = pDeviceContextGL->GetContextState(); - - // GL_TEXTURE_UPDATE_BARRIER_BIT: - // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, - // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect - // data written by shaders prior to the barrier. Additionally, texture writes from these - // commands issued after the barrier will not execute until all shader writes initiated prior - // to the barrier complete - TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); - ContextState.BindTexture( -1, m_BindTarget, m_GlTexture ); // Transfers to OpenGL memory are called unpack operations diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp index fefa51e5..1ac3ca74 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,19 +32,20 @@ namespace Diligent { -Texture2DArray_OGL::Texture2DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, +Texture2DArray_OGL::Texture2DArray_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, class DeviceContextGLImpl *pDeviceContext, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : - TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) + TextureBaseGL(TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, TexDesc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY, InitData, bIsDeviceInternal) { auto &ContextState = pDeviceContext->GetContextState(); + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); if( m_Desc.SampleCount > 1 ) { - m_BindTarget = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; - ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // format width height depth glTexStorage3DMultisample(m_BindTarget, m_Desc.SampleCount, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.ArraySize, TRUE); // The last parameter specifies whether the image will use identical sample locations and the same number of @@ -61,8 +62,6 @@ Texture2DArray_OGL::Texture2DArray_OGL( class RenderDeviceGLImpl *pDeviceGL, } else { - m_BindTarget = GL_TEXTURE_2D_ARRAY; - ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // levels format width height depth glTexStorage3D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.ArraySize); CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D texture array"); @@ -111,18 +110,8 @@ Texture2DArray_OGL::~Texture2DArray_OGL() void Texture2DArray_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { - TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); - - auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); - auto &ContextState = pDeviceContextGL->GetContextState(); - - // GL_TEXTURE_UPDATE_BARRIER_BIT: - // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, - // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect - // data written by shaders prior to the barrier. Additionally, texture writes from these - // commands issued after the barrier will not execute until all shader writes initiated prior - // to the barrier complete - TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + auto &ContextState = ValidatedCast<DeviceContextGLImpl>(pContext)->GetContextState(); + TextureBaseGL::UpdateData(ContextState, pContext, MipLevel, Slice, DstBox, SubresData); ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp index 511085ca..c9f77d80 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,19 +32,20 @@ namespace Diligent { -Texture2D_OGL::Texture2D_OGL( class RenderDeviceGLImpl *pDeviceGL, +Texture2D_OGL::Texture2D_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, class DeviceContextGLImpl *pDeviceContext, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : - TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) + TextureBaseGL(TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, TexDesc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, InitData, bIsDeviceInternal) { auto &ContextState = pDeviceContext->GetContextState(); + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); if( m_Desc.SampleCount > 1 ) { - m_BindTarget = GL_TEXTURE_2D_MULTISAMPLE; - ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // format width height depth glTexStorage2DMultisample(m_BindTarget, m_Desc.SampleCount, m_GLTexFormat, m_Desc.Width, m_Desc.Height, GL_TRUE); // The last parameter specifies whether the image will use identical sample locations and the same number of @@ -63,8 +64,6 @@ Texture2D_OGL::Texture2D_OGL( class RenderDeviceGLImpl *pDeviceGL, } else { - m_BindTarget = GL_TEXTURE_2D; - ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); // levels format width height glTexStorage2D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height); CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 2D texture"); @@ -109,18 +108,8 @@ Texture2D_OGL::~Texture2D_OGL() void Texture2D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { - TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); - - auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); - auto &ContextState = pDeviceContextGL->GetContextState(); - - // GL_TEXTURE_UPDATE_BARRIER_BIT: - // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, - // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect - // data written by shaders prior to the barrier. Additionally, texture writes from these - // commands issued after the barrier will not execute until all shader writes initiated prior - // to the barrier complete - TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + auto &ContextState = ValidatedCast<DeviceContextGLImpl>(pContext)->GetContextState(); + TextureBaseGL::UpdateData(ContextState, pContext, MipLevel, Slice, DstBox, SubresData); ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp index 03913c3d..833cd5a4 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,17 +32,18 @@ namespace Diligent { -Texture3D_OGL::Texture3D_OGL( class RenderDeviceGLImpl *pDeviceGL, +Texture3D_OGL::Texture3D_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, class DeviceContextGLImpl *pDeviceContext, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : - TextureBaseGL(pDeviceGL, TexDesc, InitData, bIsDeviceInternal) + TextureBaseGL(TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, GL_TEXTURE_3D, InitData, bIsDeviceInternal) { auto &ContextState = pDeviceContext->GetContextState(); - - m_BindTarget = GL_TEXTURE_3D; ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + // levels format width height depth glTexStorage3D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.Depth); CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the 3D texture"); @@ -89,18 +90,8 @@ Texture3D_OGL::~Texture3D_OGL() void Texture3D_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { - TextureBaseGL::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); - - auto *pDeviceContextGL = ValidatedCast<DeviceContextGLImpl>(pContext); - auto &ContextState = pDeviceContextGL->GetContextState(); - - // GL_TEXTURE_UPDATE_BARRIER_BIT: - // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, - // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect - // data written by shaders prior to the barrier. Additionally, texture writes from these - // commands issued after the barrier will not execute until all shader writes initiated prior - // to the barrier complete - TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, ContextState ); + auto &ContextState = ValidatedCast<DeviceContextGLImpl>(pContext)->GetContextState(); + TextureBaseGL::UpdateData(ContextState, pContext, MipLevel, Slice, DstBox, SubresData); ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp index 0e893369..47a8b32f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,14 +29,20 @@ #include "TextureViewGLImpl.h" #include "GLContextState.h" #include "DeviceContextGLImpl.h" +#include "EngineMemory.h" namespace Diligent { -TextureBaseGL::TextureBaseGL(class RenderDeviceGLImpl *pDeviceGL, const TextureDesc& TexDesc, const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : - TTextureBase( pDeviceGL, TexDesc, bIsDeviceInternal ), +TextureBaseGL::TextureBaseGL(FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + const TextureDesc& TexDesc, + GLenum BindTarget, + const TextureData &InitData /*= TextureData()*/, bool bIsDeviceInternal /*= false*/) : + TTextureBase( TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, bIsDeviceInternal ), m_GlTexture(true), // Create Texture immediately - m_BindTarget(0), + m_BindTarget(BindTarget), m_GLTexFormat( TexFormatToGLInternalTexFormat(m_Desc.Format, m_Desc.BindFlags) ) //m_uiMapTarget(0) { @@ -71,6 +77,10 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe auto ViewDesc = OrigViewDesc; CorrectTextureViewDesc(ViewDesc); + auto *pDeviceGLImpl = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); + auto &TexViewAllocator = pDeviceGLImpl->GetTexViewObjAllocator(); + VERIFY( &TexViewAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization" ); + // http://www.opengl.org/wiki/Texture_Storage#Texture_views GLenum GLViewFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format, m_Desc.BindFlags ); @@ -80,14 +90,15 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe if( ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE ) { bool bIsFullTextureView = - ViewDesc.TextureType == m_Desc.Type && + ViewDesc.TextureDim == m_Desc.Type && ViewDesc.Format == CorrectTextureViewFormat( m_Desc.Format, ViewDesc.ViewType ) && ViewDesc.MostDetailedMip == 0 && ViewDesc.NumMipLevels == m_Desc.MipLevels && ViewDesc.FirstArraySlice == 0 && ViewDesc.NumArraySlices == m_Desc.ArraySize; - pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + pViewOGL = NEW(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, + pDeviceGLImpl, ViewDesc, this, !bIsFullTextureView, // Create OpenGL texture view object if view // does not address the whole texture bIsDefaultView @@ -95,30 +106,38 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe if( !bIsFullTextureView ) { GLenum GLViewTarget = 0; - switch(ViewDesc.TextureType) + switch(ViewDesc.TextureDim) { - case TEXTURE_TYPE_1D: + case RESOURCE_DIM_TEX_1D: GLViewTarget = GL_TEXTURE_1D; ViewDesc.NumArraySlices = 1; break; - case TEXTURE_TYPE_1D_ARRAY: + case RESOURCE_DIM_TEX_1D_ARRAY: GLViewTarget = GL_TEXTURE_1D_ARRAY; break; - case TEXTURE_TYPE_2D: + case RESOURCE_DIM_TEX_2D: GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; ViewDesc.NumArraySlices = 1; break; - case TEXTURE_TYPE_2D_ARRAY: + case RESOURCE_DIM_TEX_2D_ARRAY: GLViewTarget = m_Desc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY; break; - case TEXTURE_TYPE_3D: + case RESOURCE_DIM_TEX_3D: GLViewTarget = GL_TEXTURE_3D; break; + case RESOURCE_DIM_TEX_CUBE: + GLViewTarget = GL_TEXTURE_CUBE_MAP; + break; + + case RESOURCE_DIM_TEX_CUBE_ARRAY: + GLViewTarget = GL_TEXTURE_CUBE_MAP_ARRAY; + break; + default: UNEXPECTED("Unsupported texture view type"); } @@ -131,7 +150,8 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe VERIFY( ViewDesc.NumArraySlices == 1 || ViewDesc.NumArraySlices == m_Desc.ArraySize, "Only single array/depth slice or the whole texture can be bound as UAV in OpenGL"); VERIFY( ViewDesc.AccessFlags != 0, "At least one access flag must be specified" ); - pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + pViewOGL = NEW(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, + pDeviceGLImpl, ViewDesc, this, false, // Do NOT create texture view OpenGL object bIsDefaultView ); @@ -139,7 +159,8 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe else if( ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET ) { VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as RTV" ); - pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + pViewOGL = NEW(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, + pDeviceGLImpl, ViewDesc, this, false, // Do NOT create texture view OpenGL object bIsDefaultView ); @@ -147,7 +168,8 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe else if( ViewDesc.ViewType == TEXTURE_VIEW_DEPTH_STENCIL ) { VERIFY( ViewDesc.NumMipLevels == 1, "Only single mip level can be bound as DSV" ); - pViewOGL = new TextureViewGLImpl( GetDevice(), ViewDesc, this, + pViewOGL = NEW(TexViewAllocator, "TextureViewGLImpl instance", TextureViewGLImpl, + pDeviceGLImpl, ViewDesc, this, false, // Do NOT create texture view OpenGL object bIsDefaultView ); @@ -171,9 +193,17 @@ void TextureBaseGL::CreateViewInternal( const struct TextureViewDesc &OrigViewDe } -void TextureBaseGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +void TextureBaseGL::UpdateData( GLContextState &CtxState, IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) { TTextureBase::UpdateData(pContext, MipLevel, Slice, DstBox, SubresData); + + // GL_TEXTURE_UPDATE_BARRIER_BIT: + // Writes to a texture via glTex( Sub )Image*, glCopyTex( Sub )Image*, glClearTex*Image, + // glCompressedTex( Sub )Image*, and reads via glTexImage() after the barrier will reflect + // data written by shaders prior to the barrier. Additionally, texture writes from these + // commands issued after the barrier will not execute until all shader writes initiated prior + // to the barrier complete + TextureMemoryBarrier( GL_TEXTURE_UPDATE_BARRIER_BIT, CtxState ); } //void TextureBaseGL :: UpdateData(Uint32 Offset, Uint32 Size, const PVoid pData) @@ -205,13 +235,13 @@ void TextureBaseGL :: CopyData(IDeviceContext *pContext, if( pSrcBox == nullptr ) { SrcBox.MaxX = std::max( SrcTexDesc.Width >> SrcMipLevel, 1u ); - if( SrcTexDesc.Type == TEXTURE_TYPE_1D || - SrcTexDesc.Type == TEXTURE_TYPE_1D_ARRAY ) + if( SrcTexDesc.Type == RESOURCE_DIM_TEX_1D || + SrcTexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY ) SrcBox.MaxY = 1; else SrcBox.MaxY = std::max( SrcTexDesc.Height >> SrcMipLevel, 1u ); - if( SrcTexDesc.Type == TEXTURE_TYPE_3D ) + if( SrcTexDesc.Type == RESOURCE_DIM_TEX_3D ) SrcBox.MaxZ = std::max( SrcTexDesc.Depth >> SrcMipLevel, 1u ); else SrcBox.MaxZ = 1; @@ -255,18 +285,22 @@ void TextureBaseGL :: CopyData(IDeviceContext *pContext, } auto *pRenderDeviceGL = ValidatedCast<RenderDeviceGLImpl>(GetDevice()); + auto &TexViewObjAllocator = pRenderDeviceGL->GetTexViewObjAllocator(); + VERIFY( &TexViewObjAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization" ); + auto &FBOCache = pRenderDeviceGL->m_FBOCache; auto &TexRegionRender = pRenderDeviceGL->m_TexRegionRender; TexRegionRender.SetStates(pDeviceCtxGL); // Create temporary SRV for the entire source texture TextureViewDesc SRVDesc; - SRVDesc.TextureType = SrcTexDesc.Type; + SRVDesc.TextureDim = SrcTexDesc.Type; SRVDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE; CorrectTextureViewDesc( SRVDesc ); // Note: texture view allocates memory for the copy of the name // If the name is empty, memory should not be allocated - TextureViewGLImpl SRV( GetDevice(), SRVDesc, pSrcTextureGL, + // We have to provide allocator even though it will never be used + TextureViewGLImpl SRV( TexViewObjAllocator, GetDevice(), SRVDesc, pSrcTextureGL, false, // Do NOT create texture view OpenGL object true // The view, like default view, should not // keep strong reference to the texture @@ -276,7 +310,7 @@ void TextureBaseGL :: CopyData(IDeviceContext *pContext, { // Create temporary RTV for the target subresource TextureViewDesc RTVDesc; - RTVDesc.TextureType = m_Desc.Type; + RTVDesc.TextureDim = m_Desc.Type; RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; RTVDesc.FirstArraySlice = DepthSlice + DstSlice; RTVDesc.MostDetailedMip = DstMipLevel; @@ -284,7 +318,8 @@ void TextureBaseGL :: CopyData(IDeviceContext *pContext, CorrectTextureViewDesc( RTVDesc ); // Note: texture view allocates memory for the copy of the name // If the name is empty, memory should not be allocated - TextureViewGLImpl RTV( GetDevice(), RTVDesc, this, + // We have to provide allocator even though it will never be used + TextureViewGLImpl RTV( TexViewObjAllocator, GetDevice(), RTVDesc, this, false, // Do NOT create texture view OpenGL object true // The view, like default view, should not // keep strong reference to the texture @@ -366,9 +401,9 @@ void TextureBaseGL :: Map(IDeviceContext *pContext, MAP_TYPE MapType, Uint32 Map //glBindTexture(m_uiMapTarget, 0); } -void TextureBaseGL::Unmap( IDeviceContext *pContext ) +void TextureBaseGL::Unmap( IDeviceContext *pContext, MAP_TYPE MapType ) { - TTextureBase::Unmap(pContext); + TTextureBase::Unmap(pContext, MapType); //glBindTexture(m_uiMapTarget, m_GlTexture); //glUnmapTexture(m_uiMapTarget); @@ -404,6 +439,8 @@ void TextureBaseGL::SetDefaultGLParameters() case GL_TEXTURE_2D_MULTISAMPLE: TextureBinding = GL_TEXTURE_BINDING_2D_MULTISAMPLE; break; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: TextureBinding = GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; break; case GL_TEXTURE_3D: TextureBinding = GL_TEXTURE_BINDING_3D; break; + case GL_TEXTURE_CUBE_MAP: TextureBinding = GL_TEXTURE_BINDING_CUBE_MAP; break; + case GL_TEXTURE_CUBE_MAP_ARRAY: TextureBinding = GL_TEXTURE_BINDING_CUBE_MAP_ARRAY; break; default: UNEXPECTED("Unknown bind target"); } glGetIntegerv( TextureBinding, &BoundTex ); diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp new file mode 100644 index 00000000..d235fa2d --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp @@ -0,0 +1,208 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "TextureCubeArray_OGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +TextureCubeArray_OGL::TextureCubeArray_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + TextureBaseGL(TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, GL_TEXTURE_CUBE_MAP_ARRAY, InitData, bIsDeviceInternal) +{ + VERIFY(m_Desc.SampleCount == 1, "Multisampled texture cube arrays are not supported") + + auto &ContextState = pDeviceContext->GetContextState(); + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + // For example, when you allocate storage for the texture, you would use glTexStorage3D? or glTexImage3D? or similar. + // The depth? parameter will be the number of layer-faces, not layers. So it must be divisible by 6. + VERIFY( (m_Desc.ArraySize % 6) == 0, "Array size must be multiple of 6"); + // levels format width height depth + glTexStorage3D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height, m_Desc.ArraySize); + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the Cubemap texture array"); + //When target is GL_TEXTURE_CUBE_MAP_ARRAY glTexStorage3D is equivalent to: + // + //for (i = 0; i < levels; i++) { + // glTexImage3D(target, i, internalformat, width, height, depth, 0, format, type, NULL); + // width = max(1, (width / 2)); + // height = max(1, (height / 2)); + //} + + SetDefaultGLParameters(); + + if( InitData.pSubResources ) + { + VERIFY( (m_Desc.ArraySize % 6) == 0, "Array size must be multiple of 6"); + if( m_Desc.MipLevels * m_Desc.ArraySize == InitData.NumSubresources ) + { + for(Uint32 Slice = 0; Slice < m_Desc.ArraySize; ++Slice) + { + for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + { + Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U) ); + // UpdateData() is a virtual function. If we try to call it through vtbl from here, + // we will get into TextureBaseGL::UpdateData(), because instance of TextureCubeArray_OGL + // is not fully constructed yet. + // To call the required function, we need to explicitly specify the class: + TextureCubeArray_OGL::UpdateData(pDeviceContext, Mip, Slice, DstBox, InitData.pSubResources[Slice*m_Desc.MipLevels + Mip]); + } + } + } + else + { + UNEXPECTED("Incorrect number of subresources"); + } + } + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +TextureCubeArray_OGL::~TextureCubeArray_OGL() +{ +} + +void TextureCubeArray_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + auto &ContextState = ValidatedCast<DeviceContextGLImpl>(pContext)->GetContextState(); + TextureBaseGL::UpdateData(ContextState, pContext, MipLevel, Slice, DstBox, SubresData); + + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + // Transfers to OpenGL memory are called unpack operations + // If there is a buffer bound to GL_PIXEL_UNPACK_BUFFER target, then all the pixel transfer + // operations will be performed from this buffer. We need to make sure none is bound + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + auto TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + if( TransferAttribs.IsCompressed ) + { + VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + "Compressed texture update region must be 4 pixel-aligned" ); + const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * FmtAttribs.ComponentSize; + VERIFY( SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + + //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + glCompressedTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + Slice, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + 1, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, + SubresData.pData); + } + else + { + const auto TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); + const auto PixelSize = TexFmtInfo.NumComponents * TexFmtInfo.ComponentSize; + VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0 ); + + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + // When uploading texel data to the cubemap array, the parameters that represent the Z component + // are layer-faces. So if you want to upload to just the positive Z face of the second layer in the array, + // you would use call glTexSubImage3D?, with the zoffset?? parameter set to 10 (layer 1 * 6 faces per layer + face index 4), + // and the depth? set to 1 (because you're only uploading one layer-face). + + // Target must be GL_TEXTURE_3D, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_CUBE_MAP_ARRAY. + // (NO individual cubemap faces GL_TEXTURE_CUBE_MAP_POSITIVE_X .. GL_TEXTURE_CUBE_MAP_NEGATIVE_Z!!!) + glTexSubImage3D(m_BindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + Slice, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + 1, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + SubresData.pData); + } + CHECK_GL_ERROR("Failed to update subimage data"); + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +void TextureCubeArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +{ + // Same as for 2D array textures + + // Every OpenGL API call that operates on cubemap array textures takes layer-faces, not array layers. + // So the parameters that represent the Z component are layer-faces. + if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + { + // glFramebufferTexture() attaches the given mipmap levelas a layered image with the number of layers that the given texture has. + glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture cubemap array to draw framebuffer" ); + glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture cubemap array to read framebuffer" ); + } + else if( ViewDesc.NumArraySlices == 1 ) + { + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // cube map array texture, or multisample array texture. + glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); + CHECK_GL_ERROR( "Failed to attach texture cubemap array to draw framebuffer" ); + glFramebufferTextureLayer( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip, ViewDesc.FirstArraySlice ); + CHECK_GL_ERROR( "Failed to attach texture cubemap array to read framebuffer" ); + } + else + { + UNEXPECTED( "Only one slice or the entire cubemap array can be attached to a framebuffer" ); + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp new file mode 100644 index 00000000..875c1855 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp @@ -0,0 +1,214 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "TextureCube_OGL.h" +#include "RenderDeviceGLImpl.h" +#include "DeviceContextGLImpl.h" +#include "GLTypeConversions.h" +#include "GraphicsUtilities.h" + +namespace Diligent +{ + +TextureCube_OGL::TextureCube_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& TexDesc, + const TextureData &InitData /*= TextureData()*/, + bool bIsDeviceInternal /*= false*/) : + TextureBaseGL(TexObjAllocator, TexViewObjAllocator, pDeviceGL, TexDesc, GL_TEXTURE_CUBE_MAP, InitData, bIsDeviceInternal) +{ + VERIFY(m_Desc.SampleCount == 1, "Multisampled cubemap textures are not supported"); + + auto &ContextState = pDeviceContext->GetContextState(); + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + VERIFY( m_Desc.ArraySize == 6, "Cubemap texture is expected to have 6 slices"); + // levels format width height + glTexStorage2D(m_BindTarget, m_Desc.MipLevels, m_GLTexFormat, m_Desc.Width, m_Desc.Height); + CHECK_GL_ERROR_AND_THROW("Failed to allocate storage for the Cubemap texture"); + //When target is GL_TEXTURE_CUBE_MAP, glTexStorage2D is equivalent to: + // + //for (i = 0; i < levels; i++) { + // for (face in (+X, -X, +Y, -Y, +Z, -Z)) { + // glTexImage2D(face, i, internalformat, width, height, 0, format, type, NULL); + // } + // width = max(1, (width / 2)); + // height = max(1, (height / 2)); + //} + SetDefaultGLParameters(); + + if( InitData.pSubResources ) + { + auto ExpectedSubresources = m_Desc.MipLevels*6; + if( m_Desc.MipLevels*6 == InitData.NumSubresources ) + { + for(Uint32 Face = 0; Face < 6; ++Face) + { + for(Uint32 Mip = 0; Mip < m_Desc.MipLevels; ++Mip) + { + Box DstBox(0, std::max(m_Desc.Width >>Mip, 1U), + 0, std::max(m_Desc.Height>>Mip, 1U) ); + // UpdateData() is a virtual function. If we try to call it through vtbl from here, + // we will get into TextureBaseGL::UpdateData(), because instance of TextureCube_OGL + // is not fully constructed yet. + // To call the required function, we need to explicitly specify the class: + TextureCube_OGL::UpdateData( pDeviceContext, Mip, Face, DstBox, InitData.pSubResources[Face*m_Desc.MipLevels + Mip] ); + } + } + } + else + { + UNEXPECTED("Incorrect number of subresources. ", InitData.NumSubresources, " while ", ExpectedSubresources," is expected" ); + } + } + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +TextureCube_OGL::~TextureCube_OGL() +{ +} + +// Move static member initialization out of function to avoid +// potential issues in multithreaded code +static const GLenum CubeMapFaces[6] = +{ + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z +}; + +void TextureCube_OGL::UpdateData( IDeviceContext *pContext, Uint32 MipLevel, Uint32 Slice, const Box &DstBox, const TextureSubResData &SubresData ) +{ + auto &ContextState = ValidatedCast<DeviceContextGLImpl>(pContext)->GetContextState(); + TextureBaseGL::UpdateData(ContextState, pContext, MipLevel, Slice, DstBox, SubresData); + + // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glTexSubImage2D() + // then takes one of GL_TEXTURE_CUBE_MAP_POSITIVE_X ... GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + ContextState.BindTexture(-1, m_BindTarget, m_GlTexture); + + auto CubeMapFaceBindTarget = CubeMapFaces[Slice]; + + // Transfers to OpenGL memory are called unpack operations + // If there is a buffer bound to GL_PIXEL_UNPACK_BUFFER target, then all the pixel transfer + // operations will be performed from this buffer. We need to make sure none is bound + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + auto TransferAttribs = GetNativePixelTransferAttribs(m_Desc.Format); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + if( TransferAttribs.IsCompressed ) + { + VERIFY( (DstBox.MinX % 4) == 0 && (DstBox.MinY % 4) == 0 && + ((DstBox.MaxX % 4) == 0 || DstBox.MaxX == std::max(m_Desc.Width >>MipLevel, 1U)) && + ((DstBox.MaxY % 4) == 0 || DstBox.MaxY == std::max(m_Desc.Height>>MipLevel, 1U)), + "Compressed texture update region must be 4 pixel-aligned" ); + const auto &FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); + auto BlockBytesInRow = ((DstBox.MaxX - DstBox.MinX + 3)/4) * FmtAttribs.ComponentSize; + VERIFY( SubresData.Stride == BlockBytesInRow, + "Compressed data stride (", SubresData.Stride, " must match the size of a row of compressed blocks (", BlockBytesInRow, ")" ); + + //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + //glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + + // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glCompressedTexSubImage2D() + // takes one of GL_TEXTURE_CUBE_MAP_POSITIVE_X ... GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + glCompressedTexSubImage2D(CubeMapFaceBindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + // The format must be the same compressed-texture format previously + // specified by glTexStorage2D() (thank you OpenGL for another useless + // parameter that is nothing but the source of confusion), otherwise + // INVALID_OPERATION error is generated. + m_GLTexFormat, + // An INVALID_VALUE error is generated if imageSize is not consistent with + // the format, dimensions, and contents of the compressed image( too little or + // too much data ), + ((DstBox.MaxY - DstBox.MinY + 3)/4) * SubresData.Stride, + SubresData.pData); + } + else + { + const auto& TexFmtInfo = GetTextureFormatAttribs(m_Desc.Format); + const auto PixelSize = TexFmtInfo.NumComponents * TexFmtInfo.ComponentSize; + VERIFY( (SubresData.Stride % PixelSize)==0, "Data stride is not multiple of pixel size" ); + glPixelStorei(GL_UNPACK_ROW_LENGTH, SubresData.Stride / PixelSize); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + + // Texture must be bound as GL_TEXTURE_CUBE_MAP, but glTexSubImage2D() + // takes one of GL_TEXTURE_CUBE_MAP_POSITIVE_X ... GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + glTexSubImage2D(CubeMapFaceBindTarget, MipLevel, + DstBox.MinX, + DstBox.MinY, + DstBox.MaxX - DstBox.MinX, + DstBox.MaxY - DstBox.MinY, + TransferAttribs.PixelFormat, TransferAttribs.DataType, + SubresData.pData); + } + CHECK_GL_ERROR("Failed to update subimage data"); + + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); +} + +void TextureCube_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) +{ + if( ViewDesc.NumArraySlices == m_Desc.ArraySize ) + { + glFramebufferTexture( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture cube to draw framebuffer" ); + glFramebufferTexture( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture cube to read framebuffer" ); + } + else if( ViewDesc.NumArraySlices == 1 ) + { + // Texture name must either be zero or the name of an existing 3D texture, 1D or 2D array texture, + // cube map array texture, or multisample array texture. + + auto CubeMapFaceBindTarget = CubeMapFaces[ViewDesc.FirstArraySlice]; + // For glFramebufferTexture2D, if texture is not zero, textarget must be one of GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE, + // GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + // GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + // or GL_TEXTURE_2D_MULTISAMPLE. + glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, AttachmentPoint, m_GlTexture, CubeMapFaceBindTarget, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture cube face to draw framebuffer" ); + glFramebufferTexture2D( GL_READ_FRAMEBUFFER, AttachmentPoint, m_GlTexture, CubeMapFaceBindTarget, ViewDesc.MostDetailedMip ); + CHECK_GL_ERROR( "Failed to attach texture cube face to read framebuffer" ); + } + else + { + UNEXPECTED( "Only one slice or the entire cubemap can be attached to a framebuffer" ); + } +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp index 10fbb630..b3b4210c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureViewGLImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,12 +30,13 @@ namespace Diligent { - TextureViewGLImpl::TextureViewGLImpl( IRenderDevice *pDevice, - const TextureViewDesc& ViewDesc, - TextureBaseGL* pTexture, - bool bCreateGLViewTex, - bool bIsDefaultView ) : - TTextureViewBase(pDevice, ViewDesc, pTexture, bIsDefaultView), + TextureViewGLImpl::TextureViewGLImpl( FixedBlockMemoryAllocator &TexViewObjAllocator, + IRenderDevice *pDevice, + const TextureViewDesc& ViewDesc, + TextureBaseGL* pTexture, + bool bCreateGLViewTex, + bool bIsDefaultView ) : + TTextureViewBase(TexViewObjAllocator, pDevice, ViewDesc, pTexture, bIsDefaultView), m_ViewTexGLHandle( bCreateGLViewTex ), m_ViewTexBindTarget(0) { diff --git a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp index 4a3891b3..00309b77 100644 --- a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ #include "BufferGLImpl.h" #include "GLTypeConversions.h" #include "GLContextState.h" +#include "PipelineStateGLImpl.h" namespace Diligent { @@ -36,14 +37,14 @@ namespace Diligent VAOCache::VAOCache() { m_Cache.max_load_factor(0.5f); - m_VertexDescToKey.max_load_factor(0.5f); + m_PSOToKey.max_load_factor(0.5f); m_BuffToKey.max_load_factor(0.5f); } VAOCache::~VAOCache() { VERIFY(m_Cache.empty(), "VAO cache is not empty. Are there any unreleased objects?"); - VERIFY(m_VertexDescToKey.empty(), "VertexDescToKey hash is not empty" ); + VERIFY(m_PSOToKey.empty(), "PSOToKey hash is not empty" ); VERIFY(m_BuffToKey.empty(), "BuffToKey hash is not empty"); } @@ -58,21 +59,22 @@ void VAOCache::OnDestroyBuffer(IBuffer *pBuffer) m_BuffToKey.erase(EqualRange.first, EqualRange.second); } -void VAOCache::OnDestroyVertexDesc(IVertexDescription *pVertexDesc) +void VAOCache::OnDestroyPSO(IPipelineState *pPSO) { ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); - auto EqualRange = m_VertexDescToKey.equal_range(pVertexDesc); + auto EqualRange = m_PSOToKey.equal_range(pPSO); for(auto It = EqualRange.first; It != EqualRange.second; ++It) { m_Cache.erase(It->second); } - m_VertexDescToKey.erase(EqualRange.first, EqualRange.second); + m_PSOToKey.erase(EqualRange.first, EqualRange.second); } -const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO( IVertexDescription &VertexDesc, - IBuffer *pIndexBuffer, - vector< VertexStreamInfo > &VertexStreams, - GLContextState &GLContextState ) +const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO( IPipelineState *pPSO, + IBuffer *pIndexBuffer, + VertexStreamInfo VertexStreams[], + Uint32 NumVertexStreams, + GLContextState &GLContextState ) { // Lock the cache ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); @@ -80,19 +82,22 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO( IVertexDescription & RefCntAutoPtr<IBuffer> spVertexBuffers[MaxBufferSlots]; // Get layout - const auto *LayoutElems = VertexDesc.GetDesc().LayoutElements; - auto NumElems = VertexDesc.GetDesc().NumElements; - const auto *TightStrides = VertexDesc.GetTightStrides(); + auto *pPSOGL = ValidatedCast<PipelineStateGLImpl>(pPSO); + + const auto &InputLayout = pPSOGL->GetDesc().GraphicsPipeline.InputLayout; + const LayoutElement *LayoutElems = InputLayout.LayoutElements; + Uint32 NumElems = InputLayout.NumElements; + const Uint32 *TightStrides = pPSOGL->GetTightStrides(); // Construct the key VAOCacheKey Key = {0}; - Key.pVertexDesc = &VertexDesc; + Key.pPSO = pPSO; Key.pIndexBuffer = pIndexBuffer; auto LayoutIt = LayoutElems; for( size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt ) { auto BuffSlot = LayoutIt->BufferSlot; - if( BuffSlot >= VertexStreams.size() ) + if( BuffSlot >= NumVertexStreams ) { UNEXPECTED( "Input layout requires more buffers than bound to the pipeline" ); continue; @@ -160,7 +165,7 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO( IVertexDescription & for( size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt ) { auto BuffSlot = LayoutIt->BufferSlot; - if( BuffSlot >= VertexStreams.size() || BuffSlot >= MaxBufferSlots ) + if( BuffSlot >= NumVertexStreams || BuffSlot >= MaxBufferSlots ) { UNEXPECTED( "Incorrect input buffer slot" ); continue; @@ -205,7 +210,7 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO( IVertexDescription & auto NewElems = m_Cache.emplace( make_pair(Key, std::move(NewVAO)) ); // New element must be actually inserted VERIFY( NewElems.second, "New element was not inserted into the cache" ); - m_VertexDescToKey.insert( make_pair(Key.pVertexDesc, Key) ); + m_PSOToKey.insert( make_pair(Key.pPSO, Key) ); for(int iStream = 0; iStream < _countof(Key.Streams); ++iStream) { auto *pCurrBuff = Key.Streams[iStream].pBuffer; diff --git a/Graphics/GraphicsEngineOpenGL/src/pch.cpp b/Graphics/GraphicsEngineOpenGL/src/pch.cpp index 0bfe300d..bd78824e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/pch.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/pch.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj b/Graphics/GraphicsTools/build/UWP/GraphicsTools.vcxproj index 85152c29..ae79dc6f 100644 --- a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj +++ b/Graphics/GraphicsTools/build/UWP/GraphicsTools.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|ARM"> <Configuration>Debug</Configuration> @@ -27,88 +27,89 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{dac331f3-c5a2-4568-8714-9213c3487a49}</ProjectGuid> + <ProjectGuid>{7a1a6e2c-3952-4a57-ad30-abd92aa39c69}</ProjectGuid> + <Keyword>StaticLibrary</Keyword> <RootNamespace>GraphicsTools</RootNamespace> <DefaultLanguage>en-US</DefaultLanguage> - <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> <AppContainerApplication>true</AppContainerApplication> <ApplicationType>Windows Store</ApplicationType> - <ApplicationTypeRevision>8.1</ApplicationTypeRevision> - <ConvergedProjectType>CodeSharingStaticLibrary</ConvergedProjectType> + <WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion> + <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion> + <ApplicationTypeRevision>10.0</ApplicationTypeRevision> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="..\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + <Import Project="..\Windows.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" /> + </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore32Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_Win32Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmDbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmDbg.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStoreArmRel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_ArmRel.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Dbg.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Dbg.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </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" /> - <Import Project="..\..\..\..\..\Shared\build\WindowsStore\WinStore64Rel.props" /> - <Import Project="..\EngineRoot.props" /> - <Import Project="..\..\Windows\GraphicsTools.props" /> + <Import Project="..\..\..\..\Shared\build\UWP\UWP_X64Rel.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <GenerateManifest>false</GenerateManifest> </PropertyGroup> @@ -129,7 +130,6 @@ </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -141,7 +141,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -153,7 +152,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -165,7 +163,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -177,7 +174,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> @@ -189,7 +185,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> <CompileAsWinRT>false</CompileAsWinRT> <SDLCheck>true</SDLCheck> </ClCompile> diff --git a/Graphics/GraphicsTools/build/UWP/GraphicsTools.vcxproj.filters b/Graphics/GraphicsTools/build/UWP/GraphicsTools.vcxproj.filters new file mode 100644 index 00000000..c31757ec --- /dev/null +++ b/Graphics/GraphicsTools/build/UWP/GraphicsTools.vcxproj.filters @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools-Debug.vgdbsettings b/Graphics/GraphicsTools/build/Win32/GraphicsTools-Debug.vgdbsettings index 3f5b24b1..3f5b24b1 100644 --- a/Graphics/GraphicsTools/build/Windows/GraphicsTools-Debug.vgdbsettings +++ b/Graphics/GraphicsTools/build/Win32/GraphicsTools-Debug.vgdbsettings diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools-Release.vgdbsettings b/Graphics/GraphicsTools/build/Win32/GraphicsTools-Release.vgdbsettings index 669691f2..669691f2 100644 --- a/Graphics/GraphicsTools/build/Windows/GraphicsTools-Release.vgdbsettings +++ b/Graphics/GraphicsTools/build/Win32/GraphicsTools-Release.vgdbsettings diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj b/Graphics/GraphicsTools/build/Win32/GraphicsTools.vcxproj index c90a589b..a1020462 100644 --- a/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj +++ b/Graphics/GraphicsTools/build/Win32/GraphicsTools.vcxproj @@ -68,31 +68,27 @@ </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> - <Import Project="..\WindowsStore\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" Condition="Exists('..\WindowsStore\GraphicsTools.Shared\GraphicsTools.Shared.vcxitems')" /> + <Import Project="..\Windows.Shared\GraphicsTools.Shared.vcxitems" Label="Shared" Condition="Exists('..\Windows.Shared\GraphicsTools.Shared.vcxitems')" /> </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" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsTools.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64d.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsTools.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </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" /> <Import Project="..\..\..\..\Shared\build\Windows\Win32r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsTools.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="..\..\..\..\Shared\build\Windows\Win64r.props" /> - <Import Project="EngineRoot.props" /> - <Import Project="GraphicsTools.props" /> + <Import Project="..\Windows.Shared\GraphicsTools.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <Import Project="..\..\..\..\Shared\build\Windows\Android32d.props" /> @@ -104,7 +100,6 @@ <PropertyGroup /> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -115,7 +110,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> @@ -126,7 +120,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> @@ -141,7 +134,6 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj.filters b/Graphics/GraphicsTools/build/Win32/GraphicsTools.vcxproj.filters index 89d44e9e..89d44e9e 100644 --- a/Graphics/GraphicsTools/build/Windows/GraphicsTools.vcxproj.filters +++ b/Graphics/GraphicsTools/build/Win32/GraphicsTools.vcxproj.filters diff --git a/Graphics/GraphicsTools/build/Windows/jni/Android.mk b/Graphics/GraphicsTools/build/Win32/jni/Android.mk index 2b02dd54..2b02dd54 100644 --- a/Graphics/GraphicsTools/build/Windows/jni/Android.mk +++ b/Graphics/GraphicsTools/build/Win32/jni/Android.mk diff --git a/Graphics/GraphicsTools/build/Windows/jni/Application.mk b/Graphics/GraphicsTools/build/Win32/jni/Application.mk index 063ff721..063ff721 100644 --- a/Graphics/GraphicsTools/build/Windows/jni/Application.mk +++ b/Graphics/GraphicsTools/build/Win32/jni/Application.mk diff --git a/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.Shared.vcxitems b/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.Shared.vcxitems new file mode 100644 index 00000000..4ca8db57 --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.Shared.vcxitems @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <ItemsProjectGuid>{3bb4f2ac-1d2f-4af6-b9cc-bdc17bb8bc39}</ItemsProjectGuid> + <ItemsRootNamespace>GraphicsTools</ItemsRootNamespace> + <ItemsProjectName>GraphicsTools.Shared</ItemsProjectName> + <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectCapability Include="SourceItemsFromImports" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BasicShaderSourceStreamFactory.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\FreeBlockListManager.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\FreeBlockListManagerGPU.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\GraphicsUtilities.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RingBuffer.h" /> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderMacroHelper.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BasicShaderSourceStreamFactory.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\GraphicsUtilities.cpp" /> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Text Include="$(MSBuildThisFileDirectory)..\..\CMakeLists.txt"> + <DeploymentContent>false</DeploymentContent> + </Text> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.Shared.vcxitems.filters b/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.Shared.vcxitems.filters new file mode 100644 index 00000000..0c8d5aa8 --- /dev/null +++ b/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.Shared.vcxitems.filters @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{610cb4a4-ad9a-42e0-936c-239055f0caa6}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{2fa69c92-b6b7-4e73-9ccd-49a715515cc8}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\pch.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\BasicShaderSourceStreamFactory.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\GraphicsUtilities.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ShaderMacroHelper.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\RingBuffer.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\FreeBlockListManager.h"> + <Filter>include</Filter> + </ClInclude> + <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\FreeBlockListManagerGPU.h"> + <Filter>include</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\pch.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\BasicShaderSourceStreamFactory.cpp"> + <Filter>src</Filter> + </ClCompile> + <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\GraphicsUtilities.cpp"> + <Filter>src</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Text Include="$(MSBuildThisFileDirectory)..\..\CMakeLists.txt" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsEngineOpenGL/build/Windows/EngineRoot.props b/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.props index 02287e9c..4da87146 100644 --- a/Graphics/GraphicsEngineOpenGL/build/Windows/EngineRoot.props +++ b/Graphics/GraphicsTools/build/Windows.Shared/GraphicsTools.props @@ -4,9 +4,10 @@ <PropertyGroup Label="UserMacros"> <EngineRoot>..\..\..\..</EngineRoot> <GraphicsRoot>..\..\..</GraphicsRoot> - <ProjectRoot>..\..</ProjectRoot> </PropertyGroup> - <PropertyGroup /> + <PropertyGroup> + <IncludePath>$(GraphicsRoot)\GraphicsTools\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\TextureLoader\interface;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath)</IncludePath> + </PropertyGroup> <ItemDefinitionGroup /> <ItemGroup> <BuildMacro Include="EngineRoot"> @@ -15,8 +16,5 @@ <BuildMacro Include="GraphicsRoot"> <Value>$(GraphicsRoot)</Value> </BuildMacro> - <BuildMacro Include="ProjectRoot"> - <Value>$(ProjectRoot)</Value> - </BuildMacro> </ItemGroup> </Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/Windows/GraphicsTools.props b/Graphics/GraphicsTools/build/Windows/GraphicsTools.props deleted file mode 100644 index 22851e71..00000000 --- a/Graphics/GraphicsTools/build/Windows/GraphicsTools.props +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <IncludePath>$(GraphicsRoot)\GraphicsTools\include;$(GraphicsRoot)\GraphicsEngine\interface;$(GraphicsRoot)\TextureLoader\interface;$(EngineRoot)\Common\include;$(EngineRoot)\Common\interface;$(EngineRoot)\Platforms\interface;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath)</IncludePath> - </PropertyGroup> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/EngineRoot.props b/Graphics/GraphicsTools/build/WindowsStore/EngineRoot.props deleted file mode 100644 index fcb891c0..00000000 --- a/Graphics/GraphicsTools/build/WindowsStore/EngineRoot.props +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros"> - <EngineRoot>..\..\..\..\..</EngineRoot> - <GraphicsRoot>..\..\..\..</GraphicsRoot> - </PropertyGroup> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup> - <BuildMacro Include="EngineRoot"> - <Value>$(EngineRoot)</Value> - </BuildMacro> - <BuildMacro Include="GraphicsRoot"> - <Value>$(GraphicsRoot)</Value> - </BuildMacro> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems deleted file mode 100644 index 6a1aa429..00000000 --- a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup Label="Globals"> - <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> - <HasSharedItems>true</HasSharedItems> - <ItemsProjectGuid>{3bb4f2ac-1d2f-4af6-b9cc-bdc17bb8bc39}</ItemsProjectGuid> - <ItemsRootNamespace>GraphicsTools</ItemsRootNamespace> - <ItemsProjectName>GraphicsTools.Shared</ItemsProjectName> - <CodeSharingProject>248F659F-DAC5-46E8-AC09-60EC9FC95053</CodeSharingProject> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ProjectCapability Include="SourceItemsFromImports" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BasicShaderSourceStreamFactory.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\GraphicsUtilities.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h" /> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderMacroHelper.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BasicShaderSourceStreamFactory.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsUtilities.cpp" /> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems.filters b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems.filters deleted file mode 100644 index ed522894..00000000 --- a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Shared/GraphicsTools.Shared.vcxitems.filters +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="include"> - <UniqueIdentifier>{610cb4a4-ad9a-42e0-936c-239055f0caa6}</UniqueIdentifier> - </Filter> - <Filter Include="src"> - <UniqueIdentifier>{2fa69c92-b6b7-4e73-9ccd-49a715515cc8}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\pch.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\BasicShaderSourceStreamFactory.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\GraphicsUtilities.h"> - <Filter>include</Filter> - </ClInclude> - <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\include\ShaderMacroHelper.h"> - <Filter>include</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\pch.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\BasicShaderSourceStreamFactory.cpp"> - <Filter>src</Filter> - </ClCompile> - <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\src\GraphicsUtilities.cpp"> - <Filter>src</Filter> - </ClCompile> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj.filters b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj.filters deleted file mode 100644 index a7761ab0..00000000 --- a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.Windows/GraphicsTools.Windows.vcxproj.filters +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - </ItemGroup> -</Project> diff --git a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj.filters b/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj.filters deleted file mode 100644 index a7761ab0..00000000 --- a/Graphics/GraphicsTools/build/WindowsStore/GraphicsTools.WindowsPhone/GraphicsTools.WindowsPhone.vcxproj.filters +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - </ItemGroup> -</Project> diff --git a/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h b/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h index 76adc056..86e2650b 100644 --- a/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h +++ b/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/include/FreeBlockListManager.h b/Graphics/GraphicsTools/include/FreeBlockListManager.h new file mode 100644 index 00000000..7eb9d931 --- /dev/null +++ b/Graphics/GraphicsTools/include/FreeBlockListManager.h @@ -0,0 +1,276 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include <map> +#include "MemoryAllocator.h" +#include "FixedBlockMemoryAllocator.h" +#include "STDAllocator.h" +#include "DebugUtilities.h" + +namespace Diligent +{ + class FreeBlockListManager + { + public: + typedef size_t OffsetType; + typedef std::pair<Uint64,OffsetType> FrameNumOffsetPair; + + struct FreeBlockInfo; + typedef std::map<OffsetType, + FreeBlockInfo, + std::less<OffsetType>, // Standard ordering + STDAllocatorRawMem<std::pair<OffsetType, FreeBlockInfo>> // Raw memory allocator + > TFreeBlocksByOffsetMap; + typedef std::multimap<OffsetType, + TFreeBlocksByOffsetMap::iterator, + std::less<OffsetType>, // Standard ordering + STDAllocatorRawMem<std::pair<OffsetType, TFreeBlocksByOffsetMap::iterator>> // Raw memory allocator + > TFreeBlocksBySizeMap; + + struct FreeBlockInfo + { + // Block size (no reserved space) + OffsetType Size; + + // Iterator referencing this block in the multimap sorted by the block size + TFreeBlocksBySizeMap::iterator OrderBySizeIt; + + FreeBlockInfo(OffsetType _Size) : Size(_Size){} + }; + + static const OffsetType InvalidOffset = static_cast<OffsetType>(-1); + + FreeBlockListManager(OffsetType MaxSize, IMemoryAllocator &Allocator) : + m_MaxSize(MaxSize), + m_FreeSize(MaxSize), + m_FreeBlocks( STD_ALLOCATOR_RAW_MEM(TFreeBlocksByOffsetMap::value_type, Allocator, "Allocator for std::map<OffsetType, FreeBlockInfo>") ), + m_FreeBlocksBySize( STD_ALLOCATOR_RAW_MEM(TFreeBlocksBySizeMap::value_type, Allocator, "multimap<OffsetType, TFreeBlocksByOffsetMap::iterator>") ) + { + AddNewBlock(0, m_MaxSize); + +#ifdef _DEBUG + DbgVerifyList(); +#endif + } + + ~FreeBlockListManager() + { + if( !m_FreeBlocks.empty() || !m_FreeBlocksBySize.empty() ) + { + VERIFY(m_FreeBlocks.size() == 1, "Single free block is expected"); + VERIFY(m_FreeBlocks.begin()->first == 0, "Head chunk offset is expected to be 0"); + VERIFY(m_FreeBlocks.begin()->second.Size == m_MaxSize, "Head chunk size is expected to be ", m_MaxSize); + + VERIFY(m_FreeBlocksBySize.size() == 1, "Single free block is expected"); + VERIFY(m_FreeBlocksBySize.begin()->first == m_MaxSize, "Head chunk size is expected to be ", m_MaxSize); + VERIFY(m_FreeBlocksBySize.begin()->second == m_FreeBlocks.begin(), "Incorrect first block"); + } + } + + FreeBlockListManager(FreeBlockListManager&& rhs) : + m_FreeBlocks(std::move(rhs.m_FreeBlocks)), + m_FreeBlocksBySize(std::move(rhs.m_FreeBlocksBySize)), + m_MaxSize(rhs.m_MaxSize), + m_FreeSize(rhs.m_FreeSize) + { + rhs.m_MaxSize = 0; + rhs.m_FreeSize = 0; + } + FreeBlockListManager& operator = (FreeBlockListManager&& rhs) = default; + FreeBlockListManager(const FreeBlockListManager&) = delete; + FreeBlockListManager& operator = (const FreeBlockListManager&) = delete; + + OffsetType Allocate(OffsetType Size) + { + VERIFY_EXPR(Size != 0); + if(m_FreeSize < Size) + return InvalidOffset; + + // Get the first block that is >= Size + auto SmallestBlockItIt = m_FreeBlocksBySize.lower_bound(Size); + if(SmallestBlockItIt == m_FreeBlocksBySize.end()) + return InvalidOffset; + + auto SmallestBlockIt = SmallestBlockItIt->second; + VERIFY_EXPR(Size <= SmallestBlockIt->second.Size); + + auto Offset = SmallestBlockIt->first; + auto NewOffset = Offset + Size; + auto NewSize = SmallestBlockIt->second.Size - Size; + VERIFY_EXPR(SmallestBlockItIt == SmallestBlockIt->second.OrderBySizeIt); + m_FreeBlocksBySize.erase(SmallestBlockItIt); + m_FreeBlocks.erase(SmallestBlockIt); + if (NewSize > 0) + { + AddNewBlock(NewOffset, NewSize); + } + + m_FreeSize -= Size; + +#ifdef _DEBUG + DbgVerifyList(); +#endif + return Offset; + } + + void Free(OffsetType Offset, OffsetType Size) + { + VERIFY_EXPR(Offset+Size <= m_MaxSize); + + auto NextBlockIt = m_FreeBlocks.upper_bound(Offset); // First element > +#ifdef _DEBUG + { + auto LowBnd = m_FreeBlocks.lower_bound(Offset); // First element >= + // Since zero-size allocations are not allowed, lower bound must always be equal upper bound + VERIFY_EXPR(LowBnd == NextBlockIt); + } +#endif + VERIFY_EXPR(NextBlockIt == m_FreeBlocks.end() || Offset <= NextBlockIt->first + NextBlockIt->second.Size); + auto PrevBlockIt = NextBlockIt; + if(PrevBlockIt != m_FreeBlocks.begin()) + { + --PrevBlockIt; + VERIFY_EXPR(Offset >= PrevBlockIt->first + PrevBlockIt->second.Size); + } + else + PrevBlockIt = m_FreeBlocks.end(); + + OffsetType NewSize, NewOffset; + if(PrevBlockIt != m_FreeBlocks.end() && Offset == PrevBlockIt->first + PrevBlockIt->second.Size) + { + // PrevBlock.Offset Offset + // | | + // |<-----PrevBlock.Size----->|<------Size-------->| + // + NewSize = PrevBlockIt->second.Size + Size; + NewOffset = PrevBlockIt->first; + + if (NextBlockIt != m_FreeBlocks.end() && Offset + Size == NextBlockIt->first) + { + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->|<------Size-------->|<-----NextBlock.Size----->| + // + NewSize += NextBlockIt->second.Size; + m_FreeBlocksBySize.erase(PrevBlockIt->second.OrderBySizeIt); + m_FreeBlocksBySize.erase(NextBlockIt->second.OrderBySizeIt); + ++NextBlockIt; + m_FreeBlocks.erase(PrevBlockIt, NextBlockIt); + } + else + { + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->|<------Size-------->| ~ ~ ~ |<-----NextBlock.Size----->| + // + m_FreeBlocksBySize.erase(PrevBlockIt->second.OrderBySizeIt); + m_FreeBlocks.erase(PrevBlockIt); + } + } + else if (NextBlockIt != m_FreeBlocks.end() && Offset + Size == NextBlockIt->first) + { + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->|<-----NextBlock.Size----->| + // + NewSize = Size + NextBlockIt->second.Size; + NewOffset = Offset; + m_FreeBlocksBySize.erase(NextBlockIt->second.OrderBySizeIt); + m_FreeBlocks.erase(NextBlockIt); + } + else + { + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->| ~ ~ ~ |<-----NextBlock.Size----->| + // + NewSize = Size; + NewOffset = Offset; + } + + AddNewBlock(NewOffset, NewSize); + + m_FreeSize += Size; +#ifdef _DEBUG + DbgVerifyList(); +#endif + } + + OffsetType GetMaxSize()const{return m_MaxSize;} + bool IsFull()const{ return m_FreeSize==0; }; + bool IsEmpty()const{ return m_FreeSize==m_MaxSize; }; + OffsetType GetFreeSize()const{return m_FreeSize;} + +#ifdef _DEBUG + size_t DbgGetNumFreeBlocks()const{return m_FreeBlocks.size();} +#endif + + private: + void AddNewBlock(OffsetType Offset, OffsetType Size) + { + auto NewBlockIt = m_FreeBlocks.emplace(Offset, Size); + VERIFY_EXPR(NewBlockIt.second); + auto OrderIt = m_FreeBlocksBySize.emplace(Size, NewBlockIt.first); + NewBlockIt.first->second.OrderBySizeIt = OrderIt; + } + + +#ifdef _DEBUG + void DbgVerifyList() + { + OffsetType TotalFreeSize = 0; + + auto BlockIt = m_FreeBlocks.begin(); + auto PrevBlockIt = m_FreeBlocks.end(); + VERIFY_EXPR(m_FreeBlocks.size() == m_FreeBlocksBySize.size()); + while (BlockIt != m_FreeBlocks.end()) + { + VERIFY_EXPR(BlockIt->first >= 0 && BlockIt->first + BlockIt->second.Size <= m_MaxSize); + VERIFY_EXPR(BlockIt == BlockIt->second.OrderBySizeIt->second); + VERIFY(PrevBlockIt == m_FreeBlocks.end() || BlockIt->first > PrevBlockIt->first + PrevBlockIt->second.Size, "Adjoint blocks detected" ); + TotalFreeSize += BlockIt->second.Size; + + PrevBlockIt = BlockIt; + ++BlockIt; + } + + auto OrderIt = m_FreeBlocksBySize.begin(); + while (OrderIt != m_FreeBlocksBySize.end()) + { + VERIFY_EXPR(OrderIt->first == OrderIt->second->second.Size); + ++OrderIt; + } + + VERIFY_EXPR(TotalFreeSize == m_FreeSize); + } +#endif + + TFreeBlocksByOffsetMap m_FreeBlocks; + TFreeBlocksBySizeMap m_FreeBlocksBySize; + + OffsetType m_MaxSize = 0; + OffsetType m_FreeSize = 0; + }; +} diff --git a/Graphics/GraphicsTools/include/FreeBlockListManagerGPU.h b/Graphics/GraphicsTools/include/FreeBlockListManagerGPU.h new file mode 100644 index 00000000..f2961bd3 --- /dev/null +++ b/Graphics/GraphicsTools/include/FreeBlockListManagerGPU.h @@ -0,0 +1,85 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include <deque> +#include "FreeBlockListManager.h" +#include "STDAllocator.h" + +namespace Diligent +{ + class FreeBlockListManagerGPU : public FreeBlockListManager + { + private: + struct FreedAllocationInfo + { + OffsetType Offset; + OffsetType Size; + Uint64 FrameNumber; + FreedAllocationInfo(OffsetType _Offset, OffsetType _Size, Uint64 _FrameNumber) : + Offset(_Offset), Size(_Size), FrameNumber(_FrameNumber) + {} + }; + + public: + FreeBlockListManagerGPU(OffsetType MaxSize, IMemoryAllocator &Allocator) : + FreeBlockListManager(MaxSize, Allocator), + m_StaleAllocations(0, FreedAllocationInfo(0,0,0), STD_ALLOCATOR_RAW_MEM(FreedAllocationInfo, Allocator, "Allocator for deque< FreedAllocationInfo>" )) + {} + + ~FreeBlockListManagerGPU() + { + VERIFY(m_StaleAllocations.empty(), "Not all stale allocations released"); + } + + // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL) + FreeBlockListManagerGPU(FreeBlockListManagerGPU&& rhs) : + FreeBlockListManager(std::move(rhs)), + m_StaleAllocations(std::move(rhs.m_StaleAllocations)) + { + } + + FreeBlockListManagerGPU& operator = (FreeBlockListManagerGPU&& rhs) = default; + FreeBlockListManagerGPU(const FreeBlockListManagerGPU&) = delete; + FreeBlockListManagerGPU& operator = (const FreeBlockListManagerGPU&) = delete; + + void Free(OffsetType Offset, OffsetType Size, Uint64 FrameNumber) + { + m_StaleAllocations.emplace_back(Offset, Size, FrameNumber); + } + + void ReleaseCompletedFrames(Uint64 NumCompletedFrames) + { + while(!m_StaleAllocations.empty() && m_StaleAllocations.front().FrameNumber < NumCompletedFrames) + { + auto &OldestAllocation = m_StaleAllocations.front(); + FreeBlockListManager::Free(OldestAllocation.Offset, OldestAllocation.Size); + m_StaleAllocations.pop_front(); + } + } + + private: + std::deque< FreedAllocationInfo, STDAllocatorRawMem<FreedAllocationInfo> > m_StaleAllocations; + }; +} diff --git a/Graphics/GraphicsTools/include/GraphicsUtilities.h b/Graphics/GraphicsTools/include/GraphicsUtilities.h index 78002d01..6e6b34f6 100644 --- a/Graphics/GraphicsTools/include/GraphicsUtilities.h +++ b/Graphics/GraphicsTools/include/GraphicsUtilities.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ #include "Texture.h" #include "Buffer.h" #include "RenderDevice.h" +#include "DebugUtilities.h" namespace Diligent { @@ -99,8 +100,26 @@ template<>struct VALUE_TYPE2CType<VT_FLOAT16>{ typedef Uint16 CType; }; template<>struct VALUE_TYPE2CType<VT_FLOAT32>{ typedef Float32 CType; }; +static const Uint32 ValueTypeToSizeMap[] = +{ + 0, + sizeof(VALUE_TYPE2CType<VT_INT8> :: CType), + sizeof(VALUE_TYPE2CType<VT_INT16> :: CType), + sizeof(VALUE_TYPE2CType<VT_INT32> :: CType), + sizeof(VALUE_TYPE2CType<VT_UINT8> :: CType), + sizeof(VALUE_TYPE2CType<VT_UINT16> :: CType), + sizeof(VALUE_TYPE2CType<VT_UINT32> :: CType), + sizeof(VALUE_TYPE2CType<VT_FLOAT16> :: CType), + sizeof(VALUE_TYPE2CType<VT_FLOAT32> :: CType) +}; +static_assert(VT_NUM_TYPES == VT_FLOAT32 + 1, "Not all value type sizes initialized."); + /// Returns the size of the specified value type -Uint32 GetValueSize( VALUE_TYPE Val ); +inline Uint32 GetValueSize(VALUE_TYPE Val) +{ + VERIFY_EXPR(Val < _countof(ValueTypeToSizeMap)); + return ValueTypeToSizeMap[Val]; +} /// Returns the string representing the specified value type const Char* GetValueTypeString( VALUE_TYPE Val ); @@ -134,6 +153,16 @@ const Char *GetBufferViewTypeLiteralName(BUFFER_VIEW_TYPE ViewType); /// \return Literal name of the shader type. const Char *GetShaderTypeLiteralName(SHADER_TYPE ShaderType); + +/// Returns the literal name of a shader variable type. For instance, +/// for SHADER_VARIABLE_TYPE_STATIC, if bGetFullName == true, "SHADER_VARIABLE_TYPE_STATIC" will be returned; +/// if bGetFullName == false, "static" will be returned + +/// \param [in] VarType - Variable type. +/// \param [in] bGetFullName - Whether to return string representation of the enum value +/// \return Literal name of the shader variable type. +const Char *GetShaderVariableTypeLiteralName(SHADER_VARIABLE_TYPE VarType, bool bGetFullName = false); + /// Overloaded function that returns the literal name of a texture view type. /// see GetTexViewTypeLiteralName(). inline const Char* GetViewTypeLiteralName(TEXTURE_VIEW_TYPE TexViewType) @@ -152,7 +181,7 @@ inline const Char* GetViewTypeLiteralName(BUFFER_VIEW_TYPE BuffViewType) const Char* GetUsageString(USAGE Usage); /// Returns the string containing the texture type -const Char* GetTextureTypeString( TEXTURE_TYPE TexType ); +const Char* GetResourceDimString( RESOURCE_DIMENSION TexType ); /// Returns the string containing the bind flags String GetBindFlagsString( Uint32 BindFlags ); diff --git a/Graphics/GraphicsTools/include/RingBuffer.h b/Graphics/GraphicsTools/include/RingBuffer.h new file mode 100644 index 00000000..043e884d --- /dev/null +++ b/Graphics/GraphicsTools/include/RingBuffer.h @@ -0,0 +1,181 @@ +/* Copyright 2015-2016 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include <deque> +#include "MemoryAllocator.h" +#include "STDAllocator.h" +#include "DebugUtilities.h" + +namespace Diligent +{ + class RingBuffer + { + public: + typedef size_t OffsetType; + typedef std::pair<Uint64,OffsetType> FrameNumOffsetPair; + + static const OffsetType InvalidOffset = static_cast<OffsetType>(-1); + + RingBuffer(OffsetType MaxSize, IMemoryAllocator &Allocator) : + m_CompletedFrameTails(0, FrameNumOffsetPair(), STD_ALLOCATOR_RAW_MEM(FrameNumOffsetPair, Allocator, "Allocator for vector<FrameNumOffsetPair>" )), + m_MaxSize(MaxSize) + {} + + RingBuffer(RingBuffer&& rhs) : + m_CompletedFrameTails(std::move(rhs.m_CompletedFrameTails)), + m_Head(rhs.m_Head), + m_Tail(rhs.m_Tail), + m_MaxSize(rhs.m_MaxSize), + m_UsedSize(rhs.m_UsedSize) + { + rhs.m_Head = 0; + rhs.m_Tail = 0; + rhs.m_MaxSize = 0; + rhs.m_UsedSize = 0; + } + + RingBuffer& operator = (RingBuffer&& rhs) + { + m_CompletedFrameTails = std::move(rhs.m_CompletedFrameTails); + m_Head = rhs.m_Head; + m_Tail = rhs.m_Tail; + m_MaxSize = rhs.m_MaxSize; + m_UsedSize = rhs.m_UsedSize; + + rhs.m_MaxSize = 0; + rhs.m_Head = 0; + rhs.m_Tail = 0; + rhs.m_UsedSize = 0; + + return *this; + } + + RingBuffer(const RingBuffer&) = delete; + RingBuffer& operator = (const RingBuffer&) = delete; + + OffsetType Allocate(OffsetType Size) + { + if(IsFull()) + { + return InvalidOffset; + } + + if (m_Tail >= m_Head ) + { + // Head Tail MaxSize + // | | | + // [ xxxxxxxxxxxxxxxxx ] + // + // + if (m_Tail + Size <= m_MaxSize) + { + auto Offset = m_Tail; + m_Tail += Size; + m_UsedSize += Size; + return Offset; + } + else if(Size <= m_Head) + { + // Allocate from the beginning of the buffer + m_UsedSize += (m_MaxSize - m_Tail) + Size; + m_Tail = Size; + return 0; + } + } + else if (m_Tail + Size <= m_Head ) + { + // + // Tail Head + // | | + // [xxxx xxxxxxxxxxxxxxxxxxxxxxxxxx] + // + auto Offset = m_Tail; + m_Tail += Size; + m_UsedSize += Size; + return Offset; + } + + return InvalidOffset; + } + + void FinishCurrentFrame(Uint64 FrameNum) + { + m_CompletedFrameTails.push_back(std::make_pair(FrameNum, m_Tail) ); + } + + void ReleaseCompletedFrames(Uint64 NumCompletedFrames) + { + while(!m_CompletedFrameTails.empty() && m_CompletedFrameTails.front().first < NumCompletedFrames) + { + auto &OldestFrameTail = m_CompletedFrameTails.front().second; + if( m_UsedSize > 0 ) + { + if (OldestFrameTail > m_Head) + { + // m_Head OldestFrameTail MaxSize + // | | | + // [ xxxxxxxxxxxxxxxxxxxxx ] + // + // + VERIFY_EXPR(m_UsedSize >= OldestFrameTail - m_Head); + m_UsedSize -= OldestFrameTail - m_Head; + } + else + { + // OldestFrameTail m_Head MaxSize + // | | | + // [xxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx] + // + + // + // m_Head,OldestFrameTail MaxSize + // | | + // [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] + // + // + // + VERIFY_EXPR(m_UsedSize >= (m_MaxSize - m_Head) + OldestFrameTail); + m_UsedSize -= (m_MaxSize - m_Head); + m_UsedSize -= OldestFrameTail; + } + } + m_Head = OldestFrameTail; + m_CompletedFrameTails.pop_front(); + } + } + + OffsetType GetMaxSize()const{return m_MaxSize;} + bool IsFull()const{ return m_UsedSize==m_MaxSize; }; + bool IsEmpty()const{ return m_UsedSize==0; }; + OffsetType GetUsedSize()const{return m_UsedSize;} + + private: + std::deque< FrameNumOffsetPair, STDAllocatorRawMem<FrameNumOffsetPair> > m_CompletedFrameTails; + OffsetType m_Head = 0; + OffsetType m_Tail = 0; + OffsetType m_MaxSize = 0; + OffsetType m_UsedSize = 0; + }; +} diff --git a/Graphics/GraphicsTools/include/ShaderMacroHelper.h b/Graphics/GraphicsTools/include/ShaderMacroHelper.h index bcfc3e52..f64c2349 100644 --- a/Graphics/GraphicsTools/include/ShaderMacroHelper.h +++ b/Graphics/GraphicsTools/include/ShaderMacroHelper.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/include/pch.h b/Graphics/GraphicsTools/include/pch.h index b2893486..41fa3c3b 100644 --- a/Graphics/GraphicsTools/include/pch.h +++ b/Graphics/GraphicsTools/include/pch.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp b/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp index fa69c7c1..e15635e8 100644 --- a/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp +++ b/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/src/GraphicsUtilities.cpp b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp index 05cc0a3a..f3a7d873 100644 --- a/Graphics/GraphicsTools/src/GraphicsUtilities.cpp +++ b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,42 +29,6 @@ namespace Diligent { -Uint32 GetValueSize( VALUE_TYPE Val ) -{ - static Uint32 Sizes[VT_NUM_TYPES] = {}; - static bool bIsInit = false; - // Note that this implementation is thread-safe - // Even if two threads try to call the function at the same time, - // the worst thing that might happen is that the array will be - // initialized multiple times. But the result will always be correct - if( !bIsInit ) - { - Sizes[VT_UNDEFINED] = 0; -#define INIT_VALUE_SIZE( ValType ) Sizes[ValType] = sizeof(VALUE_TYPE2CType<ValType>::CType) - INIT_VALUE_SIZE( VT_INT8 ); - INIT_VALUE_SIZE( VT_INT16 ); - INIT_VALUE_SIZE( VT_INT32 ); - INIT_VALUE_SIZE( VT_UINT8 ); - INIT_VALUE_SIZE( VT_UINT16 ); - INIT_VALUE_SIZE( VT_UINT32 ); - INIT_VALUE_SIZE( VT_FLOAT16 ); - INIT_VALUE_SIZE( VT_FLOAT32 ); -#undef INIT_VALUE_SIZE - static_assert(VT_NUM_TYPES == VT_FLOAT32 + 1, "Not all value type sizes initialized."); - bIsInit = true; - } - - if( Val > VT_UNDEFINED && Val < VT_NUM_TYPES ) - { - return Sizes[Val]; - } - else - { - UNEXPECTED( "Incorrect value type (", Val, ")" ) - return 0; - } -} - const Char* GetValueTypeString( VALUE_TYPE Val ) { static const Char* ValueTypeStrings[VT_NUM_TYPES] = {}; @@ -233,7 +197,7 @@ const TextureFormatAttribs& GetTextureFormatAttribs( TEXTURE_FORMAT Format ) #ifdef _DEBUG for( Uint32 Fmt = TEX_FORMAT_UNKNOWN; Fmt < TEX_FORMAT_NUM_FORMATS; ++Fmt ) - VERIFY(FmtAttribs[Fmt].Format == Fmt, "Uninitialized format"); + VERIFY(FmtAttribs[Fmt].Format == static_cast<TEXTURE_FORMAT>(Fmt), "Uninitialized format"); #endif bIsInit = true; @@ -337,6 +301,33 @@ const Char *GetShaderTypeLiteralName( SHADER_TYPE ShaderType ) } } +const Char *GetShaderVariableTypeLiteralName(SHADER_VARIABLE_TYPE VarType, bool bGetFullName) +{ + static const Char* ShortVarTypeNameStrings[SHADER_VARIABLE_TYPE_NUM_TYPES]; + static const Char* FullVarTypeNameStrings[SHADER_VARIABLE_TYPE_NUM_TYPES]; + static bool bVarTypeStrsInit = false; + if( !bVarTypeStrsInit ) + { + ShortVarTypeNameStrings[SHADER_VARIABLE_TYPE_STATIC] = "static"; + ShortVarTypeNameStrings[SHADER_VARIABLE_TYPE_MUTABLE] = "mutable"; + ShortVarTypeNameStrings[SHADER_VARIABLE_TYPE_DYNAMIC] = "dynamic"; + FullVarTypeNameStrings[SHADER_VARIABLE_TYPE_STATIC] = "SHADER_VARIABLE_TYPE_STATIC"; + FullVarTypeNameStrings[SHADER_VARIABLE_TYPE_MUTABLE] = "SHADER_VARIABLE_TYPE_MUTABLE"; + FullVarTypeNameStrings[SHADER_VARIABLE_TYPE_DYNAMIC] = "SHADER_VARIABLE_TYPE_DYNAMIC"; + + static_assert(SHADER_VARIABLE_TYPE_NUM_TYPES == SHADER_VARIABLE_TYPE_DYNAMIC + 1, "Not all shader variable types initialized."); + + bVarTypeStrsInit = true; + } + if( VarType >= SHADER_VARIABLE_TYPE_STATIC && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES ) + return (bGetFullName ? FullVarTypeNameStrings : ShortVarTypeNameStrings)[VarType]; + else + { + UNEXPECTED("Unknow shader variable type") + return "unknow"; + } +} + /// Returns the string containing the usage const Char* GetUsageString( USAGE Usage ) { @@ -361,25 +352,26 @@ const Char* GetUsageString( USAGE Usage ) } } -const Char* GetTextureTypeString( TEXTURE_TYPE TexType ) +const Char* GetResourceDimString( RESOURCE_DIMENSION TexType ) { - static const Char* TexTypeStrings[TEXTURE_TYPE_NUM_TYPES]; + static const Char* TexTypeStrings[RESOURCE_DIM_NUM_DIMENSIONS]; static bool bTexTypeStrsInit = false; if( !bTexTypeStrsInit ) { - TexTypeStrings[TEXTURE_TYPE_UNDEFINED] = "Undefined"; - TexTypeStrings[TEXTURE_TYPE_1D] = "1D"; - TexTypeStrings[TEXTURE_TYPE_1D_ARRAY] = "1D Array"; - TexTypeStrings[TEXTURE_TYPE_2D] = "2D"; - TexTypeStrings[TEXTURE_TYPE_2D_ARRAY] = "2D Array"; - TexTypeStrings[TEXTURE_TYPE_3D] = "3D"; - TexTypeStrings[TEXTURE_TYPE_2D_ARRAY] = "Cube"; - TexTypeStrings[TEXTURE_TYPE_3D] = "Cube Array"; - static_assert(TEXTURE_TYPE_NUM_TYPES == TEXTURE_TYPE_CUBE_ARRAY + 1, "Not all texture type strings initialized."); + TexTypeStrings[RESOURCE_DIM_UNDEFINED] = "Undefined"; + TexTypeStrings[RESOURCE_DIM_BUFFER] = "Buffer"; + TexTypeStrings[RESOURCE_DIM_TEX_1D] = "Tex 1D"; + TexTypeStrings[RESOURCE_DIM_TEX_1D_ARRAY] = "Tex 1D Array"; + TexTypeStrings[RESOURCE_DIM_TEX_2D] = "Tex 2D"; + TexTypeStrings[RESOURCE_DIM_TEX_2D_ARRAY] = "Tex 2D Array"; + TexTypeStrings[RESOURCE_DIM_TEX_3D] = "Tex 3D"; + TexTypeStrings[RESOURCE_DIM_TEX_2D_ARRAY] = "Tex Cube"; + TexTypeStrings[RESOURCE_DIM_TEX_3D] = "Tex Cube Array"; + static_assert(RESOURCE_DIM_NUM_DIMENSIONS == RESOURCE_DIM_TEX_CUBE_ARRAY + 1, "Not all texture type strings initialized."); bTexTypeStrsInit = true; } - if( TexType >= TEXTURE_TYPE_UNDEFINED && TexType < TEXTURE_TYPE_NUM_TYPES ) + if( TexType >= RESOURCE_DIM_UNDEFINED && TexType < RESOURCE_DIM_NUM_DIMENSIONS ) return TexTypeStrings[TexType]; else { @@ -473,22 +465,22 @@ String ToString( T Val ) String GetTextureDescString( const TextureDesc &Desc ) { String Str = "Type: "; - Str += GetTextureTypeString(Desc.Type); + Str += GetResourceDimString(Desc.Type); Str += "; size: "; Str += ToString(Desc.Width); - if( Desc.Type == TEXTURE_TYPE_2D || Desc.Type == TEXTURE_TYPE_2D_ARRAY || Desc.Type == TEXTURE_TYPE_3D) + if( Desc.Type == RESOURCE_DIM_TEX_2D || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_3D || Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) { Str += "x"; Str += ToString( Desc.Height ); } - if( Desc.Type == TEXTURE_TYPE_3D ) + if( Desc.Type == RESOURCE_DIM_TEX_3D ) { Str += "x"; Str += ToString( Desc.Depth ); } - if( Desc.Type == TEXTURE_TYPE_1D_ARRAY || Desc.Type == TEXTURE_TYPE_2D_ARRAY ) + if( Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY ) { Str += "; Num Slices: "; Str += ToString( Desc.ArraySize ); @@ -593,8 +585,9 @@ String GetBufferDescString( const BufferDesc &Desc ) Uint32 ComputeMipLevelsCount( Uint32 Width ) { Uint32 MipLevels = 0; - while( (Width >> MipLevels) > 1 ) + while( (Width >> MipLevels) > 0 ) ++MipLevels; + VERIFY( Width >= (1U << (MipLevels-1)) && Width < (1U << MipLevels), "Incorrect number of Mip levels" ) return MipLevels; } diff --git a/Graphics/GraphicsTools/src/pch.cpp b/Graphics/GraphicsTools/src/pch.cpp index 809315e1..997e0f4a 100644 --- a/Graphics/GraphicsTools/src/pch.cpp +++ b/Graphics/GraphicsTools/src/pch.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 Egor Yusov +/* Copyright 2015-2016 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. |
