[Bf-blender-cvs] [140a129f22f] opencl_half_textures: Cycles: Enabled half precision float textures for OpenCL devices that support it.

Stefan Werner noreply at git.blender.org
Thu Jul 5 15:17:48 CEST 2018


Commit: 140a129f22f07a77127aa1e47cc65b5e3d2d4dcb
Author: Stefan Werner
Date:   Thu Jul 5 15:17:48 2018 +0200
Branches: opencl_half_textures
https://developer.blender.org/rB140a129f22f07a77127aa1e47cc65b5e3d2d4dcb

Cycles: Enabled half precision float textures for OpenCL devices that support it.

===================================================================

M	intern/cycles/device/device_opencl.cpp
M	intern/cycles/device/opencl/opencl.h
M	intern/cycles/device/opencl/opencl_mega.cpp
M	intern/cycles/device/opencl/opencl_split.cpp
M	intern/cycles/device/opencl/opencl_util.cpp
M	intern/cycles/kernel/kernel_compat_opencl.h
M	intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h

===================================================================

diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 9d61bbdae5d..95eef8263d4 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -137,6 +137,10 @@ void device_opencl_info(vector<DeviceInfo>& devices)
 		info.has_volume_decoupled = false;
 		info.bvh_layout_mask = BVH_LAYOUT_BVH2;
 		info.id = id;
+
+		/* Check OpenCL extensions */
+		info.has_half_images = platform_device.device_extensions.find("cl_khr_fp16") != string::npos;
+
 		devices.push_back(info);
 		num_devices++;
 	}
diff --git a/intern/cycles/device/opencl/opencl.h b/intern/cycles/device/opencl/opencl.h
index 22e0503365c..d0571fc3c14 100644
--- a/intern/cycles/device/opencl/opencl.h
+++ b/intern/cycles/device/opencl/opencl.h
@@ -59,19 +59,22 @@ struct OpenCLPlatformDevice {
 	                     cl_device_id device_id,
 	                     cl_device_type device_type,
 	                     const string& device_name,
-	                     const string& hardware_id)
+	                     const string& hardware_id,
+		                 const string& device_extensions)
 	  : platform_id(platform_id),
 	    platform_name(platform_name),
 	    device_id(device_id),
 	    device_type(device_type),
 	    device_name(device_name),
-	    hardware_id(hardware_id) {}
+	    hardware_id(hardware_id),
+	    device_extensions(device_extensions) {}
 	cl_platform_id platform_id;
 	string platform_name;
 	cl_device_id device_id;
 	cl_device_type device_type;
 	string device_name;
 	string hardware_id;
+	string device_extensions;
 };
 
 /* Contains all static OpenCL helper functions. */
@@ -130,6 +133,12 @@ public:
 
 	static string get_device_name(cl_device_id device_id);
 
+	static bool get_device_extensions(cl_device_id device_id,
+	                                  string *device_extensions,
+	                                  cl_int* error = NULL);
+
+	static string get_device_extensions(cl_device_id device_id);
+
 	static bool get_device_type(cl_device_id device_id,
 	                            cl_device_type *device_type,
 	                            cl_int* error = NULL);
diff --git a/intern/cycles/device/opencl/opencl_mega.cpp b/intern/cycles/device/opencl/opencl_mega.cpp
index e004c0b44f4..64b67091674 100644
--- a/intern/cycles/device/opencl/opencl_mega.cpp
+++ b/intern/cycles/device/opencl/opencl_mega.cpp
@@ -35,7 +35,7 @@ public:
 
 	OpenCLDeviceMegaKernel(DeviceInfo& info, Stats &stats, bool background_)
 	: OpenCLDeviceBase(info, stats, background_),
-	  path_trace_program(this, "megakernel", "kernel.cl", "-D__COMPILE_ONLY_MEGAKERNEL__ ")
+	  path_trace_program(this, "megakernel", "kernel.cl", info.has_half_images ? "-D__COMPILE_ONLY_MEGAKERNEL__ -D__KERNEL_CL_KHR_FP16__" : "-D__COMPILE_ONLY_MEGAKERNEL__ ")
 	{
 	}
 
diff --git a/intern/cycles/device/opencl/opencl_split.cpp b/intern/cycles/device/opencl/opencl_split.cpp
index 66a4aa7e891..51c16d8aafc 100644
--- a/intern/cycles/device/opencl/opencl_split.cpp
+++ b/intern/cycles/device/opencl/opencl_split.cpp
@@ -67,6 +67,9 @@ static string get_build_options(OpenCLDeviceBase *device, const DeviceRequestedF
 	if(device_type == CL_DEVICE_TYPE_GPU) {
 		build_options += " -D__COMPUTE_DEVICE_GPU__";
 	}
+	if(device->info.has_half_images) {
+		build_options += " -D__KERNEL_CL_KHR_FP16__";
+	}
 
 	return build_options;
 }
diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp
index 78ed401bff5..9104f64bedd 100644
--- a/intern/cycles/device/opencl/opencl_util.cpp
+++ b/intern/cycles/device/opencl/opencl_util.cpp
@@ -831,13 +831,15 @@ void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices
 				FIRST_VLOG(2) << "Adding new device "
 				              << readable_device_name << ".";
 				string hardware_id = get_hardware_id(platform_name, device_id);
+				string device_extensions = get_device_extensions(device_id);
 				usable_devices->push_back(OpenCLPlatformDevice(
 				        platform_id,
 				        platform_name,
 				        device_id,
 				        device_type,
 				        readable_device_name,
-				        hardware_id));
+				        hardware_id,
+				        device_extensions));
 			}
 			else {
 				FIRST_VLOG(2) << "Ignoring device " << device_name
@@ -1047,6 +1049,40 @@ string OpenCLInfo::get_device_name(cl_device_id device_id)
 	return device_name;
 }
 
+bool OpenCLInfo::get_device_extensions(cl_device_id device_id,
+	string *device_extensions,
+	cl_int* error)
+{
+	char buffer[1024];
+	cl_int err;
+	if((err = clGetDeviceInfo(device_id,
+		CL_DEVICE_EXTENSIONS,
+		sizeof(buffer),
+		&buffer,
+		NULL)) != CL_SUCCESS)
+	{
+		if(error != NULL) {
+			*error = err;
+		}
+		*device_extensions = "";
+		return false;
+	}
+	if(error != NULL) {
+		*error = CL_SUCCESS;
+	}
+	*device_extensions = buffer;
+	return true;
+}
+
+string OpenCLInfo::get_device_extensions(cl_device_id device_id)
+{
+	string device_extensions;
+	if(!get_device_extensions(device_id, &device_extensions)) {
+		return "";
+	}
+	return device_extensions;
+}
+
 bool OpenCLInfo::get_device_type(cl_device_id device_id,
                                  cl_device_type *device_type,
                                  cl_int* error)
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index 671c47e2225..5b171034308 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -150,6 +150,11 @@
 /* define NULL */
 #define NULL 0
 
+/* enable extensions */
+#ifdef __KERNEL_CL_KHR_FP16__
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+#endif
+
 #include "util/util_half.h"
 #include "util/util_types.h"
 
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
index 011623130eb..b8473c54907 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
@@ -72,6 +72,17 @@ ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, const ccl_glo
 		return make_float4(f, f, f, 1.0f);
 	}
 	/* Byte */
+#ifdef __KERNEL_CL_KHR_FP16__
+	/* half and half4 are optional in OpenCL */
+	else if(texture_type == IMAGE_DATA_TYPE_HALF) {
+		float f = tex_fetch(half, info, offset);
+		return make_float4(f, f, f, 1.0f);
+	}
+	else if(texture_type == IMAGE_DATA_TYPE_HALF4) {
+		half4 r = tex_fetch(half4, info, offset);
+		return make_float4(r.x, r.y, r.z, r.w);
+	}
+#endif
 	else {
 		uchar r = tex_fetch(uchar, info, offset);
 		float f = r * (1.0f/255.0f);



More information about the Bf-blender-cvs mailing list