autocommit 2022-04-04 14:29:04 CEST
This commit is contained in:
parent
1f71290dab
commit
e897d271af
21 changed files with 278 additions and 127 deletions
|
|
@ -42,6 +42,9 @@ pub fn init() -> Result<(), RenderError> {
|
|||
if !EXTS.device_enumeration() {
|
||||
return Err(RenderError::DeviceEnumeration);
|
||||
}
|
||||
if !EXTS.platform_gbm() {
|
||||
return Err(RenderError::DeviceEnumeration);
|
||||
}
|
||||
if EXTS.contains(ClientExt::KHR_DEBUG) {
|
||||
let attrib: &[EGLAttrib] = &[
|
||||
EGL_DEBUG_MSG_CRITICAL_KHR as _,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ impl EglDevice {
|
|||
let mut dpy = EglDisplay {
|
||||
exts: DisplayExt::empty(),
|
||||
formats: Rc::new(AHashMap::new()),
|
||||
dev: *self,
|
||||
dev: Some(*self),
|
||||
gbm: None,
|
||||
dpy,
|
||||
};
|
||||
let mut major = 0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::ptr;
|
||||
use crate::drm::dma::DmaBuf;
|
||||
use crate::drm::INVALID_MODIFIER;
|
||||
use crate::format::Format;
|
||||
use crate::format::{Format, formats};
|
||||
use crate::render::egl::context::EglContext;
|
||||
use crate::render::egl::device::EglDevice;
|
||||
use crate::render::egl::image::EglImage;
|
||||
|
|
@ -18,20 +19,75 @@ use crate::render::egl::sys::{
|
|||
EGL_LINUX_DRM_FOURCC_EXT, EGL_NONE, EGL_TRUE, EGL_WIDTH,
|
||||
};
|
||||
use crate::render::egl::PROCS;
|
||||
use crate::render::ext::{get_gl_ext, DisplayExt, GlExt};
|
||||
use crate::render::ext::{get_gl_ext, DisplayExt, GlExt, get_display_ext};
|
||||
use crate::render::RenderError;
|
||||
use ahash::AHashMap;
|
||||
use std::rc::Rc;
|
||||
use crate::drm::drm::Drm;
|
||||
use crate::drm::gbm::GbmDevice;
|
||||
use crate::render::sys::{EGL_PLATFORM_GBM_KHR, eglInitialize};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct EglDisplay {
|
||||
pub exts: DisplayExt,
|
||||
pub formats: Rc<AHashMap<u32, &'static Format>>,
|
||||
pub dev: EglDevice,
|
||||
pub dev: Option<EglDevice>,
|
||||
pub gbm: Option<GbmDevice>,
|
||||
pub dpy: EGLDisplay,
|
||||
}
|
||||
|
||||
impl EglDisplay {
|
||||
pub fn create(drm: &Drm) -> Result<Rc<Self>, RenderError> {
|
||||
unsafe {
|
||||
let gbm = match GbmDevice::new(drm) {
|
||||
Ok(gbm) => gbm,
|
||||
Err(e) => return Err(RenderError::Gbm(e)),
|
||||
};
|
||||
let dpy = PROCS.eglGetPlatformDisplayEXT(
|
||||
EGL_PLATFORM_GBM_KHR as _,
|
||||
gbm.raw() as _,
|
||||
ptr::null(),
|
||||
);
|
||||
if dpy.is_none() {
|
||||
return Err(RenderError::GetDisplay);
|
||||
}
|
||||
let mut dpy = EglDisplay {
|
||||
exts: DisplayExt::empty(),
|
||||
formats: Rc::new(AHashMap::new()),
|
||||
dev: None,
|
||||
gbm: Some(gbm),
|
||||
dpy,
|
||||
};
|
||||
let mut major = 0;
|
||||
let mut minor = 0;
|
||||
if eglInitialize(dpy.dpy, &mut major, &mut minor) != EGL_TRUE {
|
||||
return Err(RenderError::Initialize);
|
||||
}
|
||||
dpy.exts = get_display_ext(dpy.dpy);
|
||||
if !dpy.exts.intersects(DisplayExt::KHR_IMAGE_BASE) {
|
||||
return Err(RenderError::ImageBase);
|
||||
}
|
||||
if !dpy
|
||||
.exts
|
||||
.intersects(DisplayExt::EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS)
|
||||
{
|
||||
return Err(RenderError::DmaBufImport);
|
||||
}
|
||||
if !dpy
|
||||
.exts
|
||||
.intersects(DisplayExt::KHR_NO_CONFIG_CONTEXT | DisplayExt::MESA_CONFIGLESS_CONTEXT)
|
||||
{
|
||||
return Err(RenderError::ConfiglessContext);
|
||||
}
|
||||
if !dpy.exts.intersects(DisplayExt::KHR_SURFACELESS_CONTEXT) {
|
||||
return Err(RenderError::SurfacelessContext);
|
||||
}
|
||||
dpy.formats = Rc::new(query_formats(dpy.dpy)?);
|
||||
|
||||
Ok(Rc::new(dpy))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_context(self: &Rc<Self>) -> Result<Rc<EglContext>, RenderError> {
|
||||
let attrib = [EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE];
|
||||
unsafe {
|
||||
|
|
@ -141,3 +197,26 @@ impl Drop for EglDisplay {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, &'static Format>, RenderError> {
|
||||
let mut vec = vec![];
|
||||
let mut num = 0;
|
||||
let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num);
|
||||
if res != EGL_TRUE {
|
||||
return Err(RenderError::QueryDmaBufFormats);
|
||||
}
|
||||
vec.reserve_exact(num as usize);
|
||||
let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, vec.as_mut_ptr(), &mut num);
|
||||
if res != EGL_TRUE {
|
||||
return Err(RenderError::QueryDmaBufFormats);
|
||||
}
|
||||
vec.set_len(num as usize);
|
||||
let mut res = AHashMap::new();
|
||||
let formats = formats();
|
||||
for fmt in vec {
|
||||
if let Some(format) = formats.get(&(fmt as u32)) {
|
||||
res.insert(format.drm, *format);
|
||||
}
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ pub const EGL_BAD_DEVICE_EXT: EGLint = 0x322B;
|
|||
pub const EGL_OPENGL_ES_API: EGLenum = 0x30A0;
|
||||
pub const EGL_DRM_DEVICE_FILE_EXT: EGLint = 0x3233;
|
||||
pub const EGL_PLATFORM_DEVICE_EXT: EGLint = 0x313F;
|
||||
pub const EGL_PLATFORM_GBM_KHR: EGLint = 0x31D7;
|
||||
pub const EGL_CONTEXT_CLIENT_VERSION: EGLint = 0x3098;
|
||||
|
||||
pub const EGL_WIDTH: EGLint = 0x3057;
|
||||
|
|
|
|||
|
|
@ -58,11 +58,15 @@ bitflags::bitflags! {
|
|||
|
||||
impl ClientExt {
|
||||
pub fn device_enumeration(self) -> bool {
|
||||
self.intersects(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_ENUMERATION)
|
||||
self.contains(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_ENUMERATION)
|
||||
}
|
||||
|
||||
pub fn device_query(self) -> bool {
|
||||
self.intersects(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_QUERY)
|
||||
self.contains(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_QUERY)
|
||||
}
|
||||
|
||||
pub fn platform_gbm(self) -> bool {
|
||||
self.contains(Self::KHR_PLATFORM_GBM)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use std::ffi::CString;
|
|||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
use uapi::ustr;
|
||||
use crate::render::egl::display::EglDisplay;
|
||||
|
||||
pub(super) struct TexProg {
|
||||
pub(super) prog: GlProgram,
|
||||
|
|
@ -57,15 +58,14 @@ impl Debug for RenderContext {
|
|||
impl RenderContext {
|
||||
pub fn from_drm_device(drm: &Drm) -> Result<Self, RenderError> {
|
||||
let nodes = drm.get_nodes()?;
|
||||
let node = match nodes.get(&NodeType::Render) {
|
||||
let node = match nodes
|
||||
.get(&NodeType::Render)
|
||||
.or_else(|| nodes.get(&NodeType::Primary))
|
||||
{
|
||||
None => return Err(RenderError::NoRenderNode),
|
||||
Some(path) => Rc::new(path.to_owned()),
|
||||
};
|
||||
let egl_dev = match find_drm_device(&nodes)? {
|
||||
Some(d) => d,
|
||||
None => return Err(RenderError::UnknownDrmDevice),
|
||||
};
|
||||
let dpy = egl_dev.create_display()?;
|
||||
let dpy = EglDisplay::create(drm)?;
|
||||
if !dpy.formats.contains_key(&XRGB8888.drm) {
|
||||
return Err(RenderError::XRGB888);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue