aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/module/iofx/src/IofxScene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'APEX_1.4/module/iofx/src/IofxScene.cpp')
-rw-r--r--APEX_1.4/module/iofx/src/IofxScene.cpp527
1 files changed, 527 insertions, 0 deletions
diff --git a/APEX_1.4/module/iofx/src/IofxScene.cpp b/APEX_1.4/module/iofx/src/IofxScene.cpp
new file mode 100644
index 00000000..400fca10
--- /dev/null
+++ b/APEX_1.4/module/iofx/src/IofxScene.cpp
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+
+#include "Apex.h"
+#include "ApexUsingNamespace.h"
+#include "ModuleIofxImpl.h"
+#include "IofxSceneCPU.h"
+#include "IofxSceneGPU.h"
+#include "IofxAssetImpl.h"
+#include "IofxActorImpl.h"
+#include "IofxActorCPU.h"
+#include "IofxDebugRenderParams.h"
+#include "DebugRenderParams.h"
+#include "RenderVolumeImpl.h"
+#include "SceneIntl.h"
+#include "ModulePerfScope.h"
+#include "RenderDebugInterface.h"
+
+#if APEX_CUDA_SUPPORT
+#include <cuda.h>
+#include "ApexCutil.h"
+#include "IofxActorGPU.h"
+
+#include "ApexCudaSource.h"
+#endif
+
+#include "Lock.h"
+
+namespace nvidia
+{
+namespace iofx
+{
+
+IofxRenderable* IofxRenderableIteratorImpl::findNextInActorList()
+{
+ for (; mActorIndex < mActorCount; ++mActorIndex)
+ {
+ IofxRenderable* result = mActorList[mActorIndex]->acquireRenderableReference();
+ if (result != NULL)
+ {
+ return result;
+ }
+ }
+ mIofxScene.mLiveRenderVolumes[mVolumeIndex]->unlockIofxActorList();
+ return NULL;
+}
+
+IofxRenderable* IofxRenderableIteratorImpl::findFirstInNotEmptyVolume()
+{
+ for (; mVolumeIndex < mVolumeCount; ++mVolumeIndex)
+ {
+ mActorList = mIofxScene.mLiveRenderVolumes[mVolumeIndex]->lockIofxActorList(mActorCount);
+ mActorIndex = 0;
+ IofxRenderable* result = findNextInActorList();
+ if (result != NULL)
+ {
+ return result;
+ }
+ }
+ mIofxScene.mLiveRenderVolumesLock.unlockReader();
+ return NULL;
+}
+
+IofxRenderable* IofxRenderableIteratorImpl::getFirst()
+{
+ mIofxScene.mLiveRenderVolumesLock.lockReader();
+ mVolumeCount = mIofxScene.mLiveRenderVolumes.size();
+ mVolumeIndex = 0;
+ return findFirstInNotEmptyVolume();
+}
+
+IofxRenderable* IofxRenderableIteratorImpl::getNext()
+{
+ if (mVolumeIndex < mVolumeCount)
+ {
+ PX_ASSERT(mActorIndex < mActorCount);
+ ++mActorIndex;
+ IofxRenderable* result = findNextInActorList();
+ if (result != NULL)
+ {
+ return result;
+ }
+ ++mVolumeIndex;
+ return findFirstInNotEmptyVolume();
+ }
+ return NULL;
+}
+
+
+static StatsInfo IOFXStatsData[] =
+{
+ {"IOFX: SimulatedSpriteParticlesCount", StatDataType::INT, {{0}} },
+ {"IOFX: SimulatedMeshParticlesCount", StatDataType::INT, {{0}} }
+};
+
+IofxScene::IofxScene(ModuleIofxImpl& module, SceneIntl& scene, RenderDebugInterface* debugRender, ResourceList& list)
+ : mModule(&module)
+ , mApexScene(&scene)
+ , mDebugRender(debugRender)
+ , mPrevTotalSimulatedSpriteParticles(0)
+ , mPrevTotalSimulatedMeshParticles(0)
+ , mRenderCallback(NULL)
+{
+ list.add(*this); // Add self to module's list of IofxScenes
+
+ /* Initialize reference to IofxDebugRenderParams */
+ {
+ WRITE_LOCK(*mApexScene);
+ mDebugRenderParams = DYNAMIC_CAST(DebugRenderParams*)(mApexScene->getDebugRenderParams());
+ }
+ PX_ASSERT(mDebugRenderParams);
+ NvParameterized::Handle handle(*mDebugRenderParams), memberHandle(*mDebugRenderParams);
+ int size;
+
+ if (mDebugRenderParams->getParameterHandle("moduleName", handle) == NvParameterized::ERROR_NONE)
+ {
+ handle.getArraySize(size, 0);
+ handle.resizeArray(size + 1);
+ if (handle.getChildHandle(size, memberHandle) == NvParameterized::ERROR_NONE)
+ {
+ memberHandle.initParamRef(IofxDebugRenderParams::staticClassName(), true);
+ }
+ }
+
+ /* Load reference to IofxDebugRenderParams */
+ NvParameterized::Interface* refPtr = NULL;
+ memberHandle.getParamRef(refPtr);
+ mIofxDebugRenderParams = DYNAMIC_CAST(IofxDebugRenderParams*)(refPtr);
+ PX_ASSERT(mIofxDebugRenderParams);
+
+ createModuleStats();
+}
+
+IofxScene::~IofxScene()
+{
+ destroyModuleStats();
+}
+
+Module* IofxScene::getModule()
+{
+ return mModule;
+}
+
+void IofxScene::release()
+{
+ mModule->releaseModuleSceneIntl(*this);
+}
+
+IofxManager* IofxScene::createIofxManager(const IofxAsset& asset, const IofxManagerDescIntl& desc)
+{
+ mManagersLock.lockWriter();
+
+ IofxManager* iofxManager = PX_NEW(IofxManager)(*this, desc, asset.getMeshAssetCount() > 0);
+
+ mManagersLock.unlockWriter();
+
+ return iofxManager;
+}
+
+void IofxScene::releaseIofxManager(IofxManager* manager)
+{
+ mManagersLock.lockWriter();
+
+ manager->destroy();
+
+ mManagersLock.unlockWriter();
+}
+
+void IofxScene::createModuleStats(void)
+{
+ mModuleSceneStats.numApexStats = NumberOfStats;
+ mModuleSceneStats.ApexStatsInfoPtr = (StatsInfo*)PX_ALLOC(sizeof(StatsInfo) * NumberOfStats, PX_DEBUG_EXP("StatsInfo"));
+
+ for (uint32_t i = 0; i < NumberOfStats; i++)
+ {
+ mModuleSceneStats.ApexStatsInfoPtr[i] = IOFXStatsData[i];
+ }
+}
+
+void IofxScene::destroyModuleStats(void)
+{
+ mModuleSceneStats.numApexStats = 0;
+ if (mModuleSceneStats.ApexStatsInfoPtr)
+ {
+ PX_FREE_AND_RESET(mModuleSceneStats.ApexStatsInfoPtr);
+ }
+}
+
+void IofxScene::setStatValue(StatsDataEnum index, StatValue dataVal)
+{
+ if (mModuleSceneStats.ApexStatsInfoPtr)
+ {
+ mModuleSceneStats.ApexStatsInfoPtr[index].StatCurrentValue = dataVal;
+ }
+}
+
+void IofxScene::visualize()
+{
+#ifndef WITHOUT_DEBUG_VISUALIZE
+ if (!mIofxDebugRenderParams->VISUALIZE_IOFX_ACTOR)
+ {
+ return;
+ }
+
+ PxMat44 cameraFacingPose((mApexScene->getViewMatrix(0)).inverseRT());
+
+ const physx::PxMat44& savedPose = *RENDER_DEBUG_IFACE(mDebugRender)->getPoseTyped();
+ RENDER_DEBUG_IFACE(mDebugRender)->setIdentityPose();
+ RENDER_DEBUG_IFACE(mDebugRender)->pushRenderState();
+ RENDER_DEBUG_IFACE(mDebugRender)->setCurrentTextScale(3.0f);
+
+ // iofx current bounding volume
+ // there is a bug with setting the color. it can change under certain circumstances. use default color for now
+ //RENDER_DEBUG_IFACE(mDebugRender)->setCurrentColor(RENDER_DEBUG_IFACE(mDebugRender)->getDebugColor(DebugColors::LightBlue));
+ for (uint32_t i = 0 ; i < mActorArray.size() ; i++)
+ {
+ IofxActorImpl* actor = DYNAMIC_CAST(IofxActorImpl*)(mActorArray[ i ]);
+ if (mIofxDebugRenderParams->VISUALIZE_IOFX_ACTOR_NAME)
+ {
+ PxVec3 textLocation = actor->getBounds().maximum;
+ cameraFacingPose.setPosition(textLocation);
+ if(actor->getOwner() != NULL)
+ {
+ RENDER_DEBUG_IFACE(mDebugRender)->debugText(textLocation, " %s %s", actor->getOwner()->getObjTypeName(), actor->getOwner()->getName());
+ }
+ }
+ if (mIofxDebugRenderParams->VISUALIZE_IOFX_BOUNDING_BOX)
+ {
+ RENDER_DEBUG_IFACE(mDebugRender)->debugBound(actor->getBounds());
+ }
+ }
+
+ // iofx max bounding volume
+ // there is a bug with setting the color. it can change under certain circumstances. use default color for now
+ //RENDER_DEBUG_IFACE(mDebugRender)->setCurrentColor(RENDER_DEBUG_IFACE(mDebugRender)->getDebugColor(DebugColors::Orange));
+ mLiveRenderVolumesLock.lockReader();
+ for (uint32_t i = 0 ; i < mLiveRenderVolumes.size() ; i++)
+ {
+ if (mIofxDebugRenderParams->VISUALIZE_IOFX_BOUNDING_BOX)
+ {
+ PxVec3 textLocation = mLiveRenderVolumes[i]->getOwnershipBounds().maximum;
+ cameraFacingPose.setPosition(textLocation);
+ RENDER_DEBUG_IFACE(mDebugRender)->debugText(textLocation, " Max Render Volume %d", i);
+ RENDER_DEBUG_IFACE(mDebugRender)->debugBound(mLiveRenderVolumes[i]->getOwnershipBounds());
+ }
+ }
+ mLiveRenderVolumesLock.unlockReader();
+
+ RENDER_DEBUG_IFACE(mDebugRender)->setPose(savedPose);
+ RENDER_DEBUG_IFACE(mDebugRender)->popRenderState();
+#endif
+}
+
+void IofxScene::destroy()
+{
+ removeAllActors();
+ mApexScene->moduleReleased(*this);
+
+ {
+ mLiveRenderVolumesLock.lockWriter();
+
+ /* Handle deferred insertions/deletions of ApexRenderVolumes */
+ processDeferredRenderVolumes();
+
+ /* Delete all Live ApexRenderVolumes */
+ for (uint32_t i = 0 ; i < mLiveRenderVolumes.size() ; i++)
+ {
+ RenderVolumeImpl* arv = mLiveRenderVolumes[ i ];
+ PX_DELETE(arv);
+ }
+ mLiveRenderVolumes.clear();
+
+ mLiveRenderVolumesLock.unlockWriter();
+ }
+ delete this;
+}
+
+void IofxScene::setModulePhysXScene(PxScene* nxScene)
+{
+ if (nxScene)
+ {
+ for (uint32_t i = 0 ; i < mActorArray.size() ; i++)
+ {
+ IofxActorImpl* actor = DYNAMIC_CAST(IofxActorImpl*)(mActorArray[ i ]);
+ actor->setPhysXScene(nxScene);
+ }
+ }
+ else
+ {
+ for (uint32_t i = 0 ; i < mActorArray.size() ; i++)
+ {
+ IofxActorImpl* actor = DYNAMIC_CAST(IofxActorImpl*)(mActorArray[ i ]);
+ actor->setPhysXScene(NULL);
+ }
+ }
+
+ mPhysXScene = nxScene;
+}
+
+void IofxScene::processDeferredRenderVolumes()
+{
+ mAddedRenderVolumesLock.lock();
+ while (mAddedRenderVolumes.size())
+ {
+ RenderVolumeImpl* arv = mAddedRenderVolumes.popBack();
+ mLiveRenderVolumes.pushBack(arv);
+ }
+ mAddedRenderVolumesLock.unlock();
+
+ mDeletedRenderVolumesLock.lock();
+ while (mDeletedRenderVolumes.size())
+ {
+ RenderVolumeImpl* arv = mDeletedRenderVolumes.popBack();
+ mLiveRenderVolumes.findAndReplaceWithLast(arv);
+ PX_DELETE(arv);
+ }
+ mDeletedRenderVolumesLock.unlock();
+}
+
+void IofxScene::submitTasks(float /*elapsedTime*/, float /*substepSize*/, uint32_t /*numSubSteps*/)
+{
+ {
+ mLiveRenderVolumesLock.lockWriter();
+
+ /* Handle deferred insertions/deletions of ApexRenderVolumes */
+ processDeferredRenderVolumes();
+
+ mLiveRenderVolumesLock.unlockWriter();
+ }
+
+ mManagersLock.lockReader();
+
+ //IofxManager::submitTasks reads mLiveRenderVolumes so we lock it here and unlock later
+ mLiveRenderVolumesLock.lockReader();
+ for (uint32_t i = 0; i < mActorManagers.getSize(); ++i)
+ {
+ IofxManager* mgr = DYNAMIC_CAST(IofxManager*)(mActorManagers.getResource(i));
+ mgr->submitTasks();
+ }
+ mLiveRenderVolumesLock.unlockReader();
+
+ mManagersLock.unlockReader();
+}
+
+void IofxScene::fetchResults()
+{
+ mManagersLock.lockReader();
+
+ mFetchResultsLock.lock();
+
+ uint32_t totalSimulatedSpriteParticles = 0,
+ totalSimulatedMeshParticles = 0;
+ for (uint32_t i = 0; i < mActorManagers.getSize(); ++i)
+ {
+ IofxManager* mgr = DYNAMIC_CAST(IofxManager*)(mActorManagers.getResource(i));
+ mgr->fetchResults();
+
+ if(mgr->isMesh())
+ totalSimulatedMeshParticles += mgr->getSimulatedParticlesCount();
+ else
+ totalSimulatedSpriteParticles += mgr->getSimulatedParticlesCount();
+ }
+
+ StatValue dataVal;
+ dataVal.Int = int32_t(totalSimulatedSpriteParticles - mPrevTotalSimulatedSpriteParticles);
+ setStatValue(SimulatedSpriteParticlesCount, dataVal);
+ mPrevTotalSimulatedSpriteParticles = totalSimulatedSpriteParticles;
+ dataVal.Int = int32_t(totalSimulatedMeshParticles - mPrevTotalSimulatedMeshParticles);
+ setStatValue(SimulatedMeshParticlesCount, dataVal);
+ mPrevTotalSimulatedMeshParticles = totalSimulatedMeshParticles;
+
+ mFetchResultsLock.unlock();
+
+ mManagersLock.unlockReader();
+}
+
+void IofxScene::prepareRenderables()
+{
+ mManagersLock.lockReader();
+
+ lockLiveRenderVolumes();
+ mFetchResultsLock.lock();
+
+ for (uint32_t i = 0; i < mActorManagers.getSize(); ++i)
+ {
+ IofxManager* mgr = DYNAMIC_CAST(IofxManager*)(mActorManagers.getResource(i));
+ mgr->prepareRenderables();
+ }
+
+ mFetchResultsLock.unlock();
+ unlockLiveRenderVolumes();
+
+ mManagersLock.unlockReader();
+}
+
+
+void IofxScene::lockLiveRenderVolumes()
+{
+ mLiveRenderVolumesLock.lockReader();
+ //for (uint32_t i = 0 ; i < mLiveRenderVolumes.size() ; i++)
+ //{
+ // mLiveRenderVolumes[ i ]->lockReader();
+ //}
+}
+
+void IofxScene::unlockLiveRenderVolumes()
+{
+ //for (uint32_t i = 0 ; i < mLiveRenderVolumes.size() ; i++)
+ //{
+ // mLiveRenderVolumes[ i ]->unlockReader();
+ //}
+ mLiveRenderVolumesLock.unlockReader();
+}
+
+/******************************** CPU Version ********************************/
+
+IofxSceneCPU::IofxSceneCPU(ModuleIofxImpl& module, SceneIntl& scene, RenderDebugInterface* debugRender, ResourceList& list)
+ : IOFX_SCENE(module, scene, debugRender, list)
+{
+}
+
+/******************************** GPU Version ********************************/
+
+#if APEX_CUDA_SUPPORT
+IofxSceneGPU::IofxSceneGPU(ModuleIofxImpl& module, SceneIntl& scene, RenderDebugInterface* debugRender, ResourceList& list) :
+ IOFX_SCENE(module, scene, debugRender, list),
+ CudaModuleScene(scene, *mModule, APEX_CUDA_TO_STR(APEX_CUDA_MODULE_PREFIX)),
+ mContextManager(scene.getTaskManager()->getGpuDispatcher()->getCudaContextManager())
+{
+ PxGpuDispatcher* gd = scene.getTaskManager()->getGpuDispatcher();
+ PX_ASSERT(gd != NULL);
+ PxScopedCudaLock _lock_(*gd->getCudaContextManager());
+
+//CUDA module objects
+#include "../cuda/include/moduleList.h"
+}
+
+IofxSceneGPU::~IofxSceneGPU()
+{
+ PxScopedCudaLock s(*mContextManager);
+ CudaModuleScene::destroy(*mApexScene);
+}
+
+void IofxSceneGPU::submitTasks(float elapsedTime, float substepSize, uint32_t numSubSteps)
+{
+ IofxScene::submitTasks(elapsedTime, substepSize, numSubSteps);
+
+ {
+ PxScopedCudaLock _lock_(*mContextManager);
+
+ APEX_CUDA_OBJ_NAME(migrationStorage).copyToDevice(mContextManager, 0);
+ APEX_CUDA_OBJ_NAME(remapStorage).copyToDevice(mContextManager, 0);
+ APEX_CUDA_OBJ_NAME(modifierStorage).copyToDevice(mContextManager, 0);
+ }
+}
+
+
+void IofxSceneGPU::prepareRenderables()
+{
+ mManagersLock.lockReader();
+
+ lockLiveRenderVolumes();
+ mFetchResultsLock.lock();
+
+ for (uint32_t i = 0; i < mActorManagers.getSize(); ++i)
+ {
+ IofxManager* mgr = DYNAMIC_CAST(IofxManager*)(mActorManagers.getResource(i));
+ mgr->prepareRenderables();
+ }
+
+ if (mContextManager->getInteropMode() != PxCudaInteropMode::NO_INTEROP)
+ {
+ mToMapArray.clear();
+ mToUnmapArray.clear();
+
+ for (uint32_t i = 0; i < mActorManagers.getSize(); ++i)
+ {
+ IofxManager* mgr = DYNAMIC_CAST(IofxManager*)(mActorManagers.getResource(i));
+ mgr->fillMapUnmapArraysForInterop(mToMapArray, mToUnmapArray);
+ }
+
+ bool mapSuccess = true;
+ bool unmapSuccess = true;
+ {
+ PxScopedCudaLock s(*mContextManager);
+
+ if (!mToMapArray.empty())
+ {
+ for (uint32_t i = 0; i < mToMapArray.size(); ++i)
+ {
+ cuGraphicsResourceSetMapFlags( mToMapArray[i], CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD );
+ }
+ CUresult res = cuGraphicsMapResources(mToMapArray.size(), &mToMapArray.front(), 0);
+ mapSuccess = (res == CUDA_SUCCESS || res == CUDA_ERROR_ALREADY_MAPPED);
+ }
+ if (!mToUnmapArray.empty())
+ {
+ CUresult res = cuGraphicsUnmapResources(mToUnmapArray.size(), &mToUnmapArray.front(), 0);
+ unmapSuccess = (res == CUDA_SUCCESS || res == CUDA_ERROR_NOT_MAPPED);
+ }
+ }
+
+ for (uint32_t i = 0; i < mActorManagers.getSize(); ++i)
+ {
+ IofxManager* mgr = DYNAMIC_CAST(IofxManager*)(mActorManagers.getResource(i));
+ mgr->mapBufferResultsForInterop(mapSuccess, unmapSuccess);
+ }
+ }
+
+ mFetchResultsLock.unlock();
+ unlockLiveRenderVolumes();
+
+ mManagersLock.unlockReader();
+}
+
+#endif
+
+}
+} // namespace nvidia