BsGpuPipelineParamInfo.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. SetInfo& setInfo = mSetInfos[entry.set];
  96. setInfo.slotIndices[entry.slot] = mNumElementsPerType[typeIdx];
  97. setInfo.slotTypes[entry.slot] = type;
  98. mNumElementsPerType[typeIdx]++;
  99. mResourceInfos[typeIdx]->set = entry.set;
  100. mResourceInfos[typeIdx]->slot = entry.slot;
  101. };
  102. for (UINT32 i = 0; i < numParamDescs; i++)
  103. {
  104. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[i];
  105. if (paramDesc == nullptr)
  106. continue;
  107. for (auto& paramBlock : paramDesc->paramBlocks)
  108. populateSetInfo(paramBlock.second, ParamType::ParamBlock);
  109. for (auto& texture : paramDesc->textures)
  110. populateSetInfo(texture.second, ParamType::Texture);
  111. for (auto& texture : paramDesc->loadStoreTextures)
  112. populateSetInfo(texture.second, ParamType::LoadStoreTexture);
  113. for (auto& buffer : paramDesc->buffers)
  114. populateSetInfo(buffer.second, ParamType::Buffer);
  115. for (auto& sampler : paramDesc->samplers)
  116. populateSetInfo(sampler.second, ParamType::SamplerState);
  117. }
  118. }
  119. GpuPipelineParamInfoBase::~GpuPipelineParamInfoBase()
  120. { }
  121. UINT32 GpuPipelineParamInfoBase::getSequentialSlot(ParamType type, UINT32 set, UINT32 slot) const
  122. {
  123. #if BS_DEBUG_MODE
  124. if (set >= mNumSets)
  125. {
  126. LOGERR("Set index out of range: Valid range: [0, " +
  127. toString(mNumSets) + "). Requested: " + toString(set) + ".");
  128. return -1;
  129. }
  130. if (slot >= mSetInfos[set].numSlots)
  131. {
  132. LOGERR("Slot index out of range: Valid range: [0, " +
  133. toString(mSetInfos[set].numSlots) + "). Requested: " + toString(slot) + ".");
  134. return -1;
  135. }
  136. ParamType slotType = mSetInfos[set].slotTypes[slot];
  137. if(slotType != type)
  138. {
  139. // Allow sampler states & textures to share the same slot, as some APIs combine them
  140. bool potentialCombinedSampler = (slotType == ParamType::SamplerState && type == ParamType::Texture) ||
  141. (slotType == ParamType::Texture && type == ParamType::SamplerState);
  142. if (!potentialCombinedSampler)
  143. {
  144. LOGERR("Requested parameter is not of the valid type. Requested: " + toString((UINT32)type) + ". Actual: " +
  145. toString((UINT32)mSetInfos[set].slotTypes[slot]) + ".");
  146. return -1;
  147. }
  148. }
  149. #endif
  150. return mSetInfos[set].slotIndices[slot];
  151. }
  152. void GpuPipelineParamInfoBase::getSetSlot(ParamType type, UINT32 sequentialSlot, UINT32& set, UINT32& slot) const
  153. {
  154. #if BS_DEBUG_MODE
  155. if(sequentialSlot >= mNumElementsPerType[(int)type])
  156. {
  157. LOGERR("Sequential slot index out of range: Valid range: [0, " + toString(mNumElementsPerType[(int)type]) +
  158. "). Requested: " + toString(sequentialSlot) + ".");
  159. set = 0;
  160. slot = 0;
  161. return;
  162. }
  163. #endif
  164. set = mResourceInfos[(int)type][sequentialSlot].set;
  165. slot = mResourceInfos[(int)type][sequentialSlot].slot;
  166. }
  167. GpuPipelineParamInfoCore::GpuPipelineParamInfoCore(const GPU_PIPELINE_PARAMS_DESC& desc, GpuDeviceFlags deviceMask)
  168. :GpuPipelineParamInfoBase(desc)
  169. { }
  170. SPtr<GpuPipelineParamInfoCore> GpuPipelineParamInfoCore::create(const GPU_PIPELINE_PARAMS_DESC& desc,
  171. GpuDeviceFlags deviceMask)
  172. {
  173. return RenderStateCoreManager::instance().createPipelineParamInfo(desc, deviceMask);
  174. }
  175. GpuPipelineParamInfo::GpuPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc)
  176. :GpuPipelineParamInfoBase(desc)
  177. { }
  178. SPtr<GpuPipelineParamInfo> GpuPipelineParamInfo::create(const GPU_PIPELINE_PARAMS_DESC& desc)
  179. {
  180. SPtr<GpuPipelineParamInfo> paramInfo =
  181. bs_core_ptr<GpuPipelineParamInfo>(new (bs_alloc<GpuPipelineParamInfo>()) GpuPipelineParamInfo(desc));
  182. paramInfo->_setThisPtr(paramInfo);
  183. paramInfo->initialize();
  184. return paramInfo;
  185. }
  186. SPtr<GpuPipelineParamInfoCore> GpuPipelineParamInfo::getCore() const
  187. {
  188. return std::static_pointer_cast<GpuPipelineParamInfoCore>(mCoreSpecific);
  189. }
  190. SPtr<CoreObjectCore> GpuPipelineParamInfo::createCore() const
  191. {
  192. GPU_PIPELINE_PARAMS_DESC desc;
  193. desc.fragmentParams = mParamDescs[GPT_FRAGMENT_PROGRAM];
  194. desc.vertexParams = mParamDescs[GPT_VERTEX_PROGRAM];
  195. desc.geometryParams = mParamDescs[GPT_GEOMETRY_PROGRAM];
  196. desc.hullParams = mParamDescs[GPT_HULL_PROGRAM];
  197. desc.domainParams = mParamDescs[GPT_DOMAIN_PROGRAM];
  198. desc.computeParams = mParamDescs[GPT_COMPUTE_PROGRAM];
  199. return RenderStateCoreManager::instance()._createPipelineParamInfo(desc);
  200. }
  201. }