278 lines
5.8 KiB
Common Lisp
278 lines
5.8 KiB
Common Lisp
|
|
||
|
/*
|
||
|
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 "Bullet3Dynamics/shared/b3ConvertConstraint4.h"
|
||
|
|
||
|
#pragma OPENCL EXTENSION cl_amd_printf : enable
|
||
|
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
|
||
|
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
|
||
|
#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable
|
||
|
#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
|
||
|
|
||
|
|
||
|
#ifdef cl_ext_atomic_counters_32
|
||
|
#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable
|
||
|
#else
|
||
|
#define counter32_t volatile global int*
|
||
|
#endif
|
||
|
|
||
|
typedef unsigned int u32;
|
||
|
typedef unsigned short u16;
|
||
|
typedef unsigned char u8;
|
||
|
|
||
|
#define GET_GROUP_IDX get_group_id(0)
|
||
|
#define GET_LOCAL_IDX get_local_id(0)
|
||
|
#define GET_GLOBAL_IDX get_global_id(0)
|
||
|
#define GET_GROUP_SIZE get_local_size(0)
|
||
|
#define GET_NUM_GROUPS get_num_groups(0)
|
||
|
#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)
|
||
|
#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)
|
||
|
#define AtomInc(x) atom_inc(&(x))
|
||
|
#define AtomInc1(x, out) out = atom_inc(&(x))
|
||
|
#define AppendInc(x, out) out = atomic_inc(x)
|
||
|
#define AtomAdd(x, value) atom_add(&(x), value)
|
||
|
#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )
|
||
|
#define AtomXhg(x, value) atom_xchg ( &(x), value )
|
||
|
|
||
|
|
||
|
#define SELECT_UINT4( b, a, condition ) select( b,a,condition )
|
||
|
|
||
|
#define make_float4 (float4)
|
||
|
#define make_float2 (float2)
|
||
|
#define make_uint4 (uint4)
|
||
|
#define make_int4 (int4)
|
||
|
#define make_uint2 (uint2)
|
||
|
#define make_int2 (int2)
|
||
|
|
||
|
|
||
|
#define max2 max
|
||
|
#define min2 min
|
||
|
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
// Vector
|
||
|
///////////////////////////////////////
|
||
|
__inline
|
||
|
float fastDiv(float numerator, float denominator)
|
||
|
{
|
||
|
return native_divide(numerator, denominator);
|
||
|
// return numerator/denominator;
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float4 fastDiv4(float4 numerator, float4 denominator)
|
||
|
{
|
||
|
return native_divide(numerator, denominator);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float fastSqrtf(float f2)
|
||
|
{
|
||
|
return native_sqrt(f2);
|
||
|
// return sqrt(f2);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float fastRSqrt(float f2)
|
||
|
{
|
||
|
return native_rsqrt(f2);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float fastLength4(float4 v)
|
||
|
{
|
||
|
return fast_length(v);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float4 fastNormalize4(float4 v)
|
||
|
{
|
||
|
return fast_normalize(v);
|
||
|
}
|
||
|
|
||
|
|
||
|
__inline
|
||
|
float sqrtf(float a)
|
||
|
{
|
||
|
// return sqrt(a);
|
||
|
return native_sqrt(a);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float4 cross3(float4 a, float4 b)
|
||
|
{
|
||
|
return cross(a,b);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float dot3F4(float4 a, float4 b)
|
||
|
{
|
||
|
float4 a1 = make_float4(a.xyz,0.f);
|
||
|
float4 b1 = make_float4(b.xyz,0.f);
|
||
|
return dot(a1, b1);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float length3(const float4 a)
|
||
|
{
|
||
|
return sqrtf(dot3F4(a,a));
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float dot4(const float4 a, const float4 b)
|
||
|
{
|
||
|
return dot( a, b );
|
||
|
}
|
||
|
|
||
|
// for height
|
||
|
__inline
|
||
|
float dot3w1(const float4 point, const float4 eqn)
|
||
|
{
|
||
|
return dot3F4(point,eqn) + eqn.w;
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float4 normalize3(const float4 a)
|
||
|
{
|
||
|
float4 n = make_float4(a.x, a.y, a.z, 0.f);
|
||
|
return fastNormalize4( n );
|
||
|
// float length = sqrtf(dot3F4(a, a));
|
||
|
// return 1.f/length * a;
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float4 normalize4(const float4 a)
|
||
|
{
|
||
|
float length = sqrtf(dot4(a, a));
|
||
|
return 1.f/length * a;
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
float4 createEquation(const float4 a, const float4 b, const float4 c)
|
||
|
{
|
||
|
float4 eqn;
|
||
|
float4 ab = b-a;
|
||
|
float4 ac = c-a;
|
||
|
eqn = normalize3( cross3(ab, ac) );
|
||
|
eqn.w = -dot3F4(eqn,a);
|
||
|
return eqn;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#define WG_SIZE 64
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int m_nConstraints;
|
||
|
int m_start;
|
||
|
int m_batchIdx;
|
||
|
int m_nSplit;
|
||
|
// int m_paddings[1];
|
||
|
} ConstBuffer;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int m_solveFriction;
|
||
|
int m_maxBatch; // long batch really kills the performance
|
||
|
int m_batchIdx;
|
||
|
int m_nSplit;
|
||
|
// int m_paddings[1];
|
||
|
} ConstBufferBatchSolve;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int m_valInt0;
|
||
|
int m_valInt1;
|
||
|
int m_valInt2;
|
||
|
int m_valInt3;
|
||
|
|
||
|
float m_val0;
|
||
|
float m_val1;
|
||
|
float m_val2;
|
||
|
float m_val3;
|
||
|
} SolverDebugInfo;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int m_nContacts;
|
||
|
float m_dt;
|
||
|
float m_positionDrift;
|
||
|
float m_positionConstraintCoeff;
|
||
|
} ConstBufferCTC;
|
||
|
|
||
|
__kernel
|
||
|
__attribute__((reqd_work_group_size(WG_SIZE,1,1)))
|
||
|
void ContactToConstraintKernel(__global struct b3Contact4Data* gContact, __global b3RigidBodyData_t* gBodies, __global b3InertiaData_t* gShapes, __global b3ContactConstraint4_t* gConstraintOut,
|
||
|
int nContacts,
|
||
|
float dt,
|
||
|
float positionDrift,
|
||
|
float positionConstraintCoeff
|
||
|
)
|
||
|
{
|
||
|
int gIdx = GET_GLOBAL_IDX;
|
||
|
|
||
|
if( gIdx < nContacts )
|
||
|
{
|
||
|
int aIdx = abs(gContact[gIdx].m_bodyAPtrAndSignBit);
|
||
|
int bIdx = abs(gContact[gIdx].m_bodyBPtrAndSignBit);
|
||
|
|
||
|
float4 posA = gBodies[aIdx].m_pos;
|
||
|
float4 linVelA = gBodies[aIdx].m_linVel;
|
||
|
float4 angVelA = gBodies[aIdx].m_angVel;
|
||
|
float invMassA = gBodies[aIdx].m_invMass;
|
||
|
b3Mat3x3 invInertiaA = gShapes[aIdx].m_initInvInertia;
|
||
|
|
||
|
float4 posB = gBodies[bIdx].m_pos;
|
||
|
float4 linVelB = gBodies[bIdx].m_linVel;
|
||
|
float4 angVelB = gBodies[bIdx].m_angVel;
|
||
|
float invMassB = gBodies[bIdx].m_invMass;
|
||
|
b3Mat3x3 invInertiaB = gShapes[bIdx].m_initInvInertia;
|
||
|
|
||
|
b3ContactConstraint4_t cs;
|
||
|
|
||
|
setConstraint4( posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB,
|
||
|
&gContact[gIdx], dt, positionDrift, positionConstraintCoeff,
|
||
|
&cs );
|
||
|
|
||
|
cs.m_batchIdx = gContact[gIdx].m_batchIdx;
|
||
|
|
||
|
gConstraintOut[gIdx] = cs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|