首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PhysX --如果GPU使用

PhysX --如果GPU使用
EN

Stack Overflow用户
提问于 2013-12-23 22:52:16
回答 1查看 1.3K关注 0票数 1

我还在研究模拟流体的物理系统。为了更客观地使用PhysX 3.3.0,我重写了我的应用程序,现在我遇到了一个问题,需要一两周的时间才能解决。

这是我对PhysX上下文的启动:

代码语言:javascript
运行
复制
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场景,但是即使在一个空场景中也会出现问题:

代码语言:javascript
运行
复制
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()方法永远不会完成它的工作)。我没有错误日志,只是冻结了。不管它是调试还是发布,或者是32或64版本,都会发生这种情况。

我有一个GeForce 560。我使用PhysxSDK3.3.0。我连接(如)在win64调试构建上) vs:

opengl32.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()上冻结。

我不知道该在哪里找错误。一切看起来都很好。我会感谢你的帮助!

EN

回答 1

Stack Overflow用户

发布于 2014-08-28 21:30:07

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

我确实找到了解决办法。问题是在这里初始化扩展两次。您正在使用PxCreateBasePhysics创建SDK对象,该对象在后台完成一些额外的工作。也就是说,如果我没有弄错的话,它就叫PxInitExtensions

修复方法是将PxCreateBasePhysics函数更改为具有完全相同参数的标准PxCreatePhysics调用。这个人不会在现场后面做任何额外的设置。只是忽略了InitExtensions调用可能也同样有效,但我只是尝试了第一个想法。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20752381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档