BsGpuResourcePool.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsGpuResourcePool.h"
  4. #include "BsRenderTexture.h"
  5. #include "BsTexture.h"
  6. #include "BsGpuBuffer.h"
  7. #include "BsTextureManager.h"
  8. namespace bs { namespace ct
  9. {
  10. PooledRenderTexture::PooledRenderTexture(GpuResourcePool* pool)
  11. :mPool(pool), mIsFree(false)
  12. { }
  13. PooledRenderTexture::~PooledRenderTexture()
  14. {
  15. if (mPool != nullptr)
  16. mPool->_unregisterTexture(this);
  17. }
  18. PooledStorageBuffer::PooledStorageBuffer(GpuResourcePool* pool)
  19. :mPool(pool), mIsFree(false)
  20. { }
  21. PooledStorageBuffer::~PooledStorageBuffer()
  22. {
  23. if (mPool != nullptr)
  24. mPool->_unregisterBuffer(this);
  25. }
  26. GpuResourcePool::~GpuResourcePool()
  27. {
  28. for (auto& texture : mTextures)
  29. texture.second.lock()->mPool = nullptr;
  30. for (auto& buffer : mBuffers)
  31. buffer.second.lock()->mPool = nullptr;
  32. }
  33. SPtr<PooledRenderTexture> GpuResourcePool::get(const POOLED_RENDER_TEXTURE_DESC& desc)
  34. {
  35. for (auto& texturePair : mTextures)
  36. {
  37. SPtr<PooledRenderTexture> textureData = texturePair.second.lock();
  38. if (!textureData->mIsFree)
  39. continue;
  40. if (textureData->texture == nullptr)
  41. continue;
  42. if (matches(textureData->texture, desc))
  43. {
  44. textureData->mIsFree = false;
  45. return textureData;
  46. }
  47. }
  48. SPtr<PooledRenderTexture> newTextureData = bs_shared_ptr_new<PooledRenderTexture>(this);
  49. _registerTexture(newTextureData);
  50. TEXTURE_DESC texDesc;
  51. texDesc.type = desc.type;
  52. texDesc.width = desc.width;
  53. texDesc.height = desc.height;
  54. texDesc.depth = desc.depth;
  55. texDesc.format = desc.format;
  56. texDesc.usage = desc.flag;
  57. texDesc.hwGamma = desc.hwGamma;
  58. texDesc.numSamples = desc.numSamples;
  59. if (desc.type != TEX_TYPE_3D)
  60. texDesc.numArraySlices = desc.arraySize;
  61. newTextureData->texture = TextureManager::instance().createTexture(texDesc);
  62. if ((desc.flag & (TU_RENDERTARGET | TU_DEPTHSTENCIL)) != 0)
  63. {
  64. RENDER_TEXTURE_DESC rtDesc;
  65. if ((desc.flag & TU_RENDERTARGET) != 0)
  66. {
  67. rtDesc.colorSurfaces[0].texture = newTextureData->texture;
  68. rtDesc.colorSurfaces[0].face = 0;
  69. rtDesc.colorSurfaces[0].numFaces = newTextureData->texture->getProperties().getNumFaces();
  70. rtDesc.colorSurfaces[0].mipLevel = 0;
  71. }
  72. if ((desc.flag & TU_DEPTHSTENCIL) != 0)
  73. {
  74. rtDesc.depthStencilSurface.texture = newTextureData->texture;
  75. rtDesc.depthStencilSurface.face = 0;
  76. rtDesc.depthStencilSurface.numFaces = newTextureData->texture->getProperties().getNumFaces();
  77. rtDesc.depthStencilSurface.mipLevel = 0;
  78. }
  79. newTextureData->renderTexture = TextureManager::instance().createRenderTexture(rtDesc);
  80. }
  81. return newTextureData;
  82. }
  83. SPtr<PooledStorageBuffer> GpuResourcePool::get(const POOLED_STORAGE_BUFFER_DESC& desc)
  84. {
  85. for (auto& bufferPair : mBuffers)
  86. {
  87. SPtr<PooledStorageBuffer> bufferData = bufferPair.second.lock();
  88. if (!bufferData->mIsFree)
  89. continue;
  90. if (bufferData->buffer == nullptr)
  91. continue;
  92. if (matches(bufferData->buffer, desc))
  93. {
  94. bufferData->mIsFree = false;
  95. return bufferData;
  96. }
  97. }
  98. SPtr<PooledStorageBuffer> newBufferData = bs_shared_ptr_new<PooledStorageBuffer>(this);
  99. _registerBuffer(newBufferData);
  100. GPU_BUFFER_DESC bufferDesc;
  101. bufferDesc.type = desc.type;
  102. bufferDesc.elementSize = desc.elementSize;
  103. bufferDesc.elementCount = desc.numElements;
  104. bufferDesc.format = desc.format;
  105. bufferDesc.randomGpuWrite = true;
  106. newBufferData->buffer = GpuBuffer::create(bufferDesc);
  107. return newBufferData;
  108. }
  109. void GpuResourcePool::release(const SPtr<PooledRenderTexture>& texture)
  110. {
  111. auto iterFind = mTextures.find(texture.get());
  112. iterFind->second.lock()->mIsFree = true;
  113. }
  114. void GpuResourcePool::release(const SPtr<PooledStorageBuffer>& buffer)
  115. {
  116. auto iterFind = mBuffers.find(buffer.get());
  117. iterFind->second.lock()->mIsFree = true;
  118. }
  119. bool GpuResourcePool::matches(const SPtr<Texture>& texture, const POOLED_RENDER_TEXTURE_DESC& desc)
  120. {
  121. const TextureProperties& texProps = texture->getProperties();
  122. bool match = texProps.getTextureType() == desc.type
  123. && texProps.getFormat() == desc.format
  124. && texProps.getWidth() == desc.width
  125. && texProps.getHeight() == desc.height
  126. && (texProps.getUsage() & desc.flag) == desc.flag
  127. && (
  128. (desc.type == TEX_TYPE_2D
  129. && texProps.isHardwareGammaEnabled() == desc.hwGamma
  130. && texProps.getNumSamples() == desc.numSamples)
  131. || (desc.type == TEX_TYPE_3D
  132. && texProps.getDepth() == desc.depth)
  133. || (desc.type == TEX_TYPE_CUBE_MAP)
  134. )
  135. && texProps.getNumArraySlices() == desc.arraySize
  136. ;
  137. return match;
  138. }
  139. bool GpuResourcePool::matches(const SPtr<GpuBuffer>& buffer, const POOLED_STORAGE_BUFFER_DESC& desc)
  140. {
  141. const GpuBufferProperties& props = buffer->getProperties();
  142. bool match = props.getType() == desc.type && props.getElementCount() == desc.numElements;
  143. if(match)
  144. {
  145. if (desc.type == GBT_STANDARD)
  146. match = props.getFormat() == desc.format;
  147. else // Structured
  148. match = props.getElementSize() == desc.elementSize;
  149. }
  150. return match;
  151. }
  152. void GpuResourcePool::_registerTexture(const SPtr<PooledRenderTexture>& texture)
  153. {
  154. mTextures.insert(std::make_pair(texture.get(), texture));
  155. }
  156. void GpuResourcePool::_unregisterTexture(PooledRenderTexture* texture)
  157. {
  158. mTextures.erase(texture);
  159. }
  160. void GpuResourcePool::_registerBuffer(const SPtr<PooledStorageBuffer>& buffer)
  161. {
  162. mBuffers.insert(std::make_pair(buffer.get(), buffer));
  163. }
  164. void GpuResourcePool::_unregisterBuffer(PooledStorageBuffer* buffer)
  165. {
  166. mBuffers.erase(buffer);
  167. }
  168. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::create2D(PixelFormat format, UINT32 width, UINT32 height,
  169. INT32 usage, UINT32 samples, bool hwGamma, UINT32 arraySize)
  170. {
  171. POOLED_RENDER_TEXTURE_DESC desc;
  172. desc.width = width;
  173. desc.height = height;
  174. desc.depth = 1;
  175. desc.format = format;
  176. desc.numSamples = samples;
  177. desc.flag = (TextureUsage)usage;
  178. desc.hwGamma = hwGamma;
  179. desc.type = TEX_TYPE_2D;
  180. desc.arraySize = arraySize;
  181. return desc;
  182. }
  183. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::create3D(PixelFormat format, UINT32 width, UINT32 height,
  184. UINT32 depth, INT32 usage)
  185. {
  186. POOLED_RENDER_TEXTURE_DESC desc;
  187. desc.width = width;
  188. desc.height = height;
  189. desc.depth = depth;
  190. desc.format = format;
  191. desc.numSamples = 1;
  192. desc.flag = (TextureUsage)usage;
  193. desc.hwGamma = false;
  194. desc.type = TEX_TYPE_3D;
  195. desc.arraySize = 1;
  196. return desc;
  197. }
  198. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::createCube(PixelFormat format, UINT32 width, UINT32 height,
  199. INT32 usage, UINT32 arraySize)
  200. {
  201. POOLED_RENDER_TEXTURE_DESC desc;
  202. desc.width = width;
  203. desc.height = height;
  204. desc.depth = 1;
  205. desc.format = format;
  206. desc.numSamples = 1;
  207. desc.flag = (TextureUsage)usage;
  208. desc.hwGamma = false;
  209. desc.type = TEX_TYPE_CUBE_MAP;
  210. desc.arraySize = arraySize;
  211. return desc;
  212. }
  213. POOLED_STORAGE_BUFFER_DESC POOLED_STORAGE_BUFFER_DESC::createStandard(GpuBufferFormat format, UINT32 numElements)
  214. {
  215. POOLED_STORAGE_BUFFER_DESC desc;
  216. desc.type = GBT_STANDARD;
  217. desc.format = format;
  218. desc.numElements = numElements;
  219. desc.elementSize = 0;
  220. return desc;
  221. }
  222. POOLED_STORAGE_BUFFER_DESC POOLED_STORAGE_BUFFER_DESC::createStructured(UINT32 elementSize, UINT32 numElements)
  223. {
  224. POOLED_STORAGE_BUFFER_DESC desc;
  225. desc.type = GBT_STRUCTURED;
  226. desc.format = BF_UNKNOWN;
  227. desc.numElements = numElements;
  228. desc.elementSize = elementSize;
  229. return desc;
  230. }
  231. }}