Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
0002 /**************************************************************************
0003  *
0004  * Copyright 2021 VMware, Inc., Palo Alto, CA., USA
0005  *
0006  * Permission is hereby granted, free of charge, to any person obtaining a
0007  * copy of this software and associated documentation files (the
0008  * "Software"), to deal in the Software without restriction, including
0009  * without limitation the rights to use, copy, modify, merge, publish,
0010  * distribute, sub license, and/or sell copies of the Software, and to
0011  * permit persons to whom the Software is furnished to do so, subject to
0012  * the following conditions:
0013  *
0014  * The above copyright notice and this permission notice (including the
0015  * next paragraph) shall be included in all copies or substantial portions
0016  * of the Software.
0017  *
0018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0020  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
0021  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
0022  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0023  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0024  * USE OR OTHER DEALINGS IN THE SOFTWARE.
0025  *
0026  **************************************************************************/
0027 
0028 #include "vmwgfx_devcaps.h"
0029 
0030 #include "vmwgfx_drv.h"
0031 
0032 
0033 struct svga_3d_compat_cap {
0034     SVGA3dFifoCapsRecordHeader header;
0035     SVGA3dFifoCapPair pairs[SVGA3D_DEVCAP_MAX];
0036 };
0037 
0038 
0039 static u32 vmw_mask_legacy_multisample(unsigned int cap, u32 fmt_value)
0040 {
0041     /*
0042      * A version of user-space exists which use MULTISAMPLE_MASKABLESAMPLES
0043      * to check the sample count supported by virtual device. Since there
0044      * never was support for multisample count for backing MOB return 0.
0045      *
0046      * MULTISAMPLE_MASKABLESAMPLES devcap is marked as deprecated by virtual
0047      * device.
0048      */
0049     if (cap == SVGA3D_DEVCAP_DEAD5)
0050         return 0;
0051 
0052     return fmt_value;
0053 }
0054 
0055 static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce,
0056                    size_t size)
0057 {
0058     struct svga_3d_compat_cap *compat_cap =
0059         (struct svga_3d_compat_cap *) bounce;
0060     unsigned int i;
0061     size_t pair_offset = offsetof(struct svga_3d_compat_cap, pairs);
0062     unsigned int max_size;
0063 
0064     if (size < pair_offset)
0065         return -EINVAL;
0066 
0067     max_size = (size - pair_offset) / sizeof(SVGA3dFifoCapPair);
0068 
0069     if (max_size > SVGA3D_DEVCAP_MAX)
0070         max_size = SVGA3D_DEVCAP_MAX;
0071 
0072     compat_cap->header.length =
0073         (pair_offset + max_size * sizeof(SVGA3dFifoCapPair)) / sizeof(u32);
0074     compat_cap->header.type = SVGA3D_FIFO_CAPS_RECORD_DEVCAPS;
0075 
0076     for (i = 0; i < max_size; ++i) {
0077         compat_cap->pairs[i][0] = i;
0078         compat_cap->pairs[i][1] = vmw_mask_legacy_multisample
0079             (i, dev_priv->devcaps[i]);
0080     }
0081 
0082     return 0;
0083 }
0084 
0085 int vmw_devcaps_create(struct vmw_private *vmw)
0086 {
0087     bool gb_objects = !!(vmw->capabilities & SVGA_CAP_GBOBJECTS);
0088     uint32_t i;
0089 
0090     if (gb_objects) {
0091         vmw->devcaps = vzalloc(sizeof(uint32_t) * SVGA3D_DEVCAP_MAX);
0092         if (!vmw->devcaps)
0093             return -ENOMEM;
0094         for (i = 0; i < SVGA3D_DEVCAP_MAX; ++i) {
0095             vmw_write(vmw, SVGA_REG_DEV_CAP, i);
0096             vmw->devcaps[i] = vmw_read(vmw, SVGA_REG_DEV_CAP);
0097         }
0098     }
0099     return 0;
0100 }
0101 
0102 void vmw_devcaps_destroy(struct vmw_private *vmw)
0103 {
0104     vfree(vmw->devcaps);
0105     vmw->devcaps = NULL;
0106 }
0107 
0108 
0109 uint32 vmw_devcaps_size(const struct vmw_private *vmw,
0110             bool gb_aware)
0111 {
0112     bool gb_objects = !!(vmw->capabilities & SVGA_CAP_GBOBJECTS);
0113     if (gb_objects && gb_aware)
0114         return SVGA3D_DEVCAP_MAX * sizeof(uint32_t);
0115     else if (gb_objects)
0116         return  sizeof(struct svga_3d_compat_cap) +
0117                 sizeof(uint32_t);
0118     else if (vmw->fifo_mem != NULL)
0119         return (SVGA_FIFO_3D_CAPS_LAST - SVGA_FIFO_3D_CAPS + 1) *
0120                 sizeof(uint32_t);
0121     else
0122         return 0;
0123 }
0124 
0125 int vmw_devcaps_copy(struct vmw_private *vmw, bool gb_aware,
0126              void *dst, uint32_t dst_size)
0127 {
0128     int ret;
0129     bool gb_objects = !!(vmw->capabilities & SVGA_CAP_GBOBJECTS);
0130     if (gb_objects && gb_aware) {
0131         memcpy(dst, vmw->devcaps, dst_size);
0132     } else if (gb_objects) {
0133         ret = vmw_fill_compat_cap(vmw, dst, dst_size);
0134         if (unlikely(ret != 0))
0135             return ret;
0136     } else if (vmw->fifo_mem) {
0137         u32 *fifo_mem = vmw->fifo_mem;
0138         memcpy(dst, &fifo_mem[SVGA_FIFO_3D_CAPS], dst_size);
0139     } else
0140         return -EINVAL;
0141     return 0;
0142 }