summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c14
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c63
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h12
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_screen.c44
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.c19
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.h3
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.c10
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h12
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c6
10 files changed, 160 insertions, 26 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index e719644d340..4e01bd10306 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -299,6 +299,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
GCPtr gc;
RegionPtr copy_clip;
Bool save_accel;
+ CustomizerPtr cust = ms->cust;
/*
* In driCreateBuffers we dewrap windows into the
@@ -352,7 +353,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
ValidateGC(dst_draw, gc);
/* If this is a full buffer swap, throttle on the previous one */
- if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
+ if (ms->swapThrottling &&
+ dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
if (extents->x1 == 0 && extents->y1 == 0 &&
@@ -374,6 +376,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
DamageRegionAppend(src_draw, pRegion);
DamageRegionProcessPending(src_draw);
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP);
+
(*gc->ops->CopyArea)(src_draw, dst_draw, gc,
0, 0, pDraw->width, pDraw->height, 0, 0);
ms->exa->accel = save_accel;
@@ -381,8 +386,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
FreeScratchGC(gc);
ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
- pDestBuffer->attachment == DRI2BufferFrontLeft ?
+ (pDestBuffer->attachment == DRI2BufferFrontLeft
+ && ms->swapThrottling) ?
&dst_priv->fence : NULL);
+
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
+
}
Bool
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 84c0545b1b7..6b6e2009fea 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -79,12 +79,16 @@ typedef enum
OPTION_SW_CURSOR,
OPTION_2D_ACCEL,
OPTION_DEBUG_FALLBACK,
+ OPTION_THROTTLE_SWAP,
+ OPTION_THROTTLE_DIRTY
} drv_option_enums;
static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_THROTTLE_SWAP, "SwapThrottling", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_THROTTLE_DIRTY, "DirtyThrottling", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -534,23 +538,29 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
if (ms->ctx) {
int j;
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
+ ms->dirtyThrottling ?
+ &ms->fence[XORG_NR_FENCES-1] :
+ NULL);
- if (ms->fence[0])
- ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
+ if (ms->dirtyThrottling) {
+ if (ms->fence[0])
+ ms->ctx->screen->fence_finish(ms->ctx->screen,
+ ms->fence[0], 0);
- /* The amount of rendering generated by a block handler can be
- * quite small. Let us get a fair way ahead of hardware before
- * throttling.
- */
- for (j = 0; j < XORG_NR_FENCES - 1; j++)
- ms->screen->fence_reference(ms->screen,
- &ms->fence[j],
- ms->fence[j+1]);
-
- ms->screen->fence_reference(ms->screen,
- &ms->fence[XORG_NR_FENCES-1],
- NULL);
+ /* The amount of rendering generated by a block handler can be
+ * quite small. Let us get a fair way ahead of hardware before
+ * throttling.
+ */
+ for (j = 0; j < XORG_NR_FENCES - 1; j++)
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[j],
+ ms->fence[j+1]);
+
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[XORG_NR_FENCES-1],
+ NULL);
+ }
}
@@ -634,6 +644,8 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
unsigned max_width, max_height;
VisualPtr visual;
CustomizerPtr cust = ms->cust;
+ MessageType from_st;
+ MessageType from_dt;
if (!drv_init_drm(pScrn)) {
FatalError("Could not init DRM");
@@ -720,6 +732,19 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
+ if (cust && cust->winsys_screen_init)
+ cust->winsys_screen_init(cust, ms->fd);
+
+ ms->swapThrottling = cust ? cust->swap_throttling : TRUE;
+ from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP,
+ &ms->swapThrottling) ?
+ X_CONFIG : X_DEFAULT;
+
+ ms->dirtyThrottling = cust ? cust->dirty_throttling : TRUE;
+ from_dt = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_DIRTY,
+ &ms->dirtyThrottling) ?
+ X_CONFIG : X_DEFAULT;
+
if (ms->screen) {
ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
@@ -744,6 +769,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
#endif
+ xf86DrvMsg(pScrn->scrnIndex, from_st, "Swap Throttling is %s.\n",
+ ms->swapThrottling ? "enabled" : "disabled");
+ xf86DrvMsg(pScrn->scrnIndex, from_dt, "Dirty Throttling is %s.\n",
+ ms->dirtyThrottling ? "enabled" : "disabled");
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
miInitializeBackingStore(pScreen);
@@ -776,9 +806,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- if (cust && cust->winsys_screen_init)
- cust->winsys_screen_init(cust, ms->fd);
-
return drv_enter_vt(scrnIndex, 1);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index ce5e5874e79..bd846683000 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -986,6 +986,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa;
ExaDriverPtr pExa;
+ CustomizerPtr cust = ms->cust;
exa = xcalloc(1, sizeof(struct exa_context));
if (!exa)
@@ -1047,6 +1048,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
/* Share context with DRI */
ms->ctx = exa->pipe;
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
exa->renderer = renderer_create(exa->pipe);
exa->accel = accel;
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 65fbc3234ba..25da9b1a3bd 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -67,12 +67,22 @@ typedef struct
#define XORG_NR_FENCES 3
+enum xorg_throttling_reason {
+ THROTTLE_RENDER,
+ THROTTLE_SWAP
+};
+
typedef struct _CustomizerRec
{
+ Bool dirty_throttling;
+ Bool swap_throttling;
Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
+ void (*winsys_context_throttle)(struct _CustomizerRec *cust,
+ struct pipe_context *pipe,
+ enum xorg_throttling_reason reason);
} CustomizerRec, *CustomizerPtr;
typedef struct _modesettingRec
@@ -91,6 +101,8 @@ typedef struct _modesettingRec
Bool noAccel;
Bool SWCursor;
CursorPtr cursor;
+ Bool swapThrottling;
+ Bool dirtyThrottling;
CloseScreenProcPtr CloseScreen;
/* Broken-out options. */
diff --git a/src/gallium/targets/xorg-vmwgfx/vmw_screen.c b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
index 5e4ef41688d..e0edf32adb4 100644
--- a/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
@@ -32,9 +32,14 @@
#include "vmw_hook.h"
#include "vmw_driver.h"
+#include <pipe/p_context.h>
#include "cursorstr.h"
+void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us);
+
+
/* modified version of crtc functions */
xf86CrtcFuncsRec vmw_screen_crtc_funcs;
@@ -83,12 +88,51 @@ vmw_screen_cursor_close(struct vmw_customizer *vmw)
config->crtc[i]->funcs = vmw->cursor_priv;
}
+static void
+vmw_context_throttle(CustomizerPtr cust,
+ struct pipe_context *pipe,
+ enum xorg_throttling_reason reason)
+{
+ switch (reason) {
+ case THROTTLE_RENDER:
+ vmw_winsys_screen_set_throttling(pipe->screen, 20000);
+ break;
+ default:
+ vmw_winsys_screen_set_throttling(pipe->screen, 0);
+ }
+}
+
+static void
+vmw_context_no_throttle(CustomizerPtr cust,
+ struct pipe_context *pipe,
+ enum xorg_throttling_reason reason)
+{
+ vmw_winsys_screen_set_throttling(pipe->screen, 0);
+}
+
static Bool
vmw_screen_init(CustomizerPtr cust, int fd)
{
struct vmw_customizer *vmw = vmw_customizer(cust);
+ drmVersionPtr ver;
vmw->fd = fd;
+ ver = drmGetVersion(fd);
+ if (ver == NULL ||
+ (ver->version_major == 1 && ver->version_minor < 1)) {
+ cust->swap_throttling = TRUE;
+ cust->dirty_throttling = TRUE;
+ cust->winsys_context_throttle = vmw_context_no_throttle;
+ } else {
+ cust->swap_throttling = TRUE;
+ cust->dirty_throttling = FALSE;
+ cust->winsys_context_throttle = vmw_context_throttle;
+ debug_printf("%s: Enabling kernel throttling.\n", __func__);
+ }
+
+ if (ver)
+ drmFreeVersion(ver);
+
vmw_screen_cursor_init(vmw);
vmw_ctrl_ext_init(vmw);
diff --git a/src/gallium/winsys/svga/drm/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c
index 104d03f2730..11626ee637d 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
@@ -103,6 +103,9 @@ struct vmw_svga_winsys_context
* referred.
*/
boolean preemptive_flush;
+
+ boolean throttle_set;
+ uint32_t throttle_us;
};
@@ -135,6 +138,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
struct pipe_fence_handle *fence = NULL;
unsigned i;
enum pipe_error ret;
+ uint32_t throttle_us;
ret = pb_validate_validate(vswc->validate);
assert(ret == PIPE_OK);
@@ -153,8 +157,13 @@ vmw_swc_flush(struct svga_winsys_context *swc,
*reloc->where = ptr;
}
+ throttle_us = vswc->throttle_set ?
+ vswc->throttle_us : vswc->vws->default_throttle_us;
+
if (vswc->command.used)
vmw_ioctl_command(vswc->vws,
+ vswc->base.cid,
+ throttle_us,
vswc->command.buffer,
vswc->command.used,
&vswc->last_fence);
@@ -395,3 +404,13 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
}
+void
+vmw_svga_context_set_throttling(struct pipe_context *pipe,
+ uint32_t throttle_us)
+{
+ struct svga_winsys_context *swc = svga_winsys_context(pipe);
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+ vswc->throttle_us = throttle_us;
+ vswc->throttle_set = TRUE;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_context.h b/src/gallium/winsys/svga/drm/vmw_context.h
index d4884d24e99..aed8b93734b 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.h
+++ b/src/gallium/winsys/svga/drm/vmw_context.h
@@ -52,5 +52,8 @@ struct pipe_screen;
struct svga_winsys_context *
vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
+void
+vmw_svga_context_set_throttling(struct pipe_context *pipe,
+ uint32_t throttle_us);
#endif /* VMW_CONTEXT_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
index 6cc9b382932..51a4c55e5a2 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
@@ -75,3 +75,13 @@ vmw_winsys_destroy(struct vmw_winsys_screen *vws)
vmw_ioctl_cleanup(vws);
FREE(vws);
}
+
+void
+vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us)
+{
+ struct vmw_winsys_screen *vws =
+ vmw_winsys_screen(svga_winsys_screen(screen));
+
+ vws->default_throttle_us = throttle_us;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index d3f2c2c7f56..b3de72df881 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -53,6 +53,7 @@ struct vmw_winsys_screen
struct svga_winsys_screen base;
boolean use_old_scanout_flag;
+ uint32_t default_throttle_us;
struct {
volatile uint32_t *fifo_map;
@@ -96,9 +97,11 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
void
vmw_ioctl_command(struct vmw_winsys_screen *vws,
- void *commands,
- uint32_t size,
- uint32_t *fence);
+ int32_t cid,
+ uint32_t throttle_us,
+ void *commands,
+ uint32_t size,
+ uint32_t *fence);
struct vmw_region *
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
@@ -135,6 +138,7 @@ void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag);
void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
-
+void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us);
#endif /* VMW_SCREEN_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 5d81fa8c4a6..d92ba389d35 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -241,8 +241,9 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
}
void
-vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
- uint32_t * pfence)
+vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
+ uint32_t throttle_us, void *commands, uint32_t size,
+ uint32_t *pfence)
{
struct drm_vmw_execbuf_arg arg;
struct drm_vmw_fence_rep rep;
@@ -275,6 +276,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
arg.fence_rep = (unsigned long)&rep;
arg.commands = (unsigned long)commands;
arg.command_size = size;
+ arg.throttle_us = throttle_us;
do {
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));