NVIDIAGameWorks / PhysX-3.4

NVIDIA PhysX SDK 3.4
https://www.nvidia.com/
2.35k stars 274 forks source link

DirectX 11 GRB problem #36

Closed Kabak closed 5 years ago

Kabak commented 7 years ago

I try to init GPU Rigid Bodies :

    PxGpuDispatcher * GPUDispatcher;
    PxCudaContextManager* gCudaContextManager;

    PxCudaContextManagerDesc cudaContextManagerDesc;
    ZeroMemory(&cudaContextManagerDesc, sizeof ( PxCudaContextManagerDesc ));
    cudaContextManagerDesc.graphicsDevice = MY_DX11_device;
    cudaContextManagerDesc.interopMode = PxCudaInteropMode::D3D11_INTEROP;
    cudaContextManagerDesc.ctx = NULL;
    cudaContextManagerDesc.appGUID = "APName";

    gCudaContextManager = PxCreateCudaContextManager( *gFoundation, cudaContextManagerDesc );

    if ( gCudaContextManager )  
    GPUDispatcher = gCudaContextManager->getGpuDispatcher();

    if ( GPUDispatcher )        
    {
        desc.gpuDispatcher = GPUDispatcher;
        desc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS;
        desc.flags |= PxSceneFlag::eENABLE_PCM;
        desc.flags |= PxSceneFlag::eENABLE_STABILIZATION;
        desc.broadPhaseType = PxBroadPhaseType::eGPU;
        desc.gpuMaxNumPartitions = 8;
        desc.gpuDynamicsConfig.constraintBufferCapacity = (32 * 1024 * 1024);
        desc.gpuDynamicsConfig.contactBufferCapacity = (24 * 1024 * 1024);
        desc.gpuDynamicsConfig.tempBufferCapacity = (16 * 1024 * 1024);
        desc.gpuDynamicsConfig.contactStreamSize = (6 * 1024 * 1024);
        desc.gpuDynamicsConfig.patchStreamSize = (5 * 1024 * 1024);
        desc.gpuDynamicsConfig.forceStreamCapacity = (1 * 1024 * 1024);
        desc.gpuDynamicsConfig.heapCapacity = (64 * 1024 * 1024);
        desc.gpuDynamicsConfig.foundLostPairsCapacity = (256 * 1024);
    }

    gScene = gPhysics->createScene(desc);

Initialization was successful, but RigidBodies - Boxes behavior are wrong : Something wrong with Boxes gravity and frictions if colliding with Heightfield or with each other. Boxes just skating on Heightfield surface as there no frictions at all.

If i use CPU PhysX i have no problem with RigidBodies and Heightfield behavior.

What is wrong with initialisation or whatever?

marzer commented 7 years ago

Well, there's a few things that strike me as odd, though I'm not sure if they're causing your problem.

//you should not do this:
ZeroMemory(&cudaContextManagerDesc, sizeof ( PxCudaContextManagerDesc ));
//the PxCudaContextManagerDesc has a default constructor that initializes it appropriately,
//and some of it is non-zero

//my directx11 app initializes OK without doing this:
cudaContextManagerDesc.graphicsDevice = MY_DX11_device;
cudaContextManagerDesc.interopMode = PxCudaInteropMode::D3D11_INTEROP;
//I believe leaving this unset will honour the values set in the driver control panel

//you also do not need to do this:
cudaContextManagerDesc.ctx = NULL;
//NULL is the default value

//you should not be doing this:
cudaContextManagerDesc.appGUID = "APName";
//the appGUI field is for applications that have
//corresponding tweaks in nVIDIA drivers, so they have an actual GUID issued by nVIDIA.

//this is not sufficient:
if ( gCudaContextManager )
//you should also check contextIsValid(), e.g.:
if ( gCudaContextManager && gCudaContextManager->contextIsValid() )

It also seems as though you're being overly pessimistic with your configuration of GPU memory allocations (the gpuDynamicsConfig). By default it sets some very sensible values; you'd only really need to modify them if you run into any issues after-the-fact. Try commenting out everything beginning with desc.gpu, and then uncomment as necessary once you have things working.

Note that my remarks above I learned by reading the physx headers. I suggest you do the same, as they're very descriptive.

Finally: if you haven't already, add an error callback in your call to PxCreateFoundation. Doing so makes debugging physx issues a lot easier, since it will tell you if you've configured something incorrectly or are doing things in the wrong order.

Kabak commented 7 years ago

Hi Thanks for your answer.

I installed all the settings as you advised. And yes, gCudaContextManager was also initialized successfully (as in my case), and the behavior of cubes is the same as when initializing in my way. I attach the video so that you can better understand what is happening. If I do not use GRB, then the cubes rebound from the HightField and then calm down - this is the correct behavior. If I enable GRB, the cubes very quickly, without rebounds, go into a state of rest and some of them start to tremble and slide on the HightField - this is a mistaken behavior.

NO GRB ( correct behavior ) https://1drv.ms/v/s!Akw1Zo0XJGL88HUSR_830LG6xD9D

GRB Initialized and used ( bad behavior ) https://1drv.ms/v/s!Akw1Zo0XJGL88Hbnzg4GXA9ZrnNJ

I did all according PhysX documentation and code examples. But there no DirectX GRB initialization code example, only for OpenGL. So, i trying to use it for DirectX. Seems to me, something wrong with gravity.

May be i missed something...

marzer commented 7 years ago

Did you try providing an error callback to PxCreateFoundation?

kstorey-nvidia commented 7 years ago

The videos look to me like material information is incorrect in the simulation for some reason. Both friction and restitution seem to be using the wrong values - notable by the lack of bounce and the objects rotating/sliding when using GRB compared to CPU simulation.

There was a material issue found and fixed with GRB after the most recent release was pushed to GitHub. I would be surprised if what you're seeing is not the same issue. It produces incorrect results if you are using multiple materials and it was caused by a simple copy n' paste typo in the code that moves the materials from host memory to GPU memory.

This fix should be included in the next PhysX release, which should be released in around 2 weeks time.

kstorey-nvidia commented 7 years ago

To confirm this hypothesis, could you please set up a scene where all shapes use the same material and confirm whether it behaves as you would expect. They all have to be assigned the same material pointer, not just the same values.

Kabak commented 7 years ago
PxDefaultAllocator gDefaultAllocatorCallback;
PxDefaultAllocator *allocator = &gDefaultAllocatorCallback;

PxErrorCallback& getSampleErrorCallback(  ) 
{
    static PxDefaultErrorCallback gDefaultErrorCallback;
    return gDefaultErrorCallback;
}

gFoundation = PxCreateFoundation( PX_FOUNDATION_VERSION, *allocator , getSampleErrorCallback() );

I run project in Debug Mode and set Breakpoint inside getSampleErrorCallback()

it is called once at start, when PxCreateFoundation() was called.

kstorey-nvidia commented 7 years ago

Your code creating the CUDA context seems OK to me. Given that the GRB simulation is running, it has successfully created a context and is using it for simulation.

Providing the DX device and requesting DX interop is optional. PhysX particles and clothing support the DX interop feature to provide direct access to particle positions on the GPU in your rendering code to avoid needing to DMA the particle buffers from the GPU to CPU, have you copy them to a DX buffer, then DMA that back to the GPU.

GRB doesn't currently support this feature.

Hope this helps

Kier

Kabak commented 7 years ago
PxMaterial* WorkgMaterial;
WorkgMaterial = gPhysics->createMaterial(StaticFriction, DynamicFriction, Restitution);

For HightField material set as : WorkgMaterial = gPhysics->createMaterial(1.0f, 1.0f, 1.0f);

if i initialized material for cubes as WorkgMaterial = gPhysics->createMaterial(0.0f, 0.0f, 0.0f); Problem appear.

if i set WorkgMaterial = gPhysics->createMaterial(0.1f, 0.1f, 0.1f); I see no problem with cubes behaviors

But if i use CPU for RB calculations , zero settings for StaticFriction, DynamicFriction, Restitution works fine.

kstorey-nvidia commented 7 years ago

It all depends on how the materials are being blended - this is in the blend options. Default setting is AVERAGE, but it can also be min, multiply or max operations. Similarly, there's a flag that can be set on the materials to fully disable friction.

As mentioned, there's a bug in the GRB build you have with multiple materials where the data for the materials isn't correctly copied to GPU. Specifically, the destination target is offset by the wrong size and the wrong size of data is copied (it's a copy and paste typo from the code updating shape properties that went unnoticed).

What probably is happening is that the first few values of your second material are copied correctly along with the first material, but later data like the blend mode is missing and is just picking up whatever is left in memory there. It's probably mapping to "min" or "multiply", which is why a value of 0 is causing behaviour you didn't expect/want.

The next PhysX release in ~2 weeks will include a fix for this. For now, maybe just set the same material on both, e.g. share heightfield material with cubes for now and set it to this:

 WorkgMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.5f); 

which is what you would get with the default averaging blend state. You should hopefully see similar results between GRB and CPU PhysX.

I can only apologise that this bug managed to get past our internal testing.

Kabak commented 7 years ago

Thank you for your work.