mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
svga: Introduce userspace managed surfaces
Surfaces are currently managed by the vmwgfx kernel driver, and userspace interacts with surfaces through DRM_VMW_*_SURFACE ioctls. We would like to move to userspace managed surfaces to simplify surface and buffer management across mesa and kernel driver. This change introduces such surfaces, in which the userspace manages surface id's and submits the create and destroy commands. Userspace managed surfaces can be enabled with VMW_SVGA_USERSPACE_SURFACE environment variable. This change is tested with all piglit tests under spec@arb_copy_buffer@* with userspace surfaces turned on. Signed-off-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31744>
This commit is contained in:
parent
40e6761262
commit
88804b8265
10 changed files with 200 additions and 3 deletions
|
|
@ -239,6 +239,20 @@ SVGA3D_SetGBShader(struct svga_winsys_context *swc,
|
|||
SVGA3dShaderType type,
|
||||
struct svga_winsys_gb_shader *gbshader);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DefineGBSurface_v4(struct svga_winsys_context *swc,
|
||||
uint32 sid,
|
||||
SVGA3dSurfaceAllFlags surfaceFlags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
uint32 numMipLevels,
|
||||
uint32 multisampleCount,
|
||||
SVGA3dMSPattern multisamplePattern,
|
||||
SVGA3dMSQualityLevel qualityLevel,
|
||||
SVGA3dTextureFilter autogenFilter,
|
||||
SVGA3dSize size,
|
||||
uint32 arraySize,
|
||||
uint32 bufferByteStride);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_BindGBSurface(struct svga_winsys_context *swc,
|
||||
struct svga_winsys_surface *surface);
|
||||
|
|
@ -293,6 +307,10 @@ SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc,
|
|||
SVGA3dShaderConstType constType,
|
||||
const void *values);
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DestroyGBSurface(struct svga_winsys_context *swc,
|
||||
uint32 sid);
|
||||
|
||||
/*
|
||||
* Queries
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1813,3 +1813,63 @@ SVGA3D_sm5_DefineRasterizerState_v2(struct svga_winsys_context *swc,
|
|||
swc->commit(swc);
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DefineGBSurface_v4(struct svga_winsys_context *swc,
|
||||
uint32 sid,
|
||||
SVGA3dSurfaceAllFlags surfaceFlags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
uint32 numMipLevels,
|
||||
uint32 multisampleCount,
|
||||
SVGA3dMSPattern multisamplePattern,
|
||||
SVGA3dMSQualityLevel qualityLevel,
|
||||
SVGA3dTextureFilter autogenFilter,
|
||||
SVGA3dSize size,
|
||||
uint32 arraySize,
|
||||
uint32 bufferByteStride)
|
||||
{
|
||||
SVGA3dCmdDefineGBSurface_v4 *cmd =
|
||||
SVGA3D_FIFOReserve(swc,
|
||||
SVGA_3D_CMD_DEFINE_GB_SURFACE_V4,
|
||||
sizeof(*cmd),
|
||||
0);
|
||||
|
||||
if(!cmd)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
cmd->sid = sid;
|
||||
cmd->surfaceFlags = surfaceFlags;
|
||||
cmd->format = format;
|
||||
cmd->numMipLevels = numMipLevels;
|
||||
cmd->multisampleCount = multisampleCount;
|
||||
cmd->multisamplePattern = multisamplePattern;
|
||||
cmd->qualityLevel = qualityLevel;
|
||||
cmd->autogenFilter = autogenFilter;
|
||||
cmd->size = size;
|
||||
cmd->arraySize = arraySize;
|
||||
cmd->bufferByteStride = bufferByteStride;
|
||||
|
||||
swc->commit(swc);
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
enum pipe_error
|
||||
SVGA3D_DestroyGBSurface(struct svga_winsys_context *swc,
|
||||
uint32 sid)
|
||||
{
|
||||
SVGA3dCmdDestroyGBSurface *cmd =
|
||||
SVGA3D_FIFOReserve(swc,
|
||||
SVGA_3D_CMD_DESTROY_GB_SURFACE,
|
||||
sizeof(*cmd),
|
||||
0);
|
||||
|
||||
if(!cmd)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
cmd->sid = sid;
|
||||
|
||||
swc->commit(swc);
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "util/u_debug_stack.h"
|
||||
#include "util/u_debug_flush.h"
|
||||
#include "util/u_hash_table.h"
|
||||
#include "util/u_bitmask.h"
|
||||
#include "util/u_atomic.h"
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_validate.h"
|
||||
|
|
@ -130,6 +131,9 @@ struct vmw_svga_winsys_context
|
|||
|
||||
int32_t refcount;
|
||||
|
||||
/* Bitmask of userspace managed surfaces */
|
||||
struct util_bitmask *surface_id_bm;
|
||||
|
||||
/**
|
||||
* Whether this context should fail to reserve more commands, not because it
|
||||
* ran out of command space, but because a substantial ammount of GMR was
|
||||
|
|
@ -660,6 +664,8 @@ vmw_swc_destroy(struct svga_winsys_context *swc)
|
|||
vmw_svga_winsys_shader_reference(&ishader->vshader, NULL);
|
||||
}
|
||||
|
||||
if (vmw_has_userspace_surface(vswc->vws))
|
||||
util_bitmask_destroy(vswc->surface_id_bm);
|
||||
_mesa_hash_table_destroy(vswc->hash, NULL);
|
||||
pb_validate_destroy(vswc->validate);
|
||||
vmw_ioctl_context_destroy(vswc->vws, swc->cid);
|
||||
|
|
@ -825,6 +831,16 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
|
|||
if (!vswc->hash)
|
||||
goto out_no_hash;
|
||||
|
||||
if (vmw_has_userspace_surface(vws)) {
|
||||
if(!(vswc->surface_id_bm = util_bitmask_create()))
|
||||
goto out_no_user_srf;
|
||||
/**
|
||||
* First id assigned is 0 which is invalid for surface id. Consume the
|
||||
* first id.
|
||||
*/
|
||||
vmw_swc_surface_add_userspace_id(&vswc->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* The context refcount is initialized to 2, one reference is for the context
|
||||
* itself and the other is for vws screen. One unref is done when context
|
||||
|
|
@ -847,6 +863,8 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
|
|||
vswc->base.force_coherent = vws->force_coherent;
|
||||
return &vswc->base;
|
||||
|
||||
out_no_user_srf:
|
||||
_mesa_hash_table_destroy(vswc->hash, NULL);
|
||||
out_no_hash:
|
||||
pb_validate_destroy(vswc->validate);
|
||||
out_no_validate:
|
||||
|
|
@ -855,3 +873,18 @@ out_no_context:
|
|||
FREE(vswc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
vmw_swc_surface_clear_userspace_id(struct svga_winsys_context *swc,
|
||||
uint32 sid)
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
util_bitmask_clear(vswc->surface_id_bm, sid);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
vmw_swc_surface_add_userspace_id(struct svga_winsys_context *swc)
|
||||
{
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
return util_bitmask_add(vswc->surface_id_bm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,5 +54,11 @@ vmw_swc_surface_clear_reference(struct svga_winsys_context *swc,
|
|||
void
|
||||
vmw_swc_unref(struct svga_winsys_context *swc);
|
||||
|
||||
void
|
||||
vmw_swc_surface_clear_userspace_id(struct svga_winsys_context *swc,
|
||||
uint32_t sid);
|
||||
|
||||
uint32_t
|
||||
vmw_swc_surface_add_userspace_id(struct svga_winsys_context *swc);
|
||||
|
||||
#endif /* VMW_CONTEXT_H_ */
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ struct vmw_winsys_screen
|
|||
|
||||
bool force_coherent;
|
||||
bool cache_maps;
|
||||
bool userspace_surface;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -114,6 +115,14 @@ vmw_winsys_screen(struct svga_winsys_screen *base)
|
|||
return (struct vmw_winsys_screen *)base;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
vmw_has_userspace_surface(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
if (!vws->base.have_gb_objects || !vws->base.have_vgpu10)
|
||||
return false;
|
||||
return vws->userspace_surface;
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32_t
|
||||
vmw_region_size(struct vmw_region *region);
|
||||
|
|
|
|||
|
|
@ -1181,6 +1181,22 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/* Userspace surfaces are only supported on guest-backed hardware */
|
||||
vws->userspace_surface = false;
|
||||
getenv_val = getenv("VMW_SVGA_USERSPACE_SURFACE");
|
||||
if (getenv_val && atoi(getenv_val)) {
|
||||
assert(vws->base.have_gb_objects);
|
||||
assert(vws->base.have_vgpu10);
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_USER_SRF;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM, &gp_arg,
|
||||
sizeof(gp_arg));
|
||||
if (!ret && gp_arg.value == true) {
|
||||
vws->userspace_surface = true;
|
||||
debug_printf("Using userspace managed surfaces\n");
|
||||
}
|
||||
}
|
||||
|
||||
debug_printf("VGPU10 interface is %s.\n",
|
||||
vws->base.have_vgpu10 ? "on" : "off");
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "util/u_inlines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_bitmask.h"
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_bufmgr.h"
|
||||
#include "svga_winsys.h"
|
||||
|
|
@ -516,7 +517,41 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
|
|||
goto no_sid;
|
||||
}
|
||||
|
||||
if (sws->have_gb_objects) {
|
||||
if (vmw_has_userspace_surface(vws)) {
|
||||
struct svga_winsys_context *swc = vws->swc;
|
||||
struct pb_buffer *pb_buf;
|
||||
|
||||
surface->sid = vmw_swc_surface_add_userspace_id(swc);
|
||||
if (surface->sid == UTIL_BITMASK_INVALID_INDEX)
|
||||
goto no_sid;
|
||||
|
||||
if (SVGA3D_DefineGBSurface_v4(swc, surface->sid, flags, format,
|
||||
numMipLevels, sampleCount, multisample_pattern, quality_level,
|
||||
SVGA3D_TEX_FILTER_NONE, size, numLayers, 0) != PIPE_OK) {
|
||||
vmw_swc_surface_clear_userspace_id(swc, surface->sid);
|
||||
goto no_sid;
|
||||
}
|
||||
|
||||
desc.pb_desc.alignment = 4096;
|
||||
desc.pb_desc.usage = VMW_BUFFER_USAGE_SHARED;
|
||||
surface->size = buffer_size;
|
||||
pb_buf = provider->create_buffer(provider, surface->size,
|
||||
&desc.pb_desc);
|
||||
surface->buf = vmw_svga_winsys_buffer_wrap(pb_buf);
|
||||
|
||||
if (surface->buf == NULL) {
|
||||
vmw_svga_winsys_userspace_surface_destroy(swc, surface->sid);
|
||||
goto no_sid;
|
||||
}
|
||||
|
||||
if (SVGA3D_BindGBSurface(swc, svga_winsys_surface(surface)) != PIPE_OK) {
|
||||
vmw_svga_winsys_buffer_destroy(sws, surface->buf);
|
||||
vmw_svga_winsys_userspace_surface_destroy(swc, surface->sid);
|
||||
goto no_sid;
|
||||
}
|
||||
|
||||
swc->flush(swc, NULL);
|
||||
} else if (sws->have_gb_objects) {
|
||||
struct pb_buffer *pb_buf;
|
||||
|
||||
surface->sid = vmw_ioctl_gb_surface_create(vws, flags, format, usage,
|
||||
|
|
|
|||
|
|
@ -223,6 +223,15 @@ vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc,
|
|||
mtx_unlock(&vsrf->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
vmw_svga_winsys_userspace_surface_destroy(struct svga_winsys_context *swc,
|
||||
uint32 sid)
|
||||
{
|
||||
SVGA3D_DestroyGBSurface(swc, sid);
|
||||
swc->flush(swc, NULL);
|
||||
vmw_swc_surface_clear_userspace_id(swc, sid);
|
||||
}
|
||||
|
||||
void
|
||||
vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
|
||||
struct vmw_svga_winsys_surface *src)
|
||||
|
|
@ -242,7 +251,10 @@ vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
|
|||
if (pipe_reference(dst_ref, src_ref)) {
|
||||
if (dst->buf)
|
||||
vmw_svga_winsys_buffer_destroy(&dst->screen->base, dst->buf);
|
||||
vmw_ioctl_surface_destroy(dst->screen, dst->sid);
|
||||
if (vmw_has_userspace_surface(dst->screen))
|
||||
vmw_svga_winsys_userspace_surface_destroy(dst->screen->swc, dst->sid);
|
||||
else
|
||||
vmw_ioctl_surface_destroy(dst->screen, dst->sid);
|
||||
#if MESA_DEBUG
|
||||
/* to detect dangling pointers */
|
||||
assert(p_atomic_read(&dst->validated) == 0);
|
||||
|
|
|
|||
|
|
@ -82,5 +82,9 @@ void
|
|||
vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_surface *surface,
|
||||
unsigned surf_size, SVGA3dSurfaceAllFlags flags);
|
||||
|
||||
|
||||
void
|
||||
vmw_svga_winsys_userspace_surface_destroy(struct svga_winsys_context *swc,
|
||||
uint32 sid);
|
||||
|
||||
#endif /* VMW_SURFACE_H_ */
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ extern "C" {
|
|||
*
|
||||
* DRM_VMW_PARAM_DEVICE_ID
|
||||
* PCI ID of the underlying SVGA device.
|
||||
*
|
||||
* DRM_VMW_PARAM_USER_SRF
|
||||
* Userspace managed surface support is enabled.
|
||||
*/
|
||||
|
||||
#define DRM_VMW_PARAM_NUM_STREAMS 0
|
||||
|
|
@ -98,6 +101,7 @@ extern "C" {
|
|||
#define DRM_VMW_PARAM_SM5 15
|
||||
#define DRM_VMW_PARAM_GL43 16
|
||||
#define DRM_VMW_PARAM_DEVICE_ID 17
|
||||
#define DRM_VMW_PARAM_USER_SRF 18
|
||||
|
||||
/**
|
||||
* enum drm_vmw_handle_type - handle type for ref ioctls
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue