[Beignet] [PATCH 18/57] Add extension support to runtime.

junyan.he at inbox.com junyan.he at inbox.com
Sun Jun 11 05:50:04 UTC 2017


From: Junyan He <junyan.he at intel.com>

The intel platform will provide a basic extension, all devices on
this platform need to support these extensions. Each device can
add some extension based on the device capability and configuration
if needed.

Signed-off-by: Junyan He <junyan.he at intel.com>
---
 runtime/cl_extensions.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++
 runtime/cl_extensions.h | 118 ++++++++++++++++++++++++++++++++++
 2 files changed, 283 insertions(+)
 create mode 100644 runtime/cl_extensions.c
 create mode 100644 runtime/cl_extensions.h

diff --git a/runtime/cl_extensions.c b/runtime/cl_extensions.c
new file mode 100644
index 0000000..47b1349
--- /dev/null
+++ b/runtime/cl_extensions.c
@@ -0,0 +1,165 @@
+#include "llvm/Config/llvm-config.h"
+#ifdef HAS_GL_EGL
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+#endif
+
+#include "cl_platform_id.h"
+#include "cl_device_id.h"
+#include "CL/cl.h"
+#include "cl_utils.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* This extension should be common for all the intel GPU platform.
+   Every device may have its own additional externsions. */
+static struct cl_extensions intel_platform_extensions =
+  {
+    {
+#define DECL_EXT(name) \
+  {(struct cl_extension_base){.ext_id = cl_##name##_ext_id, .ext_name = "cl_" #name, .ext_enabled = 0}},
+      DECL_ALL_EXTENSIONS},
+#undef DECL_EXT
+    {""}};
+
+void static check_basic_extension(cl_extensions_t *extensions)
+{
+  int id;
+  for (id = BASE_EXT_START_ID; id <= BASE_EXT_END_ID; id++)
+    if (id != EXT_ID(khr_fp64))
+      extensions->extensions[id].base.ext_enabled = 1;
+}
+
+void static check_opt1_extension(cl_extensions_t *extensions)
+{
+  int id;
+  for (id = OPT1_EXT_START_ID; id <= OPT1_EXT_END_ID; id++) {
+    if (id == EXT_ID(khr_icd))
+      extensions->extensions[id].base.ext_enabled = 1;
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5
+    if (id == EXT_ID(khr_spir))
+      extensions->extensions[id].base.ext_enabled = 1;
+#endif
+    if (id == EXT_ID(khr_image2d_from_buffer))
+      extensions->extensions[id].base.ext_enabled = 1;
+    if (id == EXT_ID(khr_3d_image_writes))
+      extensions->extensions[id].base.ext_enabled = 1;
+  }
+}
+
+static void
+check_gl_extension(cl_extensions_t *extensions)
+{
+#if defined(HAS_GL_EGL)
+  int id;
+  /* For now, we only support cl_khr_gl_sharing. */
+  for (id = GL_EXT_START_ID; id <= GL_EXT_END_ID; id++)
+    if (id == EXT_ID(khr_gl_sharing))
+      extensions->extensions[id].base.ext_enabled = 1;
+#endif
+}
+
+static void
+check_intel_extension(cl_extensions_t *extensions)
+{
+  int id;
+  for (id = INTEL_EXT_START_ID; id <= INTEL_EXT_END_ID; id++)
+    if (id != EXT_ID(intel_motion_estimation))
+      extensions->extensions[id].base.ext_enabled = 1;
+}
+
+static void
+process_extension_str(cl_extensions_t *extensions)
+{
+  int str_max = sizeof(extensions->ext_str);
+  int str_offset = 0;
+  int id;
+
+  memset(extensions->ext_str, 0, sizeof(extensions->ext_str));
+
+  for (id = 0; id < cl_khr_extension_id_max; id++) {
+    if (extensions->extensions[id].base.ext_enabled) {
+      int copy_len;
+      char *ext_name = extensions->extensions[id].base.ext_name;
+      if (str_offset + 1 >= str_max)
+        return;
+
+      if (str_offset != 0)
+        extensions->ext_str[str_offset - 1] = ' ';
+      copy_len = (strlen(ext_name) + 1 + str_offset) < str_max
+                   ? (strlen(ext_name) + 1)
+                   : (str_max - str_offset - 1);
+      strncpy(&extensions->ext_str[str_offset],
+              extensions->extensions[id].base.ext_name, copy_len);
+      str_offset += copy_len;
+    }
+  }
+}
+
+LOCAL void
+cl_intel_platform_get_default_extension(cl_device_id device)
+{
+  cl_platform_id pf = device->platform;
+  memcpy((char *)device->extensions,
+         pf->internal_extensions->ext_str, sizeof(device->extensions));
+  device->extensions_sz = strlen(pf->internal_extensions->ext_str) + 1;
+}
+
+LOCAL void
+cl_intel_platform_enable_extension(cl_device_id device, uint32_t ext)
+{
+  int id;
+  char *ext_str = NULL;
+  cl_platform_id pf = device->platform;
+  assert(pf);
+
+  for (id = BASE_EXT_START_ID; id < cl_khr_extension_id_max; id++) {
+    if (id == ext) {
+      if (!pf->internal_extensions->extensions[id].base.ext_enabled)
+        ext_str = pf->internal_extensions->extensions[id].base.ext_name;
+
+      break;
+    }
+  }
+
+  /* already enabled, skip. */
+  if (ext_str && strstr(device->extensions, ext_str))
+    ext_str = NULL;
+
+  if (ext_str) {
+    if (device->extensions_sz <= 1) {
+      memcpy((char *)device->extensions, ext_str, strlen(ext_str));
+      device->extensions_sz = strlen(ext_str) + 1;
+    } else {
+      assert(device->extensions_sz + 1 + strlen(ext_str) < EXTENSTION_LENGTH);
+      *(char *)(device->extensions + device->extensions_sz - 1) = ' ';
+      memcpy((char *)device->extensions + device->extensions_sz, ext_str, strlen(ext_str));
+      device->extensions_sz = device->extensions_sz + strlen(ext_str) + 1;
+    }
+
+    *(char *)(device->extensions + device->extensions_sz - 1) = 0;
+  }
+}
+
+LOCAL void
+cl_intel_platform_extension_init(cl_platform_id intel_platform)
+{
+  static int ext_initialized = 0;
+
+  /* The EXT should be only inited once. */
+  (void)ext_initialized;
+  assert(!ext_initialized);
+  check_basic_extension(&intel_platform_extensions);
+  check_opt1_extension(&intel_platform_extensions);
+  check_gl_extension(&intel_platform_extensions);
+  check_intel_extension(&intel_platform_extensions);
+  process_extension_str(&intel_platform_extensions);
+  ext_initialized = 1;
+
+  intel_platform->internal_extensions = &intel_platform_extensions;
+  intel_platform->extensions = intel_platform_extensions.ext_str;
+  intel_platform->extensions_sz = strlen(intel_platform->extensions) + 1;
+  return;
+}
diff --git a/runtime/cl_extensions.h b/runtime/cl_extensions.h
new file mode 100644
index 0000000..145778d
--- /dev/null
+++ b/runtime/cl_extensions.h
@@ -0,0 +1,118 @@
+#ifndef __CL_EXTENSIONS_H__
+#define __CL_EXTENSIONS_H__
+/* The following approved Khronos extension
+ * names must be returned by all device that
+ * support OpenCL C 1.2. */
+#define DECL_BASE_EXTENSIONS                  \
+  DECL_EXT(khr_global_int32_base_atomics)     \
+  DECL_EXT(khr_global_int32_extended_atomics) \
+  DECL_EXT(khr_local_int32_base_atomics)      \
+  DECL_EXT(khr_local_int32_extended_atomics)  \
+  DECL_EXT(khr_byte_addressable_store)        \
+  DECL_EXT(khr_3d_image_writes)               \
+  DECL_EXT(khr_image2d_from_buffer)           \
+  DECL_EXT(khr_depth_images)                  \
+  DECL_EXT(khr_fp64)
+
+/* The OPT1 extensions are those optional extensions
+ * which don't have external dependecies*/
+#define DECL_OPT1_EXTENSIONS           \
+  DECL_EXT(khr_int64_base_atomics)     \
+  DECL_EXT(khr_int64_extended_atomics) \
+  DECL_EXT(khr_fp16)                   \
+  DECL_EXT(khr_initialize_memory)      \
+  DECL_EXT(khr_context_abort)          \
+  DECL_EXT(khr_spir)                   \
+  DECL_EXT(khr_icd)
+
+#define DECL_INTEL_EXTENSIONS       \
+  DECL_EXT(intel_accelerator)       \
+  DECL_EXT(intel_motion_estimation) \
+  DECL_EXT(intel_subgroups)         \
+  DECL_EXT(intel_subgroups_short)   \
+  DECL_EXT(intel_media_block_io)    \
+  DECL_EXT(intel_planar_yuv)
+
+#define DECL_GL_EXTENSIONS      \
+  DECL_EXT(khr_gl_sharing)      \
+  DECL_EXT(khr_gl_event)        \
+  DECL_EXT(khr_gl_depth_images) \
+  DECL_EXT(khr_gl_msaa_sharing)
+
+#define DECL_D3D_EXTENSIONS       \
+  DECL_EXT(khr_d3d10_sharing)     \
+  DECL_EXT(khr_dx9_media_sharing) \
+  DECL_EXT(khr_d3d11_sharing)
+
+#define DECL_ALL_EXTENSIONS \
+  DECL_BASE_EXTENSIONS      \
+  DECL_OPT1_EXTENSIONS      \
+  DECL_INTEL_EXTENSIONS     \
+  DECL_GL_EXTENSIONS        \
+  DECL_D3D_EXTENSIONS
+
+#define EXT_ID(name) cl_##name##_ext_id
+#define EXT_STRUCT_NAME(name) cl_##name##ext
+/*Declare enum ids */
+typedef enum {
+#define DECL_EXT(name) \
+  EXT_ID(name)         \
+  ,
+  DECL_ALL_EXTENSIONS
+#undef DECL_EXT
+    cl_khr_extension_id_max
+} cl_extension_enum;
+
+#define BASE_EXT_START_ID EXT_ID(khr_global_int32_base_atomics)
+#define BASE_EXT_END_ID EXT_ID(khr_fp64)
+#define OPT1_EXT_START_ID EXT_ID(khr_int64_base_atomics)
+#define OPT1_EXT_END_ID EXT_ID(khr_icd)
+#define INTEL_EXT_START_ID EXT_ID(intel_accelerator)
+#define INTEL_EXT_END_ID EXT_ID(intel_planar_yuv)
+#define GL_EXT_START_ID EXT_ID(khr_gl_sharing)
+#define GL_EXT_END_ID EXT_ID(khr_gl_msaa_sharing)
+
+#define IS_BASE_EXTENSION(id) (id >= BASE_EXT_START_ID && id <= BASE_EXT_END_ID)
+#define IS_OPT1_EXTENSION(id) (id >= OPT1_EXT_START_ID && id <= OPT1_EXT_END_ID)
+#define IS_GL_EXTENSION(id) (id >= GL_EXT_START_ID && id <= GL_EXT_END_ID)
+
+struct cl_extension_base {
+  cl_extension_enum ext_id;
+  int ext_enabled;
+  char *ext_name;
+};
+
+/* Declare each extension structure. */
+#define DECL_EXT(name)             \
+  struct EXT_STRUCT_NAME(name) {   \
+    struct cl_extension_base base; \
+  };
+
+DECL_BASE_EXTENSIONS
+DECL_OPT1_EXTENSIONS
+DECL_INTEL_EXTENSIONS
+DECL_D3D_EXTENSIONS
+DECL_GL_EXTENSIONS
+#undef DECL_EXT
+
+/* Union all extensions together. */
+typedef union {
+  struct cl_extension_base base;
+#define DECL_EXT(name) struct EXT_STRUCT_NAME(name) EXT_STRUCT_NAME(name);
+  DECL_ALL_EXTENSIONS
+#undef DECL_EXT
+} extension_union;
+
+#include "cl_device_id.h"
+typedef struct cl_extensions {
+  extension_union extensions[cl_khr_extension_id_max];
+  char ext_str[EXTENSTION_LENGTH];
+} cl_extensions_t;
+
+extern void
+cl_intel_platform_extension_init(cl_platform_id intel_platform);
+extern void
+cl_intel_platform_enable_extension(cl_device_id device, uint32_t name);
+extern void
+cl_intel_platform_get_default_extension(cl_device_id device);
+#endif /* __CL_EXTENSIONS_H__ */
-- 
2.7.4





More information about the Beignet mailing list