コード例 #1
0
void PathOCLRenderThread::InitFrameBuffer() {
	//--------------------------------------------------------------------------
	// FrameBuffer definition
	//--------------------------------------------------------------------------

	frameBufferPixelCount =	(renderEngine->film->GetWidth() + 2) * (renderEngine->film->GetHeight() + 2);

	// Delete previous allocated frameBuffer
	delete[] frameBuffer;
	frameBuffer = new PathOCL::Pixel[frameBufferPixelCount];

	for (unsigned int i = 0; i < frameBufferPixelCount; ++i) {
		frameBuffer[i].c.r = 0.f;
		frameBuffer[i].c.g = 0.f;
		frameBuffer[i].c.b = 0.f;
		frameBuffer[i].count = 0.f;
	}

	AllocOCLBufferRW(&frameBufferBuff, sizeof(PathOCL::Pixel) * frameBufferPixelCount, "FrameBuffer");

	delete[] alphaFrameBuffer;
	alphaFrameBuffer = NULL;

	// Check if the film has an alpha channel
	if (renderEngine->film->IsAlphaChannelEnabled()) {
		alphaFrameBuffer = new PathOCL::AlphaPixel[frameBufferPixelCount];

		for (unsigned int i = 0; i < frameBufferPixelCount; ++i)
			alphaFrameBuffer[i].alpha = 0.f;

		AllocOCLBufferRW(&alphaFrameBufferBuff, sizeof(PathOCL::AlphaPixel) * frameBufferPixelCount, "Alpha Channel FrameBuffer");
	}
}
コード例 #2
0
void PathOCLRenderThread::InitFrameBuffer() {
	//--------------------------------------------------------------------------
	// FrameBuffer definition
	//--------------------------------------------------------------------------

	frameBufferPixelCount =	(renderEngine->film->GetWidth() + 2) * (renderEngine->film->GetHeight() + 2);

	// Delete previous allocated frameBuffer
	delete[] frameBuffer;
	frameBuffer = new PathOCL::Pixel[frameBufferPixelCount];

	for (unsigned int i = 0; i < frameBufferPixelCount; ++i) {
		frameBuffer[i].c.r = 0.f;
		frameBuffer[i].c.g = 0.f;
		frameBuffer[i].c.b = 0.f;
		frameBuffer[i].count = 0.f;
	}

	AllocOCLBufferRW(&frameBufferBuff, sizeof(PathOCL::Pixel) * frameBufferPixelCount, "FrameBuffer");
}
コード例 #3
0
ファイル: oclrenderer.cpp プロジェクト: WarterKu/sfera
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;
	}
}