//-------------------------------------------------------------------------------------- // Name: Initialize() // Desc: Initialize the OpenCL implementation of the cloth simulation //-------------------------------------------------------------------------------------- BOOL CClothSimCL::Initialize( cl_context context, cl_device_id device ) { // Call the base class first if( !CClothSim::Initialize() ) return FALSE; // Generate VBO for previous position glGenBuffers( 1, &m_hPrevPositionVBO ); glBindBuffer( GL_ARRAY_BUFFER, m_hPrevPositionVBO ); glBufferData( GL_ARRAY_BUFFER, m_uiNumVerts * 4 * sizeof(float), NULL, GL_DYNAMIC_DRAW ); glBufferSubData( GL_ARRAY_BUFFER, 0, m_uiNumVerts * 4 * sizeof(float), m_pVerts ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); if( !InitKernels( context, device ) ) return FALSE; // Create OpenCL memory objects for the VBOs UINT32 vbos[NUM_VBOS] = { m_hPositionVBO, m_hPrevPositionVBO, m_hNormalVBO, m_hTangentVBO, m_hBitangentVBO, m_hTextureVBO, m_hBackNormalVBO, m_hBackTangentVBO, m_hBackBitangentVBO }; cl_int errNum = 0; for( INT32 i = 0; i < NUM_VBOS; i++ ) { m_vboMem[i] = clCreateFromGLBuffer( context, CL_MEM_READ_WRITE, vbos[i], &errNum ); if( errNum != CL_SUCCESS ) { FrmLogMessage( "Error creating OpenCL memory object from GL VBO." ); return FALSE; } } // Initialize the base distances memory object if( !InitConstraintsBaseDists( context ) ) return FALSE; m_vertsCopyMem = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(cl_float4) * m_uiNumVerts, NULL, &errNum); if( errNum != CL_SUCCESS ) { FrmLogMessage( "Error creating OpenCL memory object." ); return FALSE; } return TRUE; }
result MultiFrame::Init( const int &device_id, const int &temporal_radius, const int &width, const int &height, const int &src_pitch, const int &dst_pitch, const float &h, const int &sample_expand, const int &linear, const int &correction, const int &balanced) { if (device_id >= g_device_count) return FILTER_ERROR; result status = FILTER_OK; device_id_ = device_id; temporal_radius_ = temporal_radius; width_ = width; height_ = height; src_pitch_ = src_pitch; dst_pitch_ = dst_pitch; region_width_ = width; region_height_ = 8; h_ = 1.f/h; cq_ = g_devices[device_id_].cq(); if (width_ == 0 || height_ == 0 || src_pitch_ == 0 || dst_pitch_ == 0 || h == 0 ) return FILTER_INVALID_PARAMETER; alpha_set_size_ = GetAlphaSetSize(temporal_radius, sample_expand); status = InitBuffers(sample_expand); if (status != FILTER_OK) return status; status = InitKernels(sample_expand, linear, correction, balanced); if (status != FILTER_OK) return status; status = InitFrames(); return status; }
void PathOCLRenderThread::InitRender() { Scene *scene = renderEngine->renderConfig->scene; cl::Context &oclContext = intersectionDevice->GetOpenCLContext(); cl::Device &oclDevice = intersectionDevice->GetOpenCLDevice(); const OpenCLDeviceDescription *deviceDesc = intersectionDevice->GetDeviceDesc(); double tStart, tEnd; //-------------------------------------------------------------------------- // FrameBuffer definition //-------------------------------------------------------------------------- InitFrameBuffer(); //-------------------------------------------------------------------------- // Camera definition //-------------------------------------------------------------------------- InitCamera(); //-------------------------------------------------------------------------- // Scene geometry //-------------------------------------------------------------------------- InitGeometry(); //-------------------------------------------------------------------------- // Translate material definitions //-------------------------------------------------------------------------- InitMaterials(); //-------------------------------------------------------------------------- // Translate area lights //-------------------------------------------------------------------------- InitAreaLights(); //-------------------------------------------------------------------------- // Check if there is an infinite light source //-------------------------------------------------------------------------- InitInfiniteLight(); //-------------------------------------------------------------------------- // Check if there is an sun light source //-------------------------------------------------------------------------- InitSunLight(); //-------------------------------------------------------------------------- // Check if there is an sky light source //-------------------------------------------------------------------------- InitSkyLight(); const unsigned int areaLightCount = renderEngine->compiledScene->areaLights.size(); if (!skyLightBuff && !sunLightBuff && !infiniteLightBuff && (areaLightCount == 0)) throw runtime_error("There are no light sources supported by PathOCL in the scene"); //-------------------------------------------------------------------------- // Translate mesh texture maps //-------------------------------------------------------------------------- InitTextureMaps(); //-------------------------------------------------------------------------- // Allocate Ray/RayHit buffers //-------------------------------------------------------------------------- const unsigned int taskCount = renderEngine->taskCount; tStart = WallClockTime(); LM_LOG_ENGINE("[PathOCLRenderThread::" << threadIndex << "] Ray buffer size: " << (sizeof(Ray) * taskCount / 1024) << "Kbytes"); raysBuff = new cl::Buffer(oclContext, CL_MEM_READ_WRITE, sizeof(Ray) * taskCount); deviceDesc->AllocMemory(raysBuff->getInfo<CL_MEM_SIZE>()); LM_LOG_ENGINE("[PathOCLRenderThread::" << threadIndex << "] RayHit buffer size: " << (sizeof(RayHit) * taskCount / 1024) << "Kbytes"); hitsBuff = new cl::Buffer(oclContext, CL_MEM_READ_WRITE, sizeof(RayHit) * taskCount); deviceDesc->AllocMemory(hitsBuff->getInfo<CL_MEM_SIZE>()); tEnd = WallClockTime(); LM_LOG_ENGINE("[PathOCLRenderThread::" << threadIndex << "] OpenCL buffer creation time: " << int((tEnd - tStart) * 1000.0) << "ms"); //-------------------------------------------------------------------------- // Allocate GPU task buffers //-------------------------------------------------------------------------- // TODO: clenup all this mess const size_t gpuTaksSizePart1 = // Seed size sizeof(PathOCL::Seed); const size_t uDataEyePathVertexSize = // IDX_SCREEN_X, IDX_SCREEN_Y sizeof(float) * 2 + // IDX_DOF_X, IDX_DOF_Y ((scene->camera->lensRadius > 0.f) ? (sizeof(float) * 2) : 0); const size_t uDataPerPathVertexSize = // IDX_TEX_ALPHA, ((texMapAlphaBuff) ? sizeof(float) : 0) + // IDX_BSDF_X, IDX_BSDF_Y, IDX_BSDF_Z sizeof(float) * 3 + // IDX_DIRECTLIGHT_X, IDX_DIRECTLIGHT_Y, IDX_DIRECTLIGHT_Z (((areaLightCount > 0) || sunLightBuff) ? (sizeof(float) * 3) : 0) + // IDX_RR sizeof(float); const size_t uDataSize = (renderEngine->sampler->type == PathOCL::INLINED_RANDOM) ? // Only IDX_SCREEN_X, IDX_SCREEN_Y (sizeof(float) * 2) : ((renderEngine->sampler->type == PathOCL::METROPOLIS) ? (sizeof(float) * 2 + sizeof(unsigned int) * 5 + sizeof(Spectrum) + 2 * (uDataEyePathVertexSize + uDataPerPathVertexSize * renderEngine->maxPathDepth)) : (uDataEyePathVertexSize + uDataPerPathVertexSize * renderEngine->maxPathDepth)); size_t sampleSize = // uint pixelIndex; ((renderEngine->sampler->type == PathOCL::METROPOLIS) ? 0 : sizeof(unsigned int)) + uDataSize + // Spectrum radiance; sizeof(Spectrum); stratifiedDataSize = 0; if (renderEngine->sampler->type == PathOCL::STRATIFIED) { PathOCL::StratifiedSampler *s = (PathOCL::StratifiedSampler *)renderEngine->sampler; stratifiedDataSize = // stratifiedScreen2D sizeof(float) * s->xSamples * s->ySamples * 2 + // stratifiedDof2D ((scene->camera->lensRadius > 0.f) ? (sizeof(float) * s->xSamples * s->ySamples * 2) : 0) + // stratifiedAlpha1D ((texMapAlphaBuff) ? (sizeof(float) * s->xSamples) : 0) + // stratifiedBSDF2D sizeof(float) * s->xSamples * s->ySamples * 2 + // stratifiedBSDF1D sizeof(float) * s->xSamples + // stratifiedLight2D // stratifiedLight1D (((areaLightCount > 0) || sunLightBuff) ? (sizeof(float) * s->xSamples * s->ySamples * 2 + sizeof(float) * s->xSamples) : 0); sampleSize += stratifiedDataSize; } const size_t gpuTaksSizePart2 = sampleSize; const size_t gpuTaksSizePart3 = // PathState size ((((areaLightCount > 0) || sunLightBuff) ? sizeof(PathOCL::PathStateDL) : sizeof(PathOCL::PathState)) + //unsigned int diffuseVertexCount; ((renderEngine->maxDiffusePathVertexCount < renderEngine->maxPathDepth) ? sizeof(unsigned int) : 0)); const size_t gpuTaksSize = gpuTaksSizePart1 + gpuTaksSizePart2 + gpuTaksSizePart3; LM_LOG_ENGINE("[PathOCLRenderThread::" << threadIndex << "] Size of a GPUTask: " << gpuTaksSize << "bytes (" << gpuTaksSizePart1 << " + " << gpuTaksSizePart2 << " + " << gpuTaksSizePart3 << ")"); LM_LOG_ENGINE("[PathOCLRenderThread::" << threadIndex << "] Tasks buffer size: " << (gpuTaksSize * taskCount / 1024) << "Kbytes"); // Check if the task buffer is too big if (oclDevice.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>() < gpuTaksSize * taskCount) { stringstream ss; ss << "The GPUTask buffer is too big for this device (i.e. CL_DEVICE_MAX_MEM_ALLOC_SIZE=" << oclDevice.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>() << "): try to reduce opencl.task.count and/or path.maxdepth and/or to change Sampler"; throw std::runtime_error(ss.str()); } tasksBuff = new cl::Buffer(oclContext, CL_MEM_READ_WRITE, gpuTaksSize * taskCount); deviceDesc->AllocMemory(tasksBuff->getInfo<CL_MEM_SIZE>()); //-------------------------------------------------------------------------- // Allocate GPU task statistic buffers //-------------------------------------------------------------------------- LM_LOG_ENGINE("[PathOCLRenderThread::" << threadIndex << "] Task Stats buffer size: " << (sizeof(PathOCL::GPUTaskStats) * taskCount / 1024) << "Kbytes"); taskStatsBuff = new cl::Buffer(oclContext, CL_MEM_READ_WRITE, sizeof(PathOCL::GPUTaskStats) * taskCount); deviceDesc->AllocMemory(taskStatsBuff->getInfo<CL_MEM_SIZE>()); //-------------------------------------------------------------------------- // Compile kernels //-------------------------------------------------------------------------- InitKernels(); //-------------------------------------------------------------------------- // Initialize //-------------------------------------------------------------------------- // Set kernel arguments SetKernelArgs(); cl::CommandQueue &oclQueue = intersectionDevice->GetOpenCLQueue(); // Clear the frame buffer oclQueue.enqueueNDRangeKernel(*initFBKernel, cl::NullRange, cl::NDRange(RoundUp<unsigned int>(frameBufferPixelCount, initFBWorkGroupSize)), cl::NDRange(initFBWorkGroupSize)); // Initialize the tasks buffer oclQueue.enqueueNDRangeKernel(*initKernel, cl::NullRange, cl::NDRange(taskCount), cl::NDRange(initWorkGroupSize)); oclQueue.finish(); // Reset statistics in order to be more accurate intersectionDevice->ResetPerformaceStats(); }
void PathOCLRenderThread::EndEdit(const EditActionList &editActions) { //-------------------------------------------------------------------------- // Update OpenCL buffers //-------------------------------------------------------------------------- if (editActions.Has(FILM_EDIT)) { // Resize the Framebuffer InitFrameBuffer(); } if (editActions.Has(CAMERA_EDIT)) { // Update Camera InitCamera(); } if (editActions.Has(GEOMETRY_EDIT)) { // Update Scene Geometry InitGeometry(); } if (editActions.Has(MATERIALS_EDIT) || editActions.Has(MATERIAL_TYPES_EDIT)) { // Update Scene Materials InitMaterials(); } if (editActions.Has(AREALIGHTS_EDIT)) { // Update Scene Area Lights InitAreaLights(); } if (editActions.Has(INFINITELIGHT_EDIT)) { // Update Scene Infinite Light InitInfiniteLight(); } if (editActions.Has(SUNLIGHT_EDIT)) { // Update Scene Sun Light InitSunLight(); } if (editActions.Has(SKYLIGHT_EDIT)) { // Update Scene Sun Light InitSkyLight(); } //-------------------------------------------------------------------------- // Recompile Kernels if required //-------------------------------------------------------------------------- if (editActions.Has(FILM_EDIT) || editActions.Has(MATERIAL_TYPES_EDIT)) InitKernels(); if (editActions.Size() > 0) SetKernelArgs(); //-------------------------------------------------------------------------- // Execute initialization kernels //-------------------------------------------------------------------------- if (editActions.Size() > 0) { cl::CommandQueue &oclQueue = intersectionDevice->GetOpenCLQueue(); // Clear the frame buffer oclQueue.enqueueNDRangeKernel(*initFBKernel, cl::NullRange, cl::NDRange(RoundUp<unsigned int>(frameBufferPixelCount, initFBWorkGroupSize)), cl::NDRange(initFBWorkGroupSize)); // Initialize the tasks buffer oclQueue.enqueueNDRangeKernel(*initKernel, cl::NullRange, cl::NDRange(renderEngine->taskCount), cl::NDRange(initWorkGroupSize)); } // Reset statistics in order to be more accurate intersectionDevice->ResetPerformaceStats(); StartRenderThread(); }