|
13 | 13 |
|
14 | 14 | namespace validation_layer |
15 | 15 | { |
| 16 | + // Forward declaration for Intel experimental extension |
| 17 | + // This is needed because zeDriverGetExtensionFunctionAddress needs to reference zexCounterBasedEventCreate2 |
| 18 | + __zedlllocal ze_result_t ZE_APICALL zexCounterBasedEventCreate2( |
| 19 | + ze_context_handle_t hContext, |
| 20 | + ze_device_handle_t hDevice, |
| 21 | + const void *desc, |
| 22 | + ze_event_handle_t *phEvent |
| 23 | + ); |
| 24 | + |
16 | 25 | static ze_result_t logAndPropagateResult(const char* fname, ze_result_t result) { |
17 | 26 | if (result != ZE_RESULT_SUCCESS) { |
18 | 27 | context.logger->log_trace("Error (" + loader::to_string(result) + ") in " + std::string(fname)); |
@@ -382,6 +391,15 @@ namespace validation_layer |
382 | 391 |
|
383 | 392 | auto driver_result = pfnGetExtensionFunctionAddress( hDriver, name, ppFunctionAddress ); |
384 | 393 |
|
| 394 | + // For Intel experimental extensions, we need to return our validation layer function |
| 395 | + // instead of the raw driver function so that validation/leak tracking works |
| 396 | + if (driver_result == ZE_RESULT_SUCCESS && ppFunctionAddress && name) { |
| 397 | + if (strcmp(name, "zexCounterBasedEventCreate2") == 0) { |
| 398 | + // Return our validation layer intercept function instead of the raw driver function |
| 399 | + *ppFunctionAddress = (void*)zexCounterBasedEventCreate2; |
| 400 | + } |
| 401 | + } |
| 402 | + |
385 | 403 | for (size_t i = 0; i < numValHandlers; i++) { |
386 | 404 | auto result = context.validationHandlers[i]->zeValidation->zeDriverGetExtensionFunctionAddressEpilogue( hDriver, name, ppFunctionAddress ,driver_result); |
387 | 405 | if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zeDriverGetExtensionFunctionAddress", result); |
@@ -9411,7 +9429,97 @@ namespace validation_layer |
9411 | 9429 |
|
9412 | 9430 | return logAndPropagateResult("zeCommandListUpdateMutableCommandKernelsExp", driver_result); |
9413 | 9431 | } |
| 9432 | + /////////////////////////////////////////////////////////////////////////////// |
| 9433 | + /// @brief Intercept function for zexCounterBasedEventCreate2 |
| 9434 | + __zedlllocal ze_result_t ZE_APICALL zexCounterBasedEventCreate2( |
| 9435 | + ze_context_handle_t hContext, ///< [in] handle of the context object |
| 9436 | + ze_device_handle_t hDevice, ///< [in] handle of the device |
| 9437 | + const void *desc, ///< [in] pointer to counter-based event descriptor |
| 9438 | + ze_event_handle_t *phEvent ///< [out] pointer to handle of event object created |
| 9439 | + ) { |
| 9440 | + context.logger->log_trace( |
| 9441 | + "zexCounterBasedEventCreate2(hContext, hDevice, desc, phEvent)"); |
9414 | 9442 |
|
| 9443 | + // Note: This is an experimental function that may not have a DDI table entry. |
| 9444 | + // For now, we'll return unsupported feature as this function should be |
| 9445 | + // accessed through zeDriverGetExtensionFunctionAddress mechanism, but we |
| 9446 | + // still want to track it in the validation layers for leak checking purposes. |
| 9447 | + |
| 9448 | + auto numValHandlers = context.validationHandlers.size(); |
| 9449 | + for (size_t i = 0; i < numValHandlers; i++) { |
| 9450 | + auto result = context.validationHandlers[i] |
| 9451 | + ->zeValidation->zexCounterBasedEventCreate2Prologue( |
| 9452 | + hContext, hDevice, desc, phEvent); |
| 9453 | + if (result != ZE_RESULT_SUCCESS) |
| 9454 | + return logAndPropagateResult("zexCounterBasedEventCreate2", result); |
| 9455 | + } |
| 9456 | + |
| 9457 | + if (context.enableThreadingValidation) { |
| 9458 | + // Unimplemented |
| 9459 | + } |
| 9460 | + |
| 9461 | + if (context.enableHandleLifetime) { |
| 9462 | + auto result = context.handleLifetime->zeHandleLifetime |
| 9463 | + .zexCounterBasedEventCreate2Prologue(hContext, hDevice, |
| 9464 | + desc, phEvent); |
| 9465 | + if (result != ZE_RESULT_SUCCESS) |
| 9466 | + return logAndPropagateResult("zexCounterBasedEventCreate2", result); |
| 9467 | + } |
| 9468 | + |
| 9469 | + // This is an experimental function that must be accessed through the extension mechanism |
| 9470 | + // We need to get the function pointer through zeDriverGetExtensionFunctionAddress |
| 9471 | + ze_result_t driver_result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; |
| 9472 | + |
| 9473 | + // Get the real Intel experimental function through the extension mechanism |
| 9474 | + auto pfnGetExtensionFunctionAddress = context.zeDdiTable.Driver.pfnGetExtensionFunctionAddress; |
| 9475 | + |
| 9476 | + if (pfnGetExtensionFunctionAddress) { |
| 9477 | + // Get the driver handle - use the first available driver |
| 9478 | + ze_driver_handle_t hDriver = nullptr; |
| 9479 | + |
| 9480 | + if (context.zeDdiTable.Driver.pfnGet) { |
| 9481 | + uint32_t driverCount = 1; |
| 9482 | + ze_driver_handle_t drivers[1] = {nullptr}; |
| 9483 | + auto result = context.zeDdiTable.Driver.pfnGet(&driverCount, drivers); |
| 9484 | + if (result == ZE_RESULT_SUCCESS && driverCount > 0) { |
| 9485 | + hDriver = drivers[0]; |
| 9486 | + } |
| 9487 | + } |
| 9488 | + |
| 9489 | + if (hDriver) { |
| 9490 | + // Get the real Intel experimental function |
| 9491 | + typedef ze_result_t (*zexCounterBasedEventCreate2_t)(ze_context_handle_t, ze_device_handle_t, const void*, ze_event_handle_t*); |
| 9492 | + zexCounterBasedEventCreate2_t pfnRealFunction = nullptr; |
| 9493 | + |
| 9494 | + auto ext_result = pfnGetExtensionFunctionAddress(hDriver, "zexCounterBasedEventCreate2", (void**)&pfnRealFunction); |
| 9495 | + |
| 9496 | + if (ext_result == ZE_RESULT_SUCCESS && pfnRealFunction) { |
| 9497 | + // Call the real Intel experimental function |
| 9498 | + driver_result = pfnRealFunction(hContext, hDevice, desc, phEvent); |
| 9499 | + } else { |
| 9500 | + // Extension not available in this driver |
| 9501 | + driver_result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; |
| 9502 | + } |
| 9503 | + } |
| 9504 | + } |
| 9505 | + |
| 9506 | + for (size_t i = 0; i < numValHandlers; i++) { |
| 9507 | + auto result = context.validationHandlers[i] |
| 9508 | + ->zeValidation->zexCounterBasedEventCreate2Epilogue( |
| 9509 | + hContext, hDevice, desc, phEvent, driver_result); |
| 9510 | + if (result != ZE_RESULT_SUCCESS) |
| 9511 | + return logAndPropagateResult("zexCounterBasedEventCreate2", result); |
| 9512 | + } |
| 9513 | + |
| 9514 | + if (driver_result == ZE_RESULT_SUCCESS && context.enableHandleLifetime) { |
| 9515 | + if (phEvent) { |
| 9516 | + context.handleLifetime->addHandle(*phEvent); |
| 9517 | + // Note: counter-based events may not have a traditional event pool |
| 9518 | + // dependency |
| 9519 | + } |
| 9520 | + } |
| 9521 | + return logAndPropagateResult("zexCounterBasedEventCreate2", driver_result); |
| 9522 | + } |
9415 | 9523 | } // namespace validation_layer |
9416 | 9524 |
|
9417 | 9525 | #if defined(__cplusplus) |
|
0 commit comments