Browse Source

Platform: minor whitespace, doc and error handling cleanup.

In particular, the "likely a driver issue" messages don't apply here.
pull/454/head
Vladimír Vondruš 6 years ago
parent
commit
2803ccb241
  1. 39
      src/Magnum/Platform/WindowlessEglApplication.cpp
  2. 34
      src/Magnum/Platform/WindowlessEglApplication.h

39
src/Magnum/Platform/WindowlessEglApplication.cpp

@ -162,44 +162,49 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G
UnsignedInt selectedDevice;
Containers::Array<EGLDeviceEXT> devices;
if (configuration.cudaDevice() != (~UnsignedInt{})) {
if (!(extensionSupported(extensions, "EGL_EXT_device_query") || extensionSupported(extensions, "EGL_EXT_device_base"))) {
/* Look for CUDA devices */
if(configuration.cudaDevice() != ~UnsignedInt{}) {
if(!(extensionSupported(extensions, "EGL_EXT_device_query") || extensionSupported(extensions, "EGL_EXT_device_base"))) {
Error e;
e << "Platform::WindowlessEglApplication: CUDA device selection requires 'EGL_EXT_device_query' or 'EGL_EXT_device_base' extension, likely a driver issue";
if(!magnumContext || !(magnumContext->internalFlags() & GL::Context::InternalFlag::GpuValidation))
e << Debug::nospace << "; enable --magnum-gpu-validation to see additional info";
e << "Platform::WindowlessEglApplication: CUDA device selection requires EGL_EXT_device_query or EGL_EXT_device_base extensions";
return;
}
devices = Containers::Array<EGLDeviceEXT>{MaxEGLDevices};
/* Assuming the same thing won't suddenly start failing when
called the second time */
CORRADE_INTERNAL_ASSERT_OUTPUT(eglQueryDevices(devices.size(), devices, &count));
auto eglQueryDeviceAttribEXT = reinterpret_cast<EGLBoolean (*)(EGLDeviceEXT, EGLint, EGLAttrib*)>(eglGetProcAddress("eglQueryDeviceAttribEXT"));
auto eglQueryDeviceStringEXT = reinterpret_cast<const char* (*)(EGLDeviceEXT, EGLint)>(eglGetProcAddress("eglQueryDeviceStringEXT"));
for (selectedDevice = 0; selectedDevice < UnsignedInt(count); ++selectedDevice) {
/* Go through the EGL devices and find one that has the desired
CUDA device number */
for(selectedDevice = 0; selectedDevice < UnsignedInt(count); ++selectedDevice) {
if(magnumContext && (magnumContext->internalFlags() >= GL::Context::InternalFlag::DisplayVerboseInitializationLog))
Debug{} << "Platform::WindowlessEglApplication: eglQueryDeviceStringEXT(EGLDevice=" << Debug::nospace << selectedDevice << Debug::nospace << "):" << eglQueryDeviceStringEXT(devices[selectedDevice], EGL_EXTENSIONS);
EGLAttrib cudaDeviceNumber;
if ((eglQueryDeviceAttribEXT(devices[selectedDevice], EGL_CUDA_DEVICE_NV, &cudaDeviceNumber) == EGL_TRUE) && (cudaDeviceNumber == configuration.cudaDevice())) {
if(eglQueryDeviceAttribEXT(devices[selectedDevice], EGL_CUDA_DEVICE_NV, &cudaDeviceNumber) && cudaDeviceNumber == configuration.cudaDevice())
break;
}
}
if (selectedDevice == UnsignedInt(count)) {
/* None found */
if(selectedDevice == UnsignedInt(count)) {
Error e;
e << "Platform::WindowlessEglApplication::tryCreateContext(): Unable to find EGL device for CUDA device" << configuration.cudaDevice();
if (!magnumContext || !(magnumContext->internalFlags() &
GL::Context::InternalFlag::GpuValidation))
e << Debug::nospace << "; enable --magnum-gpu-validation to see additional info";
e << "Platform::WindowlessEglApplication::tryCreateContext(): unable to find EGL device for CUDA device" << configuration.cudaDevice();
return;
}
if(magnumContext && (magnumContext->internalFlags() >= GL::Context::InternalFlag::DisplayVerboseInitializationLog)) {
Debug{} << "Platform::WindowlessEglApplication: found" << count << "EGL devices, choosing EGL device" << selectedDevice << "for CUDA device" << configuration.cudaDevice();
}
/* Otherwise just a normal EGL device */
} else {
devices = Containers::Array<EGLDeviceEXT>{configuration.device() + 1};
/* Assuming the same thing won't suddenly start failing when called the
second time */
/* Assuming the same thing won't suddenly start failing when
called the second time */
CORRADE_INTERNAL_ASSERT_OUTPUT(eglQueryDevices(configuration.device() + 1, devices, &count));
selectedDevice = configuration.device();
if(magnumContext && (magnumContext->internalFlags() >= GL::Context::InternalFlag::DisplayVerboseInitializationLog)) {
@ -497,7 +502,7 @@ WindowlessEglApplication::WindowlessEglApplication(const Arguments& arguments, N
#ifndef MAGNUM_TARGET_WEBGL
args.addOption("device", "").setHelp("device", "GPU device to use", "N")
.setFromEnvironment("device")
.addOption("cuda-device", "").setHelp("cuda-device", "CUDA device to use. Supersedes --magnum-device.", "N")
.addOption("cuda-device", "").setHelp("cuda-device", "CUDA device to use. Takes precedence over --magnum-device.", "N")
.setFromEnvironment("cuda-device");
#endif
_context.reset(new GLContext{NoCreate, args, arguments.argc, arguments.argv});

34
src/Magnum/Platform/WindowlessEglApplication.h

@ -266,6 +266,9 @@ class WindowlessEglContext::Configuration {
* set, this value is ignored and the device is picked to be the same
* as in the shared context instead.
*
* By default it's set to @cpp 0 @ce, taking the first found EGL
* device.
* @see @ref setCudaDevice()
* @requires_gles Device selection is not available in WebGL.
*/
Configuration& setDevice(UnsignedInt id) {
@ -280,20 +283,20 @@ class WindowlessEglContext::Configuration {
*/
UnsignedInt cudaDevice() const { return _cudaDevice; }
/**
* @brief Set the CUDA device ID to use
* @return Reference to self (for method chaining)
*
* The device ID is expected to be smaller than the count of devices
* reported by EGL. When using @ref WindowlessEglApplication, this is
* also exposed as a `--magnum-cuda-device` command-line option and a
* `MAGNUM_CUDA_DEVICE` environment variable. If @ref setSharedContext() is
* set, this value is ignored and the device is picked to be the same
* as in the shared context instead.
*
* Takes precedence over the device ID set with @ref setDevice().
* If a device with given CUDA ID is not found, context creation fails.
* When using @ref WindowlessEglApplication, this is also exposed as a
* `--magnum-cuda-device` command-line option and a
* `MAGNUM_CUDA_DEVICE` environment variable. If @ref setSharedContext()
* is set, this value is ignored and the device is picked to be the
* same as in the shared context instead.
*
* If a CUDA device is set, it takes precedence over the device ID set
* with @ref setDevice(). By default it's set to @cpp 0xffffffffu @ce,
* indicating that @ref setDevice() is used instead.
* @requires_gles Device selection is not available in WebGL.
*/
Configuration& setCudaDevice(UnsignedInt id) {
@ -340,7 +343,7 @@ class WindowlessEglContext::Configuration {
#ifndef MAGNUM_TARGET_WEBGL
Flags _flags;
UnsignedInt _device;
// Assumes that you can't have 2^32 - 1 GPUs
/* Assumes that you can't have 2^32 - 1 GPUs */
UnsignedInt _cudaDevice = ~UnsignedInt{};
EGLDisplay _sharedDisplay = EGL_NO_DISPLAY;
EGLContext _sharedContext = EGL_NO_CONTEXT;
@ -478,11 +481,12 @@ filter named devices, so the best you can do is checking reported device count
printed by the `--magnum-log verbose` @ref GL-Context-command-line "command-line option",
and then going from `0` up to figure out the desired device ID.
On systems with modern NVIDIA GPU(s)/CUDA, the device ID can also be interpreted as a CUDA device ID
(allowing for EGL and CUDA to both target the same physical device for a given ID). This can be
enabled via the `--magnum-cuda-device` command-line option (and the `MAGNUM_CUDA_DEVICE` environment variable).
If either of these are present, they take precedence over `--magnum-device`. This can also be specified
via @ref Configuration::setCudaDevice.
On systems with NVIDIA GPUs and CUDA, it's possible to directly select a
particular CUDA device, allowing for EGL and CUDA to both target the same
physical device for a given ID. This can be chosen via the
`--magnum-cuda-device` command-line option (and the `MAGNUM_CUDA_DEVICE`
environment variable), which then takes precedence over `--magnum-device`. The
same can be also specified via via @ref Configuration::setCudaDevice().
@m_class{m-block m-danger}

Loading…
Cancel
Save