summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vmwgfx/vmwgfx_driver.c34
-rw-r--r--vmwgfx/vmwgfx_driver.h2
-rw-r--r--vmwgfx/vmwgfx_saa.c87
-rw-r--r--vmwgfx/vmwgfx_saa.h3
4 files changed, 93 insertions, 33 deletions
diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c
index 4ac829f..0504c2d 100644
--- a/vmwgfx/vmwgfx_driver.c
+++ b/vmwgfx/vmwgfx_driver.c
@@ -107,6 +107,7 @@ typedef enum
OPTION_RENDER_ACCEL,
OPTION_DRI,
OPTION_DIRECT_PRESENTS,
+ OPTION_HW_PRESENTS
} drv_option_enums;
static const OptionInfoRec drv_options[] = {
@@ -114,6 +115,7 @@ static const OptionInfoRec drv_options[] = {
{OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DIRECT_PRESENTS, "DirectPresents", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_HW_PRESENTS, "HWPresents", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -417,6 +419,11 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
&ms->direct_presents) ?
X_CONFIG : X_DEFAULT;
+ ms->only_hw_presents = FALSE;
+ ms->from_hwp = xf86GetOptValBool(ms->Options, OPTION_HW_PRESENTS,
+ &ms->only_hw_presents) ?
+ X_CONFIG : X_DEFAULT;
+
/* Allocate an xf86CrtcConfig */
xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -551,7 +558,7 @@ vmwgfx_scanout_present(ScreenPtr pScreen, int drm_fd,
}
if (vmwgfx_present(drm_fd, vpix->fb_id, 0, 0, dirty, handle) != 0) {
- LogMessage(X_ERROR, "Could not get present surface handle.\n");
+ LogMessage(X_ERROR, "Failed present kernel call.\n");
return FALSE;
}
@@ -610,13 +617,24 @@ void xorg_flush(ScreenPtr pScreen)
if (vpix->fb_id != -1) {
if (vpix->pending_update) {
- (void) vmwgfx_scanout_update(ms->fd, vpix->fb_id,
- vpix->pending_update);
+ if (ms->only_hw_presents &&
+ REGION_NOTEMPTY(pscreen, vpix->pending_update)) {
+ (void) vmwgfx_hw_accel_validate(pixmap, 0, XA_FLAG_SCANOUT,
+ 0, NULL);
+ REGION_UNION(pScreen, vpix->pending_present,
+ vpix->pending_present, vpix->pending_update);
+ } else
+ (void) vmwgfx_scanout_update(ms->fd, vpix->fb_id,
+ vpix->pending_update);
REGION_EMPTY(pScreen, vpix->pending_update);
}
if (vpix->pending_present) {
- (void) vmwgfx_scanout_present(pScreen, ms->fd, vpix,
- vpix->pending_present);
+ if (ms->only_hw_presents)
+ (void) vmwgfx_scanout_update(ms->fd, vpix->fb_id,
+ vpix->pending_present);
+ else
+ (void) vmwgfx_scanout_present(pScreen, ms->fd, vpix,
+ vpix->pending_present);
REGION_EMPTY(pScreen, vpix->pending_present);
}
}
@@ -916,7 +934,8 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
if (!vmwgfx_saa_init(pScreen, ms->fd, ms->xat, &xorg_flush,
- ms->direct_presents)) {
+ ms->direct_presents,
+ ms->only_hw_presents)) {
FatalError("Failed to initialize SAA.\n");
}
@@ -944,6 +963,9 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (ms->xat != NULL) {
xf86DrvMsg(pScrn->scrnIndex, ms->from_dp, "Direct presents are %s.\n",
(ms->direct_presents) ? "enabled" : "disabled");
+ xf86DrvMsg(pScrn->scrnIndex, ms->from_hwp, "Hardware only presents "
+ "are %s.\n",
+ (ms->only_hw_presents) ? "enabled" : "disabled");
}
miInitializeBackingStore(pScreen);
diff --git a/vmwgfx/vmwgfx_driver.h b/vmwgfx/vmwgfx_driver.h
index a88fa82..d0d4e52 100644
--- a/vmwgfx/vmwgfx_driver.h
+++ b/vmwgfx/vmwgfx_driver.h
@@ -94,6 +94,8 @@ typedef struct _modesettingRec
Bool from_dri;
Bool direct_presents;
Bool from_dp;
+ Bool only_hw_presents;
+ Bool from_hwp;
Bool isMaster;
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 50b9fe6..bd90b3d 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -1194,19 +1194,22 @@ vmwgfx_dirty(struct saa_driver *driver, PixmapPtr pixmap,
if (WSBMLISTEMPTY(&vpix->scanout_list))
return TRUE;
+#if 0
+ /*
+ * This code can be enabled to immediately upload scanout sw
+ * contents to the hw surface. Otherwise this is done
+ * just before we call the kms update function for the hw
+ * surface.
+ */
if (vsaa->only_hw_presents) {
- if (!vpix->hw) {
- if (!vmwgfx_hw_accel_stage(pixmap, 0, XA_FLAG_RENDER_TARGET, 0))
- return FALSE;
- if (!vmwgfx_hw_commit(pixmap))
- return FALSE;
- }
if (!hw && !vmwgfx_upload_to_hw(&vsaa->driver, pixmap, damage))
return FALSE;
+
REGION_SUBTRACT(&vsaa->pScreen, &spix->dirty_shadow,
&spix->dirty_shadow, damage);
hw = TRUE;
}
+#endif
/*
* Is the new scanout damage hw or sw?
@@ -1286,7 +1289,8 @@ static const struct saa_driver vmwgfx_saa_driver = {
Bool
vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
void (*present_flush)(ScreenPtr pScreen),
- Bool direct_presents)
+ Bool direct_presents,
+ Bool only_hw_presents)
{
struct vmwgfx_saa *vsaa;
@@ -1294,6 +1298,11 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
if (!vsaa)
return FALSE;
+ if (xat == NULL) {
+ direct_presents = FALSE;
+ only_hw_presents = FALSE;
+ }
+
vsaa->pScreen = pScreen;
vsaa->xat = xat;
if (xat)
@@ -1302,7 +1311,7 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
vsaa->present_flush = present_flush;
vsaa->can_optimize_dma = FALSE;
vsaa->use_present_opt = direct_presents;
- vsaa->only_hw_presents = FALSE;
+ vsaa->only_hw_presents = only_hw_presents;
WSBMINITLISTHEAD(&vsaa->sync_x_list);
vsaa->driver = vmwgfx_saa_driver;
@@ -1365,33 +1374,59 @@ vmwgfx_scanout_ref(struct vmwgfx_screen_entry *entry)
struct vmwgfx_saa *vsaa =
to_vmwgfx_saa(saa_get_driver(pixmap->drawable.pScreen));
struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
- int ret;
if (WSBMLISTEMPTY(&vpix->scanout_list)) {
- ret = !vmwgfx_pixmap_create_gmr(vsaa, pixmap);
- if (!ret)
- ret = !vmwgfx_pixmap_add_present(pixmap, vsaa->use_present_opt);
- if (!ret)
- ret = drmModeAddFB(vsaa->drm_fd,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->drawable.depth,
- pixmap->drawable.bitsPerPixel,
- pixmap->devKind,
- vpix->gmr->handle,
- &vpix->fb_id);
- if (ret) {
- entry->pixmap = NULL;
- vpix->fb_id = -1;
- goto out_err;
+ uint32_t handle, dummy;
+ unsigned int depth;
+
+ if (vsaa->only_hw_presents) {
+ /*
+ * The KMS fb will be a HW surface. Create it, add damage
+ * and get the handle.
+ */
+ if (!vmwgfx_hw_accel_validate(pixmap, 0, XA_FLAG_SCANOUT, 0, NULL))
+ goto out_err;
+ if (xa_surface_handle(vpix->hw, &handle, &dummy) != 0)
+ goto out_err;
+ depth = xa_format_depth(xa_surface_format(vpix->hw));
+
+ } else {
+ /*
+ * The KMS fb will be a Guest Memory Region. Create it,
+ * add damage and get the handle.
+ */
+ if (!vmwgfx_pixmap_create_gmr(vsaa, pixmap))
+ goto out_err;
+
+ handle = vpix->gmr->handle;
+ depth = pixmap->drawable.depth;
+
}
+ if (!vmwgfx_pixmap_add_present(pixmap, vsaa->use_present_opt))
+ goto out_no_present;
+
+ if (drmModeAddFB(vsaa->drm_fd,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ depth,
+ pixmap->drawable.bitsPerPixel,
+ pixmap->devKind,
+ handle,
+ &vpix->fb_id) != 0)
+ goto out_no_fb;;
}
pixmap->refcnt += 1;
WSBMLISTADDTAIL(&entry->scanout_head, &vpix->scanout_list);
+ return vpix->fb_id;
+ out_no_fb:
+ vmwgfx_pixmap_remove_present(vpix);
+ out_no_present:
+ vmwgfx_pixmap_remove_damage(pixmap);
out_err:
- return vpix->fb_id;
+ vpix->fb_id = -1;
+ return -1;
}
/*
diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h
index 1fd06b6..1276768 100644
--- a/vmwgfx/vmwgfx_saa.h
+++ b/vmwgfx/vmwgfx_saa.h
@@ -81,7 +81,8 @@ vmwgfx_saa_pixmap(PixmapPtr pix)
extern Bool
vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
void (*present_flush)(ScreenPtr pScreen),
- Bool direct_presents);
+ Bool direct_presents,
+ Bool only_hw_presents);
extern uint32_t
vmwgfx_scanout_ref(struct vmwgfx_screen_entry *box);