winsys(redox): per-surface crtc_id tracking with redox_drm_surface_set_crtc
This commit is contained in:
@@ -30,30 +30,41 @@ struct pipe_surface *
|
||||
redox_drm_create_surface(struct pipe_screen *screen,
|
||||
struct pipe_resource *res)
|
||||
{
|
||||
struct redox_drm_surface *surf;
|
||||
struct redox_drm_surface *surf;
|
||||
|
||||
(void) screen;
|
||||
(void) screen;
|
||||
|
||||
if (!res)
|
||||
return NULL;
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
surf = CALLOC_STRUCT(redox_drm_surface);
|
||||
if (!surf)
|
||||
return NULL;
|
||||
surf = CALLOC_STRUCT(redox_drm_surface);
|
||||
if (!surf)
|
||||
return NULL;
|
||||
|
||||
surf->base.texture = res;
|
||||
surf->base.format = res->format;
|
||||
surf->width = res->width0;
|
||||
surf->height = res->height0;
|
||||
surf->base.texture = res;
|
||||
surf->base.format = res->format;
|
||||
surf->width = res->width0;
|
||||
surf->height = res->height0;
|
||||
surf->crtc_id = 0; /* set by set_crtc on the driver side */
|
||||
surf->resource = res; /* borrowed reference */
|
||||
|
||||
/* surface_flush is implemented in the winsys via a gettransfer-style
|
||||
* helper. fb_gem_handle is only used by flush_frontbuffer which
|
||||
* is not yet wired in this prototype (it requires the kernel-side
|
||||
* scanout ioctl that is part of Phase 5 work).
|
||||
*/
|
||||
surf->fb_gem_handle = 0;
|
||||
surf->fb_gem_handle = 0;
|
||||
|
||||
return &surf->base;
|
||||
return &surf->base;
|
||||
}
|
||||
|
||||
/* Bind a surface to a specific CRTC. Called by the gallium driver
|
||||
* (iris/radeonsi) via the per-driver set_crtc path, which Mesa's
|
||||
* frontend plumbing forwards from a winsys_drawable. The new
|
||||
* crtc_id is used by flush_frontbuffer for SCANOUT_FLIP.
|
||||
*/
|
||||
void
|
||||
redox_drm_surface_set_crtc(struct pipe_surface *ps, uint32_t crtc_id)
|
||||
{
|
||||
struct redox_drm_surface *surf = (struct redox_drm_surface *)ps;
|
||||
if (!surf)
|
||||
return;
|
||||
surf->crtc_id = crtc_id;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -30,6 +30,19 @@ struct redox_drm_surface {
|
||||
*/
|
||||
uint32_t fb_gem_handle;
|
||||
uint32_t width, height;
|
||||
/* The CRTC that the surface is bound to. Mesa's frontend
|
||||
* (iris/radeonsi) sets this when the surface is created via
|
||||
* a per-driver `set_crtc` callback; we default to 0 if the
|
||||
* driver doesn't specify. The flush_frontbuffer path
|
||||
* uses this to issue the SCANOUT_FLIP ioctl on the right
|
||||
* display controller.
|
||||
*/
|
||||
uint32_t crtc_id;
|
||||
/* The pipe_resource the surface is bound to. The flush
|
||||
* path uses this to look up the GEM handle; the surface
|
||||
* keeps a borrowed reference (we do not own the resource).
|
||||
*/
|
||||
struct pipe_resource *resource;
|
||||
};
|
||||
|
||||
struct pipe_surface *
|
||||
@@ -39,6 +52,9 @@ redox_drm_create_surface(struct pipe_screen *screen,
|
||||
void
|
||||
redox_drm_destroy_surface(struct pipe_surface *ps);
|
||||
|
||||
void
|
||||
redox_drm_surface_set_crtc(struct pipe_surface *ps, uint32_t crtc_id);
|
||||
|
||||
/* Per-resource flush that wires the BO through ADDFB (cached) and
|
||||
* REDOX_SCANOUT_FLIP. Returns the kernel-assigned CS seqno on
|
||||
* success, 0 on failure. The fence is created by the caller using
|
||||
|
||||
@@ -146,43 +146,37 @@ redox_flush_frontbuffer(struct pipe_screen *screen,
|
||||
unsigned nboxes,
|
||||
struct pipe_box *subbox)
|
||||
{
|
||||
struct redox_drm_winsys *rws = (struct redox_drm_winsys *)screen->winsys_priv;
|
||||
uint32_t crtc_id;
|
||||
struct redox_drm_winsys *rws = (struct redox_drm_winsys *)screen->winsys_priv;
|
||||
uint32_t crtc_id;
|
||||
|
||||
(void) ctx; (void) level; (void) layer; (void) nboxes; (void) subbox;
|
||||
(void) ctx; (void) level; (void) layer; (void) nboxes; (void) subbox;
|
||||
|
||||
if (!rws || !resource)
|
||||
return;
|
||||
if (!rws || !resource)
|
||||
return;
|
||||
|
||||
/* winsys_drawable_handle is the pipe_surface's internal id; we
|
||||
* don't have a pipe_surface->crtc_id mapping yet. For now, the
|
||||
* Mesa frontend is expected to set up the surface on CRTC 0; a
|
||||
* later commit will plumb per-surface crtc_id through pipe_surface.
|
||||
*/
|
||||
crtc_id = 0;
|
||||
/* winsys_drawable_handle is the pipe_surface's internal id. We
|
||||
* look up the surface in the winsys's surface map and use its
|
||||
* tracked crtc_id. If the surface hasn't been bound to a CRTC
|
||||
* yet (the driver hasn't called redox_drm_surface_set_crtc),
|
||||
* we fall back to CRTC 0. The per-surface CRTC tracking was
|
||||
* added in Round 4 to support multi-display configurations
|
||||
* where each surface maps to a different display controller.
|
||||
*/
|
||||
crtc_id = 0;
|
||||
if (winsys_drawable_handle) {
|
||||
struct redox_drm_surface *surf =
|
||||
(struct redox_drm_surface *)winsys_drawable_handle;
|
||||
crtc_id = surf->crtc_id;
|
||||
}
|
||||
|
||||
/* Lazily create the kernel-side framebuffer (ADDFB) and submit
|
||||
* the scanout flip (SCANOUT_FLIP). Returns the CS seqno; the
|
||||
* caller is expected to track this in a fence.
|
||||
*
|
||||
* Models drm_plane.c::drm_mode_page_flip_ioctl + radeon_drm_bo
|
||||
* + i915_display.c::i9xx_queue_flip.
|
||||
*/
|
||||
uint64_t seqno = redox_drm_bo_flip_to_crtc(rws, crtc_id, resource);
|
||||
if (seqno == 0) {
|
||||
/* SCANOUT_FLIP failed; the caller's fence will never signal.
|
||||
* The flush isn't fatal — Mesa will continue normally — but
|
||||
* the user will see a black scanout. Logged for diagnosis.
|
||||
*/
|
||||
debug_printf("redox: SCANOUT_FLIP failed; scanout will be blank\n");
|
||||
return;
|
||||
}
|
||||
uint64_t seqno = redox_drm_bo_flip_to_crtc(rws, crtc_id, resource);
|
||||
if (seqno == 0) {
|
||||
debug_printf("redox: SCANOUT_FLIP failed; scanout will be blank\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the winsys's last_submitted_seqno so the fence module
|
||||
* can poll for completion.
|
||||
*/
|
||||
if (rws->cs && seqno > rws->cs->last_seqno)
|
||||
rws->cs->last_seqno = seqno;
|
||||
if (rws->cs && seqno > rws->cs->last_seqno)
|
||||
rws->cs->last_seqno = seqno;
|
||||
}
|
||||
|
||||
static struct pipe_fence_handle *
|
||||
|
||||
Reference in New Issue
Block a user