Batch.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "../Container/Ptr.h"
  5. #include "../Graphics/Drawable.h"
  6. #include "../Graphics/Material.h"
  7. #include "../Math/MathDefs.h"
  8. #include "../Math/Matrix3x4.h"
  9. #include "../Math/Rect.h"
  10. namespace Urho3D
  11. {
  12. class Camera;
  13. class Drawable;
  14. class Geometry;
  15. class Light;
  16. class Material;
  17. class Matrix3x4;
  18. class Pass;
  19. class ShaderVariation;
  20. class Texture2D;
  21. class VertexBuffer;
  22. class View;
  23. class Zone;
  24. struct LightBatchQueue;
  25. /// Queued 3D geometry draw call.
  26. struct Batch
  27. {
  28. /// Construct with defaults.
  29. Batch() = default;
  30. /// Construct from a drawable's source batch.
  31. explicit Batch(const SourceBatch& rhs) :
  32. distance_(rhs.distance_),
  33. renderOrder_(rhs.material_ ? rhs.material_->GetRenderOrder() : DEFAULT_RENDER_ORDER),
  34. isBase_(false),
  35. geometry_(rhs.geometry_),
  36. material_(rhs.material_),
  37. worldTransform_(rhs.worldTransform_),
  38. numWorldTransforms_(rhs.numWorldTransforms_),
  39. instancingData_(rhs.instancingData_),
  40. lightQueue_(nullptr),
  41. geometryType_(rhs.geometryType_)
  42. {
  43. }
  44. /// Calculate state sorting key, which consists of base pass flag, light, pass and geometry.
  45. void CalculateSortKey();
  46. /// Prepare for rendering.
  47. void Prepare(View* view, Camera* camera, bool setModelTransform, bool allowDepthWrite) const;
  48. /// Prepare and draw.
  49. void Draw(View* view, Camera* camera, bool allowDepthWrite) const;
  50. /// State sorting key.
  51. hash64 sortKey_{};
  52. /// Distance from camera.
  53. float distance_{};
  54. /// 8-bit render order modifier from material.
  55. i8 renderOrder_{};
  56. /// 8-bit light mask for stencil marking in deferred rendering.
  57. unsigned char lightMask_{};
  58. /// Base batch flag. This tells to draw the object fully without light optimizations.
  59. bool isBase_{};
  60. /// Geometry.
  61. Geometry* geometry_{};
  62. /// Material.
  63. Material* material_{};
  64. /// World transform(s). For a skinned model, these are the bone transforms.
  65. const Matrix3x4* worldTransform_{};
  66. /// Number of world transforms.
  67. i32 numWorldTransforms_{};
  68. /// Per-instance data. If not null, must contain enough data to fill instancing buffer.
  69. void* instancingData_{};
  70. /// Zone.
  71. Zone* zone_{};
  72. /// Light properties.
  73. LightBatchQueue* lightQueue_{};
  74. /// Material pass.
  75. Pass* pass_{};
  76. /// Vertex shader.
  77. ShaderVariation* vertexShader_{};
  78. /// Pixel shader.
  79. ShaderVariation* pixelShader_{};
  80. /// %Geometry type.
  81. GeometryType geometryType_{};
  82. };
  83. /// Data for one geometry instance.
  84. struct InstanceData
  85. {
  86. /// Construct undefined.
  87. InstanceData() = default;
  88. /// Construct with transform, instancing data and distance.
  89. InstanceData(const Matrix3x4* worldTransform, const void* instancingData, float distance) :
  90. worldTransform_(worldTransform),
  91. instancingData_(instancingData),
  92. distance_(distance)
  93. {
  94. }
  95. /// World transform.
  96. const Matrix3x4* worldTransform_{};
  97. /// Instancing data buffer.
  98. const void* instancingData_{};
  99. /// Distance from camera.
  100. float distance_{};
  101. };
  102. /// Instanced 3D geometry draw call.
  103. struct BatchGroup : public Batch
  104. {
  105. /// Construct with defaults.
  106. BatchGroup() :
  107. startIndex_(NINDEX)
  108. {
  109. }
  110. /// Construct from a batch.
  111. explicit BatchGroup(const Batch& batch) :
  112. Batch(batch),
  113. startIndex_(NINDEX)
  114. {
  115. }
  116. /// Destruct.
  117. ~BatchGroup() = default;
  118. /// Add world transform(s) from a batch.
  119. void AddTransforms(const Batch& batch)
  120. {
  121. InstanceData newInstance;
  122. newInstance.distance_ = batch.distance_;
  123. newInstance.instancingData_ = batch.instancingData_;
  124. for (i32 i = 0; i < batch.numWorldTransforms_; ++i)
  125. {
  126. newInstance.worldTransform_ = &batch.worldTransform_[i];
  127. instances_.Push(newInstance);
  128. }
  129. }
  130. /// Pre-set the instance data. Buffer must be big enough to hold all data.
  131. void SetInstancingData(void* lockedData, i32 stride, i32& freeIndex);
  132. /// Prepare and draw.
  133. void Draw(View* view, Camera* camera, bool allowDepthWrite) const;
  134. /// Instance data.
  135. Vector<InstanceData> instances_;
  136. /// Instance stream start index, or NINDEX if transforms not pre-set.
  137. i32 startIndex_;
  138. };
  139. /// Instanced draw call grouping key.
  140. struct BatchGroupKey
  141. {
  142. /// Construct undefined.
  143. BatchGroupKey() = default;
  144. /// Construct from a batch.
  145. explicit BatchGroupKey(const Batch& batch) :
  146. zone_(batch.zone_),
  147. lightQueue_(batch.lightQueue_),
  148. pass_(batch.pass_),
  149. material_(batch.material_),
  150. geometry_(batch.geometry_),
  151. renderOrder_(batch.renderOrder_)
  152. {
  153. }
  154. /// Zone.
  155. Zone* zone_;
  156. /// Light properties.
  157. LightBatchQueue* lightQueue_;
  158. /// Material pass.
  159. Pass* pass_;
  160. /// Material.
  161. Material* material_;
  162. /// Geometry.
  163. Geometry* geometry_;
  164. /// 8-bit render order modifier from material.
  165. i8 renderOrder_;
  166. /// Test for equality with another batch group key.
  167. bool operator ==(const BatchGroupKey& rhs) const
  168. {
  169. return zone_ == rhs.zone_ && lightQueue_ == rhs.lightQueue_ && pass_ == rhs.pass_ && material_ == rhs.material_ &&
  170. geometry_ == rhs.geometry_ && renderOrder_ == rhs.renderOrder_;
  171. }
  172. /// Test for inequality with another batch group key.
  173. bool operator !=(const BatchGroupKey& rhs) const
  174. {
  175. return zone_ != rhs.zone_ || lightQueue_ != rhs.lightQueue_ || pass_ != rhs.pass_ || material_ != rhs.material_ ||
  176. geometry_ != rhs.geometry_ || renderOrder_ != rhs.renderOrder_;
  177. }
  178. /// Return hash value.
  179. hash32 ToHash() const;
  180. };
  181. /// Queue that contains both instanced and non-instanced draw calls.
  182. struct BatchQueue
  183. {
  184. public:
  185. /// Clear for new frame by clearing all groups and batches.
  186. void Clear(int maxSortedInstances);
  187. /// Sort non-instanced draw calls back to front.
  188. void SortBackToFront();
  189. /// Sort instanced and non-instanced draw calls front to back.
  190. void SortFrontToBack();
  191. /// Sort batches front to back while also maintaining state sorting.
  192. void SortFrontToBack2Pass(Vector<Batch*>& batches);
  193. /// Pre-set instance data of all groups. The vertex buffer must be big enough to hold all data.
  194. void SetInstancingData(void* lockedData, i32 stride, i32& freeIndex);
  195. /// Draw.
  196. void Draw(View* view, Camera* camera, bool markToStencil, bool usingLightOptimization, bool allowDepthWrite) const;
  197. /// Return the combined amount of instances.
  198. i32 GetNumInstances() const;
  199. /// Return whether the batch group is empty.
  200. bool IsEmpty() const { return batches_.Empty() && batchGroups_.Empty(); }
  201. /// Instanced draw calls.
  202. HashMap<BatchGroupKey, BatchGroup> batchGroups_;
  203. /// Shader remapping table for 2-pass state and distance sort.
  204. HashMap<hash32, hash32> shaderRemapping_;
  205. /// Material remapping table for 2-pass state and distance sort.
  206. HashMap<hash16, hash16> materialRemapping_;
  207. /// Geometry remapping table for 2-pass state and distance sort.
  208. HashMap<hash16, hash16> geometryRemapping_;
  209. /// Unsorted non-instanced draw calls.
  210. Vector<Batch> batches_;
  211. /// Sorted non-instanced draw calls.
  212. Vector<Batch*> sortedBatches_;
  213. /// Sorted instanced draw calls.
  214. Vector<BatchGroup*> sortedBatchGroups_;
  215. /// Maximum sorted instances.
  216. i32 maxSortedInstances_;
  217. /// Whether the pass command contains extra shader defines.
  218. bool hasExtraDefines_;
  219. /// Vertex shader extra defines.
  220. String vsExtraDefines_;
  221. /// Pixel shader extra defines.
  222. String psExtraDefines_;
  223. /// Hash for vertex shader extra defines.
  224. StringHash vsExtraDefinesHash_;
  225. /// Hash for pixel shader extra defines.
  226. StringHash psExtraDefinesHash_;
  227. };
  228. /// Queue for shadow map draw calls.
  229. struct ShadowBatchQueue
  230. {
  231. /// Shadow map camera.
  232. Camera* shadowCamera_{};
  233. /// Shadow map viewport.
  234. IntRect shadowViewport_;
  235. /// Shadow caster draw calls.
  236. BatchQueue shadowBatches_;
  237. /// Directional light cascade near split distance.
  238. float nearSplit_{};
  239. /// Directional light cascade far split distance.
  240. float farSplit_{};
  241. };
  242. /// Queue for light related draw calls.
  243. struct LightBatchQueue
  244. {
  245. /// Per-pixel light.
  246. Light* light_;
  247. /// Light negative flag.
  248. bool negative_;
  249. /// Shadow map depth texture.
  250. Texture2D* shadowMap_;
  251. /// Lit geometry draw calls, base (replace blend mode).
  252. BatchQueue litBaseBatches_;
  253. /// Lit geometry draw calls, non-base (additive).
  254. BatchQueue litBatches_;
  255. /// Shadow map split queues.
  256. Vector<ShadowBatchQueue> shadowSplits_;
  257. /// Per-vertex lights.
  258. Vector<Light*> vertexLights_;
  259. /// Light volume draw calls.
  260. Vector<Batch> volumeBatches_;
  261. };
  262. }