BsGpuResourcePool.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. texDesc.numMips = desc.numMipLevels;
  60. if (desc.type != TEX_TYPE_3D)
  61. texDesc.numArraySlices = desc.arraySize;
  62. newTextureData->texture = TextureManager::instance().createTexture(texDesc);
  63. if ((desc.flag & (TU_RENDERTARGET | TU_DEPTHSTENCIL)) != 0)
  64. {
  65. RENDER_TEXTURE_DESC rtDesc;
  66. if ((desc.flag & TU_RENDERTARGET) != 0)
  67. {
  68. rtDesc.colorSurfaces[0].texture = newTextureData->texture;
  69. rtDesc.colorSurfaces[0].face = 0;
  70. rtDesc.colorSurfaces[0].numFaces = newTextureData->texture->getProperties().getNumFaces();
  71. rtDesc.colorSurfaces[0].mipLevel = 0;
  72. }
  73. if ((desc.flag & TU_DEPTHSTENCIL) != 0)
  74. {
  75. rtDesc.depthStencilSurface.texture = newTextureData->texture;
  76. rtDesc.depthStencilSurface.face = 0;
  77. rtDesc.depthStencilSurface.numFaces = newTextureData->texture->getProperties().getNumFaces();
  78. rtDesc.depthStencilSurface.mipLevel = 0;
  79. }
  80. newTextureData->renderTexture = TextureManager::instance().createRenderTexture(rtDesc);
  81. }
  82. return newTextureData;
  83. }
  84. SPtr<PooledStorageBuffer> GpuResourcePool::get(const POOLED_STORAGE_BUFFER_DESC& desc)
  85. {
  86. for (auto& bufferPair : mBuffers)
  87. {
  88. SPtr<PooledStorageBuffer> bufferData = bufferPair.second.lock();
  89. if (!bufferData->mIsFree)
  90. continue;
  91. if (bufferData->buffer == nullptr)
  92. continue;
  93. if (matches(bufferData->buffer, desc))
  94. {
  95. bufferData->mIsFree = false;
  96. return bufferData;
  97. }
  98. }
  99. SPtr<PooledStorageBuffer> newBufferData = bs_shared_ptr_new<PooledStorageBuffer>(this);
  100. _registerBuffer(newBufferData);
  101. GPU_BUFFER_DESC bufferDesc;
  102. bufferDesc.type = desc.type;
  103. bufferDesc.elementSize = desc.elementSize;
  104. bufferDesc.elementCount = desc.numElements;
  105. bufferDesc.format = desc.format;
  106. bufferDesc.randomGpuWrite = true;
  107. newBufferData->buffer = GpuBuffer::create(bufferDesc);
  108. return newBufferData;
  109. }
  110. void GpuResourcePool::release(const SPtr<PooledRenderTexture>& texture)
  111. {
  112. auto iterFind = mTextures.find(texture.get());
  113. iterFind->second.lock()->mIsFree = true;
  114. }
  115. void GpuResourcePool::release(const SPtr<PooledStorageBuffer>& buffer)
  116. {
  117. auto iterFind = mBuffers.find(buffer.get());
  118. iterFind->second.lock()->mIsFree = true;
  119. }
  120. bool GpuResourcePool::matches(const SPtr<Texture>& texture, const POOLED_RENDER_TEXTURE_DESC& desc)
  121. {
  122. const TextureProperties& texProps = texture->getProperties();
  123. bool match = texProps.getTextureType() == desc.type
  124. && texProps.getFormat() == desc.format
  125. && texProps.getWidth() == desc.width
  126. && texProps.getHeight() == desc.height
  127. && (texProps.getUsage() & desc.flag) == desc.flag
  128. && (
  129. (desc.type == TEX_TYPE_2D
  130. && texProps.isHardwareGammaEnabled() == desc.hwGamma
  131. && texProps.getNumSamples() == desc.numSamples)
  132. || (desc.type == TEX_TYPE_3D
  133. && texProps.getDepth() == desc.depth)
  134. || (desc.type == TEX_TYPE_CUBE_MAP)
  135. )
  136. && texProps.getNumArraySlices() == desc.arraySize
  137. && texProps.getNumMipmaps() == desc.numMipLevels
  138. ;
  139. return match;
  140. }
  141. bool GpuResourcePool::matches(const SPtr<GpuBuffer>& buffer, const POOLED_STORAGE_BUFFER_DESC& desc)
  142. {
  143. const GpuBufferProperties& props = buffer->getProperties();
  144. bool match = props.getType() == desc.type && props.getElementCount() == desc.numElements;
  145. if(match)
  146. {
  147. if (desc.type == GBT_STANDARD)
  148. match = props.getFormat() == desc.format;
  149. else // Structured
  150. match = props.getElementSize() == desc.elementSize;
  151. }
  152. return match;
  153. }
  154. void GpuResourcePool::_registerTexture(const SPtr<PooledRenderTexture>& texture)
  155. {
  156. mTextures.insert(std::make_pair(texture.get(), texture));
  157. }
  158. void GpuResourcePool::_unregisterTexture(PooledRenderTexture* texture)
  159. {
  160. mTextures.erase(texture);
  161. }
  162. void GpuResourcePool::_registerBuffer(const SPtr<PooledStorageBuffer>& buffer)
  163. {
  164. mBuffers.insert(std::make_pair(buffer.get(), buffer));
  165. }
  166. void GpuResourcePool::_unregisterBuffer(PooledStorageBuffer* buffer)
  167. {
  168. mBuffers.erase(buffer);
  169. }
  170. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::create2D(PixelFormat format, UINT32 width, UINT32 height,
  171. INT32 usage, UINT32 samples, bool hwGamma, UINT32 arraySize, UINT32 mipCount)
  172. {
  173. POOLED_RENDER_TEXTURE_DESC desc;
  174. desc.width = width;
  175. desc.height = height;
  176. desc.depth = 1;
  177. desc.format = format;
  178. desc.numSamples = samples;
  179. desc.flag = (TextureUsage)usage;
  180. desc.hwGamma = hwGamma;
  181. desc.type = TEX_TYPE_2D;
  182. desc.arraySize = arraySize;
  183. desc.numMipLevels = mipCount;
  184. return desc;
  185. }
  186. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::create3D(PixelFormat format, UINT32 width, UINT32 height,
  187. UINT32 depth, INT32 usage)
  188. {
  189. POOLED_RENDER_TEXTURE_DESC desc;
  190. desc.width = width;
  191. desc.height = height;
  192. desc.depth = depth;
  193. desc.format = format;
  194. desc.numSamples = 1;
  195. desc.flag = (TextureUsage)usage;
  196. desc.hwGamma = false;
  197. desc.type = TEX_TYPE_3D;
  198. desc.arraySize = 1;
  199. desc.numMipLevels = 0;
  200. return desc;
  201. }
  202. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::createCube(PixelFormat format, UINT32 width, UINT32 height,
  203. INT32 usage, UINT32 arraySize)
  204. {
  205. POOLED_RENDER_TEXTURE_DESC desc;
  206. desc.width = width;
  207. desc.height = height;
  208. desc.depth = 1;
  209. desc.format = format;
  210. desc.numSamples = 1;
  211. desc.flag = (TextureUsage)usage;
  212. desc.hwGamma = false;
  213. desc.type = TEX_TYPE_CUBE_MAP;
  214. desc.arraySize = arraySize;
  215. desc.numMipLevels = 0;
  216. return desc;
  217. }
  218. POOLED_STORAGE_BUFFER_DESC POOLED_STORAGE_BUFFER_DESC::createStandard(GpuBufferFormat format, UINT32 numElements)
  219. {
  220. POOLED_STORAGE_BUFFER_DESC desc;
  221. desc.type = GBT_STANDARD;
  222. desc.format = format;
  223. desc.numElements = numElements;
  224. desc.elementSize = 0;
  225. return desc;
  226. }
  227. POOLED_STORAGE_BUFFER_DESC POOLED_STORAGE_BUFFER_DESC::createStructured(UINT32 elementSize, UINT32 numElements)
  228. {
  229. POOLED_STORAGE_BUFFER_DESC desc;
  230. desc.type = GBT_STRUCTURED;
  231. desc.format = BF_UNKNOWN;
  232. desc.numElements = numElements;
  233. desc.elementSize = elementSize;
  234. return desc;
  235. }
  236. }}