BsParamBlocks.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsGpuParamDesc.h"
  4. #include "BsGpuParams.h"
  5. #include "BsRenderAPI.h"
  6. #include "BsGpuParamBlockBuffer.h"
  7. namespace BansheeEngine
  8. {
  9. /** @cond INTERNAL */
  10. /** @addtogroup Renderer
  11. * @{
  12. */
  13. /**
  14. * Starts a new custom parameter block. Custom parameter blocks allow you to create C++ structures that map directly
  15. * to GPU program buffers (e.g. uniform buffer in OpenGL or constant buffer in DX). Must be followed by BS_PARAM_BLOCK_END.
  16. */
  17. #define BS_PARAM_BLOCK_BEGIN(Name) \
  18. struct Name \
  19. { \
  20. Name() \
  21. { \
  22. Vector<GpuParamDataDesc> params = getEntries(); \
  23. RenderAPICore& rapi = RenderAPICore::instance(); \
  24. \
  25. mBlockDesc = rapi.generateParamBlockDesc(#Name, params); \
  26. \
  27. SPtr<GpuParamDesc> paramsDesc = bs_shared_ptr_new<GpuParamDesc>(); \
  28. paramsDesc->paramBlocks[#Name] = mBlockDesc; \
  29. for (auto& param : params) \
  30. paramsDesc->params[param.name] = param; \
  31. \
  32. mParams = GpuParamsCore::create(paramsDesc, rapi.getGpuProgramHasColumnMajorMatrices()); \
  33. \
  34. mBuffer = GpuParamBlockBufferCore::create(mBlockDesc.blockSize * sizeof(UINT32)); \
  35. mParams->setParamBlockBuffer(#Name, mBuffer); \
  36. initEntries(); \
  37. } \
  38. \
  39. const SPtr<GpuParamBlockBufferCore>& getBuffer() const { return mBuffer; } \
  40. const GpuParamBlockDesc& getDesc() const { return mBlockDesc; } \
  41. \
  42. private: \
  43. struct META_FirstEntry {}; \
  44. static void META_GetPrevEntries(Vector<GpuParamDataDesc>& params, META_FirstEntry id) { } \
  45. void META_InitPrevEntry(const SPtr<GpuParamsCore>& params, META_FirstEntry id) { } \
  46. \
  47. typedef META_FirstEntry
  48. /**
  49. * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls.
  50. */
  51. #define BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, NumElements) \
  52. META_Entry_##Name; \
  53. \
  54. struct META_NextEntry_##Name {}; \
  55. static void META_GetPrevEntries(Vector<GpuParamDataDesc>& params, META_NextEntry_##Name id) \
  56. { \
  57. META_GetPrevEntries(params, META_Entry_##Name##()); \
  58. \
  59. params.push_back(GpuParamDataDesc()); \
  60. GpuParamDataDesc& newEntry = params.back(); \
  61. newEntry.name = #Name; \
  62. newEntry.type = (GpuParamDataType)TGpuDataParamInfo<Type>::TypeId; \
  63. newEntry.arraySize = NumElements; \
  64. } \
  65. \
  66. void META_InitPrevEntry(const SPtr<GpuParamsCore>& params, META_NextEntry_##Name id) \
  67. { \
  68. META_InitPrevEntry(params, META_Entry_##Name##()); \
  69. params->getParam(#Name, Name); \
  70. } \
  71. \
  72. public: \
  73. TGpuDataParam<Type, true> Name; \
  74. \
  75. private: \
  76. typedef META_NextEntry_##Name
  77. /**
  78. * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls.
  79. */
  80. #define BS_PARAM_BLOCK_ENTRY(Type, Name) BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, 1)
  81. /** Ends parameter block definition. See BS_PARAM_BLOCK_BEGIN. */
  82. #define BS_PARAM_BLOCK_END \
  83. META_LastEntry; \
  84. \
  85. static Vector<GpuParamDataDesc> getEntries() \
  86. { \
  87. Vector<GpuParamDataDesc> entries; \
  88. META_GetPrevEntries(entries, META_LastEntry()); \
  89. return entries; \
  90. } \
  91. \
  92. void initEntries() \
  93. { \
  94. META_InitPrevEntry(mParams, META_LastEntry()); \
  95. } \
  96. \
  97. SPtr<GpuParamsCore> mParams; \
  98. SPtr<GpuParamBlockBufferCore> mBuffer; \
  99. GpuParamBlockDesc mBlockDesc; \
  100. };
  101. /** @} */
  102. /** @endcond */
  103. }