CmDeferredRenderContext.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmDeferredRenderContextFwd.h"
  4. #include "CmCommonEnums.h"
  5. #include "CmRenderSystem.h"
  6. #include "CmCommandQueue.h"
  7. #include "CmSamplerState.h"
  8. #include "CmGpuProgram.h"
  9. #include "CmColor.h"
  10. namespace CamelotFramework
  11. {
  12. /**
  13. * @brief Deferred render context allows you to execute RenderSystem commands outside of the render thread.
  14. *
  15. * @note All commands are queued and only executed after the call to submitToGpu, in the order they were called.
  16. */
  17. template <class CommandQueueSyncPolicy = CommandQueueNoSync>
  18. class CM_EXPORT DeferredRenderContext
  19. {
  20. public:
  21. /**
  22. * @brief Constructor.
  23. *
  24. * @param rs Render system to be used by the context.
  25. * @param threadId Identifier for the thread that created the context.
  26. * @param syncedAccess If false, the deferred render context can only be safely accessed from the thread that created it.
  27. * If true, deferred render context can be accessed from any thread safely, however there will be a slight performance
  28. * hit due to synchronization. In most cases you will want not to use synced access and instead create a separate context
  29. * for specific threads.
  30. */
  31. DeferredRenderContext(RenderSystem* rs, CM_THREAD_ID_TYPE threadId)
  32. :mRenderSystem(rs)
  33. {
  34. assert(mRenderSystem != nullptr);
  35. mCommandQueue = CM_NEW(CommandQueue<CommandQueueSyncPolicy>, GenAlloc) CommandQueue<CommandQueueSyncPolicy>(threadId);
  36. }
  37. ~DeferredRenderContext()
  38. {
  39. CM_DELETE(mCommandQueue, CommandQueue<CommandQueueSyncPolicy>, GenAlloc);
  40. }
  41. /** @copydoc RenderSystem::disableTextureUnit() */
  42. void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit)
  43. {
  44. mCommandQueue->queue(boost::bind(&RenderSystem::disableTextureUnit, mRenderSystem, gptype, texUnit));
  45. }
  46. /** @copydoc RenderSystem::setPointParameters() */
  47. void setPointParameters(float size, bool attenuationEnabled, float constant, float linear, float quadratic, float minSize, float maxSize);
  48. /** @copydoc RenderSystem::setTexture() */
  49. void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
  50. {
  51. mCommandQueue->queue(boost::bind(&RenderSystem::setTexture, mRenderSystem, gptype, unit, enabled, texPtr));
  52. }
  53. /** @copydoc RenderSystem::setSamplerState() */
  54. void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerStatePtr& samplerState)
  55. {
  56. mCommandQueue->queue(boost::bind(&RenderSystem::setSamplerState, mRenderSystem, gptype, texUnit, samplerState));
  57. }
  58. /** @copydoc RenderSystem::setBlendState() */
  59. void setBlendState(const BlendStatePtr& blendState)
  60. {
  61. mCommandQueue->queue(boost::bind(&RenderSystem::setBlendState, mRenderSystem, blendState));
  62. }
  63. /** @copydoc RenderSystem::setRasterizerState() */
  64. void setRasterizerState(const RasterizerStatePtr& rasterizerState)
  65. {
  66. mCommandQueue->queue(boost::bind(&RenderSystem::setRasterizerState, mRenderSystem, rasterizerState));
  67. }
  68. /** @copydoc RenderSystem::setRasterizerState() */
  69. void setDepthStencilState(const DepthStencilStatePtr& depthStencilState, UINT32 stencilRefValue)
  70. {
  71. mCommandQueue->queue(boost::bind(&RenderSystem::setDepthStencilState, mRenderSystem, depthStencilState, stencilRefValue));
  72. }
  73. /** @copydoc RenderSystem::setViewport() */
  74. void setViewport(ViewportPtr& vp)
  75. {
  76. mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, mRenderSystem, vp));
  77. }
  78. /** @copydoc RenderSystem::setVertexBuffer() */
  79. void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer)
  80. {
  81. mCommandQueue->queue(boost::bind(&RenderSystem::setVertexBuffer, mRenderSystem, index, buffer));
  82. }
  83. /** @copydoc RenderSystem::setIndexBuffer() */
  84. void setIndexBuffer(const IndexBufferPtr& buffer)
  85. {
  86. mCommandQueue->queue(boost::bind(&RenderSystem::setIndexBuffer, mRenderSystem, buffer));
  87. }
  88. /** @copydoc RenderSystem::setVertexDeclaration() */
  89. void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration)
  90. {
  91. mCommandQueue->queue(boost::bind(&RenderSystem::setVertexDeclaration, mRenderSystem, vertexDeclaration));
  92. }
  93. /** @copydoc RenderSystem::setDrawOperation() */
  94. void setDrawOperation(DrawOperationType op)
  95. {
  96. mCommandQueue->queue(boost::bind(&RenderSystem::setDrawOperation, mRenderSystem, op));
  97. }
  98. /** @copydoc RenderSystem::setClipPlanes() */
  99. void setClipPlanes(const PlaneList& clipPlanes)
  100. {
  101. mCommandQueue->queue(boost::bind(&RenderSystem::setClipPlanes, mRenderSystem, clipPlanes));
  102. }
  103. /** @copydoc RenderSystem::addClipPlane(const Plane&) */
  104. void addClipPlane(const Plane& p)
  105. {
  106. mCommandQueue->queue(boost::bind(&RenderSystem::addClipPlane, mRenderSystem, p));
  107. }
  108. /** @copydoc RenderSystem::addClipPlane(float, float, float, float) */
  109. void addClipPlane(float A, float B, float C, float D)
  110. {
  111. mCommandQueue->queue(boost::bind(&RenderSystem::addClipPlane, mRenderSystem, A, B, C, D));
  112. }
  113. /** @copydoc RenderSystem::resetClipPlanes() */
  114. void resetClipPlanes()
  115. {
  116. mCommandQueue->queue(boost::bind(&RenderSystem::resetClipPlanes, mRenderSystem));
  117. }
  118. /** @copydoc RenderSystem::setScissorTest() */
  119. void setScissorTest(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600)
  120. {
  121. mCommandQueue->queue(boost::bind(&RenderSystem::setScissorRect, mRenderSystem, left, top, right, bottom));
  122. }
  123. /** @copydoc RenderSystem::setRenderTarget() */
  124. void setRenderTarget(RenderTargetPtr target)
  125. {
  126. mCommandQueue->queue(boost::bind(&RenderSystem::setRenderTarget, mRenderSystem, target));
  127. }
  128. /** @copydoc RenderSystem::bindGpuProgram() */
  129. void bindGpuProgram(HGpuProgram prg)
  130. {
  131. mCommandQueue->queue(boost::bind(&RenderSystem::bindGpuProgram, mRenderSystem, prg));
  132. }
  133. /** @copydoc RenderSystem::unbindGpuProgram() */
  134. void unbindGpuProgram(GpuProgramType gptype)
  135. {
  136. mCommandQueue->queue(boost::bind(&RenderSystem::unbindGpuProgram, mRenderSystem, gptype));
  137. }
  138. /** @copydoc RenderSystem::bindGpuParams() */
  139. void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params)
  140. {
  141. mCommandQueue->queue(boost::bind(&RenderSystem::bindGpuParams, mRenderSystem, gptype, params));
  142. }
  143. /** @copydoc RenderSystem::beginFrame() */
  144. void beginFrame(void)
  145. {
  146. mCommandQueue->queue(boost::bind(&RenderSystem::beginFrame, mRenderSystem));
  147. }
  148. /** @copydoc RenderSystem::endFrame() */
  149. void endFrame(void)
  150. {
  151. mCommandQueue->queue(boost::bind(&RenderSystem::endFrame, mRenderSystem));
  152. }
  153. /** @copydoc RenderSystem::clear() */
  154. void clear(RenderTargetPtr target, unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0)
  155. {
  156. mCommandQueue->queue(boost::bind(&RenderSystem::clear, mRenderSystem, target, buffers, color, depth, stencil));
  157. }
  158. /** @copydoc RenderSystem::swapBuffers() */
  159. void swapBuffers(RenderTargetPtr target)
  160. {
  161. mCommandQueue->queue(boost::bind(&RenderSystem::swapBuffers, mRenderSystem, target));
  162. }
  163. /** @copydoc RenderSystem::render() */
  164. void render(const RenderOperation& op)
  165. {
  166. mCommandQueue->queue(boost::bind(&RenderSystem::render, mRenderSystem, op));
  167. }
  168. /** @copydoc RenderSystem::draw() */
  169. void draw(UINT32 vertexCount)
  170. {
  171. mCommandQueue->queue(boost::bind(&RenderSystem::draw, mRenderSystem, vertexCount));
  172. }
  173. /** @copydoc RenderSystem::drawIndexed() */
  174. void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexCount)
  175. {
  176. mCommandQueue->queue(boost::bind(&RenderSystem::drawIndexed, mRenderSystem, startIndex, indexCount, vertexCount));
  177. }
  178. /**
  179. * @copydoc RenderSystem::writeSubresource()
  180. *
  181. * @note Resource is updated with data from "data" parameter when the async operation completes.
  182. * Until the async operation completes "data" is owned by the render thread and you won't
  183. * be able to access it.
  184. */
  185. AsyncOp writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceData& data)
  186. {
  187. data.lock();
  188. return mCommandQueue->queueReturn(boost::bind(&RenderSystem::writeSubresource, mRenderSystem, resource, subresourceIdx, boost::cref(data), _1));
  189. }
  190. /**
  191. * @copydoc RenderSystem::writeSubresource()
  192. *
  193. * @note "data" parameter is populated with subresource data when the async operation completes.
  194. * Until the async operation completes "data" is owned by the render thread and you won't
  195. * be able to access it.
  196. */
  197. AsyncOp readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceData& data)
  198. {
  199. data.lock();
  200. return mCommandQueue->queueReturn(boost::bind(&RenderSystem::readSubresource, mRenderSystem, resource, subresourceIdx, boost::ref(data), _1));
  201. }
  202. /**
  203. * @brief Makes all the currently queued commands available to the GPU. They will be executed
  204. * as soon as the render thread is ready.
  205. */
  206. void submitToGpu(bool blockUntilComplete = false)
  207. {
  208. std::queue<QueuedCommand>* commands = mCommandQueue->flush();
  209. RenderSystem* rs = RenderSystem::instancePtr();
  210. rs->queueCommand(boost::bind(&CommandQueueBase::playback, mCommandQueue, commands), blockUntilComplete);
  211. }
  212. /**
  213. * @brief Cancels all commands in the queue.
  214. */
  215. void cancelAll()
  216. {
  217. mCommandQueue->cancelAll();
  218. }
  219. private:
  220. CommandQueue<CommandQueueSyncPolicy>* mCommandQueue;
  221. RenderSystem* mRenderSystem;
  222. };
  223. }