Skip to content

Commit

Permalink
Adding new loader API for handle translation
Browse files Browse the repository at this point in the history
* Adding new loader API for handle translation

Add an new loader API that can be used in the rare cases where access to underlying 
raw driver handle types is needed. 

Signed-off-by: Brandon Yates <[email protected]>
  • Loading branch information
bmyates committed Dec 16, 2021
1 parent ba41862 commit 06862fc
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 3 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ endif()

# This project follows semantic versioning (https://semver.org/). Only set the
# major and minor version here - patch version is determined dynamically.
project(level-zero VERSION 1.6)
project(level-zero VERSION 1.7)

# Patch version corresponds to # of commits on master since last version
# major/minor tag (e.g., v1.0). If not building in a git repository, then get
Expand Down
23 changes: 22 additions & 1 deletion doc/loader_api.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Level Zero Loader APIs

## Introduction
The Level Zero Loader will expose some additional APIs beyond what is defined in the Level Zero spec. The purpose of these APIs will generally be to access and set various loader configuration components. At the current time, only one such API exists. It's expected more will be added in the future, and they will be documented here.
The Level Zero Loader will expose some additional APIs beyond what is defined in the Level Zero spec. The purpose of these APIs will generally be to access and set various loader configuration components.

This document does not cover APIs specific to individual layers (ie. tracing) or APIs defined in the Level Zero spec.

Expand All @@ -20,3 +20,24 @@ There are currently 3 versioned components assigned the following name strings:
- `"tracing layer"`
- `"validation layer"`
- `"loader"`


### zelLoaderTranslateHandle

When a system has multiple L0 drivers, raw handles returned from the L0 drivers are modified by the loader before being returned to the application. This allows the loader to determine which handles belong to which driver and forward API calls appropriately. In most cases the loader will perform this handle translation completely transparently to the application and no manual translation is ever needed.

In some rare cases when the application needs to occasionally bypass the loader, handle conflicts can arise. One such case is when an application wants to call a driver extension function whose address has been retreived with `zeDriverGetExtensionFunctionAddress`

To solve this issue, `zelLoaderTranslateHandle` is used to retrieve the raw driver handle associated with a loader handle.

- __handleType__ Type of the L0 handle to translate
- __*handleIn__ Input handle to translate
- __**handleOut__ Output location to store the translated handle








27 changes: 26 additions & 1 deletion include/loader/ze_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#pragma once
#endif

#include "ze_api.h"
#include "../ze_api.h"

#if defined(__cplusplus)
extern "C" {
Expand All @@ -39,6 +39,31 @@ zelLoaderGetVersions(
size_t *num_elems, //Pointer to num versions to get.
zel_component_version_t *versions); //Pointer to array of versions. If set to NULL, num_elems is returned

typedef enum _zel_handle_type_t {
ZEL_HANDLE_DRIVER,
ZEL_HANDLE_DEVICE,
ZEL_HANDLE_CONTEXT,
ZEL_HANDLE_COMMAND_QUEUE,
ZEL_HANDLE_COMMAND_LIST,
ZEL_HANDLE_FENCE,
ZEL_HANDLE_EVENT_POOL,
ZEL_HANDLE_EVENT,
ZEL_HANDLE_IMAGE,
ZEL_HANDLE_MODULE,
ZEL_HANDLE_MODULE_BUILD_LOG,
ZEL_HANDLE_KERNEL,
ZEL_HANDLE_SAMPLER,
ZEL_HANDLE_PHYSICAL_MEM
} zel_handle_type_t;

//Translates Loader Handles to Driver Handles if loader handle intercept is enabled.
//If handle intercept is not enabled handleOut is set to handleIn
ZE_APIEXPORT ze_result_t ZE_APICALL
zelLoaderTranslateHandle(
zel_handle_type_t handleType, //Handle Type
void *handleIn, //Input: handle to translate from loader handle to driver handle
void **handleOut); //Output: Pointer to handleOut is set to driver handle if successful


#if defined(__cplusplus)
} // extern "C"
Expand Down
14 changes: 14 additions & 0 deletions source/lib/ze_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,18 @@ zelLoaderGetVersions(
#endif
}


ze_result_t ZE_APICALL
zelLoaderTranslateHandle(
zel_handle_type_t handleType,
void *handleIn,
void **handleOut)

{
return zelLoaderTranslateHandleInternal(handleType, handleIn, handleOut);
}




} //extern "c"
64 changes: 64 additions & 0 deletions source/loader/ze_loader_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,70 @@ zelLoaderGetVersionsInternal(
return ZE_RESULT_SUCCESS;
}


ZE_DLLEXPORT ze_result_t ZE_APICALL
zelLoaderTranslateHandleInternal(
zel_handle_type_t handleType,
void *handleIn,
void **handleOut)
{

if((loader::context->drivers.size() == 1 ) && !loader::context->forceIntercept) {
*handleOut = handleIn;
return ZE_RESULT_SUCCESS;
}

switch(handleType){
case ZEL_HANDLE_DRIVER:
*handleOut = reinterpret_cast<loader::ze_driver_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_DEVICE:
*handleOut = reinterpret_cast<loader::ze_device_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_CONTEXT:
*handleOut = reinterpret_cast<loader::ze_context_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_COMMAND_QUEUE:
*handleOut = reinterpret_cast<loader::ze_command_queue_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_COMMAND_LIST:
*handleOut = reinterpret_cast<loader::ze_command_list_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_FENCE:
*handleOut = reinterpret_cast<loader::ze_fence_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_EVENT_POOL:
*handleOut = reinterpret_cast<loader::ze_event_pool_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_EVENT:
*handleOut = reinterpret_cast<loader::ze_event_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_IMAGE:
*handleOut = reinterpret_cast<loader::ze_image_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_MODULE:
*handleOut = reinterpret_cast<loader::ze_module_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_MODULE_BUILD_LOG:
*handleOut = reinterpret_cast<loader::ze_module_build_log_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_KERNEL:
*handleOut = reinterpret_cast<loader::ze_kernel_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_SAMPLER:
*handleOut = reinterpret_cast<loader::ze_sampler_object_t*>( handleIn )->handle;
break;
case ZEL_HANDLE_PHYSICAL_MEM:
*handleOut = reinterpret_cast<loader::ze_physical_mem_object_t*>( handleIn )->handle;
break;
default:
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
}

return ZE_RESULT_SUCCESS;
}


#if defined(__cplusplus)
}
#endif
8 changes: 8 additions & 0 deletions source/loader/ze_loader_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ zelLoaderGetVersionsInternal(
size_t *num_elems, //Pointer to num versions to get.
zel_component_version_t *versions); //Pointer to array of versions. If set to NULL, num_elems is returned


ZE_DLLEXPORT ze_result_t ZE_APICALL
zelLoaderTranslateHandleInternal(
zel_handle_type_t handleType, //Handle type
void *handleIn, //Input: handle to translate from loader handle to driver handle
void **handleOut); //Output: Pointer to handleOut is set to driver handle if successful


#if defined(__cplusplus)
}
#endif

0 comments on commit 06862fc

Please sign in to comment.