Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14b1c33e authored by Deepak Rawat's avatar Deepak Rawat Committed by Thomas Hellstrom
Browse files

drm/vmwgfx: Add new ioctl for GB surface create and reference



New ioctls DRM_VMW_GB_SURFACE_CREATE_EXT and DRM_VMW_GB_SURFACE_REF_EXT
are added which support 64-bit wide svga device surface flags, quality
level and multisample pattern.

Signed-off-by: default avatarDeepak Rawat <drawat@vmware.com>
Reviewed-by: default avatarSinclair Yeh <syeh@vmware.com>
Reviewed-by: default avatarBrian Paul <brianp@vmware.com>
Reviewed-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarCharmaine Lee <charmainel@vmware.com>
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
parent 397a1117
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -137,6 +137,12 @@
#define DRM_IOCTL_VMW_CREATE_EXTENDED_CONTEXT			\
	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_CREATE_EXTENDED_CONTEXT,	\
		struct drm_vmw_context_arg)
#define DRM_IOCTL_VMW_GB_SURFACE_CREATE_EXT				\
	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GB_SURFACE_CREATE_EXT,	\
		union drm_vmw_gb_surface_create_ext_arg)
#define DRM_IOCTL_VMW_GB_SURFACE_REF_EXT				\
	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GB_SURFACE_REF_EXT,		\
		union drm_vmw_gb_surface_reference_ext_arg)

/**
 * The core DRM version of this macro doesn't account for
@@ -224,6 +230,12 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
	VMW_IOCTL_DEF(VMW_CREATE_EXTENDED_CONTEXT,
		      vmw_extended_context_define_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_GB_SURFACE_CREATE_EXT,
		      vmw_gb_surface_define_ext_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
	VMW_IOCTL_DEF(VMW_GB_SURFACE_REF_EXT,
		      vmw_gb_surface_reference_ext_ioctl,
		      DRM_AUTH | DRM_RENDER_ALLOW),
};

static const struct pci_device_id vmw_pci_id_list[] = {
+8 −0
Original line number Diff line number Diff line
@@ -1087,7 +1087,15 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
			       uint32_t multisample_count,
			       uint32_t array_size,
			       struct drm_vmw_size size,
			       SVGA3dMSPattern multisample_pattern,
			       SVGA3dMSQualityLevel quality_level,
			       struct vmw_surface **srf_out);
extern int vmw_gb_surface_define_ext_ioctl(struct drm_device *dev,
					   void *data,
					   struct drm_file *file_priv);
extern int vmw_gb_surface_reference_ext_ioctl(struct drm_device *dev,
					      void *data,
					      struct drm_file *file_priv);

/*
 * Shader management - vmwgfx_shader.c
+11 −9
Original line number Diff line number Diff line
@@ -1246,6 +1246,8 @@ static int vmw_create_bo_proxy(struct drm_device *dev,
					 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");
+2 −0
Original line number Diff line number Diff line
@@ -1188,6 +1188,8 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
				 content_srf.multisample_count,
				 0,
				 display_base_size,
				 content_srf.multisample_pattern,
				 content_srf.quality_level,
				 &vps->surf);
			if (ret != 0) {
				DRM_ERROR("Couldn't allocate STDU surface.\n");
+302 −166
Original line number Diff line number Diff line
@@ -33,6 +33,10 @@
#include "vmwgfx_binding.h"
#include "device_include/svga3d_surfacedefs.h"

#define SVGA3D_FLAGS_64(upper32, lower32) (((uint64_t)upper32 << 32) | lower32)
#define SVGA3D_FLAGS_UPPER_32(svga3d_flags) (svga3d_flags >> 32)
#define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \
	(svga3d_flags & ((uint64_t)U32_MAX))

/**
 * struct vmw_user_surface - User-space visible surface resource
@@ -81,7 +85,16 @@ static int vmw_gb_surface_unbind(struct vmw_resource *res,
				 bool readback,
				 struct ttm_validate_buffer *val_buf);
static int vmw_gb_surface_destroy(struct vmw_resource *res);

static int
vmw_gb_surface_define_internal(struct drm_device *dev,
			       struct drm_vmw_gb_surface_create_ext_req *req,
			       struct drm_vmw_gb_surface_create_rep *rep,
			       struct drm_file *file_priv);
static int
vmw_gb_surface_reference_internal(struct drm_device *dev,
				  struct drm_vmw_surface_arg *req,
				  struct drm_vmw_gb_surface_ref_ext_rep *rep,
				  struct drm_file *file_priv);

static const struct vmw_user_resource_conv user_surface_conv = {
	.object_type = VMW_RES_SURFACE,
@@ -1298,117 +1311,19 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res)
int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
				struct drm_file *file_priv)
{
	struct vmw_private *dev_priv = vmw_priv(dev);
	struct vmw_user_surface *user_srf;
	struct vmw_surface *srf;
	struct vmw_resource *res;
	struct vmw_resource *tmp;
	union drm_vmw_gb_surface_create_arg *arg =
	    (union drm_vmw_gb_surface_create_arg *)data;
	struct drm_vmw_gb_surface_create_req *req = &arg->req;
	struct drm_vmw_gb_surface_create_rep *rep = &arg->rep;
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
	int ret;
	uint32_t size;
	uint32_t backup_handle = 0;

	if (req->multisample_count != 0)
		return -EINVAL;

	if (req->mip_levels > DRM_VMW_MAX_MIP_LEVELS)
		return -EINVAL;

	if (unlikely(vmw_user_surface_size == 0))
		vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +
			128;

	size = vmw_user_surface_size + 128;

	/* Define a surface based on the parameters. */
	ret = vmw_surface_gb_priv_define(dev,
			size,
			(SVGA3dSurfaceAllFlags)req->svga3d_flags,
			req->format,
			req->drm_surface_flags & drm_vmw_surface_flag_scanout,
			req->mip_levels,
			req->multisample_count,
			req->array_size,
			req->base_size,
			&srf);
	if (unlikely(ret != 0))
		return ret;

	user_srf = container_of(srf, struct vmw_user_surface, srf);
	if (drm_is_primary_client(file_priv))
		user_srf->master = drm_master_get(file_priv->master);

	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
	if (unlikely(ret != 0))
		return ret;

	res = &user_srf->srf.res;


	if (req->buffer_handle != SVGA3D_INVALID_ID) {
		ret = vmw_user_bo_lookup(tfile, req->buffer_handle,
					 &res->backup,
					 &user_srf->backup_base);
		if (ret == 0) {
			if (res->backup->base.num_pages * PAGE_SIZE <
			    res->backup_size) {
				DRM_ERROR("Surface backup buffer is too small.\n");
				vmw_bo_unreference(&res->backup);
				ret = -EINVAL;
				goto out_unlock;
			} else {
				backup_handle = req->buffer_handle;
			}
		}
	} else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer)
		ret = vmw_user_bo_alloc(dev_priv, tfile,
					res->backup_size,
					req->drm_surface_flags &
					drm_vmw_surface_flag_shareable,
					&backup_handle,
					&res->backup,
					&user_srf->backup_base);

	if (unlikely(ret != 0)) {
		vmw_resource_unreference(&res);
		goto out_unlock;
	}

	tmp = vmw_resource_reference(res);
	ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
				    req->drm_surface_flags &
				    drm_vmw_surface_flag_shareable,
				    VMW_RES_SURFACE,
				    &vmw_user_surface_base_release, NULL);

	if (unlikely(ret != 0)) {
		vmw_resource_unreference(&tmp);
		vmw_resource_unreference(&res);
		goto out_unlock;
	}

	rep->handle      = user_srf->prime.base.hash.key;
	rep->backup_size = res->backup_size;
	if (res->backup) {
		rep->buffer_map_handle =
			drm_vma_node_offset_addr(&res->backup->base.vma_node);
		rep->buffer_size = res->backup->base.num_pages * PAGE_SIZE;
		rep->buffer_handle = backup_handle;
	} else {
		rep->buffer_map_handle = 0;
		rep->buffer_size = 0;
		rep->buffer_handle = SVGA3D_INVALID_ID;
	}
	struct drm_vmw_gb_surface_create_ext_req req_ext;

	vmw_resource_unreference(&res);
	req_ext.base = arg->req;
	req_ext.version = drm_vmw_gb_surface_v1;
	req_ext.svga3d_flags_upper_32_bits = 0;
	req_ext.multisample_pattern = SVGA3D_MS_PATTERN_NONE;
	req_ext.quality_level = SVGA3D_MS_QUALITY_NONE;
	req_ext.must_be_zero = 0;

out_unlock:
	ttm_read_unlock(&dev_priv->reservation_sem);
	return ret;
	return vmw_gb_surface_define_internal(dev, &req_ext, rep, file_priv);
}

/**
@@ -1422,60 +1337,20 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data,
				   struct drm_file *file_priv)
{
	struct vmw_private *dev_priv = vmw_priv(dev);
	union drm_vmw_gb_surface_reference_arg *arg =
	    (union drm_vmw_gb_surface_reference_arg *)data;
	struct drm_vmw_surface_arg *req = &arg->req;
	struct drm_vmw_gb_surface_ref_rep *rep = &arg->rep;
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
	struct vmw_surface *srf;
	struct vmw_user_surface *user_srf;
	struct ttm_base_object *base;
	uint32_t backup_handle;
	int ret = -EINVAL;
	struct drm_vmw_gb_surface_ref_ext_rep rep_ext;
	int ret;

	ret = vmw_gb_surface_reference_internal(dev, req, &rep_ext, file_priv);

	ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
					   req->handle_type, &base);
	if (unlikely(ret != 0))
		return ret;

	user_srf = container_of(base, struct vmw_user_surface, prime.base);
	srf = &user_srf->srf;
	if (!srf->res.backup) {
		DRM_ERROR("Shared GB surface is missing a backup buffer.\n");
		goto out_bad_resource;
	}

	mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */
	ret = vmw_user_bo_reference(tfile, srf->res.backup, &backup_handle);
	mutex_unlock(&dev_priv->cmdbuf_mutex);

	if (unlikely(ret != 0)) {
		DRM_ERROR("Could not add a reference to a GB surface "
			  "backup buffer.\n");
		(void) ttm_ref_object_base_unref(tfile, base->hash.key,
						 TTM_REF_USAGE);
		goto out_bad_resource;
	}

	rep->creq.svga3d_flags = (uint32_t)srf->flags;
	rep->creq.format = srf->format;
	rep->creq.mip_levels = srf->mip_levels[0];
	rep->creq.drm_surface_flags = 0;
	rep->creq.multisample_count = srf->multisample_count;
	rep->creq.autogen_filter = srf->autogen_filter;
	rep->creq.array_size = srf->array_size;
	rep->creq.buffer_handle = backup_handle;
	rep->creq.base_size = srf->base_size;
	rep->crep.handle = user_srf->prime.base.hash.key;
	rep->crep.backup_size = srf->res.backup_size;
	rep->crep.buffer_handle = backup_handle;
	rep->crep.buffer_map_handle =
		drm_vma_node_offset_addr(&srf->res.backup->base.vma_node);
	rep->crep.buffer_size = srf->res.backup->base.num_pages * PAGE_SIZE;

out_bad_resource:
	ttm_base_object_unref(&base);
	rep->creq = rep_ext.creq.base;
	rep->crep = rep_ext.crep;

	return ret;
}
@@ -1493,6 +1368,8 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data,
 * @multisample_count:
 * @array_size: Surface array size.
 * @size: width, heigh, depth of the surface requested
 * @multisample_pattern: Multisampling pattern when msaa is supported
 * @quality_level: Precision settings
 * @user_srf_out: allocated user_srf.  Set to NULL on failure.
 *
 * GB surfaces allocated by this function will not have a user mode handle, and
@@ -1509,6 +1386,8 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
			       uint32_t multisample_count,
			       uint32_t array_size,
			       struct drm_vmw_size size,
			       SVGA3dMSPattern multisample_pattern,
			       SVGA3dMSQualityLevel quality_level,
			       struct vmw_surface **srf_out)
{
	struct vmw_private *dev_priv = vmw_priv(dev);
@@ -1519,7 +1398,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
	};
	struct vmw_surface *srf;
	int ret;
	u32 num_layers;
	u32 num_layers = 1;

	*srf_out = NULL;

@@ -1594,15 +1473,13 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
	srf->autogen_filter    = SVGA3D_TEX_FILTER_NONE;
	srf->array_size        = array_size;
	srf->multisample_count = multisample_count;
	srf->multisample_pattern = SVGA3D_MS_PATTERN_NONE;
	srf->quality_level = SVGA3D_MS_QUALITY_NONE;
	srf->multisample_pattern = multisample_pattern;
	srf->quality_level = quality_level;

	if (array_size)
		num_layers = array_size;
	else if (svga3d_flags & SVGA3D_SURFACE_CUBEMAP)
		num_layers = SVGA3D_MAX_SURFACE_FACES;
	else
		num_layers = 1;

	srf->res.backup_size   =
		svga3dsurface_get_serialized_size(srf->format,
@@ -1633,3 +1510,262 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
	ttm_read_unlock(&dev_priv->reservation_sem);
	return ret;
}

/**
 * vmw_gb_surface_define_ext_ioctl - Ioctl function implementing
 * the user surface define functionality.
 *
 * @dev: Pointer to a struct drm_device.
 * @data: Pointer to data copied from / to user-space.
 * @file_priv: Pointer to a drm file private structure.
 */
int vmw_gb_surface_define_ext_ioctl(struct drm_device *dev, void *data,
				struct drm_file *file_priv)
{
	union drm_vmw_gb_surface_create_ext_arg *arg =
	    (union drm_vmw_gb_surface_create_ext_arg *)data;
	struct drm_vmw_gb_surface_create_ext_req *req = &arg->req;
	struct drm_vmw_gb_surface_create_rep *rep = &arg->rep;

	return vmw_gb_surface_define_internal(dev, req, rep, file_priv);
}

/**
 * vmw_gb_surface_reference_ext_ioctl - Ioctl function implementing
 * the user surface reference functionality.
 *
 * @dev: Pointer to a struct drm_device.
 * @data: Pointer to data copied from / to user-space.
 * @file_priv: Pointer to a drm file private structure.
 */
int vmw_gb_surface_reference_ext_ioctl(struct drm_device *dev, void *data,
				   struct drm_file *file_priv)
{
	union drm_vmw_gb_surface_reference_ext_arg *arg =
	    (union drm_vmw_gb_surface_reference_ext_arg *)data;
	struct drm_vmw_surface_arg *req = &arg->req;
	struct drm_vmw_gb_surface_ref_ext_rep *rep = &arg->rep;

	return vmw_gb_surface_reference_internal(dev, req, rep, file_priv);
}

/**
 * vmw_gb_surface_define_internal - Ioctl function implementing
 * the user surface define functionality.
 *
 * @dev: Pointer to a struct drm_device.
 * @req: Request argument from user-space.
 * @rep: Response argument to user-space.
 * @file_priv: Pointer to a drm file private structure.
 */
static int
vmw_gb_surface_define_internal(struct drm_device *dev,
			       struct drm_vmw_gb_surface_create_ext_req *req,
			       struct drm_vmw_gb_surface_create_rep *rep,
			       struct drm_file *file_priv)
{
	struct vmw_private *dev_priv = vmw_priv(dev);
	struct vmw_user_surface *user_srf;
	struct vmw_surface *srf;
	struct vmw_resource *res;
	struct vmw_resource *tmp;
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
	int ret;
	uint32_t size;
	uint32_t backup_handle = 0;
	SVGA3dSurfaceAllFlags svga3d_flags_64 =
		SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits,
				req->base.svga3d_flags);

	if (!dev_priv->has_sm4_1) {
		/*
		 * If SM4_1 is not support then cannot send 64-bit flag to
		 * device.
		 */
		if (req->svga3d_flags_upper_32_bits != 0)
			return -EINVAL;

		if (req->base.multisample_count != 0)
			return -EINVAL;

		if (req->multisample_pattern != SVGA3D_MS_PATTERN_NONE)
			return -EINVAL;

		if (req->quality_level != SVGA3D_MS_QUALITY_NONE)
			return -EINVAL;
	}

	if (req->base.mip_levels > DRM_VMW_MAX_MIP_LEVELS)
		return -EINVAL;

	if (unlikely(vmw_user_surface_size == 0))
		vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +
			128;

	size = vmw_user_surface_size + 128;

	/* Define a surface based on the parameters. */
	ret = vmw_surface_gb_priv_define(dev,
					 size,
					 svga3d_flags_64,
					 req->base.format,
					 req->base.drm_surface_flags &
					 drm_vmw_surface_flag_scanout,
					 req->base.mip_levels,
					 req->base.multisample_count,
					 req->base.array_size,
					 req->base.base_size,
					 req->multisample_pattern,
					 req->quality_level,
					 &srf);
	if (unlikely(ret != 0))
		return ret;

	user_srf = container_of(srf, struct vmw_user_surface, srf);
	if (drm_is_primary_client(file_priv))
		user_srf->master = drm_master_get(file_priv->master);

	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
	if (unlikely(ret != 0))
		return ret;

	res = &user_srf->srf.res;

	if (req->base.buffer_handle != SVGA3D_INVALID_ID) {
		ret = vmw_user_bo_lookup(tfile, req->base.buffer_handle,
					 &res->backup,
					 &user_srf->backup_base);
		if (ret == 0) {
			if (res->backup->base.num_pages * PAGE_SIZE <
			    res->backup_size) {
				DRM_ERROR("Surface backup buffer too small.\n");
				vmw_bo_unreference(&res->backup);
				ret = -EINVAL;
				goto out_unlock;
			} else {
				backup_handle = req->base.buffer_handle;
			}
		}
	} else if (req->base.drm_surface_flags &
		   drm_vmw_surface_flag_create_buffer)
		ret = vmw_user_bo_alloc(dev_priv, tfile,
					res->backup_size,
					req->base.drm_surface_flags &
					drm_vmw_surface_flag_shareable,
					&backup_handle,
					&res->backup,
					&user_srf->backup_base);

	if (unlikely(ret != 0)) {
		vmw_resource_unreference(&res);
		goto out_unlock;
	}

	tmp = vmw_resource_reference(res);
	ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
				    req->base.drm_surface_flags &
				    drm_vmw_surface_flag_shareable,
				    VMW_RES_SURFACE,
				    &vmw_user_surface_base_release, NULL);

	if (unlikely(ret != 0)) {
		vmw_resource_unreference(&tmp);
		vmw_resource_unreference(&res);
		goto out_unlock;
	}

	rep->handle      = user_srf->prime.base.hash.key;
	rep->backup_size = res->backup_size;
	if (res->backup) {
		rep->buffer_map_handle =
			drm_vma_node_offset_addr(&res->backup->base.vma_node);
		rep->buffer_size = res->backup->base.num_pages * PAGE_SIZE;
		rep->buffer_handle = backup_handle;
	} else {
		rep->buffer_map_handle = 0;
		rep->buffer_size = 0;
		rep->buffer_handle = SVGA3D_INVALID_ID;
	}

	vmw_resource_unreference(&res);

out_unlock:
	ttm_read_unlock(&dev_priv->reservation_sem);
	return ret;
}

/**
 * vmw_gb_surface_reference_internal - Ioctl function implementing
 * the user surface reference functionality.
 *
 * @dev: Pointer to a struct drm_device.
 * @req: Pointer to user-space request surface arg.
 * @rep: Pointer to response to user-space.
 * @file_priv: Pointer to a drm file private structure.
 */
static int
vmw_gb_surface_reference_internal(struct drm_device *dev,
				  struct drm_vmw_surface_arg *req,
				  struct drm_vmw_gb_surface_ref_ext_rep *rep,
				  struct drm_file *file_priv)
{
	struct vmw_private *dev_priv = vmw_priv(dev);
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
	struct vmw_surface *srf;
	struct vmw_user_surface *user_srf;
	struct ttm_base_object *base;
	uint32_t backup_handle;
	int ret = -EINVAL;

	ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
					   req->handle_type, &base);
	if (unlikely(ret != 0))
		return ret;

	user_srf = container_of(base, struct vmw_user_surface, prime.base);
	srf = &user_srf->srf;
	if (!srf->res.backup) {
		DRM_ERROR("Shared GB surface is missing a backup buffer.\n");
		goto out_bad_resource;
	}

	mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */
	ret = vmw_user_bo_reference(tfile, srf->res.backup, &backup_handle);
	mutex_unlock(&dev_priv->cmdbuf_mutex);

	if (unlikely(ret != 0)) {
		DRM_ERROR("Could not add a reference to a GB surface "
			  "backup buffer.\n");
		(void) ttm_ref_object_base_unref(tfile, base->hash.key,
						 TTM_REF_USAGE);
		goto out_bad_resource;
	}

	rep->creq.base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(srf->flags);
	rep->creq.base.format = srf->format;
	rep->creq.base.mip_levels = srf->mip_levels[0];
	rep->creq.base.drm_surface_flags = 0;
	rep->creq.base.multisample_count = srf->multisample_count;
	rep->creq.base.autogen_filter = srf->autogen_filter;
	rep->creq.base.array_size = srf->array_size;
	rep->creq.base.buffer_handle = backup_handle;
	rep->creq.base.base_size = srf->base_size;
	rep->crep.handle = user_srf->prime.base.hash.key;
	rep->crep.backup_size = srf->res.backup_size;
	rep->crep.buffer_handle = backup_handle;
	rep->crep.buffer_map_handle =
		drm_vma_node_offset_addr(&srf->res.backup->base.vma_node);
	rep->crep.buffer_size = srf->res.backup->base.num_pages * PAGE_SIZE;

	rep->creq.version = drm_vmw_gb_surface_v1;
	rep->creq.svga3d_flags_upper_32_bits =
		SVGA3D_FLAGS_UPPER_32(srf->flags);
	rep->creq.multisample_pattern = srf->multisample_pattern;
	rep->creq.quality_level = srf->quality_level;
	rep->creq.must_be_zero = 0;

out_bad_resource:
	ttm_base_object_unref(&base);

	return ret;
}
Loading