-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce MultiGPU renderer #503
Conversation
58443b4
to
3a9836e
Compare
60b38b7
to
fb4e467
Compare
src/backend/renderer/gles2/mod.rs
Outdated
@@ -784,6 +784,89 @@ impl ImportShm for Gles2Renderer { | |||
.map_err(Gles2Error::BufferAccessError)? | |||
} | |||
|
|||
fn import_memory(&mut self, data: &[u8], size: Size<i32, Buffer>) -> Result<Gles2Texture, Gles2Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to be there is quite a bit of repetition, I'm thinking we might:
- change the
import_memory
/update_memory
to take as argument a&[u8]
and aBufferData
- make
import_shm_buffer
useimport_memory
/update_memory
would it make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly it does, more work for me! :)
} | ||
} | ||
|
||
impl std::ops::Add for Transform { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, this is extremely subjective, but Add
does not feel like the appropriate operator for this to me. I think Mul
would make more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So 90 * 90 = 180? Feels weird to me.
Also Flipped * Flipped = Normal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but that clearly my inner mathematician speaking (seeing composition of rotations as multiplication of complex numbers, and likewise, -1 * -1 = 1
makes sense to me for flipping). But I'm clearly not going to die on that hill. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I am indecisive about this, do we already have similar cases for composition in the library? Because at least it should be consistent.
anvil/src/udev.rs
Outdated
|
||
// setup the timer | ||
let timer = Timer::new().unwrap(); | ||
|
||
std::mem::drop(renderer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any particular reason for this drop? If so, could we get a comment about the reason?
If this is just a stylistic choice, then don't mind me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because the renderer borrows gpus
mutably, so without the drop rustc complains, that it cannot move gpus
into the UdevData
in the next line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment to explain this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because the renderer borrows
gpus
mutably, so without the drop rustc complains, that it cannot movegpus
into theUdevData
in the next line.
Just checked and it compiles just fine for me, so rustc does not complain for me, maybe it'a a certain feature combination? (I'm building the default feature set of anvil)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe some recent changes made this obsolete? I will remove it and see what CI think about it.
@@ -313,7 +314,7 @@ impl X11Handle { | |||
/// Returns the DRM node the X server uses for direct rendering. | |||
/// | |||
/// The DRM node may be used to create a [`gbm::Device`] to allocate buffers. | |||
pub fn drm_node(&self) -> Result<DrmNode, X11Error> { | |||
pub fn drm_node(&self) -> Result<(DrmNode, RawFd), X11Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OwnedFd in std is currently unstable. We should probably wrap the fd in something so we can't leak it since the method gives you ownership of the fd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well that is also how e.g. IntoRawFd
works, ownership is implicit.
But yes, we could probably wrap it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note on that, I want to change the X11-backend soon to use an EGLSurface
, which will not require downstream to access the RawFd
anymore anyway. I will thus skip wrapping the RawFd
in this PR and deal with it in an upcoming one.
Ok(texture) | ||
} | ||
|
||
fn update_memory( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this work on an EGLImage or Dmabuf backed texture?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be in the case of the Gles2Renderer
(though it likely depends on the EGLImage/Dmabuf),
but the docs of the trait clearly state that:
/// This function *may* error, if (but not limited to):
/// - The texture was not created using either [`ImportMem::import_shm_buffer`] or [`ImportMem::import_memory`].
/// ...
Add the possibility of importing memory slices to the ImportShm trait, just like the ImportDma trait supports importing Dmabufs and not only dmabuf-based WlBuffers. Also rename ImportShm to ImportMem to better reflect the new functionality.
dadde8a
to
1dffaa6
Compare
1dffaa6
to
2e0ae16
Compare
Best reviewed commit by commit:
Adds a new trait
Offscreen
to ourrenderer
module, that describes the feature to create offscreen-framebuffers to render into. (Actually rendering to them is handled byBind
andRenderer
as previously.)Adds two implementations of
Offscreen
(and matchingBind
implementations) to ourGles2Renderer
.Gles2Texture
allow now to render into textures, which is useful to do some post-processing.Gles2Renderbuffer
, which is faster than a texture, but cannot be sampled from.Renames
ImportShm
toImportMem
and adds functions to import bitmaps, that don't belong to a wl_buffer.Introduces a new
ExportMem
trait that allows copying textures and from bound framebuffers into memoryand implements it for our
Gles2Renderer
Prequisite for ea9aabd. Adds the ability to convert from egl-images to dmabuf. (We previously only supported the other way around.)
Introduces a new
ExportDma
trait, that analogous toExportMem
(and toImportDma
andImportMem
being the opposites) allows to export textures and framebuffers to dmabufs. Again implemented for ourGles2Renderer
Changes the
DrmNode
type to not contain a file descriptor, essentially only describing a drm-device. Can be used across the code base to uniquely identify drm-nodes, but is currently a bit under-used (except for the multigpu module).This also makes the X11-backend api a little more awkward, but that is meant to switch to rendering via a
EGLSurface
in the future anyway.Removes the 'static-constraint on the
Renderer
provided toSpace::render_output
by not using trait-objects for customRenderElement
s anymore. A new macro is provided to generate a collating enum-type for downstream. This is required, given theMultiRenderer
borrows internalRenderer
s from theGpuManager
.Introduce a new multigpu-module, containing the
GpuManager
,MultiRenderer
and some accompanying types.Also implements its use in anvil's udev-backend.
The idea is, that a
GpuManager
enumerates available rendering devices for a givenApi
(only Egl+Gles2 is provided at the moment) and then allows to createMultiRenderer
s from two gpus represented byDrmNode
s. The render-gpu, where compositing will take place and the target-gpu, where the result will reside on. Client buffers will be imported by anysource
-gpu, if it is available to the used api.Almost all of the processing required to move stuff between gpus is done transparently in the background and using the new
Offscreen
- andExport*
-traits, meaning this should theoretically just work with a future Vulkan-based renderer.One exception is the
GpuManager::early_import
function, that can be used to pro-actively start copy-operations of client buffers on commit as opposed to during compositing, risking running late on the frame.A bunch of smaller fixes and additions...
Todo
GpuManager::early_import
in anvilSometimes windows moved between outputs of different gpus will take a second to show up, probably a caching issue, because performance so far seems to be really smooth for a first attempt.fixedQuestions