diff options
Diffstat (limited to 'src/gallium/winsys/svga')
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_context.c | 19 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_screen.h | 1 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_screen_ioctl.c | 17 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_screen_svga.c | 24 |
4 files changed, 59 insertions, 2 deletions
diff --git a/src/gallium/winsys/svga/drm/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c index 1234a5edce3..4e1c41db886 100644 --- a/src/gallium/winsys/svga/drm/vmw_context.c +++ b/src/gallium/winsys/svga/drm/vmw_context.c @@ -49,6 +49,21 @@ #define VMW_MUST_FLUSH_STACK 8 +/* + * A factor applied to the maximum mob memory size to determine + * the optimial time to preemptively flush the command buffer. + * The constant is based on some performance trials with SpecViewperf. + */ +#define VMW_MAX_MOB_MEM_FACTOR 2 + +/* + * A factor applied to the maximum surface memory size to determine + * the optimial time to preemptively flush the command buffer. + * The constant is based on some performance trials with SpecViewperf. + */ +#define VMW_MAX_SURF_MEM_FACTOR 2 + + struct vmw_buffer_relocation { struct pb_buffer *buffer; @@ -395,7 +410,7 @@ vmw_swc_mob_relocation(struct svga_winsys_context *swc, if (vmw_swc_add_validate_buffer(vswc, reloc->buffer, flags)) { vswc->seen_mobs += reloc->buffer->size; /* divide by 5, tested for best performance */ - if (vswc->seen_mobs >= vswc->vws->ioctl.max_mob_memory / 5) + if (vswc->seen_mobs >= vswc->vws->ioctl.max_mob_memory / VMW_MAX_MOB_MEM_FACTOR) vswc->preemptive_flush = TRUE; } @@ -457,7 +472,7 @@ vmw_swc_surface_only_relocation(struct svga_winsys_context *swc, vswc->seen_surfaces += vsurf->size; /* divide by 5 not well tuned for performance */ - if (vswc->seen_surfaces >= vswc->vws->ioctl.max_surface_memory / 5) + if (vswc->seen_surfaces >= vswc->vws->ioctl.max_surface_memory / VMW_MAX_SURF_MEM_FACTOR) vswc->preemptive_flush = TRUE; } diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h index 1a39039aabd..fd76e614a5e 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen.h +++ b/src/gallium/winsys/svga/drm/vmw_screen.h @@ -74,6 +74,7 @@ struct vmw_winsys_screen struct vmw_cap_3d *cap_3d; uint64_t max_mob_memory; uint64_t max_surface_memory; + uint64_t max_texture_size; boolean have_drm_2_6; } ioctl; diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c index 9c0abe96204..c9a3b7544d2 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c @@ -51,6 +51,8 @@ #include <errno.h> #include <unistd.h> +#define VMW_MAX_DEFAULT_TEXTURE_SIZE (128 * 1024 * 1024) + struct vmw_region { uint32_t handle; @@ -904,6 +906,18 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws) } else { vws->ioctl.max_mob_memory = gp_arg.value; } + + memset(&gp_arg, 0, sizeof(gp_arg)); + gp_arg.param = DRM_VMW_PARAM_MAX_MOB_SIZE; + ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM, + &gp_arg, sizeof(gp_arg)); + + if (ret || gp_arg.value == 0) { + vws->ioctl.max_texture_size = VMW_MAX_DEFAULT_TEXTURE_SIZE; + } else { + vws->ioctl.max_texture_size = gp_arg.value; + } + /* Never early flush surfaces, mobs do accounting. */ vws->ioctl.max_surface_memory = -1; } else { @@ -920,6 +934,9 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws) } else { vws->ioctl.max_surface_memory = gp_arg.value; } + + vws->ioctl.max_texture_size = VMW_MAX_DEFAULT_TEXTURE_SIZE; + size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t); } diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c index 6d592f2a957..32f16cd447a 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c @@ -164,6 +164,10 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws, * when to flush on non-GB hosts. */ buffer_size = svga3dsurface_get_serialized_size(format, size, numMipLevels, (numFaces == 6)); + if (buffer_size > vws->ioctl.max_texture_size) { + goto no_sid; + } + if (sws->have_gb_objects) { SVGAGuestPtr ptr = {0,0}; @@ -249,6 +253,25 @@ no_surface: return NULL; } +static boolean +vmw_svga_winsys_surface_can_create(struct svga_winsys_screen *sws, + SVGA3dSurfaceFormat format, + SVGA3dSize size, + uint32 numFaces, + uint32 numMipLevels) +{ + struct vmw_winsys_screen *vws = vmw_winsys_screen(sws); + uint32_t buffer_size; + + buffer_size = svga3dsurface_get_serialized_size(format, size, + numMipLevels, + (numFaces == 6)); + if (buffer_size > vws->ioctl.max_texture_size) { + return FALSE; + } + return TRUE; +} + static boolean vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen *sws, @@ -371,6 +394,7 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws) vws->base.surface_create = vmw_svga_winsys_surface_create; vws->base.surface_is_flushed = vmw_svga_winsys_surface_is_flushed; vws->base.surface_reference = vmw_svga_winsys_surface_ref; + vws->base.surface_can_create = vmw_svga_winsys_surface_can_create; vws->base.buffer_create = vmw_svga_winsys_buffer_create; vws->base.buffer_map = vmw_svga_winsys_buffer_map; vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap; |