diff --git a/layers/11_semaemu/emulate.cpp b/layers/11_semaemu/emulate.cpp index 3e40b1a..d572dee 100644 --- a/layers/11_semaemu/emulate.cpp +++ b/layers/11_semaemu/emulate.cpp @@ -27,7 +27,7 @@ #endif static constexpr cl_version version_cl_khr_semaphore = - CL_MAKE_VERSION(0, 9, 1); + CL_MAKE_VERSION(1, 0, 0); SLayerContext& getLayerContext(void) { @@ -35,26 +35,39 @@ SLayerContext& getLayerContext(void) return c; } -static bool isDeviceWithinContext(const cl_context context, - const cl_device_id device) { - cl_uint numDevices = 0; - cl_int error = g_pNextDispatch->clGetContextInfo( - context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDevices, NULL); - if (error != CL_SUCCESS || numDevices == 0) - return false; +static bool isDeviceWithinContext( + const cl_context context, + const cl_device_id device) +{ + cl_uint numDevices = 0; + cl_int error = g_pNextDispatch->clGetContextInfo( + context, + CL_CONTEXT_NUM_DEVICES, + sizeof(cl_uint), + &numDevices, + nullptr); + if (error != CL_SUCCESS || numDevices == 0) { + return false; + } - std::vector devices(numDevices, 0); - error = g_pNextDispatch->clGetContextInfo(context, CL_CONTEXT_DEVICES, - numDevices * sizeof(cl_device_id), - devices.data(), NULL); - if (error != CL_SUCCESS) - return false; + std::vector devices(numDevices); + error = g_pNextDispatch->clGetContextInfo( + context, + CL_CONTEXT_DEVICES, + numDevices * sizeof(cl_device_id), + devices.data(), + nullptr); + if (error != CL_SUCCESS) { + return false; + } - for (auto dev : devices) - if (dev == device) - return true; + for (auto check : devices) { + if (check == device) { + return true; + } + } - return false; + return false; } typedef struct _cl_semaphore_khr @@ -64,21 +77,24 @@ typedef struct _cl_semaphore_khr const cl_semaphore_properties_khr* properties, cl_int* errcode_ret) { - cl_semaphore_khr semaphore = NULL; + cl_semaphore_khr semaphore = nullptr; cl_int errorCode = CL_SUCCESS; ptrdiff_t numProperties = 0; cl_semaphore_type_khr type = ~0; - std::vector devices; - if ( properties == nullptr ) + if( properties == nullptr ) + { errorCode = CL_INVALID_VALUE; + } - if ( context == nullptr ) + if( context == nullptr ) + { errorCode = CL_INVALID_CONTEXT; + } - if( errorCode == CL_SUCCESS && properties ) + if( errorCode == CL_SUCCESS ) { const cl_semaphore_properties_khr* check = properties; bool found_CL_SEMAPHORE_TYPE_KHR = false; @@ -98,6 +114,15 @@ typedef struct _cl_semaphore_khr found_CL_SEMAPHORE_TYPE_KHR = true; type = ((const cl_semaphore_type_khr*)(check + 1))[0]; check += 2; + + switch( type ) + { + case CL_SEMAPHORE_TYPE_BINARY_KHR: + break; + default: + errorCode = CL_INVALID_PROPERTY; + break; + } } break; case CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR: @@ -111,7 +136,8 @@ typedef struct _cl_semaphore_khr check++; while(*check != CL_SEMAPHORE_DEVICE_HANDLE_LIST_END_KHR) { - devices.push_back(((cl_device_id*)check)[0]); + cl_device_id device = ((cl_device_id*)check)[0]; + devices.push_back(device); check++; } check++; @@ -124,41 +150,55 @@ typedef struct _cl_semaphore_khr } numProperties = check - properties + 1; - if ( errorCode == CL_SUCCESS && type == ~0) + // The semaphore type must be included in the property list. + if( !found_CL_SEMAPHORE_TYPE_KHR ) + { errorCode = CL_INVALID_VALUE; + } - // validate device handles. - if (!devices.empty()) { - // for now - if CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR is specified - // as part of sema_props, but it does not identify exactly one - // valid device - if (devices.size() > 1) { - errorCode = CL_INVALID_DEVICE; - } else { - // if a device identified by CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR - // is not one of the devices within context - std::vector types; - for (auto device : devices) { - if (device == nullptr || - !isDeviceWithinContext(context, device)) { + if( devices.empty() ) + { + // If the device handle list is empty, the semaphore is + // accessible to all devices in the context, and the context + // must be a single-device context. + cl_uint numDevices = 0; + g_pNextDispatch->clGetContextInfo( + context, + CL_CONTEXT_NUM_DEVICES, + sizeof(cl_uint), + &numDevices, + nullptr); + if( numDevices != 1 ) + { + errorCode = CL_INVALID_PROPERTY; + } + } + else + { + // If the device handle list is present, it must contain + // exactly one device. + if( devices.size() != 1 ) + { errorCode = CL_INVALID_DEVICE; - break; - } } - } + else + { + // Additionally, the device must be within the context. + for( auto device : devices ) + { + if( device == nullptr || + !isDeviceWithinContext(context, device) ) + { + errorCode = CL_INVALID_DEVICE; + break; + } + } + } } } - - if (errorCode == CL_SUCCESS) { - switch (type) { - case CL_SEMAPHORE_TYPE_BINARY_KHR: - break; - default: - errorCode = CL_INVALID_PROPERTY; - } - } - if (errcode_ret) { - errcode_ret[0] = errorCode; + if( errcode_ret ) + { + errcode_ret[0] = errorCode; } if( errorCode == CL_SUCCESS ) { @@ -168,7 +208,6 @@ typedef struct _cl_semaphore_khr semaphore->Properties.begin(), properties, properties + numProperties ); - semaphore->Devices=devices; } return semaphore; @@ -196,7 +235,7 @@ typedef struct _cl_semaphore_khr Context(context), Type(type), RefCount(1), - Event(NULL) {} + Event(nullptr) {} } cli_semaphore; cl_semaphore_khr CL_API_CALL clCreateSemaphoreWithPropertiesKHR_EMU( @@ -236,7 +275,7 @@ cl_int CL_API_CALL clEnqueueWaitSemaphoresKHR_EMU( { return CL_INVALID_SEMAPHORE_KHR; } - if( semaphores[i]->Event == NULL ) + if( semaphores[i]->Event == nullptr ) { // This is a semaphore that is not in a pending signal // or signaled state. What should happen here? @@ -256,7 +295,7 @@ cl_int CL_API_CALL clEnqueueWaitSemaphoresKHR_EMU( { g_pNextDispatch->clReleaseEvent( semaphores[i]->Event); - semaphores[i]->Event = NULL; + semaphores[i]->Event = nullptr; } if( event ) @@ -287,7 +326,7 @@ cl_int CL_API_CALL clEnqueueSignalSemaphoresKHR_EMU( { return CL_INVALID_SEMAPHORE_KHR; } - if( semaphores[i]->Event != NULL ) + if( semaphores[i]->Event != nullptr ) { // This is a semaphore that is in a pending signal or signaled // state. What should happen here? @@ -295,8 +334,8 @@ cl_int CL_API_CALL clEnqueueSignalSemaphoresKHR_EMU( } } - cl_event local_event = NULL; - if( event == NULL ) + cl_event local_event = nullptr; + if( event == nullptr ) { event = &local_event; } @@ -314,11 +353,11 @@ cl_int CL_API_CALL clEnqueueSignalSemaphoresKHR_EMU( semaphores[i]->Event ); } - if( local_event != NULL ) + if( local_event != nullptr ) { g_pNextDispatch->clReleaseEvent( local_event ); - local_event = NULL; + local_event = nullptr; } else { @@ -386,7 +425,7 @@ cl_int CL_API_CALL clGetSemaphoreInfoKHR_EMU( // semaphore is in the unsignaled state and one if it is in // the signaled state. cl_semaphore_payload_khr payload = 0; - if( semaphore->Event != NULL ) + if( semaphore->Event != nullptr ) { cl_int eventStatus = 0; g_pNextDispatch->clGetEventInfo( @@ -394,7 +433,7 @@ cl_int CL_API_CALL clGetSemaphoreInfoKHR_EMU( CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( eventStatus ), &eventStatus, - NULL ); + nullptr ); if( eventStatus == CL_COMPLETE ) { payload = 1; @@ -555,7 +594,7 @@ bool clGetDeviceInfo_override( memset(extension.name, 0, CL_NAME_VERSION_MAX_NAME_SIZE); strcpy(extension.name, CL_KHR_SEMAPHORE_EXTENSION_NAME); - extension.version = CL_MAKE_VERSION(0, 9, 0); + extension.version = version_cl_khr_semaphore; auto ptr = (cl_name_version*)param_value; cl_int errorCode = writeVectorToMemory( @@ -734,7 +773,7 @@ bool clGetPlatformInfo_override( memset(extension.name, 0, CL_NAME_VERSION_MAX_NAME_SIZE); strcpy(extension.name, CL_KHR_SEMAPHORE_EXTENSION_NAME); - extension.version = CL_MAKE_VERSION(0, 9, 0); + extension.version = version_cl_khr_semaphore; auto ptr = (cl_name_version*)param_value; cl_int errorCode = writeVectorToMemory( diff --git a/layers/11_semaemu/main.cpp b/layers/11_semaemu/main.cpp index 0a80417..7fe66b7 100644 --- a/layers/11_semaemu/main.cpp +++ b/layers/11_semaemu/main.cpp @@ -88,7 +88,17 @@ clGetEventInfo_layer( return errorCode; } - +static cl_int CL_API_CALL +clGetSemaphoreHandleForTypeKHR_EMU( + cl_semaphore_khr sema_object, + cl_device_id device, + cl_external_semaphore_handle_type_khr handle_type, + size_t handle_size, + void* handle_ptr, + size_t* handle_size_ret) +{ + return CL_INVALID_OPERATION; +} #define CHECK_RETURN_EXTENSION_FUNCTION( _funcname ) \ if (strcmp(func_name, #_funcname) == 0) { \ @@ -109,6 +119,11 @@ clGetExtensionFunctionAddressForPlatform_layer( CHECK_RETURN_EXTENSION_FUNCTION( clRetainSemaphoreKHR ); CHECK_RETURN_EXTENSION_FUNCTION( clReleaseSemaphoreKHR ); + // This is currently required to run the semaphore conformance tests, + // although it is part of cl_khr_external_semaphore, and not part of + // cl_khr_semaphore. + CHECK_RETURN_EXTENSION_FUNCTION( clGetSemaphoreHandleForTypeKHR ); + return g_pNextDispatch->clGetExtensionFunctionAddressForPlatform( platform, func_name);