Skip to content
Snippets Groups Projects
Commit b1254327 authored by Jens Nolte's avatar Jens Nolte
Browse files

Refactor EGL device enumeration code

parent f36ad41f
No related branches found
No related tags found
No related merge requests found
......@@ -80,7 +80,6 @@ library
unix,
unordered-containers,
utf8-string,
vector,
xml,
extra-libraries: EGL, GLESv2
hs-source-dirs:
......
......@@ -10,7 +10,6 @@ import Control.Exception
import Data.Foldable (elem)
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Vector.Storable.Mutable qualified as V
import Foreign
import Foreign.C.Error
import Foreign.C.String
......@@ -55,63 +54,27 @@ instance Show EglException where
show (EglException 0x300e) = "EGL_CONTEXT_LOST"
show _ = "Invalid EGL error number"
loadEglExtensionFunctions :: IO ()
loadEglExtensionFunctions =
[CU.block|
void {
eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT");
// if (eglQueryDevicesEXT == NULL) {
// return NULL;
// }
}
|]
eglGetError :: IO EglException
eglGetError = EglException <$> [CU.exp| EGLint { eglGetError() } |]
initializeEgl :: IO ()
initializeEgl = do
loadEglExtensionFunctions
clientExtensionsString <-
eglQueryString
[CU.pure|EGLDisplay { EGL_NO_DISPLAY }|]
[CU.pure|EGLint { EGL_EXTENSIONS }|]
deviceCount <- throwErrnoIfMinus1 "eglQueryDevicesEXT"
[CU.block|
EGLint {
EGLint count;
EGLBoolean result = eglQueryDevicesEXT(0, NULL, &count);
if (!result) {
return -1;
}
return count;
}
|]
traceIO $ "Available EGL devices: " <> show deviceCount
traceIO $ mconcat ["EGL client extensions: ", clientExtensionsString]
devices :: V.IOVector EGLDeviceEXT <- V.new (fromIntegral deviceCount)
V.unsafeWith devices \devicesPtr ->
throwErrnoIf_ (== 0) "eglQueryDevicesEXT"
[CU.block|
EGLBoolean {
EGLint count;
EGLBoolean result = eglQueryDevicesEXT($(EGLint deviceCount), $(EGLDeviceEXT* devicesPtr), &count);
if (count < $(EGLint deviceCount)) {
return EGL_FALSE;
}
return result;
}
|]
let clientExtensions = Set.fromList (words clientExtensionsString)
V.iforM_ devices \i device -> do
vendor <- eglQueryDeviceString device [CU.pure|EGLint { EGL_EXTENSIONS }|]
traceIO $ mconcat ["Device ", show i, ": ", vendor]
renderNode <- eglTryQueryDeviceString device [CU.pure|EGLint { EGL_DRM_RENDER_NODE_FILE_EXT }|]
traceIO $ mconcat ["Device ", show i, ": ", show renderNode]
unless ("EGL_EXT_device_enumeration" `elem` clientExtensions && "EGL_EXT_device_query" `elem` clientExtensions) do
fail "Missing extensions for device enumeration"
display <- getEglDisplayDevice
traceIO "Using device 0"
device <- V.read devices 0
display <- throwErrnoIfNull "eglGetPlatformDisplay"
[CU.exp|EGLDisplay { eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, $(EGLDeviceEXT device), NULL) }|]
--when ("EGL_MESA_platform_surfaceless" `elem` clientExtensions) do
-- traceIO "Surfaceless platform available"
--display <- getEglDisplaySurfaceless
(major :: EGLint, minor :: EGLint) <- C.withPtrs_ \(majorPtr, minorPtr) ->
throwErrnoIf_ (== 0) "eglInitialize"
......@@ -161,6 +124,64 @@ initializeEgl = do
[CU.exp|EGLBoolean { eglMakeCurrent($(EGLDisplay display), EGL_NO_SURFACE, EGL_NO_SURFACE, $(EGLContext context)) }|]
getEglDisplayDevice :: IO EGLDisplay
getEglDisplayDevice = do
-- Requires EGL_EXT_device_enumeration and EGL_EXT_device_query
[CU.block|
void {
eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT");
}
|]
deviceCount <- throwErrnoIfMinus1 "eglQueryDevicesEXT"
[CU.block|
EGLint {
EGLint count;
EGLBoolean result = eglQueryDevicesEXT(0, NULL, &count);
if (!result) {
return -1;
}
return count;
}
|]
traceIO $ "Available EGL devices: " <> show deviceCount
(devices :: [EGLDeviceEXT]) <- allocaArray (fromIntegral deviceCount) \ptr -> do
throwErrnoIf_ (== 0) "eglQueryDevicesEXT"
[CU.block|
EGLBoolean {
EGLint count;
EGLBoolean result = eglQueryDevicesEXT($(EGLint deviceCount), $(EGLDeviceEXT* ptr), &count);
if (count < $(EGLint deviceCount)) {
return EGL_FALSE;
}
return result;
}
|]
peekArray (fromIntegral deviceCount) ptr
forM_ (zip [0,1..] devices) \(i, device) -> do
vendor <- eglQueryDeviceString device [CU.pure|EGLint { EGL_EXTENSIONS }|]
traceIO $ mconcat ["Device ", show i, ": ", vendor]
deviceNode <- eglTryQueryDeviceString device [CU.pure|EGLint { EGL_DRM_DEVICE_FILE_EXT }|]
traceIO $ mconcat ["Device ", show i, ": ", show deviceNode]
renderNode <- eglTryQueryDeviceString device [CU.pure|EGLint { EGL_DRM_RENDER_NODE_FILE_EXT }|]
traceIO $ mconcat ["Device ", show i, ": ", show renderNode]
traceIO "Using device 0"
(device:_) <- pure devices
throwErrnoIfNull "eglGetPlatformDisplay"
[CU.exp|EGLDisplay { eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, $(EGLDeviceEXT device), NULL) }|]
--getEglDisplaySurfaceless :: IO EGLDisplay
--getEglDisplaySurfaceless = do
-- -- Requires EGL_MESA_platform_surfaceless
-- throwErrnoIfNull "eglGetPlatformDisplay"
-- [CU.exp|EGLDisplay { eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, NULL) }|]
eglQueryString :: EGLDisplay -> EGLint -> IO String
eglQueryString display name =
peekCString =<< throwErrnoIfNull "eglQueryString"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment