BsGpuBuffer.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsGpuBufferView.h"
  4. #include "BsCoreObject.h"
  5. namespace BansheeEngine
  6. {
  7. /** @addtogroup RenderAPI
  8. * @{
  9. */
  10. /**
  11. * Information about a GpuBuffer. Allows core and non-core versions of GpuBuffer to share the same structure for
  12. * properties.
  13. */
  14. class BS_CORE_EXPORT GpuBufferProperties
  15. {
  16. public:
  17. GpuBufferProperties(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
  18. GpuBufferUsage usage, bool randomGpuWrite, bool useCounter);
  19. /**
  20. * Returns the type of the GPU buffer. Type determines which kind of views (if any) can be created for the buffer,
  21. * and how is data read or modified in it.
  22. */
  23. GpuBufferType getType() const { return mType; }
  24. /** Returns buffer usage which determines how are planning on updating the buffer contents. */
  25. GpuBufferUsage getUsage() const { return mUsage; }
  26. /** Return whether the buffer supports random reads and writes within the GPU programs. */
  27. bool getRandomGpuWrite() const { return mRandomGpuWrite; }
  28. /** Returns whether the buffer supports counter use within GPU programs. */
  29. bool getUseCounter() const { return mUseCounter; }
  30. /** Returns number of elements in the buffer. */
  31. UINT32 getElementCount() const { return mElementCount; }
  32. /** Returns size of a single element in the buffer in bytes. */
  33. UINT32 getElementSize() const { return mElementSize; }
  34. protected:
  35. GpuBufferType mType;
  36. GpuBufferUsage mUsage;
  37. bool mRandomGpuWrite;
  38. bool mUseCounter;
  39. UINT32 mElementCount;
  40. UINT32 mElementSize;
  41. };
  42. /** @cond INTERNAL */
  43. /**
  44. * Core thread version of a GpuBuffer.
  45. *
  46. * @note Core thread only.
  47. */
  48. class BS_CORE_EXPORT GpuBufferCore : public CoreObjectCore
  49. {
  50. public:
  51. virtual ~GpuBufferCore();
  52. /**
  53. * Locks the buffer returning a pointer to the internal buffer data that you may then read or write to.
  54. * Caller must ensure it will only perform actions promised in the provided GPU lock options parameter.
  55. *
  56. * @param[in] offset Number of bytes at which to lock the buffer. Returned pointer points to this location.
  57. * @param[in] length Number of bytes to lock.
  58. * @param[in] options How to lock the buffer. Certain options offer better performance than others.
  59. */
  60. virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
  61. /**
  62. * Unlocks a previously locked buffer. Any pointers to internal buffers returned when it was locked will become
  63. * invalid.
  64. */
  65. virtual void unlock() = 0;
  66. /**
  67. * Reads buffer data into the previously allocated buffer.
  68. *
  69. * @param[in] offset Number of bytes at which to start reading the buffer.
  70. * @param[in] length Number of bytes to read.
  71. * @param[in] pDest Previously allocated buffer of @p length bytes size.
  72. */
  73. virtual void readData(UINT32 offset, UINT32 length, void* pDest) = 0;
  74. /**
  75. * Writes data into the buffer.
  76. *
  77. * @param[in] offset Number of bytes at which to start writing to the buffer.
  78. * @param[in] length Number of bytes to write.
  79. * @param[in] pDest Previously allocated buffer used to retrieve the data from.
  80. * @param[in] writeFlags Flags that may be used to improve performance for specific use cases.
  81. */
  82. virtual void writeData(UINT32 offset, UINT32 length, const void* pSource, BufferWriteType writeFlags = BufferWriteType::Normal) = 0;
  83. /**
  84. * Copies data from another buffer into this buffer.
  85. *
  86. * @param[in] srcBuffer Buffer to copy the data from.
  87. * @param[in] srcOffset Offset in bytes into the source buffer - this is where reading starts from.
  88. * @param[in] dstOffset Offset in bytes into the destination buffer - this is where writing starts from.
  89. * @param[in] length Number of bytes to copy from source to destination.
  90. * @param[in] discardWholeBuffer If true, the contents of the current buffer will be entirely discarded. This can
  91. * improve performance if you know you wont be needing that data any more.
  92. */
  93. virtual void copyData(GpuBufferCore& srcBuffer, UINT32 srcOffset,
  94. UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false) = 0;
  95. /** Returns properties describing the buffer. */
  96. const GpuBufferProperties& getProperties() const { return mProperties; }
  97. /**
  98. * Creates a buffer view that may be used for binding a buffer to a slot in the pipeline. Views allow you to specify
  99. * how is data in the buffer organized to make it easier for the pipeline to interpret.
  100. *
  101. * @param[in] buffer Buffer to create the view for.
  102. * @param[in] firstElement Position of the first element visible by the view.
  103. * @param[in] elementWidth Width of one element in bytes.
  104. * @param[in] numElements Number of elements in the buffer.
  105. * @param[in] useCounter Should the buffer allow use of a counter. This is only relevant for random read write buffers.
  106. * @param[in] usage Determines type of the view we are creating, and which slots in the pipeline will the view be bindable to.
  107. *
  108. * @note If a view with this exact parameters already exists, it will be returned and new one will not be created.
  109. * @note Only Default and RandomWrite views are supported for this type of buffer.
  110. */
  111. // TODO Low Priority: Perhaps reflect usage flag limitation by having an enum with only the supported two options?
  112. static GpuBufferView* requestView(const SPtr<GpuBufferCore>& buffer, UINT32 firstElement, UINT32 elementWidth,
  113. UINT32 numElements, bool useCounter, GpuViewUsage usage);
  114. /**
  115. * Releases a view created with requestView.
  116. *
  117. * @note View will only truly get released once all references to it are released.
  118. */
  119. static void releaseView(GpuBufferView* view);
  120. protected:
  121. GpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
  122. GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
  123. /** Creates an empty view for the current buffer. */
  124. virtual GpuBufferView* createView() = 0;
  125. /** Destroys a view previously created for this buffer. */
  126. virtual void destroyView(GpuBufferView* view) = 0;
  127. /** Destroys all buffer views regardless if their reference count is zero or not. */
  128. void clearBufferViews();
  129. /** Helper class to help with reference counting for GPU buffer views. */
  130. struct GpuBufferReference
  131. {
  132. GpuBufferReference(GpuBufferView* _view)
  133. :view(_view), refCount(0)
  134. { }
  135. GpuBufferView* view;
  136. UINT32 refCount;
  137. };
  138. UnorderedMap<GPU_BUFFER_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
  139. GpuBufferProperties mProperties;
  140. };
  141. /** @endcond */
  142. /**
  143. * Handles a generic GPU buffer that you may use for storing any kind of data you wish to be accessible to the GPU.
  144. * These buffers may be bounds to GPU program binding slots and accessed from a GPU program, or may be used by fixed
  145. * pipeline in some way.
  146. *
  147. * Buffer types:
  148. * - Raw buffers containing a block of bytes that are up to the GPU program to interpret.
  149. * - Structured buffer containing an array of structures compliant to a certain layout. Similar to raw buffer but
  150. * easier to interpret the data.
  151. * - Random read/write buffers that allow you to write to random parts of the buffer from within the GPU program, and
  152. * then read it later. These can only be bound to pixel and compute stages.
  153. * - Append/Consume buffers also allow you to write to them, but in a stack-like fashion, usually where one set of
  154. * programs produces data while other set consumes it from the same buffer. Append/Consume buffers are structured
  155. * by default.
  156. *
  157. * @note Sim thread only.
  158. */
  159. class BS_CORE_EXPORT GpuBuffer : public CoreObject
  160. {
  161. public:
  162. virtual ~GpuBuffer() { }
  163. /** Returns properties describing the buffer. */
  164. const GpuBufferProperties& getProperties() const { return mProperties; }
  165. /** Retrieves a core implementation of a GPU buffer usable only from the core thread. */
  166. SPtr<GpuBufferCore> getCore() const;
  167. protected:
  168. friend class HardwareBufferManager;
  169. GpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferUsage usage,
  170. bool randomGpuWrite = false, bool useCounter = false);
  171. /** @copydoc CoreObject::createCore */
  172. SPtr<CoreObjectCore> createCore() const override;
  173. /** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
  174. static GpuParamBlockBufferPtr create(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
  175. GpuBufferProperties mProperties;
  176. };
  177. /** @} */
  178. }