Batch.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/Ptr.h"
  24. #include "../Graphics/Drawable.h"
  25. #include "../Graphics/Material.h"
  26. #include "../Math/MathDefs.h"
  27. #include "../Math/Matrix3x4.h"
  28. #include "../Math/Rect.h"
  29. namespace Atomic
  30. {
  31. class Camera;
  32. class Drawable;
  33. class Geometry;
  34. class Light;
  35. class Material;
  36. class Matrix3x4;
  37. class Pass;
  38. class ShaderVariation;
  39. class Texture2D;
  40. class VertexBuffer;
  41. class View;
  42. class Zone;
  43. struct LightBatchQueue;
  44. /// Queued 3D geometry draw call.
  45. struct Batch
  46. {
  47. /// Construct with defaults.
  48. Batch() :
  49. isBase_(false),
  50. lightQueue_(0),
  51. // ATOMIC BEGIN
  52. lightmapTilingOffset_(0),
  53. lightmapTextureID_(0)
  54. // ATOMIC END
  55. {
  56. }
  57. /// Construct from a drawable's source batch.
  58. Batch(const SourceBatch& rhs) :
  59. distance_(rhs.distance_),
  60. renderOrder_(rhs.material_ ? rhs.material_->GetRenderOrder() : DEFAULT_RENDER_ORDER),
  61. isBase_(false),
  62. geometry_(rhs.geometry_),
  63. material_(rhs.material_),
  64. worldTransform_(rhs.worldTransform_),
  65. numWorldTransforms_(rhs.numWorldTransforms_),
  66. instancingData_(rhs.instancingData_),
  67. lightQueue_(0),
  68. geometryType_(rhs.geometryType_),
  69. // ATOMIC BEGIN
  70. lightmapTilingOffset_(rhs.lightmapTilingOffset_),
  71. lightmapTextureID_(rhs.lightmapTextureID_)
  72. // ATOMIC END
  73. {
  74. }
  75. /// Calculate state sorting key, which consists of base pass flag, light, pass and geometry.
  76. void CalculateSortKey();
  77. /// Prepare for rendering.
  78. void Prepare(View* view, Camera* camera, bool setModelTransform, bool allowDepthWrite) const;
  79. /// Prepare and draw.
  80. void Draw(View* view, Camera* camera, bool allowDepthWrite) const;
  81. /// State sorting key.
  82. unsigned long long sortKey_;
  83. /// Distance from camera.
  84. float distance_;
  85. /// 8-bit render order modifier from material.
  86. unsigned char renderOrder_;
  87. /// 8-bit light mask for stencil marking in deferred rendering.
  88. unsigned char lightMask_;
  89. /// Base batch flag. This tells to draw the object fully without light optimizations.
  90. bool isBase_;
  91. /// Geometry.
  92. Geometry* geometry_;
  93. /// Material.
  94. Material* material_;
  95. /// World transform(s). For a skinned model, these are the bone transforms.
  96. const Matrix3x4* worldTransform_;
  97. /// Number of world transforms.
  98. unsigned numWorldTransforms_;
  99. /// Per-instance data. If not null, must contain enough data to fill instancing buffer.
  100. void* instancingData_;
  101. /// Zone.
  102. Zone* zone_;
  103. /// Light properties.
  104. LightBatchQueue* lightQueue_;
  105. /// Material pass.
  106. Pass* pass_;
  107. /// Vertex shader.
  108. ShaderVariation* vertexShader_;
  109. /// Pixel shader.
  110. ShaderVariation* pixelShader_;
  111. /// %Geometry type.
  112. GeometryType geometryType_;
  113. // ATOMIC BEGIN
  114. Vector4* lightmapTilingOffset_;
  115. unsigned lightmapTextureID_;
  116. // ATOMIC END
  117. };
  118. /// Data for one geometry instance.
  119. struct InstanceData
  120. {
  121. /// Construct undefined.
  122. InstanceData()
  123. {
  124. }
  125. /// Construct with transform, instancing data and distance.
  126. InstanceData(const Matrix3x4* worldTransform, const void* instancingData, float distance) :
  127. worldTransform_(worldTransform),
  128. instancingData_(instancingData),
  129. distance_(distance)
  130. {
  131. }
  132. /// World transform.
  133. const Matrix3x4* worldTransform_;
  134. /// Instancing data buffer.
  135. const void* instancingData_;
  136. /// Distance from camera.
  137. float distance_;
  138. };
  139. /// Instanced 3D geometry draw call.
  140. struct BatchGroup : public Batch
  141. {
  142. /// Construct with defaults.
  143. BatchGroup() :
  144. startIndex_(M_MAX_UNSIGNED)
  145. {
  146. }
  147. /// Construct from a batch.
  148. BatchGroup(const Batch& batch) :
  149. Batch(batch),
  150. startIndex_(M_MAX_UNSIGNED)
  151. {
  152. }
  153. /// Destruct.
  154. ~BatchGroup()
  155. {
  156. }
  157. /// Add world transform(s) from a batch.
  158. void AddTransforms(const Batch& batch)
  159. {
  160. InstanceData newInstance;
  161. newInstance.distance_ = batch.distance_;
  162. newInstance.instancingData_ = batch.instancingData_;
  163. for (unsigned i = 0; i < batch.numWorldTransforms_; ++i)
  164. {
  165. newInstance.worldTransform_ = &batch.worldTransform_[i];
  166. instances_.Push(newInstance);
  167. }
  168. }
  169. /// Pre-set the instance data. Buffer must be big enough to hold all data.
  170. void SetInstancingData(void* lockedData, unsigned stride, unsigned& freeIndex);
  171. /// Prepare and draw.
  172. void Draw(View* view, Camera* camera, bool allowDepthWrite) const;
  173. /// Instance data.
  174. PODVector<InstanceData> instances_;
  175. /// Instance stream start index, or M_MAX_UNSIGNED if transforms not pre-set.
  176. unsigned startIndex_;
  177. };
  178. /// Instanced draw call grouping key.
  179. struct BatchGroupKey
  180. {
  181. /// Construct undefined.
  182. BatchGroupKey()
  183. {
  184. }
  185. /// Construct from a batch.
  186. BatchGroupKey(const Batch& batch) :
  187. zone_(batch.zone_),
  188. lightQueue_(batch.lightQueue_),
  189. pass_(batch.pass_),
  190. material_(batch.material_),
  191. geometry_(batch.geometry_),
  192. renderOrder_(batch.renderOrder_)
  193. {
  194. }
  195. /// Zone.
  196. Zone* zone_;
  197. /// Light properties.
  198. LightBatchQueue* lightQueue_;
  199. /// Material pass.
  200. Pass* pass_;
  201. /// Material.
  202. Material* material_;
  203. /// Geometry.
  204. Geometry* geometry_;
  205. /// 8-bit render order modifier from material.
  206. unsigned char renderOrder_;
  207. /// Test for equality with another batch group key.
  208. bool operator ==(const BatchGroupKey& rhs) const
  209. {
  210. return zone_ == rhs.zone_ && lightQueue_ == rhs.lightQueue_ && pass_ == rhs.pass_ && material_ == rhs.material_ &&
  211. geometry_ == rhs.geometry_ && renderOrder_ == rhs.renderOrder_;
  212. }
  213. /// Test for inequality with another batch group key.
  214. bool operator !=(const BatchGroupKey& rhs) const
  215. {
  216. return zone_ != rhs.zone_ || lightQueue_ != rhs.lightQueue_ || pass_ != rhs.pass_ || material_ != rhs.material_ ||
  217. geometry_ != rhs.geometry_ || renderOrder_ != rhs.renderOrder_;
  218. }
  219. /// Return hash value.
  220. unsigned ToHash() const;
  221. };
  222. /// Queue that contains both instanced and non-instanced draw calls.
  223. struct BatchQueue
  224. {
  225. public:
  226. /// Clear for new frame by clearing all groups and batches.
  227. void Clear(int maxSortedInstances);
  228. /// Sort non-instanced draw calls back to front.
  229. void SortBackToFront();
  230. /// Sort instanced and non-instanced draw calls front to back.
  231. void SortFrontToBack();
  232. /// Sort batches front to back while also maintaining state sorting.
  233. void SortFrontToBack2Pass(PODVector<Batch*>& batches);
  234. /// Pre-set instance data of all groups. The vertex buffer must be big enough to hold all data.
  235. void SetInstancingData(void* lockedData, unsigned stride, unsigned& freeIndex);
  236. /// Draw.
  237. void Draw(View* view, Camera* camera, bool markToStencil, bool usingLightOptimization, bool allowDepthWrite) const;
  238. /// Return the combined amount of instances.
  239. unsigned GetNumInstances() const;
  240. /// Return whether the batch group is empty.
  241. bool IsEmpty() const { return batches_.Empty() && batchGroups_.Empty(); }
  242. /// Instanced draw calls.
  243. HashMap<BatchGroupKey, BatchGroup> batchGroups_;
  244. /// Shader remapping table for 2-pass state and distance sort.
  245. HashMap<unsigned, unsigned> shaderRemapping_;
  246. /// Material remapping table for 2-pass state and distance sort.
  247. HashMap<unsigned short, unsigned short> materialRemapping_;
  248. /// Geometry remapping table for 2-pass state and distance sort.
  249. HashMap<unsigned short, unsigned short> geometryRemapping_;
  250. /// Unsorted non-instanced draw calls.
  251. PODVector<Batch> batches_;
  252. /// Sorted non-instanced draw calls.
  253. PODVector<Batch*> sortedBatches_;
  254. /// Sorted instanced draw calls.
  255. PODVector<BatchGroup*> sortedBatchGroups_;
  256. /// Maximum sorted instances.
  257. unsigned maxSortedInstances_;
  258. /// Whether the pass command contains extra shader defines.
  259. bool hasExtraDefines_;
  260. /// Vertex shader extra defines.
  261. String vsExtraDefines_;
  262. /// Pixel shader extra defines.
  263. String psExtraDefines_;
  264. /// Hash for vertex shader extra defines.
  265. StringHash vsExtraDefinesHash_;
  266. /// Hash for pixel shader extra defines.
  267. StringHash psExtraDefinesHash_;
  268. };
  269. /// Queue for shadow map draw calls
  270. struct ShadowBatchQueue
  271. {
  272. /// Shadow map camera.
  273. Camera* shadowCamera_;
  274. /// Shadow map viewport.
  275. IntRect shadowViewport_;
  276. /// Shadow caster draw calls.
  277. BatchQueue shadowBatches_;
  278. /// Directional light cascade near split distance.
  279. float nearSplit_;
  280. /// Directional light cascade far split distance.
  281. float farSplit_;
  282. };
  283. /// Queue for light related draw calls.
  284. struct LightBatchQueue
  285. {
  286. /// Per-pixel light.
  287. Light* light_;
  288. /// Light negative flag.
  289. bool negative_;
  290. /// Shadow map depth texture.
  291. Texture2D* shadowMap_;
  292. /// Lit geometry draw calls, base (replace blend mode)
  293. BatchQueue litBaseBatches_;
  294. /// Lit geometry draw calls, non-base (additive)
  295. BatchQueue litBatches_;
  296. /// Shadow map split queues.
  297. Vector<ShadowBatchQueue> shadowSplits_;
  298. /// Per-vertex lights.
  299. PODVector<Light*> vertexLights_;
  300. /// Light volume draw calls.
  301. PODVector<Batch> volumeBatches_;
  302. };
  303. }