BsGpuPipelineParamInfo.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsGpuPipelineParamInfo.h"
  4. #include "BsGpuParamDesc.h"
  5. #include "BsRenderStateManager.h"
  6. namespace bs
  7. {
  8. GpuPipelineParamInfoBase::GpuPipelineParamInfoBase(const GPU_PIPELINE_PARAMS_DESC& desc)
  9. :mNumSets(0), mNumElements(0), mSetInfos(nullptr), mResourceInfos()
  10. {
  11. bs_zero_out(mNumElementsPerType);
  12. mParamDescs[GPT_FRAGMENT_PROGRAM] = desc.fragmentParams;
  13. mParamDescs[GPT_VERTEX_PROGRAM] = desc.vertexParams;
  14. mParamDescs[GPT_GEOMETRY_PROGRAM] = desc.geometryParams;
  15. mParamDescs[GPT_HULL_PROGRAM] = desc.hullParams;
  16. mParamDescs[GPT_DOMAIN_PROGRAM] = desc.domainParams;
  17. mParamDescs[GPT_COMPUTE_PROGRAM] = desc.computeParams;
  18. auto countElements = [&](auto& entry, ParamType type)
  19. {
  20. int typeIdx = (int)type;
  21. if ((entry.set + 1) > mNumSets)
  22. mNumSets = entry.set + 1;
  23. mNumElementsPerType[typeIdx]++;
  24. mNumElements++;
  25. };
  26. UINT32 numParamDescs = sizeof(mParamDescs) / sizeof(mParamDescs[0]);
  27. for (UINT32 i = 0; i < numParamDescs; i++)
  28. {
  29. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[i];
  30. if (paramDesc == nullptr)
  31. continue;
  32. for (auto& paramBlock : paramDesc->paramBlocks)
  33. countElements(paramBlock.second, ParamType::ParamBlock);
  34. for (auto& texture : paramDesc->textures)
  35. countElements(texture.second, ParamType::Texture);
  36. for (auto& texture : paramDesc->loadStoreTextures)
  37. countElements(texture.second, ParamType::LoadStoreTexture);
  38. for (auto& buffer : paramDesc->buffers)
  39. countElements(buffer.second, ParamType::Buffer);
  40. for (auto& sampler : paramDesc->samplers)
  41. countElements(sampler.second, ParamType::SamplerState);
  42. }
  43. UINT32* numSlotsPerSet = (UINT32*)bs_stack_alloc(mNumSets * sizeof(UINT32));
  44. bs_zero_out(numSlotsPerSet, mNumSets);
  45. for (UINT32 i = 0; i < numParamDescs; i++)
  46. {
  47. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[i];
  48. if (paramDesc == nullptr)
  49. continue;
  50. for (auto& paramBlock : paramDesc->paramBlocks)
  51. numSlotsPerSet[paramBlock.second.set] =
  52. std::max(numSlotsPerSet[paramBlock.second.set], paramBlock.second.slot + 1);
  53. for (auto& texture : paramDesc->textures)
  54. numSlotsPerSet[texture.second.set] =
  55. std::max(numSlotsPerSet[texture.second.set], texture.second.slot + 1);
  56. for (auto& texture : paramDesc->loadStoreTextures)
  57. numSlotsPerSet[texture.second.set] =
  58. std::max(numSlotsPerSet[texture.second.set], texture.second.slot + 1);
  59. for (auto& buffer : paramDesc->buffers)
  60. numSlotsPerSet[buffer.second.set] =
  61. std::max(numSlotsPerSet[buffer.second.set], buffer.second.slot + 1);
  62. for (auto& sampler : paramDesc->samplers)
  63. numSlotsPerSet[sampler.second.set] =
  64. std::max(numSlotsPerSet[sampler.second.set], sampler.second.slot + 1);
  65. }
  66. UINT32 totalNumSlots = 0;
  67. for (UINT32 i = 0; i < mNumSets; i++)
  68. totalNumSlots += numSlotsPerSet[i];
  69. mAlloc.reserve<SetInfo>(mNumSets)
  70. .reserve<UINT32>(totalNumSlots)
  71. .reserve<ParamType>(totalNumSlots);
  72. for (UINT32 i = 0; i < (UINT32)ParamType::Count; i++)
  73. mAlloc.reserve<ResourceInfo>(mNumElementsPerType[i]);
  74. mAlloc.init();
  75. mSetInfos = mAlloc.alloc<SetInfo>(mNumSets);
  76. if(mSetInfos != nullptr)
  77. bs_zero_out(mSetInfos, mNumSets);
  78. for (UINT32 i = 0; i < mNumSets; i++)
  79. mSetInfos[i].numSlots = numSlotsPerSet[i];
  80. bs_stack_free(numSlotsPerSet);
  81. for(UINT32 i = 0; i < mNumSets; i++)
  82. {
  83. mSetInfos[i].slotIndices = mAlloc.alloc<UINT32>(mSetInfos[i].numSlots);
  84. memset(mSetInfos[i].slotIndices, -1, sizeof(UINT32) * mSetInfos[i].numSlots);
  85. mSetInfos[i].slotTypes = mAlloc.alloc<ParamType>(mSetInfos[i].numSlots);
  86. }
  87. for (UINT32 i = 0; i < (UINT32)ParamType::Count; i++)
  88. {
  89. mResourceInfos[i] = mAlloc.alloc<ResourceInfo>(mNumElementsPerType[i]);
  90. mNumElementsPerType[i] = 0;
  91. }
  92. auto populateSetInfo = [&](auto& entry, ParamType type)
  93. {
  94. int typeIdx = (int)type;
  95. UINT32 sequentialIdx = mNumElementsPerType[typeIdx];
  96. SetInfo& setInfo = mSetInfos[entry.set];
  97. setInfo.slotIndices[entry.slot] = sequentialIdx;
  98. setInfo.slotTypes[entry.slot] = type;
  99. mResourceInfos[typeIdx][sequentialIdx].set = entry.set;
  100. mResourceInfos[typeIdx][sequentialIdx].slot = entry.slot;
  101. mNumElementsPerType[typeIdx]++;
  102. };
  103. for (UINT32 i = 0; i < numParamDescs; i++)
  104. {
  105. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[i];
  106. if (paramDesc == nullptr)
  107. continue;
  108. for (auto& paramBlock : paramDesc->paramBlocks)
  109. populateSetInfo(paramBlock.second, ParamType::ParamBlock);
  110. for (auto& texture : paramDesc->textures)
  111. populateSetInfo(texture.second, ParamType::Texture);
  112. for (auto& texture : paramDesc->loadStoreTextures)
  113. populateSetInfo(texture.second, ParamType::LoadStoreTexture);
  114. for (auto& buffer : paramDesc->buffers)
  115. populateSetInfo(buffer.second, ParamType::Buffer);
  116. for (auto& sampler : paramDesc->samplers)
  117. populateSetInfo(sampler.second, ParamType::SamplerState);
  118. }
  119. }
  120. GpuPipelineParamInfoBase::~GpuPipelineParamInfoBase()
  121. { }
  122. UINT32 GpuPipelineParamInfoBase::getSequentialSlot(ParamType type, UINT32 set, UINT32 slot) const
  123. {
  124. #if BS_DEBUG_MODE
  125. if (set >= mNumSets)
  126. {
  127. LOGERR("Set index out of range: Valid range: [0, " +
  128. toString(mNumSets) + "). Requested: " + toString(set) + ".");
  129. return -1;
  130. }
  131. if (slot >= mSetInfos[set].numSlots)
  132. {
  133. LOGERR("Slot index out of range: Valid range: [0, " +
  134. toString(mSetInfos[set].numSlots) + "). Requested: " + toString(slot) + ".");
  135. return -1;
  136. }
  137. ParamType slotType = mSetInfos[set].slotTypes[slot];
  138. if(slotType != type)
  139. {
  140. // Allow sampler states & textures to share the same slot, as some APIs combine them
  141. bool potentialCombinedSampler = (slotType == ParamType::SamplerState && type == ParamType::Texture) ||
  142. (slotType == ParamType::Texture && type == ParamType::SamplerState);
  143. if (!potentialCombinedSampler)
  144. {
  145. LOGERR("Requested parameter is not of the valid type. Requested: " + toString((UINT32)type) + ". Actual: " +
  146. toString((UINT32)mSetInfos[set].slotTypes[slot]) + ".");
  147. return -1;
  148. }
  149. }
  150. #endif
  151. return mSetInfos[set].slotIndices[slot];
  152. }
  153. void GpuPipelineParamInfoBase::getSetSlot(ParamType type, UINT32 sequentialSlot, UINT32& set, UINT32& slot) const
  154. {
  155. #if BS_DEBUG_MODE
  156. if(sequentialSlot >= mNumElementsPerType[(int)type])
  157. {
  158. LOGERR("Sequential slot index out of range: Valid range: [0, " + toString(mNumElementsPerType[(int)type]) +
  159. "). Requested: " + toString(sequentialSlot) + ".");
  160. set = 0;
  161. slot = 0;
  162. return;
  163. }
  164. #endif
  165. set = mResourceInfos[(int)type][sequentialSlot].set;
  166. slot = mResourceInfos[(int)type][sequentialSlot].slot;
  167. }
  168. GpuPipelineParamInfo::GpuPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc)
  169. :GpuPipelineParamInfoBase(desc)
  170. { }
  171. SPtr<GpuPipelineParamInfo> GpuPipelineParamInfo::create(const GPU_PIPELINE_PARAMS_DESC& desc)
  172. {
  173. SPtr<GpuPipelineParamInfo> paramInfo =
  174. bs_core_ptr<GpuPipelineParamInfo>(new (bs_alloc<GpuPipelineParamInfo>()) GpuPipelineParamInfo(desc));
  175. paramInfo->_setThisPtr(paramInfo);
  176. paramInfo->initialize();
  177. return paramInfo;
  178. }
  179. SPtr<ct::GpuPipelineParamInfo> GpuPipelineParamInfo::getCore() const
  180. {
  181. return std::static_pointer_cast<ct::GpuPipelineParamInfo>(mCoreSpecific);
  182. }
  183. SPtr<ct::CoreObject> GpuPipelineParamInfo::createCore() const
  184. {
  185. GPU_PIPELINE_PARAMS_DESC desc;
  186. desc.fragmentParams = mParamDescs[GPT_FRAGMENT_PROGRAM];
  187. desc.vertexParams = mParamDescs[GPT_VERTEX_PROGRAM];
  188. desc.geometryParams = mParamDescs[GPT_GEOMETRY_PROGRAM];
  189. desc.hullParams = mParamDescs[GPT_HULL_PROGRAM];
  190. desc.domainParams = mParamDescs[GPT_DOMAIN_PROGRAM];
  191. desc.computeParams = mParamDescs[GPT_COMPUTE_PROGRAM];
  192. return ct::RenderStateManager::instance()._createPipelineParamInfo(desc);
  193. }
  194. namespace ct
  195. {
  196. GpuPipelineParamInfo::GpuPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc, GpuDeviceFlags deviceMask)
  197. :GpuPipelineParamInfoBase(desc)
  198. { }
  199. SPtr<GpuPipelineParamInfo> GpuPipelineParamInfo::create(const GPU_PIPELINE_PARAMS_DESC& desc,
  200. GpuDeviceFlags deviceMask)
  201. {
  202. return RenderStateManager::instance().createPipelineParamInfo(desc, deviceMask);
  203. }
  204. }
  205. }