//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// #pragma once #include "BsCorePrerequisites.h" #include "BsGpuParamDesc.h" #include "BsGpuParams.h" #include "BsRenderAPI.h" #include "BsGpuParamBlockBuffer.h" namespace BansheeEngine { /** @addtogroup Renderer-Internal * @{ */ /** * Starts a new custom parameter block. Custom parameter blocks allow you to create C++ structures that map directly * to GPU program buffers (for example uniform buffer in OpenGL or constant buffer in DX). Must be followed by * BS_PARAM_BLOCK_END. */ #define BS_PARAM_BLOCK_BEGIN(Name) \ struct Name \ { \ Name() \ { \ Vector params = getEntries(); \ RenderAPICore& rapi = RenderAPICore::instance(); \ \ mBlockDesc = rapi.generateParamBlockDesc(#Name, params); \ \ SPtr paramsDesc = bs_shared_ptr_new(); \ paramsDesc->paramBlocks[#Name] = mBlockDesc; \ for (auto& param : params) \ paramsDesc->params[param.name] = param; \ \ mParams = GpuParamsCore::create(paramsDesc); \ \ mBuffer = GpuParamBlockBufferCore::create(mBlockDesc.blockSize * sizeof(UINT32)); \ mParams->setParamBlockBuffer(#Name, mBuffer); \ initEntries(); \ } \ \ const SPtr& getBuffer() const { return mBuffer; } \ const GpuParamBlockDesc& getDesc() const { return mBlockDesc; } \ void flushToGPU() { mBuffer->flushToGPU(); } \ \ private: \ struct META_FirstEntry {}; \ static void META_GetPrevEntries(Vector& params, META_FirstEntry id) { } \ void META_InitPrevEntry(const SPtr& params, META_FirstEntry id) { } \ \ typedef META_FirstEntry /** * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls. */ #define BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, NumElements) \ META_Entry_##Name; \ \ struct META_NextEntry_##Name {}; \ static void META_GetPrevEntries(Vector& params, META_NextEntry_##Name id) \ { \ META_GetPrevEntries(params, META_Entry_##Name()); \ \ params.push_back(GpuParamDataDesc()); \ GpuParamDataDesc& newEntry = params.back(); \ newEntry.name = #Name; \ newEntry.type = (GpuParamDataType)TGpuDataParamInfo::TypeId; \ newEntry.arraySize = NumElements; \ } \ \ void META_InitPrevEntry(const SPtr& params, META_NextEntry_##Name id) \ { \ META_InitPrevEntry(params, META_Entry_##Name()); \ params->getParam(#Name, Name); \ } \ \ public: \ TGpuDataParam Name; \ \ private: \ typedef META_NextEntry_##Name /** * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls. */ #define BS_PARAM_BLOCK_ENTRY(Type, Name) BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, 1) /** Ends parameter block definition. See BS_PARAM_BLOCK_BEGIN. */ #define BS_PARAM_BLOCK_END \ META_LastEntry; \ \ static Vector getEntries() \ { \ Vector entries; \ META_GetPrevEntries(entries, META_LastEntry()); \ return entries; \ } \ \ void initEntries() \ { \ META_InitPrevEntry(mParams, META_LastEntry()); \ } \ \ SPtr mParams; \ SPtr mBuffer; \ GpuParamBlockDesc mBlockDesc; \ }; /** @} */ }