|
|
@@ -1,7 +1,10 @@
|
|
|
#pragma once
|
|
|
|
|
|
#include "CmPrerequisites.h"
|
|
|
+#include "CmDeferredRenderContextFwd.h"
|
|
|
#include "CmCommonEnums.h"
|
|
|
+#include "CmRenderSystem.h"
|
|
|
+#include "CmCommandQueue.h"
|
|
|
#include "CmSamplerState.h"
|
|
|
#include "CmGpuProgram.h"
|
|
|
#include "CmColor.h"
|
|
|
@@ -10,93 +13,205 @@ namespace CamelotFramework
|
|
|
{
|
|
|
/**
|
|
|
* @brief Deferred render context allows you to execute RenderSystem commands outside of the render thread.
|
|
|
- * DeferredRenderContext cannot be shared between threads. It must be created and used on the threat that created it.
|
|
|
*
|
|
|
* @note All commands are queued and only executed after the call to submitToGpu, in the order they were called.
|
|
|
*/
|
|
|
+ template <class CommandQueueSyncPolicy = CommandQueueNoSync>
|
|
|
class CM_EXPORT DeferredRenderContext
|
|
|
{
|
|
|
public:
|
|
|
- DeferredRenderContext(RenderSystem* rs, CM_THREAD_ID_TYPE threadId);
|
|
|
- ~DeferredRenderContext();
|
|
|
+ /**
|
|
|
+ * @brief Constructor.
|
|
|
+ *
|
|
|
+ * @param rs Render system to be used by the context.
|
|
|
+ * @param threadId Identifier for the thread that created the context.
|
|
|
+ * @param syncedAccess If false, the deferred render context can only be safely accessed from the thread that created it.
|
|
|
+ * If true, deferred render context can be accessed from any thread safely, however there will be a slight performance
|
|
|
+ * hit due to synchronization. In most cases you will want not to use synced access and instead create a separate context
|
|
|
+ * for specific threads.
|
|
|
+ */
|
|
|
+ DeferredRenderContext(RenderSystem* rs, CM_THREAD_ID_TYPE threadId)
|
|
|
+ :mRenderSystem(rs)
|
|
|
+ {
|
|
|
+ assert(mRenderSystem != nullptr);
|
|
|
+
|
|
|
+ mCommandQueue = CM_NEW(CommandQueue<CommandQueueSyncPolicy>, GenAlloc) CommandQueue<CommandQueueSyncPolicy>(threadId);
|
|
|
+ }
|
|
|
+
|
|
|
+ ~DeferredRenderContext()
|
|
|
+ {
|
|
|
+ CM_DELETE(mCommandQueue, CommandQueue<CommandQueueSyncPolicy>, GenAlloc);
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::disableTextureUnit() */
|
|
|
- void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit);
|
|
|
+ void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::disableTextureUnit, mRenderSystem, gptype, texUnit));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setPointParameters() */
|
|
|
void setPointParameters(float size, bool attenuationEnabled, float constant, float linear, float quadratic, float minSize, float maxSize);
|
|
|
|
|
|
/** @copydoc RenderSystem::setTexture() */
|
|
|
- void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
|
|
|
+ void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setTexture, mRenderSystem, gptype, unit, enabled, texPtr));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setSamplerState() */
|
|
|
- void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerStatePtr& samplerState);
|
|
|
+ void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerStatePtr& samplerState)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setSamplerState, mRenderSystem, gptype, texUnit, samplerState));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setBlendState() */
|
|
|
- void setBlendState(const BlendStatePtr& blendState);
|
|
|
+ void setBlendState(const BlendStatePtr& blendState)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setBlendState, mRenderSystem, blendState));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setRasterizerState() */
|
|
|
- void setRasterizerState(const RasterizerStatePtr& rasterizerState);
|
|
|
+ void setRasterizerState(const RasterizerStatePtr& rasterizerState)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setRasterizerState, mRenderSystem, rasterizerState));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setRasterizerState() */
|
|
|
- void setDepthStencilState(const DepthStencilStatePtr& depthStencilState, UINT32 stencilRefValue);
|
|
|
+ void setDepthStencilState(const DepthStencilStatePtr& depthStencilState, UINT32 stencilRefValue)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setDepthStencilState, mRenderSystem, depthStencilState, stencilRefValue));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setViewport() */
|
|
|
- void setViewport(ViewportPtr& vp);
|
|
|
+ void setViewport(ViewportPtr& vp)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, mRenderSystem, vp));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setVertexBuffer() */
|
|
|
- void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer);
|
|
|
+ void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setVertexBuffer, mRenderSystem, index, buffer));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setIndexBuffer() */
|
|
|
- void setIndexBuffer(const IndexBufferPtr& buffer);
|
|
|
+ void setIndexBuffer(const IndexBufferPtr& buffer)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setIndexBuffer, mRenderSystem, buffer));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setVertexDeclaration() */
|
|
|
- void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration);
|
|
|
+ void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setVertexDeclaration, mRenderSystem, vertexDeclaration));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setDrawOperation() */
|
|
|
- void setDrawOperation(DrawOperationType op);
|
|
|
+ void setDrawOperation(DrawOperationType op)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setDrawOperation, mRenderSystem, op));
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/** @copydoc RenderSystem::setClipPlanes() */
|
|
|
- void setClipPlanes(const PlaneList& clipPlanes);
|
|
|
+ void setClipPlanes(const PlaneList& clipPlanes)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setClipPlanes, mRenderSystem, clipPlanes));
|
|
|
+ }
|
|
|
+
|
|
|
/** @copydoc RenderSystem::addClipPlane(const Plane&) */
|
|
|
- void addClipPlane(const Plane& p);
|
|
|
+ void addClipPlane(const Plane& p)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::addClipPlane, mRenderSystem, p));
|
|
|
+ }
|
|
|
+
|
|
|
/** @copydoc RenderSystem::addClipPlane(float, float, float, float) */
|
|
|
- void addClipPlane(float A, float B, float C, float D);
|
|
|
+ void addClipPlane(float A, float B, float C, float D)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::addClipPlane, mRenderSystem, A, B, C, D));
|
|
|
+ }
|
|
|
+
|
|
|
/** @copydoc RenderSystem::resetClipPlanes() */
|
|
|
- void resetClipPlanes();
|
|
|
+ void resetClipPlanes()
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::resetClipPlanes, mRenderSystem));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::setScissorTest() */
|
|
|
- void setScissorTest(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600);
|
|
|
+ void setScissorTest(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setScissorRect, mRenderSystem, left, top, right, bottom));
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/** @copydoc RenderSystem::setRenderTarget() */
|
|
|
- void setRenderTarget(RenderTargetPtr target);
|
|
|
+ void setRenderTarget(RenderTargetPtr target)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::setRenderTarget, mRenderSystem, target));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::bindGpuProgram() */
|
|
|
- void bindGpuProgram(HGpuProgram prg);
|
|
|
+ void bindGpuProgram(HGpuProgram prg)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::bindGpuProgram, mRenderSystem, prg));
|
|
|
+ }
|
|
|
+
|
|
|
/** @copydoc RenderSystem::unbindGpuProgram() */
|
|
|
- void unbindGpuProgram(GpuProgramType gptype);
|
|
|
+ void unbindGpuProgram(GpuProgramType gptype)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::unbindGpuProgram, mRenderSystem, gptype));
|
|
|
+ }
|
|
|
+
|
|
|
/** @copydoc RenderSystem::bindGpuParams() */
|
|
|
- void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params);
|
|
|
+ void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::bindGpuParams, mRenderSystem, gptype, params));
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/** @copydoc RenderSystem::beginFrame() */
|
|
|
- void beginFrame(void);
|
|
|
+ void beginFrame(void)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::beginFrame, mRenderSystem));
|
|
|
+ }
|
|
|
+
|
|
|
/** @copydoc RenderSystem::endFrame() */
|
|
|
- void endFrame(void);
|
|
|
+ void endFrame(void)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::endFrame, mRenderSystem));
|
|
|
+ }
|
|
|
+
|
|
|
+ /** @copydoc RenderSystem::clear() */
|
|
|
+ void clear(RenderTargetPtr target, unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::clear, mRenderSystem, target, buffers, color, depth, stencil));
|
|
|
+ }
|
|
|
+
|
|
|
+ /** @copydoc RenderSystem::swapBuffers() */
|
|
|
+ void swapBuffers(RenderTargetPtr target)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::swapBuffers, mRenderSystem, target));
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/** @copydoc RenderSystem::render() */
|
|
|
- void render(const RenderOperation& op);
|
|
|
+ void render(const RenderOperation& op)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::render, mRenderSystem, op));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::draw() */
|
|
|
- void draw(UINT32 vertexCount);
|
|
|
+ void draw(UINT32 vertexCount)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::draw, mRenderSystem, vertexCount));
|
|
|
+ }
|
|
|
|
|
|
/** @copydoc RenderSystem::drawIndexed() */
|
|
|
- void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexCount);
|
|
|
+ void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexCount)
|
|
|
+ {
|
|
|
+ mCommandQueue->queue(boost::bind(&RenderSystem::drawIndexed, mRenderSystem, startIndex, indexCount, vertexCount));
|
|
|
+ }
|
|
|
|
|
|
- /** @copydoc RenderSystem::clear() */
|
|
|
- void clear(RenderTargetPtr target, unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0);
|
|
|
-
|
|
|
- /** @copydoc RenderSystem::swapBuffers() */
|
|
|
- void swapBuffers(RenderTargetPtr target);
|
|
|
|
|
|
/**
|
|
|
* @copydoc RenderSystem::writeSubresource()
|
|
|
@@ -105,7 +220,12 @@ namespace CamelotFramework
|
|
|
* Until the async operation completes "data" is owned by the render thread and you won't
|
|
|
* be able to access it.
|
|
|
*/
|
|
|
- AsyncOp writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceData& data);
|
|
|
+ AsyncOp writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceData& data)
|
|
|
+ {
|
|
|
+ data.lock();
|
|
|
+
|
|
|
+ return mCommandQueue->queueReturn(boost::bind(&RenderSystem::writeSubresource, mRenderSystem, resource, subresourceIdx, boost::cref(data), _1));
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* @copydoc RenderSystem::writeSubresource()
|
|
|
@@ -114,21 +234,35 @@ namespace CamelotFramework
|
|
|
* Until the async operation completes "data" is owned by the render thread and you won't
|
|
|
* be able to access it.
|
|
|
*/
|
|
|
- AsyncOp readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceData& data);
|
|
|
+ AsyncOp readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceData& data)
|
|
|
+ {
|
|
|
+ data.lock();
|
|
|
+
|
|
|
+ return mCommandQueue->queueReturn(boost::bind(&RenderSystem::readSubresource, mRenderSystem, resource, subresourceIdx, boost::ref(data), _1));
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* @brief Makes all the currently queued commands available to the GPU. They will be executed
|
|
|
* as soon as the render thread is ready.
|
|
|
*/
|
|
|
- void submitToGpu();
|
|
|
+ void submitToGpu(bool blockUntilComplete = false)
|
|
|
+ {
|
|
|
+ std::queue<QueuedCommand>* commands = mCommandQueue->flush();
|
|
|
+
|
|
|
+ RenderSystem* rs = RenderSystem::instancePtr();
|
|
|
+ rs->queueCommand(boost::bind(&CommandQueueBase::playback, mCommandQueue, commands), blockUntilComplete);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* @brief Cancels all commands in the queue.
|
|
|
*/
|
|
|
- void cancelAll();
|
|
|
+ void cancelAll()
|
|
|
+ {
|
|
|
+ mCommandQueue->cancelAll();
|
|
|
+ }
|
|
|
|
|
|
private:
|
|
|
- CommandQueue* mCommandQueue;
|
|
|
+ CommandQueue<CommandQueueSyncPolicy>* mCommandQueue;
|
|
|
RenderSystem* mRenderSystem;
|
|
|
};
|
|
|
}
|