//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// #include "RenderAPI/BsGpuParams.h" #include "RenderAPI/BsGpuParamDesc.h" #include "RenderAPI/BsGpuParamBlockBuffer.h" #include "RenderAPI/BsGpuPipelineParamInfo.h" #include "RenderAPI/BsGpuPipelineState.h" #include "Math/BsVector2.h" #include "Image/BsTexture.h" #include "RenderAPI/BsGpuBuffer.h" #include "RenderAPI/BsSamplerState.h" #include "Allocators/BsFrameAlloc.h" #include "Debug/BsDebug.h" #include "Error/BsException.h" #include "Math/BsVectorNI.h" #include "Math/BsMatrixNxM.h" #include "Managers/BsHardwareBufferManager.h" namespace bs { const TextureSurface TextureSurface::COMPLETE = TextureSurface(0, 0, 0, 0); GpuParamsBase::GpuParamsBase(const SPtr& paramInfo) :mParamInfo(paramInfo) { } GpuParamsBase::~GpuParamsBase() { } SPtr GpuParamsBase::getParamDesc(GpuProgramType type) const { return mParamInfo->getParamDesc(type); } UINT32 GpuParamsBase::getDataParamSize(GpuProgramType type, const String& name) const { GpuParamDataDesc* desc = getParamDesc(type, name); if(desc != nullptr) return desc->elementSize * 4; return 0; } bool GpuParamsBase::hasParam(GpuProgramType type, const String& name) const { return getParamDesc(type, name) != nullptr; } bool GpuParamsBase::hasTexture(GpuProgramType type, const String& name) const { const SPtr& paramDesc = mParamInfo->getParamDesc(type); if (paramDesc == nullptr) return false; auto paramIter = paramDesc->textures.find(name); if(paramIter != paramDesc->textures.end()) return true; return false; } bool GpuParamsBase::hasBuffer(GpuProgramType type, const String& name) const { const SPtr& paramDesc = mParamInfo->getParamDesc(type); if (paramDesc == nullptr) return false; auto paramIter = paramDesc->buffers.find(name); if (paramIter != paramDesc->buffers.end()) return true; return false; } bool GpuParamsBase::hasLoadStoreTexture(GpuProgramType type, const String& name) const { const SPtr& paramDesc = mParamInfo->getParamDesc(type); if (paramDesc == nullptr) return false; auto paramIter = paramDesc->loadStoreTextures.find(name); if (paramIter != paramDesc->loadStoreTextures.end()) return true; return false; } bool GpuParamsBase::hasSamplerState(GpuProgramType type, const String& name) const { const SPtr& paramDesc = mParamInfo->getParamDesc(type); if (paramDesc == nullptr) return false; auto paramIter = paramDesc->samplers.find(name); if(paramIter != paramDesc->samplers.end()) return true; return false; } bool GpuParamsBase::hasParamBlock(GpuProgramType type, const String& name) const { const SPtr& paramDesc = mParamInfo->getParamDesc(type); if (paramDesc == nullptr) return false; auto paramBlockIter = paramDesc->paramBlocks.find(name); if(paramBlockIter != paramDesc->paramBlocks.end()) return true; return false; } GpuParamDataDesc* GpuParamsBase::getParamDesc(GpuProgramType type, const String& name) const { const SPtr& paramDesc = mParamInfo->getParamDesc(type); if (paramDesc == nullptr) return nullptr; auto paramIter = paramDesc->params.find(name); if (paramIter != paramDesc->params.end()) return ¶mIter->second; return nullptr; } GpuParamBlockDesc* GpuParamsBase::getParamBlockDesc(GpuProgramType type, const String& name) const { const SPtr& paramDesc = mParamInfo->getParamDesc(type); if (paramDesc == nullptr) return nullptr; auto paramBlockIter = paramDesc->paramBlocks.find(name); if (paramBlockIter != paramDesc->paramBlocks.end()) return ¶mBlockIter->second; return nullptr; } template TGpuParams::TGpuParams(const SPtr& paramInfo) : GpuParamsBase(paramInfo) { UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock); UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture); UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture); UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer); UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState); UINT32 paramBlocksSize = sizeof(ParamsBufferType) * numParamBlocks; UINT32 texturesSize = (sizeof(TextureType) + sizeof(TextureSurface)) * numTextures; UINT32 loadStoreTexturesSize = (sizeof(TextureType) + sizeof(TextureSurface)) * numStorageTextures; UINT32 buffersSize = sizeof(BufferType) * numBuffers; UINT32 samplerStatesSize = sizeof(SamplerType) * numSamplers; UINT32 totalSize = paramBlocksSize + texturesSize + loadStoreTexturesSize + buffersSize + samplerStatesSize; UINT8* data = (UINT8*)bs_alloc(totalSize); mParamBlockBuffers = (ParamsBufferType*)data; for (UINT32 i = 0; i < numParamBlocks; i++) new (&mParamBlockBuffers[i]) ParamsBufferType(); data += paramBlocksSize; mSampledTextureData = (TextureData*)data; for (UINT32 i = 0; i < numTextures; i++) { new (&mSampledTextureData[i].texture) TextureType(); new (&mSampledTextureData[i].surface) TextureSurface(0, 0, 0, 0); } data += texturesSize; mLoadStoreTextureData = (TextureData*)data; for (UINT32 i = 0; i < numStorageTextures; i++) { new (&mLoadStoreTextureData[i].texture) TextureType(); new (&mLoadStoreTextureData[i].surface) TextureSurface(0, 0, 0, 0); } data += loadStoreTexturesSize; mBuffers = (BufferType*)data; for (UINT32 i = 0; i < numBuffers; i++) new (&mBuffers[i]) BufferType(); data += buffersSize; mSamplerStates = (SamplerType*)data; for (UINT32 i = 0; i < numSamplers; i++) new (&mSamplerStates[i]) SamplerType(); data += samplerStatesSize; } template TGpuParams::~TGpuParams() { UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock); UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture); UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture); UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer); UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState); for (UINT32 i = 0; i < numParamBlocks; i++) mParamBlockBuffers[i].~ParamsBufferType(); for (UINT32 i = 0; i < numTextures; i++) { mSampledTextureData[i].texture.~TextureType(); mSampledTextureData[i].surface.~TextureSurface(); } for (UINT32 i = 0; i < numStorageTextures; i++) { mLoadStoreTextureData[i].texture.~TextureType(); mLoadStoreTextureData[i].surface.~TextureSurface(); } for (UINT32 i = 0; i < numBuffers; i++) mBuffers[i].~BufferType(); for (UINT32 i = 0; i < numSamplers; i++) mSamplerStates[i].~SamplerType(); // Everything is allocated in a single block, so it's enough to free the first element bs_free(mParamBlockBuffers); } template void TGpuParams::setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer) { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::ParamBlock, set, slot); if (globalSlot == (UINT32)-1) return; mParamBlockBuffers[globalSlot] = paramBlockBuffer; _markCoreDirty(); } template void TGpuParams::setParamBlockBuffer(GpuProgramType type, const String& name, const ParamsBufferType& paramBlockBuffer) { const SPtr& paramDescs = mParamInfo->getParamDesc(type); if(paramDescs == nullptr) { LOGWRN("Cannot find parameter block with the name: '" + name + "'"); return; } auto iterFind = paramDescs->paramBlocks.find(name); if (iterFind == paramDescs->paramBlocks.end()) { LOGWRN("Cannot find parameter block with the name: '" + name + "'"); return; } setParamBlockBuffer(iterFind->second.set, iterFind->second.slot, paramBlockBuffer); } template template void TGpuParams::getParam(GpuProgramType type, const String& name, TGpuDataParam& output) const { const SPtr& paramDescs = mParamInfo->getParamDesc(type); if (paramDescs == nullptr) { output = TGpuDataParam(nullptr, nullptr); LOGWRN("Cannot find parameter block with the name: '" + name + "'"); return; } auto iterFind = paramDescs->params.find(name); if (iterFind == paramDescs->params.end()) { output = TGpuDataParam(nullptr, nullptr); LOGWRN("Cannot find parameter with the name '" + name + "'"); } else output = TGpuDataParam(&iterFind->second, _getThisPtr()); } template void TGpuParams::getStructParam(GpuProgramType type, const String& name, TGpuParamStruct& output) const { const SPtr& paramDescs = mParamInfo->getParamDesc(type); if (paramDescs == nullptr) { output = TGpuParamStruct(nullptr, nullptr); LOGWRN("Cannot find struct parameter with the name: '" + name + "'"); return; } auto iterFind = paramDescs->params.find(name); if (iterFind == paramDescs->params.end() || iterFind->second.type != GPDT_STRUCT) { output = TGpuParamStruct(nullptr, nullptr); LOGWRN("Cannot find struct parameter with the name '" + name + "'"); } else output = TGpuParamStruct(&iterFind->second, _getThisPtr()); } template void TGpuParams::getTextureParam(GpuProgramType type, const String& name, TGpuParamTexture& output) const { const SPtr& paramDescs = mParamInfo->getParamDesc(type); if (paramDescs == nullptr) { output = TGpuParamTexture(nullptr, nullptr); LOGWRN("Cannot find texture parameter with the name: '" + name + "'"); return; } auto iterFind = paramDescs->textures.find(name); if (iterFind == paramDescs->textures.end()) { output = TGpuParamTexture(nullptr, nullptr); LOGWRN("Cannot find texture parameter with the name '" + name + "'"); } else output = TGpuParamTexture(&iterFind->second, _getThisPtr()); } template void TGpuParams::getLoadStoreTextureParam(GpuProgramType type, const String& name, TGpuParamLoadStoreTexture& output) const { const SPtr& paramDescs = mParamInfo->getParamDesc(type); if (paramDescs == nullptr) { output = TGpuParamLoadStoreTexture(nullptr, nullptr); LOGWRN("Cannot find texture parameter with the name: '" + name + "'"); return; } auto iterFind = paramDescs->loadStoreTextures.find(name); if (iterFind == paramDescs->loadStoreTextures.end()) { output = TGpuParamLoadStoreTexture(nullptr, nullptr); LOGWRN("Cannot find texture parameter with the name '" + name + "'"); } else output = TGpuParamLoadStoreTexture(&iterFind->second, _getThisPtr()); } template void TGpuParams::getBufferParam(GpuProgramType type, const String& name, TGpuParamBuffer& output) const { const SPtr& paramDescs = mParamInfo->getParamDesc(type); if (paramDescs == nullptr) { output = TGpuParamBuffer(nullptr, nullptr); LOGWRN("Cannot find buffer parameter with the name: '" + name + "'"); return; } auto iterFind = paramDescs->buffers.find(name); if (iterFind == paramDescs->buffers.end()) { output = TGpuParamBuffer(nullptr, nullptr); LOGWRN("Cannot find buffer parameter with the name '" + name + "'"); } else output = TGpuParamBuffer(&iterFind->second, _getThisPtr()); } template void TGpuParams::getSamplerStateParam(GpuProgramType type, const String& name, TGpuParamSampState& output) const { const SPtr& paramDescs = mParamInfo->getParamDesc(type); if (paramDescs == nullptr) { output = TGpuParamSampState(nullptr, nullptr); LOGWRN("Cannot find sampler state parameter with the name: '" + name + "'"); return; } auto iterFind = paramDescs->samplers.find(name); if (iterFind == paramDescs->samplers.end()) { output = TGpuParamSampState(nullptr, nullptr); LOGWRN("Cannot find sampler state parameter with the name '" + name + "'"); } else output = TGpuParamSampState(&iterFind->second, _getThisPtr()); } template typename TGpuParams::ParamsBufferType TGpuParams::getParamBlockBuffer(UINT32 set, UINT32 slot) const { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::ParamBlock, set, slot); if (globalSlot == (UINT32)-1) return nullptr; return mParamBlockBuffers[globalSlot]; } template typename TGpuParams::TextureType TGpuParams::getTexture(UINT32 set, UINT32 slot) const { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot); if (globalSlot == (UINT32)-1) return TGpuParams::TextureType(); return mSampledTextureData[globalSlot].texture; } template typename TGpuParams::TextureType TGpuParams::getLoadStoreTexture(UINT32 set, UINT32 slot) const { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::LoadStoreTexture, set, slot); if (globalSlot == (UINT32)-1) return TGpuParams::TextureType(); return mLoadStoreTextureData[globalSlot].texture; } template typename TGpuParams::BufferType TGpuParams::getBuffer(UINT32 set, UINT32 slot) const { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Buffer, set, slot); if (globalSlot == (UINT32)-1) return nullptr; return mBuffers[globalSlot]; } template typename TGpuParams::SamplerType TGpuParams::getSamplerState(UINT32 set, UINT32 slot) const { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::SamplerState, set, slot); if (globalSlot == (UINT32)-1) return nullptr; return mSamplerStates[globalSlot]; } template const TextureSurface& TGpuParams::getTextureSurface(UINT32 set, UINT32 slot) const { static TextureSurface emptySurface; UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot); if (globalSlot == (UINT32)-1) return emptySurface; return mSampledTextureData[globalSlot].surface; } template const TextureSurface& TGpuParams::getLoadStoreSurface(UINT32 set, UINT32 slot) const { static TextureSurface emptySurface; UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::LoadStoreTexture, set, slot); if (globalSlot == (UINT32)-1) return emptySurface; return mLoadStoreTextureData[globalSlot].surface; } template void TGpuParams::setTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface) { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot); if (globalSlot == (UINT32)-1) return; mSampledTextureData[globalSlot].texture = texture; mSampledTextureData[globalSlot].surface = surface; _markResourcesDirty(); _markCoreDirty(); } template void TGpuParams::setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface) { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::LoadStoreTexture, set, slot); if (globalSlot == (UINT32)-1) return; mLoadStoreTextureData[globalSlot].texture = texture; mLoadStoreTextureData[globalSlot].surface = surface; _markResourcesDirty(); _markCoreDirty(); } template void TGpuParams::setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer) { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Buffer, set, slot); if (globalSlot == (UINT32)-1) return; mBuffers[globalSlot] = buffer; _markResourcesDirty(); _markCoreDirty(); } template void TGpuParams::setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler) { UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::SamplerState, set, slot); if (globalSlot == (UINT32)-1) return; mSamplerStates[globalSlot] = sampler; _markResourcesDirty(); _markCoreDirty(); } template class TGpuParams < false > ; template class TGpuParams < true > ; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; template BS_CORE_EXPORT void TGpuParams::getParam(GpuProgramType type, const String&, TGpuDataParam&) const; const GpuDataParamInfos GpuParams::PARAM_SIZES; GpuParams::GpuParams(const SPtr& paramInfo) : TGpuParams(paramInfo) { } SPtr GpuParams::_getThisPtr() const { return std::static_pointer_cast(getThisPtr()); } SPtr GpuParams::getCore() const { return std::static_pointer_cast(mCoreSpecific); } SPtr GpuParams::createCore() const { SPtr paramInfo = std::static_pointer_cast(mParamInfo); return ct::HardwareBufferManager::instance().createGpuParams(paramInfo->getCore()); } void GpuParams::_markCoreDirty() { markCoreDirty(); } void GpuParams::_markResourcesDirty() { markListenerResourcesDirty(); } SPtr GpuParams::create(const SPtr& pipelineState) { return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo()); } SPtr GpuParams::create(const SPtr& pipelineState) { return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo()); } SPtr GpuParams::create(const SPtr& paramInfo) { return HardwareBufferManager::instance().createGpuParams(paramInfo); } CoreSyncData GpuParams::syncToCore(FrameAlloc* allocator) { UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock); UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture); UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture); UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer); UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState); UINT32 sampledSurfacesSize = numTextures * sizeof(TextureSurface); UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface); UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr); UINT32 textureArraySize = numTextures * sizeof(SPtr); UINT32 loadStoreTextureArraySize = numStorageTextures * sizeof(SPtr); UINT32 bufferArraySize = numBuffers * sizeof(SPtr); UINT32 samplerArraySize = numSamplers * sizeof(SPtr); UINT32 totalSize = sampledSurfacesSize + loadStoreSurfacesSize + paramBufferSize + textureArraySize + loadStoreTextureArraySize + bufferArraySize + samplerArraySize; UINT32 sampledSurfaceOffset = 0; UINT32 loadStoreSurfaceOffset = sampledSurfaceOffset + sampledSurfacesSize; UINT32 paramBufferOffset = loadStoreSurfaceOffset + loadStoreSurfacesSize; UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize; UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize; UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize; UINT32 samplerArrayOffset = bufferArrayOffset + bufferArraySize; UINT8* data = allocator->alloc(totalSize); TextureSurface* sampledSurfaces = (TextureSurface*)(data + sampledSurfaceOffset); TextureSurface* loadStoreSurfaces = (TextureSurface*)(data + loadStoreSurfaceOffset); SPtr* paramBuffers = (SPtr*)(data + paramBufferOffset); SPtr* textures = (SPtr*)(data + textureArrayOffset); SPtr* loadStoreTextures = (SPtr*)(data + loadStoreTextureArrayOffset); SPtr* buffers = (SPtr*)(data + bufferArrayOffset); SPtr* samplers = (SPtr*)(data + samplerArrayOffset); // Construct & copy for (UINT32 i = 0; i < numParamBlocks; i++) { new (¶mBuffers[i]) SPtr(); if (mParamBlockBuffers[i] != nullptr) paramBuffers[i] = mParamBlockBuffers[i]->getCore(); } for (UINT32 i = 0; i < numTextures; i++) { new (&sampledSurfaces[i]) TextureSurface(); sampledSurfaces[i] = mSampledTextureData[i].surface; new (&textures[i]) SPtr(); if (mSampledTextureData[i].texture.isLoaded()) textures[i] = mSampledTextureData[i].texture->getCore(); else textures[i] = nullptr; } for (UINT32 i = 0; i < numStorageTextures; i++) { new (&loadStoreSurfaces[i]) TextureSurface(); loadStoreSurfaces[i] = mLoadStoreTextureData[i].surface; new (&loadStoreTextures[i]) SPtr(); if (mLoadStoreTextureData[i].texture.isLoaded()) loadStoreTextures[i] = mLoadStoreTextureData[i].texture->getCore(); else loadStoreTextures[i] = nullptr; } for (UINT32 i = 0; i < numBuffers; i++) { new (&buffers[i]) SPtr(); if (mBuffers[i] != nullptr) buffers[i] = mBuffers[i]->getCore(); else buffers[i] = nullptr; } for (UINT32 i = 0; i < numSamplers; i++) { new (&samplers[i]) SPtr(); if (mSamplerStates[i] != nullptr) samplers[i] = mSamplerStates[i]->getCore(); else samplers[i] = nullptr; } return CoreSyncData(data, totalSize); } void GpuParams::getListenerResources(Vector& resources) { UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture); UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture); for (UINT32 i = 0; i < numTextures; i++) { if (mSampledTextureData[i].texture != nullptr) resources.push_back(mSampledTextureData[i].texture); } for (UINT32 i = 0; i < numStorageTextures; i++) { if (mLoadStoreTextureData[i].texture != nullptr) resources.push_back(mLoadStoreTextureData[i].texture); } } namespace ct { GpuParams::GpuParams(const SPtr& paramInfo, GpuDeviceFlags deviceMask) : TGpuParams(paramInfo) { } SPtr GpuParams::_getThisPtr() const { return std::static_pointer_cast(getThisPtr()); } void GpuParams::syncToCore(const CoreSyncData& data) { UINT32 numParamBlocks = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::ParamBlock); UINT32 numTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Texture); UINT32 numStorageTextures = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::LoadStoreTexture); UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer); UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState); UINT32 sampledSurfacesSize = numTextures * sizeof(TextureSurface); UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface); UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr); UINT32 textureArraySize = numTextures * sizeof(SPtr); UINT32 loadStoreTextureArraySize = numStorageTextures * sizeof(SPtr); UINT32 bufferArraySize = numBuffers * sizeof(SPtr); UINT32 samplerArraySize = numSamplers * sizeof(SPtr); UINT32 totalSize = sampledSurfacesSize + loadStoreSurfacesSize + paramBufferSize + textureArraySize + loadStoreTextureArraySize + bufferArraySize + samplerArraySize; UINT32 sampledSurfacesOffset = 0; UINT32 loadStoreSurfaceOffset = sampledSurfacesOffset + sampledSurfacesSize; UINT32 paramBufferOffset = loadStoreSurfaceOffset + loadStoreSurfacesSize; UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize; UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize; UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize; UINT32 samplerArrayOffset = bufferArrayOffset + bufferArraySize; assert(data.getBufferSize() == totalSize); UINT8* dataPtr = data.getBuffer(); TextureSurface* sampledSurfaces = (TextureSurface*)(dataPtr + sampledSurfacesOffset); TextureSurface* loadStoreSurfaces = (TextureSurface*)(dataPtr + loadStoreSurfaceOffset); SPtr* paramBuffers = (SPtr*)(dataPtr + paramBufferOffset); SPtr* textures = (SPtr*)(dataPtr + textureArrayOffset); SPtr* loadStoreTextures = (SPtr*)(dataPtr + loadStoreTextureArrayOffset); SPtr* buffers = (SPtr*)(dataPtr + bufferArrayOffset); SPtr* samplers = (SPtr*)(dataPtr + samplerArrayOffset); // Copy & destruct for (UINT32 i = 0; i < numParamBlocks; i++) { mParamBlockBuffers[i] = paramBuffers[i]; paramBuffers[i].~SPtr(); } for (UINT32 i = 0; i < numTextures; i++) { mSampledTextureData[i].surface = sampledSurfaces[i]; loadStoreSurfaces[i].~TextureSurface(); mSampledTextureData[i].texture = textures[i]; textures[i].~SPtr(); } for (UINT32 i = 0; i < numStorageTextures; i++) { mLoadStoreTextureData[i].surface = loadStoreSurfaces[i]; loadStoreSurfaces[i].~TextureSurface(); mLoadStoreTextureData[i].texture = loadStoreTextures[i]; loadStoreTextures[i].~SPtr(); } for (UINT32 i = 0; i < numBuffers; i++) { mBuffers[i] = buffers[i]; buffers[i].~SPtr(); } for (UINT32 i = 0; i < numSamplers; i++) { mSamplerStates[i] = samplers[i]; samplers[i].~SPtr(); } } SPtr GpuParams::create(const SPtr& pipelineState, GpuDeviceFlags deviceMask) { return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo(), deviceMask); } SPtr GpuParams::create(const SPtr& pipelineState, GpuDeviceFlags deviceMask) { return HardwareBufferManager::instance().createGpuParams(pipelineState->getParamInfo(), deviceMask); } SPtr GpuParams::create(const SPtr& paramInfo, GpuDeviceFlags deviceMask) { return HardwareBufferManager::instance().createGpuParams(paramInfo, deviceMask); } } }