BsParamBlocks.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "BsGpuParamDesc.h"
  6. #include "BsGpuParams.h"
  7. #include "BsGpuPipelineParamInfo.h"
  8. #include "BsRenderAPI.h"
  9. #include "BsGpuParamBlockBuffer.h"
  10. namespace bs
  11. {
  12. /** @addtogroup Renderer-Internal
  13. * @{
  14. */
  15. // Note: Every time one of these param blocks is instantiated we generate its descriptor. It would be better to generate
  16. // it once, and then just quickly instantiate for subsequent creations.
  17. /**
  18. * Starts a new custom parameter block. Custom parameter blocks allow you to create C++ structures that map directly
  19. * to GPU program buffers (for example uniform buffer in OpenGL or constant buffer in DX). Must be followed by
  20. * BS_PARAM_BLOCK_END.
  21. */
  22. #define BS_PARAM_BLOCK_BEGIN(Name) \
  23. struct Name \
  24. { \
  25. Name() \
  26. { \
  27. static SPtr<GpuPipelineParamInfoCore> paramInfo = nullptr; \
  28. static GpuParamBlockDesc blockDesc; \
  29. \
  30. if (paramInfo == nullptr) \
  31. { \
  32. Vector<GpuParamDataDesc> params = getEntries(); \
  33. RenderAPICore& rapi = RenderAPICore::instance(); \
  34. \
  35. blockDesc = rapi.generateParamBlockDesc(#Name, params); \
  36. \
  37. SPtr<GpuParamDesc> paramsDesc = bs_shared_ptr_new<GpuParamDesc>(); \
  38. paramsDesc->paramBlocks[#Name] = blockDesc; \
  39. for (auto& param : params) \
  40. paramsDesc->params[param.name] = param; \
  41. \
  42. GPU_PIPELINE_PARAMS_DESC pipelineParamDesc; \
  43. pipelineParamDesc.vertexParams = paramsDesc; \
  44. paramInfo = GpuPipelineParamInfoCore::create(pipelineParamDesc); \
  45. } \
  46. \
  47. mParams = GpuParamsCore::create(paramInfo); \
  48. \
  49. mBuffer = GpuParamBlockBufferCore::create(blockDesc.blockSize * sizeof(UINT32)); \
  50. mParams->setParamBlockBuffer(GPT_VERTEX_PROGRAM, #Name, mBuffer); \
  51. initEntries(); \
  52. } \
  53. \
  54. const SPtr<GpuParamBlockBufferCore>& getBuffer() const { return mBuffer; } \
  55. void setBuffer(const SPtr<GpuParamBlockBufferCore>& buffer) \
  56. { \
  57. mBuffer = buffer; \
  58. mParams->setParamBlockBuffer(GPT_VERTEX_PROGRAM, #Name, mBuffer); \
  59. } \
  60. void flushToGPU(UINT32 queueIdx = 0) { mBuffer->flushToGPU(queueIdx); } \
  61. \
  62. private: \
  63. struct META_FirstEntry {}; \
  64. static void META_GetPrevEntries(Vector<GpuParamDataDesc>& params, META_FirstEntry id) { } \
  65. void META_InitPrevEntry(const SPtr<GpuParamsCore>& params, META_FirstEntry id) { } \
  66. \
  67. typedef META_FirstEntry
  68. /**
  69. * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls.
  70. */
  71. #define BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, NumElements) \
  72. META_Entry_##Name; \
  73. \
  74. struct META_NextEntry_##Name {}; \
  75. static void META_GetPrevEntries(Vector<GpuParamDataDesc>& params, META_NextEntry_##Name id) \
  76. { \
  77. META_GetPrevEntries(params, META_Entry_##Name()); \
  78. \
  79. params.push_back(GpuParamDataDesc()); \
  80. GpuParamDataDesc& newEntry = params.back(); \
  81. newEntry.name = #Name; \
  82. newEntry.type = (GpuParamDataType)TGpuDataParamInfo<Type>::TypeId; \
  83. newEntry.arraySize = NumElements; \
  84. } \
  85. \
  86. void META_InitPrevEntry(const SPtr<GpuParamsCore>& params, META_NextEntry_##Name id) \
  87. { \
  88. META_InitPrevEntry(params, META_Entry_##Name()); \
  89. params->getParam(GPT_VERTEX_PROGRAM, #Name, Name); \
  90. } \
  91. \
  92. public: \
  93. TGpuDataParam<Type, true> Name; \
  94. \
  95. private: \
  96. typedef META_NextEntry_##Name
  97. /**
  98. * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls.
  99. */
  100. #define BS_PARAM_BLOCK_ENTRY(Type, Name) BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, 1)
  101. /** Ends parameter block definition. See BS_PARAM_BLOCK_BEGIN. */
  102. #define BS_PARAM_BLOCK_END \
  103. META_LastEntry; \
  104. \
  105. static Vector<GpuParamDataDesc> getEntries() \
  106. { \
  107. Vector<GpuParamDataDesc> entries; \
  108. META_GetPrevEntries(entries, META_LastEntry()); \
  109. return entries; \
  110. } \
  111. \
  112. void initEntries() \
  113. { \
  114. META_InitPrevEntry(mParams, META_LastEntry()); \
  115. } \
  116. \
  117. SPtr<GpuParamsCore> mParams; \
  118. SPtr<GpuParamBlockBufferCore> mBuffer; \
  119. };
  120. /** @} */
  121. }