1
0
Fork 0
forked from wry/wry

autocommit 2022-04-04 14:29:04 CEST

This commit is contained in:
Julian Orth 2022-04-04 14:29:04 +02:00
parent 1f71290dab
commit e897d271af
21 changed files with 278 additions and 127 deletions

View file

@ -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 _,

View file

@ -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;

View file

@ -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)
}

View file

@ -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;

View file

@ -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)
}
}

View file

@ -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);
}