diff --git a/layers/10_cmdbufemu/emulate.cpp b/layers/10_cmdbufemu/emulate.cpp index 0251c6b..1505cb3 100644 --- a/layers/10_cmdbufemu/emulate.cpp +++ b/layers/10_cmdbufemu/emulate.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,8 @@ const cl_mutable_dispatch_fields_khr g_MutableDispatchCaps = #if !defined(CL_MUTABLE_DISPATCH_ASSERTS_KHR) typedef cl_bitfield cl_mutable_dispatch_asserts_khr; -#define CL_MUTABLE_DISPATCH_ASSERTS_KHR 0x12B7 +#define CL_COMMAND_BUFFER_MUTABLE_DISPATCH_ASSERTS_KHR 0x12B7 +#define CL_MUTABLE_DISPATCH_ASSERTS_KHR 0x12B8 #define CL_MUTABLE_DISPATCH_ASSERT_NO_ADDITIONAL_WORK_GROUPS_KHR (1 << 0) #endif // !defined(CL_MUTABLE_DISPATCH_ASSERTS_KHR) @@ -826,8 +826,8 @@ struct NDRangeKernel : Command ptrdiff_t numProperties = 0; #if defined(cl_khr_command_buffer_mutable_dispatch) cl_mutable_dispatch_fields_khr mutableFields = g_MutableDispatchCaps; - cl_mutable_dispatch_asserts_khr mutableDispatchAsserts = 0; -#endif + cl_mutable_dispatch_asserts_khr mutableAsserts = 0; +#endif // defined(cl_khr_command_buffer_mutable_dispatch) if( properties ) { @@ -862,11 +862,11 @@ struct NDRangeKernel : Command else { found_CL_MUTABLE_DISPATCH_ASSERTS_KHR = true; - mutableDispatchAsserts = ((const cl_mutable_dispatch_asserts_khr*)(check + 1))[0]; + mutableAsserts = ((const cl_mutable_dispatch_asserts_khr*)(check + 1))[0]; check += 2; } break; -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) default: errorCode = CL_INVALID_VALUE; return nullptr; @@ -875,6 +875,22 @@ struct NDRangeKernel : Command numProperties = check - properties + 1; } +#if defined(cl_khr_command_buffer_mutable_dispatch) + if( local_work_size == nullptr ) + { + // The current spec says that the behavior of this assertion is + // undefined when the local work size is NULL, but it seems safest + // to return an error in this case. + // Note, this currently only checks the per-command asserts, and + // does not currently check the global command buffer asserts! + if( mutableAsserts & CL_MUTABLE_DISPATCH_ASSERT_NO_ADDITIONAL_WORK_GROUPS_KHR ) + { + errorCode = CL_INVALID_WORK_GROUP_SIZE; + return nullptr; + } + } +#endif // defined(cl_khr_command_buffer_mutable_dispatch) + auto command = std::unique_ptr( new NDRangeKernel(cmdbuf, queue)); @@ -884,12 +900,12 @@ struct NDRangeKernel : Command #if defined(cl_khr_command_buffer_mutable_dispatch) command->mutableFields = mutableFields; - command->mutableDispatchAsserts = mutableDispatchAsserts; + command->mutableAsserts = mutableAsserts; command->numWorkGroups = getNumWorkGroups( work_dim, global_work_size, local_work_size ); -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) command->properties.reserve(numProperties); command->properties.insert( @@ -1043,7 +1059,7 @@ struct NDRangeKernel : Command } cl_int mutate( - const cl_mutable_dispatch_asserts_khr commandBufferMutableDispatchAsserts, + const cl_mutable_dispatch_asserts_khr mutableAssertsCmdBuf, const cl_mutable_dispatch_config_khr* dispatchConfig ) { //CL_INVALID_OPERATION if values of local_work_size and/or global_work_size result in an increase to the number of work-groups in the ND-range. @@ -1129,24 +1145,33 @@ struct NDRangeKernel : Command } } - if( commandBufferMutableDispatchAsserts & CL_MUTABLE_DISPATCH_ASSERT_NO_ADDITIONAL_WORK_GROUPS_KHR || - mutableDispatchAsserts & CL_MUTABLE_DISPATCH_ASSERT_NO_ADDITIONAL_WORK_GROUPS_KHR ) + if( mutableAssertsCmdBuf & CL_MUTABLE_DISPATCH_ASSERT_NO_ADDITIONAL_WORK_GROUPS_KHR || + mutableAsserts & CL_MUTABLE_DISPATCH_ASSERT_NO_ADDITIONAL_WORK_GROUPS_KHR ) { const size_t* check_global_work_size = dispatchConfig->global_work_size ? dispatchConfig->global_work_size : - global_work_size.data(); + global_work_size.size() > 0 ? + global_work_size.data() : + nullptr; const size_t* check_local_work_size = dispatchConfig->local_work_size ? dispatchConfig->local_work_size : - local_work_size.data(); + local_work_size.size() > 0 ? + local_work_size.data() : + nullptr; + if( check_local_work_size == nullptr ) + { + return CL_INVALID_WORK_GROUP_SIZE; + } + size_t newNumWorkGroups = getNumWorkGroups( work_dim, check_global_work_size, check_local_work_size ); if( newNumWorkGroups > numWorkGroups ) { - return CL_INVALID_OPERATION; + return CL_INVALID_WORK_GROUP_SIZE; } } @@ -1198,9 +1223,9 @@ struct NDRangeKernel : Command cl_uint work_dim = 0; #if defined(cl_khr_command_buffer_mutable_dispatch) cl_mutable_dispatch_fields_khr mutableFields = 0; - cl_mutable_dispatch_asserts_khr mutableDispatchAsserts = 0; + cl_mutable_dispatch_asserts_khr mutableAsserts = 0; size_t numWorkGroups = 0; -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) std::vector properties; std::vector global_work_offset; std::vector global_work_size; @@ -1222,11 +1247,6 @@ struct NDRangeKernel : Command return 1; } - if( local_work_size == nullptr ) - { - return std::numeric_limits::max(); - } - size_t count = 1; for( cl_uint i = 0; i < work_dim; i++ ) { @@ -1264,7 +1284,7 @@ typedef struct _cl_command_buffer_khr { const cl_command_buffer_properties_khr* check = properties; bool found_CL_COMMAND_BUFFER_FLAGS_KHR = false; - bool found_CL_MUTABLE_DISPATCH_ASSERTS_KHR = false; + bool found_CL_COMMAND_BUFFER_MUTABLE_DISPATCH_ASSERTS_KHR = false; while( errorCode == CL_SUCCESS && check[0] != 0 ) { cl_int property = (cl_int)check[0]; @@ -1283,14 +1303,14 @@ typedef struct _cl_command_buffer_khr } break; #if defined(cl_khr_command_buffer_mutable_dispatch) - case CL_MUTABLE_DISPATCH_ASSERTS_KHR: - if( found_CL_MUTABLE_DISPATCH_ASSERTS_KHR ) + case CL_COMMAND_BUFFER_MUTABLE_DISPATCH_ASSERTS_KHR: + if( found_CL_COMMAND_BUFFER_MUTABLE_DISPATCH_ASSERTS_KHR ) { errorCode = CL_INVALID_VALUE; } else { - found_CL_MUTABLE_DISPATCH_ASSERTS_KHR = true; + found_CL_COMMAND_BUFFER_MUTABLE_DISPATCH_ASSERTS_KHR = true; mutableDispatchAsserts = ((const cl_mutable_dispatch_asserts_khr*)(check + 1))[0]; check += 2; } @@ -1448,7 +1468,7 @@ typedef struct _cl_command_buffer_khr ptr ); } break; -#endif +#endif // defined(CL_COMMAND_BUFFER_CONTEXT_KHR) default: break; } @@ -2328,7 +2348,7 @@ cl_int CL_API_CALL clCommandNDRangeKernelKHR_EMU( { return CL_INVALID_VALUE; } -#endif // cl_khr_command_buffer_mutable_dispatch +#endif // !defined(cl_khr_command_buffer_mutable_dispatch) cl_int errorCode = CL_SUCCESS; auto command = NDRangeKernel::create( @@ -2398,7 +2418,7 @@ cl_command_buffer_khr CL_API_CALL clRemapCommandBufferKHR_EMU( return nullptr; } -#endif +#endif // defined(cl_khr_command_buffer_multi_device) #if defined(cl_khr_command_buffer_mutable_dispatch) @@ -2500,7 +2520,7 @@ bool clGetDeviceInfo_override( #if defined(cl_khr_command_buffer_mutable_dispatch) newExtensions += ' '; newExtensions += CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_NAME; -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) std::string oldExtensions(deviceExtensions.data()); @@ -2600,7 +2620,7 @@ bool clGetDeviceInfo_override( extension.version = version_cl_khr_command_buffer_mutable_dispatch; } -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) auto ptr = (cl_name_version*)param_value; cl_int errorCode = writeVectorToMemory( @@ -2700,7 +2720,7 @@ bool clGetDeviceInfo_override( return true; } break; -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) default: break; } @@ -2832,7 +2852,7 @@ bool clGetPlatformInfo_override( #if defined(cl_khr_command_buffer_mutable_dispatch) newExtensions += ' '; newExtensions += CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_NAME; -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) std::string oldExtensions(platformExtensions.data()); @@ -2932,7 +2952,7 @@ bool clGetPlatformInfo_override( extension.version = version_cl_khr_command_buffer_mutable_dispatch; } -#endif +#endif // defined(cl_khr_command_buffer_mutable_dispatch) auto ptr = (cl_name_version*)param_value; cl_int errorCode = writeVectorToMemory(