diff options
author | Jakob Bornecrantz <jakob@vmware.com> | 2009-11-24 17:54:10 +0100 |
---|---|---|
committer | Jakob Bornecrantz <jakob@vmware.com> | 2009-12-04 16:11:55 +0100 |
commit | 8c0571a73399c372644c8d92a136a474f3e05d48 (patch) | |
tree | 1067f940118c64267f4a0bfe49b04e9f4971e94d /libkms/vmwgfx.c | |
parent | 28eae30689610faa0fe043ab869587e7699e82bf (diff) | |
download | libdrm-8c0571a73399c372644c8d92a136a474f3e05d48.tar.gz libdrm-8c0571a73399c372644c8d92a136a474f3e05d48.tar.bz2 libdrm-8c0571a73399c372644c8d92a136a474f3e05d48.zip |
libkms: Add libkms
Diffstat (limited to 'libkms/vmwgfx.c')
-rw-r--r-- | libkms/vmwgfx.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/libkms/vmwgfx.c b/libkms/vmwgfx.c new file mode 100644 index 00000000..5030b7e3 --- /dev/null +++ b/libkms/vmwgfx.c @@ -0,0 +1,226 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + + +#define HAVE_STDINT_H +#define _FILE_OFFSET_BITS 64 + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include "internal.h" + +#include <sys/mman.h> +#include "xf86drm.h" +#include "vmwgfx_drm.h" + +struct vmwgfx_bo +{ + struct kms_bo base; + uint64_t map_handle; + unsigned map_count; +}; + +static int +vmwgfx_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) +{ + switch (key) { + case KMS_MAX_SCANOUT_WIDTH: + *out = 2048; + break; + case KMS_MAX_SCANOUT_HEIGHT: + *out = 2048; + break; + case KMS_MIN_SCANOUT_WIDTH: + *out = 1; + break; + case KMS_MIN_SCANOUT_HEIGHT: + *out = 1; + break; + case KMS_MAX_CURSOR_WIDTH: + *out = 64; + break; + case KMS_MAX_CURSOR_HEIGHT: + *out = 64; + break; + case KMS_MIN_CURSOR_WIDTH: + *out = 64; + break; + case KMS_MIN_CURSOR_HEIGHT: + *out = 64; + break; + default: + return -EINVAL; + } + return 0; +} + +static int +vmwgfx_destroy(struct kms_driver *kms) +{ + free(kms); + return 0; +} + +static int +vmwgfx_bo_create(struct kms_driver *kms, + const unsigned width, const unsigned height, + const enum kms_bo_type type, const unsigned *attr, + struct kms_bo **out) +{ + struct vmwgfx_bo *bo; + int i, ret; + + for (i = 0; attr[i]; i += 2) { + switch (attr[i]) { + case KMS_WIDTH: + case KMS_HEIGHT: + case KMS_BO_TYPE: + break; + default: + return EINVAL; + } + } + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return -EINVAL; + + { + union drm_vmw_alloc_dmabuf_arg arg; + struct drm_vmw_alloc_dmabuf_req *req = &arg.req; + struct drm_vmw_dmabuf_rep *rep = &arg.rep; + + memset(&arg, 0, sizeof(arg)); + req->size = width * height * 4; + bo->base.size = req->size; + bo->base.pitch = width * 4; + bo->base.kms = kms; + + do { + ret = drmCommandWriteRead(bo->base.kms->fd, + DRM_VMW_ALLOC_DMABUF, + &arg, sizeof(arg)); + } while (ret == -ERESTART); + + if (ret) + goto err_free; + + bo->base.handle = rep->handle; + bo->map_handle = rep->map_handle; + bo->base.handle = rep->cur_gmr_id; + bo->base.offset = rep->cur_gmr_offset; + } + + *out = &bo->base; + + return 0; + +err_free: + free(bo); + return ret; +} + +static int +vmwgfx_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) +{ + switch (key) { + default: + return -EINVAL; + } +} + +static int +vmwgfx_bo_map(struct kms_bo *_bo, void **out) +{ + struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo; + void *map; + + if (!bo->map_count) { + map = mmap(NULL, bo->base.size, PROT_READ | PROT_WRITE, + MAP_SHARED, bo->base.kms->fd, bo->map_handle); + + if (!map) + return -ENOMEM; + + bo->base.ptr = map; + } + + bo->map_count++; + *out = bo->base.ptr; + + return 0; +} + +static int +vmwgfx_bo_unmap(struct kms_bo *_bo) +{ + struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo; + bo->map_count--; + return 0; +} + +static int +vmwgfx_bo_destroy(struct kms_bo *_bo) +{ + struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo; + struct drm_vmw_unref_dmabuf_arg arg; + + if (bo->map_count) { + munmap(bo->base.ptr, bo->base.size); + bo->base.ptr = NULL; + } + + memset(&arg, 0, sizeof(arg)); + arg.handle = bo->base.handle; + drmCommandWrite(bo->base.kms->fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg)); + + free(bo); + return 0; +} + +int +vmwgfx_create(int fd, struct kms_driver **out) +{ + struct kms_driver *kms; + + kms = calloc(1, sizeof(*kms)); + if (!kms) + return -ENOMEM; + + kms->fd = fd; + + kms->bo_create = vmwgfx_bo_create; + kms->bo_map = vmwgfx_bo_map; + kms->bo_unmap = vmwgfx_bo_unmap; + kms->bo_get_prop = vmwgfx_bo_get_prop; + kms->bo_destroy = vmwgfx_bo_destroy; + kms->get_prop = vmwgfx_get_prop; + kms->destroy = vmwgfx_destroy; + *out = kms; + return 0; +} |