diff options
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_dri2.c | 14 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_driver.c | 63 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 3 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_tracker.h | 12 | ||||
-rw-r--r-- | src/gallium/targets/xorg-vmwgfx/vmw_screen.c | 44 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_context.c | 19 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_context.h | 3 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_screen.c | 10 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_screen.h | 12 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_screen_ioctl.c | 6 |
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)); |