PairBench.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. //those header files need to be at the top, because of conflict __global and STL
  2. #include "PairBench.h"
  3. #include "Bullet3Common/b3Quaternion.h"
  4. #include "Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h"
  5. #include "Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h"
  6. #include "Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.h"
  7. #include "../Utils/b3Clock.h"
  8. //#include "../GpuDemoInternalData.h"
  9. #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
  10. #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
  11. #include "../OpenGLWindow/OpenGLInclude.h"
  12. #include "../OpenGLWindow/ShapeData.h"
  13. #include <string.h>
  14. #include "pairsKernel.h"
  15. extern int gPreferredOpenCLDeviceIndex;
  16. extern int gPreferredOpenCLPlatformIndex;
  17. #include "../CommonInterfaces/CommonExampleInterface.h"
  18. #include "../CommonInterfaces/CommonGUIHelperInterface.h"
  19. #include "../CommonInterfaces/CommonRenderInterface.h"
  20. #include "../CommonInterfaces/CommonCameraInterface.h"
  21. #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
  22. #include "../CommonInterfaces/CommonWindowInterface.h"
  23. #include "../CommonOpenCL/CommonOpenCLBase.h"
  24. #include "../OpenGLWindow/GLInstancingRenderer.h"
  25. #include "../OpenGLWindow/GLInstanceRendererInternalData.h"
  26. char* gPairBenchFileName = 0;
  27. class PairBench : public CommonOpenCLBase
  28. {
  29. struct PairBenchInternalData* m_data;
  30. public:
  31. PairBench(GUIHelperInterface* helper);
  32. virtual ~PairBench();
  33. virtual void initPhysics();
  34. virtual void exitPhysics();
  35. void createBroadphase(int xdim, int ydim, int zdim);
  36. void deleteBroadphase();
  37. virtual void stepSimulation(float deltaTime);
  38. virtual void renderScene();
  39. virtual void resetCamera()
  40. {
  41. float dist = 10;
  42. if (gPairBenchFileName)
  43. {
  44. dist = 830;
  45. }
  46. else
  47. {
  48. dist = 130;
  49. }
  50. float pitch = -33;
  51. float yaw = 62;
  52. float targetPos[4] = {15.5, 12.5, 15.5, 0};
  53. m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
  54. }
  55. };
  56. //we use an offset, just for testing to make sure there is no assumption in the broadphase that 'index' starts at 0
  57. #define TEST_INDEX_OFFSET 1024
  58. extern bool useShadowMap;
  59. float maxExtents = -1e30f;
  60. int largeCount = 0;
  61. float timeStepPos = 0.000166666;
  62. float mAmplitude = 251.f;
  63. int dimensions[3] = {10, 10, 10}; //initialized with x_dim/y_dim/z_dim
  64. const char* axisNames[3] = {"# x-axis", "# y-axis", "# z-axis"};
  65. extern bool gReset;
  66. static int curUseLargeAabbOption = 0;
  67. const char* useLargeAabbOptions[] =
  68. {
  69. "NoLargeAabb",
  70. "UseLargeAabb",
  71. };
  72. struct BroadphaseEntry
  73. {
  74. const char* m_name;
  75. b3GpuBroadphaseInterface::CreateFunc* m_createFunc;
  76. };
  77. static PairBench* sPairDemo = 0;
  78. #define BP_COMBO_INDEX 123
  79. static int curSelectedBroadphase = 0;
  80. static BroadphaseEntry allBroadphases[] =
  81. {
  82. {"Gpu Grid", b3GpuGridBroadphase::CreateFunc},
  83. {"Parallel Linear BVH", b3GpuParallelLinearBvhBroadphase::CreateFunc},
  84. {"CPU Brute Force", b3GpuSapBroadphase::CreateFuncBruteForceCpu},
  85. {"GPU Brute Force", b3GpuSapBroadphase::CreateFuncBruteForceGpu},
  86. {"GPU 1-SAP Original", b3GpuSapBroadphase::CreateFuncOriginal},
  87. {"GPU 1-SAP Barrier", b3GpuSapBroadphase::CreateFuncBarrier},
  88. {"GPU 1-SAP LDS", b3GpuSapBroadphase::CreateFuncLocalMemory}};
  89. struct PairBenchInternalData
  90. {
  91. b3GpuBroadphaseInterface* m_broadphaseGPU;
  92. b3GpuBroadphaseInterface* m_validationBroadphase;
  93. cl_kernel m_moveObjectsKernel;
  94. cl_kernel m_sineWaveKernel;
  95. cl_kernel m_colorPairsKernel;
  96. cl_kernel m_updateAabbSimple;
  97. b3OpenCLArray<b3Vector4>* m_instancePosOrnColor;
  98. b3OpenCLArray<float>* m_bodyTimes;
  99. PairBenchInternalData()
  100. : m_broadphaseGPU(0),
  101. m_moveObjectsKernel(0),
  102. m_sineWaveKernel(0),
  103. m_colorPairsKernel(0),
  104. m_instancePosOrnColor(0),
  105. m_bodyTimes(0),
  106. m_updateAabbSimple(0)
  107. {
  108. }
  109. int m_oldYposition;
  110. };
  111. PairBench::PairBench(GUIHelperInterface* helper)
  112. : CommonOpenCLBase(helper)
  113. {
  114. m_data = new PairBenchInternalData;
  115. m_data->m_validationBroadphase = 0;
  116. }
  117. PairBench::~PairBench()
  118. {
  119. delete m_data;
  120. }
  121. static inline float parseFloat(const char*& token)
  122. {
  123. token += strspn(token, " \t");
  124. float f = (float)atof(token);
  125. token += strcspn(token, " \t\r");
  126. return f;
  127. }
  128. enum PairToggleButtons
  129. {
  130. MY_RESET = 1024,
  131. };
  132. #define PAIRS_CL_PROGRAM_PATH "Demos3/GpuDemos/broadphase/pairsKernel.cl"
  133. void PairBench::initPhysics()
  134. {
  135. dimensions[0] = 10;
  136. dimensions[1] = 10;
  137. dimensions[2] = 10;
  138. //m_guiHelper->getRenderInterface() = ci.m_guiHelper->getRenderInterface();
  139. sPairDemo = this;
  140. useShadowMap = false;
  141. initCL(gPreferredOpenCLDeviceIndex, gPreferredOpenCLPlatformIndex);
  142. if (m_clData->m_clContext)
  143. {
  144. cl_int err;
  145. cl_program pairBenchProg = b3OpenCLUtils::compileCLProgramFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, &err, "", PAIRS_CL_PROGRAM_PATH);
  146. int errNum = 0;
  147. m_data->m_moveObjectsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "moveObjectsKernel", &errNum, pairBenchProg);
  148. m_data->m_sineWaveKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "sineWaveKernel", &errNum, pairBenchProg);
  149. m_data->m_colorPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "colorPairsKernel2", &errNum, pairBenchProg);
  150. m_data->m_updateAabbSimple = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice, pairsKernelsCL, "updateAabbSimple", &errNum, pairBenchProg);
  151. //Method for validating the overlapping pairs requires that the
  152. //reference broadphase does not maintain internal state aside from AABB data.
  153. //That is, overwriting the AABB state in the broadphase using
  154. // b3GpuBroadphaseInterface::getAllAabbsGPU(),
  155. // b3GpuBroadphaseInterface::getSmallAabbIndicesGPU(), and
  156. // b3GpuBroadphaseInterface::getLargeAabbIndicesGPU()
  157. //and then calling b3GpuBroadphaseInterface::calculateOverlappingPairs() should
  158. //always produce the same result regardless of the current state of the broadphase.
  159. m_data->m_validationBroadphase = b3GpuParallelLinearBvhBroadphase::CreateFunc(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue);
  160. }
  161. createBroadphase(dimensions[0], dimensions[1], dimensions[2]);
  162. }
  163. void PairBench::createBroadphase(int arraySizeX, int arraySizeY, int arraySizeZ)
  164. {
  165. m_data->m_broadphaseGPU = (allBroadphases[curSelectedBroadphase].m_createFunc)(m_clData->m_clContext, m_clData->m_clDevice, m_clData->m_clQueue);
  166. int strideInBytes = 9 * sizeof(float);
  167. int numVertices = sizeof(cube_vertices) / strideInBytes;
  168. int numIndices = sizeof(cube_vertices) / sizeof(int);
  169. int shapeId = m_guiHelper->getRenderInterface()->registerShape(&cube_vertices[0], numVertices, cube_indices, numIndices);
  170. int group = 1;
  171. int mask = 1;
  172. int index = TEST_INDEX_OFFSET;
  173. if (gPairBenchFileName)
  174. {
  175. //char* fileName = "32006GPUAABBs.txt";
  176. char relativeFileName[1024];
  177. const char* prefix[] = {"./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"};
  178. int prefixIndex = -1;
  179. {
  180. int numPrefixes = sizeof(prefix) / sizeof(char*);
  181. for (int i = 0; i < numPrefixes; i++)
  182. {
  183. FILE* f = 0;
  184. sprintf(relativeFileName, "%s%s", prefix[i], gPairBenchFileName);
  185. f = fopen(relativeFileName, "rb");
  186. if (f)
  187. {
  188. fseek(f, 0L, SEEK_END);
  189. int size = ftell(f);
  190. rewind(f);
  191. char* buf = (char*)malloc(size);
  192. int actualReadBytes = 0;
  193. while (actualReadBytes < size)
  194. {
  195. int left = size - actualReadBytes;
  196. int chunk = 8192;
  197. int numPlannedRead = left < chunk ? left : chunk;
  198. actualReadBytes += fread(&buf[actualReadBytes], 1, numPlannedRead, f);
  199. }
  200. fclose(f);
  201. char pattern[1024];
  202. pattern[0] = 0x0a;
  203. pattern[1] = 0;
  204. size_t const patlen = strlen(pattern);
  205. size_t patcnt = 0;
  206. char* oriptr;
  207. char* patloc;
  208. for (oriptr = buf; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
  209. {
  210. if (patloc)
  211. {
  212. *patloc = 0;
  213. const char* token = oriptr;
  214. b3Vector3 aabbMin;
  215. b3Vector3 aabbMax;
  216. aabbMin.x = parseFloat(token);
  217. aabbMin.y = parseFloat(token);
  218. aabbMin.z = parseFloat(token);
  219. aabbMin.w = 0.f;
  220. aabbMax.x = parseFloat(token);
  221. aabbMax.y = parseFloat(token);
  222. aabbMax.z = parseFloat(token);
  223. aabbMax.w = 0.f;
  224. aabbMin *= 0.1;
  225. aabbMax *= 0.1;
  226. b3Vector3 extents = aabbMax - aabbMin;
  227. //printf("%s\n", oriptr);
  228. b3Vector3 position = 0.5 * (aabbMax + aabbMin);
  229. b3Quaternion orn(0, 0, 0, 1);
  230. b3Vector4 scaling = b3MakeVector4(0.5 * extents.x, 0.5 * extents.y, 0.5 * extents.z, 1); //b3MakeVector4(1,1,1,1);
  231. float l = extents.length();
  232. if (l > 500)
  233. {
  234. b3Vector4 color = b3MakeVector4(0, 1, 0, 0.1);
  235. int id;
  236. id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
  237. m_data->m_broadphaseGPU->createLargeProxy(aabbMin, aabbMax, index, group, mask);
  238. }
  239. else
  240. {
  241. b3Vector4 color = b3MakeVector4(1, 0, 0, 1);
  242. int id;
  243. id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
  244. m_data->m_broadphaseGPU->createProxy(aabbMin, aabbMax, index, group, mask);
  245. index++;
  246. }
  247. patcnt++;
  248. }
  249. }
  250. prefixIndex = i;
  251. break;
  252. }
  253. }
  254. if (prefixIndex < 0)
  255. {
  256. b3Printf("Cannot find %s\n", gPairBenchFileName);
  257. }
  258. }
  259. }
  260. else
  261. {
  262. for (int i = 0; i < arraySizeX; i++)
  263. {
  264. for (int j = 0; j < arraySizeY; j++)
  265. {
  266. for (int k = 0; k < arraySizeZ; k++)
  267. {
  268. b3Vector3 position = b3MakeVector3(k * 3, i * 3, j * 3);
  269. b3Quaternion orn(0, 0, 0, 1);
  270. b3Vector4 color = b3MakeVector4(0, 1, 0, 1);
  271. b3Vector4 scaling = b3MakeVector4(1, 1, 1, 1);
  272. bool large = false;
  273. if (curUseLargeAabbOption)
  274. {
  275. if (i == 0 && j == 0 && k == 0)
  276. {
  277. large = true;
  278. scaling[0] = 1000;
  279. scaling[1] = 1000;
  280. scaling[2] = 1000;
  281. }
  282. }
  283. /*if (j==0)
  284. {
  285. large=true;
  286. scaling[1] = 10000;
  287. }
  288. if (k==0)
  289. {
  290. large=true;
  291. scaling[2] = 10000;
  292. }*/
  293. int id;
  294. id = m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling);
  295. b3Vector3 aabbMin = position - scaling;
  296. b3Vector3 aabbMax = position + scaling;
  297. if (large)
  298. {
  299. m_data->m_broadphaseGPU->createLargeProxy(aabbMin, aabbMax, index, group, mask);
  300. }
  301. else
  302. {
  303. m_data->m_broadphaseGPU->createProxy(aabbMin, aabbMax, index, group, mask);
  304. }
  305. index++;
  306. }
  307. }
  308. }
  309. }
  310. m_guiHelper->getRenderInterface()->writeTransforms();
  311. m_data->m_broadphaseGPU->writeAabbsToGpu();
  312. }
  313. void PairBench::deleteBroadphase()
  314. {
  315. delete m_data->m_broadphaseGPU;
  316. m_data->m_broadphaseGPU = 0;
  317. delete m_data->m_instancePosOrnColor;
  318. m_data->m_instancePosOrnColor = 0;
  319. delete m_data->m_bodyTimes;
  320. m_data->m_bodyTimes = 0;
  321. m_data->m_broadphaseGPU = 0;
  322. m_guiHelper->getRenderInterface()->removeAllInstances();
  323. }
  324. void PairBench::exitPhysics()
  325. {
  326. //reset the state to 'on'
  327. useShadowMap = true;
  328. if (m_data->m_validationBroadphase)
  329. {
  330. delete m_data->m_validationBroadphase;
  331. m_data->m_validationBroadphase = 0;
  332. }
  333. sPairDemo = 0;
  334. exitCL();
  335. }
  336. void PairBench::renderScene()
  337. {
  338. m_guiHelper->getRenderInterface()->renderScene();
  339. }
  340. struct OverlappingPairSortPredicate
  341. {
  342. inline bool operator()(const b3Int4& a, const b3Int4& b) const
  343. {
  344. if (a.x != b.x) return (a.x < b.x);
  345. if (a.y != b.y) return (a.y < b.y);
  346. if (a.z != b.z) return (a.z < b.z);
  347. return (a.w < b.w);
  348. }
  349. };
  350. void PairBench::stepSimulation(float deltaTime)
  351. {
  352. //color all objects blue
  353. GLInstanceRendererInternalData* internalData = m_guiHelper->getRenderInterface()->getInternalData();
  354. if (internalData == 0)
  355. return;
  356. //bool animate=true;
  357. int numObjects = 0;
  358. {
  359. B3_PROFILE("Num Objects");
  360. numObjects = internalData->m_totalNumInstances;
  361. }
  362. b3Vector4* positions = 0;
  363. if (numObjects)
  364. {
  365. B3_PROFILE("Sync");
  366. GLuint vbo = internalData->m_vbo;
  367. int arraySizeInBytes = numObjects * (3) * sizeof(b3Vector4);
  368. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  369. // cl_bool blocking= CL_TRUE;
  370. char* hostPtr = 0;
  371. {
  372. B3_PROFILE("glMapBufferRange");
  373. hostPtr = (char*)glMapBufferRange(GL_ARRAY_BUFFER, internalData->m_maxShapeCapacityInBytes, arraySizeInBytes, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT); //GL_READ_WRITE);//GL_WRITE_ONLY
  374. }
  375. GLint err = glGetError();
  376. assert(err == GL_NO_ERROR);
  377. positions = (b3Vector4*)hostPtr;
  378. if (m_data->m_instancePosOrnColor && m_data->m_instancePosOrnColor->size() != 3 * numObjects)
  379. {
  380. delete m_data->m_instancePosOrnColor;
  381. m_data->m_instancePosOrnColor = 0;
  382. }
  383. if (!m_data->m_instancePosOrnColor)
  384. {
  385. m_data->m_instancePosOrnColor = new b3OpenCLArray<b3Vector4>(m_clData->m_clContext, m_clData->m_clQueue);
  386. m_data->m_instancePosOrnColor->resize(3 * numObjects);
  387. m_data->m_instancePosOrnColor->copyFromHostPointer(positions, 3 * numObjects, 0);
  388. m_data->m_bodyTimes = new b3OpenCLArray<float>(m_clData->m_clContext, m_clData->m_clQueue);
  389. m_data->m_bodyTimes->resize(numObjects);
  390. b3AlignedObjectArray<float> tmp;
  391. tmp.resize(numObjects);
  392. for (int i = 0; i < numObjects; i++)
  393. {
  394. tmp[i] = float(i) * (1024.f / numObjects);
  395. }
  396. m_data->m_bodyTimes->copyFromHost(tmp);
  397. }
  398. if (!gPairBenchFileName)
  399. {
  400. if (1)
  401. {
  402. if (1)
  403. {
  404. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_sineWaveKernel, "m_sineWaveKernel");
  405. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
  406. launcher.setBuffer(m_data->m_bodyTimes->getBufferCL());
  407. launcher.setConst(timeStepPos);
  408. launcher.setConst(mAmplitude);
  409. launcher.setConst(numObjects);
  410. launcher.launch1D(numObjects);
  411. clFinish(m_clData->m_clQueue);
  412. }
  413. else
  414. {
  415. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_moveObjectsKernel, "m_moveObjectsKernel");
  416. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
  417. launcher.setConst(numObjects);
  418. launcher.launch1D(numObjects);
  419. clFinish(m_clData->m_clQueue);
  420. }
  421. }
  422. }
  423. }
  424. bool updateOnGpu = true;
  425. if (1)
  426. {
  427. if (updateOnGpu)
  428. {
  429. B3_PROFILE("updateOnGpu");
  430. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_updateAabbSimple, "m_updateAabbSimple");
  431. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
  432. launcher.setConst(numObjects);
  433. launcher.setBuffer(m_data->m_broadphaseGPU->getAabbBufferWS());
  434. launcher.launch1D(numObjects);
  435. clFinish(m_clData->m_clQueue);
  436. }
  437. else
  438. {
  439. B3_PROFILE("updateOnCpu");
  440. if (!gPairBenchFileName)
  441. {
  442. // int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
  443. b3AlignedObjectArray<b3Vector4> posOrnColorsCpu;
  444. if (m_data->m_instancePosOrnColor)
  445. m_data->m_instancePosOrnColor->copyToHost(posOrnColorsCpu);
  446. for (int nodeId = 0; nodeId < numObjects; nodeId++)
  447. {
  448. {
  449. b3Vector3 position = posOrnColorsCpu[nodeId];
  450. b3SapAabb orgAabb = m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId];
  451. b3Vector3 halfExtents = 0.5f * (orgAabb.m_maxVec - orgAabb.m_minVec);
  452. int orgNodeIndex = orgAabb.m_minIndices[3];
  453. int orgBroadphaseIndex = orgAabb.m_signedMaxIndices[3];
  454. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_minVec = position - halfExtents;
  455. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_minIndices[3] = orgNodeIndex;
  456. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_maxVec = position + halfExtents;
  457. m_data->m_broadphaseGPU->getAllAabbsCPU()[nodeId].m_signedMaxIndices[3] = orgBroadphaseIndex;
  458. }
  459. }
  460. m_data->m_broadphaseGPU->writeAabbsToGpu();
  461. }
  462. }
  463. }
  464. int prealloc = 3 * 1024 * 1024;
  465. int maxOverlap = b3Min(prealloc, 16 * numObjects);
  466. unsigned long dt = 0;
  467. if (numObjects)
  468. {
  469. b3Clock cl;
  470. dt = cl.getTimeMicroseconds();
  471. B3_PROFILE("calculateOverlappingPairs");
  472. //int sz = sizeof(b3Int4)*64*numObjects;
  473. m_data->m_broadphaseGPU->calculateOverlappingPairs(maxOverlap);
  474. int numPairs;
  475. numPairs = m_data->m_broadphaseGPU->getNumOverlap();
  476. //printf("numPairs = %d\n", numPairs);
  477. dt = cl.getTimeMicroseconds() - dt;
  478. }
  479. const bool VALIDATE_BROADPHASE = false; //Check that overlapping pairs of 2 broadphases are the same
  480. if (numObjects && VALIDATE_BROADPHASE)
  481. {
  482. B3_PROFILE("validate broadphases");
  483. {
  484. B3_PROFILE("calculateOverlappingPairs m_validationBroadphase");
  485. //m_data->m_validationBroadphase->getAllAabbsCPU() = m_data->m_broadphaseGPU->getAllAabbsCPU();
  486. m_data->m_validationBroadphase->getAllAabbsGPU().copyFromOpenCLArray(m_data->m_broadphaseGPU->getAllAabbsGPU());
  487. m_data->m_validationBroadphase->getSmallAabbIndicesGPU().copyFromOpenCLArray(m_data->m_broadphaseGPU->getSmallAabbIndicesGPU());
  488. m_data->m_validationBroadphase->getLargeAabbIndicesGPU().copyFromOpenCLArray(m_data->m_broadphaseGPU->getLargeAabbIndicesGPU());
  489. m_data->m_validationBroadphase->calculateOverlappingPairs(maxOverlap);
  490. }
  491. static b3AlignedObjectArray<b3Int4> overlappingPairs;
  492. static b3AlignedObjectArray<b3Int4> overlappingPairsReference;
  493. m_data->m_broadphaseGPU->getOverlappingPairsGPU().copyToHost(overlappingPairs);
  494. m_data->m_validationBroadphase->getOverlappingPairsGPU().copyToHost(overlappingPairsReference);
  495. //Reorder pairs so that (pair.x < pair.y) is always true
  496. {
  497. B3_PROFILE("reorder pairs");
  498. for (int i = 0; i < overlappingPairs.size(); ++i)
  499. {
  500. b3Int4 pair = overlappingPairs[i];
  501. if (pair.x > pair.y)
  502. {
  503. b3Swap(pair.x, pair.y);
  504. b3Swap(pair.z, pair.w);
  505. overlappingPairs[i] = pair;
  506. }
  507. }
  508. for (int i = 0; i < overlappingPairsReference.size(); ++i)
  509. {
  510. b3Int4 pair = overlappingPairsReference[i];
  511. if (pair.x > pair.y)
  512. {
  513. b3Swap(pair.x, pair.y);
  514. b3Swap(pair.z, pair.w);
  515. overlappingPairsReference[i] = pair;
  516. }
  517. }
  518. }
  519. //
  520. {
  521. B3_PROFILE("Sort overlapping pairs from most to least significant bit");
  522. overlappingPairs.quickSort(OverlappingPairSortPredicate());
  523. overlappingPairsReference.quickSort(OverlappingPairSortPredicate());
  524. }
  525. //Compare
  526. {
  527. B3_PROFILE("compare pairs");
  528. int numPairs = overlappingPairs.size();
  529. int numPairsReference = overlappingPairsReference.size();
  530. bool success = true;
  531. if (numPairs == numPairsReference)
  532. {
  533. for (int i = 0; i < numPairsReference; ++i)
  534. {
  535. const b3Int4& pairA = overlappingPairs[i];
  536. const b3Int4& pairB = overlappingPairsReference[i];
  537. if (pairA.x != pairB.x || pairA.y != pairB.y || pairA.z != pairB.z || pairA.w != pairB.w)
  538. {
  539. b3Error("Error: one or more overlappingPairs differs from reference.\n");
  540. success = false;
  541. break;
  542. }
  543. }
  544. }
  545. else
  546. {
  547. b3Error("Error: numPairs %d != numPairsReference %d \n", numPairs, numPairsReference);
  548. success = false;
  549. }
  550. printf("Broadphase validation: %d \n", success);
  551. }
  552. }
  553. /*
  554. if (m_data->m_gui)
  555. {
  556. B3_PROFILE("update Gui");
  557. int allAabbs = m_data->m_broadphaseGPU->getAllAabbsCPU().size();
  558. int numOverlap = m_data->m_broadphaseGPU->getNumOverlap();
  559. float time = dt/1000.f;
  560. //printf("time = %f\n", time);
  561. char msg[1024];
  562. sprintf(msg,"#objects = %d, #overlapping pairs = %d, time = %f ms", allAabbs,numOverlap,time );
  563. //printf("msg=%s\n",msg);
  564. m_data->m_gui->setStatusBarMessage(msg,true);
  565. }
  566. */
  567. if (numObjects)
  568. {
  569. B3_PROFILE("animate");
  570. GLint err = glGetError();
  571. assert(err == GL_NO_ERROR);
  572. //color overlapping objects in red
  573. if (m_data->m_broadphaseGPU->getNumOverlap())
  574. {
  575. bool colorPairsOnHost = false;
  576. if (colorPairsOnHost)
  577. {
  578. }
  579. else
  580. {
  581. int numPairs = m_data->m_broadphaseGPU->getNumOverlap();
  582. cl_mem pairBuf = m_data->m_broadphaseGPU->getOverlappingPairBuffer();
  583. b3LauncherCL launcher(m_clData->m_clQueue, m_data->m_colorPairsKernel, "m_colorPairsKernel");
  584. launcher.setBuffer(m_data->m_instancePosOrnColor->getBufferCL());
  585. launcher.setConst(numObjects);
  586. launcher.setBuffer(pairBuf);
  587. int indexOffset = TEST_INDEX_OFFSET;
  588. launcher.setConst(indexOffset);
  589. launcher.setConst(numPairs);
  590. launcher.launch1D(numPairs);
  591. clFinish(m_clData->m_clQueue);
  592. }
  593. }
  594. if (numObjects)
  595. {
  596. m_data->m_instancePosOrnColor->copyToHostPointer(positions, 3 * numObjects, 0);
  597. }
  598. glUnmapBuffer(GL_ARRAY_BUFFER);
  599. err = glGetError();
  600. assert(err == GL_NO_ERROR);
  601. }
  602. }
  603. class CommonExampleInterface* PairBenchOpenCLCreateFunc(struct CommonExampleOptions& options)
  604. {
  605. return new PairBench(options.m_guiHelper);
  606. }