PhysX — simulate () никогда не заканчивается, если используется GPU

Я все еще работаю над системой физики для моделирования жидкостей. Я переписал свое приложение, чтобы использовать 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 закомментирован, все работает нормально. Жидкость течет так, как должна. Но когда я пытаюсь использовать мой графический процессор, приложение останавливается при первом вызове fetchResult () (метод simulate () никогда не завершает свою работу). У меня нет журнала ошибок, он просто зависает. Это происходит независимо от того, является ли он DEBUG или RELEASE, и является ли он 32 или 64 билдом.

У меня GeForce 560Ti. Я использую Physx SDK 3.3.0. Я ссылаюсь (например, на сборку отладки win64) против:

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 и добавлять .dll, требуемые приложением, но каждый набор заканчивался зависанием на fetchResult ().

Я понятия не имею, где искать ошибки. Все выглядит хорошо. Буду благодарен за любую помощь!

1

Решение

Я знаю, что это старая тема, но у меня возникла та же проблема, когда я перешел с 3.2.5 на 3.3.0.

Я нашел решение. Проблема в том, что вы дважды инициализируете расширения. Ты используешь PxCreateBasePhysics создать свой объект SDK, который выполняет дополнительную работу в фоновом режиме. А именно это вызывает PxInitExtensions если я не ошибаюсь.

Исправление состоит в том, чтобы просто изменить PxCreateBasePhysics функция к стандарту PxCreatePhysics звоните с точно такими же аргументами. Этот не делает никаких дополнительных настроек за сценой. Просто опуская InitExtensions Call может работать, но я попробовал только первую идею.

Странно, что это приводит к зависанию только в том случае, если используется графический процессор, может быть, nVidia должна посмотреть на это.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]