Merge branch 'gpu-reset-recover' into 'master'

Automatic GPU reset recovery

See merge request wlroots/wlroots!3910
This commit is contained in:
Alexander Orzechowski 2024-10-09 09:31:41 +00:00
commit 863ed02d54
29 changed files with 1822 additions and 541 deletions

View file

@ -32,21 +32,12 @@ struct wlr_drm_lease {
/**
* Creates a DRM backend using the specified GPU file descriptor (typically from
* a device node in /dev/dri).
*
* To slave this to another DRM backend, pass it as the parent (which _must_ be
* a DRM backend, other kinds of backends raise SIGABRT).
*/
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
struct wlr_device *dev, struct wlr_backend *parent);
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session, struct wlr_device *dev);
bool wlr_backend_is_drm(struct wlr_backend *backend);
bool wlr_output_is_drm(struct wlr_output *output);
/**
* Get the parent DRM backend, if any.
*/
struct wlr_backend *wlr_drm_backend_get_parent(struct wlr_backend *backend);
/**
* Get the KMS connector object ID.
*/

View file

@ -56,6 +56,7 @@ struct wlr_buffer {
struct {
struct wl_signal destroy;
struct wl_signal release;
struct wl_signal prerelease;
} events;
struct wlr_addon_set addons;

View file

@ -239,6 +239,7 @@ struct wlr_surface {
// private state
struct wl_listener role_resource_destroy;
struct wl_listener current_buffer_release;
struct {
int32_t scale;
@ -250,6 +251,7 @@ struct wlr_surface {
bool unmap_commit;
bool opaque;
bool consumed;
bool handling_commit;
bool pending_rejected;
@ -536,6 +538,12 @@ void wlr_surface_synced_finish(struct wlr_surface_synced *synced);
void *wlr_surface_synced_get_state(struct wlr_surface_synced *synced,
const struct wlr_surface_state *state);
/*
* Consumes buffer and damage state of the buffer so that the compositor may
* drop references to any of these resources.
*/
void wlr_surface_consume(struct wlr_surface *surface);
/**
* Get a Pixman region from a wl_region resource.
*/

View file

@ -17,6 +17,8 @@
#include <wlr/render/drm_format_set.h>
struct wlr_surface;
struct wlr_renderer;
struct wlr_allocator;
struct wlr_dmabuf_v1_buffer {
struct wlr_buffer base;
@ -27,6 +29,8 @@ struct wlr_dmabuf_v1_buffer {
// private state
struct wl_listener release;
struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1;
};
/**
@ -63,7 +67,13 @@ struct wlr_linux_dmabuf_v1 {
int main_device_fd; // to sanity check FDs sent by clients, -1 if unavailable
// used for multigpu
struct wlr_renderer *main_renderer;
struct wlr_allocator *main_allocator;
struct wl_listener display_destroy;
struct wl_listener main_renderer_destroy;
struct wl_listener main_allocator_destroy;
bool (*check_dmabuf_callback)(struct wlr_dmabuf_attributes *attribs, void *data);
void *check_dmabuf_callback_data;
@ -78,6 +88,23 @@ struct wlr_linux_dmabuf_v1 {
struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_create(struct wl_display *display,
uint32_t version, const struct wlr_linux_dmabuf_feedback_v1 *default_feedback);
/**
* Returns the associated dmabuf object from a generic buffer. Returnns
* NULL if the generic buffer is not a dmabuf.
*/
struct wlr_dmabuf_v1_buffer *wlr_dmabuf_v1_buffer_try_from_buffer(
struct wlr_buffer *buffer);
/**
* Sets the main blit device used for multigpu. With multigpu, dmabufs with
* implicit modifiers or just modifiers that aren't supported by other GPUs
* might need to be blitted into a staging buffer with correct modifiers. This
* will be done with this allocator (to allocate the staging buffer) and renderer
* to render into the staging buffer.
*/
void wlr_linux_dmabuf_v1_set_main_blit_device(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
struct wlr_renderer *renderer, struct wlr_allocator *allocator);
/**
* Create the linux-dmabuf-v1 global.
*
@ -120,6 +147,9 @@ void wlr_linux_dmabuf_feedback_v1_finish(struct wlr_linux_dmabuf_feedback_v1 *fe
struct wlr_linux_dmabuf_feedback_v1_init_options {
// Main renderer used by the compositor
struct wlr_renderer *main_renderer;
// Optional allocator created for the primary GPU used by the default feedback.
// This is used for multi gpu for allocating staging buffers.
struct wlr_allocator *main_allocator;
// Output on which direct scan-out is possible on the primary plane, or NULL
struct wlr_output *scanout_primary_output;
// Output layer feedback event, or NULL

View file

@ -0,0 +1,97 @@
/*
* This an unstable interface of wlroots. No guarantees are made regarding the
* future consistency of this API.
*/
#ifndef WLR_USE_UNSTABLE
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
#endif
#ifndef WLR_TYPES_OUTPUT_MANAGER_H
#define WLR_TYPES_OUTPUT_MANAGER_H
#include <stdbool.h>
#include <wayland-server-core.h>
#include <wlr/render/drm_format_set.h>
struct wlr_renderer;
struct wlr_allocator;
struct wlr_backend;
struct wlr_output;
struct wlr_output_manager_backend {
struct wlr_output_manager *manager;
struct wlr_renderer *renderer;
struct wlr_allocator *allocator;
struct wlr_backend *backend;
struct wl_list link; // wlr_output_manager.backends
struct {
struct wl_signal recovery;
} events;
// private state
uint32_t locks;
struct wl_listener backend_destroy;
struct wl_listener renderer_lost;
};
struct wlr_output_manager {
struct wl_list backends; // wlr_output_manager_backend.link
struct wlr_output_manager_backend primary;
};
/**
* Initializes the output given output manager. wlr_output_manager_finish
* must be called to clean up this manager.
*/
bool wlr_output_manager_init(struct wlr_output_manager *manager,
struct wlr_backend *backend);
/**
* Finishes this output_manager and cleans up all its resources including any
* output manager backends.
*/
void wlr_output_manager_finish(struct wlr_output_manager *manager);
/**
* This will return a output_manager backend that will be reference counted.
* wlr_output_manager_unlock_backend is required to be called after the usage
* of this is finished.
*/
struct wlr_output_manager_backend *wlr_output_manager_lock_backend(
struct wlr_output_manager *manager, struct wlr_backend *wlr_backend);
/**
* wlr_output_manager_unlock_backend will unlock any backend returned by
* wlr_output_manager_lock_rendener. The allocator and backend allocated
* may be destroyed when the reference count reaches 0
*/
void wlr_output_manager_unlock_backend(struct wlr_output_manager_backend *backend);
/**
* wlr_output_manager_init_output will automatically initialize the given output.
* This is a helder function that will handle unlocking backends automatically
* upon output destroy
*/
bool wlr_output_manager_init_output(struct wlr_output_manager *manager,
struct wlr_output *output);
/**
* Initializes shm for the given wl_display given the constraints all devices
* on the manager have
*/
bool wlr_output_manager_init_wl_shm(struct wlr_output_manager *manager,
struct wl_display *wl_display);
/**
* Initializes the given wl_display given the constraints all devices
* on the manager have
*/
bool wlr_output_manager_init_wl_display(struct wlr_output_manager *manager,
struct wl_display *wl_display);
#endif

View file

@ -0,0 +1,120 @@
/*
* This an unstable interface of wlroots. No guarantees are made regarding the
* future consistency of this API.
*/
#ifndef WLR_USE_UNSTABLE
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
#endif
#ifndef WLR_TYPES_WLR_RASTER_H
#define WLR_TYPES_WLR_RASTER_H
#include <stdbool.h>
#include <stdlib.h>
#include <wayland-server-core.h>
struct wlr_buffer;
struct wlr_texture;
struct wlr_renderer;
struct wlr_drm_syncobj_timeline;
struct wlr_surface;
struct wlr_allocator;
struct wlr_raster_source {
struct wlr_texture *texture;
struct wlr_allocator *allocator; // may be NULL
struct wlr_raster *raster;
struct wl_list link;
struct wl_listener renderer_destroy;
struct wl_listener allocator_destroy;
};
struct wlr_raster {
// May be NULL
struct wlr_buffer *buffer;
struct wl_list sources;
uint32_t width, height;
bool opaque;
struct wlr_drm_syncobj_timeline *wait_timeline;
uint64_t wait_point;
struct {
struct wl_signal destroy;
struct wl_signal invalidated;
} events;
// private state
size_t n_locks;
struct wl_listener buffer_release;
};
struct wlr_raster_create_options {
struct wlr_drm_syncobj_timeline *wait_timeline;
uint64_t wait_point;
};
/**
* Creates a new wlr_raster being backed by the given buffer. The raster will
* not lock the given buffer meaning that once it's released, the raster will
* NULL its buffer reference and potentially become invalid.
* The creation function is referenced: once the creator is done with the raster,
* wlr_raster_unlock must be called as the reference count will start at 1
* from creation.
*
* Options can be NULL.
*/
struct wlr_raster *wlr_raster_create(struct wlr_buffer *buffer,
const struct wlr_raster_create_options *options);
/**
* Lock the raster for use. As long as the raster has at least one lock, it
* will not be destroyed.
*/
struct wlr_raster *wlr_raster_lock(struct wlr_raster *raster);
/**
* Unlock the raster. This must be called after wlr_raster_lock once the raster
* has been finished being used or after creation from wlr_raster_create.
*/
void wlr_raster_unlock(struct wlr_raster *raster);
/**
* Returns the texture allocated for this renderer. If there is none,
* a new texture will be created and attached to this wlr_raster. Users do not
* own the texture returned by this function and can only be used for read-only
* purposes.
*
* Will return NULL if the creation was unsuccessful.
*/
struct wlr_texture *wlr_raster_obtain_texture(struct wlr_raster *raster,
struct wlr_renderer *renderer);
/**
* Returns the texture allocated for this renderer. If there is none,
* a new texture will be created and attached to this wlr_raster. Users do not
* own the texture returned by this function and can only be used for read-only
* purposes.
*
* An optional allocator can be provided which will be used to allocate staging
* buffers to blit between graphics devices if needed.
*
* Will return NULL if the creation was unsuccessful.
*/
struct wlr_texture *wlr_raster_obtain_texture_with_allocator(struct wlr_raster *raster,
struct wlr_renderer *renderer, struct wlr_allocator *allocator);
/**
* Creates a wlr_raster from a surface. This will automatically deduplicate
* rasters if multiple are consumed from the same surface so that redundant
* uploads are not performed. The raster returned will automatically be locked.
* Users are required to call wlr_raster_unlock() after invoking this function.
*/
struct wlr_raster *wlr_raster_from_surface(struct wlr_surface *surface);
#endif

View file

@ -35,6 +35,7 @@ struct wlr_xdg_surface;
struct wlr_layer_surface_v1;
struct wlr_drag_icon;
struct wlr_surface;
struct wlr_raster;
struct wlr_scene_node;
struct wlr_scene_buffer;
@ -158,6 +159,7 @@ struct wlr_scene_buffer {
// May be NULL
struct wlr_buffer *buffer;
struct wlr_raster *raster;
struct {
struct wl_signal outputs_update; // struct wlr_scene_outputs_update_event
@ -188,15 +190,9 @@ struct wlr_scene_buffer {
// private state
uint64_t active_outputs;
struct wlr_texture *texture;
struct wlr_linux_dmabuf_feedback_v1_init_options prev_feedback_options;
bool own_buffer;
int buffer_width, buffer_height;
bool buffer_is_opaque;
struct wlr_drm_syncobj_timeline *wait_timeline;
uint64_t wait_point;
struct wl_listener buffer_release;
struct wl_listener renderer_destroy;
@ -427,7 +423,7 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_tree *parent,
struct wlr_buffer *buffer);
/**
* Sets the buffer's backing buffer.
* Sets the buffer's backing raster.
*
* If the buffer is NULL, the buffer node will not be displayed.
*/
@ -435,7 +431,7 @@ void wlr_scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer,
struct wlr_buffer *buffer);
/**
* Sets the buffer's backing buffer with a custom damage region.
* Sets the buffer's backing raster with a custom damage region.
*
* The damage region is in buffer-local coordinates. If the region is NULL,
* the whole buffer node will be damaged.
@ -465,6 +461,15 @@ struct wlr_scene_buffer_set_buffer_options {
void wlr_scene_buffer_set_buffer_with_options(struct wlr_scene_buffer *scene_buffer,
struct wlr_buffer *buffer, const struct wlr_scene_buffer_set_buffer_options *options);
/*
* Sets the buffer's backing raster with a custom damage region.
*
* The damage region is in buffer-local coordinates. If the region is NULL,
* the whole buffer node will be damaged.
*/
void wlr_scene_buffer_set_raster_with_damage(struct wlr_scene_buffer *scene_buffer,
struct wlr_raster *raster, const pixman_region32_t *damage);
/**
* Sets the buffer's opaque region. This is an optimization hint used to
* determine if buffers which reside under this one need to be rendered or not.

View file

@ -0,0 +1,32 @@
/*
* This an unstable interface of wlroots. No guarantees are made regarding the
* future consistency of this API.
*/
#ifndef WLR_USE_UNSTABLE
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
#endif
#ifndef WLR_TYPES_WLR_SURFACE_INVALIDATION_V1_H
#define WLR_TYPES_WLR_SURFACE_INVALIDATION_V1_H
#include <wayland-server-core.h>
struct wlr_surface;
struct wlr_surface_invalidation_manager_v1 {
struct wl_global *global;
struct {
struct wl_signal destroy;
} events;
struct wl_listener display_destroy;
};
struct wlr_surface_invalidation_manager_v1 *wlr_surface_invalidation_manager_v1_create(
struct wl_display *display, uint32_t version);
void wlr_surface_invalidation_manager_v1_send_surface_invalidation(
struct wlr_surface *surface);
#endif