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/GraphicsEngineOpenGL | |
| parent | Release v1.0.0 (diff) | |
| download | DiligentCore-2b64f003622ee7871fd7aec041622427dd2fc88f.tar.gz DiligentCore-2b64f003622ee7871fd7aec041622427dd2fc88f.zip | |
Updated to Diligent Engine 2.0
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
101 files changed, 2565 insertions, 1893 deletions
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/GraphicsEngineOpenGL/build/Windows/EngineRoot.props b/Graphics/GraphicsEngineOpenGL/build/Win32/EngineRoot.props index 02287e9c..02287e9c 100644 --- a/Graphics/GraphicsEngineOpenGL/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/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/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/DSStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h index 38f8eaff..1ba6ec43 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DSStateGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.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,39 @@ #pragma once -#include "BaseInterfacesGL.h" -#include "DepthStencilStateGL.h" -#include "DepthStencilStateBase.h" -#include "RenderDevice.h" +/// \file +/// Declaration of Diligent::ShaderResourceBindingGLImpl class + +#include "ShaderResourceBindingGL.h" +#include "RenderDeviceGL.h" +#include "ShaderResourceBindingBase.h" +#include "GLProgramResources.h" +#include "ShaderBase.h" namespace Diligent { -/// Implementation of the Diligent::IDepthStencilStateGL interface -class DSStateGLImpl : public DepthStencilStateBase<IDepthStencilStateGL, IGLDeviceBaseInterface> +class FixedBlockMemoryAllocator; +/// Implementation of the Diligent::IShaderResourceBindingGL interface +class ShaderResourceBindingGLImpl : public ShaderResourceBindingBase<IShaderResourceBindingGL, FixedBlockMemoryAllocator> { public: - typedef DepthStencilStateBase<IDepthStencilStateGL, IGLDeviceBaseInterface> TDSStateBase; + 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; - DSStateGLImpl(class IRenderDevice *pDeviceGL, const DepthStencilStateDesc& DepthStencilStateDesc, bool bIsDeviceInternal = false); - ~DSStateGLImpl(); + GLProgramResources &GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl *pdbgPSO); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); +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/RasterizerStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_OGL.h index 6e28893a..7b2ff823 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RasterizerStateGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureCubeArray_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,24 +23,28 @@ #pragma once -#include "BaseInterfacesGL.h" -#include "RasterizerStateGL.h" -#include "RasterizerStateBase.h" -#include "RenderDevice.h" +#include "TextureBaseGL.h" namespace Diligent { -/// Implementation of the Diligent::IRasterizerStateGL interface -class RasterizerStateGLImpl : public RasterizerStateBase<IRasterizerStateGL, IGLDeviceBaseInterface> +class TextureCubeArray_OGL : public TextureBaseGL { public: - typedef RasterizerStateBase<IRasterizerStateGL, IGLDeviceBaseInterface> TRasterizerStateBase; + TextureCubeArray_OGL( FixedBlockMemoryAllocator& TexObjAllocator, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl *pDeviceGL, + class DeviceContextGLImpl *pDeviceContext, + const TextureDesc& BuffDesc, + const TextureData &InitData = TextureData(), + bool bIsDeviceInternal = false ); + ~TextureCubeArray_OGL(); - RasterizerStateGLImpl(class IRenderDevice *pDeviceGL, const RasterizerStateDesc& RasterizerStateDesc, bool bIsDeviceInternal = false ); - ~RasterizerStateGLImpl(); + 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: - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); }; } 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/BlendStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/PipelineStateGL.h index 8923adf5..0d5601fa 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/BlendStateGL.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::IBlendStateGL interface +/// Definition of the Diligent::IPipelineStateGL interface -#include "BlendState.h" +#include "PipelineState.h" namespace Diligent { -// {B543F4DC-000F-4EE6-AC06-E6642BBC3560} -static const Diligent::INTERFACE_ID IID_BlendStateGL = -{ 0xb543f4dc, 0xf, 0x4ee6, { 0xac, 0x6, 0xe6, 0x64, 0x2b, 0xbc, 0x35, 0x60 } }; +// {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 blend state object implemented in OpenGL -class IBlendStateGL : public Diligent::IBlendState -{ -public: +/// Interface to the PipelineState object implemented in OpenGL +class IPipelineStateGL : public Diligent::IPipelineState +{ + }; } diff --git a/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h b/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h deleted file mode 100644 index 685dff08..00000000 --- a/Graphics/GraphicsEngineOpenGL/interface/RasterizerStateGL.h +++ /dev/null @@ -1,45 +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 -/// Definition of the Diligent::IRasterizerStateGL interface - -#include "RasterizerState.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 } }; - -/// Interface to the rasterizer state object implemented in OpenGL -class IRasterizerStateGL : public Diligent::IRasterizerState -{ -public: - -}; - -} 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/interface/VertexDescriptionGL.h b/Graphics/GraphicsEngineOpenGL/interface/VertexDescriptionGL.h deleted file mode 100644 index 1a785e9b..00000000 --- a/Graphics/GraphicsEngineOpenGL/interface/VertexDescriptionGL.h +++ /dev/null @@ -1,45 +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 -/// Definition of the Diligent::IVertexDescriptionGL interface - -#include "VertexDescription.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 } }; - -/// Interface to the vertex description object implemented in OpenGL -class IVertexDescriptionGL : public Diligent::IVertexDescription -{ -public: - -}; - -} diff --git a/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp deleted file mode 100644 index fd0f1734..00000000 --- a/Graphics/GraphicsEngineOpenGL/src/BlendStateGLImpl.cpp +++ /dev/null @@ -1,42 +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 "BlendStateGLImpl.h" -#include "RenderDeviceGLImpl.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/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/DSStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DSStateGLImpl.cpp deleted file mode 100644 index 1b9929b6..00000000 --- a/Graphics/GraphicsEngineOpenGL/src/DSStateGLImpl.cpp +++ /dev/null @@ -1,43 +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 "DSStateGLImpl.h" -#include "RenderDeviceGLImpl.h" - -namespace Diligent -{ - -DSStateGLImpl::DSStateGLImpl(class IRenderDevice *pDeviceGL, const DepthStencilStateDesc& DepthStencilStateDesc, bool bIsDeviceInternal) : - TDSStateBase(pDeviceGL, DepthStencilStateDesc, bIsDeviceInternal) -{ -} - -DSStateGLImpl::~DSStateGLImpl() -{ - -} - -IMPLEMENT_QUERY_INTERFACE( DSStateGLImpl, IID_DepthStencilStateGL, TDSStateBase ) - -} 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/RasterizerStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RasterizerStateGLImpl.cpp deleted file mode 100644 index 191253f5..00000000 --- a/Graphics/GraphicsEngineOpenGL/src/RasterizerStateGLImpl.cpp +++ /dev/null @@ -1,43 +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 "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/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/VertexDescGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/VertexDescGLImpl.cpp deleted file mode 100644 index 0b2b6b50..00000000 --- a/Graphics/GraphicsEngineOpenGL/src/VertexDescGLImpl.cpp +++ /dev/null @@ -1,45 +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 "VertexDescGLImpl.h" -#include "RenderDeviceGLImpl.h" - -namespace Diligent -{ - -VertexDescGLImpl::VertexDescGLImpl( RenderDeviceGLImpl *pDeviceGL, const LayoutDesc &LayoutDesc, bool bIsDeviceInternal ) : - TVertexDescriptionBase(pDeviceGL, LayoutDesc) -{ - -} - -VertexDescGLImpl::~VertexDescGLImpl() -{ - static_cast<RenderDeviceGLImpl*>( GetDevice() )->m_VAOCache.OnDestroyVertexDesc(this); -} - -IMPLEMENT_QUERY_INTERFACE( VertexDescGLImpl, IID_VertexDescriptionGL, TVertexDescriptionBase ) - -} 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. |
