CmBindableGpuParams.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "CmBindableGpuParams.h"
  2. #include "CmGpuParams.h"
  3. #include "CmGpuParamDesc.h"
  4. #include "CmBindableGpuParamBlock.h"
  5. #include "CmGpuParamBlockBuffer.h"
  6. #include "CmDebug.h"
  7. #include "CmFrameAlloc.h"
  8. namespace BansheeEngine
  9. {
  10. BindableGpuParams::BindableGpuParams(const GpuParamsPtr& params, FrameAlloc* allocator)
  11. :mOwnsData(true), mParamDesc(params->getParamDesc()), mData(nullptr), mNumParamBlocks(0), mAllocator(allocator),
  12. mNumTextures(0), mNumSamplerStates(0),mParamBlocks(nullptr), mParamBlockBuffers(nullptr), mTextures(nullptr), mSamplerStates(nullptr)
  13. {
  14. // Allocate everything in a single block of memory to get rid of extra memory allocations
  15. UINT32 paramBlockBufferSize = params->mNumParamBlocks * sizeof(BindableGpuParamBlock*);
  16. UINT32 paramBlockBuffersBufferSize = params->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
  17. UINT32 textureBufferSize = params->mNumTextures * sizeof(HTexture);
  18. UINT32 samplerStateBufferSize = params->mNumSamplerStates * sizeof(HSamplerState);
  19. UINT32 bufferSize = paramBlockBufferSize + paramBlockBuffersBufferSize + textureBufferSize + samplerStateBufferSize;
  20. for(UINT32 i = 0; i < params->mNumParamBlocks; i++)
  21. {
  22. if(params->mParamBlockBuffers[i] != nullptr)
  23. bufferSize += sizeof(BindableGpuParamBlock) + params->mParamBlockBuffers[i]->getSize();
  24. }
  25. mData = (UINT8*)allocator->alloc(bufferSize);
  26. mNumParamBlocks = params->mNumParamBlocks;
  27. mNumTextures = params->mNumTextures;
  28. mNumSamplerStates = params->mNumSamplerStates;
  29. UINT8* dataIter = mData;
  30. mParamBlocks = (BindableGpuParamBlock**)dataIter;
  31. dataIter += paramBlockBufferSize;
  32. mParamBlockBuffers = (GpuParamBlockBufferPtr*)dataIter;
  33. dataIter += paramBlockBuffersBufferSize;
  34. mTextures = (HTexture*)dataIter;
  35. dataIter += textureBufferSize;
  36. mSamplerStates = (HSamplerState*)dataIter;
  37. dataIter += samplerStateBufferSize;
  38. // Copy data
  39. memcpy(mParamBlockBuffers, params->mParamBlockBuffers, paramBlockBuffersBufferSize);
  40. memcpy(mTextures, params->mTextures, textureBufferSize);
  41. memcpy(mSamplerStates, params->mSamplerStates, samplerStateBufferSize);
  42. for(UINT32 i = 0; i < params->mNumParamBlocks; i++)
  43. {
  44. if(params->mParamBlockBuffers[i] != nullptr)
  45. {
  46. GpuParamBlock* paramBlock = params->mParamBlockBuffers[i]->getParamBlock();
  47. UINT32 bufferSize = paramBlock->getSize();
  48. mParamBlocks[i] = (BindableGpuParamBlock*)dataIter;
  49. dataIter += sizeof(BindableGpuParamBlock);
  50. mParamBlocks[i]->mData = dataIter;
  51. dataIter += bufferSize;
  52. memcpy(mParamBlocks[i]->mData, paramBlock->getData(), bufferSize);
  53. mParamBlocks[i]->mSize = bufferSize;
  54. mParamBlocks[i]->mDirty = paramBlock->isDirty();
  55. }
  56. }
  57. }
  58. BindableGpuParams::BindableGpuParams(const BindableGpuParams& source)
  59. :mParamDesc(source.mParamDesc)
  60. {
  61. mOwnsData = true;
  62. source.mOwnsData = false;
  63. mAllocator = source.mAllocator;
  64. mData = source.mData;
  65. mNumParamBlocks = source.mNumParamBlocks;
  66. mNumTextures = source.mNumTextures;
  67. mNumSamplerStates = source.mNumSamplerStates;
  68. mParamBlocks = source.mParamBlocks;
  69. mParamBlockBuffers = source.mParamBlockBuffers;
  70. mTextures = source.mTextures;
  71. mSamplerStates = source.mSamplerStates;
  72. }
  73. BindableGpuParams::~BindableGpuParams()
  74. {
  75. if(mOwnsData && mData != nullptr)
  76. {
  77. mAllocator->dealloc(mData);
  78. }
  79. }
  80. GpuParamBlockBufferPtr BindableGpuParams::getParamBlockBuffer(UINT32 slot) const
  81. {
  82. if(slot < 0 || slot >= mNumParamBlocks)
  83. {
  84. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  85. toString(mNumParamBlocks - 1) + ". Requested: " + toString(slot));
  86. }
  87. return mParamBlockBuffers[slot];
  88. }
  89. GpuParamBlockBufferPtr BindableGpuParams::getParamBlockBuffer(const String& name) const
  90. {
  91. auto iterFind = mParamDesc.paramBlocks.find(name);
  92. if(iterFind == mParamDesc.paramBlocks.end())
  93. {
  94. LOGWRN("Cannot find parameter block with the name: " + name);
  95. return nullptr;
  96. }
  97. return mParamBlockBuffers[iterFind->second.slot];
  98. }
  99. HTexture BindableGpuParams::getTexture(UINT32 slot)
  100. {
  101. if(slot < 0 || slot >= mNumTextures)
  102. {
  103. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  104. toString(mNumTextures - 1) + ". Requested: " + toString(slot));
  105. }
  106. return mTextures[slot];
  107. }
  108. HSamplerState BindableGpuParams::getSamplerState(UINT32 slot)
  109. {
  110. if(slot < 0 || slot >= mNumSamplerStates)
  111. {
  112. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  113. toString(mNumSamplerStates - 1) + ". Requested: " + toString(slot));
  114. }
  115. return mSamplerStates[slot];
  116. }
  117. void BindableGpuParams::updateHardwareBuffers()
  118. {
  119. for(size_t i = 0; i < mNumParamBlocks; i++)
  120. {
  121. if(mParamBlocks[i] != nullptr && mParamBlockBuffers[i] != nullptr)
  122. {
  123. if(mParamBlocks[i]->isDirty())
  124. mParamBlocks[i]->uploadToBuffer(mParamBlockBuffers[i]);
  125. }
  126. }
  127. }
  128. }