【问题标题】:PhysX - simulate() never ends if GPU usedPhysX - 如果使用 GPU,则模拟()永远不会结束
【发布时间】:2013-12-23 22:52:16
【问题描述】:

我仍在研究用于模拟流体的物理系统。我重写了我的应用程序以使用 PhysX 3.3.0 并更加客观,现在我遇到了一个问题,我无法在一两个星期内解决。

这是我对 PhysX Context 的启蒙:

void PhysXSPH::initContext(void){
    static LogPxErrorCallback gLogPxErrorCallback;
    static PxDefaultAllocator gDefaultAllocatorCallback;

    mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gLogPxErrorCallback);
    check(mFoundation, "PxFoundation creating failed!");

    static PxProfileZoneManager *mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation);
    check(mProfileZoneManager, "PxProfileZoneManager creation failed!");

    bool recordMemoryAllocations = true;
    mPhysics = PxCreateBasePhysics(PX_PHYSICS_VERSION, *mFoundation,
        PxTolerancesScale(), recordMemoryAllocations, mProfileZoneManager );
    check(mPhysics, "PxPhysics creating failed!");

    PxRegisterParticles(*mPhysics);
    if(!PxInitExtensions(*mPhysics)){
        check(NULL, "PxInitExtensions failed!");
    }

    static PxSimulationFilterShader gDefaultFilterShader = PxDefaultSimulationFilterShader;
    PxSceneDesc sceneDesc(mPhysics->getTolerancesScale());

    sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);

    if(!sceneDesc.cpuDispatcher){
        mCpuDispatcher = PxDefaultCpuDispatcherCreate(4);
        check(mCpuDispatcher, "PxDefaultCpuDispatcherCreate failed!");
        sceneDesc.cpuDispatcher = mCpuDispatcher;
    }
    if(!sceneDesc.filterShader){
        sceneDesc.filterShader = gDefaultFilterShader;
    }

#ifdef PX_WINDOWS

    PxCudaContextManagerDesc cudaContextManagerDesc;
    mCudaContextManager = PxCreateCudaContextManager(*mFoundation, cudaContextManagerDesc, mProfileZoneManager);
    if( mCudaContextManager ){
        if( !mCudaContextManager->contextIsValid() ){
            mCudaContextManager->release();
            mCudaContextManager = NULL;
            CLOG(ERROR, "physX")<<"Invalid CUDA context.";
            exit(EXIT_FAILURE);
        }

        if(!sceneDesc.gpuDispatcher){
            sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher();
        }
        CLOG(INFO, "physX")<<"CUDA context created.";
    } else {
        CLOG(ERROR, "physX")<<"Creating CUDA context manager failed.";
        exit(EXIT_FAILURE);
    }

#endif

    mScene = mPhysics->createScene(sceneDesc);
    check(mScene, "createScene failed!");

    createScene(mScene);
}

并启动 physX 场景,但即使场景为空,也会出现问题:

void PhysXSPH::createScene(PxScene *mScene){
    mScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1.0);
    mScene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f);
    createPlanes(mScene);
    createParticles(mScene);
    CLOG(INFO, "physX") << "PhysX scene created.";
}

void PhysXSPH::createPlanes(PxScene *mScene){
    PxMaterial* mMaterial = mPhysics->createMaterial(0.5,0.5,0.5);

    //Create actors 
    //1) Create ground plane
    PxReal d = 0.0f;     
    PxTransform pose = PxTransform(PxVec3(0.0f, 0, 0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)));

    PxRigidStatic* plane = mPhysics->createRigidStatic(pose);
    check(plane, "Creating plane failed!");

    //create 4 more planes for aquarium

    PxRigidStatic* plane2 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(-4.0f, 0.0, 0.0), PxVec3(1.0, 0.0, 0.0)), *mMaterial);

    PxRigidStatic* plane3 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(4.0f, 0.0, 0.0), PxVec3(-1.0, 0.0, 0.0)), *mMaterial);

    PxRigidStatic* plane4 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0.0f, 0.0, -4.0f), PxVec3(0.0, 0.0, 1.0)), *mMaterial);

    PxRigidStatic* plane5 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0.0f, 0.0, 4.0f), PxVec3(0.0, 0.0, -1.0)), *mMaterial);

    // create shape
    PxShape* shape = plane->createShape(PxPlaneGeometry(), *mMaterial);
    check(shape, "Creating shape failed!");

    mScene->addActor(*plane);

    PxShape* shape2 = plane2->createShape(PxPlaneGeometry(), *mMaterial);
    check(shape2, "Creating shape failed!");
    mScene->addActor(*plane2);


    PxShape* shape3 = plane3->createShape(PxPlaneGeometry(), *mMaterial);
    check(shape3, "Creating shape failed!");
    mScene->addActor(*plane3);

    PxShape* shape4 = plane4->createShape(PxPlaneGeometry(), *mMaterial);
    check(shape4, "Creating shape failed!");
    mScene->addActor(*plane4);

    PxShape* shape5 = plane5->createShape(PxPlaneGeometry(), *mMaterial);
    check(shape5, "Creating shape failed!");
    mScene->addActor(*plane5);
}

void PhysXSPH::createParticles(PxScene *mScene){
    // set immutable properties.
    bool perParticleRestOffset = false;

    //get data from scene model
    int maxParticles = scene->getMaxParticles();
    int xDim = scene->getXDim();
    int yDim = scene->getYDim();
    int zDim = scene->getZDim();

    // create particle system in PhysX SDK
    particleSystem = mPhysics->createParticleFluid(maxParticles, perParticleRestOffset);
    check(particleSystem, "Creating particle system failed!");

    particleSystem->setRestOffset(particleRadius);
    particleSystem->setRestParticleDistance(particleRadius);
    particleSystem->setParticleBaseFlag(PxParticleBaseFlag::eGPU,true);
    // TODO set fluid parameters


    // add particle system to scene, in case creation was successful
    if (particleSystem)
        mScene->addActor(*particleSystem);

    indexes = new PxU32[maxParticles];
    particle_positions = new PxVec3[maxParticles];

    int index=0;
    for(int x=0; x<xDim ;x++){
        for(int y=0; y<yDim ;y++){
            for(int z=0; z<zDim; z++){
                indexes[index]=(PxU32)index;
                int v=3*index;

                particle_positions[index]=PxVec3((physx::PxReal)(scene->m_vPos[v]), (physx::PxReal)(scene->m_vPos[v+1]), (physx::PxReal)(scene->m_vPos[v+2]));

                //CLOG(INFO, "physX")<<index<<"["<<particle_positions[index].x<<"; "<<particle_positions[index].y<<"; "<<particle_positions[index].z<<"]";
                index++;
            }
        }
    }

    PxParticleCreationData particleCreationData;
    particleCreationData.numParticles = maxParticles;
    particleCreationData.indexBuffer = PxStrideIterator<const PxU32>(indexes);
    particleCreationData.positionBuffer = PxStrideIterator<const PxVec3>(particle_positions);

    // create particles in *PxParticleSystem* ps
    bool success = particleSystem->createParticles(particleCreationData);
    if(!success){
        CLOG(ERROR, "physX")<<"Creating particles failed.";
        exit(EXIT_FAILURE);
    }
}

如果#ifdef PX_WINDOWS 中的代码被注释,一切正常。流体按应有的方式流动。但是当我尝试使用我的 GPU 时,应用程序在第一次 fetchResult() 调用时冻结(simulate() 方法永远不会完成它的工作)。我没有错误日志,它只是冻结。无论是 DEBUG 还是 RELEASE,以及它是 32 还是 64 版本,都会发生这种情况。

我有一个 GeForce 560Ti。我使用 Physx SDK 3.3.0。我链接(例如在 win64 调试版本上)vs:

opengl32.lib glew32.lib glfw3.lib PhysX3DEBUG_x64.lib PhysX3CommonDEBUG_x64.lib PxTaskDEBUG.lib PhysX3ExtensionsDEBUG.lib PhysXProfileSDKDEBUG.lib

使用:

nvToolsExt64_1.dll PhysX3XHECKED_x64.dll PhysX3CommonCHECKED_x64.dll PhysX3GpuCHECKED_x64.dll PhysX3GpuDEBUG_x64.dll

我尝试使用不同版本的 .libs 并添加应用程序所需的 .dlls,但每组都在 fetchResult() 上冻结。

我不知道去哪里寻找错误。一切看起来都很好。如有任何帮助,我将不胜感激!

【问题讨论】:

  • 我迁移到了 PhysX 3.2.5,经过几次 api 更改后它就可以工作了。我猜可能是 PhysX 中的一个错误。 oO

标签: c++ gpu physx


【解决方案1】:

我知道这是一个旧线程,但是当我从 3.2.5 切换到 3.3.0 时遇到了完全相同的问题。

我确实找到了解决方案。问题是你在这里初始化了两次扩展。您正在使用 PxCreateBasePhysics 创建您的 SDK 对象,该对象在后台执行一些额外的工作。也就是说,如果我没记错的话,它会调用PxInitExtensions。

解决方法是将PxCreateBasePhysics 函数更改为具有完全相同参数的标准PxCreatePhysics 调用。这个在幕后没有做任何额外的设置。省略InitExtensions 电话也可以,但我只尝试了第一个想法。

奇怪的是,这只会在使用 GPU 时导致冻结,也许 nVidia 应该看看它。

【讨论】:

  • 有趣的是,我很确定 PxCreatePhysics 会初始化所有扩展,而 PxCreateBasePhysix 让您自己选择它。来自 SDK 文档:If your application requires a subset of this functionality, it is recommended that you call PxCreateBasePhysics as opposed to PxCreatePhysics and then manually register the compoments you require.
  • 来自 3.3.0 的代码:PX_INLINE physx::PxPhysics* PxCreatePhysics(...) { physx::PxPhysics* physics = PxCreateBasePhysics(version, foundation, scale, trackOutstandingAllocations, profileZoneManager); if(!physics) return NULL; PxRegisterArticulations(*physics); PxRegisterHeightFields(*physics); PxRegisterCloth(*physics); PxRegisterParticles(*physics); return physics; }
猜你喜欢
  • 1970-01-01
  • 2015-06-26
  • 2021-05-17
  • 2013-04-09
  • 2010-12-27
  • 1970-01-01
  • 2021-08-05
  • 2019-06-08
  • 2011-01-20
相关资源
最近更新 更多