void PathOCLRenderThread::InitMaterials() { const size_t materialsCount = renderEngine->compiledScene->mats.size(); AllocOCLBufferRO(&materialsBuff, &renderEngine->compiledScene->mats[0], sizeof(PathOCL::Material) * materialsCount, "Materials"); const unsigned int meshCount = renderEngine->compiledScene->meshMats.size(); AllocOCLBufferRO(&meshMatsBuff, &renderEngine->compiledScene->meshMats[0], sizeof(unsigned int) * meshCount, "Mesh material index"); }
void OCLRendererThread::UpdateMaterialsBuffer() { const CompiledScene &compiledScene(*(renderer->compiledScene)); if (compiledScene.editActionsUsed.Has(MATERIALS_EDIT)) { AllocOCLBufferRO(&matBuffer, (void *)(&compiledScene.mats[0]), sizeof(compiledscene::Material) * compiledScene.mats.size(), "Materials"); AllocOCLBufferRO(&matIndexBuffer, (void *)(&compiledScene.sphereMats[0]), sizeof(unsigned int) * compiledScene.sphereMats.size(), "Material Indices"); kernelPathTracing->setArg(5, *matBuffer); kernelPathTracing->setArg(6, *matIndexBuffer); } }
void PathOCLRenderThread::InitInfiniteLight() { CompiledScene *cscene = renderEngine->compiledScene; if (cscene->infiniteLight) { AllocOCLBufferRO(&infiniteLightBuff, cscene->infiniteLight, sizeof(PathOCL::InfiniteLight), "InfiniteLight"); const unsigned int pixelCount = cscene->infiniteLight->width * cscene->infiniteLight->height; AllocOCLBufferRO(&infiniteLightMapBuff, (void *)cscene->infiniteLightMap, sizeof(Spectrum) * pixelCount, "InfiniteLight map"); } else { infiniteLightBuff = NULL; infiniteLightMapBuff = NULL; } }
void AllocateBuffers() { // Allocate the pixels buffer const unsigned int pixelCount = windowWidth * windowHeight; AllocOCLBufferWO(0, &pixelsBuff, pixelCount * sizeof(PixelRGBA8888), "PixelsBuffer"); // Allocate the scene buffer AllocOCLBufferRO(0, &sceneBuff, scene, sizeof(Scene), "SceneBuffer"); }
void PathOCLRenderThread::InitSkyLight() { CompiledScene *cscene = renderEngine->compiledScene; if (cscene->skyLight) AllocOCLBufferRO(&skyLightBuff, cscene->skyLight, sizeof(PathOCL::SkyLight), "SkyLight"); else skyLightBuff = NULL; }
void PathOCLRenderThread::InitAreaLights() { CompiledScene *cscene = renderEngine->compiledScene; if (cscene->areaLights.size() > 0) { AllocOCLBufferRO(&areaLightsBuff, &cscene->areaLights[0], sizeof(PathOCL::TriangleLight) * cscene->areaLights.size(), "AreaLights"); } else areaLightsBuff = NULL; }
void OCLRendererThread::UpdateBVHBuffer() { const CompiledScene &compiledScene(*(renderer->compiledScene)); size_t bvhBufferSize = compiledScene.accel->nNodes * sizeof(BVHAccelArrayNode); if (!bvhBuffer || (bvhBuffer->getInfo<CL_MEM_SIZE>() < bvhBufferSize)) { AllocOCLBufferRO(&bvhBuffer, compiledScene.accel->bvhTree, bvhBufferSize, "BVH"); kernelPathTracing->setArg(1, *bvhBuffer); } else if (compiledScene.editActionsUsed.Has(GEOMETRY_EDIT)) { // Upload the new BVH to the GPU cmdQueue->enqueueWriteBuffer(*bvhBuffer, CL_FALSE, 0, bvhBufferSize, compiledScene.accel->bvhTree); } }
void PathOCLRenderThread::InitTextureMaps() { CompiledScene *cscene = renderEngine->compiledScene; if ((cscene->totRGBTexMem > 0) || (cscene->totAlphaTexMem > 0)) { if (cscene->totRGBTexMem > 0) AllocOCLBufferRO(&texMapRGBBuff, cscene->rgbTexMem, sizeof(Spectrum) * cscene->totRGBTexMem, "TexMaps"); else texMapRGBBuff = NULL; if (cscene->totAlphaTexMem > 0) AllocOCLBufferRO(&texMapAlphaBuff, cscene->alphaTexMem, sizeof(float) * cscene->totAlphaTexMem, "TexMaps Alpha Channel"); else texMapAlphaBuff = NULL; AllocOCLBufferRO(&texMapDescBuff, &cscene->gpuTexMaps[0], sizeof(PathOCL::TexMap) * cscene->gpuTexMaps.size(), "TexMaps description"); const unsigned int meshCount = renderEngine->compiledScene->meshMats.size(); AllocOCLBufferRO(&meshTexsBuff, cscene->meshTexs, sizeof(unsigned int) * meshCount, "Mesh TexMaps index"); if (cscene->meshBumps) { AllocOCLBufferRO(&meshBumpsBuff, cscene->meshBumps, sizeof(unsigned int) * meshCount, "Mesh BumpMaps index"); AllocOCLBufferRO(&meshBumpsScaleBuff, cscene->bumpMapScales, sizeof(float) * meshCount, "Mesh BumpMaps scales"); } else { meshBumpsBuff = NULL; meshBumpsScaleBuff = NULL; } if (cscene->meshNormalMaps) AllocOCLBufferRO(&meshNormalMapsBuff, cscene->meshNormalMaps, sizeof(unsigned int) * meshCount, "Mesh NormalMaps index"); else meshNormalMapsBuff = NULL; } else { texMapRGBBuff = NULL; texMapAlphaBuff = NULL; texMapDescBuff = NULL; meshTexsBuff = NULL; meshBumpsBuff = NULL; meshBumpsScaleBuff = NULL; meshNormalMapsBuff = NULL; } }
void PathOCLRenderThread::InitGeometry() { Scene *scene = renderEngine->renderConfig->scene; CompiledScene *cscene = renderEngine->compiledScene; const unsigned int trianglesCount = scene->dataSet->GetTotalTriangleCount(); AllocOCLBufferRO(&meshIDBuff, (void *)cscene->meshIDs, sizeof(unsigned int) * trianglesCount, "MeshIDs"); AllocOCLBufferRO(&normalsBuff, &cscene->normals[0], sizeof(Normal) * cscene->normals.size(), "Normals"); if (cscene->uvs.size() > 0) AllocOCLBufferRO(&uvsBuff, &cscene->uvs[0], sizeof(UV) * cscene->uvs.size(), "UVs"); else uvsBuff = NULL; AllocOCLBufferRO(&vertsBuff, &cscene->verts[0], sizeof(Point) * cscene->verts.size(), "Vertices"); AllocOCLBufferRO(&trianglesBuff, &cscene->tris[0], sizeof(Triangle) * cscene->tris.size(), "Triangles"); // Check the used accelerator type if (scene->dataSet->GetAcceleratorType() == ACCEL_MQBVH) { // MQBVH geometry must be defined in a specific way. AllocOCLBufferRO(&triangleIDBuff, (void *)cscene->meshFirstTriangleOffset, sizeof(unsigned int) * cscene->meshDescs.size(), "First mesh triangle offset"); AllocOCLBufferRO(&meshDescsBuff, &cscene->meshDescs[0], sizeof(PathOCL::Mesh) * cscene->meshDescs.size(), "Mesh description"); } else { triangleIDBuff = NULL; meshDescsBuff = NULL; } }
void PathOCLRenderThread::InitCamera() { AllocOCLBufferRO(&cameraBuff, &renderEngine->compiledScene->camera, sizeof(PathOCL::Camera), "Camera"); }
OCLRendererThread::OCLRendererThread(const size_t threadIndex, OCLRenderer *renderer, cl::Device device) : index(threadIndex), renderer(renderer), dev(device), usedDeviceMemory(0) { const GameLevel &gameLevel(*(renderer->gameLevel)); const unsigned int width = gameLevel.gameConfig->GetScreenWidth(); const unsigned int height = gameLevel.gameConfig->GetScreenHeight(); const CompiledScene &compiledScene(*(renderer->compiledScene)); if (renderer->renderThread.size() > 1) cpuFrameBuffer = new FrameBuffer(width, height); else cpuFrameBuffer = NULL; //-------------------------------------------------------------------------- // OpenCL setup //-------------------------------------------------------------------------- // Allocate a context with the selected device VECTOR_CLASS<cl::Device> devices; devices.push_back(dev); cl::Platform platform = dev.getInfo<CL_DEVICE_PLATFORM>(); // The first thread uses OpenCL/OpenGL interoperability if (index == 0) { #if defined (__APPLE__) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties cps[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; #else #ifdef WIN32 cl_context_properties cps[] = { CL_GL_CONTEXT_KHR, (intptr_t)wglGetCurrentContext(), CL_WGL_HDC_KHR, (intptr_t)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform(), 0 }; #else cl_context_properties cps[] = { CL_GL_CONTEXT_KHR, (intptr_t)glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (intptr_t)glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform(), 0 }; #endif #endif ctx = new cl::Context(devices, cps); } else ctx = new cl::Context(devices); // Allocate the queue for this device cmdQueue = new cl::CommandQueue(*ctx, dev); //-------------------------------------------------------------------------- // Allocate the buffers //-------------------------------------------------------------------------- passFrameBuffer = NULL; tmpFrameBuffer = NULL; frameBuffer = NULL; toneMapFrameBuffer = NULL; bvhBuffer = NULL; gpuTaskBuffer = NULL; cameraBuffer = NULL; infiniteLightBuffer = NULL; matBuffer = NULL; matIndexBuffer = NULL; texMapBuffer = NULL; texMapRGBBuffer = NULL; texMapInstanceBuffer = NULL; bumpMapInstanceBuffer = NULL; AllocOCLBufferRW(&passFrameBuffer, sizeof(Pixel) * width * height, "Pass FrameBuffer"); AllocOCLBufferRW(&tmpFrameBuffer, sizeof(Pixel) * width * height, "Temporary FrameBuffer"); if (index == 0) { AllocOCLBufferRW(&frameBuffer, sizeof(Pixel) * width * height, "FrameBuffer"); AllocOCLBufferRW(&toneMapFrameBuffer, sizeof(Pixel) * width * height, "ToneMap FrameBuffer"); } AllocOCLBufferRW(&gpuTaskBuffer, sizeof(ocl_kernels::GPUTask) * width * height, "GPUTask"); AllocOCLBufferRO(&cameraBuffer, sizeof(compiledscene::Camera), "Camera"); AllocOCLBufferRO(&infiniteLightBuffer, (void *)(gameLevel.scene->infiniteLight->GetTexture()->GetTexMap()->GetPixels()), sizeof(Spectrum) * gameLevel.scene->infiniteLight->GetTexture()->GetTexMap()->GetWidth() * gameLevel.scene->infiniteLight->GetTexture()->GetTexMap()->GetHeight(), "Inifinite Light"); AllocOCLBufferRO(&matBuffer, (void *)(&compiledScene.mats[0]), sizeof(compiledscene::Material) * compiledScene.mats.size(), "Materials"); AllocOCLBufferRO(&matIndexBuffer, (void *)(&compiledScene.sphereMats[0]), sizeof(unsigned int) * compiledScene.sphereMats.size(), "Material Indices"); if (compiledScene.texMaps.size() > 0) { AllocOCLBufferRO(&texMapBuffer, (void *)(&compiledScene.texMaps[0]), sizeof(compiledscene::TexMap) * compiledScene.texMaps.size(), "Texture Maps"); AllocOCLBufferRO(&texMapRGBBuffer, (void *)(compiledScene.rgbTexMem), sizeof(Spectrum) * compiledScene.totRGBTexMem, "Texture Map Images"); AllocOCLBufferRO(&texMapInstanceBuffer, (void *)(&compiledScene.sphereTexs[0]), sizeof(compiledscene::TexMapInstance) * compiledScene.sphereTexs.size(), "Texture Map Instances"); if (compiledScene.sphereBumps.size() > 0) AllocOCLBufferRO(&bumpMapInstanceBuffer, (void *)(&compiledScene.sphereBumps[0]), sizeof(compiledscene::BumpMapInstance) * compiledScene.sphereBumps.size(), "Bump Map Instances"); } SFERA_LOG("[OCLRenderer] Total OpenCL device memory used: " << fixed << setprecision(2) << usedDeviceMemory / (1024 * 1024) << "Mbytes"); if (index == 0) { //-------------------------------------------------------------------------- // Create pixel buffer object for display //-------------------------------------------------------------------------- glGenBuffersARB(1, &pbo); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * sizeof(GLubyte) * 4, 0, GL_STREAM_DRAW_ARB); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); pboBuff = new cl::BufferGL(*ctx, CL_MEM_READ_WRITE, pbo); } //-------------------------------------------------------------------------- // Compile the kernel source //-------------------------------------------------------------------------- // Set #define symbols stringstream ss; ss.precision(6); ss << scientific << " -D PARAM_SCREEN_WIDTH=" << width << " -D PARAM_SCREEN_HEIGHT=" << height << " -D PARAM_SCREEN_SAMPLEPERPASS="******" -D PARAM_RAY_EPSILON=" << EPSILON << "f" << " -D PARAM_MAX_DIFFUSE_BOUNCE=" << gameLevel.maxPathDiffuseBounces << " -D PARAM_MAX_SPECULARGLOSSY_BOUNCE=" << gameLevel.maxPathSpecularGlossyBounces << " -D PARAM_IL_SHIFT_U=" << gameLevel.scene->infiniteLight->GetShiftU() << "f" << " -D PARAM_IL_SHIFT_V=" << gameLevel.scene->infiniteLight->GetShiftV() << "f" << " -D PARAM_IL_GAIN_R=" << gameLevel.scene->infiniteLight->GetGain().r << "f" << " -D PARAM_IL_GAIN_G=" << gameLevel.scene->infiniteLight->GetGain().g << "f" << " -D PARAM_IL_GAIN_B=" << gameLevel.scene->infiniteLight->GetGain().b << "f" << " -D PARAM_IL_MAP_WIDTH=" << gameLevel.scene->infiniteLight->GetTexture()->GetTexMap()->GetWidth() << " -D PARAM_IL_MAP_HEIGHT=" << gameLevel.scene->infiniteLight->GetTexture()->GetTexMap()->GetHeight() << " -D PARAM_GAMMA=" << gameLevel.toneMap->GetGamma() << "f" << " -D PARAM_MEM_TYPE=" << gameLevel.gameConfig->GetOpenCLMemType(); if (compiledScene.enable_MAT_MATTE) ss << " -D PARAM_ENABLE_MAT_MATTE"; if (compiledScene.enable_MAT_MIRROR) ss << " -D PARAM_ENABLE_MAT_MIRROR"; if (compiledScene.enable_MAT_GLASS) ss << " -D PARAM_ENABLE_MAT_GLASS"; if (compiledScene.enable_MAT_METAL) ss << " -D PARAM_ENABLE_MAT_METAL"; if (compiledScene.enable_MAT_ALLOY) ss << " -D PARAM_ENABLE_MAT_ALLOY"; if (texMapBuffer) { ss << " -D PARAM_HAS_TEXTUREMAPS"; if (compiledScene.sphereBumps.size() > 0) ss << " -D PARAM_HAS_BUMPMAPS"; } switch (gameLevel.toneMap->GetType()) { case TONEMAP_REINHARD02: ss << " -D PARAM_TM_LINEAR_SCALE=1.0f"; break; case TONEMAP_LINEAR: { LinearToneMap *tm = (LinearToneMap *)gameLevel.toneMap; ss << " -D PARAM_TM_LINEAR_SCALE=" << tm->scale << "f"; break; } default: assert (false); } #if defined(__APPLE__) ss << " -D __APPLE__"; #endif SFERA_LOG("[OCLRenderer] Defined symbols: " << ss.str()); SFERA_LOG("[OCLRenderer] Compiling kernels"); cl::Program::Sources source(1, std::make_pair(KernelSource_kernel_core.c_str(), KernelSource_kernel_core.length())); cl::Program program = cl::Program(*ctx, source); try { VECTOR_CLASS<cl::Device> buildDevice; buildDevice.push_back(dev); program.build(buildDevice, ss.str().c_str()); } catch (cl::Error err) { cl::STRING_CLASS strError = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(dev); SFERA_LOG("[OCLRenderer] Kernel compilation error:\n" << strError.c_str()); throw err; } kernelInit = new cl::Kernel(program, "Init"); kernelInit->setArg(0, *gpuTaskBuffer); cmdQueue->enqueueNDRangeKernel(*kernelInit, cl::NullRange, cl::NDRange(RoundUp<unsigned int>(width * height, WORKGROUP_SIZE)), cl::NDRange(WORKGROUP_SIZE)); kernelInitFrameBuffer = new cl::Kernel(program, "InitFB"); if (index == 0) { kernelInitFrameBuffer->setArg(0, *frameBuffer); cmdQueue->enqueueNDRangeKernel(*kernelInitFrameBuffer, cl::NullRange, cl::NDRange(RoundUp<unsigned int>(width * height, WORKGROUP_SIZE)), cl::NDRange(WORKGROUP_SIZE)); } kernelInitFrameBuffer->setArg(0, *passFrameBuffer); kernelPathTracing = new cl::Kernel(program, "PathTracing"); unsigned int argIndex = 0; kernelPathTracing->setArg(argIndex++, *gpuTaskBuffer); argIndex++; kernelPathTracing->setArg(argIndex++, *cameraBuffer); kernelPathTracing->setArg(argIndex++, *infiniteLightBuffer); kernelPathTracing->setArg(argIndex++, *passFrameBuffer); kernelPathTracing->setArg(argIndex++, *matBuffer); kernelPathTracing->setArg(argIndex++, *matIndexBuffer); if (texMapBuffer) { kernelPathTracing->setArg(argIndex++, *texMapBuffer); kernelPathTracing->setArg(argIndex++, *texMapRGBBuffer); kernelPathTracing->setArg(argIndex++, *texMapInstanceBuffer); if (compiledScene.sphereBumps.size() > 0) kernelPathTracing->setArg(argIndex++, *bumpMapInstanceBuffer); } kernelApplyBlurLightFilterXR1 = new cl::Kernel(program, "ApplyBlurLightFilterXR1"); kernelApplyBlurLightFilterXR1->setArg(0, *passFrameBuffer); kernelApplyBlurLightFilterXR1->setArg(1, *tmpFrameBuffer); kernelApplyBlurLightFilterYR1 = new cl::Kernel(program, "ApplyBlurLightFilterYR1"); kernelApplyBlurLightFilterYR1->setArg(0, *tmpFrameBuffer); kernelApplyBlurLightFilterYR1->setArg(1, *passFrameBuffer); kernelApplyBlurHeavyFilterXR1 = new cl::Kernel(program, "ApplyBlurHeavyFilterXR1"); kernelApplyBlurHeavyFilterXR1->setArg(0, *passFrameBuffer); kernelApplyBlurHeavyFilterXR1->setArg(1, *tmpFrameBuffer); kernelApplyBlurHeavyFilterYR1 = new cl::Kernel(program, "ApplyBlurHeavyFilterYR1"); kernelApplyBlurHeavyFilterYR1->setArg(0, *tmpFrameBuffer); kernelApplyBlurHeavyFilterYR1->setArg(1, *passFrameBuffer); kernelApplyBoxFilterXR1 = new cl::Kernel(program, "ApplyBoxFilterXR1"); kernelApplyBoxFilterXR1->setArg(0, *passFrameBuffer); kernelApplyBoxFilterXR1->setArg(1, *tmpFrameBuffer); kernelApplyBoxFilterYR1 = new cl::Kernel(program, "ApplyBoxFilterYR1"); kernelApplyBoxFilterYR1->setArg(0, *tmpFrameBuffer); kernelApplyBoxFilterYR1->setArg(1, *passFrameBuffer); if (index == 0) { kernelBlendFrame = new cl::Kernel(program, "BlendFrame"); kernelBlendFrame->setArg(0, *passFrameBuffer); kernelBlendFrame->setArg(1, *frameBuffer); kernelToneMapLinear = new cl::Kernel(program, "ToneMapLinear"); kernelToneMapLinear->setArg(0, *frameBuffer); kernelToneMapLinear->setArg(1, *toneMapFrameBuffer); kernelUpdatePixelBuffer = new cl::Kernel(program, "UpdatePixelBuffer"); kernelUpdatePixelBuffer->setArg(0, *toneMapFrameBuffer); kernelUpdatePixelBuffer->setArg(1, *pboBuff); } else { kernelBlendFrame = NULL; kernelToneMapLinear = NULL; kernelUpdatePixelBuffer = NULL; } }