summaryrefslogtreecommitdiff
path: root/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2022-03-09 21:15:53 +0100
committerRémi Verschelde <rverschelde@gmail.com>2022-03-09 21:45:47 +0100
commit3d7f1555865a981b7144becfc58d3f3f34362f5f (patch)
treed92912c6d700468b3330148b9179026b9f4efcb4 /thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp
parent33c907f9f5b3ec1a43d0251d7cac80da49b5b658 (diff)
Remove unused Bullet module and thirdparty code
It has been disabled in `master` since one year (#45852) and our plan is for Bullet, and possibly other thirdparty physics engines, to be implemented via GDExtension so that they can be selected by the users who need them.
Diffstat (limited to 'thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp')
-rw-r--r--thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp1529
1 files changed, 0 insertions, 1529 deletions
diff --git a/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp b/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp
deleted file mode 100644
index e3d235a4fd..0000000000
--- a/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp
+++ /dev/null
@@ -1,1529 +0,0 @@
-
-bool gUseLargeBatches = false;
-bool gCpuBatchContacts = false;
-bool gCpuSolveConstraint = false;
-bool gCpuRadixSort = false;
-bool gCpuSetSortData = false;
-bool gCpuSortContactsDeterminism = false;
-bool gUseCpuCopyConstraints = false;
-bool gUseScanHost = false;
-bool gReorderContactsOnCpu = false;
-
-bool optionalSortContactsDeterminism = true;
-
-#include "b3GpuPgsContactSolver.h"
-#include "Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h"
-
-#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
-#include "Bullet3OpenCL/ParallelPrimitives/b3BoundSearchCL.h"
-#include "Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h"
-#include <string.h>
-#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
-#include "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
-#include "b3Solver.h"
-
-#define B3_SOLVER_SETUP_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverSetup.cl"
-#define B3_SOLVER_SETUP2_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverSetup2.cl"
-#define B3_SOLVER_CONTACT_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solveContact.cl"
-#define B3_SOLVER_FRICTION_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solveFriction.cl"
-#define B3_BATCHING_PATH "src/Bullet3OpenCL/RigidBody/kernels/batchingKernels.cl"
-#define B3_BATCHING_NEW_PATH "src/Bullet3OpenCL/RigidBody/kernels/batchingKernelsNew.cl"
-
-#include "kernels/solverSetup.h"
-#include "kernels/solverSetup2.h"
-#include "kernels/solveContact.h"
-#include "kernels/solveFriction.h"
-#include "kernels/batchingKernels.h"
-#include "kernels/batchingKernelsNew.h"
-
-struct b3GpuBatchingPgsSolverInternalData
-{
- cl_context m_context;
- cl_device_id m_device;
- cl_command_queue m_queue;
- int m_pairCapacity;
- int m_nIterations;
-
- b3OpenCLArray<b3GpuConstraint4>* m_contactCGPU;
- b3OpenCLArray<unsigned int>* m_numConstraints;
- b3OpenCLArray<unsigned int>* m_offsets;
-
- b3Solver* m_solverGPU;
-
- cl_kernel m_batchingKernel;
- cl_kernel m_batchingKernelNew;
- cl_kernel m_solveContactKernel;
- cl_kernel m_solveSingleContactKernel;
- cl_kernel m_solveSingleFrictionKernel;
- cl_kernel m_solveFrictionKernel;
- cl_kernel m_contactToConstraintKernel;
- cl_kernel m_setSortDataKernel;
- cl_kernel m_reorderContactKernel;
- cl_kernel m_copyConstraintKernel;
-
- cl_kernel m_setDeterminismSortDataBodyAKernel;
- cl_kernel m_setDeterminismSortDataBodyBKernel;
- cl_kernel m_setDeterminismSortDataChildShapeAKernel;
- cl_kernel m_setDeterminismSortDataChildShapeBKernel;
-
- class b3RadixSort32CL* m_sort32;
- class b3BoundSearchCL* m_search;
- class b3PrefixScanCL* m_scan;
-
- b3OpenCLArray<b3SortData>* m_sortDataBuffer;
- b3OpenCLArray<b3Contact4>* m_contactBuffer;
-
- b3OpenCLArray<b3RigidBodyData>* m_bodyBufferGPU;
- b3OpenCLArray<b3InertiaData>* m_inertiaBufferGPU;
- b3OpenCLArray<b3Contact4>* m_pBufContactOutGPU;
-
- b3OpenCLArray<b3Contact4>* m_pBufContactOutGPUCopy;
- b3OpenCLArray<b3SortData>* m_contactKeyValues;
-
- b3AlignedObjectArray<unsigned int> m_idxBuffer;
- b3AlignedObjectArray<b3SortData> m_sortData;
- b3AlignedObjectArray<b3Contact4> m_old;
-
- b3AlignedObjectArray<int> m_batchSizes;
- b3OpenCLArray<int>* m_batchSizesGpu;
-};
-
-b3GpuPgsContactSolver::b3GpuPgsContactSolver(cl_context ctx, cl_device_id device, cl_command_queue q, int pairCapacity)
-{
- m_debugOutput = 0;
- m_data = new b3GpuBatchingPgsSolverInternalData;
- m_data->m_context = ctx;
- m_data->m_device = device;
- m_data->m_queue = q;
- m_data->m_pairCapacity = pairCapacity;
- m_data->m_nIterations = 4;
- m_data->m_batchSizesGpu = new b3OpenCLArray<int>(ctx, q);
- m_data->m_bodyBufferGPU = new b3OpenCLArray<b3RigidBodyData>(ctx, q);
- m_data->m_inertiaBufferGPU = new b3OpenCLArray<b3InertiaData>(ctx, q);
- m_data->m_pBufContactOutGPU = new b3OpenCLArray<b3Contact4>(ctx, q);
-
- m_data->m_pBufContactOutGPUCopy = new b3OpenCLArray<b3Contact4>(ctx, q);
- m_data->m_contactKeyValues = new b3OpenCLArray<b3SortData>(ctx, q);
-
- m_data->m_solverGPU = new b3Solver(ctx, device, q, 512 * 1024);
-
- m_data->m_sort32 = new b3RadixSort32CL(ctx, device, m_data->m_queue);
- m_data->m_scan = new b3PrefixScanCL(ctx, device, m_data->m_queue, B3_SOLVER_N_CELLS);
- m_data->m_search = new b3BoundSearchCL(ctx, device, m_data->m_queue, B3_SOLVER_N_CELLS);
-
- const int sortSize = B3NEXTMULTIPLEOF(pairCapacity, 512);
-
- m_data->m_sortDataBuffer = new b3OpenCLArray<b3SortData>(ctx, m_data->m_queue, sortSize);
- m_data->m_contactBuffer = new b3OpenCLArray<b3Contact4>(ctx, m_data->m_queue);
-
- m_data->m_numConstraints = new b3OpenCLArray<unsigned int>(ctx, m_data->m_queue, B3_SOLVER_N_CELLS);
- m_data->m_numConstraints->resize(B3_SOLVER_N_CELLS);
-
- m_data->m_contactCGPU = new b3OpenCLArray<b3GpuConstraint4>(ctx, q, pairCapacity);
-
- m_data->m_offsets = new b3OpenCLArray<unsigned int>(ctx, m_data->m_queue, B3_SOLVER_N_CELLS);
- m_data->m_offsets->resize(B3_SOLVER_N_CELLS);
- const char* additionalMacros = "";
- //const char* srcFileNameForCaching="";
-
- cl_int pErrNum;
- const char* batchKernelSource = batchingKernelsCL;
- const char* batchKernelNewSource = batchingKernelsNewCL;
- const char* solverSetupSource = solverSetupCL;
- const char* solverSetup2Source = solverSetup2CL;
- const char* solveContactSource = solveContactCL;
- const char* solveFrictionSource = solveFrictionCL;
-
- {
- cl_program solveContactProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveContactSource, &pErrNum, additionalMacros, B3_SOLVER_CONTACT_KERNEL_PATH);
- b3Assert(solveContactProg);
-
- cl_program solveFrictionProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveFrictionSource, &pErrNum, additionalMacros, B3_SOLVER_FRICTION_KERNEL_PATH);
- b3Assert(solveFrictionProg);
-
- cl_program solverSetup2Prog = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetup2Source, &pErrNum, additionalMacros, B3_SOLVER_SETUP2_KERNEL_PATH);
-
- b3Assert(solverSetup2Prog);
-
- cl_program solverSetupProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetupSource, &pErrNum, additionalMacros, B3_SOLVER_SETUP_KERNEL_PATH);
- b3Assert(solverSetupProg);
-
- m_data->m_solveFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg, additionalMacros);
- b3Assert(m_data->m_solveFrictionKernel);
-
- m_data->m_solveContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg, additionalMacros);
- b3Assert(m_data->m_solveContactKernel);
-
- m_data->m_solveSingleContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveContactSource, "solveSingleContactKernel", &pErrNum, solveContactProg, additionalMacros);
- b3Assert(m_data->m_solveSingleContactKernel);
-
- m_data->m_solveSingleFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveFrictionSource, "solveSingleFrictionKernel", &pErrNum, solveFrictionProg, additionalMacros);
- b3Assert(m_data->m_solveSingleFrictionKernel);
-
- m_data->m_contactToConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg, additionalMacros);
- b3Assert(m_data->m_contactToConstraintKernel);
-
- m_data->m_setSortDataKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog, additionalMacros);
- b3Assert(m_data->m_setSortDataKernel);
-
- m_data->m_setDeterminismSortDataBodyAKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyA", &pErrNum, solverSetup2Prog, additionalMacros);
- b3Assert(m_data->m_setDeterminismSortDataBodyAKernel);
-
- m_data->m_setDeterminismSortDataBodyBKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyB", &pErrNum, solverSetup2Prog, additionalMacros);
- b3Assert(m_data->m_setDeterminismSortDataBodyBKernel);
-
- m_data->m_setDeterminismSortDataChildShapeAKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeA", &pErrNum, solverSetup2Prog, additionalMacros);
- b3Assert(m_data->m_setDeterminismSortDataChildShapeAKernel);
-
- m_data->m_setDeterminismSortDataChildShapeBKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeB", &pErrNum, solverSetup2Prog, additionalMacros);
- b3Assert(m_data->m_setDeterminismSortDataChildShapeBKernel);
-
- m_data->m_reorderContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog, additionalMacros);
- b3Assert(m_data->m_reorderContactKernel);
-
- m_data->m_copyConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog, additionalMacros);
- b3Assert(m_data->m_copyConstraintKernel);
- }
-
- {
- cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelSource, &pErrNum, additionalMacros, B3_BATCHING_PATH);
- b3Assert(batchingProg);
-
- m_data->m_batchingKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg, additionalMacros);
- b3Assert(m_data->m_batchingKernel);
- }
-
- {
- cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelNewSource, &pErrNum, additionalMacros, B3_BATCHING_NEW_PATH);
- b3Assert(batchingNewProg);
-
- m_data->m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelNewSource, "CreateBatchesNew", &pErrNum, batchingNewProg, additionalMacros);
- b3Assert(m_data->m_batchingKernelNew);
- }
-}
-
-b3GpuPgsContactSolver::~b3GpuPgsContactSolver()
-{
- delete m_data->m_batchSizesGpu;
- delete m_data->m_bodyBufferGPU;
- delete m_data->m_inertiaBufferGPU;
- delete m_data->m_pBufContactOutGPU;
- delete m_data->m_pBufContactOutGPUCopy;
- delete m_data->m_contactKeyValues;
-
- delete m_data->m_contactCGPU;
- delete m_data->m_numConstraints;
- delete m_data->m_offsets;
- delete m_data->m_sortDataBuffer;
- delete m_data->m_contactBuffer;
-
- delete m_data->m_sort32;
- delete m_data->m_scan;
- delete m_data->m_search;
- delete m_data->m_solverGPU;
-
- clReleaseKernel(m_data->m_batchingKernel);
- clReleaseKernel(m_data->m_batchingKernelNew);
- clReleaseKernel(m_data->m_solveSingleContactKernel);
- clReleaseKernel(m_data->m_solveSingleFrictionKernel);
- clReleaseKernel(m_data->m_solveContactKernel);
- clReleaseKernel(m_data->m_solveFrictionKernel);
-
- clReleaseKernel(m_data->m_contactToConstraintKernel);
- clReleaseKernel(m_data->m_setSortDataKernel);
- clReleaseKernel(m_data->m_reorderContactKernel);
- clReleaseKernel(m_data->m_copyConstraintKernel);
-
- clReleaseKernel(m_data->m_setDeterminismSortDataBodyAKernel);
- clReleaseKernel(m_data->m_setDeterminismSortDataBodyBKernel);
- clReleaseKernel(m_data->m_setDeterminismSortDataChildShapeAKernel);
- clReleaseKernel(m_data->m_setDeterminismSortDataChildShapeBKernel);
-
- delete m_data;
-}
-
-struct b3ConstraintCfg
-{
- b3ConstraintCfg(float dt = 0.f) : m_positionDrift(0.005f), m_positionConstraintCoeff(0.2f), m_dt(dt), m_staticIdx(0) {}
-
- float m_positionDrift;
- float m_positionConstraintCoeff;
- float m_dt;
- bool m_enableParallelSolve;
- float m_batchCellSize;
- int m_staticIdx;
-};
-
-void b3GpuPgsContactSolver::solveContactConstraintBatchSizes(const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf,
- b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes) //const b3OpenCLArray<int>* gpuBatchSizes)
-{
- B3_PROFILE("solveContactConstraintBatchSizes");
- int numBatches = batchSizes->size() / B3_MAX_NUM_BATCHES;
- for (int iter = 0; iter < numIterations; iter++)
- {
- for (int cellId = 0; cellId < numBatches; cellId++)
- {
- int offset = 0;
- for (int ii = 0; ii < B3_MAX_NUM_BATCHES; ii++)
- {
- int numInBatch = batchSizes->at(cellId * B3_MAX_NUM_BATCHES + ii);
- if (!numInBatch)
- break;
-
- {
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solveSingleContactKernel, "m_solveSingleContactKernel");
- launcher.setBuffer(bodyBuf->getBufferCL());
- launcher.setBuffer(shapeBuf->getBufferCL());
- launcher.setBuffer(constraint->getBufferCL());
- launcher.setConst(cellId);
- launcher.setConst(offset);
- launcher.setConst(numInBatch);
- launcher.launch1D(numInBatch);
- offset += numInBatch;
- }
- }
- }
- }
-
- for (int iter = 0; iter < numIterations; iter++)
- {
- for (int cellId = 0; cellId < numBatches; cellId++)
- {
- int offset = 0;
- for (int ii = 0; ii < B3_MAX_NUM_BATCHES; ii++)
- {
- int numInBatch = batchSizes->at(cellId * B3_MAX_NUM_BATCHES + ii);
- if (!numInBatch)
- break;
-
- {
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solveSingleFrictionKernel, "m_solveSingleFrictionKernel");
- launcher.setBuffer(bodyBuf->getBufferCL());
- launcher.setBuffer(shapeBuf->getBufferCL());
- launcher.setBuffer(constraint->getBufferCL());
- launcher.setConst(cellId);
- launcher.setConst(offset);
- launcher.setConst(numInBatch);
- launcher.launch1D(numInBatch);
- offset += numInBatch;
- }
- }
- }
- }
-}
-
-void b3GpuPgsContactSolver::solveContactConstraint(const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf,
- b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes) //,const b3OpenCLArray<int>* gpuBatchSizes)
-{
- //sort the contacts
-
- b3Int4 cdata = b3MakeInt4(n, 0, 0, 0);
- {
- const int nn = B3_SOLVER_N_CELLS;
-
- cdata.x = 0;
- cdata.y = maxNumBatches; //250;
-
- int numWorkItems = 64 * nn / B3_SOLVER_N_BATCHES;
-#ifdef DEBUG_ME
- SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems];
- adl::b3OpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device, numWorkItems);
-#endif
-
- {
- B3_PROFILE("m_batchSolveKernel iterations");
- for (int iter = 0; iter < numIterations; iter++)
- {
- for (int ib = 0; ib < B3_SOLVER_N_BATCHES; ib++)
- {
-#ifdef DEBUG_ME
- memset(debugInfo, 0, sizeof(SolverDebugInfo) * numWorkItems);
- gpuDebugInfo.write(debugInfo, numWorkItems);
-#endif
-
- cdata.z = ib;
-
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solveContactKernel, "m_solveContactKernel");
-#if 1
-
- b3BufferInfoCL bInfo[] = {
-
- b3BufferInfoCL(bodyBuf->getBufferCL()),
- b3BufferInfoCL(shapeBuf->getBufferCL()),
- b3BufferInfoCL(constraint->getBufferCL()),
- b3BufferInfoCL(m_data->m_solverGPU->m_numConstraints->getBufferCL()),
- b3BufferInfoCL(m_data->m_solverGPU->m_offsets->getBufferCL())
-#ifdef DEBUG_ME
- ,
- b3BufferInfoCL(&gpuDebugInfo)
-#endif
- };
-
- launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
- launcher.setBuffer(m_data->m_solverGPU->m_batchSizes.getBufferCL());
- //launcher.setConst( cdata.x );
- launcher.setConst(cdata.y);
- launcher.setConst(cdata.z);
- b3Int4 nSplit;
- nSplit.x = B3_SOLVER_N_SPLIT_X;
- nSplit.y = B3_SOLVER_N_SPLIT_Y;
- nSplit.z = B3_SOLVER_N_SPLIT_Z;
-
- launcher.setConst(nSplit);
- launcher.launch1D(numWorkItems, 64);
-
-#else
- const char* fileName = "m_batchSolveKernel.bin";
- FILE* f = fopen(fileName, "rb");
- if (f)
- {
- int sizeInBytes = 0;
- if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET))
- {
- printf("error, cannot get file size\n");
- exit(0);
- }
-
- unsigned char* buf = (unsigned char*)malloc(sizeInBytes);
- fread(buf, sizeInBytes, 1, f);
- int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes, m_context);
- int num = *(int*)&buf[serializedBytes];
-
- launcher.launch1D(num);
-
- //this clFinish is for testing on errors
- clFinish(m_queue);
- }
-
-#endif
-
-#ifdef DEBUG_ME
- clFinish(m_queue);
- gpuDebugInfo.read(debugInfo, numWorkItems);
- clFinish(m_queue);
- for (int i = 0; i < numWorkItems; i++)
- {
- if (debugInfo[i].m_valInt2 > 0)
- {
- printf("debugInfo[i].m_valInt2 = %d\n", i, debugInfo[i].m_valInt2);
- }
-
- if (debugInfo[i].m_valInt3 > 0)
- {
- printf("debugInfo[i].m_valInt3 = %d\n", i, debugInfo[i].m_valInt3);
- }
- }
-#endif //DEBUG_ME
- }
- }
-
- clFinish(m_data->m_queue);
- }
-
- cdata.x = 1;
- bool applyFriction = true;
- if (applyFriction)
- {
- B3_PROFILE("m_batchSolveKernel iterations2");
- for (int iter = 0; iter < numIterations; iter++)
- {
- for (int ib = 0; ib < B3_SOLVER_N_BATCHES; ib++)
- {
- cdata.z = ib;
-
- b3BufferInfoCL bInfo[] = {
- b3BufferInfoCL(bodyBuf->getBufferCL()),
- b3BufferInfoCL(shapeBuf->getBufferCL()),
- b3BufferInfoCL(constraint->getBufferCL()),
- b3BufferInfoCL(m_data->m_solverGPU->m_numConstraints->getBufferCL()),
- b3BufferInfoCL(m_data->m_solverGPU->m_offsets->getBufferCL())
-#ifdef DEBUG_ME
- ,
- b3BufferInfoCL(&gpuDebugInfo)
-#endif //DEBUG_ME
- };
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solveFrictionKernel, "m_solveFrictionKernel");
- launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
- launcher.setBuffer(m_data->m_solverGPU->m_batchSizes.getBufferCL());
- //launcher.setConst( cdata.x );
- launcher.setConst(cdata.y);
- launcher.setConst(cdata.z);
-
- b3Int4 nSplit;
- nSplit.x = B3_SOLVER_N_SPLIT_X;
- nSplit.y = B3_SOLVER_N_SPLIT_Y;
- nSplit.z = B3_SOLVER_N_SPLIT_Z;
-
- launcher.setConst(nSplit);
-
- launcher.launch1D(64 * nn / B3_SOLVER_N_BATCHES, 64);
- }
- }
- clFinish(m_data->m_queue);
- }
-#ifdef DEBUG_ME
- delete[] debugInfo;
-#endif //DEBUG_ME
- }
-}
-
-static bool sortfnc(const b3SortData& a, const b3SortData& b)
-{
- return (a.m_key < b.m_key);
-}
-
-static bool b3ContactCmp(const b3Contact4& p, const b3Contact4& q)
-{
- return ((p.m_bodyAPtrAndSignBit < q.m_bodyAPtrAndSignBit) ||
- ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit < q.m_bodyBPtrAndSignBit)) ||
- ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit == q.m_bodyBPtrAndSignBit) && p.m_childIndexA < q.m_childIndexA) ||
- ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit == q.m_bodyBPtrAndSignBit) && p.m_childIndexA < q.m_childIndexA) ||
- ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit == q.m_bodyBPtrAndSignBit) && p.m_childIndexA == q.m_childIndexA && p.m_childIndexB < q.m_childIndexB));
-}
-
-#define USE_SPATIAL_BATCHING 1
-#define USE_4x4_GRID 1
-
-#ifndef USE_SPATIAL_BATCHING
-static const int gridTable4x4[] =
- {
- 0, 1, 17, 16,
- 1, 2, 18, 19,
- 17, 18, 32, 3,
- 16, 19, 3, 34};
-static const int gridTable8x8[] =
- {
- 0, 2, 3, 16, 17, 18, 19, 1,
- 66, 64, 80, 67, 82, 81, 65, 83,
- 131, 144, 128, 130, 147, 129, 145, 146,
- 208, 195, 194, 192, 193, 211, 210, 209,
- 21, 22, 23, 5, 4, 6, 7, 20,
- 86, 85, 69, 87, 70, 68, 84, 71,
- 151, 133, 149, 150, 135, 148, 132, 134,
- 197, 27, 214, 213, 212, 199, 198, 196
-
-};
-
-#endif
-
-void SetSortDataCPU(b3Contact4* gContact, b3RigidBodyData* gBodies, b3SortData* gSortDataOut, int nContacts, float scale, const b3Int4& nSplit, int staticIdx)
-{
- for (int gIdx = 0; gIdx < nContacts; gIdx++)
- {
- if (gIdx < nContacts)
- {
- int aPtrAndSignBit = gContact[gIdx].m_bodyAPtrAndSignBit;
- int bPtrAndSignBit = gContact[gIdx].m_bodyBPtrAndSignBit;
-
- int aIdx = abs(aPtrAndSignBit);
- int bIdx = abs(bPtrAndSignBit);
-
- bool aStatic = (aPtrAndSignBit < 0) || (aPtrAndSignBit == staticIdx);
-
-#if USE_SPATIAL_BATCHING
- int idx = (aStatic) ? bIdx : aIdx;
- b3Vector3 p = gBodies[idx].m_pos;
- int xIdx = (int)((p.x - ((p.x < 0.f) ? 1.f : 0.f)) * scale) & (nSplit.x - 1);
- int yIdx = (int)((p.y - ((p.y < 0.f) ? 1.f : 0.f)) * scale) & (nSplit.y - 1);
- int zIdx = (int)((p.z - ((p.z < 0.f) ? 1.f : 0.f)) * scale) & (nSplit.z - 1);
-
- int newIndex = (xIdx + yIdx * nSplit.x + zIdx * nSplit.x * nSplit.y);
-
-#else //USE_SPATIAL_BATCHING
- bool bStatic = (bPtrAndSignBit < 0) || (bPtrAndSignBit == staticIdx);
-
-#if USE_4x4_GRID
- int aa = aIdx & 3;
- int bb = bIdx & 3;
- if (aStatic)
- aa = bb;
- if (bStatic)
- bb = aa;
-
- int gridIndex = aa + bb * 4;
- int newIndex = gridTable4x4[gridIndex];
-#else //USE_4x4_GRID
- int aa = aIdx & 7;
- int bb = bIdx & 7;
- if (aStatic)
- aa = bb;
- if (bStatic)
- bb = aa;
-
- int gridIndex = aa + bb * 8;
- int newIndex = gridTable8x8[gridIndex];
-#endif //USE_4x4_GRID
-#endif //USE_SPATIAL_BATCHING
-
- gSortDataOut[gIdx].x = newIndex;
- gSortDataOut[gIdx].y = gIdx;
- }
- else
- {
- gSortDataOut[gIdx].x = 0xffffffff;
- }
- }
-}
-
-void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const b3Config& config, int static0Index)
-{
- B3_PROFILE("solveContacts");
- m_data->m_bodyBufferGPU->setFromOpenCLBuffer(bodyBuf, numBodies);
- m_data->m_inertiaBufferGPU->setFromOpenCLBuffer(inertiaBuf, numBodies);
- m_data->m_pBufContactOutGPU->setFromOpenCLBuffer(contactBuf, numContacts);
-
- if (optionalSortContactsDeterminism)
- {
- if (!gCpuSortContactsDeterminism)
- {
- B3_PROFILE("GPU Sort contact constraints (determinism)");
-
- m_data->m_pBufContactOutGPUCopy->resize(numContacts);
- m_data->m_contactKeyValues->resize(numContacts);
-
- m_data->m_pBufContactOutGPU->copyToCL(m_data->m_pBufContactOutGPUCopy->getBufferCL(), numContacts, 0, 0);
-
- {
- b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeBKernel, "m_setDeterminismSortDataChildShapeBKernel");
- launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL());
- launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL());
- launcher.setConst(numContacts);
- launcher.launch1D(numContacts, 64);
- }
- m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues);
- {
- b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeAKernel, "m_setDeterminismSortDataChildShapeAKernel");
- launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL());
- launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL());
- launcher.setConst(numContacts);
- launcher.launch1D(numContacts, 64);
- }
- m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues);
- {
- b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyBKernel, "m_setDeterminismSortDataBodyBKernel");
- launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL());
- launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL());
- launcher.setConst(numContacts);
- launcher.launch1D(numContacts, 64);
- }
-
- m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues);
-
- {
- b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyAKernel, "m_setDeterminismSortDataBodyAKernel");
- launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL());
- launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL());
- launcher.setConst(numContacts);
- launcher.launch1D(numContacts, 64);
- }
-
- m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues);
-
- {
- B3_PROFILE("gpu reorderContactKernel (determinism)");
-
- b3Int4 cdata;
- cdata.x = numContacts;
-
- //b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ), b3BufferInfoCL( m_data->m_solverGPU->m_contactBuffer2->getBufferCL())
- // , b3BufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) };
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_reorderContactKernel, "m_reorderContactKernel");
- launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL());
- launcher.setBuffer(m_data->m_pBufContactOutGPU->getBufferCL());
- launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL());
- launcher.setConst(cdata);
- launcher.launch1D(numContacts, 64);
- }
- }
- else
- {
- B3_PROFILE("CPU Sort contact constraints (determinism)");
- b3AlignedObjectArray<b3Contact4> cpuConstraints;
- m_data->m_pBufContactOutGPU->copyToHost(cpuConstraints);
- bool sort = true;
- if (sort)
- {
- cpuConstraints.quickSort(b3ContactCmp);
-
- for (int i = 0; i < cpuConstraints.size(); i++)
- {
- cpuConstraints[i].m_batchIdx = i;
- }
- }
- m_data->m_pBufContactOutGPU->copyFromHost(cpuConstraints);
- if (m_debugOutput == 100)
- {
- for (int i = 0; i < cpuConstraints.size(); i++)
- {
- printf("c[%d].m_bodyA = %d, m_bodyB = %d, batchId = %d\n", i, cpuConstraints[i].m_bodyAPtrAndSignBit, cpuConstraints[i].m_bodyBPtrAndSignBit, cpuConstraints[i].m_batchIdx);
- }
- }
-
- m_debugOutput++;
- }
- }
-
- int nContactOut = m_data->m_pBufContactOutGPU->size();
-
- bool useSolver = true;
-
- if (useSolver)
- {
- float dt = 1. / 60.;
- b3ConstraintCfg csCfg(dt);
- csCfg.m_enableParallelSolve = true;
- csCfg.m_batchCellSize = 6;
- csCfg.m_staticIdx = static0Index;
-
- b3OpenCLArray<b3RigidBodyData>* bodyBuf = m_data->m_bodyBufferGPU;
-
- void* additionalData = 0; //m_data->m_frictionCGPU;
- const b3OpenCLArray<b3InertiaData>* shapeBuf = m_data->m_inertiaBufferGPU;
- b3OpenCLArray<b3GpuConstraint4>* contactConstraintOut = m_data->m_contactCGPU;
- int nContacts = nContactOut;
-
- int maxNumBatches = 0;
-
- if (!gUseLargeBatches)
- {
- if (m_data->m_solverGPU->m_contactBuffer2)
- {
- m_data->m_solverGPU->m_contactBuffer2->resize(nContacts);
- }
-
- if (m_data->m_solverGPU->m_contactBuffer2 == 0)
- {
- m_data->m_solverGPU->m_contactBuffer2 = new b3OpenCLArray<b3Contact4>(m_data->m_context, m_data->m_queue, nContacts);
- m_data->m_solverGPU->m_contactBuffer2->resize(nContacts);
- }
-
- //clFinish(m_data->m_queue);
-
- {
- B3_PROFILE("batching");
- //@todo: just reserve it, without copy of original contact (unless we use warmstarting)
-
- //const b3OpenCLArray<b3RigidBodyData>* bodyNative = bodyBuf;
-
- {
- //b3OpenCLArray<b3RigidBodyData>* bodyNative = b3OpenCLArrayUtils::map<adl::TYPE_CL, true>( data->m_device, bodyBuf );
- //b3OpenCLArray<b3Contact4>* contactNative = b3OpenCLArrayUtils::map<adl::TYPE_CL, true>( data->m_device, contactsIn );
-
- const int sortAlignment = 512; // todo. get this out of sort
- if (csCfg.m_enableParallelSolve)
- {
- int sortSize = B3NEXTMULTIPLEOF(nContacts, sortAlignment);
-
- b3OpenCLArray<unsigned int>* countsNative = m_data->m_solverGPU->m_numConstraints;
- b3OpenCLArray<unsigned int>* offsetsNative = m_data->m_solverGPU->m_offsets;
-
- if (!gCpuSetSortData)
- { // 2. set cell idx
- B3_PROFILE("GPU set cell idx");
- struct CB
- {
- int m_nContacts;
- int m_staticIdx;
- float m_scale;
- b3Int4 m_nSplit;
- };
-
- b3Assert(sortSize % 64 == 0);
- CB cdata;
- cdata.m_nContacts = nContacts;
- cdata.m_staticIdx = csCfg.m_staticIdx;
- cdata.m_scale = 1.f / csCfg.m_batchCellSize;
- cdata.m_nSplit.x = B3_SOLVER_N_SPLIT_X;
- cdata.m_nSplit.y = B3_SOLVER_N_SPLIT_Y;
- cdata.m_nSplit.z = B3_SOLVER_N_SPLIT_Z;
-
- m_data->m_solverGPU->m_sortDataBuffer->resize(nContacts);
-
- b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL()), b3BufferInfoCL(bodyBuf->getBufferCL()), b3BufferInfoCL(m_data->m_solverGPU->m_sortDataBuffer->getBufferCL())};
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_setSortDataKernel, "m_setSortDataKernel");
- launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
- launcher.setConst(cdata.m_nContacts);
- launcher.setConst(cdata.m_scale);
- launcher.setConst(cdata.m_nSplit);
- launcher.setConst(cdata.m_staticIdx);
-
- launcher.launch1D(sortSize, 64);
- }
- else
- {
- m_data->m_solverGPU->m_sortDataBuffer->resize(nContacts);
- b3AlignedObjectArray<b3SortData> sortDataCPU;
- m_data->m_solverGPU->m_sortDataBuffer->copyToHost(sortDataCPU);
-
- b3AlignedObjectArray<b3Contact4> contactCPU;
- m_data->m_pBufContactOutGPU->copyToHost(contactCPU);
- b3AlignedObjectArray<b3RigidBodyData> bodiesCPU;
- bodyBuf->copyToHost(bodiesCPU);
- float scale = 1.f / csCfg.m_batchCellSize;
- b3Int4 nSplit;
- nSplit.x = B3_SOLVER_N_SPLIT_X;
- nSplit.y = B3_SOLVER_N_SPLIT_Y;
- nSplit.z = B3_SOLVER_N_SPLIT_Z;
-
- SetSortDataCPU(&contactCPU[0], &bodiesCPU[0], &sortDataCPU[0], nContacts, scale, nSplit, csCfg.m_staticIdx);
-
- m_data->m_solverGPU->m_sortDataBuffer->copyFromHost(sortDataCPU);
- }
-
- if (!gCpuRadixSort)
- { // 3. sort by cell idx
- B3_PROFILE("gpuRadixSort");
- //int n = B3_SOLVER_N_SPLIT*B3_SOLVER_N_SPLIT;
- //int sortBit = 32;
- //if( n <= 0xffff ) sortBit = 16;
- //if( n <= 0xff ) sortBit = 8;
- //adl::RadixSort<adl::TYPE_CL>::execute( data->m_sort, *data->m_sortDataBuffer, sortSize );
- //adl::RadixSort32<adl::TYPE_CL>::execute( data->m_sort32, *data->m_sortDataBuffer, sortSize );
- b3OpenCLArray<b3SortData>& keyValuesInOut = *(m_data->m_solverGPU->m_sortDataBuffer);
- this->m_data->m_solverGPU->m_sort32->execute(keyValuesInOut);
- }
- else
- {
- b3OpenCLArray<b3SortData>& keyValuesInOut = *(m_data->m_solverGPU->m_sortDataBuffer);
- b3AlignedObjectArray<b3SortData> hostValues;
- keyValuesInOut.copyToHost(hostValues);
- hostValues.quickSort(sortfnc);
- keyValuesInOut.copyFromHost(hostValues);
- }
-
- if (gUseScanHost)
- {
- // 4. find entries
- B3_PROFILE("cpuBoundSearch");
- b3AlignedObjectArray<unsigned int> countsHost;
- countsNative->copyToHost(countsHost);
-
- b3AlignedObjectArray<b3SortData> sortDataHost;
- m_data->m_solverGPU->m_sortDataBuffer->copyToHost(sortDataHost);
-
- //m_data->m_solverGPU->m_search->executeHost(*m_data->m_solverGPU->m_sortDataBuffer,nContacts,*countsNative,B3_SOLVER_N_CELLS,b3BoundSearchCL::COUNT);
- m_data->m_solverGPU->m_search->executeHost(sortDataHost, nContacts, countsHost, B3_SOLVER_N_CELLS, b3BoundSearchCL::COUNT);
-
- countsNative->copyFromHost(countsHost);
-
- //adl::BoundSearch<adl::TYPE_CL>::execute( data->m_search, *data->m_sortDataBuffer, nContacts, *countsNative,
- // B3_SOLVER_N_SPLIT*B3_SOLVER_N_SPLIT, adl::BoundSearchBase::COUNT );
-
- //unsigned int sum;
- //m_data->m_solverGPU->m_scan->execute(*countsNative,*offsetsNative, B3_SOLVER_N_CELLS);//,&sum );
- b3AlignedObjectArray<unsigned int> offsetsHost;
- offsetsHost.resize(offsetsNative->size());
-
- m_data->m_solverGPU->m_scan->executeHost(countsHost, offsetsHost, B3_SOLVER_N_CELLS); //,&sum );
- offsetsNative->copyFromHost(offsetsHost);
-
- //printf("sum = %d\n",sum);
- }
- else
- {
- // 4. find entries
- B3_PROFILE("gpuBoundSearch");
- m_data->m_solverGPU->m_search->execute(*m_data->m_solverGPU->m_sortDataBuffer, nContacts, *countsNative, B3_SOLVER_N_CELLS, b3BoundSearchCL::COUNT);
- m_data->m_solverGPU->m_scan->execute(*countsNative, *offsetsNative, B3_SOLVER_N_CELLS); //,&sum );
- }
-
- if (nContacts)
- { // 5. sort constraints by cellIdx
- if (gReorderContactsOnCpu)
- {
- B3_PROFILE("cpu m_reorderContactKernel");
- b3AlignedObjectArray<b3SortData> sortDataHost;
- m_data->m_solverGPU->m_sortDataBuffer->copyToHost(sortDataHost);
- b3AlignedObjectArray<b3Contact4> inContacts;
- b3AlignedObjectArray<b3Contact4> outContacts;
- m_data->m_pBufContactOutGPU->copyToHost(inContacts);
- outContacts.resize(inContacts.size());
- for (int i = 0; i < nContacts; i++)
- {
- int srcIdx = sortDataHost[i].y;
- outContacts[i] = inContacts[srcIdx];
- }
- m_data->m_solverGPU->m_contactBuffer2->copyFromHost(outContacts);
-
- /* "void ReorderContactKernel(__global struct b3Contact4Data* in, __global struct b3Contact4Data* out, __global int2* sortData, int4 cb )\n"
- "{\n"
- " int nContacts = cb.x;\n"
- " int gIdx = GET_GLOBAL_IDX;\n"
- " if( gIdx < nContacts )\n"
- " {\n"
- " int srcIdx = sortData[gIdx].y;\n"
- " out[gIdx] = in[srcIdx];\n"
- " }\n"
- "}\n"
- */
- }
- else
- {
- B3_PROFILE("gpu m_reorderContactKernel");
-
- b3Int4 cdata;
- cdata.x = nContacts;
-
- b3BufferInfoCL bInfo[] = {
- b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL()),
- b3BufferInfoCL(m_data->m_solverGPU->m_contactBuffer2->getBufferCL()), b3BufferInfoCL(m_data->m_solverGPU->m_sortDataBuffer->getBufferCL())};
-
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_reorderContactKernel, "m_reorderContactKernel");
- launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
- launcher.setConst(cdata);
- launcher.launch1D(nContacts, 64);
- }
- }
- }
- }
-
- //clFinish(m_data->m_queue);
-
- // {
- // b3AlignedObjectArray<unsigned int> histogram;
- // m_data->m_solverGPU->m_numConstraints->copyToHost(histogram);
- // printf(",,,\n");
- // }
-
- if (nContacts)
- {
- if (gUseCpuCopyConstraints)
- {
- for (int i = 0; i < nContacts; i++)
- {
- m_data->m_pBufContactOutGPU->copyFromOpenCLArray(*m_data->m_solverGPU->m_contactBuffer2);
- // m_data->m_solverGPU->m_contactBuffer2->getBufferCL();
- // m_data->m_pBufContactOutGPU->getBufferCL()
- }
- }
- else
- {
- B3_PROFILE("gpu m_copyConstraintKernel");
- b3Int4 cdata;
- cdata.x = nContacts;
- b3BufferInfoCL bInfo[] = {
- b3BufferInfoCL(m_data->m_solverGPU->m_contactBuffer2->getBufferCL()),
- b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL())};
-
- b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_copyConstraintKernel, "m_copyConstraintKernel");
- launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
- launcher.setConst(cdata);
- launcher.launch1D(nContacts, 64);
- //we use the clFinish for proper benchmark/profile
- clFinish(m_data->m_queue);
- }
- }
-
- // bool compareGPU = false;
- if (nContacts)
- {
- if (!gCpuBatchContacts)
- {
- B3_PROFILE("gpu batchContacts");
- maxNumBatches = 250; //250;
- m_data->m_solverGPU->batchContacts(m_data->m_pBufContactOutGPU, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx);
- clFinish(m_data->m_queue);
- }
- else
- {
- B3_PROFILE("cpu batchContacts");
- static b3AlignedObjectArray<b3Contact4> cpuContacts;
- b3OpenCLArray<b3Contact4>* contactsIn = m_data->m_solverGPU->m_contactBuffer2;
- {
- B3_PROFILE("copyToHost");
- contactsIn->copyToHost(cpuContacts);
- }
- b3OpenCLArray<unsigned int>* countsNative = m_data->m_solverGPU->m_numConstraints;
- b3OpenCLArray<unsigned int>* offsetsNative = m_data->m_solverGPU->m_offsets;
-
- b3AlignedObjectArray<unsigned int> nNativeHost;
- b3AlignedObjectArray<unsigned int> offsetsNativeHost;
-
- {
- B3_PROFILE("countsNative/offsetsNative copyToHost");
- countsNative->copyToHost(nNativeHost);
- offsetsNative->copyToHost(offsetsNativeHost);
- }
-
- int numNonzeroGrid = 0;
-
- if (gUseLargeBatches)
- {
- m_data->m_batchSizes.resize(B3_MAX_NUM_BATCHES);
- int totalNumConstraints = cpuContacts.size();
- //int simdWidth =numBodies+1;//-1;//64;//-1;//32;
- int numBatches = sortConstraintByBatch3(&cpuContacts[0], totalNumConstraints, totalNumConstraints + 1, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[0]); // on GPU
- maxNumBatches = b3Max(numBatches, maxNumBatches);
- static int globalMaxBatch = 0;
- if (maxNumBatches > globalMaxBatch)
- {
- globalMaxBatch = maxNumBatches;
- b3Printf("maxNumBatches = %d\n", maxNumBatches);
- }
- }
- else
- {
- m_data->m_batchSizes.resize(B3_SOLVER_N_CELLS * B3_MAX_NUM_BATCHES);
- B3_PROFILE("cpu batch grid");
- for (int i = 0; i < B3_SOLVER_N_CELLS; i++)
- {
- int n = (nNativeHost)[i];
- int offset = (offsetsNativeHost)[i];
- if (n)
- {
- numNonzeroGrid++;
- int simdWidth = numBodies + 1; //-1;//64;//-1;//32;
- int numBatches = sortConstraintByBatch3(&cpuContacts[0] + offset, n, simdWidth, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[i * B3_MAX_NUM_BATCHES]); // on GPU
- maxNumBatches = b3Max(numBatches, maxNumBatches);
- static int globalMaxBatch = 0;
- if (maxNumBatches > globalMaxBatch)
- {
- globalMaxBatch = maxNumBatches;
- b3Printf("maxNumBatches = %d\n", maxNumBatches);
- }
- //we use the clFinish for proper benchmark/profile
- }
- }
- //clFinish(m_data->m_queue);
- }
- {
- B3_PROFILE("m_contactBuffer->copyFromHost");
- m_data->m_solverGPU->m_contactBuffer2->copyFromHost((b3AlignedObjectArray<b3Contact4>&)cpuContacts);
- }
- }
- }
- }
- }
-
- //printf("maxNumBatches = %d\n", maxNumBatches);
-
- if (gUseLargeBatches)
- {
- if (nContacts)
- {
- B3_PROFILE("cpu batchContacts");
- static b3AlignedObjectArray<b3Contact4> cpuContacts;
- // b3OpenCLArray<b3Contact4>* contactsIn = m_data->m_solverGPU->m_contactBuffer2;
- {
- B3_PROFILE("copyToHost");
- m_data->m_pBufContactOutGPU->copyToHost(cpuContacts);
- }
- // b3OpenCLArray<unsigned int>* countsNative = m_data->m_solverGPU->m_numConstraints;
- // b3OpenCLArray<unsigned int>* offsetsNative = m_data->m_solverGPU->m_offsets;
-
- // int numNonzeroGrid=0;
-
- {
- m_data->m_batchSizes.resize(B3_MAX_NUM_BATCHES);
- int totalNumConstraints = cpuContacts.size();
- // int simdWidth =numBodies+1;//-1;//64;//-1;//32;
- int numBatches = sortConstraintByBatch3(&cpuContacts[0], totalNumConstraints, totalNumConstraints + 1, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[0]); // on GPU
- maxNumBatches = b3Max(numBatches, maxNumBatches);
- static int globalMaxBatch = 0;
- if (maxNumBatches > globalMaxBatch)
- {
- globalMaxBatch = maxNumBatches;
- b3Printf("maxNumBatches = %d\n", maxNumBatches);
- }
- }
- {
- B3_PROFILE("m_contactBuffer->copyFromHost");
- m_data->m_solverGPU->m_contactBuffer2->copyFromHost((b3AlignedObjectArray<b3Contact4>&)cpuContacts);
- }
- }
- }
-
- if (nContacts)
- {
- B3_PROFILE("gpu convertToConstraints");
- m_data->m_solverGPU->convertToConstraints(bodyBuf,
- shapeBuf, m_data->m_solverGPU->m_contactBuffer2,
- contactConstraintOut,
- additionalData, nContacts,
- (b3SolverBase::ConstraintCfg&)csCfg);
- clFinish(m_data->m_queue);
- }
-
- if (1)
- {
- int numIter = 4;
-
- m_data->m_solverGPU->m_nIterations = numIter; //10
- if (!gCpuSolveConstraint)
- {
- B3_PROFILE("GPU solveContactConstraint");
-
- /*m_data->m_solverGPU->solveContactConstraint(
- m_data->m_bodyBufferGPU,
- m_data->m_inertiaBufferGPU,
- m_data->m_contactCGPU,0,
- nContactOut ,
- maxNumBatches);
- */
-
- //m_data->m_batchSizesGpu->copyFromHost(m_data->m_batchSizes);
-
- if (gUseLargeBatches)
- {
- solveContactConstraintBatchSizes(m_data->m_bodyBufferGPU,
- m_data->m_inertiaBufferGPU,
- m_data->m_contactCGPU, 0,
- nContactOut,
- maxNumBatches, numIter, &m_data->m_batchSizes);
- }
- else
- {
- solveContactConstraint(
- m_data->m_bodyBufferGPU,
- m_data->m_inertiaBufferGPU,
- m_data->m_contactCGPU, 0,
- nContactOut,
- maxNumBatches, numIter, &m_data->m_batchSizes); //m_data->m_batchSizesGpu);
- }
- }
- else
- {
- B3_PROFILE("Host solveContactConstraint");
-
- m_data->m_solverGPU->solveContactConstraintHost(m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, m_data->m_contactCGPU, 0, nContactOut, maxNumBatches, &m_data->m_batchSizes);
- }
- }
-
-#if 0
- if (0)
- {
- B3_PROFILE("read body velocities back to CPU");
- //read body updated linear/angular velocities back to CPU
- m_data->m_bodyBufferGPU->read(
- m_data->m_bodyBufferCPU->m_ptr,numOfConvexRBodies);
- adl::DeviceUtils::waitForCompletion( m_data->m_deviceCL );
- }
-#endif
- }
-}
-
-void b3GpuPgsContactSolver::batchContacts(b3OpenCLArray<b3Contact4>* contacts, int nContacts, b3OpenCLArray<unsigned int>* n, b3OpenCLArray<unsigned int>* offsets, int staticIdx)
-{
-}
-
-b3AlignedObjectArray<unsigned int> idxBuffer;
-b3AlignedObjectArray<b3SortData> sortData;
-b3AlignedObjectArray<b3Contact4> old;
-
-inline int b3GpuPgsContactSolver::sortConstraintByBatch(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies)
-{
- B3_PROFILE("sortConstraintByBatch");
- int numIter = 0;
-
- sortData.resize(n);
- idxBuffer.resize(n);
- old.resize(n);
-
- unsigned int* idxSrc = &idxBuffer[0];
- unsigned int* idxDst = &idxBuffer[0];
- int nIdxSrc, nIdxDst;
-
- const int N_FLG = 256;
- const int FLG_MASK = N_FLG - 1;
- unsigned int flg[N_FLG / 32];
-#if defined(_DEBUG)
- for (int i = 0; i < n; i++)
- cs[i].getBatchIdx() = -1;
-#endif
- for (int i = 0; i < n; i++)
- idxSrc[i] = i;
- nIdxSrc = n;
-
- int batchIdx = 0;
-
- {
- B3_PROFILE("cpu batch innerloop");
- while (nIdxSrc)
- {
- numIter++;
- nIdxDst = 0;
- int nCurrentBatch = 0;
-
- // clear flag
- for (int i = 0; i < N_FLG / 32; i++) flg[i] = 0;
-
- for (int i = 0; i < nIdxSrc; i++)
- {
- int idx = idxSrc[i];
-
- b3Assert(idx < n);
- // check if it can go
- int bodyAS = cs[idx].m_bodyAPtrAndSignBit;
- int bodyBS = cs[idx].m_bodyBPtrAndSignBit;
-
- int bodyA = abs(bodyAS);
- int bodyB = abs(bodyBS);
-
- int aIdx = bodyA & FLG_MASK;
- int bIdx = bodyB & FLG_MASK;
-
- unsigned int aUnavailable = flg[aIdx / 32] & (1 << (aIdx & 31));
- unsigned int bUnavailable = flg[bIdx / 32] & (1 << (bIdx & 31));
-
- bool aIsStatic = (bodyAS < 0) || bodyAS == staticIdx;
- bool bIsStatic = (bodyBS < 0) || bodyBS == staticIdx;
-
- //use inv_mass!
- aUnavailable = !aIsStatic ? aUnavailable : 0; //
- bUnavailable = !bIsStatic ? bUnavailable : 0;
-
- if (aUnavailable == 0 && bUnavailable == 0) // ok
- {
- if (!aIsStatic)
- flg[aIdx / 32] |= (1 << (aIdx & 31));
- if (!bIsStatic)
- flg[bIdx / 32] |= (1 << (bIdx & 31));
-
- cs[idx].getBatchIdx() = batchIdx;
- sortData[idx].m_key = batchIdx;
- sortData[idx].m_value = idx;
-
- {
- nCurrentBatch++;
- if (nCurrentBatch == simdWidth)
- {
- nCurrentBatch = 0;
- for (int i = 0; i < N_FLG / 32; i++) flg[i] = 0;
- }
- }
- }
- else
- {
- idxDst[nIdxDst++] = idx;
- }
- }
- b3Swap(idxSrc, idxDst);
- b3Swap(nIdxSrc, nIdxDst);
- batchIdx++;
- }
- }
- {
- B3_PROFILE("quickSort");
- sortData.quickSort(sortfnc);
- }
-
- {
- B3_PROFILE("reorder");
- // reorder
-
- memcpy(&old[0], cs, sizeof(b3Contact4) * n);
- for (int i = 0; i < n; i++)
- {
- int idx = sortData[i].m_value;
- cs[i] = old[idx];
- }
- }
-
-#if defined(_DEBUG)
- // debugPrintf( "nBatches: %d\n", batchIdx );
- for (int i = 0; i < n; i++)
- {
- b3Assert(cs[i].getBatchIdx() != -1);
- }
-#endif
- return batchIdx;
-}
-
-b3AlignedObjectArray<int> bodyUsed2;
-
-inline int b3GpuPgsContactSolver::sortConstraintByBatch2(b3Contact4* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies)
-{
- B3_PROFILE("sortConstraintByBatch2");
-
- bodyUsed2.resize(2 * simdWidth);
-
- for (int q = 0; q < 2 * simdWidth; q++)
- bodyUsed2[q] = 0;
-
- int curBodyUsed = 0;
-
- int numIter = 0;
-
- m_data->m_sortData.resize(numConstraints);
- m_data->m_idxBuffer.resize(numConstraints);
- m_data->m_old.resize(numConstraints);
-
- unsigned int* idxSrc = &m_data->m_idxBuffer[0];
-
-#if defined(_DEBUG)
- for (int i = 0; i < numConstraints; i++)
- cs[i].getBatchIdx() = -1;
-#endif
- for (int i = 0; i < numConstraints; i++)
- idxSrc[i] = i;
-
- int numValidConstraints = 0;
- // int unprocessedConstraintIndex = 0;
-
- int batchIdx = 0;
-
- {
- B3_PROFILE("cpu batch innerloop");
-
- while (numValidConstraints < numConstraints)
- {
- numIter++;
- int nCurrentBatch = 0;
- // clear flag
- for (int i = 0; i < curBodyUsed; i++)
- bodyUsed2[i] = 0;
- curBodyUsed = 0;
-
- for (int i = numValidConstraints; i < numConstraints; i++)
- {
- int idx = idxSrc[i];
- b3Assert(idx < numConstraints);
- // check if it can go
- int bodyAS = cs[idx].m_bodyAPtrAndSignBit;
- int bodyBS = cs[idx].m_bodyBPtrAndSignBit;
- int bodyA = abs(bodyAS);
- int bodyB = abs(bodyBS);
- bool aIsStatic = (bodyAS < 0) || bodyAS == staticIdx;
- bool bIsStatic = (bodyBS < 0) || bodyBS == staticIdx;
- int aUnavailable = 0;
- int bUnavailable = 0;
- if (!aIsStatic)
- {
- for (int j = 0; j < curBodyUsed; j++)
- {
- if (bodyA == bodyUsed2[j])
- {
- aUnavailable = 1;
- break;
- }
- }
- }
- if (!aUnavailable)
- if (!bIsStatic)
- {
- for (int j = 0; j < curBodyUsed; j++)
- {
- if (bodyB == bodyUsed2[j])
- {
- bUnavailable = 1;
- break;
- }
- }
- }
-
- if (aUnavailable == 0 && bUnavailable == 0) // ok
- {
- if (!aIsStatic)
- {
- bodyUsed2[curBodyUsed++] = bodyA;
- }
- if (!bIsStatic)
- {
- bodyUsed2[curBodyUsed++] = bodyB;
- }
-
- cs[idx].getBatchIdx() = batchIdx;
- m_data->m_sortData[idx].m_key = batchIdx;
- m_data->m_sortData[idx].m_value = idx;
-
- if (i != numValidConstraints)
- {
- b3Swap(idxSrc[i], idxSrc[numValidConstraints]);
- }
-
- numValidConstraints++;
- {
- nCurrentBatch++;
- if (nCurrentBatch == simdWidth)
- {
- nCurrentBatch = 0;
- for (int i = 0; i < curBodyUsed; i++)
- bodyUsed2[i] = 0;
-
- curBodyUsed = 0;
- }
- }
- }
- }
-
- batchIdx++;
- }
- }
- {
- B3_PROFILE("quickSort");
- //m_data->m_sortData.quickSort(sortfnc);
- }
-
- {
- B3_PROFILE("reorder");
- // reorder
-
- memcpy(&m_data->m_old[0], cs, sizeof(b3Contact4) * numConstraints);
-
- for (int i = 0; i < numConstraints; i++)
- {
- b3Assert(m_data->m_sortData[idxSrc[i]].m_value == idxSrc[i]);
- int idx = m_data->m_sortData[idxSrc[i]].m_value;
- cs[i] = m_data->m_old[idx];
- }
- }
-
-#if defined(_DEBUG)
- // debugPrintf( "nBatches: %d\n", batchIdx );
- for (int i = 0; i < numConstraints; i++)
- {
- b3Assert(cs[i].getBatchIdx() != -1);
- }
-#endif
-
- return batchIdx;
-}
-
-b3AlignedObjectArray<int> bodyUsed;
-b3AlignedObjectArray<int> curUsed;
-
-inline int b3GpuPgsContactSolver::sortConstraintByBatch3(b3Contact4* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies, int* batchSizes)
-{
- B3_PROFILE("sortConstraintByBatch3");
-
- static int maxSwaps = 0;
- int numSwaps = 0;
-
- curUsed.resize(2 * simdWidth);
-
- static int maxNumConstraints = 0;
- if (maxNumConstraints < numConstraints)
- {
- maxNumConstraints = numConstraints;
- //printf("maxNumConstraints = %d\n",maxNumConstraints );
- }
-
- int numUsedArray = numBodies / 32 + 1;
- bodyUsed.resize(numUsedArray);
-
- for (int q = 0; q < numUsedArray; q++)
- bodyUsed[q] = 0;
-
- int curBodyUsed = 0;
-
- int numIter = 0;
-
- m_data->m_sortData.resize(0);
- m_data->m_idxBuffer.resize(0);
- m_data->m_old.resize(0);
-
-#if defined(_DEBUG)
- for (int i = 0; i < numConstraints; i++)
- cs[i].getBatchIdx() = -1;
-#endif
-
- int numValidConstraints = 0;
- // int unprocessedConstraintIndex = 0;
-
- int batchIdx = 0;
-
- {
- B3_PROFILE("cpu batch innerloop");
-
- while (numValidConstraints < numConstraints)
- {
- numIter++;
- int nCurrentBatch = 0;
- batchSizes[batchIdx] = 0;
-
- // clear flag
- for (int i = 0; i < curBodyUsed; i++)
- bodyUsed[curUsed[i] / 32] = 0;
-
- curBodyUsed = 0;
-
- for (int i = numValidConstraints; i < numConstraints; i++)
- {
- int idx = i;
- b3Assert(idx < numConstraints);
- // check if it can go
- int bodyAS = cs[idx].m_bodyAPtrAndSignBit;
- int bodyBS = cs[idx].m_bodyBPtrAndSignBit;
- int bodyA = abs(bodyAS);
- int bodyB = abs(bodyBS);
- bool aIsStatic = (bodyAS < 0) || bodyAS == staticIdx;
- bool bIsStatic = (bodyBS < 0) || bodyBS == staticIdx;
- int aUnavailable = 0;
- int bUnavailable = 0;
- if (!aIsStatic)
- {
- aUnavailable = bodyUsed[bodyA / 32] & (1 << (bodyA & 31));
- }
- if (!aUnavailable)
- if (!bIsStatic)
- {
- bUnavailable = bodyUsed[bodyB / 32] & (1 << (bodyB & 31));
- }
-
- if (aUnavailable == 0 && bUnavailable == 0) // ok
- {
- if (!aIsStatic)
- {
- bodyUsed[bodyA / 32] |= (1 << (bodyA & 31));
- curUsed[curBodyUsed++] = bodyA;
- }
- if (!bIsStatic)
- {
- bodyUsed[bodyB / 32] |= (1 << (bodyB & 31));
- curUsed[curBodyUsed++] = bodyB;
- }
-
- cs[idx].getBatchIdx() = batchIdx;
-
- if (i != numValidConstraints)
- {
- b3Swap(cs[i], cs[numValidConstraints]);
- numSwaps++;
- }
-
- numValidConstraints++;
- {
- nCurrentBatch++;
- if (nCurrentBatch == simdWidth)
- {
- batchSizes[batchIdx] += simdWidth;
- nCurrentBatch = 0;
- for (int i = 0; i < curBodyUsed; i++)
- bodyUsed[curUsed[i] / 32] = 0;
- curBodyUsed = 0;
- }
- }
- }
- }
-
- if (batchIdx >= B3_MAX_NUM_BATCHES)
- {
- b3Error("batchIdx>=B3_MAX_NUM_BATCHES");
- b3Assert(0);
- break;
- }
-
- batchSizes[batchIdx] += nCurrentBatch;
-
- batchIdx++;
- }
- }
-
-#if defined(_DEBUG)
- // debugPrintf( "nBatches: %d\n", batchIdx );
- for (int i = 0; i < numConstraints; i++)
- {
- b3Assert(cs[i].getBatchIdx() != -1);
- }
-#endif
-
- batchSizes[batchIdx] = 0;
-
- if (maxSwaps < numSwaps)
- {
- maxSwaps = numSwaps;
- //printf("maxSwaps = %d\n", maxSwaps);
- }
-
- return batchIdx;
-}