diff options
-rw-r--r-- | vmwgfx/vmwgfx_driver.c | 34 | ||||
-rw-r--r-- | vmwgfx/vmwgfx_driver.h | 2 | ||||
-rw-r--r-- | vmwgfx/vmwgfx_saa.c | 87 | ||||
-rw-r--r-- | vmwgfx/vmwgfx_saa.h | 3 |
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); |