Carlos Marti 9 лет назад
Родитель
Сommit
52d97313dd
100 измененных файлов с 906 добавлено и 521 удалено
  1. BIN
      Data/Editor/GUISkin.asset
  2. BIN
      Data/Editor/Icons/Sprites/sprite_AnimationClipIcon.psd16.asset
  3. BIN
      Data/Editor/Icons/Sprites/sprite_AnimationClipIcon.psd32.asset
  4. BIN
      Data/Editor/Icons/Sprites/sprite_AnimationClipIcon.psd48.asset
  5. BIN
      Data/Editor/Icons/Sprites/sprite_AudioClipIcon.psd16.asset
  6. BIN
      Data/Editor/Icons/Sprites/sprite_AudioClipIcon.psd32.asset
  7. BIN
      Data/Editor/Icons/Sprites/sprite_AudioClipIcon.psd48.asset
  8. BIN
      Data/Editor/Icons/Sprites/sprite_CSharpIcon.psd16.asset
  9. BIN
      Data/Editor/Icons/Sprites/sprite_CSharpIcon.psd32.asset
  10. BIN
      Data/Editor/Icons/Sprites/sprite_CSharpIcon.psd48.asset
  11. BIN
      Data/Editor/Icons/Sprites/sprite_FolderIcon.psd16.asset
  12. BIN
      Data/Editor/Icons/Sprites/sprite_FolderIcon.psd32.asset
  13. BIN
      Data/Editor/Icons/Sprites/sprite_FolderIcon.psd48.asset
  14. BIN
      Data/Editor/Icons/Sprites/sprite_FontIcon.psd16.asset
  15. BIN
      Data/Editor/Icons/Sprites/sprite_FontIcon.psd32.asset
  16. BIN
      Data/Editor/Icons/Sprites/sprite_FontIcon.psd48.asset
  17. BIN
      Data/Editor/Icons/Sprites/sprite_GUISkinIcon.psd16.asset
  18. BIN
      Data/Editor/Icons/Sprites/sprite_GUISkinIcon.psd32.asset
  19. BIN
      Data/Editor/Icons/Sprites/sprite_GUISkinIcon.psd48.asset
  20. BIN
      Data/Editor/Icons/Sprites/sprite_MaterialIcon.psd16.asset
  21. BIN
      Data/Editor/Icons/Sprites/sprite_MaterialIcon.psd32.asset
  22. BIN
      Data/Editor/Icons/Sprites/sprite_MaterialIcon.psd48.asset
  23. BIN
      Data/Editor/Icons/Sprites/sprite_MeshIcon.psd16.asset
  24. BIN
      Data/Editor/Icons/Sprites/sprite_MeshIcon.psd32.asset
  25. BIN
      Data/Editor/Icons/Sprites/sprite_MeshIcon.psd48.asset
  26. BIN
      Data/Editor/Icons/Sprites/sprite_PhysicsMaterialIcon.psd16.asset
  27. BIN
      Data/Editor/Icons/Sprites/sprite_PhysicsMaterialIcon.psd32.asset
  28. BIN
      Data/Editor/Icons/Sprites/sprite_PhysicsMaterialIcon.psd48.asset
  29. BIN
      Data/Editor/Icons/Sprites/sprite_PhysicsMeshIcon.psd16.asset
  30. BIN
      Data/Editor/Icons/Sprites/sprite_PhysicsMeshIcon.psd32.asset
  31. BIN
      Data/Editor/Icons/Sprites/sprite_PhysicsMeshIcon.psd48.asset
  32. BIN
      Data/Editor/Icons/Sprites/sprite_PrefabIcon.psd16.asset
  33. BIN
      Data/Editor/Icons/Sprites/sprite_PrefabIcon.psd32.asset
  34. BIN
      Data/Editor/Icons/Sprites/sprite_PrefabIcon.psd48.asset
  35. BIN
      Data/Editor/Icons/Sprites/sprite_ShaderIcon.psd16.asset
  36. BIN
      Data/Editor/Icons/Sprites/sprite_ShaderIcon.psd32.asset
  37. BIN
      Data/Editor/Icons/Sprites/sprite_ShaderIcon.psd48.asset
  38. BIN
      Data/Editor/Icons/Sprites/sprite_ShaderIncludeIcon.psd16.asset
  39. BIN
      Data/Editor/Icons/Sprites/sprite_ShaderIncludeIcon.psd32.asset
  40. BIN
      Data/Editor/Icons/Sprites/sprite_ShaderIncludeIcon.psd48.asset
  41. BIN
      Data/Editor/Icons/Sprites/sprite_SpriteIcon.psd16.asset
  42. BIN
      Data/Editor/Icons/Sprites/sprite_SpriteIcon.psd32.asset
  43. BIN
      Data/Editor/Icons/Sprites/sprite_SpriteIcon.psd48.asset
  44. BIN
      Data/Editor/Icons/Sprites/sprite_TextIcon.psd16.asset
  45. BIN
      Data/Editor/Icons/Sprites/sprite_TextIcon.psd32.asset
  46. BIN
      Data/Editor/Icons/Sprites/sprite_TextIcon.psd48.asset
  47. BIN
      Data/Editor/Icons/Sprites/sprite_TextureIcon.psd16.asset
  48. BIN
      Data/Editor/Icons/Sprites/sprite_TextureIcon.psd32.asset
  49. BIN
      Data/Editor/Icons/Sprites/sprite_TextureIcon.psd48.asset
  50. BIN
      Data/Editor/ResourceManifest.asset
  51. BIN
      Data/Editor/Shaders/DockDropOverlay.bsl.asset
  52. BIN
      Data/Editor/Shaders/SolidHandle.bsl.asset
  53. BIN
      Data/Editor/Timestamp.asset
  54. BIN
      Data/Editor/arial.ttf.asset
  55. BIN
      Data/Editor/arialAA.ttf.asset
  56. BIN
      Data/Engine/GUISkin.asset
  57. BIN
      Data/Engine/ResourceManifest.asset
  58. BIN
      Data/Engine/Timestamp.asset
  59. BIN
      Data/Engine/arial.ttf.asset
  60. 3 3
      Data/Raw/Editor/Shaders/DockDropOverlay.bsl
  61. 1 2
      Data/Raw/Editor/Shaders/SolidHandle.bsl
  62. 0 1
      Documentation/Doxygen/Native.doxyconfig
  63. 6 1
      Documentation/GitHub/compiling.md
  64. 18 1
      Documentation/GitHub/dependencies.md
  65. 2 0
      Documentation/GitHub/roadmap.md
  66. 2 2
      Documentation/Manuals/Native/coreThread.md
  67. 24 15
      Documentation/Manuals/Native/gpuPrograms.md
  68. 2 2
      Documentation/Manuals/Native/materials.md
  69. 8 3
      Documentation/Manuals/Native/meshes.md
  70. 115 78
      Documentation/Manuals/Native/renderAPI.md
  71. 34 18
      Documentation/Manuals/Native/renderTargets.md
  72. 7 1
      Documentation/Manuals/Native/resources.md
  73. 20 5
      Documentation/Manuals/Native/textures.md
  74. 4 0
      Documentation/glslangCompilationGuide.txt
  75. 3 0
      README.md
  76. 30 21
      Source/BansheeCore/CMakeSources.cmake
  77. 50 0
      Source/BansheeCore/Include/BsCommandBuffer.h
  78. 28 0
      Source/BansheeCore/Include/BsCommandBufferManager.h
  79. 54 2
      Source/BansheeCore/Include/BsCommonTypes.h
  80. 1 1
      Source/BansheeCore/Include/BsComponent.h
  81. 1 7
      Source/BansheeCore/Include/BsCoreObjectManager.h
  82. 3 2
      Source/BansheeCore/Include/BsCorePrerequisites.h
  83. 1 2
      Source/BansheeCore/Include/BsCoreThreadAccessor.h
  84. 0 28
      Source/BansheeCore/Include/BsDrawOps.h
  85. 6 2
      Source/BansheeCore/Include/BsEventQuery.h
  86. 48 26
      Source/BansheeCore/Include/BsGpuBuffer.h
  87. 6 6
      Source/BansheeCore/Include/BsGpuBufferView.h
  88. 7 6
      Source/BansheeCore/Include/BsGpuParamBlockBuffer.h
  89. 6 3
      Source/BansheeCore/Include/BsGpuParamDesc.h
  90. 99 78
      Source/BansheeCore/Include/BsGpuParams.h
  91. 11 56
      Source/BansheeCore/Include/BsGpuParamsSet.h
  92. 172 0
      Source/BansheeCore/Include/BsGpuPipelineState.h
  93. 20 27
      Source/BansheeCore/Include/BsGpuProgram.h
  94. 8 47
      Source/BansheeCore/Include/BsGpuProgramManager.h
  95. 4 4
      Source/BansheeCore/Include/BsHardwareBuffer.h
  96. 79 53
      Source/BansheeCore/Include/BsHardwareBufferManager.h
  97. 10 9
      Source/BansheeCore/Include/BsIndexBuffer.h
  98. 13 7
      Source/BansheeCore/Include/BsMesh.h
  99. 0 1
      Source/BansheeCore/Include/BsMeshBase.h
  100. 0 1
      Source/BansheeCore/Include/BsMeshData.h

BIN
Data/Editor/GUISkin.asset


BIN
Data/Editor/Icons/Sprites/sprite_AnimationClipIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_AnimationClipIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_AnimationClipIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_AudioClipIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_AudioClipIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_AudioClipIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_CSharpIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_CSharpIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_CSharpIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_FolderIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_FolderIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_FolderIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_FontIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_FontIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_FontIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_GUISkinIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_GUISkinIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_GUISkinIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_MaterialIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_MaterialIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_MaterialIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_MeshIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_MeshIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_MeshIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_PhysicsMaterialIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_PhysicsMaterialIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_PhysicsMaterialIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_PhysicsMeshIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_PhysicsMeshIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_PhysicsMeshIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_PrefabIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_PrefabIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_PrefabIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_ShaderIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_ShaderIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_ShaderIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_ShaderIncludeIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_ShaderIncludeIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_ShaderIncludeIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_SpriteIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_SpriteIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_SpriteIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_TextIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_TextIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_TextIcon.psd48.asset


BIN
Data/Editor/Icons/Sprites/sprite_TextureIcon.psd16.asset


BIN
Data/Editor/Icons/Sprites/sprite_TextureIcon.psd32.asset


BIN
Data/Editor/Icons/Sprites/sprite_TextureIcon.psd48.asset


BIN
Data/Editor/ResourceManifest.asset


BIN
Data/Editor/Shaders/DockDropOverlay.bsl.asset


BIN
Data/Editor/Shaders/SolidHandle.bsl.asset


BIN
Data/Editor/Timestamp.asset


BIN
Data/Editor/arial.ttf.asset


BIN
Data/Editor/arialAA.ttf.asset


BIN
Data/Engine/GUISkin.asset


BIN
Data/Engine/ResourceManifest.asset


BIN
Data/Engine/Timestamp.asset


BIN
Data/Engine/arial.ttf.asset


+ 3 - 3
Data/Raw/Editor/Shaders/DockDropOverlay.bsl

@@ -3,9 +3,9 @@ Parameters =
 	float	invViewportWidth;
 	float	invViewportHeight;
 	
-	float4		tintColor;
-	float4		highlightColor;
-	float4		highlightActive;
+	color		tintColor;
+	color		highlightColor;
+	color		highlightActive;
 };
 
 Technique =

+ 1 - 2
Data/Raw/Editor/Shaders/SolidHandle.bsl

@@ -29,8 +29,7 @@ Technique : inherits("SolidGizmo") =
 		DepthWrite = false;
 		DepthRead = false;
 		Stencil = true;
-		StencilRef = 1;
-		StencilOpBack = { KEEP, KEEP, INC, PASS };
+		StencilOpFront = { KEEP, KEEP, INC, PASS };
 		
 		Target =
 		{

+ 0 - 1
Documentation/Doxygen/Native.doxyconfig

@@ -779,7 +779,6 @@ INPUT                  = ../../Source/BansheeUtility/Include \
                          ../../Source/BansheeCore/Include \
                          ../../Source/BansheeEngine/Include \
                          ../../Source/BansheeEditor/Include \
-                         ../../Source/BansheeD3D9RenderAPI/Include \
                          ../../Source/BansheeD3D11RenderAPI/Include \
                          ../../Source/BansheeGLRenderAPI/Include \
                          ../../Source/BansheeFBXImporter/Include \

+ 6 - 1
Documentation/GitHub/compiling.md

@@ -14,7 +14,7 @@ To compile follow these steps:
  1. Download source code
  2. Set up [third party dependencies](#dependencies)
  3. Generate a build file (e.g. Visual Studio solution or a Makefile) using CMake
-  - You can customize your build by choosing options like render API (DirectX, OpenGL), audio module and whether to build the entire editor or just the engine.
+  - You can customize your build by choosing options like render API (Vulkan, DirectX, OpenGL), audio module and whether to build the entire editor or just the engine.
  4. Compile using your favorite tool
 
 # <a name="dependencies"></a>Third party dependencies
@@ -39,6 +39,11 @@ The following dependencies will need to be installed manually regardless if you
  - Only needed if on Windows 10 and using DirectX 11 render API
  - Go to Settings panel (type "Settings" in Start)->System->Apps & features->Manage optional Features->Add a feature->Select "Graphics Tools"
  
+**Vulkan SDK** (Optional if not using Vulkan) 
+ - Only needed if you selected the Vulkan render API during build configuration (selected by default)
+ - https://lunarg.com/vulkan-sdk/
+ - If CMake complains it cannot find Vulkan, manually set the Vulkan_INSTALL_DIRS to your installation directory
+ 
 **Python 3.5** (Optional)
  - Only needed if you plan on running Python scripts in the /Scripts folder
  - https://www.python.org/downloads/

+ 18 - 1
Documentation/GitHub/dependencies.md

@@ -169,7 +169,7 @@ If the library structure still isn't clear, download one of the pre-compiled dep
     - libvorbisfile.dll (All configurations)
    
 **libFLAC**
- - libflac commit:94a61241b02064c7d9fe508f72a742f2a90b8492
+ - libflac commit: 94a61241b02064c7d9fe508f72a742f2a90b8492
  - https://git.xiph.org/?p=flac.git
  - Compilation notes:
   - Requires libogg, as described in its readme file.
@@ -179,6 +179,23 @@ If the library structure still isn't clear, download one of the pre-compiled dep
     - libFLAC.lib (Compile using "release" configuration)
     - libFLAC_dynamic.dll (All configurations)
    
+**glslang**
+ - glslang commit: 19bdf90eba71390f04bb85226337517df65d73e2
+ - https://github.com/KhronosGroup/glslang
+ - Compilation notes:
+  - Read the glslangCompilationGuide.txt before compiling
+ - Required by BansheeVulkanRenderAPI
+ - Outputs:
+  - Windows (Static library):
+    - glslang.lib (Compile using "release" configuration)
+	- glslangd.lib (Compile using "debug" configuration)
+	- HLSL.lib (Compile using "release" configuration)
+	- HLSLd.lib (Compile using "debug" configuration)
+	- OGLCompiler.lib (Compile using "release" configuration)
+	- OGLCompilerd.lib (Compile using "debug" configuration)
+	- OSDependent.lib (Compile using "release" configuration)
+	- OSDependentd.lib (Compile using "debug" configuration)
+   
 **bison**
  - Bison 2.7
  - http://sourceforge.net/projects/winflexbison/files/

+ 2 - 0
Documentation/GitHub/roadmap.md

@@ -1,5 +1,7 @@
 # Roadmap
 
+[Detailed task list] (https://trello.com/b/w6CyYY37/banshee-3d)
+
 We are currently focusing on finish up a final set of features before releasing 1.0 stable. These features are:
  - Vulkan implementation
  - Physically based renderer

+ 2 - 2
Documentation/Manuals/Native/coreThread.md

@@ -45,7 +45,7 @@ Because of these two reasons core accessors are much faster than the primary com
 
 Accessor for the current thread can be retrieved with @ref BansheeEngine::CoreThread::getAccessor "CoreThread::getAccessor". You queue the commands in the accessor by calling @ref BansheeEngine::CoreThreadAccessorBase::queueCommand "CoreThreadAccessor::queueCommand" and @ref BansheeEngine::CoreThreadAccessorBase::queueReturnCommand "CoreThreadAccessor::queueReturnCommand". Once you are done queuing commands you can submit them to the core thread by calling @ref BansheeEngine::CoreThread::submitAccessors "CoreThread::submitAccessors".
 
-Internally @ref BansheeEngine::CoreThread::submitAccessors "CoreThread::submitAccessors" uses the primary queue to submit a command that reads all the commands from the accessor and executes them in order. So esentially they are just built on top of the primary command queue, and if fact most of the threading functionality is.
+Internally @ref BansheeEngine::CoreThread::submitAccessors "CoreThread::submitAccessors" uses the primary queue to submit a command that reads all the commands from the accessor and executes them in order. So esentially they are just built on top of the primary command queue, and in fact most of the threading functionality is.
 
 ### Core accessor APIs {#coreThread_a_c_a}
 Although you can queue your own commands to the core accessor, many systems provide methods that automatically queue commands on the core accessor. For example take a look at @ref BansheeEngine::RenderAPI "RenderAPI" which allows you to interact directly with the render API from the simulation thread (something that is normally reserved for the core thread). Most of the methods accept a @ref BansheeEngine::CoreThreadAccessor<CommandQueueSyncPolicy> "CoreThreadAccessor", and internally just queue commands on it. This allows you to perform low level rendering operations from the simulation thread.
@@ -133,7 +133,7 @@ Whenever you need to trigger synchronization you must call @ref BansheeEngine::C
 See implementation of @ref BansheeEngine::Light "Light" and @ref BansheeEngine::LightCore "LightCore" in "BsLight.cpp" for a simple example of synchronization.
 
 ### Dependencies {#coreThread_b_a_c}
-Core objects might be dependant on other core objects. For example a @ref BansheeEngine::Material "Material" is dependant on a @ref BansheeEngine::Shader "Shader". Whenever the shader's object is marked as dirty the material might want need to perform synchronization as well. In general whenever a dependancy core object is marked as dirty, its dependant will be synchronized as well.
+Core objects might be dependant on other core objects. For example a @ref BansheeEngine::Material "Material" is dependant on a @ref BansheeEngine::Shader "Shader". Whenever the shader's object is marked as dirty the material might need to perform synchronization as well. In general whenever a dependancy core object is marked as dirty, its dependant will be synchronized as well.
 
 To add dependencies implement the @ref BansheeEngine::CoreObject::getCoreDependencies "CoreObject::getCoreDependencies" method, which returns all currently valid dependencies. Whenever the dependencies change call @ref BansheeEngine::CoreObject::markDependenciesDirty "CoreObject::markDependenciesDirty" so the system can refresh its dependency list.
 

+ 24 - 15
Documentation/Manuals/Native/gpuPrograms.md

@@ -24,29 +24,40 @@ For example if we wanted to create a HLSL fragment program (HLSL source not show
 ~~~~~~~~~~~~~{.cpp}
 String hlslSource = "...";
 
-SPtr<GpuProgram> myProgram = GpuProgram::create(hlslSource, "main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_FS_5_0);
+GPU_PROGRAM_DESC desc;
+desc.type = GPT_FRAGMENT_PROGRAM;
+desc.source = hlslSource;
+desc.entryPoint = "main";
+desc.language = "hlsl";
+desc.profile = GPP_FS_5_0;
+
+SPtr<GpuProgram> myProgram = GpuProgram::create(desc);
 ~~~~~~~~~~~~~ 
  
 Once the GPU program has been created it is not guaranteed to be usable. The compilation of the provided source code could have failed, which you can check by calling @ref BansheeEngine::GpuProgram::isCompiled() "GpuProgram::isCompiled", and retrieve the error message by calling @ref BansheeEngine::GpuProgram::getCompileErrorMessage() "GpuProgram::getCompileErrorMessage". Be aware that both of these methods are only valid after the core thread has initialized the object. You can ensure this by calling @ref BansheeEngine::CoreObject::blockUntilCoreInitialized "GpuProgram::blockUntilCoreInitialized" but be aware this will block the calling thread which can result in a significant performance impact.
 
 # GPU program parameters {#gpuPrograms_b}
-Once the GPU program has been compiled you can access information about its parameters (constant variables, or uniforms in DirectX/OpenGL lingo). Use @ref BansheeEngine::GpuProgram::getParamDesc "GpuProgram::getParamDesc" to retrieve a structure containing all GPU parameters, including primitive parameters, textures, samplers, buffers and parameter buffers (constant/uniform buffers in DirectX/OpenGL lingo). You can use this information to manually bind parameters to the GPU program, but normally you do not have to.
+Once the GPU program has been compiled you can access information about its parameters (constant variables, or uniforms in DirectX/OpenGL lingo). Use @ref BansheeEngine::GpuProgram::getParamDesc "GpuProgram::getParamDesc" to retrieve a structure containing all GPU parameters, including primitive parameters, textures, samplers, buffers and parameter buffers (constant/uniform buffers in DirectX/OpenGL lingo). 
 
-Instead @ref BansheeEngine::GpuProgram::createParameters "GpuProgram::createParameters()" will create a @ref BansheeEngine::GpuParams "GpuParams" object which allows you to query information about all parameters, but more importantly it also allows you to set values of those parameters easily.
+You generally don't need to use this information directly, but you provide it when creating a @ref BansheeEngine::GpuParams "GpuParams" object.
 
 ## GpuParams {#gpuPrograms_b_a}
-@ref BansheeEngine::GpuParams "GpuParams" is a container for all parameters required by a GPU program. It allows you to set primitive/texture/sampler/buffer parameters used by the GPU program, which it stores in an internal buffer. You can then bind it to the pipeline and it will be used by the program.
+@ref BansheeEngine::GpuParams "GpuParams" is a container for all parameters required by a set of GPU programs (one per stage). It allows you to set primitive/texture/sampler/buffer parameters used by the GPU programs, which it stores in an internal buffer. You can then bind it to the pipeline and it will be used by the bound GPU programs.
 
 For example to assign a texture and a 2D vector as input to the program we created earlier:
 ~~~~~~~~~~~~~{.cpp}
-SPtr<GpuParams> params = myProgram->createParameters();
+GPU_PARAMS_DESC desc;
+desc.fragmentParams = myProgram->getParamDesc();
+... usually you want to set other stages as well ...
 
-// Retrieve GPU params we can then read/write to
+SPtr<GpuParams> params = GpuParams::create(desc);
+
+// Retrieve GPU param handles we can then read/write to
 GpuParamVec2 myVectorParam;
 GpuParamTexture myTextureParam;
 
-params->getParam("myVector", myVectorParam); // Assuming "myVector" is the variable name in the program source code
-params->getTextureParam("myTexture", myTextureParam); // Assuming "myTexture" is the variable name in the program source code
+params->getParam(GPT_FRAGMENT_PROGRAM, "myVector", myVectorParam); // Assuming "myVector" is the variable name in the program source code
+params->getTextureParam(GPT_FRAGMENT_PROGRAM, "myTexture", myTextureParam); // Assuming "myTexture" is the variable name in the program source code
 
 myVectorParam.set(Vector2(1, 2));
 myTextureParam.set(myTexture); // Assuming we created "myTexture" earlier.
@@ -54,16 +65,14 @@ myTextureParam.set(myTexture); // Assuming we created "myTexture" earlier.
 
 As you can see we must first retrieve a handle to the parameter, and then we can use that handle for reading/writing to the parameter. You can store those handles for easier access to the parameters, as looking them up by using the parameter name can be relatively slow.
 
-# Using GPU programs for rendering {#gpuPrograms_c}
-You can bind a GPU program to the pipeline by calling @ref BansheeEngine::RenderAPI::bindGpuProgram "RenderAPI::bindGpuProgram". Any draw calls following this bind will use the bound GPU program. You can unbind a program by calling @ref BansheeEngine::RenderAPI::unbindGpuProgram "RenderAPI::unbindGpuProgram".
-
-You can bind parameters for use in the GPU program by calling @ref BansheeEngine::RenderAPICore::setParamBuffer "RenderAPICore::setParamBuffer" for primitive parameters (vector, float, etc.) organized as @ref BansheeEngine::GpuParamBlockBuffer "GpuParamBlockBuffer", and @ref BansheeEngine::RenderAPICore::setTexture "RenderAPICore::setTexture", @ref BansheeEngine::RenderAPICore::setLoadStoreTexture "RenderAPICore::setLoadStoreTexture", @ref BansheeEngine::RenderAPICore::setBuffer "RenderAPICore::setBuffer", @ref BansheeEngine::RenderAPICore::setSamplerState "RenderAPICore::setSamplerState" for textures, buffers and sampler states.
+See the [render API manual](@ref renderAPI) for more information about how to set and bind GPU program parameters.
 
-You can retrieve the primitive parameter buffer from a @ref BansheeEngine::Material "Material" by calling @ref BansheeEngine::Material::getParamBuffer "Material::getParamBuffer", or by manually creating and populating one.
+# Using GPU programs for rendering {#gpuPrograms_c}
+You can bind a GPU program to the pipeline by assigning it to a @ref BansheeEngine::GpuPipelineState "GpuPipelineState" and calling @ref BansheeEngine::RenderAPI::setGraphicsPipeline "RenderAPI::setGraphicsPipeline". Or alternatively if using compute programs you can bind by calling @ref BansheeEngine::RenderAPI::setComputePipeline "RenderAPI::setComputePipeline". Any subsequent draw/dispatch calls will then use the bound GPU programs. 
 
-Alternatively you can use the helper method @ref BansheeEngine::RendererUtility::setGpuParams "RendererUtility::setGpuParams" which will bind both object and data parameters in the @ref BansheeEngine::GpuParams "BansheeEngine::GpuParams" object.
+You can bind parameters for use in the GPU program by calling @ref BansheeEngine::RenderAPICore::setGpuParams "RenderAPICore::setGpuParams" which accepts the @ref BansheeEngine::GpuParamsCore "GpuParamsCore" object we described above.
 
-To learn more about the render API read the [manual](@ref renderAPI).
+Much more detailed information about rendering is provided in the [render API manual](@ref renderAPI).
 
 # Core thread GPU programs {#gpuPrograms_e}
 So far we have only talked about the simulation thread @ref BansheeEngine::GpuProgram "GpuProgram" but have ignored the core thread @ref BansheeEngine::GpuProgramCore "GpuProgramCore". The functionality between the two is mostly the same, with the major difference being that operations performed on the core thread version are immediate. So calls to @ref BansheeEngine::GpuProgramCore::isCompiled() "GpuProgramCore::isCompiled" and @ref BansheeEngine::GpuProgramCore::getCompileErrorMessage() "GpuProgramCore::getCompileErrorMessage" don't require any waiting.

+ 2 - 2
Documentation/Manuals/Native/materials.md

@@ -6,7 +6,7 @@ A material controls how is an object rendered. In Banshee it is represented with
 
 We'll focus on the simulation thread @ref BansheeEngine::Material "Material" throughout this manual, but aside from the `Core` suffix there are no major differences between the two interfaces.
 
-Internally material contains a set of GPU programs, render states and GPU program parameters. GPU programs and render states are immutable and are controlled by the @ref BansheeEngine::Shader "Shader" assigned to the material. The parameters can be modified by the interface provided by the material, and this parameter access actually constitutes the bulk of the material's interface. Essentially materials can be tought of as shader "instances".
+Internally material contains a set of GPU programs, render states and GPU program parameters. GPU programs and render states are immutable and are controlled by the @ref BansheeEngine::Shader "Shader" assigned to the material. The parameters can be modified by the interface provided by the material, and this parameter access actually constitutes the bulk of the material's interface. Essentially materials can be thought of as shader "instances".
 
 Since shaders are such intrical parts of materials, we'll explain how to create them before continuing with the discussion about materials.
 
@@ -46,7 +46,7 @@ Now that we know how to create a pass, we can use one or multiple passes to init
 
 To create a technique call @ref BansheeEngine::Technique::create "Technique::create" and provide it with:
  - One or multiple passes
- - Supported render API name: Use built-in `RenderAPIAny` to signal that the technique works on any API, or use the render API identifier to signal that it only works on a specific one. By default supported identifiers are: `"D3D11RenderAPI"`, `"D3D9RenderAPI"`, `"GLRenderAPI"`, but more can be added via plugins. In general those identifiers are returned from @ref BansheeEngine::RenderAPICore::getName "RenderAPICore::getName". Most users should be okay by providing `RenderAPIAny`.
+ - Supported render API name: Use built-in `RenderAPIAny` to signal that the technique works on any API, or use the render API identifier to signal that it only works on a specific one. By default supported identifiers are: `"VulkanRenderAPI"`, `"D3D11RenderAPI"`, `"GLRenderAPI"`, but more can be added via plugins. In general those identifiers are returned from @ref BansheeEngine::RenderAPICore::getName "RenderAPICore::getName". Most users should be okay by providing `RenderAPIAny`.
  - Supported renderer name: Use built-in `RendererAny` to signal that the technique works on any renderer, or use the renderer identifier to signal that it only works on a specific one. By default the only supported identifier is `"RenderBeast"`, but more can be added via plugins. In general those identifiers are returned from @ref BansheeEngine::Renderer::getName "Renderer::getName". Most users should be okay by providing `RendererAny`.
  - An optional list of tags that allows renderer to pick which technique to use when rendering objects. Can be left empty in most cases.
 

+ 8 - 3
Documentation/Manuals/Native/meshes.md

@@ -7,7 +7,7 @@ Mesh is an object represented by a set of points, their properties and a set of
 We're going to focus on the simulation thread implementation in this manual, and then note the differences in the core thread version at the end.
 
 # Creating a mesh {#meshes_a}
-To create a mesh call @ref BansheeEngine::Mesh::create "Mesh::create" or one if its overloads. At minimum you need to provide a @ref BansheeEngine::VertexDataDesc "vertex description" that describes in what format are the vertices stored in the vertex buffer and the number of vertices and indices. 
+To create a mesh call @ref BansheeEngine::Mesh::create "Mesh::create" or one if its overloads. You'll need to populate the @ref BansheeEngine::MESH_DESC "MESH_DESC" structure and pass it as a parameter. At minimum you need to provide a @ref BansheeEngine::VertexDataDesc "vertex description" that describes in what format are the vertices stored in the vertex buffer and the number of vertices and indices. 
 
 Optionally you can also provide the type of indices, type of primitives, and a set of sub-meshes:
  - Indices can be 32- or 16-bit. This is controlled by the `indexType` parameter. Smaller indices can be used to save bandwidth if your mesh has a small enough number of primitives.
@@ -16,10 +16,15 @@ Optionally you can also provide the type of indices, type of primitives, and a s
  
 For example to create a simple mesh:
 ~~~~~~~~~~~~~{.cpp}
+// Creates an empty mesh with 36 indices and 8 vertices
+MESH_DESC meshDesc;
+meshDesc.numVertices = 8;
+meshDesc.numIndices = 36;
+
 SPtr<VertexDataDesc> vertexDesc = ...; // Vertex description creation is explained later
+meshDesc.vertexDesc = vertexDesc;
 
-// Creates an empty mesh with 36 indices and 8 vertices
-HMesh mesh = Mesh::create(8, 32, vertexDesc);
+HMesh mesh = Mesh::create(meshDesc);
 ~~~~~~~~~~~~~ 
  
 You can also create a non-empty mesh by creating it with a populated @ref BansheeEngine::MeshData "MeshData" object. More about @ref BansheeEngine::MeshData "MeshData" later. 

+ 115 - 78
Documentation/Manuals/Native/renderAPI.md

@@ -8,18 +8,15 @@ For the remainder of this manual we'll focus on the core thread portion of the A
 
 Render API lets you manipulate the GPU pipeline by setting various states (depth stencil, blend and rasterizer), binding GPU programs, textures and executing draw calls. In this manual we'll cover how to use this API to perform rendering manually. 
 
-To render something using this API you need to:
+To render using this API you need to:
  - Create and bind a render target
   - Set up a viewport (if rendering to a part of a render target)
   - Clear render target (if we're re-using a render target)
- - Create and bind depth stencil, blend and/or rasterizer states (optionally)
- - Create and bind GPU programs
-   - Create and bind vertex/fragment GPU program
+ - Create and bind a pipeline state
+   - Create and bind vertex/fragment GPU programs
+   - Create and bind depth stencil, blend and/or rasterizer states (optionally)
    - Create and bind geometry/hull/domain GPU program (optionally)
- - Bind GPU program parameters (if any)
-  - Bind textures
-  - Bind samplers
-  - Bind parameter buffers (better known constant/uniform buffers)
+ - Bind GPU program parameters (textures, samplers, etc., if any)
  - Create and bind vertices
   - Create and bind the vertex declaration
   - Create and bind the vertex buffer
@@ -53,101 +50,115 @@ rapi.clearViewport(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White, 1.0f, 0);
 rapi.swapBuffers();
 ~~~~~~~~~~~~~
  
-# Pipeline states {#renderAPI_b}
-Before executing the drawing operation you can optionally set up depth-stencil, rasterizer or blend states. If you do not set them, the default values will be used. The states allow you to customize the execution of the fixed (non-programmable) part of the GPU pipeline.
+# Pipeline state {#renderAPI_b}
+Before executing the drawing operation you must set up an @ref BansheeEngine::GpuPipelineStateCore "GpuPipelineStateCore" object, which contains a set of fixed and programmable states that control primitive rendering. This includes GPU programs (e.g. vertex/fragment) and fixed states (depth-stencil, blend, rasterizer).
 
-States can be created by:
- - @ref BansheeEngine::DepthStencilStateCore "DepthStencilStateCore" - Populate @ref BansheeEngine::DEPTH_STENCIL_STATE_DESC "DEPTH_STENCIL_STATE_DESC" and call @ref BansheeEngine::DepthStencilStateCore::create "DepthStencilStateCore::create" 
- - @ref BansheeEngine::BlendStateCore "BlendStateCore" - Populate @ref BansheeEngine::BLEND_STATE_DESC "BLEND_STATE_DESC" and call @ref BansheeEngine::BlendStateCore::create "BlendStateCore::create" 
- - @ref BansheeEngine::RasterizerStateCore "RasterizerStateCore" - Populate @ref BansheeEngine::RASTERIZER_STATE_DESC "RASTERIZER_STATE_DESC" and call @ref BansheeEngine::RasterizerStateCore::create "RasterizerStateCore::create" 
- 
-They can then be bound to the pipeline by calling:
- - @ref BansheeEngine::RenderAPICore::setDepthStencilState "RenderAPICore::setDepthStencilState" for @ref BansheeEngine::DepthStencilStateCore "DepthStencilStateCore"
- - @ref BansheeEngine::RenderAPICore::setBlendState "RenderAPICore::setBlendState" for @ref BansheeEngine::BlendStateCore "BlendStateCore".
- - @ref BansheeEngine::RenderAPICore::setRasterizerState "RenderAPICore::setRasterizerState" for @ref BansheeEngine::RasterizerStateCore "RasterizerStateCore".
-
-We won't explain what each of the state's does. For that you can check out the class documentation of the states themselves, or familiarize yourself with the modern GPU pipeline in general, as the states mirror it exactly.
-
-# GPU programs {#renderAPI_c}
-Before drawing you must bind at least a vertex and a fragment GPU program. Optionally you can also bind geometry, hull or domain programs. While pipeline states allow you to control the fixed portions of the pipeline, GPU programs are fully programmable. To learn how to create GPU programs read the [manual](@ref gpuPrograms).
+To create a pipeline state you must fill out @ref BansheeEngine::PIPELINE_STATE_CORE_DESC "PIPELINE_STATE_CORE_DESC" descriptor, and use it to construct the state, like so:
+~~~~~~~~~~~~~{.cpp}
+PIPELINE_STATE_CORE_DESC desc;
+// Fixed states (see below on how to create them)
+desc.blendState = ...;
+desc.rasterizerState = ...;
+desc.depthStencilState = ...;
+
+// GPU programs (see below on how to create them)
+desc.vertexProgram = ...
+desc.fragmentProgram = ...;
+desc.geometryProgram = ...;
+desc.hullProgram = ...;
+desc.domainProgram = ...;
+
+SPtr<GpuPipelineStateCore> state = GpuPipelineStateCore::create(desc);
+~~~~~~~~~~~~~
 
-You can bind a GPU program by calling @ref BansheeEngine::RenderAPICore::bindGpuProgram() "RenderAPICore::bindGpuProgram". You can also use @ref BansheeEngine::RenderAPICore::unbindGpuProgram() "RenderAPICore::unbindGpuProgram" to remove the GPU program from the pipeline, or @ref BansheeEngine::RenderAPICore::isGpuProgramBound() "RenderAPICore::isGpuProgramBound" to check if one is currently bound to a specific slot.
+Once created the pipeline can be bound for rendering by calling @ref BansheeEngine::RenderAPICore::setGraphicsPipeline "RenderAPICore::setGraphicsPipeline".
 
-For example:
 ~~~~~~~~~~~~~{.cpp}
-SPtr<GpuProgramCore> fragmentProgram = ...;
-SPtr<GpuProgramCore> vertexProgram = ...;
+// Bind pipeline for use (continued from above)
 
 RenderAPICore& rapi = RenderAPICore::instance();
-rapi.bindGpuProgram(vertexProgram);
-rapi.bindGpuProgram(fragmentProgram);
-... execute some draw calls ...
-
+rapi.setGraphicsPipeline(state);
 ~~~~~~~~~~~~~
 
-With most GPU programs you will also likely want to customize their execution by assigning them some parameters.
+We continue below with explanation on how to create fixed and programmable states required to initialize GpuPipelineStateCore.
 
-## GPU program parameters {#renderAPI_c_a}
-Most GPU programs also accept a number of parameters, whether textures, buffers, sampler states or primitive values like floats or integers. Parameters can be split into two categories:
- - Object - Textures, sampler states
- - Data - Float, int, bool (and their vectors and arrays)
- 
-In order to find out which parameters does a certain GPU program expect, as well as their type and other information, read the [GPU program](@ref gpuPrograms) manual. 
+## Fixed pipeline states {#renderAPI_b_a}
+Fixed pipeline states allow you to control (to some extent) non-programmable parts of the pipeline. This includes anything from blend operations, rasterization mode to depth testing. Setting these states is optional and if not set, default values will be used.
+
+States can be created by:
+ - @ref BansheeEngine::DepthStencilStateCore "DepthStencilStateCore" - Populate @ref BansheeEngine::DEPTH_STENCIL_STATE_DESC "DEPTH_STENCIL_STATE_DESC" and call @ref BansheeEngine::DepthStencilStateCore::create "DepthStencilStateCore::create" 
+ - @ref BansheeEngine::BlendStateCore "BlendStateCore" - Populate @ref BansheeEngine::BLEND_STATE_DESC "BLEND_STATE_DESC" and call @ref BansheeEngine::BlendStateCore::create "BlendStateCore::create" 
+ - @ref BansheeEngine::RasterizerStateCore "RasterizerStateCore" - Populate @ref BansheeEngine::RASTERIZER_STATE_DESC "RASTERIZER_STATE_DESC" and call @ref BansheeEngine::RasterizerStateCore::create "RasterizerStateCore::create" 
  
-### Object parameters {#renderAPI_c_a_a} 
-To assign a texture to a GPU program call @ref BansheeEngine::RenderAPICore::setTexture "RenderAPICore::setTexture". You will need to provide a GPU program type to assign the texture to, and a slot to bind the texture in. Each GPU program will provide a list of slots onto which you can bind textures in its parameter descriptor. 
+We won't explain what each of the states does. For that you can check out the class documentation of the states themselves, or familiarize yourself with the modern GPU pipeline in general, as the states mirror it exactly.
 
-By default the texture will be bound for sampling. You can customize how is the texture sampled by creating a @ref BansheeEngine::SamplerStateCore "SamplerStateCore", by populating the @ref BansheeEngine::SAMPLER_STATE_DESC "SAMPLER_STATE_DESC" and calling @ref BansheeEngine::SamplerStateCore::create "SamplerStateCore::create". The state can then be bound to the pipeline by calling @ref BansheeEngine::RenderAPICore::setSamplerState "RenderAPICore::setSamplerState" which accepts similar parameters to @ref BansheeEngine::RenderAPICore::setTexture "RenderAPICore::setTexture".
+## GPU programs {#renderAPI_b_b}
+The pipeline state also requires you to bind at least one GPU program (programmable state). At minimum you will need to bind a vertex program, while in most cases you will also need a fragment program. Optionally you can also bind geometry, hull or domain programs for more advanced functionality. To learn how to create GPU programs see [GPU program manual](@ref gpuPrograms).
 
-You can also bind a texture for both reading and writing by calling @ref BansheeEngine::RenderAPICore::setLoadStoreTexture "RenderAPICore::setLoadStoreTexture". Such textures are known as unordered-access (UAV) in DirectX, and load-store in OpenGL and are often used for compute operations (explained later). Be aware that the texture must have been created with the @ref BansheeEngine::TU_LOADSTORE "TU_LOADSTORE" flag in order to be bindable as a load-store texture. Load-store textures also cannot have multiple surfaces (i.e. faces or mip-maps) so you must choose which one to bind when calling @ref BansheeEngine::RenderAPICore::setLoadStoreTexture "RenderAPICore::setLoadStoreTexture".
- 
-To learn more about textures read the [texture](@ref textures) manual.
+Most GPU programs also accept a number of parameters, whether textures, buffers, sampler states or primitive values like floats or integers. These parameters are accessed through @ref BansheeEngine::GpuParamsCore "GpuParamsCore" object. You can use this object to assign individual parameters and then bind the object to the render API using @ref BansheeEngine::RenderAPICore::setGpuParams "RenderAPICore::setGpuParams". See below for an example.
 
-An example binding a texture and its sampler state:
 ~~~~~~~~~~~~~{.cpp}
+... assuming vertex/fragment programs are created ...
 
-// Use nearest neighbor filtering when sampling
-SAMPLER_STATE_DESC ssDesc;
-ssDesc.magFilter = FO_POINT;
-ssDesc.minFilter = FO_POINT;
-ssDesc.mipFilter = FO_POINT;
+GPU_PARAMS_DESC desc;
+desc.vertexParams = vertProgram->getParamDesc();
+desc.fragmentParams = fragProgram->getParamDesc();
 
-SPtr<SamplerStateCore> mySamplerState = SamplerStateCore::create(ssDesc);
-SPtr<TextureCore> myTexture = ...;
+SPtr<GpuParamsCore> params = GpuParamsCore::create(desc);
+
+// Retrieve GPU param handles we can then read/write to
+GpuParamVec2Core myVectorParam;
+GpuParamTextureCore myTextureParam;
 
+params->getParam(GPT_FRAGMENT_PROGRAM, "myVector", myVectorParam); // Assuming "myVector" is the variable name in the program source code
+params->getTextureParam(GPT_FRAGMENT_PROGRAM, "myTexture", myTextureParam); // Assuming "myTexture" is the variable name in the program source code
+
+myVectorParam.set(Vector2(1, 2));
+myTextureParam.set(myTexture); // Assuming we created "myTexture" earlier.
+
+// Bind parameters for use 
 RenderAPICore& rapi = RenderAPICore::instance();
+rapi.setGpuParams(params);
+~~~~~~~~~~~~~
+ 
+All parameters are bound by first retrieving their handles, and then using those handles for parameter access. In the example above we show how to bind a texture and a 2D vector to a GPU program. Same approach follows for all available parameter types.
 
-... bind GPU program ...
+After the parameters are set, we bind them to the pipeline by calling @ref BansheeEngine::RenderAPICore::setGpuParams "RenderAPICore::setGpuParams".
 
-// Bind the texture and sampler state to the 0th slot of the currently bound fragment program
-rapi.setTexture(GPT_FRAGMENT_PROGRAM, 0, myTexture);
-rapi.setSamplerState(GPT_FRAGMENT_PROGRAM, 0, mySamplerState);
+### Data parameters {#renderAPI_c_a_a} 
+Handles for data parameters like int, float, 2D vector, etc. can be retrieved by calling @ref BansheeEngine::GpuParamsCore::getParam "GpuParamsCore::getParam" which can then be assigned to as shown above.
 
-... execute some draw calls ...
+Alternatively you may also assign entire blocks of data parameters by calling @ref BansheeEngine::GpuParamsCore::setParamBlockBuffer(GpuProgramType,const String&,const ParamsBufferType&) "GpuParamsCore::setParamBlockBuffer". When assigning entire blocks you must create and populate the @ref BansheeEngine::GpuParamBlockBuffer "GpuParamBlockBuffer" object manually.
 
-~~~~~~~~~~~~~
+When writing to buffers manually you must ensure to write to offsets the GPU program expects the data to be at. You can find thise information from @ref BansheeEngine::GpuParamDesc "GpuParamDesc" structure accessible from @ref BansheeEngine::GpuProgramCore::getParamDesc "GpuProgramCore::getParamDesc". 
 
-### Data parameters {#renderAPI_c_a_b}
-Data parameters are bound to calling @ref BansheeEngine::RenderAPICore::setParamBuffer "RenderAPICore::setParamBuffer". You can manually populate the parameter buffer with required values, but generally you should use either @ref BansheeEngine::GpuParamsCore "GpuParamsCore" or @ref BansheeEngine::MaterialCore "MaterialCore" to set the parameters and then retrieve the existing parameter buffer.
+### Texture parameters {#renderAPI_c_a_b} 
+Handles for texture parameters can be retrieved by calling @ref BansheeEngine::GpuParamsCore::getTextureParam "GpuParamsCore::getTextureParam", or @ref BansheeEngine::GpuParamsCore::getLoadStoreTextureParam "GpuParamsCore::getLoadStoreTextureParam" if the texture should be bound for load-store operations.
 
-Each buffer need to be bound to a specific slot, and these slots can be read from the @ref BansheeEngine::GpuParamDesc "GpuParamDesc" structure accessible from @ref BansheeEngine::GpuProgramCore::getParamDesc "GpuProgramCore::getParamDesc". [GPU program](@ref gpuPrograms) manual has more information about GPU parameters.
+Learn more about textures and their different types in the [texture manual](@ref textures).
 
-Alternatively you can call @ref BansheeEngine::RendererUtility::setGpuParams "RendererUtility::setGpuParams" helper method which will bind both object and data parameters in the @ref BansheeEngine::GpuParamsCore "BansheeEngine::GpuParamsCore" object.
+### Sampler state parameters {#renderAPI_c_a_c}
+Sampler states can be used to customize how is the texture sampled. You can retrieve a handle for a sampler state parameter by calling @ref BansheeEngine::GpuParamsCore::getSamplerStateParam "GpuParamsCore::getSamplerStateParam".
 
-You can also call @ref BansheeEngine::RendererUtility::setPassParams "RendererUtility::setPassParams" to bind parameters for all GPU programs in a specific @ref BansheeEngine::MaterialCore "MaterialCore" pass.
+Sampler states are represented by the @ref BansheeEngine::SamplerStateCore "SamplerStateCore" object, which you can create by populating the @ref BansheeEngine::SAMPLER_STATE_DESC "SAMPLER_STATE_DESC" and calling @ref BansheeEngine::SamplerStateCore::create "SamplerStateCore::create". 
 
-For example:
+An example to create and bind a sampler state:
 ~~~~~~~~~~~~~{.cpp}
-SPtr<GpuProgramCore> program = ...;
-SPtr<GpuParamsCore> params = program->createParameters();
 
-... set param values ...
-... bind GPU program ...
+// Use nearest neighbor filtering when sampling
+SAMPLER_STATE_DESC ssDesc;
+ssDesc.magFilter = FO_POINT;
+ssDesc.minFilter = FO_POINT;
+ssDesc.mipFilter = FO_POINT;
+
+SPtr<SamplerStateCore> mySamplerState = SamplerStateCore::create(ssDesc);
 
-// Set all parameters for the currently bound fragment program
-gRendererUtility().setGpuParams(GPT_FRAGMENT_PROGRAM, params);
+SPtr<GpuParamsCore> params = ...;
 
-... execute some draw calls ...
+GpuParamSampStateCore mySamplerParam;
+params->getSamplerStateParam(GPT_FRAGMENT_PROGRAM, "mySamplerState", mySamplerParam); // Assuming "mySamplerState" is the variable name in the program source code
+
+mySamplerParam.set(mySamplerState);
 
 ~~~~~~~~~~~~~
 
@@ -227,18 +238,18 @@ If using an index buffer you should issue a @ref BansheeEngine::RenderAPICore::d
 And this wraps up the rendering pipeline. After this step your object should be rendered to your render target and ready to display. 
  
 # Compute {#renderAPI_g}
-The compute pipeline is a very simple pipeline that can be used for general purpose calculations. It is separate from the render pipeline we have been describing so far, but uses the same functionality, just in a more limited way. You don't have to set states, render targets, vertex/index buffers and only one GPU program type is supported (compute GPU program).
+The compute pipeline is a very simple pipeline that can be used for general purpose calculations. It is separate from the graphics pipeline we have been describing so far, but uses the same functionality, just in a more limited way. You don't have to set fixed states, render targets, vertex/index buffers and only one GPU program type is supported (compute GPU program).
 
-When the pipeline is set up you can execute it by calling @ref BansheeEngine::RenderAPICore::dispatchCompute "RenderAPICore::dispatchCompute". You should provide it a three dimensional number that determines how many instances of the currently bound GPU program to execute. The total number of executions will be X * Y * Z.
+Use @ref BansheeEngine::RenderAPICore::setComputePipeline "RenderAPICore::setComputePipeline" to initialize the pipeline. When the pipeline is set up you can execute it by calling @ref BansheeEngine::RenderAPICore::dispatchCompute "RenderAPICore::dispatchCompute". You should provide it a three dimensional number that determines how many instances of the currently bound GPU program to execute. The total number of executions will be X * Y * Z.
 
 Since compute pipeline doesn't support render targets, you will want to use load-store textures for output. An example of a simple compute pipeline:
 ~~~~~~~~~~~~~{.cpp}
 SPtr<GpuProgramCore> computeProgram = ...;
-SPtr<TextureCore> loadStoreTexture = ...;
+SPtr<GpuParamsCore> computeGpuParams = ...;
 
 RenderAPICore& rapi = RenderAPICore::instance();
-rapi.bindGpuProgram(computeProgram);
-rapi.setLoadStoreTexture(GPT_COMPUTE_PROGRAM, 0, true, loadStoreTexture, TextureSurface(0, 0));
+rapi.setComputePipeline(computeProgram);
+rapi.setGpuParams(computeGpuParams);
 rapi.dispatchCompute(512, 512);
 
 ... read from our texture to get the result ...
@@ -251,4 +262,30 @@ We won't go any deeper about the details of the compute pipeline as this informa
 
 Use @ref BansheeEngine::RenderAPI::getAPIInfo "RenderAPI::getAPIInfo" to receive the @ref BansheeEngine::RenderAPIInfo "RenderAPIInfo" containing such information, so you may modify your rendering accordingly. 
 
-For convenience a specialized @ref BansheeEngine::RenderAPI::convertProjectionMatrix "RenderAPI::convertProjectionMatrix" method is also provided, which converts a generic engine projection matrix, into a render API specific one.
+For convenience a specialized @ref BansheeEngine::RenderAPI::convertProjectionMatrix "RenderAPI::convertProjectionMatrix" method is also provided, which converts a generic engine projection matrix, into a render API specific one.
+
+# Command buffers {#renderAPI_i}
+Almost all @ref BansheeEngine::RenderAPICore "RenderAPICore" commands we talked about so far support @ref BansheeEngine::CommandBuffer "CommandBuffer"s. Command buffers are optional, but they allow the rendering commands to be generated from threads other than the core thread.
+
+To create a command buffer call @ref BansheeEngine::CommandBuffer::create "CommandBuffer::create" after which provide it to the relevant @ref BansheeEngine::RenderAPICore "RenderAPICore" calls. Those commands will get recorded in the command buffer, but not executed. To actually execute the commands call @ref BansheeEngine::RenderAPICore::executeCommands "RenderAPICore::executeCommands".
+
+This allows rendering to be faster since work can be distributed over multiple CPU cores. Note that only command queuing can happen on a separate thread, command buffer creation and execution must still happen on the core thread.
+
+Command buffer example:
+~~~~~~~~~~~~~{.cpp}
+// Core thread
+SPtr<CommandBuffer> cmdBuffer = CommandBuffer::create(CBT_COMPUTE);
+SPtr<GpuProgramCore> computeProgram = ...;
+SPtr<GpuParamsCore> computeGpuParams = ...;
+
+... queue up worker thread(s) ...
+
+// Worker thread
+RenderAPICore& rapi = RenderAPICore::instance();
+rapi.setComputePipeline(computeProgram, cmdBuffer);
+rapi.setGpuParams(computeGpuParams, cmdBuffer);
+rapi.dispatchCompute(512, 512, cmdBuffer);
+
+// Core thread
+rapi.executeCommands(cmdBuffer);
+~~~~~~~~~~~~~

+ 34 - 18
Documentation/Manuals/Native/renderTargets.md

@@ -6,9 +6,7 @@ Render targets represent destination surfaces onto which objects are rendered. T
 
 In Banshee render targets are represented with:
  - Windows - @ref BansheeEngine::RenderWindow "RenderWindow" and @ref BansheeEngine::RenderWindowCore "RenderWindowCore"
- - Textures
-  - Single surface: @ref BansheeEngine::RenderTexture "RenderTexture" and @ref BansheeEngine::RenderTextureCore "RenderTextureCore"
-  - Multiple surfaces: @ref BansheeEngine::MultiRenderTexture "MultiRenderTexture" and @ref BansheeEngine::MultiRenderTextureCore "MultiRenderTextureCore"
+ - Textures - @ref BansheeEngine::RenderTexture "RenderTexture" and @ref BansheeEngine::RenderTextureCore "RenderTextureCore"
  
 Each type comes in two variants, both of which provide almost equivalent functionality, but the former is for use on the simulation thread, and the latter is for use on the core thread. If you are confused by the dual nature of the objects, read the [core thread](@ref coreThread) manual. 
 
@@ -66,20 +64,34 @@ Render textures are simpler than windows, but you are given more control over th
 
 Render texture must contain at least one texture (color surface), but may optionally also contain a depth-stencil surface. Depth-stencil surface is also a @ref BansheeEngine::Texture "Texture", but one created with the @ref BansheeEngine::TU_DEPTHSTENCIL "TU_DEPTHSTENCIL" flag. Depth stencil surfaces only accept specific pixel formats starting with "D" prefix in @ref BansheeEngine::PixelFormat "PixelFormat". Dimensions of the depth stencil surface must match the color surface.
 
-To create a render texture call @ref BansheeEngine::RenderTexture::create(const RENDER_TEXTURE_DESC&) "RenderTexture::create" with a populated @ref BansheeEngine::RENDER_TEXTURE_DESC "RENDER_TEXTURE_DESC" structure. This structure expects a reference to the color surface texture, and an optional depth-stencil surface texture. For each of those you must also specify the face and mip level onto which to render, in case your texture has multiple.
+To create a render texture call @ref BansheeEngine::RenderTexture::create(const RENDER_TEXTURE_DESC&) "RenderTexture::create" with a populated @ref BansheeEngine::RENDER_TEXTURE_DESC "RENDER_TEXTURE_DESC" structure. This structure expects a reference to one or more color surface textures, and an optional depth-stencil surface texture. For each of those you must also specify the face and mip level onto which to render, in case your texture has multiple.
 
 For example:
 ~~~~~~~~~~~~~{.cpp}
 // Create a 1280x720 texture with 32-bit RGBA format
-HTexture color = Texture::create(TEX_TYPE_2D, 1280, 720, 1, 0, PF_R8G8B8A8);
+TEXTURE_DESC colorDesc;
+colorDesc.type = TEX_TYPE_2D;
+colorDesc.width = 1280;
+colorDesc.heigth = 720;
+colorDesc.format = PF_R8G8B8A8;
+colorDesc.usage = TU_RENDERTARGET;
+
+HTexture color = Texture::create(colorDesc);
 
 // Create a 1280x720 texture with a 32-bit depth-stencil format
-HTexture depthStencil = Texture::create(TEX_TYPE_2D, 1280, 720, 1, 0, PF_D24S8);
+TEXTURE_DESC depthDesc;
+depthDesc.type = TEX_TYPE_2D;
+depthDesc.width = 1280;
+depthDesc.heigth = 720;
+depthDesc.format = PF_R8G8B8A8;
+depthDesc.usage = TU_DEPTHSTENCIL;
+
+HTexture depthStencil = Texture::create(depthDesc);
 
 RENDER_TEXTURE_DESC desc;
-desc.colorSurface.texture = color;
-desc.colorSurface.face = 0;
-desc.colorSurface.mipLevel = 0;
+desc.colorSurfaces[0].texture = color;
+desc.colorSurfaces[0].face = 0;
+desc.colorSurfaces[0].mipLevel = 0;
 
 desc.depthStencilSurface.texture = depthStencil;
 desc.depthStencilSurface.face = 0;
@@ -88,16 +100,22 @@ desc.depthStencilSurface.mipLevel = 0;
 SPtr<RenderTexture> renderTexture = RenderTexture::create(desc);
 ~~~~~~~~~~~~~
 
-Optionally you can also use the overloaded @ref BansheeEngine::RenderTexture::create(TextureType, UINT32, UINT32, PixelFormat, bool, UINT32, bool, PixelFormat) "RenderTexture::create" to create the texture surfaces and the render texture in one go:
+Optionally you can also use the overloaded @ref BansheeEngine::RenderTexture::create(const TEXTURE_DESC&, bool, PixelFormat) "RenderTexture::create" to create the texture surfaces and the render texture in one go:
 ~~~~~~~~~~~~~{.cpp}
 // Has the same result as above:
-SPtr<RenderTexture> renderTexture = RenderTexture::create(TEX_TYPE_2D, 1280, 720, PF_R8G8B8A8, false, 0, true, PF_D24S8);
+TEXTURE_DESC colorDesc;
+colorDesc.type = TEX_TYPE_2D;
+colorDesc.width = 1280;
+colorDesc.heigth = 720;
+colorDesc.format = PF_R8G8B8A8;
+
+SPtr<RenderTexture> renderTexture = RenderTexture::create(colorDesc, true, PF_D24S8);
 ~~~~~~~~~~~~~
 
 ## Multiple surfaces {#renderTargets_b_a}
-Render textures can also contain multiple color surfaces (up to 8). Such targets simply allow you to write more data at once, improving performance as you do not need to execute multiple draw calls. To create a texture with multiple color surfaces you must create a @ref BansheeEngine::MultiRenderTexture "MultiRenderTexture" by calling @ref BansheeEngine::MultiRenderTexture::create "MultiRenderTexture::create". 
+Render textures can also contain multiple color surfaces (up to 8). Such targets simply allow you to write more data at once, improving performance as you do not need to execute multiple draw calls. To create a texture with multiple color surfaces simply fill out other entries of @ref BansheeEngine::RENDER_TEXTURE_DESC "RENDER_TEXTURE_DESC::colorSurfaces" array and proceed the same as in the above example.
 
-Their creation is identical to normal render textures, only they accept more than one color surface. Use `BS_MAX_MULTIPLE_RENDER_TARGETS` to learn what is the maximum supported number of color surfaces per target (usually 8). All color surfaces (and the depth/stencil surface) must have the same dimensions.
+Use `BS_MAX_MULTIPLE_RENDER_TARGETS` to learn what is the maximum supported number of color surfaces per target (usually 8). All color surfaces (and the depth/stencil surface) must have the same dimensions and sample count.
 
 ## Multi-sampled surfaces {#renderTargets_b_c}
 Same as windows, render textures can be created with support for multiple samples per pixel. This allows affects such as multi-sampled antialiasing and similar. To create a multi-sampled render texture simply create a @ref BansheeEngine::Texture "Texture" with its `multisampleCount` parameter larger than one, which you then use to initialize a render texture. Make sure that all surfaces (including depth-stencil) in a render texture have the same number of samples.
@@ -119,11 +137,9 @@ Use @ref BansheeEngine::RenderAPI::setRenderTarget "RenderAPI::setRenderTarget"
 Call @ref BansheeEngine::RenderAPI::clearRenderTarget "RenderAPI::clearRenderTarget" to clear all or portions of a render target to a specific color/value. Read the [render API](@ref renderAPI) manual for more information.
 
 ## Reading from targets {#renderTargets_d_c}
-If you wish to read render target pixels from the CPU, you can use the normal @ref BansheeEngine::Texture "Texture" read functionality as described in the [texture](@ref textures) manual. To retrieve a @ref BansheeEngine::Texture "Texture" from a @ref BansheeEngine::RenderTexture "RenderTexture" or @ref BansheeEngine::MultiRenderTexture "MultiRenderTexture" call the following methods:
- - @ref BansheeEngine::RenderTexture::getBindableColorTexture "RenderTexture::getBindableColorTexture"
- - @ref BansheeEngine::RenderTexture::getBindableDepthStencilTexture "RenderTexture::getBindableDepthStencilTexture"
- - @ref BansheeEngine::MultiRenderTexture::getBindableColorTexture "MultiRenderTexture::getBindableColorTexture"
- - @ref BansheeEngine::MultiRenderTexture::getBindableDepthStencilTexture "MultiRenderTexture::getBindableDepthStencilTexture"
+If you wish to read render target pixels from the CPU, you can use the normal @ref BansheeEngine::Texture "Texture" read functionality as described in the [texture](@ref textures) manual. To retrieve a @ref BansheeEngine::Texture "Texture" from a @ref BansheeEngine::RenderTexture "RenderTexture" call the following methods:
+ - @ref BansheeEngine::RenderTexture::getColorTexture "RenderTexture::getColorTexture"
+ - @ref BansheeEngine::RenderTexture::getDepthStencilTexture "RenderTexture::getDepthStencilTexture"
  
 Before reading you must make sure the render target is not currently bound for rendering otherwise this will fail. You cannot read from a @ref BansheeEngine::RenderWindow "RenderWindow".
 

+ 7 - 1
Documentation/Manuals/Native/resources.md

@@ -66,7 +66,13 @@ If a resource already exists on the disk (i.e. it was created by @ref BansheeEng
 
 An example:
 ~~~~~~~~~~~~~{.cpp}
-HTexture texture = Texture::create(TEX_TYPE_2D, 1280, 720, 0, PF_R8G8B8A8);
+TEXTURE_DESC desc;
+desc.type = TEX_TYPE_2D;
+desc.width = 1280;
+desc.heigth = 720;
+desc.format = PF_R8G8B8A8;
+
+HTexture texture = Texture::create(desc);
 ... fill texture with some data ...
 
 gResources().save(texture, "myTexture.asset");

+ 20 - 5
Documentation/Manuals/Native/textures.md

@@ -7,7 +7,7 @@ Textures in Banshee are represented with the @ref BansheeEngine::Texture "Textur
 We're going to focus on the simulation thread implementation in this manual, and then note the differences in the core thread version at the end.
 
 # Creating a texture {#textures_a}
-To create a texture call @ref BansheeEngine::Texture::create "Texture::create" or one if its overloads. At minimum you need to provide a @ref BansheeEngine::TextureType "texture type", dimensions and @ref BansheeEngine::PixelFormat "pixel format". The dimensions range from one to three dimensional depending on the texture type.
+To create a texture call @ref BansheeEngine::Texture::create "Texture::create" or one if its overloads. You'll need to populate the @ref BansheeEngine::TEXTURE_DESC "TEXTURE_DESC" structure and pass it as a parameter. At minimum you need to provide a @ref BansheeEngine::TextureType "texture type", dimensions and @ref BansheeEngine::PixelFormat "pixel format". The dimensions range from one to three dimensional depending on the texture type.
 
 Optionally you can also provide the number of mipmaps, number of samples, usage flags and a gamma correction flag:
  - A texture with mip-maps will contain a set of scaled down versions of itself that are used by the GPU for special filtering. 
@@ -18,13 +18,19 @@ Optionally you can also provide the number of mipmaps, number of samples, usage
 For example:
 ~~~~~~~~~~~~~{.cpp}
 // Creates a 2D texture, 128x128 with an 8-bit RGBA format
-HTexture texture = Texture::create(TEX_TYPE_2D, 128, 128, 0, PF_R8G8B8A8);
+TEXTURE_DESC desc;
+desc.type = TEX_TYPE_2D;
+desc.width = 128;
+desc.heigth = 128;
+desc.format = PF_R8G8B8A8;
+
+HTexture texture = Texture::create(desc);
 ~~~~~~~~~~~~~ 
 
 You can also create a non-empty texture by creating it with a populated @ref BansheeEngine::PixelData "PixelData" object. More about @ref BansheeEngine::PixelData "PixelData" later.
  
 # Accessing properties {#textures_b} 
-You can access all relevant texture properties by calling @ref BansheeEngine::Texture::getProperties() "Texture::getProperties()" which will return an instance of @ref BansheeEngine::TextureProperties "TextureProperties" which contains all the information about the texture, as well as some useful methods (as we'll see in the next section).
+You can access all relevant information about a texture (e.g. width, height) by calling @ref BansheeEngine::Texture::getProperties() "Texture::getProperties()" which will return an instance of @ref BansheeEngine::TextureProperties "TextureProperties". 
  
 # Reading/writing {#textures_c}
 To read and write from/to the texture use the @ref BansheeEngine::Texture::readSubresource "Texture::readSubresource" and @ref BansheeEngine::Texture::writeSubresource "Texture::writeSubresource" methods. These expect an index of a sub-resource to read/write to, and a @ref BansheeEngine::PixelData "PixelData" object.
@@ -46,7 +52,9 @@ When you read from a texture using the @ref BansheeEngine::Texture::readSubresou
 For this reason @ref BansheeEngine::Texture::readData "Texture::readData" exists. It will read data quickly with little performance impact. However you must create the texture using the @ref BansheeEngine::TU_CPUCACHED "TU_CPUCACHED" usage. This also means that the texture will keep a copy of its pixels in system memory, so use it sparingly. If the texture is modified from the GPU this method will not reflect such changes.
 
 # Rendering using the texture {#textures_d}
-To use a texture for rendering you can either bind it to the @ref BansheeEngine::RenderAPI::setTexture "RenderAPI::setTexture" directly, or assign it to a @ref BansheeEngine::Material "Material" which will then be used on a @ref BansheeEngine::Renderable "Renderable" or a similar object. To learn more about this check out the [render API](@ref renderAPI) and [material](@ref materials) manuals.
+To use a texture for rendering you need to either:
+ - (High level) Assign it to a @ref BansheeEngine::Material "Material" which will then automatically get used on a @ref BansheeEngine::Renderable "Renderable" which uses the material. Read the [material manual](@ref materials) for more information.
+ - (Low level) Bind the texture to a @ref BansheeEngine::GpuParams "GpuParams" object, which can then be assigned to pipeline for rendering. Read the [render API manual](@ref renderAPI) for more information.
 
 # Saving/loading {#textures_e}
 A texture is a @ref BansheeEngine::Resource "Resource" and can be saved/loaded like any other. See the [resource](@ref resources) manual.
@@ -56,4 +64,11 @@ So far we have only talked about the simulation thread @ref BansheeEngine::Textu
 
 You can also use @ref BansheeEngine::TextureCore::lock "TextureCore::lock" and @ref BansheeEngine::TextureCore::unlock "TextureCore::unlock" to get access to the texture buffer, which allows you to only read/write from/to portions of it, instead of always writing to the entire buffer.
 
-And finally @ref BansheeEngine::TextureCore::copy "TextureCore::copy" method can be used for quickly copying a contents of one texture to another texture. This method will also resolve multi-sampled surface in the case the source is multi-sampled but the destination is not.
+And finally @ref BansheeEngine::TextureCore::copy "TextureCore::copy" method can be used for quickly copying a contents of one texture to another texture. This method will also resolve multi-sampled surface in the case the source is multi-sampled but the destination is not.
+
+# Load-store textures {#textures_g}
+Load-store textures are a special type of textures that can be written to by the GPU. This is opposed to normal textures which are read only. They are particularily useful for compute operations which cannot use render targets for output, or for GPU operations that which to write to arbitrary locations rather than just to their own pixel location.
+
+To create a load-store texture just provide the @ref BansheeEngine::TU_LOADSTORE "TU_LOADSTORE" usage flag on creation - the rest of the creation procedure is identical. Load-store textures cannot be multisampled and cannot be used as render or depth-stencil targets. They also cannot have mip-maps nor can they be created with compressed texture formats.
+
+Rendering using these textures is similar to normal textures, but when binding them to @ref BansheeEngine::Material "Material" or @ref BansheeEngine::GpuParams "GpuParams" they also require a separate @ref BansheeEngine::TextureSurface "TextureSurface" parameter to determine the surface of the texture to bind, in case it has multiple surfaces or mip levels.

+ 4 - 0
Documentation/glslangCompilationGuide.txt

@@ -0,0 +1,4 @@
+Certain Banshee specific modification is required before compiling glslang:
+ - Add getAttributeTType to TProgram's public interface:
+  - Method signature: const TType* getAttributeTType(int index) const;
+  - Method implementation: const TType* TProgram::getAttributeTType(int index) const	 { return reflection->getAttribute(index).getType(); }

+ 3 - 0
README.md

@@ -18,7 +18,10 @@ Aside from being a fully featured game engine and toolkit, Banshee can also be u
 # Documentation
 * [Managed](http://docs.banshee3d.com/Managed/index.html) - Documentation for the scripting (C#) API. This is what most users will be interested in.
 * [Native] (http://docs.banshee3d.com/Native/index.html) - Documentation for the native (C++) API. This is meant for advanced users meaning to extend/modify the engine.
+
+# About
 * [License](https://github.com/BearishSun/BansheeEngine/blob/master/Documentation/GitHub/license.md) - Information about Banshee's license.
+* [Contribute](http://www.banshee3d.com/contribute) - Help out with the development
 
 # Media
 **Banshee Editor**

+ 30 - 21
Source/BansheeCore/CMakeSources.cmake

@@ -128,21 +128,13 @@ set(BS_BANSHEECORE_INC_RENDERAPI
 	"Include/BsTextureView.h"
 	"Include/BsSubMesh.h"
 	"Include/BsSamplerState.h"
-	"Include/BsRenderWindowManager.h"
 	"Include/BsRenderWindow.h"
 	"Include/BsRenderTexture.h"
 	"Include/BsRenderTarget.h"
-	"Include/BsRenderStateManager.h"
 	"Include/BsRasterizerState.h"
-	"Include/BsQueryManager.h"
-	"Include/BsPixelBuffer.h"
 	"Include/BsOcclusionQuery.h"
-	"Include/BsMultiRenderTexture.h"
-	"Include/BsMeshManager.h"
 	"Include/BsIndexBuffer.h"
-	"Include/BsHardwareBufferManager.h"
 	"Include/BsHardwareBuffer.h"
-	"Include/BsGpuProgramManager.h"
 	"Include/BsGpuProgram.h"
 	"Include/BsGpuParams.h"
 	"Include/BsGpuParamDesc.h"
@@ -151,14 +143,25 @@ set(BS_BANSHEECORE_INC_RENDERAPI
 	"Include/BsGpuBufferView.h"
 	"Include/BsGpuBuffer.h"
 	"Include/BsEventQuery.h"
-	"Include/BsDrawOps.h"
 	"Include/BsDepthStencilState.h"
 	"Include/BsBlendState.h"
 	"Include/BsRenderAPI.h"
-	"Include/BsRenderAPIManager.h"
-	"Include/BsRenderAPIFactory.h"
 	"Include/BsRenderAPICapabilities.h"
 	"Include/BsViewport.h"
+	"Include/BsCommandBuffer.h"
+	"Include/BsGpuPipelineState.h"
+)
+
+set(BS_BANSHEECORE_INC_RENDERAPI_FACTORIES
+	"Include/BsRenderWindowManager.h"
+	"Include/BsRenderStateManager.h"
+	"Include/BsQueryManager.h"
+	"Include/BsMeshManager.h"
+	"Include/BsHardwareBufferManager.h"
+	"Include/BsGpuProgramManager.h"
+	"Include/BsRenderAPIManager.h"
+	"Include/BsRenderAPIFactory.h"
+	"Include/BsCommandBufferManager.h"
 )
 
 set(BS_BANSHEECORE_SRC_CORETHREAD
@@ -214,7 +217,6 @@ set(BS_BANSHEECORE_SRC_UTILITY
 	"Source/BsUtility.cpp"
 	"Source/BsMeshUtility.cpp"
 	"Source/BsDeferredCallManager.cpp"
-	"Source/BsDrawOps.cpp"
 	"Source/BsIconUtility.cpp"
 	"Source/BsUUID.cpp"
 	"Source/BsPixelUtil.cpp"
@@ -422,20 +424,12 @@ set(BS_BANSHEECORE_SRC_RENDERAPI
 	"Source/BsGpuParamBlockBuffer.cpp"
 	"Source/BsGpuParams.cpp"
 	"Source/BsGpuProgram.cpp"
-	"Source/BsGpuProgramManager.cpp"
-	"Source/BsHardwareBufferManager.cpp"
 	"Source/BsIndexBuffer.cpp"
-	"Source/BsMeshManager.cpp"
-	"Source/BsMultiRenderTexture.cpp"
 	"Source/BsOcclusionQuery.cpp"
-	"Source/BsPixelBuffer.cpp"
-	"Source/BsQueryManager.cpp"
 	"Source/BsRasterizerState.cpp"
-	"Source/BsRenderStateManager.cpp"
 	"Source/BsRenderTarget.cpp"
 	"Source/BsRenderTexture.cpp"
 	"Source/BsRenderWindow.cpp"
-	"Source/BsRenderWindowManager.cpp"
 	"Source/BsSamplerState.cpp"
 	"Source/BsTextureView.cpp"
 	"Source/BsTimerQuery.cpp"
@@ -444,9 +438,20 @@ set(BS_BANSHEECORE_SRC_RENDERAPI
 	"Source/BsVertexDeclaration.cpp"
 	"Source/BsVideoModeInfo.cpp"
 	"Source/BsRenderAPI.cpp"
-	"Source/BsRenderAPIManager.cpp"
 	"Source/BsRenderAPICapabilities.cpp"
 	"Source/BsViewport.cpp"
+	"Source/BsCommandBuffer.cpp"
+	"Source/BsGpuPipelineState.cpp"
+)
+
+set(BS_BANSHEECORE_SRC_RENDERAPI_FACTORIES
+	"Source/BsGpuProgramManager.cpp"
+	"Source/BsHardwareBufferManager.cpp"
+	"Source/BsMeshManager.cpp"
+	"Source/BsQueryManager.cpp"
+	"Source/BsRenderStateManager.cpp"
+	"Source/BsRenderWindowManager.cpp"
+	"Source/BsRenderAPIManager.cpp"
 )
 
 set(BS_BANSHEECORE_SRC_NOFILTER
@@ -544,6 +549,7 @@ source_group("Source Files\\Localization" FILES ${BS_BANSHEECORE_SRC_LOCALIZATIO
 source_group("Source Files\\RTTI" FILES ${BS_BANSHEECORE_SRC_RTTI})
 source_group("Header Files\\Profiling" FILES ${BS_BANSHEECORE_INC_PROFILING})
 source_group("Header Files\\RenderAPI" FILES ${BS_BANSHEECORE_INC_RENDERAPI})
+source_group("Header Files\\RenderAPI\\Factories" FILES ${BS_BANSHEECORE_INC_RENDERAPI_FACTORIES})
 source_group("Source Files\\CoreThread" FILES ${BS_BANSHEECORE_SRC_CORETHREAD})
 source_group("Header Files" FILES ${BS_BANSHEECORE_INC_NOFILTER})
 source_group("Header Files\\Material" FILES ${BS_BANSHEECORE_INC_MATERIAL})
@@ -563,6 +569,7 @@ source_group("Source Files\\Input" FILES ${BS_BANSHEECORE_SRC_INPUT})
 source_group("Header Files\\Localization" FILES ${BS_BANSHEECORE_INC_LOCALIZATION})
 source_group("Source Files\\Text" FILES ${BS_BANSHEECORE_SRC_TEXT})
 source_group("Source Files\\RenderAPI" FILES ${BS_BANSHEECORE_SRC_RENDERAPI})
+source_group("Source Files\\RenderAPI\\Factories" FILES ${BS_BANSHEECORE_SRC_RENDERAPI_FACTORIES})
 source_group("Source Files" FILES ${BS_BANSHEECORE_SRC_NOFILTER})
 source_group("Source Files\\Physics" FILES ${BS_BANSHEECORE_SRC_PHYSICS})
 source_group("Source Files\\Scene" FILES ${BS_BANSHEECORE_SRC_SCENE})
@@ -610,4 +617,6 @@ set(BS_BANSHEECORE_SRC
 	${BS_BANSHEECORE_SRC_AUDIO}
 	${BS_BANSHEECORE_INC_ANIMATION}
 	${BS_BANSHEECORE_SRC_ANIMATION}
+	${BS_BANSHEECORE_INC_RENDERAPI_FACTORIES}
+	${BS_BANSHEECORE_SRC_RENDERAPI_FACTORIES}
 )

+ 50 - 0
Source/BansheeCore/Include/BsCommandBuffer.h

@@ -0,0 +1,50 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** 
+	 * Contains a list of render API commands that can be queued for execution on the GPU. User is allowed to populate the
+	 * command buffer from any thread, ensuring render API command generation can be multi-threaded. Command buffers
+	 * must always be created on the core thread. Same command buffer cannot be used on multiple threads simulateously
+	 * without external synchronization.
+	 */
+	class BS_CORE_EXPORT CommandBuffer
+	{
+	public:
+		/**
+		 * Creates a new CommandBuffer.
+		 * 
+		 * @param[in]	type		Determines what type of commands can be added to the command buffer.
+		 * @param[in]	deviceIdx	Index of the GPU the command buffer will be used to queue commands on. 0 is always
+		 *							the primary available GPU.
+		 * @param[in]	syncMask	Determines how is concurrency handled between multiple command buffers on the same 
+		 *							device. If buffers don't share the same bits in the sync mask they are allowed to
+		 *							execute concurrently on the GPU, however it is up to the user to ensure that they
+		 *							do not contain any resources depended on each other. Leave on default to ensure
+		 *							no concurrency is possible (safest).
+		 * @param[in]	secondary	If true the command buffer will not be allowed to execute on its own, but it can
+		 *							be appended to a primary command buffer. 
+		 * @return					New CommandBuffer instance.
+		 * 
+		 */
+		static SPtr<CommandBuffer> create(CommandBufferType type, UINT32 deviceIdx = 0, UINT32 syncMask = 0xFFFFFFFF, 
+			bool secondary = false);
+
+	protected:
+		CommandBuffer(CommandBufferType type, UINT32 syncMask, bool secondary);
+
+		CommandBufferType mType;
+		UINT32 mSyncMask;
+		bool mIsSecondary;
+	};
+
+	/** @} */
+}

+ 28 - 0
Source/BansheeCore/Include/BsCommandBufferManager.h

@@ -0,0 +1,28 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI-Internal
+	 *  @{
+	 */
+
+	/** 
+	 * Handles creation of command buffers. See CommandBuffer. 
+	 *
+	 * @note Core thread only.
+	 */
+	class BS_CORE_EXPORT CommandBufferManager : public Module<CommandBufferManager>
+	{
+	public:
+		/** @copydoc CommandBuffer::create */
+		virtual SPtr<CommandBuffer> create(CommandBufferType type, UINT32 deviceIdx = 0, UINT32 syncMask = 0xFFFFFFFF, 
+			bool secondary = false) = 0;
+	};
+
+	/** @} */
+}

+ 54 - 2
Source/BansheeCore/Include/BsCommonTypes.h

@@ -115,6 +115,24 @@ namespace BansheeEngine
 		SOP_INVERT /**< Invert the bits of the stencil buffer. */
 	};
 
+	/** Describes operation that will be used for rendering a certain set of vertices. */
+	enum DrawOperationType
+	{
+		DOT_POINT_LIST = 1, /**< Each vertex represents a point. */
+		DOT_LINE_LIST = 2, /**< Each sequential pair of vertices represent a line. */
+		DOT_LINE_STRIP = 3, /**< Each vertex (except the first) forms a line with the previous vertex. */
+		DOT_TRIANGLE_LIST = 4, /**< Each sequential 3-tuple of vertices represent a triangle. */
+		DOT_TRIANGLE_STRIP = 5, /**< Each vertex (except the first two) form a triangle with the previous two vertices. */
+		DOT_TRIANGLE_FAN = 6 /**< Each vertex (except the first two) form a triangle with the first vertex and previous vertex. */
+	};
+
+	/**	Type of the indices used, used for determining size. */
+	enum IndexType
+	{
+		IT_16BIT, /**< 16-bit indices. */
+		IT_32BIT /**< 32-bit indices. */
+	};
+
 	/** These values represent a hint to the driver when locking a hardware buffer. */
 	enum GpuLockOptions
 	{
@@ -159,11 +177,11 @@ namespace BansheeEngine
 	enum GpuBufferUsage 
 	{
 		/** 
-		 * Signifies that you don't plan on modifying the buffer often (or at all)	after creation. Modifying such buffer 
+		 * Signifies that you don't plan on modifying the buffer often (or at all) after creation. Modifying such buffer 
 		 * will involve a larger performance hit.
 		 */
         GBU_STATIC = 1,
-		/** Signifies that you will modify this buffer fairly often. */
+		/** Signifies that you will modify this buffer fairly often (e.g. every frame). */
 		GBU_DYNAMIC = 2
 	};
 
@@ -241,6 +259,26 @@ namespace BansheeEngine
 		GVU_RANDOMWRITE = 0x08
 	};
 
+	/** Combineable set of bits that describe a set of physical GPU's. */
+	enum GpuDeviceFlags
+	{
+		/** 
+		 * Use the default set of devices. This may be the primary device or multiple devices. Cannot be used together with
+		 * other device flags. 
+		 */
+		GDF_DEFAULT = 0,
+		/** Use only the primary GPU. */
+		GDF_PRIMARY = 0x01,
+		/** Use the second GPU. */
+		GDF_GPU2 = 0x02,
+		/** Use the third GPU. */
+		GDF_GPU3 = 0x04,
+		/** Use the fourth GPU. */
+		GDF_GPU4 = 0x08,
+		/** Use the fifth GPU. */
+		GDF_GPU5 = 0x10
+	};
+
 	/** Type of parameter block usages. Signifies how often will parameter blocks be changed. */
 	enum GpuParamBlockUsage
 	{
@@ -353,6 +391,20 @@ namespace BansheeEngine
 		GPOT_UNKNOWN = 0xffff
 	};
 
+	/** Types of command buffers. */
+	enum CommandBufferType
+	{
+		/** 
+		 * Command buffer used for rendering. Allows the use of draw commands, but also all commands supported by compute
+		 * or upload buffers. 
+		 */
+		CBT_GRAPHICS,
+		/** Command buffer used for compute operations. Allows the use of dispatch and upload commands. */
+		CBT_COMPUTE,
+		/** Command buffer used for memory transfer operations only. No rendering or compute dispatch allowed. */
+		CBT_UPLOAD
+	};
+
 	/** These values represent a hint to the driver when writing to a GPU buffer. */
 	enum class BufferWriteType
 	{

+ 1 - 1
Source/BansheeCore/Include/BsComponent.h

@@ -126,7 +126,7 @@ namespace BansheeEngine
 		RTTITypeBase* getRTTI() const override;
 
 	protected:
-		Component() {} // Serialization only
+		Component(); // Serialization only
 	};
 
 	/** @} */

+ 1 - 7
Source/BansheeCore/Include/BsCoreObjectManager.h

@@ -37,7 +37,7 @@ namespace BansheeEngine
 				:destinationObj(destObj), syncData(syncData), internalId(internalId)
 			{ }
 
-			std::weak_ptr<CoreObjectCore> destinationObj;
+			SPtr<CoreObjectCore> destinationObj;
 			CoreSyncData syncData;
 			UINT64 internalId;
 		};
@@ -91,12 +91,6 @@ namespace BansheeEngine
 		 */
 		void syncToCore(CoreObject* object, CoreAccessor& accessor);
 
-		/**
-		 * Clears any objects that are dirty and queued for sync on the core thread. Normally you only want to call this 
-		 * during shutdown when you no longer care about any of that data.
-		 */
-		void clearDirty();
-
 	private:
 		/**
 		 * Stores all syncable data from dirty core objects into memory allocated by the provided allocator. Additional 

+ 3 - 2
Source/BansheeCore/Include/BsCorePrerequisites.h

@@ -237,8 +237,6 @@ namespace BansheeEngine
 	class RenderTargetCore;
     class RenderTexture;
 	class RenderTextureCore;
-	class MultiRenderTexture;
-	class MultiRenderTextureCore;
     class RenderWindow;
 	class RenderWindowCore;
 	class RenderTargetProperties;
@@ -378,6 +376,9 @@ namespace BansheeEngine
 	class MorphShapes;
 	class MorphShape;
 	class MorphChannel;
+	class CommandBuffer;
+	class GpuPipelineState;
+	class GpuPipelineStateCore;
 	// Asset import
 	class SpecificImporter;
 	class Importer;

+ 1 - 2
Source/BansheeCore/Include/BsCoreThreadAccessor.h

@@ -50,8 +50,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * Core thread accessor allows you to schedule core commands outside of the core thread. Provides a set of common 
-	 * methods you may want to execute on the core thread, as well as a general command queuing methods.
+	 * Core thread accessor allows you to schedule core commands outside of the core thread. 
 	 * 			
 	 * @note	Queued commands are only executed after the call to submitToCoreThread(), in the order they were submitted.
 	 */

+ 0 - 28
Source/BansheeCore/Include/BsDrawOps.h

@@ -1,28 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/** @addtogroup RenderAPI
-	 *  @{
-	 */
-
-	/** Describes operation that will be used for rendering a certain set of vertices. */
-	enum DrawOperationType 
-	{
-		DOT_POINT_LIST = 1, /**< Each vertex represents a point. */
-		DOT_LINE_LIST = 2, /**< Each sequential pair of vertices represent a line. */
-		DOT_LINE_STRIP = 3, /**< Each vertex (except the first) forms a line with the previous vertex. */
-		DOT_TRIANGLE_LIST = 4, /**< Each sequential 3-tuple of vertices represent a triangle. */
-		DOT_TRIANGLE_STRIP = 5, /**< Each vertex (except the first two) form a triangle with the previous two vertices. */
-		DOT_TRIANGLE_FAN = 6 /**< Each vertex (except the first two) form a triangle with the first vertex and previous vertex. */
-	};
-
-	/** Converts the number of vertices to number of primitives based on the specified draw operation. */
-	UINT32 BS_CORE_EXPORT vertexCountToPrimCount(DrawOperationType type, UINT32 elementCount);
-
-	/** @} */
-}

+ 6 - 2
Source/BansheeCore/Include/BsEventQuery.h

@@ -41,8 +41,12 @@ namespace BansheeEngine
 		/**	Triggered when GPU starts processing the query. */
 		Event<void()> onTriggered;
 
-		/**	Creates a new query, but does not schedule it on GPU. */
-		static SPtr<EventQuery> create();
+		/**	
+		 * Creates a new query, but does not schedule it on GPU. 
+		 * 
+		 * @param[in]	deviceIdx	Index of the GPU device to create the query on. 
+		 */
+		static SPtr<EventQuery> create(UINT32 deviceIdx = 0);
 
 	protected:
 		friend class QueryManager;

+ 48 - 26
Source/BansheeCore/Include/BsGpuBuffer.h

@@ -12,6 +12,37 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	/** Descriptor structure used for initialization of a GpuBuffer. */
+	struct GPU_BUFFER_DESC
+	{
+		/** Number of elements in the buffer. */
+		UINT32 elementCount; 
+
+		/** 
+		 * Size of each individual element in the buffer, in bytes. Only needed if using non-standard buffer. If using
+		 * standard buffers element size is calculated from format and this must be zero.
+		 */
+		UINT32 elementSize;
+
+		/** Type of the buffer. Determines how is buffer seen by the GPU program and in what ways can it be used. */
+		GpuBufferType type;
+
+		/** Format if the data in the buffer. Only relevant for standard buffers, must be BF_UNKNOWN otherwise. */
+		GpuBufferFormat format;
+
+		/** Usage that tells the hardware how will be buffer be used. */
+		GpuBufferUsage usage = GBU_STATIC;
+
+		/** When true allows the GPU to write to the resource. Must be enabled if buffer type is GBT_APPENDCONSUME. */
+		bool randomGpuWrite = false;
+
+		/**
+		 * When true binds a counter that can be used from a GPU program on the buffer. Can only be used in combination
+		 * with GBT_STRUCTURED and randomGpuWrite must be enabled.
+		 */
+		bool useCounter = false;
+	};
+
 	/** 
 	 * Information about a GpuBuffer. Allows core and non-core versions of GpuBuffer to share the same structure for 
 	 * properties. 
@@ -19,41 +50,36 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GpuBufferProperties
 	{
 	public:
-		GpuBufferProperties(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format,
-			GpuBufferUsage usage, bool randomGpuWrite, bool useCounter);
+		GpuBufferProperties(const GPU_BUFFER_DESC& desc);
 
 		/**
 		 * Returns the type of the GPU buffer. Type determines which kind of views (if any) can be created for the buffer, 
 		 * and how is data read or modified in it.
 		 */
-		GpuBufferType getType() const { return mType; }
+		GpuBufferType getType() const { return mDesc.type; }
 
 		/** Returns format used by the buffer. Only relevant for standard buffers. */
-		GpuBufferFormat getFormat() const { return mFormat; }
+		GpuBufferFormat getFormat() const { return mDesc.format; }
 
 		/** Returns buffer usage which determines how are planning on updating the buffer contents. */
-		GpuBufferUsage getUsage() const { return mUsage; }
+		GpuBufferUsage getUsage() const { return mDesc.usage; }
 
 		/** Return whether the buffer supports random reads and writes within the GPU programs. */
-		bool getRandomGpuWrite() const { return mRandomGpuWrite; }
+		bool getRandomGpuWrite() const { return mDesc.randomGpuWrite; }
 
 		/**	Returns whether the buffer supports counter use within GPU programs. */
-		bool getUseCounter() const { return mUseCounter; }
+		bool getUseCounter() const { return mDesc.useCounter; }
 
 		/**	Returns number of elements in the buffer. */
-		UINT32 getElementCount() const { return mElementCount; }
+		UINT32 getElementCount() const { return mDesc.elementCount; }
 
 		/**	Returns size of a single element in the buffer in bytes. */
-		UINT32 getElementSize() const { return mElementSize; }
+		UINT32 getElementSize() const { return mDesc.elementSize; }
 
 	protected:
-		GpuBufferType mType;
-		GpuBufferUsage mUsage;
-		GpuBufferFormat mFormat;
-		bool mRandomGpuWrite;
-		bool mUseCounter;
-		UINT32 mElementCount;
-		UINT32 mElementSize;
+		friend class GpuBuffer;
+
+		GPU_BUFFER_DESC mDesc;
 	};
 
 	/**
@@ -88,14 +114,12 @@ namespace BansheeEngine
 		static UINT32 getFormatSize(GpuBufferFormat format);
 
 		/** @copydoc HardwareBufferManager::createGpuBuffer */
-		static SPtr<GpuBuffer> create(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		static SPtr<GpuBuffer> create(const GPU_BUFFER_DESC& desc);
 
 	protected:
 		friend class HardwareBufferManager;
 
-		GpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format, GpuBufferUsage usage,
-			bool randomGpuWrite = false, bool useCounter = false);
+		GpuBuffer(const GPU_BUFFER_DESC& desc);
 
 		/** @copydoc CoreObject::createCore */
 		SPtr<CoreObjectCore> createCore() const override;
@@ -195,13 +219,11 @@ namespace BansheeEngine
 		 */
 		static void releaseView(GpuBufferView* view);
 
-		/** @copydoc HardwareBufferManager::createGpuBuffer */
-		static SPtr<GpuBufferCore> create(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		/** @copydoc HardwareBufferCoreManager::createGpuBuffer */
+		static SPtr<GpuBufferCore> create(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
-		GpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format,
-			GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		GpuBufferCore(const GPU_BUFFER_DESC& desc, UINT32 deviceMask);
 
 		/** Creates an empty view for the current buffer. */
 		virtual GpuBufferView* createView() = 0;
@@ -223,7 +245,7 @@ namespace BansheeEngine
 			UINT32 refCount;
 		};
 
-		UnorderedMap<GPU_BUFFER_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
+		UnorderedMap<GPU_BUFFER_VIEW_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
 		GpuBufferProperties mProperties;
 	};
 

+ 6 - 6
Source/BansheeCore/Include/BsGpuBufferView.h

@@ -15,7 +15,7 @@ namespace BansheeEngine
 	 *
 	 * @see		GpuBuffer
 	 */
-	struct BS_CORE_EXPORT GPU_BUFFER_DESC
+	struct BS_CORE_EXPORT GPU_BUFFER_VIEW_DESC
 	{
 		UINT32 firstElement;
 		UINT32 elementWidth;
@@ -40,13 +40,13 @@ namespace BansheeEngine
 		class HashFunction
 		{
 		public:
-			size_t operator()(const GPU_BUFFER_DESC& key) const;
+			size_t operator()(const GPU_BUFFER_VIEW_DESC& key) const;
 		};
 
 		class EqualFunction
 		{
 		public:
-			bool operator()(const GPU_BUFFER_DESC& a, const GPU_BUFFER_DESC& b) const;
+			bool operator()(const GPU_BUFFER_VIEW_DESC& a, const GPU_BUFFER_VIEW_DESC& b) const;
 		};
 
 		GpuBufferView();
@@ -56,10 +56,10 @@ namespace BansheeEngine
 		 * Initializes the view with the specified buffer and a set of parameters describing the view to create. Must be 
 		 * called right after construction.
 		 */
-		virtual void initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_DESC& desc);
+		virtual void initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_VIEW_DESC& desc);
 
 		/** Returns a descriptor structure used for creating the view. */
-		const GPU_BUFFER_DESC& getDesc() const { return mDesc; }
+		const GPU_BUFFER_VIEW_DESC& getDesc() const { return mDesc; }
 
 		/**	Returns the buffer this view was created for. */
 		SPtr<GpuBufferCore> getBuffer() const { return mBuffer; }
@@ -80,7 +80,7 @@ namespace BansheeEngine
 		GpuViewUsage getUsage() const { return mDesc.usage; }
 
 	protected:
-		GPU_BUFFER_DESC mDesc;
+		GPU_BUFFER_VIEW_DESC mDesc;
 		SPtr<GpuBufferCore> mBuffer;
 	};
 

+ 7 - 6
Source/BansheeCore/Include/BsGpuParamBlockBuffer.h

@@ -19,7 +19,7 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GpuParamBlockBufferCore : public CoreObjectCore
 	{
 	public:
-		GpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage);
+		GpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage, GpuDeviceFlags deviceMask);
 		virtual ~GpuParamBlockBufferCore();
 
 		/** Writes all of the specified data to the buffer. Data size must be the same size as the buffer. */
@@ -61,11 +61,12 @@ namespace BansheeEngine
 		UINT32 getSize() const { return mSize; }
 
 		/** @copydoc HardwareBufferCoreManager::createGpuParamBlockBuffer */
-		static SPtr<GpuParamBlockBufferCore> create(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
+		static SPtr<GpuParamBlockBufferCore> create(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC,
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
 		/** @copydoc CoreObjectCore::syncToCore */
-		virtual void syncToCore(const CoreSyncData& data)  override;
+		void syncToCore(const CoreSyncData& data)  override;
 
 		GpuParamBlockUsage mUsage;
 		UINT32 mSize;
@@ -81,7 +82,7 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GenericGpuParamBlockBufferCore : public GpuParamBlockBufferCore
 	{
 	public:
-		GenericGpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage);
+		GenericGpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage, GpuDeviceFlags deviceMask);
 		~GenericGpuParamBlockBufferCore();
 
 		/** @copydoc GpuParamBlockBufferCore::writeToGPU */
@@ -94,7 +95,7 @@ namespace BansheeEngine
 		UINT8* mData;
 
 		/** @copydoc CoreObjectCore::initialize */
-		virtual void initialize() override;
+		void initialize() override;
 	};
 
 	/** @} */
@@ -154,7 +155,7 @@ namespace BansheeEngine
 		SPtr<CoreObjectCore> createCore() const override;
 
 		/** @copydoc CoreObject::syncToCore */
-		virtual CoreSyncData syncToCore(FrameAlloc* allocator) override;
+		CoreSyncData syncToCore(FrameAlloc* allocator) override;
 
 		GpuParamBlockUsage mUsage;
 		UINT32 mSize;

+ 6 - 3
Source/BansheeCore/Include/BsGpuParamDesc.h

@@ -20,6 +20,7 @@ namespace BansheeEngine
 		GpuParamDataType type;
 
 		UINT32 paramBlockSlot;
+		UINT32 paramBlockSet;
 		UINT32 gpuMemOffset; /**< In multiples of 4 bytes, or index for parameters not in a buffer. */
 		UINT32 cpuMemOffset; /**< In multiples of 4 bytes. */
 	};
@@ -30,16 +31,18 @@ namespace BansheeEngine
 		String name;
 		GpuParamObjectType type;
 
-		UINT32 slot;
+		UINT32 slot; /** Slot within a set. Uniquely identifies bind location in the GPU pipeline, together with the set. */
+		UINT32 set; /** Uniquely identifies the bind location in the GPU pipeline, together with the slot. */
 	};
 
 	/**	Describes a GPU program parameter block (collection of GPU program data parameters). */
 	struct GpuParamBlockDesc
 	{
 		String name;
-		UINT32 slot;
+		UINT32 slot; /** Slot within a set. Uniquely identifies bind location in the GPU pipeline, together with the set. */
+		UINT32 set; /** Uniquely identifies the bind location in the GPU pipeline, together with the slot. */
 		UINT32 blockSize; /**< In multiples of 4 bytes. */
-		bool isShareable;
+		bool isShareable; /** True for blocks that can be shared between different GPU pipeline stages. */
 	};
 
 	/** Contains all parameter information for a GPU program, including data and object parameters, plus parameter blocks. */

+ 99 - 78
Source/BansheeCore/Include/BsGpuParams.h

@@ -36,19 +36,21 @@ namespace BansheeEngine
 	template<> struct TGpuDataParamInfo < Matrix4x3 > { enum { TypeId = GPDT_MATRIX_4X3 }; };
 	template<> struct TGpuDataParamInfo < Color > { enum { TypeId = GPDT_COLOR }; };
 
+	/** Helper structure used for initializing GpuParams. */
+	struct GPU_PARAMS_DESC
+	{
+		SPtr<GpuParamDesc> fragmentParams;
+		SPtr<GpuParamDesc> vertexParams;
+		SPtr<GpuParamDesc> geometryParams;
+		SPtr<GpuParamDesc> hullParams;
+		SPtr<GpuParamDesc> domainParams;
+		SPtr<GpuParamDesc> computeParams;
+	};
+
 	/** Contains functionality common for both sim and core thread version of GpuParams. */
 	class BS_CORE_EXPORT GpuParamsBase
 	{
 	public:
-		/**
-		 * Creates new GpuParams object using the specified parameter descriptions.
-		 *
-		 * @param[in]	paramDesc			Reference to parameter descriptions that will be used for finding needed 
-		 *									parameters.
-		 *
-		 * @note	You normally do not want to call this manually. Instead use GpuProgram::createParameters.
-		 */
-		GpuParamsBase(const SPtr<GpuParamDesc>& paramDesc);
 		virtual ~GpuParamsBase();
 
 		// Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
@@ -57,39 +59,33 @@ namespace BansheeEngine
 		GpuParamsBase& operator=(const GpuParamsBase& rhs) = delete;
 
 		/** Returns a description of all stored parameters. */
-		const GpuParamDesc& getParamDesc() const { return *mParamDesc; }
+		SPtr<GpuParamDesc> getParamDesc(GpuProgramType type) const { return mParamDescs[(int)type]; }
 
 		/**
 		 * Returns the size of a data parameter with the specified name, in bytes. Returns 0 if such parameter doesn't exist.
 		 */
-		UINT32 getDataParamSize(const String& name) const;
+		UINT32 getDataParamSize(GpuProgramType type, const String& name) const;
 
 		/** Checks if parameter with the specified name exists. */
-		bool hasParam(const String& name) const;
+		bool hasParam(GpuProgramType type, const String& name) const;
 
 		/**	Checks if texture parameter with the specified name exists. */
-		bool hasTexture(const String& name) const;
+		bool hasTexture(GpuProgramType type, const String& name) const;
 
 		/**	Checks if load/store texture parameter with the specified name exists. */
-		bool hasLoadStoreTexture(const String& name) const;
+		bool hasLoadStoreTexture(GpuProgramType type, const String& name) const;
 
 		/**	Checks if buffer parameter with the specified name exists. */
-		bool hasBuffer(const String& name) const;
+		bool hasBuffer(GpuProgramType type, const String& name) const;
 
 		/**	Checks if sampler state parameter with the specified name exists. */
-		bool hasSamplerState(const String& name) const;
+		bool hasSamplerState(GpuProgramType type, const String& name) const;
 
 		/** Checks if a parameter block with the specified name exists. */
-		bool hasParamBlock(const String& name) const;
+		bool hasParamBlock(GpuProgramType type, const String& name) const;
 
 		/**	Gets a descriptor for a parameter block buffer with the specified name. */
-		GpuParamBlockDesc* getParamBlockDesc(const String& name) const;
-
-		/** Returns information that determines which texture surfaces to bind as load/store parameters. */
-		const TextureSurface& getLoadStoreSurface(UINT32 slot) const;
-
-		/**	Sets information that determines which texture surfaces to bind	as load/store parameters. */
-		void setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const;
+		GpuParamBlockDesc* getParamBlockDesc(GpuProgramType type, const String& name) const;
 
 		/** Marks the sim thread object as dirty, causing it to sync its contents with its core thread counterpart. */
 		virtual void _markCoreDirty() { }
@@ -98,18 +94,12 @@ namespace BansheeEngine
 		virtual void _markResourcesDirty() { }
 
 	protected:
-		/**	Gets a descriptor for a data parameter with the specified name. */
-		GpuParamDataDesc* getParamDesc(const String& name) const;
-
-		SPtr<GpuParamDesc> mParamDesc;
+		GpuParamsBase(const GPU_PARAMS_DESC& desc);
 
-		UINT32 mNumParamBlocks;
-		UINT32 mNumTextures;
-		UINT32 mNumLoadStoreTextures;
-		UINT32 mNumBuffers;
-		UINT32 mNumSamplerStates;
+		/**	Gets a descriptor for a data parameter with the specified name. */
+		GpuParamDataDesc* getParamDesc(GpuProgramType type, const String& name) const;
 
-		TextureSurface* mLoadStoreSurfaces;
+		SPtr<GpuParamDesc> mParamDescs[6];
 	};
 
 	template<bool Core> struct TGpuParamsTypes { };
@@ -142,8 +132,6 @@ namespace BansheeEngine
 		typedef typename TGpuParamsTypes<Core>::SamplerType SamplerType;
 		typedef typename TGpuParamsTypes<Core>::ParamsBufferType ParamsBufferType;
 
-		TGpuParams(const SPtr<GpuParamDesc>& paramDesc);
-
 		virtual ~TGpuParams();
 
 		/**
@@ -156,7 +144,7 @@ namespace BansheeEngine
 		 * @note
 		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
 		 */
-		void setParamBlockBuffer(UINT32 slot, const ParamsBufferType& paramBlockBuffer);
+		void setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer);
 
 		/**
 		 * Replaces the parameter buffer with the specified name. Any following parameter reads or writes that are 
@@ -168,7 +156,7 @@ namespace BansheeEngine
 		 * @note
 		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
 		 */
-		void setParamBlockBuffer(const String& name, const ParamsBufferType& paramBlockBuffer);
+		void setParamBlockBuffer(GpuProgramType type, const String& name, const ParamsBufferType& paramBlockBuffer);
 
 		/**
 		 * Returns a handle for the parameter with the specified name. Handle may then be stored and used for quickly 
@@ -178,59 +166,84 @@ namespace BansheeEngine
 		 *
 		 * Parameter handles will be invalidated when their parent GpuParams object changes.
 		 */
-		template<class T> void getParam(const String& name, TGpuDataParam<T, Core>& output) const;
+		template<class T> void getParam(GpuProgramType type, const String& name, TGpuDataParam<T, Core>& output) const;
 
 		/** @copydoc getParam */
-		void getStructParam(const String& name, TGpuParamStruct<Core>& output) const;
+		void getStructParam(GpuProgramType type, const String& name, TGpuParamStruct<Core>& output) const;
 
 		/** @copydoc getParam */
-		void getTextureParam(const String& name, TGpuParamTexture<Core>& output) const;
+		void getTextureParam(GpuProgramType type, const String& name, TGpuParamTexture<Core>& output) const;
 
 		/** @copydoc getParam */
-		void getLoadStoreTextureParam(const String& name, TGpuParamLoadStoreTexture<Core>& output) const;
+		void getLoadStoreTextureParam(GpuProgramType type, const String& name, TGpuParamLoadStoreTexture<Core>& output) const;
 
 		/** @copydoc getParam */
-		void getBufferParam(const String& name, TGpuParamBuffer<Core>& output) const;
+		void getBufferParam(GpuProgramType type, const String& name, TGpuParamBuffer<Core>& output) const;
 
 		/** @copydoc getParam */
-		void getSamplerStateParam(const String& name, TGpuParamSampState<Core>& output) const;
+		void getSamplerStateParam(GpuProgramType type, const String& name, TGpuParamSampState<Core>& output) const;
+
+		/**	Gets a parameter block buffer from the specified set/slot combination. */
+		ParamsBufferType getParamBlockBuffer(UINT32 set, UINT32 slot) const;
 
-		/**	Gets a parameter block buffer from the specified slot. */
-		ParamsBufferType getParamBlockBuffer(UINT32 slot) const;
+		/**	Gets a texture bound to the specified set/slot combination. */
+		TextureType getTexture(UINT32 set, UINT32 slot) const;
 
-		/**	Gets a texture bound to the specified slot. */
-		TextureType getTexture(UINT32 slot);
+		/**	Gets a load/store texture bound to the specified set/slot combination. */
+		TextureType getLoadStoreTexture(UINT32 set, UINT32 slot) const;
 
-		/**	Gets a load/store texture bound to the specified slot. */
-		TextureType getLoadStoreTexture(UINT32 slot);
+		/**	Gets a buffer bound to the specified set/slot combination. */
+		BufferType getBuffer(UINT32 set, UINT32 slot) const;
 
-		/**	Gets a buffer bound to the specified slot. */
-		BufferType getBuffer(UINT32 slot);
+		/**	Gets a sampler state bound to the specified set/slot combination. */
+		SamplerType getSamplerState(UINT32 set, UINT32 slot) const;
 
-		/**	Gets a sampler state bound to the specified slot. */
-		SamplerType getSamplerState(UINT32 slot);
+		/** Gets information that determines which texture surfaces to bind as load/store parameters. */
+		const TextureSurface& getLoadStoreSurface(UINT32 set, UINT32 slot) const;
 
-		/**	Sets a texture at the specified slot. */
-		void setTexture(UINT32 slot, const TextureType& texture);
+		/**	Sets a texture at the specified set/slot combination. */
+		void setTexture(UINT32 set, UINT32 slot, const TextureType& texture);
 
-		/**	Sets a load/store texture at the specified slot. */
-		void setLoadStoreTexture(UINT32 slot, const TextureType& texture, const TextureSurface& surface);
+		/**	Sets a load/store texture at the specified set/slot combination. */
+		void setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface);
 
-		/**	Sets a buffer at the specified slot. */
-		void setBuffer(UINT32 slot, const BufferType& buffer);
+		/**	Sets a buffer at the specified set/slot combination. */
+		void setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer);
 
-		/**	Sets a sampler state at the specified slot. */
-		void setSamplerState(UINT32 slot, const SamplerType& sampler);
+		/**	Sets a sampler state at the specified set/slot combination. */
+		void setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler);
+
+		/**	Sets information that determines which texture surfaces to bind	as load/store parameters. */
+		void setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface);
 
 	protected:
+		/** Type of elements stored in this object. */
+		enum class ElementType
+		{
+			ParamBlock, Texture, LoadStoreTexture, Buffer, SamplerState, Count
+		};
+
+		TGpuParams(const GPU_PARAMS_DESC& desc);
+
 		/** @copydoc CoreObject::getThisPtr */
 		virtual SPtr<GpuParamsType> _getThisPtr() const = 0;
 
-		ParamsBufferType* mParamBlockBuffers;
-		TextureType* mTextures;
-		TextureType* mLoadStoreTextures;
-		BufferType* mBuffers;
-		SamplerType* mSamplerStates;
+		/** 
+		 * Converts a set/slot combination into a global slot. If the set or slot is out of valid range, the method logs
+		 * an error and returns -1. Only performs range checking in debug mode.
+		 */
+		UINT32 getGlobalSlot(ElementType type, UINT32 set, UINT32 slot) const;
+
+		UINT32 mNumSets[(int)ElementType::Count];
+		UINT32 mNumElements[(int)ElementType::Count];
+		UINT32* mOffsets[(int)ElementType::Count];
+
+		ParamsBufferType* mParamBlockBuffers = nullptr;
+		TextureType* mTextures = nullptr;
+		TextureType* mLoadStoreTextures = nullptr;
+		TextureSurface* mLoadStoreSurfaces = nullptr;
+		BufferType* mBuffers = nullptr;
+		SamplerType* mSamplerStates = nullptr;
 	};
 
 	/** @} */
@@ -249,14 +262,17 @@ namespace BansheeEngine
 	public:
 		~GpuParamsCore() { }
 
-		/** @copydoc GpuParamsBase::GpuParamsBase */
-		static SPtr<GpuParamsCore> create(const SPtr<GpuParamDesc>& paramDesc);
+		/** 
+		 * @copydoc GpuParams::create 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the buffer be created on.
+		 */
+		static SPtr<GpuParamsCore> create(const GPU_PARAMS_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
 		friend class GpuParams;
+		friend class HardwareBufferCoreManager;
 
-		/** @copydoc GpuParamsBase::GpuParamsBase */
-		GpuParamsCore(const SPtr<GpuParamDesc>& paramDesc);
+		GpuParamsCore(const GPU_PARAMS_DESC& desc, GpuDeviceFlags deviceMask);
 
 		/** @copydoc CoreObject::getThisPtr */
 		SPtr<GpuParamsCore> _getThisPtr() const override;
@@ -271,9 +287,9 @@ namespace BansheeEngine
 	 */
 
 	/**
-	 * Contains descriptions for all parameters in a GPU program and also allows you to write and read those parameters. 
-	 * All parameter values are stored internally on the CPU, and are only submitted to the GPU once the parameters are 
-	 * bound to the pipeline.
+	 * Contains descriptions for all parameters in a set of programs (ones for each stage) and allows you to write and read
+	 * those parameters. All parameter values are stored internally on the CPU, and are only submitted to the GPU once the
+	 * parameters are bound to the pipeline.
 	 *
 	 * @note	Sim thread only.
 	 */
@@ -285,8 +301,12 @@ namespace BansheeEngine
 		/** Retrieves a core implementation of a mesh usable only from the core thread. */
 		SPtr<GpuParamsCore> getCore() const;
 
-		/** @copydoc GpuParamsBase::GpuParamsBase */
-		static SPtr<GpuParams> create(const SPtr<GpuParamDesc>& paramDesc);
+		/**
+		 * Creates new GpuParams object using the specified parameter descriptions.
+		 *
+		 * @param[in]	desc	Object containing parameter descriptions for all relevant GPU program stages.
+		 */
+		static SPtr<GpuParams> create(const GPU_PARAMS_DESC& desc);
 
 		/** Contains a lookup table for sizes of all data parameters. Sizes are in bytes. */
 		const static GpuDataParamInfos PARAM_SIZES;
@@ -303,8 +323,9 @@ namespace BansheeEngine
 
 		/** @} */
 	protected:
-		/** @copydoc GpuParamsBase::GpuParamsBase */
-		GpuParams(const SPtr<GpuParamDesc>& paramDesc);
+		friend class HardwareBufferManager;
+
+		GpuParams(const GPU_PARAMS_DESC& desc);
 
 		/** @copydoc CoreObject::getThisPtr */
 		SPtr<GpuParams> _getThisPtr() const override;

+ 11 - 56
Source/BansheeCore/Include/BsGpuParamsSet.h

@@ -12,11 +12,15 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	template<bool Core> struct TGpuParamsType { };
+	template<> struct TGpuParamsType<false> { typedef GpuParams Type; };
+	template<> struct TGpuParamsType<true> { typedef GpuParamsCore Type; };
+
 	/** Contains a set of GpuParams used for a single technique within a Material. */
 	template<bool Core>
 	class BS_CORE_EXPORT TGpuParamsSet
 	{
-		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+		typedef typename TGpuParamsType<Core>::Type GpuParamsType;
 		typedef typename TMaterialParamsType<Core>::Type MaterialParamsType;
 		typedef typename TGpuParamBlockBufferPtrType<Core>::Type ParamBlockPtrType;
 		typedef typename TTechniqueType<Core>::Type TechniqueType;
@@ -28,17 +32,6 @@ namespace BansheeEngine
 		typedef typename TGpuBufferType<Core>::Type BufferType;
 		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
 
-		/** Contains all parameters for a single pass. */
-		struct PassParams
-		{
-			GpuParamsType vertex;
-			GpuParamsType fragment;
-			GpuParamsType geometry;
-			GpuParamsType hull;
-			GpuParamsType domain;
-			GpuParamsType compute;
-		};
-
 		/** Information about a parameter block buffer. */
 		struct BlockInfo
 		{
@@ -66,6 +59,7 @@ namespace BansheeEngine
 		{
 			UINT32 paramIdx;
 			UINT32 slotIdx;
+			UINT32 setIdx;
 		};
 
 		/** Information about all object parameters for a specific GPU programmable stage. */
@@ -93,53 +87,14 @@ namespace BansheeEngine
 			const SPtr<MaterialParamsType>& params);
 		~TGpuParamsSet();
 
-		/**
-		 * Returns a GPU parameters for a specific shader stage and pass.
-		 *
-		 * @param[in]	stageidx	Sequential index of the shader stage to retrieve the parameters for.
-		 * @param[in]	passIdx		Pass for which to retrieve the parameters for.
-		 * @return					GPU parameters object that can be used for setting parameters of a GPU program 
-		 *							individually.
-		 *
-		 * @note	Useful when needing to iterate over all sets of GPU parameters.
-		 */
-		GpuParamsType getParamByIdx(UINT32 stageidx, UINT32 passIdx = 0)
-		{
-			GpuParamsType* paramArray[] = { &mPassParams[passIdx].vertex, &mPassParams[passIdx].fragment,
-				&mPassParams[passIdx].geometry, &mPassParams[passIdx].hull, &mPassParams[passIdx].domain, 
-				&mPassParams[passIdx].compute };
-
-			return *paramArray[stageidx];
-		}
-
-		/**
-		 * Sets GPU parameters for a specific shader stage and pass.
-		 *
-		 * @param[in]	stageidx	Sequential index of the shader stage to set the parameters for.
-		 * @param[in]	params		GPU parameters object to assign.
-		 * @param[in]	passIdx		Pass for which to set the parameters for.
-		 *
-		 * @note	Useful when needing to iterate over all sets of GPU parameters.
-		 */
-		void setParamByIdx(UINT32 stageidx, const GpuParamsType& params, UINT32 passIdx = 0)
-		{
-			GpuParamsType* paramArray[] = { &mPassParams[passIdx].vertex, &mPassParams[passIdx].fragment,
-				&mPassParams[passIdx].geometry, &mPassParams[passIdx].hull, &mPassParams[passIdx].domain,
-				&mPassParams[passIdx].compute };
-
-			(*paramArray[stageidx]) = params;
-		}
-
 		/** 
-		 * Returns a set of GPU parameters for an individual GPU program of the specified pass. 
+		 * Returns a set of GPU parameters for the specified pass. 
 		 *
-		 * @param[in]	type		Type of the program to retrieve parameters for.
 		 * @param[in]	passIdx		Pass in which to look the GPU program for in.
-		 * @return					GPU parameters object that can be used for setting parameters of a GPU program 
-		 *							individually. Returns null if program or pass doesn't exist.
+		 * @return					GPU parameters object that can be used for setting parameters of all GPU programs 
+		 *							in a pass. Returns null if pass doesn't exist.
 		 */
-		GpuParamsType getGpuParams(GpuProgramType type, UINT32 passIdx = 0);
-
+		SPtr<GpuParamsType> getGpuParams(UINT32 passIdx = 0);
 
 		/**
 		 * Assign a parameter block buffer with the specified name to all the relevant child GpuParams.
@@ -177,7 +132,7 @@ namespace BansheeEngine
 	private:
 		template<bool Core2> friend class TMaterial;
 
-		Vector<PassParams> mPassParams;
+		Vector<SPtr<GpuParamsType>> mPassParams;
 		Vector<BlockInfo> mBlocks;
 		Vector<DataParamInfo> mDataParamInfos;
 		PassParamInfo* mPassParamInfos;

+ 172 - 0
Source/BansheeCore/Include/BsGpuPipelineState.h

@@ -0,0 +1,172 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** Descriptor structure used for initializing a GPU pipeline state. */
+	struct PIPELINE_STATE_DESC
+	{
+		SPtr<BlendState> blendState;
+		SPtr<RasterizerState> rasterizerState;
+		SPtr<DepthStencilState> depthStencilState;
+
+		SPtr<GpuProgram> vertexProgram;
+		SPtr<GpuProgram> fragmentProgram;
+		SPtr<GpuProgram> geometryProgram;
+		SPtr<GpuProgram> hullProgram;
+		SPtr<GpuProgram> domainProgram;
+	};
+
+	/** @} */
+
+	/** @addtogroup RenderAPI-Internal
+	 *  @{
+	 */
+
+	/** Descriptor structure used for initializing a GPU pipeline state. */
+	struct PIPELINE_STATE_CORE_DESC
+	{
+		SPtr<BlendStateCore> blendState;
+		SPtr<RasterizerStateCore> rasterizerState;
+		SPtr<DepthStencilStateCore> depthStencilState;
+
+		SPtr<GpuProgramCore> vertexProgram;
+		SPtr<GpuProgramCore> fragmentProgram;
+		SPtr<GpuProgramCore> geometryProgram;
+		SPtr<GpuProgramCore> hullProgram;
+		SPtr<GpuProgramCore> domainProgram;
+	};
+
+	/** @} */
+
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	/** Contains all data used by a GPU pipeline state, templated so it may contain both core and sim thread data. */
+	template<bool Core>
+	struct TGpuPipelineStateTypes
+	{ };
+
+	template<>
+	struct TGpuPipelineStateTypes < false >
+	{
+		typedef SPtr<BlendState> BlendStateType;
+		typedef SPtr<RasterizerState> RasterizerStateType;
+		typedef SPtr<DepthStencilState> DepthStencilStateType;
+		typedef SPtr<GpuProgram> GpuProgramType;
+		typedef PIPELINE_STATE_DESC StateDescType;
+	};
+
+	template<>
+	struct TGpuPipelineStateTypes < true >
+	{
+		typedef SPtr<BlendStateCore> BlendStateType;
+		typedef SPtr<RasterizerStateCore> RasterizerStateType;
+		typedef SPtr<DepthStencilStateCore> DepthStencilStateType;
+		typedef SPtr<GpuProgramCore> GpuProgramType;
+		typedef PIPELINE_STATE_CORE_DESC StateDescType;
+	};
+
+	/** 
+	 * Templated version of GpuPipelineState so it can be used for both core and non-core versions of the pipeline state. 
+	 */
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuPipelineState
+    {
+    public:
+		typedef typename TGpuPipelineStateTypes<Core>::BlendStateType BlendStateType;
+		typedef typename TGpuPipelineStateTypes<Core>::RasterizerStateType RasterizerStateType;
+		typedef typename TGpuPipelineStateTypes<Core>::DepthStencilStateType DepthStencilStateType;
+		typedef typename TGpuPipelineStateTypes<Core>::GpuProgramType GpuProgramType;
+		typedef typename TGpuPipelineStateTypes<Core>::StateDescType StateDescType;
+
+		virtual ~TGpuPipelineState() { }
+
+        bool hasVertexProgram() const { return mData.vertexProgram != nullptr; }
+		bool hasFragmentProgram() const { return mData.fragmentProgram != nullptr; }
+		bool hasGeometryProgram() const { return mData.geometryProgram != nullptr; }
+		bool hasHullProgram() const { return mData.hullProgram != nullptr; }
+		bool hasDomainProgram() const { return mData.domainProgram != nullptr; }
+
+		BlendStateType getBlendState() const { return mData.blendState; }
+		RasterizerStateType getRasterizerState() const { return mData.rasterizerState; }
+		DepthStencilStateType getDepthStencilState() const { return mData.depthStencilState; }
+
+		const GpuProgramType& getVertexProgram() const { return mData.vertexProgram; }
+		const GpuProgramType& getFragmentProgram() const { return mData.fragmentProgram; }
+		const GpuProgramType& getGeometryProgram() const { return mData.geometryProgram; }
+		const GpuProgramType& getHullProgram() const { return mData.hullProgram; }
+		const GpuProgramType& getDomainProgram() const { return mData.domainProgram; }
+
+	protected:
+		TGpuPipelineState();
+		TGpuPipelineState(const StateDescType& desc);
+
+		StateDescType mData;
+    };
+
+	/** @} */
+
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	class GpuPipelineStateCore;
+
+	/**
+	 * Describes the state of the GPU pipeline that determines how are primitives rendered. It consists of programmable
+	 * states (vertex, fragment, geometry, etc. GPU programs), as well as a set of fixed states (blend, rasterizer, 
+	 * depth-stencil). Once created the state is immutable, and can be bound to RenderAPI for rendering.
+	 */
+    class BS_CORE_EXPORT GpuPipelineState : public CoreObject, public TGpuPipelineState<false>
+    {
+	public:
+		virtual ~GpuPipelineState() { }
+
+		/**
+		 * Retrieves a core implementation of the pipeline object usable only from the core thread.
+		 *
+		 * @note	Core thread only.
+		 */
+		SPtr<GpuPipelineStateCore> getCore() const;
+
+		/** @copydoc RenderStateManager::createPipelineState */
+		static SPtr<GpuPipelineState> create(const PIPELINE_STATE_DESC& desc);
+	protected:
+		friend class RenderStateManager;
+
+		GpuPipelineState(const PIPELINE_STATE_DESC& desc);
+
+		/** @copydoc CoreObject::createCore */
+		virtual SPtr<CoreObjectCore> createCore() const;
+    };
+
+	/** @} */
+
+	/** @addtogroup RenderAPI-Internal
+	 *  @{
+	 */
+
+	/** Core thread version of a GpuPipelineState. */
+	class BS_CORE_EXPORT GpuPipelineStateCore : public CoreObjectCore, public TGpuPipelineState<true>
+	{
+	public:
+		GpuPipelineStateCore(const PIPELINE_STATE_CORE_DESC& desc, GpuDeviceFlags deviceMask);
+		virtual ~GpuPipelineStateCore() { }
+
+		/** @copydoc RenderStateManager::createPipelineState */
+		static SPtr<GpuPipelineStateCore> create(const PIPELINE_STATE_CORE_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
+	};
+
+	/** @} */
+}

+ 20 - 27
Source/BansheeCore/Include/BsGpuProgram.h

@@ -45,6 +45,17 @@ namespace BansheeEngine
 		GPP_CS_5_0 /**< Compute program 5.0 profile. */
 	};
 
+	/** Descriptor structure used for initialization of a GpuProgram. */
+	struct GPU_PROGRAM_DESC
+	{
+		String source; /**< Source code to compile the program from. */
+		String entryPoint; /**< Name of the entry point function, for example "main". */
+		String language; /**< Language the source is written in, for example "hlsl" or "glsl". */
+		GpuProgramType type = GPT_VERTEX_PROGRAM; /**< Type of the program, for example vertex or fragment. */
+		GpuProgramProfile profile = GPP_NONE; /**< Program profile specifying supported feature-set. Must match the type. */
+		bool requiresAdjacency = false; /**< If true then adjacency information will be provided when rendering. */
+	};
+
 	/** Data describing a GpuProgram. */
 	class BS_CORE_EXPORT GpuProgramProperties
 	{
@@ -99,14 +110,6 @@ namespace BansheeEngine
 		 */
 		String getCompileErrorMessage() const;
 
-		/**
-		 * Creates a new parameters object compatible with this program definition. You may populate the returned object 
-		 * with actual parameter values and bind it to the pipeline to render an object using those values and this program.
-		 *
-		 * @note	Only valid after core thread has initialized the program.
-		 */
-		SPtr<GpuParams> createParameters();
-
 		/**
 		 * Returns description of all parameters in this GPU program.
 		 *
@@ -124,22 +127,14 @@ namespace BansheeEngine
 		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
 		 * isCompiled() with return false, and you will be able to retrieve the error message via getCompileErrorMessage().
 		 *
-		 * @param[in]	source				Source code to compile the program from.
-		 * @param[in]	entryPoint			Name of the entry point function, for example "main".
-		 * @param[in]	language			Language the source is written in, for example "hlsl" or "glsl".
-		 * @param[in]	gptype				Type of the program, for example vertex or fragment.
-		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
-		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
-		 *									program.
+		 * @param[in]	desc				Description of the program to create.
 		 */
-		static SPtr<GpuProgram> create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype,
-			GpuProgramProfile profile, bool requiresAdjacency = false);
+		static SPtr<GpuProgram> create(const GPU_PROGRAM_DESC& desc);
 
 	protected:
 		friend class GpuProgramManager;
 
-		GpuProgram(const String& source, const String& entryPoint, const String& language,
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+		GpuProgram(const GPU_PROGRAM_DESC& desc);
 
 		/** @copydoc CoreObject::createCore */
 		SPtr<CoreObjectCore> createCore() const override;
@@ -197,9 +192,6 @@ namespace BansheeEngine
 		 */
 		virtual bool isAdjacencyInfoRequired() const { return mNeedsAdjacencyInfo; }
 
-		/** @copydoc GpuProgram::createParameters */
-		virtual SPtr<GpuParamsCore> createParameters();
-
 		/** @copydoc GpuProgram::getParamDesc */
 		SPtr<GpuParamDesc> getParamDesc() const { return mParametersDesc; }
 
@@ -209,13 +201,14 @@ namespace BansheeEngine
 		/**	Returns properties that contain information about the GPU program. */
 		const GpuProgramProperties& getProperties() const { return mProperties; }
 
-		/** @copydoc GpuProgram::create */
-		static SPtr<GpuProgramCore> create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype,
-			GpuProgramProfile profile, bool requiresAdjacency = false);
+		/** 
+		 * @copydoc GpuProgram::create 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		static SPtr<GpuProgramCore> create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
-		GpuProgramCore(const String& source, const String& entryPoint,
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+		GpuProgramCore(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask);
 
 		/** Returns whether required capabilities for this program is supported. */
 		bool isRequiredCapabilitiesSupported() const;

+ 8 - 47
Source/BansheeCore/Include/BsGpuProgramManager.h

@@ -23,23 +23,11 @@ namespace BansheeEngine
 		/**	Returns GPU program language this factory is capable creating GPU programs from. */
 		virtual const String& getLanguage() const = 0;
 
-		/**
-		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
-		 * GpuProgram::isCompiled() method on the returned program will return false, and you will be able to retrieve 
-		 * the error message via GpuProgram::getCompileErrorMessage().
-		 *
-		 * @param[in]	source				Source code to compile the shader from.
-		 * @param[in]	entryPoint			Name of the entry point function, for example "main".
-		 * @param[in]	gptype				Type of the program, for example vertex or fragment.
-		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
-		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
-		 *									program.
-		 */
-		virtual SPtr<GpuProgramCore> create(const String& source, const String& entryPoint, GpuProgramType gptype, 
-			GpuProgramProfile profile, bool requiresAdjacency) = 0;
+		/** @copydoc GpuProgramCore::create */
+		virtual SPtr<GpuProgramCore> create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
 
 		/** @copydoc GpuProgramManager::createEmpty */
-		virtual SPtr<GpuProgramCore> create(GpuProgramType type) = 0;
+		virtual SPtr<GpuProgramCore> create(GpuProgramType type, GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
 	};
 
 	/**
@@ -51,21 +39,8 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GpuProgramManager : public Module<GpuProgramManager>
 	{
 	public:
-		/**
-		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
-		 * GpuProgram::isCompiled() method on the returned program will return false, and you will be able to retrieve the 
-		 * error message via GpuProgram::getCompileErrorMessage().
-		 *
-		 * @param[in]	source				Source code to compile the shader from.
-		 * @param[in]	entryPoint			Name of the entry point function, for example "main".
-		 * @param[in]	language			Language the source is written in, for example "hlsl" or "glsl".
-		 * @param[in]	gptype				Type of the program, for example vertex or fragment.
-		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
-		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
-		 *									program.
-		 */
-		SPtr<GpuProgram> create(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool requiresAdjacency = false);
+		/** @copydoc GpuProgram::create */
+		SPtr<GpuProgram> create(const GPU_PROGRAM_DESC& desc);
 
 		/**
 		 * Creates a completely empty and uninitialized GpuProgram. Should only be used for specific purposes, like 
@@ -101,21 +76,8 @@ namespace BansheeEngine
 		/** Query if a GPU program language is supported (for example "hlsl", "glsl"). */
 		bool isLanguageSupported(const String& lang);
 
-		/**
-		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
-		 * GpuProgramCore::isCompiled() method on the returned program will return false, and you will be able to retrieve 
-		 * the error message via GpuProgramCore::getCompileErrorMessage().
-		 *
-		 * @param[in]	source				Source code to compile the shader from.
-		 * @param[in]	entryPoint			Name of the entry point function, for example "main".
-		 * @param[in]	language			Language the source is written in, for example "hlsl" or "glsl".
-		 * @param[in]	gptype				Type of the program, for example vertex or fragment.
-		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
-		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
-		 *									program.
-		 */
-		SPtr<GpuProgramCore> create(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool requiresAdjacency = false);
+		/** @copydoc GpuProgramCore::create */
+		SPtr<GpuProgramCore> create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
 		friend class GpuProgram;
@@ -125,8 +87,7 @@ namespace BansheeEngine
 		 *
 		 * @see		create
 		 */
-		SPtr<GpuProgramCore> createInternal(const String& source, const String& entryPoint, const String& language,
-			GpuProgramType gptype, GpuProgramProfile profile, bool requiresAdjacency = false);
+		SPtr<GpuProgramCore> createInternal(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 		/** Attempts to find a factory for the specified language. Returns null if it cannot find one. */
 		GpuProgramFactory* getFactory(const String& language);

+ 4 - 4
Source/BansheeCore/Include/BsHardwareBuffer.h

@@ -34,7 +34,7 @@ namespace BansheeEngine
 		virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options)
         {
             assert(!isLocked() && "Cannot lock this buffer, it is already locked!");
-            void* ret = lockImpl(offset, length, options);
+            void* ret = map(offset, length, options);
             mIsLocked = true;
 
 			mLockStart = offset;
@@ -59,7 +59,7 @@ namespace BansheeEngine
         {
             assert(isLocked() && "Cannot unlock this buffer, it is not locked!");
 
-            unlockImpl();
+            unmap();
             mIsLocked = false;
         }
 
@@ -142,10 +142,10 @@ namespace BansheeEngine
 		{  }
 
 		/** @copydoc lock */
-		virtual void* lockImpl(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
+		virtual void* map(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
 
 		/** @copydoc unlock */
-		virtual void unlockImpl() = 0;
+		virtual void unmap() = 0;
 
 	protected:
 		UINT32 mSizeInBytes;

+ 79 - 53
Source/BansheeCore/Include/BsHardwareBufferManager.h

@@ -10,6 +10,9 @@
 
 namespace BansheeEngine 
 {
+	struct GPU_BUFFER_DESC;
+	struct GPU_PARAMS_DESC;
+
 	/** @addtogroup RenderAPI-Internal
 	 *  @{
 	 */
@@ -29,23 +32,17 @@ namespace BansheeEngine
 		 * Creates a new vertex buffer used for holding number of vertices and other per-vertex data. Buffer can be bound 
 		 * to the pipeline and its data can be passed to the active vertex GPU program.
 		 *
-		 * @param[in]	vertexSize	Size of a single vertex in the buffer, in bytes.
-		 * @param[in]	numVerts	Number of vertices the buffer can hold.
-		 * @param[in]	usage		Usage that tells the hardware how will be buffer be used. 
-		 * @param[in]	streamOut	If true the buffer will be usable for streaming out data from the GPU.
+		 * @param[in]	desc	Description of the buffer to create.
 		 */
-		virtual SPtr<VertexBuffer> createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, 
-			bool streamOut = false);
+		SPtr<VertexBuffer> createVertexBuffer(const VERTEX_BUFFER_DESC& desc);
 
 		/**
 		 * Creates a new index buffer that holds indices referencing vertices in a vertex buffer. Indices are interpreted 
 		 * by the pipeline and vertices are drawn in the order specified in the index buffer.
 		 *
-		 * @param[in]	itype		Index type, determines size of an index.
-		 * @param[in]	numIndices	Number of indexes can buffer can hold.
-		 * @param[in]	usage		Usage that tells the hardware how will be buffer be used. 
+		 * @param[in]	desc	Description of the buffer to create.
 		 */
-		virtual SPtr<IndexBuffer> createIndexBuffer(IndexType itype, UINT32 numIndices, GpuBufferUsage usage);
+		SPtr<IndexBuffer> createIndexBuffer(const INDEX_BUFFER_DESC& desc);
 
 		/**
 		 * Creates an GPU parameter block that you can use for setting parameters for GPU programs. Parameter blocks may be
@@ -55,31 +52,29 @@ namespace BansheeEngine
 		 * @param[in]	size	Size of the parameter buffer in bytes.
 		 * @param[in]	usage	Usage that tells the hardware how will be buffer be used. 
 		 */
-		virtual SPtr<GpuParamBlockBuffer> createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
+		SPtr<GpuParamBlockBuffer> createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
 
 		/**
 		 * Creates a generic buffer that can be passed as a parameter to a GPU program. This type of buffer can hold various 
-		 * type of data and can be used for various purposes. See "GpuBufferType" for explanation of different buffer types.
-		 *
-		 * @param[in]	elementCount  	Number of elements in the buffer. 
-		 * @param[in]	elementSize   	Size of each individual element in the buffer, in bytes. Only needed if using
-		 *								non-standard buffer. If using standard buffer element size is calculated from
-		 *								format.
-		 * @param[in]	type		  	Type of the buffer.
-		 * @param[in]	format			Format if the data in the buffer. Only relevant for standard buffers.
-		 * @param[in]	usage		  	Usage that tells the hardware how will be buffer be used. 
-		 * @param[in]	randomGpuWrite	(optional) Allows the GPU to write to the resource.
-		 * @param[in]	useCounter	  	(optional) Binds a counter that can be used from a GPU program on the buffer.
+		 * type of data and can be used for various purposes. See GpuBufferType for explanation of different buffer types.
 		 *
-		 * @note	
-		 * Be aware that due to some render API restrictions some of these settings cannot be used together, and if so you 
-		 * will receive an assert in debug mode.
+		 * @param[in]	desc  	Description of the buffer to create.
+		 */
+		SPtr<GpuBuffer> createGpuBuffer(const GPU_BUFFER_DESC& desc);
+
+		/** 
+		 * Creates a new vertex declaration from a list of vertex elements. 
+		 * 
+		 * @param[in]	desc	Description of the object to create.
 		 */
-		virtual SPtr<GpuBuffer> createGpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		SPtr<VertexDeclaration> createVertexDeclaration(const SPtr<VertexDataDesc>& desc);
 
-		/** Creates a new vertex declaration from a list of vertex elements. */
-		virtual SPtr<VertexDeclaration> createVertexDeclaration(const SPtr<VertexDataDesc>& desc);
+		/** 
+		 * Creates a new GpuParams object from the provided set of GPU parameter descriptors.
+		 *  
+		 * @param[in]	desc	Description of the object to create.
+		 */
+		SPtr<GpuParams> createGpuParams(const GPU_PARAMS_DESC& desc);
 	};
 
 	/**
@@ -92,26 +87,52 @@ namespace BansheeEngine
     public:
 		virtual ~HardwareBufferCoreManager() { }
 
-		/** @copydoc HardwareBufferManager::createVertexBuffer */
-		virtual SPtr<VertexBufferCore> createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, 
-			bool streamOut = false);
+		/** 
+		 * @copydoc HardwareBufferManager::createVertexBuffer 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<VertexBufferCore> createVertexBuffer(const VERTEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
+
+		/** 
+		 * @copydoc HardwareBufferManager::createIndexBuffer 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<IndexBufferCore> createIndexBuffer(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
-		/** @copydoc HardwareBufferManager::createIndexBuffer */
-		virtual SPtr<IndexBufferCore> createIndexBuffer(IndexType itype, UINT32 numIndices, GpuBufferUsage usage);
+		/** 
+		 * @copydoc HardwareBufferManager::createVertexDeclaration 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<VertexDeclarationCore> createVertexDeclaration(const SPtr<VertexDataDesc>& desc,
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
-		/** @copydoc HardwareBufferManager::createVertexDeclaration */
-		virtual SPtr<VertexDeclarationCore> createVertexDeclaration(const SPtr<VertexDataDesc>& desc);
+		/**
+		 * Creates a new vertex declaration from a list of vertex elements.
+		 *
+		 * @param[in]	elements		List of elements to initialize the declaration with.
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<VertexDeclarationCore> createVertexDeclaration(const List<VertexElement>& elements, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
-		/** @copydoc HardwareBufferManager::createVertexDeclaration */
-		virtual SPtr<VertexDeclarationCore> createVertexDeclaration(const List<VertexElement>& elements);
+		/** 
+		 * @copydoc HardwareBufferManager::createGpuParamBlockBuffer 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<GpuParamBlockBufferCore> createGpuParamBlockBuffer(UINT32 size, 
+			GpuParamBlockUsage usage = GPBU_DYNAMIC, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
-		/** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
-		virtual SPtr<GpuParamBlockBufferCore> createGpuParamBlockBuffer(UINT32 size, 
-			GpuParamBlockUsage usage = GPBU_DYNAMIC);
+		/** 
+		 * @copydoc HardwareBufferManager::createGpuBuffer
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<GpuBufferCore> createGpuBuffer(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
-		/** @copydoc HardwareBufferManager::createGpuBuffer */
-		virtual SPtr<GpuBufferCore> createGpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		/** 
+		 * @copydoc HardwareBufferManager::createGpuParams 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<GpuParamsCore> createGpuParams(const GPU_PARAMS_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
 		friend class IndexBuffer;
@@ -124,23 +145,28 @@ namespace BansheeEngine
 		friend class GpuBufferCore;
 
 		/** @copydoc createVertexBuffer */
-		virtual SPtr<VertexBufferCore> createVertexBufferInternal(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, 
-			bool streamOut = false) = 0;
+		virtual SPtr<VertexBufferCore> createVertexBufferInternal(const VERTEX_BUFFER_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
 
 		/** @copydoc createIndexBuffer */
-		virtual SPtr<IndexBufferCore> createIndexBufferInternal(IndexType itype, UINT32 numIndices, 
-			GpuBufferUsage usage) = 0;
+		virtual SPtr<IndexBufferCore> createIndexBufferInternal(const INDEX_BUFFER_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
 
 		/** @copydoc createGpuParamBlockBuffer */
 		virtual SPtr<GpuParamBlockBufferCore> createGpuParamBlockBufferInternal(UINT32 size, 
-			GpuParamBlockUsage usage = GPBU_DYNAMIC) = 0;
+			GpuParamBlockUsage usage = GPBU_DYNAMIC, GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
 
 		/** @copydoc createGpuBuffer */
-		virtual SPtr<GpuBufferCore> createGpuBufferInternal(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false) = 0;
+		virtual SPtr<GpuBufferCore> createGpuBufferInternal(const GPU_BUFFER_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
+
+		/** @copydoc createVertexDeclaration(const List<VertexElement>&, GpuDeviceFlags) */
+		virtual SPtr<VertexDeclarationCore> createVertexDeclarationInternal(const List<VertexElement>& elements,
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
-		/** @copydoc createVertexDeclaration */
-		virtual SPtr<VertexDeclarationCore> createVertexDeclarationInternal(const List<VertexElement>& elements);
+		/** @copydoc createGpuParams */
+		virtual SPtr<GpuParamsCore> createGpuParamsInternal(const GPU_PARAMS_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 	};
 
 	/** @} */

+ 10 - 9
Source/BansheeCore/Include/BsIndexBuffer.h

@@ -12,11 +12,12 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
-	/**	Type of the indices used, used for determining size. */
-	enum IndexType 
+	/** Descriptor structure used for initialization of an IndexBuffer. */
+	struct INDEX_BUFFER_DESC
 	{
-		IT_16BIT, /**< 16-bit indices. */
-		IT_32BIT /**< 32-bit indices. */
+		IndexType indexType; /**< Index type, determines the size of a single index. */
+		UINT32 numIndices; /**< Number of indices can buffer can hold. */
+		GpuBufferUsage usage = GBU_STATIC; /**< Usage that tells the hardware how will be buffer be used. */
 	};
 
 	/**	Contains information about an index buffer. */
@@ -60,12 +61,12 @@ namespace BansheeEngine
 		SPtr<IndexBufferCore> getCore() const;
 
 		/** @copydoc HardwareBufferManager::createIndexBuffer */
-		static SPtr<IndexBuffer> create(IndexType itype, UINT32 numIndices, GpuBufferUsage usage = GBU_STATIC);
+		static SPtr<IndexBuffer> create(const INDEX_BUFFER_DESC& desc);
 
 	protected:
 		friend class HardwareBufferManager;
 
-		IndexBuffer(IndexType idxType, UINT32 numIndexes, GpuBufferUsage usage);
+		IndexBuffer(const INDEX_BUFFER_DESC& desc);
 
 		/** @copydoc CoreObject::createCore */
 		virtual SPtr<CoreObjectCore> createCore() const;
@@ -84,14 +85,14 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT IndexBufferCore : public CoreObjectCore, public HardwareBuffer
 	{
 	public:
-		IndexBufferCore(IndexType idxType, UINT32 numIndices, GpuBufferUsage usage);
+		IndexBufferCore(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 		virtual ~IndexBufferCore() { }
 
 		/**	Returns information about the index buffer. */
 		const IndexBufferProperties& getProperties() const { return mProperties; }
 
-		/** @copydoc HardwareBufferManager::createIndexBuffer */
-		static SPtr<IndexBufferCore> create(IndexType itype, UINT32 numIndices, GpuBufferUsage usage = GBU_STATIC);
+		/** @copydoc HardwareBufferCoreManager::createIndexBuffer */
+		static SPtr<IndexBufferCore> create(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
 		IndexBufferProperties mProperties;

+ 13 - 7
Source/BansheeCore/Include/BsMesh.h

@@ -6,7 +6,6 @@
 #include "BsMeshBase.h"
 #include "BsMeshData.h"
 #include "BsVertexData.h"
-#include "BsDrawOps.h"
 #include "BsSubMesh.h"
 #include "BsBounds.h"
 
@@ -283,7 +282,7 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT MeshCore : public MeshCoreBase
 	{
 	public:
-		MeshCore(const SPtr<MeshData>& initialMeshData, const MESH_DESC& desc);
+		MeshCore(const SPtr<MeshData>& initialMeshData, const MESH_DESC& desc, GpuDeviceFlags deviceMask);
 
 		~MeshCore();
 
@@ -342,16 +341,19 @@ namespace BansheeEngine
 		 *								option is a triangle list, where three indices represent a single triangle.
 		 * @param[in]	indexType		Size of indices, use smaller size for better performance, however be careful not to
 		 *								go over the number of vertices limited by the size.
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
 		 */
 		static SPtr<MeshCore> create(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc, 
-			int usage = MU_STATIC, DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT);
+			int usage = MU_STATIC, DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 		/**
 		 * Creates a new empty mesh. 
 		 *
-		 * @param[in]	desc	Descriptor containing the properties of the mesh to create.
+		 * @param[in]	desc			Descriptor containing the properties of the mesh to create.
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
 		 */
-		static SPtr<MeshCore> create(const MESH_DESC& desc);
+		static SPtr<MeshCore> create(const MESH_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 		/**
 		 * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
@@ -361,8 +363,10 @@ namespace BansheeEngine
 		 * @param[in]	desc			Descriptor containing the properties of the mesh to create. Vertex and index count,
 		 *								vertex descriptor and index type properties are ignored and are read from provided
 		 *								mesh data instead.
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
 		 */
-		static SPtr<MeshCore> create(const SPtr<MeshData>& initialData, const MESH_DESC& desc);
+		static SPtr<MeshCore> create(const SPtr<MeshData>& initialData, const MESH_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 		/**
 		 * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
@@ -372,9 +376,10 @@ namespace BansheeEngine
 		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
 		 * @param[in]	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default 
 		 *								option is a triangle strip, where three indices represent a single triangle.
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
 		 */
 		static SPtr<MeshCore> create(const SPtr<MeshData>& initialData, int usage = MU_STATIC,
-			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 	protected:
 		friend class Mesh;
@@ -388,6 +393,7 @@ namespace BansheeEngine
 		SPtr<VertexDataDesc> mVertexDesc;
 		int mUsage;
 		IndexType mIndexType;
+		GpuDeviceFlags mDeviceMask;
 		SPtr<MeshData> mTempInitialMeshData;
 		SPtr<Skeleton> mSkeleton; // Immutable
 		SPtr<MorphShapes> mMorphShapes; // Immutable

+ 0 - 1
Source/BansheeCore/Include/BsMeshBase.h

@@ -5,7 +5,6 @@
 #include "BsCorePrerequisites.h"
 #include "BsResource.h"
 #include "BsBounds.h"
-#include "BsDrawOps.h"
 #include "BsSubMesh.h"
 
 namespace BansheeEngine

+ 0 - 1
Source/BansheeCore/Include/BsMeshData.h

@@ -7,7 +7,6 @@
 #include "BsVertexBuffer.h"
 #include "BsIndexBuffer.h"
 #include "BsVertexDeclaration.h"
-#include "BsDrawOps.h"
 #include "BsSubMesh.h"
 #include "BsBounds.h"
 

Некоторые файлы не были показаны из-за большого количества измененных файлов