/**Generates hit data for viewing rays, from the constructed BVH * @param err Error info * @return Result of the operation: Success or failure */ Result BVHManager::generateContacts(Camera& cam,Errata& err) { //Uploading camera state to GPU _deviceCamera.reset(new CLBuffer(_context,sizeof(struct Camera),&cam,CLBufferFlags::ReadOnly)); //Allocating memory for primary contacts size_t contactBufSize = cam.resX * cam.resY * sizeof(struct Contact); if (_primaryContactsArray) _primaryContactsArray->resize(contactBufSize); else _primaryContactsArray.reset(new CLBuffer(_context,contactBufSize,CLBufferFlags::ReadWrite)); //Getting the launch parameters size_t processors, warp; if (Success != _context.getMaximalLaunchExecParams(*_contactGenerateKernel,processors,warp,err)) return Error; //Setting kernel args try { SET_KERNEL_ARGS((*_contactGenerateKernel),_deviceCamera->getCLMem(),_bvhNodes->getCLMem(),_bvhLeavesCount,_scene.getDeviceSceneData(),_primaryContactsArray->getCLMem()); } catch (CLInterfaceException e) { err = Errata(e); return Error; } CLEvent evt; evt.reset(); cl_uint totalWorkItems = closestMultipleTo(cam.resX * cam.resY,warp); CLKernelWorkDimension globalDim(1,totalWorkItems); CLKernelWorkDimension localDim(1,warp); CLKernelExecuteParams contactsKernelExecParams(&globalDim,&localDim,&evt); //Execute kernel if (Success != _context.enqueueKernel((*_contactGenerateKernel),contactsKernelExecParams,err)) return Error; //Flush and make sure that calculation is over before returning control if (Success != _context.flushQueue(err)) return Error; if (Success != evt.wait(err)) return Error; return Success; }
/**Generates contacts for rays and fills the contacts array * @param rays The rays to be traced - A device memory buffer object that contains rays as struct Ray * @param contact The target device memory that will contain the result - For each ray rays[i] the buffer will contain * data about its closest intersection with object in the scene as contacts[i]. The contact data will be stored * as struct Contact * @param rayCount The number of rays to trace * @param err Error info * @return Result of the operation: Success or failure */ Result BVHManager::generateContacts(OpenCLUtils::CLBuffer& rays,OpenCLUtils::CLBuffer& contacts, const unsigned int rayCount, Common::Errata& err) { //Setting kernel args try { SET_KERNEL_ARGS((*_contactGenerateKernel2),rays.getCLMem(),rayCount,_bvhNodes->getCLMem(),_bvhLeavesCount,_scene.getDeviceSceneData(),contacts.getCLMem()); } catch (CLInterfaceException e) { err = Errata(e); return Error; } //Getting the launch parameters size_t processors, warp; if (Success != _context.getMaximalLaunchExecParams(*_contactGenerateKernel2,processors,warp,err)) return Error; CLEvent evt; evt.reset(); cl_uint totalWorkItems = closestMultipleTo(rayCount,warp); CLKernelWorkDimension globalDim(1,totalWorkItems); CLKernelWorkDimension localDim(1,warp); CLKernelExecuteParams contactsKernelExecParams(&globalDim,&localDim,&evt); //Execute kernel if (Success != _context.enqueueKernel((*_contactGenerateKernel2),contactsKernelExecParams,err)) return Error; //Flush and make sure that calculation is over before returning control if (Success != _context.flushQueue(err)) return Error; if (Success != evt.wait(err)) return Error; return Success; }
/**Constructs BVH acceleration structure, according to associated scene state * @param err Error info * @return Result of the operation: Success or failure */ Result BVHManager::construct(Common::Errata& err) { try { SET_KERNEL_ARGS((*_mortonCalcKernel),_bvhNodes->getCLMem(),_sortedMortonCodes->getCLMem(),_scene.getDeviceSceneData()); SET_KERNEL_ARGS((*_radixTreeBuildKernel),_bvhNodes->getCLMem(),_sortedMortonCodes->getCLMem(),_bvhLeavesCount); SET_KERNEL_ARGS((*_bbCalcKernel),_bvhNodes->getCLMem(),_nodeVisitCounters->getCLMem(), _bvhLeavesCount); } catch (CLInterfaceException e) { err = Errata(e); return Error; } CLEvent evt; evt.reset(); size_t processors, warp; if (Success != _context.getMaximalLaunchExecParams(*_mortonCalcKernel,processors,warp,err)) return Error; CL_UINT worksize = closestMultipleTo(_bvhLeavesCount,warp); CLKernelWorkDimension globalDim(1,worksize); CLKernelWorkDimension localDim(1,warp); CLKernelExecuteParams mortonKernelExecParams(&globalDim,&localDim,&evt); //1. Morton Codes //Execute kernel if (Success != _context.enqueueKernel((*_mortonCalcKernel),mortonKernelExecParams,err)) return Error; //Flush and make sure that calculation is over before returning control if (Success != _context.flushQueue(err)) return Error; if (Success != evt.wait(err)) return Error; //2.Sort the leaves by Morton Codes if (Success != _bitonicSorter->sort(_sortedMortonCodes->getCLMem(),_mortonBufferItems,err)) return Error; //3. Build Radix Tree worksize = closestMultipleTo(_bvhLeavesCount-1,warp); CLKernelWorkDimension globalDim_Radix(1,worksize); CLKernelWorkDimension localDim_Radix(1,warp); CLKernelExecuteParams radixKernelExecParams(&globalDim_Radix,&localDim_Radix,&evt); //Execute kernel if (Success != _context.enqueueKernel((*_radixTreeBuildKernel),radixKernelExecParams,err)) return Error; //Flush and make sure that calculation is over before returning control if (Success != _context.flushQueue(err)) return Error; if (Success != evt.wait(err)) return Error; worksize = closestMultipleTo(_bvhLeavesCount,warp); CLKernelExecuteParams boundingBoxKernelExecParams(new CLKernelWorkDimension(1,worksize),new CLKernelWorkDimension(1,warp,&evt)); //Execute kernel if (Success != _context.enqueueKernel((*_bbCalcKernel),boundingBoxKernelExecParams,err)) return Error; //Flush and make sure that calculation is over before returning control if (Success != _context.flushQueue(err)) return Error; if (Success != evt.wait(err)) return Error; return Success; }