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