linux/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
/**
 * vmw_create_bo_proxy - create a proxy surface for the buffer object
 *
 * @dev: DRM device
 * @mode_cmd: parameters for the new surface
 * @bo_mob: MOB backing the buffer object
 * @srf_out: newly created surface
 *
 * When the content FB is a buffer object, we create a surface as a proxy to the
 * same buffer.  This way we can do a surface copy rather than a surface DMA.
 * This is a more efficient approach
 *
 * RETURNS:
 * 0 on success, error code otherwise
 */
create a proxy surface for the buffer object
@dev: DRM device
@mode_cmd: parameters for the new surface
@bo_mob: MOB backing the buffer object
@srf_out: newly created surface

When the content FB is a buffer object, we create a surface as a proxy to the
same buffer.  This way we can do a surface copy rather than a surface DMA.
This is a more efficient approach

0 on success, error code otherwise
create a proxy surface for the buffer object @dev : DRM device @mode_cmd : parameters for the new surface @bo_mob : MOB backing the buffer object @srf_out : newly created surface When the content FB is a buffer object we create a surface as a proxy to the same buffer . This way we can do a surface copy rather than a surface DMA . This is a more efficient approach 0 on success error code otherwise
static int vmw_create_bo_proxy(struct drm_device *dev,
			       const struct drm_mode_fb_cmd2 *mode_cmd,
			       struct vmw_buffer_object *bo_mob,
			       struct vmw_surface **srf_out)
{
	uint32_t format;
	struct drm_vmw_size content_base_size = {0};
	struct vmw_resource *res;
	unsigned int bytes_pp;
	struct drm_format_name_buf format_name;
	int ret;
	switch (mode_cmd->pixel_format) {
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
		format = SVGA3D_X8R8G8B8;
		bytes_pp = 4;
		break;
	case DRM_FORMAT_RGB565:
	case DRM_FORMAT_XRGB1555:
		format = SVGA3D_R5G6B5;
		bytes_pp = 2;
		break;
	case 8:
		format = SVGA3D_P8;
		bytes_pp = 1;
		break;
	default:
		DRM_ERROR("Invalid framebuffer format %s\n",
			  drm_get_format_name(mode_cmd->pixel_format, &format_name));
		return -EINVAL;
	}
	content_base_size.width  = mode_cmd->pitches[0] / bytes_pp;
	content_base_size.height = mode_cmd->height;
	content_base_size.depth  = 1;
	ret = vmw_surface_gb_priv_define(dev,
					 0, 
					 0, 
					 format,
					 true, 
					 1, 
					 0,
					 0,
					 content_base_size,
					 SVGA3D_MS_PATTERN_NONE,
					 SVGA3D_MS_QUALITY_NONE,
					 srf_out);
	if (ret) {
		DRM_ERROR("Failed to allocate proxy content buffer\n");
		return ret;
	}
	res = &(*srf_out)->res;
	mutex_lock(&res->dev_priv->cmdbuf_mutex);
	(void) vmw_resource_reserve(res, false, true);
	vmw_bo_unreference(&res->backup);
	res->backup = vmw_bo_reference(bo_mob);
	res->backup_offset = 0;
	vmw_resource_unreserve(res, false, NULL, 0);
	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
	return 0;
}
static int vmw_create_bo_proxy ( struct drm_device * dev , const struct drm_mode_fb_cmd2 * mode_cmd , struct vmw_buffer_object * bo_mob , struct vmw_surface * * srf_out ) { uint32_t format ; struct drm_vmw_size content_base_size = { 0 } ; struct vmw_resource * res ; unsigned int bytes_pp ; struct drm_format_name_buf format_name ; int ret ; switch ( mode_cmd -> pixel_format ) { case DRM_FORMAT_ARGB8888 : case DRM_FORMAT_XRGB8888 : format = SVGA3D_X8R8G8B8 ; bytes_pp = 4 ; break ; case DRM_FORMAT_RGB565 : case DRM_FORMAT_XRGB1555 : format = SVGA3D_R5G6B5 ; bytes_pp = 2 ; break ; case 8 : format = SVGA3D_P8 ; bytes_pp = 1 ; break ; default : DRM_ERROR ( " \n " , drm_get_format_name ( mode_cmd -> pixel_format , & format_name ) ) ; return - EINVAL ; } content_base_size . width = mode_cmd -> pitches [ 0 ] / bytes_pp ; content_base_size . height = mode_cmd -> height ; content_base_size . depth = 1 ; ret = vmw_surface_gb_priv_define ( dev , 0 , 0 , format , true , 1 , 0 , 0 , content_base_size , SVGA3D_MS_PATTERN_NONE , SVGA3D_MS_QUALITY_NONE , srf_out ) ; if ( ret ) { DRM_ERROR ( " \n " ) ; return ret ; } res = & ( * srf_out ) -> res ; mutex_lock ( & res -> dev_priv -> cmdbuf_mutex ) ; ( void ) vmw_resource_reserve ( res , false , true ) ; vmw_bo_unreference ( & res -> backup ) ; res -> backup = vmw_bo_reference ( bo_mob ) ; res -> backup_offset = 0 ; vmw_resource_unreserve ( res , false , NULL , 0 ) ; mutex_unlock ( & res -> dev_priv -> cmdbuf_mutex ) ; return 0 ; }
vmw_create_bo_proxy - create a proxy surface for the buffer object
 @dev: DRM device
 @mode_cmd: parameters for the new surface
 @bo_mob: MOB backing the buffer object
 @srf_out: newly created surface
vmw_create_bo_proxy - create a proxy surface for the buffer object @dev : DRM device @mode_cmd : parameters for the new surface @bo_mob : MOB backing the buffer object @srf_out : newly created surface
/* kernel visible only */ /* flags */ /* can be a scanout buffer */ /* num of mip levels */ /* Reserve and switch the backing mob. */