BsGpuResourcePool.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsGpuResourcePool.h"
  4. #include "RenderAPI/BsRenderTexture.h"
  5. #include "Image/BsTexture.h"
  6. #include "RenderAPI/BsGpuBuffer.h"
  7. namespace bs { namespace ct
  8. {
  9. PooledRenderTexture::PooledRenderTexture(GpuResourcePool* pool)
  10. :mPool(pool), mIsFree(false)
  11. { }
  12. PooledRenderTexture::~PooledRenderTexture()
  13. {
  14. if (mPool != nullptr)
  15. mPool->_unregisterTexture(this);
  16. }
  17. PooledStorageBuffer::PooledStorageBuffer(GpuResourcePool* pool)
  18. :mPool(pool), mIsFree(false)
  19. { }
  20. PooledStorageBuffer::~PooledStorageBuffer()
  21. {
  22. if (mPool != nullptr)
  23. mPool->_unregisterBuffer(this);
  24. }
  25. GpuResourcePool::~GpuResourcePool()
  26. {
  27. for (auto& texture : mTextures)
  28. texture.second.lock()->mPool = nullptr;
  29. for (auto& buffer : mBuffers)
  30. buffer.second.lock()->mPool = nullptr;
  31. }
  32. SPtr<PooledRenderTexture> GpuResourcePool::get(const POOLED_RENDER_TEXTURE_DESC& desc)
  33. {
  34. for (auto& texturePair : mTextures)
  35. {
  36. SPtr<PooledRenderTexture> textureData = texturePair.second.lock();
  37. if (!textureData->mIsFree)
  38. continue;
  39. if (textureData->texture == nullptr)
  40. continue;
  41. if (matches(textureData->texture, desc))
  42. {
  43. textureData->mIsFree = false;
  44. return textureData;
  45. }
  46. }
  47. SPtr<PooledRenderTexture> newTextureData = bs_shared_ptr_new<PooledRenderTexture>(this);
  48. _registerTexture(newTextureData);
  49. TEXTURE_DESC texDesc;
  50. texDesc.type = desc.type;
  51. texDesc.width = desc.width;
  52. texDesc.height = desc.height;
  53. texDesc.depth = desc.depth;
  54. texDesc.format = desc.format;
  55. texDesc.usage = desc.flag;
  56. texDesc.hwGamma = desc.hwGamma;
  57. texDesc.numSamples = desc.numSamples;
  58. texDesc.numMips = desc.numMipLevels;
  59. if (desc.type != TEX_TYPE_3D)
  60. texDesc.numArraySlices = desc.arraySize;
  61. newTextureData->texture = Texture::create(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 = RenderTexture::create(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. && texProps.getNumMipmaps() == desc.numMipLevels
  137. ;
  138. return match;
  139. }
  140. bool GpuResourcePool::matches(const SPtr<GpuBuffer>& buffer, const POOLED_STORAGE_BUFFER_DESC& desc)
  141. {
  142. const GpuBufferProperties& props = buffer->getProperties();
  143. bool match = props.getType() == desc.type && props.getElementCount() == desc.numElements;
  144. if(match)
  145. {
  146. if (desc.type == GBT_STANDARD)
  147. match = props.getFormat() == desc.format;
  148. else // Structured
  149. match = props.getElementSize() == desc.elementSize;
  150. }
  151. return match;
  152. }
  153. void GpuResourcePool::_registerTexture(const SPtr<PooledRenderTexture>& texture)
  154. {
  155. mTextures.insert(std::make_pair(texture.get(), texture));
  156. }
  157. void GpuResourcePool::_unregisterTexture(PooledRenderTexture* texture)
  158. {
  159. mTextures.erase(texture);
  160. }
  161. void GpuResourcePool::_registerBuffer(const SPtr<PooledStorageBuffer>& buffer)
  162. {
  163. mBuffers.insert(std::make_pair(buffer.get(), buffer));
  164. }
  165. void GpuResourcePool::_unregisterBuffer(PooledStorageBuffer* buffer)
  166. {
  167. mBuffers.erase(buffer);
  168. }
  169. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::create2D(PixelFormat format, UINT32 width, UINT32 height,
  170. INT32 usage, UINT32 samples, bool hwGamma, UINT32 arraySize, UINT32 mipCount)
  171. {
  172. POOLED_RENDER_TEXTURE_DESC desc;
  173. desc.width = width;
  174. desc.height = height;
  175. desc.depth = 1;
  176. desc.format = format;
  177. desc.numSamples = samples;
  178. desc.flag = (TextureUsage)usage;
  179. desc.hwGamma = hwGamma;
  180. desc.type = TEX_TYPE_2D;
  181. desc.arraySize = arraySize;
  182. desc.numMipLevels = mipCount;
  183. return desc;
  184. }
  185. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::create3D(PixelFormat format, UINT32 width, UINT32 height,
  186. UINT32 depth, INT32 usage)
  187. {
  188. POOLED_RENDER_TEXTURE_DESC desc;
  189. desc.width = width;
  190. desc.height = height;
  191. desc.depth = depth;
  192. desc.format = format;
  193. desc.numSamples = 1;
  194. desc.flag = (TextureUsage)usage;
  195. desc.hwGamma = false;
  196. desc.type = TEX_TYPE_3D;
  197. desc.arraySize = 1;
  198. desc.numMipLevels = 0;
  199. return desc;
  200. }
  201. POOLED_RENDER_TEXTURE_DESC POOLED_RENDER_TEXTURE_DESC::createCube(PixelFormat format, UINT32 width, UINT32 height,
  202. INT32 usage, UINT32 arraySize)
  203. {
  204. POOLED_RENDER_TEXTURE_DESC desc;
  205. desc.width = width;
  206. desc.height = height;
  207. desc.depth = 1;
  208. desc.format = format;
  209. desc.numSamples = 1;
  210. desc.flag = (TextureUsage)usage;
  211. desc.hwGamma = false;
  212. desc.type = TEX_TYPE_CUBE_MAP;
  213. desc.arraySize = arraySize;
  214. desc.numMipLevels = 0;
  215. return desc;
  216. }
  217. POOLED_STORAGE_BUFFER_DESC POOLED_STORAGE_BUFFER_DESC::createStandard(GpuBufferFormat format, UINT32 numElements)
  218. {
  219. POOLED_STORAGE_BUFFER_DESC desc;
  220. desc.type = GBT_STANDARD;
  221. desc.format = format;
  222. desc.numElements = numElements;
  223. desc.elementSize = 0;
  224. return desc;
  225. }
  226. POOLED_STORAGE_BUFFER_DESC POOLED_STORAGE_BUFFER_DESC::createStructured(UINT32 elementSize, UINT32 numElements)
  227. {
  228. POOLED_STORAGE_BUFFER_DESC desc;
  229. desc.type = GBT_STRUCTURED;
  230. desc.format = BF_UNKNOWN;
  231. desc.numElements = numElements;
  232. desc.elementSize = elementSize;
  233. return desc;
  234. }
  235. }}