diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ab1f8bf..d61e7b09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ # Level zero loader changelog +## v1.26.3 +* fix handling of optional DDI tables missing or incorrect ## v1.26.2 * fix: fix Driver Search Paths for all Linux Distros ## v1.26.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index a0a9138d..f2dac34f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ if(MSVC AND (MSVC_VERSION LESS 1900)) endif() # This project follows semantic versioning (https://semver.org/) -project(level-zero VERSION 1.26.2) +project(level-zero VERSION 1.26.3) include(GNUInstallDirs) find_package(Git) diff --git a/PRODUCT_GUID.txt b/PRODUCT_GUID.txt index 846068bc..5cb0db2d 100644 --- a/PRODUCT_GUID.txt +++ b/PRODUCT_GUID.txt @@ -1,2 +1,2 @@ -1.26.2 -cf85b8de-e9c1-4d88-9f18-7164098e1c1e \ No newline at end of file +1.26.3 +d1ed32f4-2b7d-4718-9f86-69cbae2c1836 \ No newline at end of file diff --git a/scripts/templates/ldrddi.cpp.mako b/scripts/templates/ldrddi.cpp.mako index 08514f11..96597b34 100644 --- a/scripts/templates/ldrddi.cpp.mako +++ b/scripts/templates/ldrddi.cpp.mako @@ -22,14 +22,42 @@ using namespace loader_driver_ddi; namespace loader { + /////////////////////////////////////////////////////////////////////////////// + /// @brief Initialize all DDI tables for a driver by calling *FromDriver functions + /// + /// @details This function can fail in the following scenarios: + /// - driver->initStatus is already set to a failure code (from a previous + /// required DDI initialization failure). Each *FromDriver call first checks + /// driver->initStatus and returns it immediately if it's already a failure. + /// - A required DDI table's getTable call into the driver returns a failure, + /// which updates driver->initStatus and is propagated back + /// + /// Note: If GET_FUNCTION_PTR returns null (function not found in driver), + /// it only fails if driver->initStatus was already a failure. Otherwise, + /// driver->initStatus is returned (which would be SUCCESS). + /// + /// Note: Optional DDI tables (when namespace != "zer") are ignored if they + /// fail, and this function continues to attempt loading remaining tables. + /// Only required DDI table failures cause this function to fail and return + /// immediately. + /// + /// @returns + /// - ::ZE_RESULT_SUCCESS if all required DDI tables loaded successfully + /// - ::ZE_RESULT_ERROR_* if any required DDI table failed to load __${x}dlllocal ze_result_t ${X}_APICALL ${n}loaderInitDriverDDITables(loader::driver_t *driver) { ze_result_t result = ZE_RESULT_SUCCESS; %for tbl in th.get_pfntables(specs, meta, n, tags): + %if tbl['optional'] == True and namespace != "zer": + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + ${tbl['export']['name']}FromDriver(driver); + result = ZE_RESULT_SUCCESS; + %else: result = ${tbl['export']['name']}FromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } + %endif %endfor return result; } @@ -556,7 +584,7 @@ ${tbl['export']['name']}FromDriver(loader::driver_t *driver) %else: return driver->initStatus; %endif - %if tbl['experimental'] is False and namespace != "zer": #//Experimental Tables may not be implemented in driver + %if tbl['experimental'] is False and namespace != "zer" and tbl['optional'] != True: #//Experimental Tables may not be implemented in driver auto getTableResult = getTable( loader::context->ddi_init_version, &driver->dditable.${n}.${tbl['name']}); if(getTableResult == ZE_RESULT_SUCCESS) { loader::context->configured_version = loader::context->ddi_init_version; diff --git a/source/loader/ze_ldrddi.cpp b/source/loader/ze_ldrddi.cpp index 9b3277d5..ab769650 100644 --- a/source/loader/ze_ldrddi.cpp +++ b/source/loader/ze_ldrddi.cpp @@ -13,6 +13,28 @@ using namespace loader_driver_ddi; namespace loader { + /////////////////////////////////////////////////////////////////////////////// + /// @brief Initialize all DDI tables for a driver by calling *FromDriver functions + /// + /// @details This function can fail in the following scenarios: + /// - driver->initStatus is already set to a failure code (from a previous + /// required DDI initialization failure). Each *FromDriver call first checks + /// driver->initStatus and returns it immediately if it's already a failure. + /// - A required DDI table's getTable call into the driver returns a failure, + /// which updates driver->initStatus and is propagated back + /// + /// Note: If GET_FUNCTION_PTR returns null (function not found in driver), + /// it only fails if driver->initStatus was already a failure. Otherwise, + /// driver->initStatus is returned (which would be SUCCESS). + /// + /// Note: Optional DDI tables (when namespace != "zer") are ignored if they + /// fail, and this function continues to attempt loading remaining tables. + /// Only required DDI table failures cause this function to fail and return + /// immediately. + /// + /// @returns + /// - ::ZE_RESULT_SUCCESS if all required DDI tables loaded successfully + /// - ::ZE_RESULT_ERROR_* if any required DDI table failed to load __zedlllocal ze_result_t ZE_APICALL zeloaderInitDriverDDITables(loader::driver_t *driver) { ze_result_t result = ZE_RESULT_SUCCESS; @@ -20,38 +42,32 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetRTASBuilderProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } - result = zeGetRTASBuilderExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } - result = zeGetRTASParallelOperationProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } - result = zeGetRTASParallelOperationExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetRTASBuilderProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetRTASBuilderExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetRTASParallelOperationProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetRTASParallelOperationExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetDriverProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetDriverExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetDriverExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetDeviceProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetDeviceExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetDeviceExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetContextProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -64,18 +80,16 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetCommandListExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetCommandListExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetEventProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetEventExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetEventExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetEventPoolProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -88,26 +102,23 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetImageExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetImageExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetKernelProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetKernelExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetKernelExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetMemProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetMemExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetMemExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zeGetModuleProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -128,14 +139,12 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zeGetFabricEdgeExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } - result = zeGetFabricVertexExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetFabricEdgeExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zeGetFabricVertexExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; return result; } /////////////////////////////////////////////////////////////////////////////// @@ -7819,11 +7828,7 @@ zeGetRTASBuilderProcAddrTableFromDriver(loader::driver_t *driver) GET_FUNCTION_PTR( driver->handle, "zeGetRTASBuilderProcAddrTable") ); if(!getTable) return driver->initStatus; - auto getTableResult = getTable( loader::context->ddi_init_version, &driver->dditable.ze.RTASBuilder); - if(getTableResult == ZE_RESULT_SUCCESS) { - loader::context->configured_version = loader::context->ddi_init_version; - } else - driver->initStatus = getTableResult; + result = getTable( loader::context->ddi_init_version, &driver->dditable.ze.RTASBuilder); return result; } /////////////////////////////////////////////////////////////////////////////// @@ -7867,11 +7872,7 @@ zeGetRTASParallelOperationProcAddrTableFromDriver(loader::driver_t *driver) GET_FUNCTION_PTR( driver->handle, "zeGetRTASParallelOperationProcAddrTable") ); if(!getTable) return driver->initStatus; - auto getTableResult = getTable( loader::context->ddi_init_version, &driver->dditable.ze.RTASParallelOperation); - if(getTableResult == ZE_RESULT_SUCCESS) { - loader::context->configured_version = loader::context->ddi_init_version; - } else - driver->initStatus = getTableResult; + result = getTable( loader::context->ddi_init_version, &driver->dditable.ze.RTASParallelOperation); return result; } /////////////////////////////////////////////////////////////////////////////// diff --git a/source/loader/zer_ldrddi.cpp b/source/loader/zer_ldrddi.cpp index 60b9710a..0855eca4 100644 --- a/source/loader/zer_ldrddi.cpp +++ b/source/loader/zer_ldrddi.cpp @@ -13,6 +13,28 @@ using namespace loader_driver_ddi; namespace loader { + /////////////////////////////////////////////////////////////////////////////// + /// @brief Initialize all DDI tables for a driver by calling *FromDriver functions + /// + /// @details This function can fail in the following scenarios: + /// - driver->initStatus is already set to a failure code (from a previous + /// required DDI initialization failure). Each *FromDriver call first checks + /// driver->initStatus and returns it immediately if it's already a failure. + /// - A required DDI table's getTable call into the driver returns a failure, + /// which updates driver->initStatus and is propagated back + /// + /// Note: If GET_FUNCTION_PTR returns null (function not found in driver), + /// it only fails if driver->initStatus was already a failure. Otherwise, + /// driver->initStatus is returned (which would be SUCCESS). + /// + /// Note: Optional DDI tables (when namespace != "zer") are ignored if they + /// fail, and this function continues to attempt loading remaining tables. + /// Only required DDI table failures cause this function to fail and return + /// immediately. + /// + /// @returns + /// - ::ZE_RESULT_SUCCESS if all required DDI tables loaded successfully + /// - ::ZE_RESULT_ERROR_* if any required DDI table failed to load __zedlllocal ze_result_t ZE_APICALL zerloaderInitDriverDDITables(loader::driver_t *driver) { ze_result_t result = ZE_RESULT_SUCCESS; diff --git a/source/loader/zes_ldrddi.cpp b/source/loader/zes_ldrddi.cpp index 6fca85b6..ca14d03d 100644 --- a/source/loader/zes_ldrddi.cpp +++ b/source/loader/zes_ldrddi.cpp @@ -13,29 +13,48 @@ using namespace loader_driver_ddi; namespace loader { + /////////////////////////////////////////////////////////////////////////////// + /// @brief Initialize all DDI tables for a driver by calling *FromDriver functions + /// + /// @details This function can fail in the following scenarios: + /// - driver->initStatus is already set to a failure code (from a previous + /// required DDI initialization failure). Each *FromDriver call first checks + /// driver->initStatus and returns it immediately if it's already a failure. + /// - A required DDI table's getTable call into the driver returns a failure, + /// which updates driver->initStatus and is propagated back + /// + /// Note: If GET_FUNCTION_PTR returns null (function not found in driver), + /// it only fails if driver->initStatus was already a failure. Otherwise, + /// driver->initStatus is returned (which would be SUCCESS). + /// + /// Note: Optional DDI tables (when namespace != "zer") are ignored if they + /// fail, and this function continues to attempt loading remaining tables. + /// Only required DDI table failures cause this function to fail and return + /// immediately. + /// + /// @returns + /// - ::ZE_RESULT_SUCCESS if all required DDI tables loaded successfully + /// - ::ZE_RESULT_ERROR_* if any required DDI table failed to load __zedlllocal ze_result_t ZE_APICALL zesloaderInitDriverDDITables(loader::driver_t *driver) { ze_result_t result = ZE_RESULT_SUCCESS; - result = zesGetGlobalProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zesGetGlobalProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zesGetDeviceProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zesGetDeviceExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zesGetDeviceExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zesGetDriverProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zesGetDriverExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zesGetDriverExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zesGetDiagnosticsProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -56,10 +75,9 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zesGetFirmwareExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zesGetFirmwareExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zesGetFrequencyProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -72,10 +90,9 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zesGetOverclockProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zesGetOverclockProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zesGetPerformanceFactorProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -92,10 +109,9 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zesGetRasExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zesGetRasExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zesGetSchedulerProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -108,10 +124,9 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zesGetVFManagementExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zesGetVFManagementExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; return result; } /////////////////////////////////////////////////////////////////////////////// @@ -5056,11 +5071,7 @@ zesGetGlobalProcAddrTableFromDriver(loader::driver_t *driver) //It is valid to not have this proc addr table return ZE_RESULT_SUCCESS; } - auto getTableResult = getTable( loader::context->ddi_init_version, &driver->dditable.zes.Global); - if(getTableResult == ZE_RESULT_SUCCESS) { - loader::context->configured_version = loader::context->ddi_init_version; - } else - driver->initStatus = getTableResult; + result = getTable( loader::context->ddi_init_version, &driver->dditable.zes.Global); return result; } /////////////////////////////////////////////////////////////////////////////// @@ -5411,11 +5422,7 @@ zesGetOverclockProcAddrTableFromDriver(loader::driver_t *driver) //It is valid to not have this proc addr table return ZE_RESULT_SUCCESS; } - auto getTableResult = getTable( loader::context->ddi_init_version, &driver->dditable.zes.Overclock); - if(getTableResult == ZE_RESULT_SUCCESS) { - loader::context->configured_version = loader::context->ddi_init_version; - } else - driver->initStatus = getTableResult; + result = getTable( loader::context->ddi_init_version, &driver->dditable.zes.Overclock); return result; } /////////////////////////////////////////////////////////////////////////////// diff --git a/source/loader/zet_ldrddi.cpp b/source/loader/zet_ldrddi.cpp index 43825040..9c128323 100644 --- a/source/loader/zet_ldrddi.cpp +++ b/source/loader/zet_ldrddi.cpp @@ -13,29 +13,47 @@ using namespace loader_driver_ddi; namespace loader { + /////////////////////////////////////////////////////////////////////////////// + /// @brief Initialize all DDI tables for a driver by calling *FromDriver functions + /// + /// @details This function can fail in the following scenarios: + /// - driver->initStatus is already set to a failure code (from a previous + /// required DDI initialization failure). Each *FromDriver call first checks + /// driver->initStatus and returns it immediately if it's already a failure. + /// - A required DDI table's getTable call into the driver returns a failure, + /// which updates driver->initStatus and is propagated back + /// + /// Note: If GET_FUNCTION_PTR returns null (function not found in driver), + /// it only fails if driver->initStatus was already a failure. Otherwise, + /// driver->initStatus is returned (which would be SUCCESS). + /// + /// Note: Optional DDI tables (when namespace != "zer") are ignored if they + /// fail, and this function continues to attempt loading remaining tables. + /// Only required DDI table failures cause this function to fail and return + /// immediately. + /// + /// @returns + /// - ::ZE_RESULT_SUCCESS if all required DDI tables loaded successfully + /// - ::ZE_RESULT_ERROR_* if any required DDI table failed to load __zedlllocal ze_result_t ZE_APICALL zetloaderInitDriverDDITables(loader::driver_t *driver) { ze_result_t result = ZE_RESULT_SUCCESS; - result = zetGetMetricDecoderExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } - result = zetGetMetricProgrammableExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } - result = zetGetMetricTracerExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zetGetMetricDecoderExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zetGetMetricProgrammableExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zetGetMetricTracerExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zetGetDeviceProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zetGetDeviceExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zetGetDeviceExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zetGetContextProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -44,10 +62,9 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zetGetCommandListExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zetGetCommandListExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zetGetKernelProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; @@ -64,18 +81,16 @@ namespace loader if (result != ZE_RESULT_SUCCESS) { return result; } - result = zetGetMetricExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zetGetMetricExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zetGetMetricGroupProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result; } - result = zetGetMetricGroupExpProcAddrTableFromDriver(driver); - if (result != ZE_RESULT_SUCCESS) { - return result; - } + // Optional DDI Table, ignore failure if a driver implements the ddi table, but returns an error. + zetGetMetricGroupExpProcAddrTableFromDriver(driver); + result = ZE_RESULT_SUCCESS; result = zetGetMetricQueryProcAddrTableFromDriver(driver); if (result != ZE_RESULT_SUCCESS) { return result;