Newer
Older
// SPDX-License-Identifier: GPL-2.0 OR MIT
/******************************************************************************
*
* COPYRIGHT (C) 2014-2023 VMware, Inc., Palo Alto, CA., USA
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
******************************************************************************/
#include "vmwgfx_bo.h"
#include "vmwgfx_kms.h"
#include "vmw_surface_cache.h"
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#define vmw_crtc_to_stdu(x) \
container_of(x, struct vmw_screen_target_display_unit, base.crtc)
#define vmw_encoder_to_stdu(x) \
container_of(x, struct vmw_screen_target_display_unit, base.encoder)
#define vmw_connector_to_stdu(x) \
container_of(x, struct vmw_screen_target_display_unit, base.connector)
enum stdu_content_type {
SAME_AS_DISPLAY = 0,
SEPARATE_SURFACE,
/**
* struct vmw_stdu_dirty - closure structure for the update functions
*
* @base: The base type we derive from. Used by vmw_kms_helper_dirty().
* @transfer: Transfer direction for DMA command.
* @left: Left side of bounding box.
* @right: Right side of bounding box.
* @top: Top side of bounding box.
* @bottom: Bottom side of bounding box.
* @fb_left: Left side of the framebuffer/content bounding box
* @fb_top: Top of the framebuffer/content bounding box
* @pitch: framebuffer pitch (stride)
* @buf: buffer object when DMA-ing between buffer and screen targets.
* @sid: Surface ID when copying between surface and screen targets.
*/
struct vmw_stdu_dirty {
struct vmw_kms_dirty base;
s32 left, right, top, bottom;
u32 pitch;
union {
u32 sid;
};
};
/*
* SVGA commands that are used by this code. Please see the device headers
* for explanation.
*/
struct vmw_stdu_update {
SVGA3dCmdHeader header;
SVGA3dCmdUpdateGBScreenTarget body;
};
struct vmw_stdu_dma {
SVGA3dCmdHeader header;
SVGA3dCmdSurfaceDMA body;
};
struct vmw_stdu_surface_copy {
SVGA3dCmdHeader header;
SVGA3dCmdSurfaceCopy body;
};
struct vmw_stdu_update_gb_image {
SVGA3dCmdHeader header;
SVGA3dCmdUpdateGBImage body;
};
/**
* struct vmw_screen_target_display_unit
*
* @base: VMW specific DU structure
* @display_srf: surface to be displayed. The dimension of this will always
* match the display mode. If the display mode matches
* content_vfbs dimensions, then this is a pointer into the
* corresponding field in content_vfbs. If not, then this
* is a separate buffer to which content_vfbs will blit to.
* @content_fb_type: content_fb type
* @display_width: display width
* @display_height: display height
* @defined: true if the current display unit has been initialized
* @cpp: Bytes per pixel
*/
struct vmw_screen_target_display_unit {
struct vmw_display_unit base;
struct vmw_surface *display_srf;
enum stdu_content_type content_fb_type;
s32 display_width, display_height;
/* For CPU Blit */
unsigned int cpp;
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
};
static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu);
/******************************************************************************
* Screen Target Display Unit CRTC Functions
*****************************************************************************/
/**
* vmw_stdu_crtc_destroy - cleans up the STDU
*
* @crtc: used to get a reference to the containing STDU
*/
static void vmw_stdu_crtc_destroy(struct drm_crtc *crtc)
{
vmw_stdu_destroy(vmw_crtc_to_stdu(crtc));
}
/**
* vmw_stdu_define_st - Defines a Screen Target
*
* @dev_priv: VMW DRM device
* @stdu: display unit to create a Screen Target for
* @mode: The mode to set.
* @crtc_x: X coordinate of screen target relative to framebuffer origin.
* @crtc_y: Y coordinate of screen target relative to framebuffer origin.
*
* Creates a STDU that we can used later. This function is called whenever the
* framebuffer size changes.
*
* RETURNs:
* 0 on success, error code on failure
*/
static int vmw_stdu_define_st(struct vmw_private *dev_priv,
struct vmw_screen_target_display_unit *stdu,
struct drm_display_mode *mode,
int crtc_x, int crtc_y)
{
struct {
SVGA3dCmdHeader header;
SVGA3dCmdDefineGBScreenTarget body;
} *cmd;
cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
if (unlikely(cmd == NULL))
return -ENOMEM;
cmd->header.id = SVGA_3D_CMD_DEFINE_GB_SCREENTARGET;
cmd->header.size = sizeof(cmd->body);
cmd->body.stid = stdu->base.unit;
cmd->body.width = mode->hdisplay;
cmd->body.height = mode->vdisplay;
cmd->body.flags = (0 == cmd->body.stid) ? SVGA_STFLAG_PRIMARY : 0;
cmd->body.dpi = 0;
cmd->body.xRoot = crtc_x;
cmd->body.yRoot = crtc_y;
stdu->base.set_gui_x = cmd->body.xRoot;
stdu->base.set_gui_y = cmd->body.yRoot;
vmw_cmd_commit(dev_priv, sizeof(*cmd));
stdu->display_width = mode->hdisplay;
stdu->display_height = mode->vdisplay;
Loading
Loading full blame...