From: Thomas Hellstrom <thellstrom@vmware.com>
To: dri-devel@lists.freedesktop.org
Subject: [PATCH 19/28] drm/vmwgfx: Add a kernel interface to create a framebuffer v2
Date: Wed, 12 Aug 2015 22:43:08 -0700 [thread overview]
Message-ID: <1439444597-4664-20-git-send-email-thellstrom@vmware.com> (raw)
In-Reply-To: <1439444597-4664-1-git-send-email-thellstrom@vmware.com>
The kernel interface is needed for fbdev, and needs to be free from
a file_priv member. To accomplish this, remove the fb surface mutex
and list which isn't used anymore, anyway.
Finally, make the pin() and unpin() pin the framebuffer for all display
system backends, so that fbdev can pin its framebuffer before mapping it.
v2: Address review comments:
- Fix vmw_framebuffer_unpin() to handle also the surface framebuffer case.
- Fix vmw_kms_new_framebuffer() to actually use the only_2d parameter.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
---
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 -
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 -
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 162 +++++++++++++++++++++---------------
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 8 +-
4 files changed, 102 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index e55db3f..bcf1962 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1142,8 +1142,6 @@ static void vmw_lastclose(struct drm_device *dev)
static void vmw_master_init(struct vmw_master *vmaster)
{
ttm_lock_init(&vmaster->lock);
- INIT_LIST_HEAD(&vmaster->fb_surf);
- mutex_init(&vmaster->fb_surf_mutex);
}
static int vmw_master_create(struct drm_device *dev,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index d6b247b..9ae5736 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -372,8 +372,6 @@ struct vmw_overlay;
struct vmw_master {
struct ttm_lock lock;
- struct mutex fb_surf_mutex;
- struct list_head fb_surf;
};
struct vmw_vga_topology_state {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 234a3ce..dc9f7d0 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -369,14 +369,7 @@ static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
{
struct vmw_framebuffer_surface *vfbs =
vmw_framebuffer_to_vfbs(framebuffer);
- struct vmw_master *vmaster = vmw_master(vfbs->master);
-
- mutex_lock(&vmaster->fb_surf_mutex);
- list_del(&vfbs->head);
- mutex_unlock(&vmaster->fb_surf_mutex);
-
- drm_master_put(&vfbs->master);
drm_framebuffer_cleanup(framebuffer);
vmw_surface_unreference(&vfbs->surface);
ttm_base_object_unref(&vfbs->base.user_obj);
@@ -396,9 +389,6 @@ static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
struct drm_clip_rect norect;
int ret, inc = 1;
- if (unlikely(vfbs->master != file_priv->master))
- return -EINVAL;
-
/* Legacy Display Unit does not support 3D */
if (dev_priv->active_display_unit == vmw_du_legacy)
return -EINVAL;
@@ -485,7 +475,6 @@ static struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
};
static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
- struct drm_file *file_priv,
struct vmw_surface *surface,
struct vmw_framebuffer **out,
const struct drm_mode_fb_cmd
@@ -496,7 +485,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
struct drm_device *dev = dev_priv->dev;
struct vmw_framebuffer_surface *vfbs;
enum SVGA3dSurfaceFormat format;
- struct vmw_master *vmaster = vmw_master(file_priv->master);
int ret;
/* 3D is only supported on HWv8 and newer hosts */
@@ -564,13 +552,8 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
vfbs->base.base.height = mode_cmd->height;
vfbs->surface = surface;
vfbs->base.user_handle = mode_cmd->handle;
- vfbs->master = drm_master_get(file_priv->master);
vfbs->is_dmabuf_proxy = is_dmabuf_proxy;
- mutex_lock(&vmaster->fb_surf_mutex);
- list_add_tail(&vfbs->head, &vmaster->fb_surf);
- mutex_unlock(&vmaster->fb_surf_mutex);
-
*out = &vfbs->base;
ret = drm_framebuffer_init(dev, &vfbs->base.base,
@@ -670,39 +653,51 @@ static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
/**
* Pin the dmabuffer to the start of vram.
*/
-static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
+static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
{
struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
- struct vmw_framebuffer_dmabuf *vfbd =
- vmw_framebuffer_to_vfbd(&vfb->base);
+ struct vmw_dma_buffer *buf;
int ret;
- /* This code should only be used with Legacy Display Unit */
- BUG_ON(dev_priv->active_display_unit != vmw_du_legacy);
-
- vmw_overlay_pause_all(dev_priv);
+ buf = vfb->dmabuf ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
+ vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
- ret = vmw_dmabuf_pin_in_start_of_vram(dev_priv, vfbd->buffer, false);
+ if (!buf)
+ return 0;
- vmw_overlay_resume_all(dev_priv);
+ switch (dev_priv->active_display_unit) {
+ case vmw_du_legacy:
+ vmw_overlay_pause_all(dev_priv);
+ ret = vmw_dmabuf_pin_in_start_of_vram(dev_priv, buf, false);
+ vmw_overlay_resume_all(dev_priv);
+ break;
+ case vmw_du_screen_object:
+ case vmw_du_screen_target:
+ if (vfb->dmabuf)
+ return vmw_dmabuf_pin_in_vram_or_gmr(dev_priv, buf,
+ false);
- WARN_ON(ret != 0);
+ return vmw_dmabuf_pin_in_placement(dev_priv, buf,
+ &vmw_mob_placement, false);
+ default:
+ return -EINVAL;
+ }
- return 0;
+ return ret;
}
-static int vmw_framebuffer_dmabuf_unpin(struct vmw_framebuffer *vfb)
+static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb)
{
struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
- struct vmw_framebuffer_dmabuf *vfbd =
- vmw_framebuffer_to_vfbd(&vfb->base);
+ struct vmw_dma_buffer *buf;
- if (!vfbd->buffer) {
- WARN_ON(!vfbd->buffer);
+ buf = vfb->dmabuf ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
+ vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
+
+ if (WARN_ON(!buf))
return 0;
- }
- return vmw_dmabuf_unpin(dev_priv, vfbd->buffer, false);
+ return vmw_dmabuf_unpin(dev_priv, buf, false);
}
/**
@@ -721,7 +716,7 @@ static int vmw_framebuffer_dmabuf_unpin(struct vmw_framebuffer *vfb)
* 0 on success, error code otherwise
*/
static int vmw_create_dmabuf_proxy(struct drm_device *dev,
- struct drm_mode_fb_cmd *mode_cmd,
+ const struct drm_mode_fb_cmd *mode_cmd,
struct vmw_dma_buffer *dmabuf_mob,
struct vmw_surface **srf_out)
{
@@ -847,10 +842,6 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
vfbd->base.base.depth = mode_cmd->depth;
vfbd->base.base.width = mode_cmd->width;
vfbd->base.base.height = mode_cmd->height;
- if (dev_priv->active_display_unit == vmw_du_legacy) {
- vfbd->base.pin = vmw_framebuffer_dmabuf_pin;
- vfbd->base.unpin = vmw_framebuffer_dmabuf_unpin;
- }
vfbd->base.dmabuf = true;
vfbd->buffer = dmabuf;
vfbd->base.user_handle = mode_cmd->handle;
@@ -871,6 +862,64 @@ out_err1:
return ret;
}
+/**
+ * vmw_kms_new_framebuffer - Create a new framebuffer.
+ *
+ * @dev_priv: Pointer to device private struct.
+ * @dmabuf: Pointer to dma buffer to wrap the kms framebuffer around.
+ * Either @dmabuf or @surface must be NULL.
+ * @surface: Pointer to a surface to wrap the kms framebuffer around.
+ * Either @dmabuf or @surface must be NULL.
+ * @only_2d: No presents will occur to this dma buffer based framebuffer. This
+ * Helps the code to do some important optimizations.
+ * @mode_cmd: Frame-buffer metadata.
+ */
+struct vmw_framebuffer *
+vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
+ struct vmw_dma_buffer *dmabuf,
+ struct vmw_surface *surface,
+ bool only_2d,
+ const struct drm_mode_fb_cmd *mode_cmd)
+{
+ struct vmw_framebuffer *vfb;
+ bool is_dmabuf_proxy = false;
+ int ret;
+
+ /*
+ * We cannot use the SurfaceDMA command in an non-accelerated VM,
+ * therefore, wrap the DMA buf in a surface so we can use the
+ * SurfaceCopy command.
+ */
+ if (dmabuf && only_2d &&
+ dev_priv->active_display_unit == vmw_du_screen_target) {
+ ret = vmw_create_dmabuf_proxy(dev_priv->dev, mode_cmd,
+ dmabuf, &surface);
+ if (ret)
+ return ERR_PTR(ret);
+
+ is_dmabuf_proxy = true;
+ }
+
+ /* Create the new framebuffer depending one what we have */
+ if (surface)
+ ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
+ mode_cmd,
+ is_dmabuf_proxy);
+ else if (dmabuf)
+ ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, dmabuf, &vfb,
+ mode_cmd);
+ else
+ BUG();
+
+ if (ret)
+ return ERR_PTR(ret);
+
+ vfb->pin = vmw_framebuffer_pin;
+ vfb->unpin = vmw_framebuffer_unpin;
+
+ return vfb;
+}
+
/*
* Generic Kernel modesetting functions
*/
@@ -886,7 +935,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
struct drm_mode_fb_cmd mode_cmd;
- bool is_dmabuf_proxy = false;
int ret;
mode_cmd.width = mode_cmd2->width;
@@ -935,31 +983,13 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
if (ret)
goto err_out;
- /*
- * We cannot use the SurfaceDMA command in an non-accelerated VM,
- * therefore, wrap the DMA buf in a surface so we can use the
- * SurfaceCopy command.
- */
- if (bo && !(dev_priv->capabilities & SVGA_CAP_3D) &&
- dev_priv->active_display_unit == vmw_du_screen_target) {
- ret = vmw_create_dmabuf_proxy(dev_priv->dev, &mode_cmd, bo,
- &surface);
- if (ret)
- goto err_out;
-
- is_dmabuf_proxy = true;
- }
-
- /* Create the new framebuffer depending one what we have */
- if (surface)
- ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv,
- surface, &vfb, &mode_cmd,
- is_dmabuf_proxy);
- else if (bo)
- ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb,
- &mode_cmd);
- else
- BUG();
+ vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
+ !(dev_priv->capabilities & SVGA_CAP_3D),
+ &mode_cmd);
+ if (IS_ERR(vfb)) {
+ ret = PTR_ERR(vfb);
+ goto err_out;
+ }
err_out:
/* vmw_user_lookup_handle takes one ref so does new_fb */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index f941f92..311effc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -114,7 +114,6 @@ struct vmw_framebuffer_surface {
struct vmw_surface *surface;
struct vmw_dma_buffer *buffer;
struct list_head head;
- struct drm_master *master;
bool is_dmabuf_proxy; /* true if this is proxy surface for DMA buf */
};
@@ -238,7 +237,12 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
struct drm_vmw_fence_rep __user *user_fence_rep,
struct drm_vmw_rect *vclips,
uint32_t num_clips);
-
+struct vmw_framebuffer *
+vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
+ struct vmw_dma_buffer *dmabuf,
+ struct vmw_surface *surface,
+ bool only_2d,
+ const struct drm_mode_fb_cmd *mode_cmd);
/*
* Legacy display unit functions - vmwgfx_ldu.c
--
2.1.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2015-08-13 6:36 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-13 5:42 [PATCH 00/28] vmwgfx preparation for GL3 Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 01/28] drm/vmwgfx: Fix an fb unlocking bug Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 02/28] vmwgfx: Rework device initialization Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 03/28] drm/vmwgfx: Fix OTABLE takedown Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 04/28] vmwgfx: Update device headers for command buffers Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 05/28] drm/vmwgfx: Add command buffer support v3 Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 06/28] drm/vmwgfx: Fix an overlay lockdep error Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 07/28] drm/vmwgfx: Add an interface to pin a resource v3 Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 08/28] drm/vmwgfx: SVGA device definition update Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 09/28] drm/vmwgfx: Refactor vmw_gb_surface_define_ioctl() Thomas Hellstrom
2015-08-13 5:42 ` [PATCH 10/28] vmwgfx: Major KMS refactoring / cleanup in preparation of screen targets Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 11/28] drm/vmwgfx: Add "quirk" to handling command verification exceptions Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 12/28] drm/vmwgfx: Implement screen targets Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 13/28] drm/vmwgfx: Replace SurfaceDMA usage with SurfaceCopy in 2D VMs Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 14/28] drm/vmwgfx: Introduce a pin count to allow for recursive pinning v2 Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 15/28] drm/vmwgfx: Add kms helpers for dirty- and readback functions Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 16/28] drm/vmwgfx: Convert screen objects to the new helpers Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 17/28] drm/vmwgfx: Convert screen targets to new helpers v3 Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 18/28] drm/vmwgfx: Avoid cmdbuf alloc sleeping if !TASK_RUNNING Thomas Hellstrom
2015-08-13 5:43 ` Thomas Hellstrom [this message]
2015-08-13 5:43 ` [PATCH 20/28] drm/vmwgfx: Implement fbdev on kms v2 Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 21/28] drm/vmwgfx: Reinstate the legacy display system dirty callback Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 22/28] drm/vmwgfx: Fix kms preferred mode sorting Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 23/28] drm/vmwgfx: Kill a bunch of sparse warnings Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 24/28] drm/vmwgfx: Fix compiler warning with 32-bit dma_addr_t Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 25/28] drm/vmwgfx: Fix an uninitialized value Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 26/28] drm/vmwgfx: Fixed topology boundary checking for Screen Targets Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 27/28] drm/vmwgfx: Fix framebuffer creation on older hardware Thomas Hellstrom
2015-08-13 5:43 ` [PATCH 28/28] drm/vmwgfx: Fix crash when unloading vmwgfx v2 Thomas Hellstrom
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1439444597-4664-20-git-send-email-thellstrom@vmware.com \
--to=thellstrom@vmware.com \
--cc=dri-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox