modesetting: Add support for multi-plane pixmaps when page-flipping
This allows the uses of CCS compressed or tiled pixmaps as BOs when page-flipping. Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Keith Packard <keithp@keithp.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
4023d53734
commit
2f807c2324
@ -39,6 +39,8 @@
|
|||||||
#include "micmap.h"
|
#include "micmap.h"
|
||||||
#include "xf86cmap.h"
|
#include "xf86cmap.h"
|
||||||
#include "xf86DDC.h"
|
#include "xf86DDC.h"
|
||||||
|
#include <drm_fourcc.h>
|
||||||
|
#include <drm_mode.h>
|
||||||
|
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include "xf86Crtc.h"
|
#include "xf86Crtc.h"
|
||||||
@ -376,10 +378,57 @@ drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo)
|
|||||||
return bo->dumb->ptr;
|
return bo->dumb->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
|
||||||
|
uint32_t *fb_id)
|
||||||
|
{
|
||||||
|
#ifdef GBM_BO_WITH_MODIFIERS
|
||||||
|
if (bo->gbm &&
|
||||||
|
gbm_bo_get_modifier(bo->gbm) != DRM_FORMAT_MOD_INVALID) {
|
||||||
|
int num_fds;
|
||||||
|
|
||||||
|
num_fds = gbm_bo_get_plane_count(bo->gbm);
|
||||||
|
if (num_fds > 0) {
|
||||||
|
int i;
|
||||||
|
uint32_t format;
|
||||||
|
uint32_t handles[4];
|
||||||
|
uint32_t strides[4];
|
||||||
|
uint32_t offsets[4];
|
||||||
|
uint64_t modifiers[4];
|
||||||
|
|
||||||
|
memset(handles, 0, sizeof(handles));
|
||||||
|
memset(strides, 0, sizeof(strides));
|
||||||
|
memset(offsets, 0, sizeof(offsets));
|
||||||
|
memset(modifiers, 0, sizeof(modifiers));
|
||||||
|
|
||||||
|
format = gbm_bo_get_format(bo->gbm);
|
||||||
|
for (i = 0; i < num_fds; i++) {
|
||||||
|
handles[i] = gbm_bo_get_handle_for_plane(bo->gbm, i).u32;
|
||||||
|
strides[i] = gbm_bo_get_stride_for_plane(bo->gbm, i);
|
||||||
|
offsets[i] = gbm_bo_get_offset(bo->gbm, i);
|
||||||
|
modifiers[i] = gbm_bo_get_modifier(bo->gbm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return drmModeAddFB2WithModifiers(drmmode->fd, bo->width, bo->height,
|
||||||
|
format, handles, strides,
|
||||||
|
offsets, modifiers, fb_id,
|
||||||
|
DRM_MODE_FB_MODIFIERS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return drmModeAddFB(drmmode->fd, bo->width, bo->height,
|
||||||
|
drmmode->scrn->depth, drmmode->scrn->bitsPerPixel,
|
||||||
|
drmmode_bo_get_pitch(bo),
|
||||||
|
drmmode_bo_get_handle(bo), fb_id);
|
||||||
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
|
drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
|
||||||
unsigned width, unsigned height, unsigned bpp)
|
unsigned width, unsigned height, unsigned bpp)
|
||||||
{
|
{
|
||||||
|
bo->width = width;
|
||||||
|
bo->height = height;
|
||||||
|
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef GLAMOR_HAS_GBM
|
||||||
if (drmmode->glamor) {
|
if (drmmode->glamor) {
|
||||||
bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
|
bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
|
||||||
|
@ -53,6 +53,8 @@ enum drmmode_plane_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
struct dumb_bo *dumb;
|
struct dumb_bo *dumb;
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef GLAMOR_HAS_GBM
|
||||||
struct gbm_bo *gbm;
|
struct gbm_bo *gbm;
|
||||||
@ -202,6 +204,8 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
|
|||||||
|
|
||||||
#define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
|
#define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
|
||||||
|
|
||||||
|
int drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
|
||||||
|
uint32_t *fb_id);
|
||||||
int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo);
|
int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo);
|
||||||
uint32_t drmmode_bo_get_pitch(drmmode_bo *bo);
|
uint32_t drmmode_bo_get_pitch(drmmode_bo *bo);
|
||||||
uint32_t drmmode_bo_get_handle(drmmode_bo *bo);
|
uint32_t drmmode_bo_get_handle(drmmode_bo *bo);
|
||||||
|
@ -258,6 +258,7 @@ ms_do_pageflip(ScreenPtr screen,
|
|||||||
|
|
||||||
new_front_bo.gbm = glamor_gbm_bo_from_pixmap(screen, new_front);
|
new_front_bo.gbm = glamor_gbm_bo_from_pixmap(screen, new_front);
|
||||||
new_front_bo.dumb = NULL;
|
new_front_bo.dumb = NULL;
|
||||||
|
|
||||||
if (!new_front_bo.gbm) {
|
if (!new_front_bo.gbm) {
|
||||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
||||||
"Failed to get GBM bo for flip to new front.\n");
|
"Failed to get GBM bo for flip to new front.\n");
|
||||||
@ -288,14 +289,12 @@ ms_do_pageflip(ScreenPtr screen,
|
|||||||
|
|
||||||
/* Create a new handle for the back buffer */
|
/* Create a new handle for the back buffer */
|
||||||
flipdata->old_fb_id = ms->drmmode.fb_id;
|
flipdata->old_fb_id = ms->drmmode.fb_id;
|
||||||
if (drmModeAddFB(ms->fd, scrn->virtualX, scrn->virtualY,
|
|
||||||
scrn->depth, scrn->bitsPerPixel,
|
|
||||||
drmmode_bo_get_pitch(&new_front_bo),
|
|
||||||
drmmode_bo_get_handle(&new_front_bo), &ms->drmmode.fb_id)) {
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
|
new_front_bo.width = new_front->drawable.width;
|
||||||
|
new_front_bo.height = new_front->drawable.height;
|
||||||
|
if (drmmode_bo_import(&ms->drmmode, &new_front_bo,
|
||||||
|
&ms->drmmode.fb_id))
|
||||||
|
goto error_out;
|
||||||
|
|
||||||
flags = DRM_MODE_PAGE_FLIP_EVENT;
|
flags = DRM_MODE_PAGE_FLIP_EVENT;
|
||||||
if (async)
|
if (async)
|
||||||
@ -323,6 +322,8 @@ ms_do_pageflip(ScreenPtr screen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do we have more than our local reference,
|
* Do we have more than our local reference,
|
||||||
* if so and no errors, then drop our local
|
* if so and no errors, then drop our local
|
||||||
@ -348,6 +349,7 @@ error_undo:
|
|||||||
error_out:
|
error_out:
|
||||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
|
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
|
||||||
/* if only the local reference - free the structure,
|
/* if only the local reference - free the structure,
|
||||||
* else drop the local reference and return */
|
* else drop the local reference and return */
|
||||||
if (flipdata->flip_count == 1)
|
if (flipdata->flip_count == 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user