aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Bornecrantz2009-11-24 10:54:10 -0600
committerJakob Bornecrantz2009-12-04 09:11:55 -0600
commit8c0571a73399c372644c8d92a136a474f3e05d48 (patch)
tree1067f940118c64267f4a0bfe49b04e9f4971e94d /libkms/vmwgfx.c
parent28eae30689610faa0fe043ab869587e7699e82bf (diff)
downloadexternal-libdrm-8c0571a73399c372644c8d92a136a474f3e05d48.tar.gz
external-libdrm-8c0571a73399c372644c8d92a136a474f3e05d48.tar.xz
external-libdrm-8c0571a73399c372644c8d92a136a474f3e05d48.zip
libkms: Add libkms
Diffstat (limited to 'libkms/vmwgfx.c')
-rw-r--r--libkms/vmwgfx.c226
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 @@
1/**************************************************************************
2 *
3 * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#define HAVE_STDINT_H
30#define _FILE_OFFSET_BITS 64
31
32#include <errno.h>
33#include <stdlib.h>
34#include <string.h>
35#include "internal.h"
36
37#include <sys/mman.h>
38#include "xf86drm.h"
39#include "vmwgfx_drm.h"
40
41struct vmwgfx_bo
42{
43 struct kms_bo base;
44 uint64_t map_handle;
45 unsigned map_count;
46};
47
48static int
49vmwgfx_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
50{
51 switch (key) {
52 case KMS_MAX_SCANOUT_WIDTH:
53 *out = 2048;
54 break;
55 case KMS_MAX_SCANOUT_HEIGHT:
56 *out = 2048;
57 break;
58 case KMS_MIN_SCANOUT_WIDTH:
59 *out = 1;
60 break;
61 case KMS_MIN_SCANOUT_HEIGHT:
62 *out = 1;
63 break;
64 case KMS_MAX_CURSOR_WIDTH:
65 *out = 64;
66 break;
67 case KMS_MAX_CURSOR_HEIGHT:
68 *out = 64;
69 break;
70 case KMS_MIN_CURSOR_WIDTH:
71 *out = 64;
72 break;
73 case KMS_MIN_CURSOR_HEIGHT:
74 *out = 64;
75 break;
76 default:
77 return -EINVAL;
78 }
79 return 0;
80}
81
82static int
83vmwgfx_destroy(struct kms_driver *kms)
84{
85 free(kms);
86 return 0;
87}
88
89static int
90vmwgfx_bo_create(struct kms_driver *kms,
91 const unsigned width, const unsigned height,
92 const enum kms_bo_type type, const unsigned *attr,
93 struct kms_bo **out)
94{
95 struct vmwgfx_bo *bo;
96 int i, ret;
97
98 for (i = 0; attr[i]; i += 2) {
99 switch (attr[i]) {
100 case KMS_WIDTH:
101 case KMS_HEIGHT:
102 case KMS_BO_TYPE:
103 break;
104 default:
105 return EINVAL;
106 }
107 }
108
109 bo = calloc(1, sizeof(*bo));
110 if (!bo)
111 return -EINVAL;
112
113 {
114 union drm_vmw_alloc_dmabuf_arg arg;
115 struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
116 struct drm_vmw_dmabuf_rep *rep = &arg.rep;
117
118 memset(&arg, 0, sizeof(arg));
119 req->size = width * height * 4;
120 bo->base.size = req->size;
121 bo->base.pitch = width * 4;
122 bo->base.kms = kms;
123
124 do {
125 ret = drmCommandWriteRead(bo->base.kms->fd,
126 DRM_VMW_ALLOC_DMABUF,
127 &arg, sizeof(arg));
128 } while (ret == -ERESTART);
129
130 if (ret)
131 goto err_free;
132
133 bo->base.handle = rep->handle;
134 bo->map_handle = rep->map_handle;
135 bo->base.handle = rep->cur_gmr_id;
136 bo->base.offset = rep->cur_gmr_offset;
137 }
138
139 *out = &bo->base;
140
141 return 0;
142
143err_free:
144 free(bo);
145 return ret;
146}
147
148static int
149vmwgfx_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
150{
151 switch (key) {
152 default:
153 return -EINVAL;
154 }
155}
156
157static int
158vmwgfx_bo_map(struct kms_bo *_bo, void **out)
159{
160 struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo;
161 void *map;
162
163 if (!bo->map_count) {
164 map = mmap(NULL, bo->base.size, PROT_READ | PROT_WRITE,
165 MAP_SHARED, bo->base.kms->fd, bo->map_handle);
166
167 if (!map)
168 return -ENOMEM;
169
170 bo->base.ptr = map;
171 }
172
173 bo->map_count++;
174 *out = bo->base.ptr;
175
176 return 0;
177}
178
179static int
180vmwgfx_bo_unmap(struct kms_bo *_bo)
181{
182 struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo;
183 bo->map_count--;
184 return 0;
185}
186
187static int
188vmwgfx_bo_destroy(struct kms_bo *_bo)
189{
190 struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo;
191 struct drm_vmw_unref_dmabuf_arg arg;
192
193 if (bo->map_count) {
194 munmap(bo->base.ptr, bo->base.size);
195 bo->base.ptr = NULL;
196 }
197
198 memset(&arg, 0, sizeof(arg));
199 arg.handle = bo->base.handle;
200 drmCommandWrite(bo->base.kms->fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg));
201
202 free(bo);
203 return 0;
204}
205
206int
207vmwgfx_create(int fd, struct kms_driver **out)
208{
209 struct kms_driver *kms;
210
211 kms = calloc(1, sizeof(*kms));
212 if (!kms)
213 return -ENOMEM;
214
215 kms->fd = fd;
216
217 kms->bo_create = vmwgfx_bo_create;
218 kms->bo_map = vmwgfx_bo_map;
219 kms->bo_unmap = vmwgfx_bo_unmap;
220 kms->bo_get_prop = vmwgfx_bo_get_prop;
221 kms->bo_destroy = vmwgfx_bo_destroy;
222 kms->get_prop = vmwgfx_get_prop;
223 kms->destroy = vmwgfx_destroy;
224 *out = kms;
225 return 0;
226}