add Takahiro's batching pgs solver
This commit is contained in:
927
opencl/gpu_rigidbody/host/Solver.cpp
Normal file
927
opencl/gpu_rigidbody/host/Solver.cpp
Normal file
@@ -0,0 +1,927 @@
|
||||
/*
|
||||
Copyright (c) 2012 Advanced Micro Devices, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
//Originally written by Takahiro Harada
|
||||
|
||||
|
||||
#include "Solver.h"
|
||||
#include "../Stubs/AdlMatrix3x3.h"
|
||||
|
||||
#define SOLVER_SETUP_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solverSetup.cl"
|
||||
#define SOLVER_SETUP2_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solverSetup2.cl"
|
||||
|
||||
#define SOLVER_CONTACT_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solveContact.cl"
|
||||
#define SOLVER_FRICTION_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solveFriction.cl"
|
||||
|
||||
#define BATCHING_PATH "opencl/gpu_rigidbody/kernels/batchingKernels.cl"
|
||||
|
||||
|
||||
#include "../kernels/solverSetup.h"
|
||||
#include "../kernels/solverSetup2.h"
|
||||
|
||||
#include "../kernels/solveContact.h"
|
||||
#include "../kernels/solveFriction.h"
|
||||
|
||||
#include "../kernels/batchingKernels.h"
|
||||
#include "BulletCommon/btQuickprof.h"
|
||||
#include "../../parallel_primitives/host/btLauncherCL.h"
|
||||
|
||||
|
||||
struct SolverDebugInfo
|
||||
{
|
||||
int m_valInt0;
|
||||
int m_valInt1;
|
||||
int m_valInt2;
|
||||
int m_valInt3;
|
||||
|
||||
int m_valInt4;
|
||||
int m_valInt5;
|
||||
int m_valInt6;
|
||||
int m_valInt7;
|
||||
|
||||
int m_valInt8;
|
||||
int m_valInt9;
|
||||
int m_valInt10;
|
||||
int m_valInt11;
|
||||
|
||||
int m_valInt12;
|
||||
int m_valInt13;
|
||||
int m_valInt14;
|
||||
int m_valInt15;
|
||||
|
||||
|
||||
float m_val0;
|
||||
float m_val1;
|
||||
float m_val2;
|
||||
float m_val3;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SolverDeviceInl
|
||||
{
|
||||
public:
|
||||
struct ParallelSolveData
|
||||
{
|
||||
btOpenCLArray<unsigned int>* m_numConstraints;
|
||||
btOpenCLArray<unsigned int>* m_offsets;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
Solver::Solver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity)
|
||||
:m_nIterations(4),
|
||||
m_context(ctx),
|
||||
m_device(device),
|
||||
m_queue(queue)
|
||||
{
|
||||
m_sort32 = new btRadixSort32CL(ctx,device,queue);
|
||||
m_scan = new btPrefixScanCL(ctx,device,queue,N_SPLIT*N_SPLIT);
|
||||
m_search = new btBoundSearchCL(ctx,device,queue,N_SPLIT*N_SPLIT);
|
||||
|
||||
const int sortSize = NEXTMULTIPLEOF( pairCapacity, 512 );
|
||||
|
||||
m_sortDataBuffer = new btOpenCLArray<btSortData>(ctx,queue,sortSize);
|
||||
m_contactBuffer = new btOpenCLArray<btContact4>(ctx,queue);
|
||||
|
||||
m_numConstraints = new btOpenCLArray<unsigned int>(ctx,queue,N_SPLIT*N_SPLIT );
|
||||
m_numConstraints->resize(N_SPLIT*N_SPLIT);
|
||||
|
||||
m_offsets = new btOpenCLArray<unsigned int>( ctx,queue, N_SPLIT*N_SPLIT );
|
||||
m_offsets->resize(N_SPLIT*N_SPLIT);
|
||||
const char* additionalMacros = "";
|
||||
const char* srcFileNameForCaching="";
|
||||
|
||||
|
||||
|
||||
cl_int pErrNum;
|
||||
const char* batchKernelSource = batchingKernelsCL;
|
||||
const char* solverSetupSource = solverSetupCL;
|
||||
const char* solverSetup2Source = solverSetup2CL;
|
||||
const char* solveContactSource = solveContactCL;
|
||||
const char* solveFrictionSource = solveFrictionCL;
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
cl_program solveContactProg= btOpenCLUtils::compileCLProgramFromString( ctx, device, solveContactSource, &pErrNum,additionalMacros, SOLVER_CONTACT_KERNEL_PATH);
|
||||
btAssert(solveContactProg);
|
||||
|
||||
cl_program solveFrictionProg= btOpenCLUtils::compileCLProgramFromString( ctx, device, solveFrictionSource, &pErrNum,additionalMacros, SOLVER_FRICTION_KERNEL_PATH);
|
||||
btAssert(solveFrictionProg);
|
||||
|
||||
cl_program solverSetup2Prog= btOpenCLUtils::compileCLProgramFromString( ctx, device, solverSetup2Source, &pErrNum,additionalMacros, SOLVER_SETUP2_KERNEL_PATH);
|
||||
btAssert(solverSetup2Prog);
|
||||
|
||||
|
||||
cl_program solverSetupProg= btOpenCLUtils::compileCLProgramFromString( ctx, device, solverSetupSource, &pErrNum,additionalMacros, SOLVER_SETUP_KERNEL_PATH);
|
||||
btAssert(solverSetupProg);
|
||||
|
||||
|
||||
m_solveFrictionKernel= btOpenCLUtils::compileCLKernelFromString( ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg,additionalMacros );
|
||||
btAssert(m_solveFrictionKernel);
|
||||
|
||||
m_solveContactKernel= btOpenCLUtils::compileCLKernelFromString( ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg,additionalMacros );
|
||||
btAssert(m_solveContactKernel);
|
||||
|
||||
m_contactToConstraintKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg,additionalMacros );
|
||||
btAssert(m_contactToConstraintKernel);
|
||||
|
||||
m_setSortDataKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog,additionalMacros );
|
||||
btAssert(m_setSortDataKernel);
|
||||
|
||||
m_reorderContactKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog,additionalMacros );
|
||||
btAssert(m_reorderContactKernel);
|
||||
|
||||
|
||||
m_copyConstraintKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog,additionalMacros );
|
||||
btAssert(m_copyConstraintKernel);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
cl_program batchingProg = btOpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelSource, &pErrNum,additionalMacros, BATCHING_PATH);
|
||||
btAssert(batchingProg);
|
||||
|
||||
m_batchingKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg,additionalMacros );
|
||||
btAssert(m_batchingKernel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Solver::~Solver()
|
||||
{
|
||||
delete m_sortDataBuffer;
|
||||
delete m_contactBuffer;
|
||||
|
||||
delete m_sort32;
|
||||
delete m_scan;
|
||||
delete m_search;
|
||||
|
||||
|
||||
clReleaseKernel(m_batchingKernel);
|
||||
|
||||
clReleaseKernel( m_solveContactKernel);
|
||||
clReleaseKernel( m_solveFrictionKernel);
|
||||
|
||||
clReleaseKernel( m_contactToConstraintKernel);
|
||||
clReleaseKernel( m_setSortDataKernel);
|
||||
clReleaseKernel( m_reorderContactKernel);
|
||||
clReleaseKernel( m_copyConstraintKernel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*void Solver::reorderConvertToConstraints( const btOpenCLArray<btRigidBodyCL>* bodyBuf,
|
||||
const btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btContact4>* contactsIn, btOpenCLArray<btGpuConstraint4>* contactCOut, void* additionalData,
|
||||
int nContacts, const Solver::ConstraintCfg& cfg )
|
||||
{
|
||||
if( m_contactBuffer )
|
||||
{
|
||||
m_contactBuffer->resize(nContacts);
|
||||
}
|
||||
if( m_contactBuffer == 0 )
|
||||
{
|
||||
BT_PROFILE("new m_contactBuffer;");
|
||||
m_contactBuffer = new btOpenCLArray<btContact4>(m_context,m_queue,nContacts );
|
||||
m_contactBuffer->resize(nContacts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//DeviceUtils::Config dhCfg;
|
||||
//Device* deviceHost = DeviceUtils::allocate( TYPE_HOST, dhCfg );
|
||||
if( cfg.m_enableParallelSolve )
|
||||
{
|
||||
|
||||
|
||||
clFinish(m_queue);
|
||||
|
||||
// contactsIn -> m_contactBuffer
|
||||
{
|
||||
BT_PROFILE("sortContacts");
|
||||
sortContacts( bodyBuf, contactsIn, additionalData, nContacts, cfg );
|
||||
clFinish(m_queue);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
BT_PROFILE("m_copyConstraintKernel");
|
||||
|
||||
|
||||
|
||||
btInt4 cdata; cdata.x = nContacts;
|
||||
btBufferInfoCL bInfo[] = { btBufferInfoCL( m_contactBuffer->getBufferCL() ), btBufferInfoCL( contactsIn->getBufferCL() ) };
|
||||
// btLauncherCL launcher( m_queue, data->m_device->getKernel( PATH, "CopyConstraintKernel", "-I ..\\..\\ -Wf,--c++", 0 ) );
|
||||
btLauncherCL launcher( m_queue, m_copyConstraintKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
launcher.setConst( cdata );
|
||||
launcher.launch1D( nContacts, 64 );
|
||||
clFinish(m_queue);
|
||||
}
|
||||
|
||||
{
|
||||
BT_PROFILE("batchContacts");
|
||||
Solver::batchContacts( contactsIn, nContacts, m_numConstraints, m_offsets, cfg.m_staticIdx );
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
BT_PROFILE("waitForCompletion (batchContacts)");
|
||||
clFinish(m_queue);
|
||||
}
|
||||
|
||||
//================
|
||||
|
||||
{
|
||||
BT_PROFILE("convertToConstraints");
|
||||
Solver::convertToConstraints( bodyBuf, shapeBuf, contactsIn, contactCOut, additionalData, nContacts, cfg );
|
||||
}
|
||||
|
||||
{
|
||||
BT_PROFILE("convertToConstraints waitForCompletion");
|
||||
clFinish(m_queue);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
static
|
||||
inline
|
||||
float calcRelVel(const float4& l0, const float4& l1, const float4& a0, const float4& a1,
|
||||
const float4& linVel0, const float4& angVel0, const float4& linVel1, const float4& angVel1)
|
||||
{
|
||||
return dot3F4(l0, linVel0) + dot3F4(a0, angVel0) + dot3F4(l1, linVel1) + dot3F4(a1, angVel1);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
inline
|
||||
void setLinearAndAngular(const float4& n, const float4& r0, const float4& r1,
|
||||
float4& linear, float4& angular0, float4& angular1)
|
||||
{
|
||||
linear = -n;
|
||||
angular0 = -cross3(r0, n);
|
||||
angular1 = cross3(r1, n);
|
||||
}
|
||||
|
||||
|
||||
template<bool JACOBI>
|
||||
static
|
||||
__inline
|
||||
void solveContact(btGpuConstraint4& cs,
|
||||
const float4& posA, float4& linVelA, float4& angVelA, float invMassA, const Matrix3x3& invInertiaA,
|
||||
const float4& posB, float4& linVelB, float4& angVelB, float invMassB, const Matrix3x3& invInertiaB,
|
||||
float maxRambdaDt[4], float minRambdaDt[4])
|
||||
{
|
||||
float4 dLinVelA = make_float4(0.f);
|
||||
float4 dAngVelA = make_float4(0.f);
|
||||
float4 dLinVelB = make_float4(0.f);
|
||||
float4 dAngVelB = make_float4(0.f);
|
||||
|
||||
for(int ic=0; ic<4; ic++)
|
||||
{
|
||||
// dont necessary because this makes change to 0
|
||||
if( cs.m_jacCoeffInv[ic] == 0.f ) continue;
|
||||
|
||||
{
|
||||
float4 angular0, angular1, linear;
|
||||
btVector3 r0 = cs.m_worldPos[ic] - (btVector3&)posA;
|
||||
btVector3 r1 = cs.m_worldPos[ic] - (btVector3&)posB;
|
||||
setLinearAndAngular( (const float4 &)-cs.m_linear, (const float4 &)r0, (const float4 &)r1, linear, angular0, angular1 );
|
||||
|
||||
float rambdaDt = calcRelVel((const float4 &)cs.m_linear,(const float4 &) -cs.m_linear, angular0, angular1,
|
||||
linVelA, angVelA, linVelB, angVelB ) + cs.m_b[ic];
|
||||
rambdaDt *= cs.m_jacCoeffInv[ic];
|
||||
|
||||
{
|
||||
float prevSum = cs.m_appliedRambdaDt[ic];
|
||||
float updated = prevSum;
|
||||
updated += rambdaDt;
|
||||
updated = max2( updated, minRambdaDt[ic] );
|
||||
updated = min2( updated, maxRambdaDt[ic] );
|
||||
rambdaDt = updated - prevSum;
|
||||
cs.m_appliedRambdaDt[ic] = updated;
|
||||
}
|
||||
|
||||
float4 linImp0 = invMassA*linear*rambdaDt;
|
||||
float4 linImp1 = invMassB*(-linear)*rambdaDt;
|
||||
float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;
|
||||
float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;
|
||||
#ifdef _WIN32
|
||||
btAssert(_finite(linImp0.x));
|
||||
btAssert(_finite(linImp1.x));
|
||||
#endif
|
||||
if( JACOBI )
|
||||
{
|
||||
dLinVelA += linImp0;
|
||||
dAngVelA += angImp0;
|
||||
dLinVelB += linImp1;
|
||||
dAngVelB += angImp1;
|
||||
}
|
||||
else
|
||||
{
|
||||
linVelA += linImp0;
|
||||
angVelA += angImp0;
|
||||
linVelB += linImp1;
|
||||
angVelB += angImp1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( JACOBI )
|
||||
{
|
||||
linVelA += dLinVelA;
|
||||
angVelA += dAngVelA;
|
||||
linVelB += dLinVelB;
|
||||
angVelB += dAngVelB;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btPlaneSpace1 (const float4* n, float4* p, float4* q)
|
||||
{
|
||||
if (btFabs(n->z) > SIMDSQRT12) {
|
||||
// choose p in y-z plane
|
||||
btScalar a = n->y*n->y + n->z*n->z;
|
||||
btScalar k = btRecipSqrt (a);
|
||||
p->x = 0;
|
||||
p->y = -n->z*k;
|
||||
p->z = n->y*k;
|
||||
// set q = n x p
|
||||
q->x = a*k;
|
||||
q->y = -n->x*p->z;
|
||||
q->z = n->x*p->y;
|
||||
}
|
||||
else {
|
||||
// choose p in x-y plane
|
||||
btScalar a = n->x*n->x + n->y*n->y;
|
||||
btScalar k = btRecipSqrt (a);
|
||||
p->x = -n->y*k;
|
||||
p->y = n->x*k;
|
||||
p->z = 0;
|
||||
// set q = n x p
|
||||
q->x = -n->z*p->y;
|
||||
q->y = n->z*p->x;
|
||||
q->z = a*k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
__inline
|
||||
void solveFriction(btGpuConstraint4& cs,
|
||||
const float4& posA, float4& linVelA, float4& angVelA, float invMassA, const Matrix3x3& invInertiaA,
|
||||
const float4& posB, float4& linVelB, float4& angVelB, float invMassB, const Matrix3x3& invInertiaB,
|
||||
float maxRambdaDt[4], float minRambdaDt[4])
|
||||
{
|
||||
if( cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0 ) return;
|
||||
const float4& center = (const float4&)cs.m_center;
|
||||
|
||||
float4 n = -(const float4&)cs.m_linear;
|
||||
|
||||
float4 tangent[2];
|
||||
#if 1
|
||||
btPlaneSpace1 (&n, &tangent[0],&tangent[1]);
|
||||
#else
|
||||
float4 r = cs.m_worldPos[0]-center;
|
||||
tangent[0] = cross3( n, r );
|
||||
tangent[1] = cross3( tangent[0], n );
|
||||
tangent[0] = normalize3( tangent[0] );
|
||||
tangent[1] = normalize3( tangent[1] );
|
||||
#endif
|
||||
|
||||
float4 angular0, angular1, linear;
|
||||
float4 r0 = center - posA;
|
||||
float4 r1 = center - posB;
|
||||
for(int i=0; i<2; i++)
|
||||
{
|
||||
setLinearAndAngular( tangent[i], r0, r1, linear, angular0, angular1 );
|
||||
float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,
|
||||
linVelA, angVelA, linVelB, angVelB );
|
||||
rambdaDt *= cs.m_fJacCoeffInv[i];
|
||||
|
||||
{
|
||||
float prevSum = cs.m_fAppliedRambdaDt[i];
|
||||
float updated = prevSum;
|
||||
updated += rambdaDt;
|
||||
updated = max2( updated, minRambdaDt[i] );
|
||||
updated = min2( updated, maxRambdaDt[i] );
|
||||
rambdaDt = updated - prevSum;
|
||||
cs.m_fAppliedRambdaDt[i] = updated;
|
||||
}
|
||||
|
||||
float4 linImp0 = invMassA*linear*rambdaDt;
|
||||
float4 linImp1 = invMassB*(-linear)*rambdaDt;
|
||||
float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;
|
||||
float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;
|
||||
#ifdef _WIN32
|
||||
btAssert(_finite(linImp0.x));
|
||||
btAssert(_finite(linImp1.x));
|
||||
#endif
|
||||
linVelA += linImp0;
|
||||
angVelA += angImp0;
|
||||
linVelB += linImp1;
|
||||
angVelB += angImp1;
|
||||
}
|
||||
|
||||
{ // angular damping for point constraint
|
||||
float4 ab = normalize3( posB - posA );
|
||||
float4 ac = normalize3( center - posA );
|
||||
if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))
|
||||
{
|
||||
float angNA = dot3F4( n, angVelA );
|
||||
float angNB = dot3F4( n, angVelB );
|
||||
|
||||
angVelA -= (angNA*0.1f)*n;
|
||||
angVelB -= (angNB*0.1f)*n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct SolveTask// : public ThreadPool::Task
|
||||
{
|
||||
SolveTask(btAlignedObjectArray<btRigidBodyCL>& bodies, btAlignedObjectArray<btInertiaCL>& shapes, btAlignedObjectArray<btGpuConstraint4>& constraints,
|
||||
int start, int nConstraints)
|
||||
: m_bodies( bodies ), m_shapes( shapes ), m_constraints( constraints ), m_start( start ), m_nConstraints( nConstraints ),
|
||||
m_solveFriction( true ){}
|
||||
|
||||
u16 getType(){ return 0; }
|
||||
|
||||
void run(int tIdx)
|
||||
{
|
||||
|
||||
|
||||
for(int ic=0; ic<m_nConstraints; ic++)
|
||||
{
|
||||
int i = m_start + ic;
|
||||
|
||||
float frictionCoeff = m_constraints[i].getFrictionCoeff();
|
||||
int aIdx = (int)m_constraints[i].m_bodyA;
|
||||
int bIdx = (int)m_constraints[i].m_bodyB;
|
||||
btRigidBodyCL& bodyA = m_bodies[aIdx];
|
||||
btRigidBodyCL& bodyB = m_bodies[bIdx];
|
||||
|
||||
if( !m_solveFriction )
|
||||
{
|
||||
float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};
|
||||
float minRambdaDt[4] = {0.f,0.f,0.f,0.f};
|
||||
|
||||
solveContact<false>( m_constraints[i], (float4&)bodyA.m_pos, (float4&)bodyA.m_linVel, (float4&)bodyA.m_angVel, bodyA.m_invMass, (const Matrix3x3 &)m_shapes[aIdx].m_invInertiaWorld,
|
||||
(float4&)bodyB.m_pos, (float4&)bodyB.m_linVel, (float4&)bodyB.m_angVel, bodyB.m_invMass, (const Matrix3x3 &)m_shapes[bIdx].m_invInertiaWorld,
|
||||
maxRambdaDt, minRambdaDt );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};
|
||||
float minRambdaDt[4] = {0.f,0.f,0.f,0.f};
|
||||
|
||||
float sum = 0;
|
||||
for(int j=0; j<4; j++)
|
||||
{
|
||||
sum +=m_constraints[i].m_appliedRambdaDt[j];
|
||||
}
|
||||
frictionCoeff = 0.7f;
|
||||
for(int j=0; j<4; j++)
|
||||
{
|
||||
maxRambdaDt[j] = frictionCoeff*sum;
|
||||
minRambdaDt[j] = -maxRambdaDt[j];
|
||||
}
|
||||
|
||||
solveFriction( m_constraints[i], (float4&)bodyA.m_pos, (float4&)bodyA.m_linVel, (float4&)bodyA.m_angVel, bodyA.m_invMass,(const Matrix3x3 &) m_shapes[aIdx].m_invInertiaWorld,
|
||||
(float4&)bodyB.m_pos, (float4&)bodyB.m_linVel, (float4&)bodyB.m_angVel, bodyB.m_invMass,(const Matrix3x3 &) m_shapes[bIdx].m_invInertiaWorld,
|
||||
maxRambdaDt, minRambdaDt );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
btAlignedObjectArray<btRigidBodyCL>& m_bodies;
|
||||
btAlignedObjectArray<btInertiaCL>& m_shapes;
|
||||
btAlignedObjectArray<btGpuConstraint4>& m_constraints;
|
||||
int m_start;
|
||||
int m_nConstraints;
|
||||
bool m_solveFriction;
|
||||
};
|
||||
|
||||
|
||||
void Solver::solveContactConstraintHost( btOpenCLArray<btRigidBodyCL>* bodyBuf, btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches)
|
||||
{
|
||||
|
||||
btAlignedObjectArray<btRigidBodyCL> bodyNative;
|
||||
bodyBuf->copyToHost(bodyNative);
|
||||
btAlignedObjectArray<btInertiaCL> shapeNative;
|
||||
shapeBuf->copyToHost(shapeNative);
|
||||
btAlignedObjectArray<btGpuConstraint4> constraintNative;
|
||||
constraint->copyToHost(constraintNative);
|
||||
|
||||
for(int iter=0; iter<m_nIterations; iter++)
|
||||
{
|
||||
SolveTask task( bodyNative, shapeNative, constraintNative, 0, n );
|
||||
task.m_solveFriction = false;
|
||||
task.run(0);
|
||||
}
|
||||
|
||||
for(int iter=0; iter<m_nIterations; iter++)
|
||||
{
|
||||
SolveTask task( bodyNative, shapeNative, constraintNative, 0, n );
|
||||
task.m_solveFriction = true;
|
||||
task.run(0);
|
||||
}
|
||||
|
||||
bodyBuf->copyFromHost(bodyNative);
|
||||
shapeBuf->copyFromHost(shapeNative);
|
||||
constraint->copyFromHost(constraintNative);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Solver::solveContactConstraint( const btOpenCLArray<btRigidBodyCL>* bodyBuf, const btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches)
|
||||
{
|
||||
|
||||
|
||||
btInt4 cdata = btMakeInt4( n, 0, 0, 0 );
|
||||
{
|
||||
|
||||
const int nn = N_SPLIT*N_SPLIT;
|
||||
|
||||
cdata.x = 0;
|
||||
cdata.y = maxNumBatches;//250;
|
||||
|
||||
|
||||
int numWorkItems = 64*nn/N_BATCHES;
|
||||
#ifdef DEBUG_ME
|
||||
SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems];
|
||||
adl::btOpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device,numWorkItems);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
BT_PROFILE("m_batchSolveKernel iterations");
|
||||
for(int iter=0; iter<m_nIterations; iter++)
|
||||
{
|
||||
for(int ib=0; ib<N_BATCHES; ib++)
|
||||
{
|
||||
#ifdef DEBUG_ME
|
||||
memset(debugInfo,0,sizeof(SolverDebugInfo)*numWorkItems);
|
||||
gpuDebugInfo.write(debugInfo,numWorkItems);
|
||||
#endif
|
||||
|
||||
|
||||
cdata.z = ib;
|
||||
cdata.w = N_SPLIT;
|
||||
|
||||
btLauncherCL launcher( m_queue, m_solveContactKernel );
|
||||
#if 1
|
||||
|
||||
btBufferInfoCL bInfo[] = {
|
||||
|
||||
btBufferInfoCL( bodyBuf->getBufferCL() ),
|
||||
btBufferInfoCL( shapeBuf->getBufferCL() ),
|
||||
btBufferInfoCL( constraint->getBufferCL() ),
|
||||
btBufferInfoCL( m_numConstraints->getBufferCL() ),
|
||||
btBufferInfoCL( m_offsets->getBufferCL() )
|
||||
#ifdef DEBUG_ME
|
||||
, btBufferInfoCL(&gpuDebugInfo)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
//launcher.setConst( cdata.x );
|
||||
launcher.setConst( cdata.y );
|
||||
launcher.setConst( cdata.z );
|
||||
launcher.setConst( cdata.w );
|
||||
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_queue);
|
||||
|
||||
|
||||
}
|
||||
|
||||
cdata.x = 1;
|
||||
bool applyFriction=true;
|
||||
if (applyFriction)
|
||||
{
|
||||
BT_PROFILE("m_batchSolveKernel iterations2");
|
||||
for(int iter=0; iter<m_nIterations; iter++)
|
||||
{
|
||||
for(int ib=0; ib<N_BATCHES; ib++)
|
||||
{
|
||||
cdata.z = ib;
|
||||
cdata.w = N_SPLIT;
|
||||
|
||||
btBufferInfoCL bInfo[] = {
|
||||
btBufferInfoCL( bodyBuf->getBufferCL() ),
|
||||
btBufferInfoCL( shapeBuf->getBufferCL() ),
|
||||
btBufferInfoCL( constraint->getBufferCL() ),
|
||||
btBufferInfoCL( m_numConstraints->getBufferCL() ),
|
||||
btBufferInfoCL( m_offsets->getBufferCL() )
|
||||
#ifdef DEBUG_ME
|
||||
,btBufferInfoCL(&gpuDebugInfo)
|
||||
#endif //DEBUG_ME
|
||||
};
|
||||
btLauncherCL launcher( m_queue, m_solveFrictionKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
//launcher.setConst( cdata.x );
|
||||
launcher.setConst( cdata.y );
|
||||
launcher.setConst( cdata.z );
|
||||
launcher.setConst( cdata.w );
|
||||
|
||||
launcher.launch1D( 64*nn/N_BATCHES, 64 );
|
||||
}
|
||||
}
|
||||
clFinish(m_queue);
|
||||
|
||||
}
|
||||
#ifdef DEBUG_ME
|
||||
delete[] debugInfo;
|
||||
#endif //DEBUG_ME
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Solver::convertToConstraints( const btOpenCLArray<btRigidBodyCL>* bodyBuf,
|
||||
const btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btContact4>* contactsIn, btOpenCLArray<btGpuConstraint4>* contactCOut, void* additionalData,
|
||||
int nContacts, const ConstraintCfg& cfg )
|
||||
{
|
||||
btOpenCLArray<btGpuConstraint4>* constraintNative =0;
|
||||
|
||||
struct CB
|
||||
{
|
||||
int m_nContacts;
|
||||
float m_dt;
|
||||
float m_positionDrift;
|
||||
float m_positionConstraintCoeff;
|
||||
};
|
||||
|
||||
{
|
||||
BT_PROFILE("m_contactToConstraintKernel");
|
||||
CB cdata;
|
||||
cdata.m_nContacts = nContacts;
|
||||
cdata.m_dt = cfg.m_dt;
|
||||
cdata.m_positionDrift = cfg.m_positionDrift;
|
||||
cdata.m_positionConstraintCoeff = cfg.m_positionConstraintCoeff;
|
||||
|
||||
|
||||
btBufferInfoCL bInfo[] = { btBufferInfoCL( contactsIn->getBufferCL() ), btBufferInfoCL( bodyBuf->getBufferCL() ), btBufferInfoCL( shapeBuf->getBufferCL()),
|
||||
btBufferInfoCL( contactCOut->getBufferCL() )};
|
||||
btLauncherCL launcher( m_queue, m_contactToConstraintKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
//launcher.setConst( cdata );
|
||||
|
||||
launcher.setConst(cdata.m_nContacts);
|
||||
launcher.setConst(cdata.m_dt);
|
||||
launcher.setConst(cdata.m_positionDrift);
|
||||
launcher.setConst(cdata.m_positionConstraintCoeff);
|
||||
|
||||
launcher.launch1D( nContacts, 64 );
|
||||
clFinish(m_queue);
|
||||
|
||||
}
|
||||
|
||||
contactCOut->resize(nContacts);
|
||||
}
|
||||
|
||||
/*
|
||||
void Solver::sortContacts( const btOpenCLArray<btRigidBodyCL>* bodyBuf,
|
||||
btOpenCLArray<btContact4>* contactsIn, void* additionalData,
|
||||
int nContacts, const Solver::ConstraintCfg& cfg )
|
||||
{
|
||||
|
||||
|
||||
|
||||
const int sortAlignment = 512; // todo. get this out of sort
|
||||
if( cfg.m_enableParallelSolve )
|
||||
{
|
||||
|
||||
|
||||
int sortSize = NEXTMULTIPLEOF( nContacts, sortAlignment );
|
||||
|
||||
btOpenCLArray<unsigned int>* countsNative = m_numConstraints;//BufferUtils::map<TYPE_CL, false>( data->m_device, &countsHost );
|
||||
btOpenCLArray<unsigned int>* offsetsNative = m_offsets;//BufferUtils::map<TYPE_CL, false>( data->m_device, &offsetsHost );
|
||||
|
||||
{ // 2. set cell idx
|
||||
struct CB
|
||||
{
|
||||
int m_nContacts;
|
||||
int m_staticIdx;
|
||||
float m_scale;
|
||||
int m_nSplit;
|
||||
};
|
||||
|
||||
btAssert( sortSize%64 == 0 );
|
||||
CB cdata;
|
||||
cdata.m_nContacts = nContacts;
|
||||
cdata.m_staticIdx = cfg.m_staticIdx;
|
||||
cdata.m_scale = 1.f/(N_OBJ_PER_SPLIT*cfg.m_averageExtent);
|
||||
cdata.m_nSplit = N_SPLIT;
|
||||
|
||||
|
||||
btBufferInfoCL bInfo[] = { btBufferInfoCL( contactsIn->getBufferCL() ), btBufferInfoCL( bodyBuf->getBufferCL() ), btBufferInfoCL( m_sortDataBuffer->getBufferCL() ) };
|
||||
btLauncherCL launcher( m_queue, m_setSortDataKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
launcher.setConst( cdata );
|
||||
launcher.launch1D( sortSize, 64 );
|
||||
}
|
||||
|
||||
{ // 3. sort by cell idx
|
||||
int n = N_SPLIT*N_SPLIT;
|
||||
int sortBit = 32;
|
||||
//if( n <= 0xffff ) sortBit = 16;
|
||||
//if( n <= 0xff ) sortBit = 8;
|
||||
m_sort32->execute(*m_sortDataBuffer,sortSize);
|
||||
}
|
||||
{ // 4. find entries
|
||||
m_search->execute( *m_sortDataBuffer, nContacts, *countsNative, N_SPLIT*N_SPLIT, btBoundSearchCL::COUNT);
|
||||
|
||||
m_scan->execute( *countsNative, *offsetsNative, N_SPLIT*N_SPLIT );
|
||||
}
|
||||
|
||||
{ // 5. sort constraints by cellIdx
|
||||
// todo. preallocate this
|
||||
// btAssert( contactsIn->getType() == TYPE_HOST );
|
||||
// btOpenCLArray<btContact4>* out = BufferUtils::map<TYPE_CL, false>( data->m_device, contactsIn ); // copying contacts to this buffer
|
||||
|
||||
{
|
||||
|
||||
|
||||
btInt4 cdata; cdata.x = nContacts;
|
||||
btBufferInfoCL bInfo[] = { btBufferInfoCL( contactsIn->getBufferCL() ), btBufferInfoCL( m_contactBuffer->getBufferCL() ), btBufferInfoCL( m_sortDataBuffer->getBufferCL() ) };
|
||||
btLauncherCL launcher( m_queue, m_reorderContactKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
launcher.setConst( cdata );
|
||||
launcher.launch1D( nContacts, 64 );
|
||||
}
|
||||
// BufferUtils::unmap<true>( out, contactsIn, nContacts );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void Solver::batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* nNative, btOpenCLArray<unsigned int>* offsetsNative, int staticIdx )
|
||||
{
|
||||
|
||||
{
|
||||
BT_PROFILE("batch generation");
|
||||
|
||||
btInt4 cdata;
|
||||
cdata.x = nContacts;
|
||||
cdata.y = 0;
|
||||
cdata.z = staticIdx;
|
||||
|
||||
int numWorkItems = 64*N_SPLIT*N_SPLIT;
|
||||
#ifdef BATCH_DEBUG
|
||||
SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems];
|
||||
adl::btOpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device,numWorkItems);
|
||||
memset(debugInfo,0,sizeof(SolverDebugInfo)*numWorkItems);
|
||||
gpuDebugInfo.write(debugInfo,numWorkItems);
|
||||
#endif
|
||||
|
||||
|
||||
btBufferInfoCL bInfo[] = {
|
||||
btBufferInfoCL( contacts->getBufferCL() ),
|
||||
btBufferInfoCL( m_contactBuffer->getBufferCL() ),
|
||||
btBufferInfoCL( nNative->getBufferCL() ),
|
||||
btBufferInfoCL( offsetsNative->getBufferCL() )
|
||||
#ifdef BATCH_DEBUG
|
||||
, btBufferInfoCL(&gpuDebugInfo)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
{
|
||||
BT_PROFILE("batchingKernel");
|
||||
btLauncherCL launcher( m_queue, m_batchingKernel);
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
//launcher.setConst( cdata );
|
||||
launcher.setConst(staticIdx);
|
||||
|
||||
launcher.launch1D( numWorkItems, 64 );
|
||||
clFinish(m_queue);
|
||||
}
|
||||
|
||||
#ifdef BATCH_DEBUG
|
||||
aaaa
|
||||
btContact4* hostContacts = new btContact4[nContacts];
|
||||
m_contactBuffer->read(hostContacts,nContacts);
|
||||
clFinish(m_queue);
|
||||
|
||||
gpuDebugInfo.read(debugInfo,numWorkItems);
|
||||
clFinish(m_queue);
|
||||
|
||||
for (int i=0;i<numWorkItems;i++)
|
||||
{
|
||||
if (debugInfo[i].m_valInt1>0)
|
||||
{
|
||||
printf("catch\n");
|
||||
}
|
||||
if (debugInfo[i].m_valInt2>0)
|
||||
{
|
||||
printf("catch22\n");
|
||||
}
|
||||
|
||||
if (debugInfo[i].m_valInt3>0)
|
||||
{
|
||||
printf("catch666\n");
|
||||
}
|
||||
|
||||
if (debugInfo[i].m_valInt4>0)
|
||||
{
|
||||
printf("catch777\n");
|
||||
}
|
||||
}
|
||||
delete[] debugInfo;
|
||||
#endif //BATCH_DEBUG
|
||||
|
||||
}
|
||||
|
||||
// copy buffer to buffer
|
||||
btAssert(m_contactBuffer->size()==nContacts);
|
||||
//contacts->copyFromOpenCLArray( *m_contactBuffer);
|
||||
//clFinish(m_queue);//needed?
|
||||
|
||||
|
||||
}
|
||||
|
||||
168
opencl/gpu_rigidbody/host/Solver.h
Normal file
168
opencl/gpu_rigidbody/host/Solver.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
Copyright (c) 2012 Advanced Micro Devices, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
//Originally written by Takahiro Harada
|
||||
|
||||
|
||||
#ifndef __ADL_SOLVER_H
|
||||
#define __ADL_SOLVER_H
|
||||
|
||||
#include "../../parallel_primitives/host/btOpenCLArray.h"
|
||||
#include "../host/btGpuConstraint4.h"
|
||||
|
||||
|
||||
//#include <AdlPhysics/TypeDefinition.h>
|
||||
//#include "AdlRigidBody.h"
|
||||
#include "../../gpu_sat/host/btRigidBodyCL.h"
|
||||
#include "../../gpu_sat/host/btContact4.h"
|
||||
#include "../Stubs/AdlMath.h"
|
||||
#include "../Stubs/AdlMatrix3x3.h"
|
||||
|
||||
|
||||
//#include "AdlPhysics/Batching/Batching.h>
|
||||
|
||||
|
||||
#define MYF4 float4
|
||||
#define MAKE_MYF4 make_float4
|
||||
|
||||
//#define MYF4 float4sse
|
||||
//#define MAKE_MYF4 make_float4sse
|
||||
|
||||
#include "../host/btGpuConstraint4.h"
|
||||
#include "../../parallel_primitives/host/btPrefixScanCL.h"
|
||||
#include "../../parallel_primitives/host/btRadixSort32CL.h"
|
||||
#include "../../parallel_primitives/host/btBoundSearchCL.h"
|
||||
|
||||
#include "../../basic_initialize/btOpenCLUtils.h"
|
||||
|
||||
|
||||
|
||||
class SolverBase
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
struct ConstraintData
|
||||
{
|
||||
ConstraintData(): m_b(0.f), m_appliedRambdaDt(0.f) {}
|
||||
|
||||
float4 m_linear; // have to be normalized
|
||||
float4 m_angular0;
|
||||
float4 m_angular1;
|
||||
float m_jacCoeffInv;
|
||||
float m_b;
|
||||
float m_appliedRambdaDt;
|
||||
|
||||
unsigned int m_bodyAPtr;
|
||||
unsigned int m_bodyBPtr;
|
||||
|
||||
bool isInvalid() const { return ((unsigned int)m_bodyAPtr+(unsigned int)m_bodyBPtr) == 0; }
|
||||
float getFrictionCoeff() const { return m_linear.w; }
|
||||
void setFrictionCoeff(float coeff) { m_linear.w = coeff; }
|
||||
};
|
||||
|
||||
struct ConstraintCfg
|
||||
{
|
||||
ConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(-1) {}
|
||||
|
||||
float m_positionDrift;
|
||||
float m_positionConstraintCoeff;
|
||||
float m_dt;
|
||||
bool m_enableParallelSolve;
|
||||
float m_averageExtent;
|
||||
int m_staticIdx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
N_SPLIT = 16,
|
||||
N_BATCHES = 4,
|
||||
N_OBJ_PER_SPLIT = 10,
|
||||
N_TASKS_PER_BATCH = N_SPLIT*N_SPLIT,
|
||||
};
|
||||
};
|
||||
|
||||
class Solver : public SolverBase
|
||||
{
|
||||
public:
|
||||
|
||||
cl_context m_context;
|
||||
cl_device_id m_device;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
|
||||
btOpenCLArray<unsigned int>* m_numConstraints;
|
||||
btOpenCLArray<unsigned int>* m_offsets;
|
||||
|
||||
|
||||
int m_nIterations;
|
||||
cl_kernel m_batchingKernel;
|
||||
cl_kernel m_solveContactKernel;
|
||||
cl_kernel m_solveFrictionKernel;
|
||||
cl_kernel m_contactToConstraintKernel;
|
||||
cl_kernel m_setSortDataKernel;
|
||||
cl_kernel m_reorderContactKernel;
|
||||
cl_kernel m_copyConstraintKernel;
|
||||
|
||||
class btRadixSort32CL* m_sort32;
|
||||
class btBoundSearchCL* m_search;
|
||||
class btPrefixScanCL* m_scan;
|
||||
|
||||
btOpenCLArray<btSortData>* m_sortDataBuffer;
|
||||
btOpenCLArray<btContact4>* m_contactBuffer;
|
||||
|
||||
enum
|
||||
{
|
||||
DYNAMIC_CONTACT_ALLOCATION_THRESHOLD = 2000000,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
Solver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity);
|
||||
|
||||
virtual ~Solver();
|
||||
|
||||
/* void reorderConvertToConstraints( const btOpenCLArray<btRigidBodyCL>* bodyBuf,
|
||||
const btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btContact4>* contactsIn, btOpenCLArray<btGpuConstraint4>* contactCOut, void* additionalData,
|
||||
int nContacts, const ConstraintCfg& cfg );
|
||||
*/
|
||||
|
||||
void solveContactConstraint( const btOpenCLArray<btRigidBodyCL>* bodyBuf, const btOpenCLArray<btInertiaCL>* inertiaBuf,
|
||||
btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches);
|
||||
|
||||
void solveContactConstraintHost( btOpenCLArray<btRigidBodyCL>* bodyBuf, btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches);
|
||||
|
||||
|
||||
void convertToConstraints( const btOpenCLArray<btRigidBodyCL>* bodyBuf,
|
||||
const btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btContact4>* contactsIn, btOpenCLArray<btGpuConstraint4>* contactCOut, void* additionalData,
|
||||
int nContacts, const ConstraintCfg& cfg );
|
||||
|
||||
/* void sortContacts( const btOpenCLArray<btRigidBodyCL>* bodyBuf,
|
||||
btOpenCLArray<btContact4>* contactsIn, void* additionalData,
|
||||
int nContacts, const ConstraintCfg& cfg );
|
||||
*/
|
||||
void batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* n, btOpenCLArray<unsigned int>* offsets, int staticIdx );
|
||||
|
||||
};
|
||||
|
||||
|
||||
#undef MYF4
|
||||
#undef MAKE_MYF4
|
||||
|
||||
#endif //__ADL_SOLVER_H
|
||||
824
opencl/gpu_rigidbody/host/btGpuBatchingPgsSolver.cpp
Normal file
824
opencl/gpu_rigidbody/host/btGpuBatchingPgsSolver.cpp
Normal file
@@ -0,0 +1,824 @@
|
||||
|
||||
|
||||
#include "btGpuBatchingPgsSolver.h"
|
||||
#include "../../parallel_primitives/host/btRadixSort32CL.h"
|
||||
#include "BulletCommon/btQuickprof.h"
|
||||
#include "../../parallel_primitives/host/btLauncherCL.h"
|
||||
#include "../../parallel_primitives/host/btBoundSearchCL.h"
|
||||
#include "../../parallel_primitives/host/btPrefixScanCL.h"
|
||||
#include <string.h>
|
||||
#include "../../basic_initialize/btOpenCLUtils.h"
|
||||
#include "../host/btConfig.h"
|
||||
#include "../Stubs/Solver.h"
|
||||
|
||||
|
||||
#define SOLVER_SETUP_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solverSetup.cl"
|
||||
#define SOLVER_SETUP2_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solverSetup2.cl"
|
||||
#define SOLVER_CONTACT_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solveContact.cl"
|
||||
#define SOLVER_FRICTION_KERNEL_PATH "opencl/gpu_rigidbody/kernels/solveFriction.cl"
|
||||
#define BATCHING_PATH "opencl/gpu_rigidbody/kernels/batchingKernels.cl"
|
||||
|
||||
#include "../kernels/solverSetup.h"
|
||||
#include "../kernels/solverSetup2.h"
|
||||
#include "../kernels/solveContact.h"
|
||||
#include "../kernels/solveFriction.h"
|
||||
#include "../kernels/batchingKernels.h"
|
||||
|
||||
|
||||
#define BTNEXTMULTIPLEOF(num, alignment) (((num)/(alignment) + (((num)%(alignment)==0)?0:1))*(alignment))
|
||||
enum
|
||||
{
|
||||
BT_SOLVER_N_SPLIT = 16,
|
||||
BT_SOLVER_N_BATCHES = 4,
|
||||
BT_SOLVER_N_OBJ_PER_SPLIT = 10,
|
||||
BT_SOLVER_N_TASKS_PER_BATCH = BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT,
|
||||
};
|
||||
|
||||
|
||||
bool gpuBatchContacts = true;
|
||||
bool gpuSolveConstraint = true;
|
||||
|
||||
|
||||
struct btGpuBatchingPgsSolverInternalData
|
||||
{
|
||||
cl_context m_context;
|
||||
cl_device_id m_device;
|
||||
cl_command_queue m_queue;
|
||||
int m_pairCapacity;
|
||||
int m_nIterations;
|
||||
|
||||
btOpenCLArray<btGpuConstraint4>* m_contactCGPU;
|
||||
|
||||
btOpenCLArray<unsigned int>* m_numConstraints;
|
||||
btOpenCLArray<unsigned int>* m_offsets;
|
||||
|
||||
Solver* m_solverGPU;
|
||||
|
||||
cl_kernel m_batchingKernel;
|
||||
cl_kernel m_solveContactKernel;
|
||||
cl_kernel m_solveFrictionKernel;
|
||||
cl_kernel m_contactToConstraintKernel;
|
||||
cl_kernel m_setSortDataKernel;
|
||||
cl_kernel m_reorderContactKernel;
|
||||
cl_kernel m_copyConstraintKernel;
|
||||
|
||||
class btRadixSort32CL* m_sort32;
|
||||
class btBoundSearchCL* m_search;
|
||||
class btPrefixScanCL* m_scan;
|
||||
|
||||
btOpenCLArray<btSortData>* m_sortDataBuffer;
|
||||
btOpenCLArray<btContact4>* m_contactBuffer;
|
||||
|
||||
btOpenCLArray<btRigidBodyCL>* m_bodyBufferGPU;
|
||||
btOpenCLArray<btInertiaCL>* m_inertiaBufferGPU;
|
||||
btOpenCLArray<btContact4>* m_pBufContactOutGPU;
|
||||
};
|
||||
|
||||
|
||||
|
||||
btGpuBatchingPgsSolver::btGpuBatchingPgsSolver(cl_context ctx,cl_device_id device, cl_command_queue q,int pairCapacity)
|
||||
{
|
||||
m_data = new btGpuBatchingPgsSolverInternalData;
|
||||
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_bodyBufferGPU = new btOpenCLArray<btRigidBodyCL>(ctx,q);
|
||||
m_data->m_inertiaBufferGPU = new btOpenCLArray<btInertiaCL>(ctx,q);
|
||||
m_data->m_pBufContactOutGPU = new btOpenCLArray<btContact4>(ctx,q);
|
||||
|
||||
m_data->m_solverGPU = new Solver(ctx,device,q,512*1024);
|
||||
|
||||
m_data->m_sort32 = new btRadixSort32CL(ctx,device,m_data->m_queue);
|
||||
m_data->m_scan = new btPrefixScanCL(ctx,device,m_data->m_queue,BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT);
|
||||
m_data->m_search = new btBoundSearchCL(ctx,device,m_data->m_queue,BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT);
|
||||
|
||||
const int sortSize = BTNEXTMULTIPLEOF( pairCapacity, 512 );
|
||||
|
||||
m_data->m_sortDataBuffer = new btOpenCLArray<btSortData>(ctx,m_data->m_queue,sortSize);
|
||||
m_data->m_contactBuffer = new btOpenCLArray<btContact4>(ctx,m_data->m_queue);
|
||||
|
||||
m_data->m_numConstraints = new btOpenCLArray<unsigned int>(ctx,m_data->m_queue,BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT );
|
||||
m_data->m_numConstraints->resize(BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT);
|
||||
|
||||
m_data->m_contactCGPU = new btOpenCLArray<btGpuConstraint4>(ctx,q,pairCapacity);
|
||||
|
||||
m_data->m_offsets = new btOpenCLArray<unsigned int>( ctx,m_data->m_queue, BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT );
|
||||
m_data->m_offsets->resize(BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT);
|
||||
const char* additionalMacros = "";
|
||||
const char* srcFileNameForCaching="";
|
||||
|
||||
|
||||
|
||||
cl_int pErrNum;
|
||||
const char* batchKernelSource = batchingKernelsCL;
|
||||
const char* solverSetupSource = solverSetupCL;
|
||||
const char* solverSetup2Source = solverSetup2CL;
|
||||
const char* solveContactSource = solveContactCL;
|
||||
const char* solveFrictionSource = solveFrictionCL;
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
cl_program solveContactProg= btOpenCLUtils::compileCLProgramFromString( ctx, device, solveContactSource, &pErrNum,additionalMacros, SOLVER_CONTACT_KERNEL_PATH);
|
||||
btAssert(solveContactProg);
|
||||
|
||||
cl_program solveFrictionProg= btOpenCLUtils::compileCLProgramFromString( ctx, device, solveFrictionSource, &pErrNum,additionalMacros, SOLVER_FRICTION_KERNEL_PATH);
|
||||
btAssert(solveFrictionProg);
|
||||
|
||||
cl_program solverSetup2Prog= btOpenCLUtils::compileCLProgramFromString( ctx, device, solverSetup2Source, &pErrNum,additionalMacros, SOLVER_SETUP2_KERNEL_PATH);
|
||||
btAssert(solverSetup2Prog);
|
||||
|
||||
|
||||
cl_program solverSetupProg= btOpenCLUtils::compileCLProgramFromString( ctx, device, solverSetupSource, &pErrNum,additionalMacros, SOLVER_SETUP_KERNEL_PATH);
|
||||
btAssert(solverSetupProg);
|
||||
|
||||
|
||||
m_data->m_solveFrictionKernel= btOpenCLUtils::compileCLKernelFromString( ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg,additionalMacros );
|
||||
btAssert(m_data->m_solveFrictionKernel);
|
||||
|
||||
m_data->m_solveContactKernel= btOpenCLUtils::compileCLKernelFromString( ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg,additionalMacros );
|
||||
btAssert(m_data->m_solveContactKernel);
|
||||
|
||||
m_data->m_contactToConstraintKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg,additionalMacros );
|
||||
btAssert(m_data->m_contactToConstraintKernel);
|
||||
|
||||
m_data->m_setSortDataKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog,additionalMacros );
|
||||
btAssert(m_data->m_setSortDataKernel);
|
||||
|
||||
m_data->m_reorderContactKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog,additionalMacros );
|
||||
btAssert(m_data->m_reorderContactKernel);
|
||||
|
||||
|
||||
m_data->m_copyConstraintKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog,additionalMacros );
|
||||
btAssert(m_data->m_copyConstraintKernel);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
cl_program batchingProg = btOpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelSource, &pErrNum,additionalMacros, BATCHING_PATH);
|
||||
btAssert(batchingProg);
|
||||
|
||||
m_data->m_batchingKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg,additionalMacros );
|
||||
btAssert(m_data->m_batchingKernel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
btGpuBatchingPgsSolver::~btGpuBatchingPgsSolver()
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
clReleaseKernel(m_data->m_batchingKernel);
|
||||
|
||||
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);
|
||||
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct btConstraintCfg
|
||||
{
|
||||
btConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(-1) {}
|
||||
|
||||
float m_positionDrift;
|
||||
float m_positionConstraintCoeff;
|
||||
float m_dt;
|
||||
bool m_enableParallelSolve;
|
||||
float m_averageExtent;
|
||||
int m_staticIdx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void btGpuBatchingPgsSolver::solveContactConstraint( const btOpenCLArray<btRigidBodyCL>* bodyBuf, const btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches,int numIterations)
|
||||
{
|
||||
|
||||
|
||||
btInt4 cdata = btMakeInt4( n, 0, 0, 0 );
|
||||
{
|
||||
|
||||
const int nn = BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT;
|
||||
|
||||
cdata.x = 0;
|
||||
cdata.y = maxNumBatches;//250;
|
||||
|
||||
|
||||
int numWorkItems = 64*nn/BT_SOLVER_N_BATCHES;
|
||||
#ifdef DEBUG_ME
|
||||
SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems];
|
||||
adl::btOpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device,numWorkItems);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
BT_PROFILE("m_batchSolveKernel iterations");
|
||||
for(int iter=0; iter<numIterations; iter++)
|
||||
{
|
||||
for(int ib=0; ib<BT_SOLVER_N_BATCHES; ib++)
|
||||
{
|
||||
#ifdef DEBUG_ME
|
||||
memset(debugInfo,0,sizeof(SolverDebugInfo)*numWorkItems);
|
||||
gpuDebugInfo.write(debugInfo,numWorkItems);
|
||||
#endif
|
||||
|
||||
|
||||
cdata.z = ib;
|
||||
cdata.w = BT_SOLVER_N_SPLIT;
|
||||
|
||||
btLauncherCL launcher( m_data->m_queue, m_data->m_solveContactKernel );
|
||||
#if 1
|
||||
|
||||
btBufferInfoCL bInfo[] = {
|
||||
|
||||
btBufferInfoCL( bodyBuf->getBufferCL() ),
|
||||
btBufferInfoCL( shapeBuf->getBufferCL() ),
|
||||
btBufferInfoCL( constraint->getBufferCL() ),
|
||||
btBufferInfoCL( m_data->m_numConstraints->getBufferCL() ),
|
||||
btBufferInfoCL( m_data->m_offsets->getBufferCL() )
|
||||
#ifdef DEBUG_ME
|
||||
, btBufferInfoCL(&gpuDebugInfo)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
//launcher.setConst( cdata.x );
|
||||
launcher.setConst( cdata.y );
|
||||
launcher.setConst( cdata.z );
|
||||
launcher.setConst( cdata.w );
|
||||
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)
|
||||
{
|
||||
BT_PROFILE("m_batchSolveKernel iterations2");
|
||||
for(int iter=0; iter<numIterations; iter++)
|
||||
{
|
||||
for(int ib=0; ib<BT_SOLVER_N_BATCHES; ib++)
|
||||
{
|
||||
cdata.z = ib;
|
||||
cdata.w = BT_SOLVER_N_SPLIT;
|
||||
|
||||
btBufferInfoCL bInfo[] = {
|
||||
btBufferInfoCL( bodyBuf->getBufferCL() ),
|
||||
btBufferInfoCL( shapeBuf->getBufferCL() ),
|
||||
btBufferInfoCL( constraint->getBufferCL() ),
|
||||
btBufferInfoCL( m_data->m_numConstraints->getBufferCL() ),
|
||||
btBufferInfoCL( m_data->m_offsets->getBufferCL() )
|
||||
#ifdef DEBUG_ME
|
||||
,btBufferInfoCL(&gpuDebugInfo)
|
||||
#endif //DEBUG_ME
|
||||
};
|
||||
btLauncherCL launcher( m_data->m_queue, m_data->m_solveFrictionKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
//launcher.setConst( cdata.x );
|
||||
launcher.setConst( cdata.y );
|
||||
launcher.setConst( cdata.z );
|
||||
launcher.setConst( cdata.w );
|
||||
|
||||
launcher.launch1D( 64*nn/BT_SOLVER_N_BATCHES, 64 );
|
||||
}
|
||||
}
|
||||
clFinish(m_data->m_queue);
|
||||
|
||||
}
|
||||
#ifdef DEBUG_ME
|
||||
delete[] debugInfo;
|
||||
#endif //DEBUG_ME
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void btGpuBatchingPgsSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const btConfig& config)
|
||||
{
|
||||
m_data->m_bodyBufferGPU->setFromOpenCLBuffer(bodyBuf,numBodies);
|
||||
m_data->m_inertiaBufferGPU->setFromOpenCLBuffer(inertiaBuf,numBodies);
|
||||
m_data->m_pBufContactOutGPU->setFromOpenCLBuffer(contactBuf,numContacts);
|
||||
|
||||
int nContactOut = m_data->m_pBufContactOutGPU->size();
|
||||
|
||||
bool useSolver = true;
|
||||
|
||||
if (useSolver)
|
||||
{
|
||||
float dt=1./60.;
|
||||
btConstraintCfg csCfg( dt );
|
||||
csCfg.m_enableParallelSolve = true;
|
||||
csCfg.m_averageExtent = 0.2f;//@TODO m_averageObjExtent;
|
||||
csCfg.m_staticIdx = -1;//m_static0Index;//m_planeBodyIndex;
|
||||
|
||||
btOpenCLArray<btContact4>* contactsIn = m_data->m_pBufContactOutGPU;
|
||||
btOpenCLArray<btRigidBodyCL>* bodyBuf = m_data->m_bodyBufferGPU;
|
||||
|
||||
void* additionalData = 0;//m_data->m_frictionCGPU;
|
||||
const btOpenCLArray<btInertiaCL>* shapeBuf = m_data->m_inertiaBufferGPU;
|
||||
btOpenCLArray<btGpuConstraint4>* contactConstraintOut = m_data->m_contactCGPU;
|
||||
int nContacts = nContactOut;
|
||||
|
||||
|
||||
int maxNumBatches = 0;
|
||||
|
||||
{
|
||||
|
||||
if( m_data->m_solverGPU->m_contactBuffer)
|
||||
{
|
||||
m_data->m_solverGPU->m_contactBuffer->resize(nContacts);
|
||||
}
|
||||
|
||||
if( m_data->m_solverGPU->m_contactBuffer == 0 )
|
||||
{
|
||||
m_data->m_solverGPU->m_contactBuffer = new btOpenCLArray<btContact4>(m_data->m_context,m_data->m_queue, nContacts );
|
||||
m_data->m_solverGPU->m_contactBuffer->resize(nContacts);
|
||||
}
|
||||
clFinish(m_data->m_queue);
|
||||
|
||||
|
||||
|
||||
{
|
||||
BT_PROFILE("batching");
|
||||
//@todo: just reserve it, without copy of original contact (unless we use warmstarting)
|
||||
|
||||
|
||||
btOpenCLArray<btContact4>* contactNative = contactsIn;
|
||||
const btOpenCLArray<btRigidBodyCL>* bodyNative = bodyBuf;
|
||||
|
||||
|
||||
{
|
||||
|
||||
//btOpenCLArray<btRigidBodyCL>* bodyNative = btOpenCLArrayUtils::map<adl::TYPE_CL, true>( data->m_device, bodyBuf );
|
||||
//btOpenCLArray<btContact4>* contactNative = btOpenCLArrayUtils::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 = NEXTMULTIPLEOF( nContacts, sortAlignment );
|
||||
|
||||
btOpenCLArray<u32>* countsNative = m_data->m_solverGPU->m_numConstraints;
|
||||
btOpenCLArray<u32>* offsetsNative = m_data->m_solverGPU->m_offsets;
|
||||
|
||||
{ // 2. set cell idx
|
||||
BT_PROFILE("GPU set cell idx");
|
||||
struct CB
|
||||
{
|
||||
int m_nContacts;
|
||||
int m_staticIdx;
|
||||
float m_scale;
|
||||
int m_nSplit;
|
||||
};
|
||||
|
||||
btAssert( sortSize%64 == 0 );
|
||||
CB cdata;
|
||||
cdata.m_nContacts = nContacts;
|
||||
cdata.m_staticIdx = csCfg.m_staticIdx;
|
||||
cdata.m_scale = 1.f/(BT_SOLVER_N_OBJ_PER_SPLIT*csCfg.m_averageExtent);
|
||||
cdata.m_nSplit = BT_SOLVER_N_SPLIT;
|
||||
|
||||
m_data->m_solverGPU->m_sortDataBuffer->resize(nContacts);
|
||||
|
||||
|
||||
btBufferInfoCL bInfo[] = { btBufferInfoCL( contactNative->getBufferCL() ), btBufferInfoCL( bodyBuf->getBufferCL()), btBufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) };
|
||||
btLauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_setSortDataKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
launcher.setConst( cdata.m_nContacts );
|
||||
launcher.setConst( cdata.m_scale );
|
||||
launcher.setConst(cdata.m_nSplit);
|
||||
|
||||
|
||||
launcher.launch1D( sortSize, 64 );
|
||||
}
|
||||
|
||||
|
||||
bool gpuRadixSort=true;
|
||||
if (gpuRadixSort)
|
||||
{ // 3. sort by cell idx
|
||||
BT_PROFILE("gpuRadixSort");
|
||||
int n = BT_SOLVER_N_SPLIT*BT_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 );
|
||||
btOpenCLArray<btSortData>& keyValuesInOut = *(m_data->m_solverGPU->m_sortDataBuffer);
|
||||
this->m_data->m_solverGPU->m_sort32->execute(keyValuesInOut);
|
||||
|
||||
/*btAlignedObjectArray<btSortData> hostValues;
|
||||
keyValuesInOut.copyToHost(hostValues);
|
||||
printf("hostValues.size=%d\n",hostValues.size());
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
// 4. find entries
|
||||
BT_PROFILE("gpuBoundSearch");
|
||||
|
||||
m_data->m_solverGPU->m_search->execute(*m_data->m_solverGPU->m_sortDataBuffer,nContacts,*countsNative,
|
||||
BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT,btBoundSearchCL::COUNT);
|
||||
|
||||
|
||||
//adl::BoundSearch<adl::TYPE_CL>::execute( data->m_search, *data->m_sortDataBuffer, nContacts, *countsNative,
|
||||
// BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT, adl::BoundSearchBase::COUNT );
|
||||
|
||||
//unsigned int sum;
|
||||
m_data->m_solverGPU->m_scan->execute(*countsNative,*offsetsNative, BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT);//,&sum );
|
||||
//printf("sum = %d\n",sum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (nContacts)
|
||||
{ // 5. sort constraints by cellIdx
|
||||
{
|
||||
BT_PROFILE("gpu m_reorderContactKernel");
|
||||
|
||||
btInt4 cdata;
|
||||
cdata.x = nContacts;
|
||||
|
||||
btBufferInfoCL bInfo[] = { btBufferInfoCL( contactNative->getBufferCL() ), btBufferInfoCL( m_data->m_solverGPU->m_contactBuffer->getBufferCL())
|
||||
, btBufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) };
|
||||
btLauncherCL launcher(m_data->m_queue,m_data->m_solverGPU->m_reorderContactKernel);
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
launcher.setConst( cdata );
|
||||
launcher.launch1D( nContacts, 64 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
clFinish(m_data->m_queue);
|
||||
|
||||
if (nContacts)
|
||||
{
|
||||
BT_PROFILE("gpu m_copyConstraintKernel");
|
||||
|
||||
btInt4 cdata; cdata.x = nContacts;
|
||||
btBufferInfoCL bInfo[] = { btBufferInfoCL( m_data->m_solverGPU->m_contactBuffer->getBufferCL() ), btBufferInfoCL( contactNative->getBufferCL() ) };
|
||||
btLauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_copyConstraintKernel );
|
||||
launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) );
|
||||
launcher.setConst( cdata );
|
||||
launcher.launch1D( nContacts, 64 );
|
||||
clFinish(m_data->m_queue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool compareGPU = false;
|
||||
if (nContacts)
|
||||
{
|
||||
if (gpuBatchContacts)
|
||||
{
|
||||
maxNumBatches=250;//for now
|
||||
BT_PROFILE("gpu batchContacts");
|
||||
m_data->m_solverGPU->batchContacts( (btOpenCLArray<btContact4>*)contactNative, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx );
|
||||
} else
|
||||
{
|
||||
BT_PROFILE("cpu batchContacts");
|
||||
btAlignedObjectArray<btContact4> cpuContacts;
|
||||
btOpenCLArray<btContact4>* contactsIn = m_data->m_pBufContactOutGPU;
|
||||
contactsIn->copyToHost(cpuContacts);
|
||||
|
||||
btOpenCLArray<u32>* countsNative = m_data->m_solverGPU->m_numConstraints;
|
||||
btOpenCLArray<u32>* offsetsNative = m_data->m_solverGPU->m_offsets;
|
||||
|
||||
btAlignedObjectArray<u32> nNativeHost;
|
||||
btAlignedObjectArray<u32> offsetsNativeHost;
|
||||
|
||||
{
|
||||
BT_PROFILE("countsNative/offsetsNative copyToHost");
|
||||
countsNative->copyToHost(nNativeHost);
|
||||
offsetsNative->copyToHost(offsetsNativeHost);
|
||||
}
|
||||
|
||||
|
||||
int numNonzeroGrid=0;
|
||||
|
||||
{
|
||||
BT_PROFILE("batch grid");
|
||||
for(int i=0; i<BT_SOLVER_N_SPLIT*BT_SOLVER_N_SPLIT; i++)
|
||||
{
|
||||
int n = (nNativeHost)[i];
|
||||
int offset = (offsetsNativeHost)[i];
|
||||
|
||||
if( n )
|
||||
{
|
||||
numNonzeroGrid++;
|
||||
//printf("cpu batch\n");
|
||||
|
||||
int simdWidth = -1;
|
||||
int numBatches = sortConstraintByBatch( &cpuContacts[0]+offset, n, simdWidth,csCfg.m_staticIdx ); // on GPU
|
||||
maxNumBatches = btMax(numBatches,maxNumBatches);
|
||||
|
||||
clFinish(m_data->m_queue);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
BT_PROFILE("m_contactBuffer->copyFromHost");
|
||||
m_data->m_solverGPU->m_contactBuffer->copyFromHost((btAlignedObjectArray<btContact4>&)cpuContacts);
|
||||
}
|
||||
// printf("maxNumBatches = %d\n", maxNumBatches);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (nContacts)
|
||||
{
|
||||
//BT_PROFILE("gpu convertToConstraints");
|
||||
m_data->m_solverGPU->convertToConstraints( bodyBuf,
|
||||
shapeBuf, m_data->m_solverGPU->m_contactBuffer /*contactNative*/,
|
||||
contactConstraintOut,
|
||||
additionalData, nContacts,
|
||||
(SolverBase::ConstraintCfg&) csCfg );
|
||||
clFinish(m_data->m_queue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (1)
|
||||
{
|
||||
BT_PROFILE("GPU solveContactConstraint");
|
||||
m_data->m_solverGPU->m_nIterations = 4;//10
|
||||
if (gpuSolveConstraint)
|
||||
{
|
||||
m_data->m_solverGPU->solveContactConstraint(
|
||||
m_data->m_bodyBufferGPU,
|
||||
m_data->m_inertiaBufferGPU,
|
||||
m_data->m_contactCGPU,0,
|
||||
nContactOut ,
|
||||
maxNumBatches);
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_data->m_solverGPU->solveContactConstraintHost(m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, m_data->m_contactCGPU,0, nContactOut ,maxNumBatches);
|
||||
}
|
||||
|
||||
clFinish(m_data->m_queue);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (0)
|
||||
{
|
||||
BT_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 btGpuBatchingPgsSolver::batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* n, btOpenCLArray<unsigned int>* offsets, int staticIdx )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool sortfnc(const btSortData& a,const btSortData& b)
|
||||
{
|
||||
return (a.m_key<b.m_key);
|
||||
}
|
||||
|
||||
btAlignedObjectArray<unsigned int> idxBuffer;
|
||||
btAlignedObjectArray<btSortData> sortData;
|
||||
btAlignedObjectArray<btContact4> old;
|
||||
|
||||
|
||||
inline int btGpuBatchingPgsSolver::sortConstraintByBatch( btContact4* cs, int n, int simdWidth , int staticIdx)
|
||||
{
|
||||
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;
|
||||
|
||||
{
|
||||
BT_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];
|
||||
btAssert( idx < n );
|
||||
// check if it can go
|
||||
int bodyAS = cs[idx].m_bodyAPtrAndSignBit;
|
||||
int bodyBS = cs[idx].m_bodyBPtrAndSignBit;
|
||||
|
||||
/*if (bodyAS<0)
|
||||
printf("A static\n");
|
||||
|
||||
if (bodyBS<0)
|
||||
printf("B static\n");
|
||||
*/
|
||||
|
||||
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));
|
||||
|
||||
//use inv_mass!
|
||||
aUnavailable = (bodyAS>=0)&&bodyAS!=staticIdx? aUnavailable:0;//
|
||||
bUnavailable = (bodyBS>=0)&&bodyBS!=staticIdx? bUnavailable:0;
|
||||
|
||||
if( aUnavailable==0 && bUnavailable==0 ) // ok
|
||||
{
|
||||
flg[ aIdx/32 ] |= (1<<(aIdx&31));
|
||||
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;
|
||||
}
|
||||
}
|
||||
btSwap( idxSrc, idxDst );
|
||||
btSwap( nIdxSrc, nIdxDst );
|
||||
batchIdx ++;
|
||||
}
|
||||
}
|
||||
{
|
||||
BT_PROFILE("quickSort");
|
||||
sortData.quickSort(sortfnc);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
BT_PROFILE("reorder");
|
||||
// reorder
|
||||
|
||||
memcpy( &old[0], cs, sizeof(btContact4)*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++)
|
||||
{
|
||||
btAssert( cs[i].getBatchIdx() != -1 );
|
||||
}
|
||||
#endif
|
||||
return batchIdx;
|
||||
}
|
||||
32
opencl/gpu_rigidbody/host/btGpuBatchingPgsSolver.h
Normal file
32
opencl/gpu_rigidbody/host/btGpuBatchingPgsSolver.h
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
#ifndef BT_GPU_BATCHING_PGS_SOLVER_H
|
||||
#define BT_GPU_BATCHING_PGS_SOLVER_H
|
||||
|
||||
#include "../../basic_initialize/btOpenCLInclude.h"
|
||||
#include "../../parallel_primitives/host/btOpenCLArray.h"
|
||||
#include "../../gpu_sat/host/btRigidBodyCL.h"
|
||||
#include "../../gpu_sat/host/btContact4.h"
|
||||
#include "btGpuConstraint4.h"
|
||||
|
||||
class btGpuBatchingPgsSolver
|
||||
{
|
||||
protected:
|
||||
|
||||
struct btGpuBatchingPgsSolverInternalData* m_data;
|
||||
|
||||
void batchContacts( btOpenCLArray<btContact4>* contacts, int nContacts, btOpenCLArray<unsigned int>* n, btOpenCLArray<unsigned int>* offsets, int staticIdx );
|
||||
inline int sortConstraintByBatch( btContact4* cs, int n, int simdWidth , int staticIdx);
|
||||
void solveContactConstraint( const btOpenCLArray<btRigidBodyCL>* bodyBuf, const btOpenCLArray<btInertiaCL>* shapeBuf,
|
||||
btOpenCLArray<btGpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches, int numIterations);
|
||||
|
||||
public:
|
||||
|
||||
btGpuBatchingPgsSolver(cl_context ctx,cl_device_id device, cl_command_queue q,int pairCapacity);
|
||||
virtual ~btGpuBatchingPgsSolver();
|
||||
|
||||
void solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const struct btConfig& config);
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_GPU_BATCHING_PGS_SOLVER_H
|
||||
|
||||
31
opencl/gpu_rigidbody/host/btGpuConstraint4.h
Normal file
31
opencl/gpu_rigidbody/host/btGpuConstraint4.h
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
#ifndef BT_CONSTRAINT4_h
|
||||
#define BT_CONSTRAINT4_h
|
||||
#include "BulletCommon/btVector3.h"
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) btGpuConstraint4
|
||||
{
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
btVector3 m_linear;//normal?
|
||||
btVector3 m_worldPos[4];
|
||||
btVector3 m_center; // friction
|
||||
float m_jacCoeffInv[4];
|
||||
float m_b[4];
|
||||
float m_appliedRambdaDt[4];
|
||||
|
||||
float m_fJacCoeffInv[2]; // friction
|
||||
float m_fAppliedRambdaDt[2]; // friction
|
||||
|
||||
unsigned int m_bodyA;
|
||||
unsigned int m_bodyB;
|
||||
|
||||
unsigned int m_batchIdx;
|
||||
unsigned int m_paddings[1];
|
||||
|
||||
inline void setFrictionCoeff(float value) { m_linear[3] = value; }
|
||||
inline float getFrictionCoeff() const { return m_linear[3]; }
|
||||
};
|
||||
|
||||
#endif //BT_CONSTRAINT4_h
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
#include "btPgsJacobiSolver.h"
|
||||
#include "../../gpu_sat/host/btRigidBodyCL.h"
|
||||
#include "../../gpu_sat/host/btContact4.h"
|
||||
#include "btGpuBatchingPgsSolver.h"
|
||||
#include "../Stubs/Solver.h"
|
||||
|
||||
#include "btConfig.h"
|
||||
|
||||
btGpuRigidBodyPipeline::btGpuRigidBodyPipeline(cl_context ctx,cl_device_id device, cl_command_queue q,class btGpuNarrowPhase* narrowphase, class btGpuSapBroadphase* broadphaseSap )
|
||||
{
|
||||
@@ -21,7 +24,9 @@ btGpuRigidBodyPipeline::btGpuRigidBodyPipeline(cl_context ctx,cl_device_id devic
|
||||
m_data->m_device = device;
|
||||
m_data->m_queue = q;
|
||||
m_data->m_solver = new btPgsJacobiSolver();
|
||||
|
||||
m_data->m_solver2 = new btGpuBatchingPgsSolver(ctx,device,q,256*1024);
|
||||
|
||||
|
||||
m_data->m_broadphaseSap = broadphaseSap;
|
||||
m_data->m_narrowphase = narrowphase;
|
||||
|
||||
@@ -48,7 +53,9 @@ btGpuRigidBodyPipeline::btGpuRigidBodyPipeline(cl_context ctx,cl_device_id devic
|
||||
btGpuRigidBodyPipeline::~btGpuRigidBodyPipeline()
|
||||
{
|
||||
clReleaseKernel(m_data->m_integrateTransformsKernel);
|
||||
|
||||
|
||||
delete m_data->m_solver;
|
||||
delete m_data->m_solver2;
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
@@ -66,11 +73,13 @@ void btGpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
int numPairs = m_data->m_broadphaseSap->getNumOverlap();
|
||||
int numContacts = 0;
|
||||
|
||||
int numBodies = m_data->m_narrowphase->getNumBodiesGpu();
|
||||
|
||||
if (numPairs)
|
||||
{
|
||||
cl_mem pairs = m_data->m_broadphaseSap->getOverlappingPairBuffer();
|
||||
cl_mem aabbs = m_data->m_broadphaseSap->getAabbBuffer();
|
||||
int numBodies = m_data->m_narrowphase->getNumBodiesGpu();
|
||||
|
||||
|
||||
m_data->m_narrowphase->computeContacts(pairs,numPairs,aabbs,numBodies);
|
||||
numContacts = m_data->m_narrowphase->getNumContactsGpu();
|
||||
@@ -85,27 +94,41 @@ void btGpuRigidBodyPipeline::stepSimulation(float deltaTime)
|
||||
|
||||
if (numContacts)
|
||||
{
|
||||
// m_data->m_solver->solveGroup(bodies, inertias,numBodies,contacts,numContacts,0,0,infoGlobal);
|
||||
btAlignedObjectArray<btRigidBodyCL> hostBodies;
|
||||
btOpenCLArray<btRigidBodyCL> gpuBodies(m_data->m_context,m_data->m_queue,0,true);
|
||||
gpuBodies.setFromOpenCLBuffer(m_data->m_narrowphase->getBodiesGpu(),m_data->m_narrowphase->getNumBodiesGpu());
|
||||
gpuBodies.copyToHost(hostBodies);
|
||||
|
||||
btAlignedObjectArray<btInertiaCL> hostInertias;
|
||||
btOpenCLArray<btInertiaCL> gpuInertias(m_data->m_context,m_data->m_queue,0,true);
|
||||
gpuInertias.setFromOpenCLBuffer(m_data->m_narrowphase->getBodyInertiasGpu(),m_data->m_narrowphase->getNumBodiesGpu());
|
||||
gpuInertias.copyToHost(hostInertias);
|
||||
|
||||
btAlignedObjectArray<btContact4> hostContacts;
|
||||
btOpenCLArray<btContact4> gpuContacts(m_data->m_context,m_data->m_queue,0,true);
|
||||
gpuContacts.setFromOpenCLBuffer(m_data->m_narrowphase->getContactsGpu(),m_data->m_narrowphase->getNumContactsGpu());
|
||||
gpuContacts.copyToHost(hostContacts);
|
||||
|
||||
bool useJacobi = false;
|
||||
if (useJacobi)
|
||||
{
|
||||
btAlignedObjectArray<btRigidBodyCL> hostBodies;
|
||||
gpuBodies.copyToHost(hostBodies);
|
||||
btAlignedObjectArray<btInertiaCL> hostInertias;
|
||||
gpuInertias.copyToHost(hostInertias);
|
||||
btAlignedObjectArray<btContact4> hostContacts;
|
||||
gpuContacts.copyToHost(hostContacts);
|
||||
{
|
||||
m_data->m_solver->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(),&hostBodies[0],&hostInertias[0],numContacts,&hostContacts[0]);
|
||||
}
|
||||
|
||||
gpuBodies.copyFromHost(hostBodies);
|
||||
} else
|
||||
{
|
||||
btConfig config;
|
||||
m_data->m_solver2->solveContacts(numBodies, gpuBodies.getBufferCL(),gpuInertias.getBufferCL(),numContacts, gpuContacts.getBufferCL(),config);
|
||||
|
||||
//m_data->m_solver4->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(), gpuBodies.getBufferCL(), gpuInertias.getBufferCL(), numContacts, gpuContacts.getBufferCL());
|
||||
|
||||
|
||||
/*m_data->m_solver3->solveContactConstraintHost(
|
||||
(btOpenCLArray<RigidBodyBase::Body>*)&gpuBodies,
|
||||
(btOpenCLArray<RigidBodyBase::Inertia>*)&gpuInertias,
|
||||
(btOpenCLArray<Constraint4>*) &gpuContacts,
|
||||
0,numContacts,256);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
integrate(deltaTime);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../../parallel_primitives/host/btOpenCLArray.h"
|
||||
#include "../../gpu_sat/host/btCollidable.h"
|
||||
|
||||
|
||||
struct btGpuRigidBodyPipelineInternalData
|
||||
{
|
||||
|
||||
@@ -18,7 +19,8 @@ struct btGpuRigidBodyPipelineInternalData
|
||||
cl_kernel m_updateAabbsKernel;
|
||||
|
||||
class btPgsJacobiSolver* m_solver;
|
||||
|
||||
class btGpuBatchingPgsSolver* m_solver2;
|
||||
|
||||
class btGpuSapBroadphase* m_broadphaseSap;
|
||||
|
||||
class btGpuNarrowPhase* m_narrowphase;
|
||||
|
||||
@@ -33,7 +33,7 @@ subject to the following restrictions:
|
||||
//#include "../../dynamics/basic_demo/Stubs/AdlContact4.h"
|
||||
#include "../../gpu_sat/host/btContact4.h"
|
||||
|
||||
bool usePgs = false;
|
||||
bool usePgs = true;
|
||||
int gNumSplitImpulseRecoveries2 = 0;
|
||||
|
||||
#include "btRigidBody.h"
|
||||
|
||||
Reference in New Issue
Block a user