Forráskód Böngészése

Updated docs to so they reflect the GPU parameter design changes

BearishSun 9 éve
szülő
commit
426fffb882

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

@@ -30,23 +30,27 @@ SPtr<GpuProgram> myProgram = GpuProgram::create(hlslSource, "main", "hlsl", GPT_
 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.
 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}
 # 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}
 ## 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:
 For example to assign a texture and a 2D vector as input to the program we created earlier:
 ~~~~~~~~~~~~~{.cpp}
 ~~~~~~~~~~~~~{.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;
 GpuParamVec2 myVectorParam;
 GpuParamTexture myTextureParam;
 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));
 myVectorParam.set(Vector2(1, 2));
 myTextureParam.set(myTexture); // Assuming we created "myTexture" earlier.
 myTextureParam.set(myTexture); // Assuming we created "myTexture" earlier.
@@ -54,14 +58,12 @@ 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.
 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 assigning it to a @ref BansheeEngine::GpuPipelineState "GpuPipelineState" and calling @ref BansheeEngine::RenderAPICore::setGraphicsPipeline "RenderAPICore::setGraphicsPipeline". Or alternatively if using compute programs you can bind by calling @ref BansheeEngine::RenderAPICore::setComputePipeline "RenderAPICore::setComputePipeline". Any subsequent draw/dispatch calls will then use the bound GPU programs. 
-
-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.
 
 
 Much more detailed information about rendering is provided in the [render API manual](@ref renderAPI).
 Much more detailed information about rendering is provided in the [render API manual](@ref renderAPI).
 
 

+ 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.
 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.
 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:
 To create a technique call @ref BansheeEngine::Technique::create "Technique::create" and provide it with:
  - One or multiple passes
  - 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`.
  - 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.
  - An optional list of tags that allows renderer to pick which technique to use when rendering objects. Can be left empty in most cases.
 
 

+ 83 - 49
Documentation/Manuals/Native/renderAPI.md

@@ -8,7 +8,7 @@ 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. 
 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
  - Create and bind a render target
   - Set up a viewport (if rendering to a part of 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)
   - Clear render target (if we're re-using a render target)
@@ -16,10 +16,7 @@ To render something using this API you need to:
    - Create and bind vertex/fragment GPU programs
    - Create and bind vertex/fragment GPU programs
    - Create and bind depth stencil, blend and/or rasterizer states (optionally)
    - Create and bind depth stencil, blend and/or rasterizer states (optionally)
    - Create and bind geometry/hull/domain GPU program (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 vertices
   - Create and bind the vertex declaration
   - Create and bind the vertex declaration
   - Create and bind the vertex buffer
   - Create and bind the vertex buffer
@@ -76,6 +73,13 @@ SPtr<GpuPipelineStateCore> state = GpuPipelineStateCore::create(desc);
 
 
 Once created the pipeline can be bound for rendering by calling @ref BansheeEngine::RenderAPICore::setGraphicsPipeline "RenderAPICore::setGraphicsPipeline".
 Once created the pipeline can be bound for rendering by calling @ref BansheeEngine::RenderAPICore::setGraphicsPipeline "RenderAPICore::setGraphicsPipeline".
 
 
+~~~~~~~~~~~~~{.cpp}
+// Bind pipeline for use (continued from above)
+
+RenderAPICore& rapi = RenderAPICore::instance();
+rapi.setGraphicsPipeline(state);
+~~~~~~~~~~~~~
+
 We continue below with explanation on how to create fixed and programmable states required to initialize GpuPipelineStateCore.
 We continue below with explanation on how to create fixed and programmable states required to initialize GpuPipelineStateCore.
 
 
 ## Fixed pipeline states {#renderAPI_b_a}
 ## Fixed pipeline states {#renderAPI_b_a}
@@ -89,68 +93,72 @@ States can be created by:
 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.
 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.
 
 
 ## GPU programs {#renderAPI_b_b}
 ## 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. GPU programs are explained in their own [manual](@ref gpuPrograms).
+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).
 
 
-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. 
- 
-### 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. 
+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.
 
 
-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".
+~~~~~~~~~~~~~{.cpp}
+... assuming vertex/fragment programs are created ...
 
 
-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.
+GPU_PARAMS_DESC desc;
+desc.vertexParams = vertProgram->getParamDesc();
+desc.fragmentParams = fragProgram->getParamDesc();
 
 
-An example binding a texture and its sampler state:
-~~~~~~~~~~~~~{.cpp}
+SPtr<GpuParamsCore> params = GpuParamsCore::create(desc);
 
 
-// Use nearest neighbor filtering when sampling
-SAMPLER_STATE_DESC ssDesc;
-ssDesc.magFilter = FO_POINT;
-ssDesc.minFilter = FO_POINT;
-ssDesc.mipFilter = FO_POINT;
+// Retrieve GPU param handles we can then read/write to
+GpuParamVec2Core myVectorParam;
+GpuParamTextureCore myTextureParam;
 
 
-SPtr<SamplerStateCore> mySamplerState = SamplerStateCore::create(ssDesc);
-SPtr<TextureCore> myTexture = ...;
+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();
 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}
 ~~~~~~~~~~~~~{.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);
 
 
 ~~~~~~~~~~~~~
 ~~~~~~~~~~~~~
 
 
@@ -237,11 +245,11 @@ Use @ref BansheeEngine::RenderAPICore::setComputePipeline "RenderAPICore::setCom
 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:
 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}
 ~~~~~~~~~~~~~{.cpp}
 SPtr<GpuProgramCore> computeProgram = ...;
 SPtr<GpuProgramCore> computeProgram = ...;
-SPtr<TextureCore> loadStoreTexture = ...;
+SPtr<GpuParamsCore> computeGpuParams = ...;
 
 
 RenderAPICore& rapi = RenderAPICore::instance();
 RenderAPICore& rapi = RenderAPICore::instance();
 rapi.setComputePipeline(computeProgram);
 rapi.setComputePipeline(computeProgram);
-rapi.setLoadStoreTexture(GPT_COMPUTE_PROGRAM, 0, true, loadStoreTexture, TextureSurface(0, 0));
+rapi.setGpuParams(computeGpuParams);
 rapi.dispatchCompute(512, 512);
 rapi.dispatchCompute(512, 512);
 
 
 ... read from our texture to get the result ...
 ... read from our texture to get the result ...
@@ -254,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. 
 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);
+~~~~~~~~~~~~~

+ 12 - 3
Documentation/Manuals/Native/textures.md

@@ -24,7 +24,7 @@ HTexture texture = Texture::create(TEX_TYPE_2D, 128, 128, 0, PF_R8G8B8A8);
 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.
 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} 
 # 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}
 # 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.
 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 +46,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.
 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}
 # 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}
 # 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.
 A texture is a @ref BansheeEngine::Resource "Resource" and can be saved/loaded like any other. See the [resource](@ref resources) manual.
@@ -56,4 +58,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.
 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.

+ 8 - 9
Source/BansheeCore/Include/BsGpuParams.h

@@ -94,11 +94,6 @@ namespace BansheeEngine
 		virtual void _markResourcesDirty() { }
 		virtual void _markResourcesDirty() { }
 
 
 	protected:
 	protected:
-		/**
-		 * Creates new GpuParams object using the specified parameter descriptions.
-		 *
-		 * @param[in]	desc	Object containing parameter descriptions for all relevant GPU program stages.
-		 */
 		GpuParamsBase(const GPU_PARAMS_DESC& desc);
 		GpuParamsBase(const GPU_PARAMS_DESC& desc);
 
 
 		/**	Gets a descriptor for a data parameter with the specified name. */
 		/**	Gets a descriptor for a data parameter with the specified name. */
@@ -267,13 +262,13 @@ namespace BansheeEngine
 	public:
 	public:
 		~GpuParamsCore() { }
 		~GpuParamsCore() { }
 
 
-		/** @copydoc GpuParamsBase::GpuParamsBase */
+		/** @copydoc GpuParams::create */
 		static SPtr<GpuParamsCore> create(const GPU_PARAMS_DESC& desc);
 		static SPtr<GpuParamsCore> create(const GPU_PARAMS_DESC& desc);
 
 
 	protected:
 	protected:
 		friend class GpuParams;
 		friend class GpuParams;
 
 
-		/** @copydoc GpuParamsBase::GpuParamsBase */
+		/** @copydoc GpuParams::create */
 		GpuParamsCore(const GPU_PARAMS_DESC& desc);
 		GpuParamsCore(const GPU_PARAMS_DESC& desc);
 
 
 		/** @copydoc CoreObject::getThisPtr */
 		/** @copydoc CoreObject::getThisPtr */
@@ -303,7 +298,11 @@ namespace BansheeEngine
 		/** Retrieves a core implementation of a mesh usable only from the core thread. */
 		/** Retrieves a core implementation of a mesh usable only from the core thread. */
 		SPtr<GpuParamsCore> getCore() const;
 		SPtr<GpuParamsCore> getCore() const;
 
 
-		/** @copydoc GpuParamsBase::GpuParamsBase */
+		/**
+		 * 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);
 		static SPtr<GpuParams> create(const GPU_PARAMS_DESC& desc);
 
 
 		/** Contains a lookup table for sizes of all data parameters. Sizes are in bytes. */
 		/** Contains a lookup table for sizes of all data parameters. Sizes are in bytes. */
@@ -321,7 +320,7 @@ namespace BansheeEngine
 
 
 		/** @} */
 		/** @} */
 	protected:
 	protected:
-		/** @copydoc GpuParamsBase::GpuParamsBase */
+		/** @copydoc GpuParams::create */
 		GpuParams(const GPU_PARAMS_DESC& desc);
 		GpuParams(const GPU_PARAMS_DESC& desc);
 
 
 		/** @copydoc CoreObject::getThisPtr */
 		/** @copydoc CoreObject::getThisPtr */