OSDN Git Service

Merge remote-tracking branch 'mesa/12.0' into marshmallow-x86
[android-x86/external-mesa.git] / src / gallium / winsys / svga / drm / vmw_screen.c
1 /**********************************************************
2  * Copyright 2009-2015 VMware, Inc.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  **********************************************************/
25
26
27 #include "vmw_screen.h"
28 #include "vmw_fence.h"
29 #include "vmw_context.h"
30
31 #include "util/u_memory.h"
32 #include "pipe/p_compiler.h"
33 #include "util/u_hash_table.h"
34 #ifdef MAJOR_IN_MKDEV
35 #include <sys/mkdev.h>
36 #endif
37 #ifdef MAJOR_IN_SYSMACROS
38 #include <sys/sysmacros.h>
39 #endif
40 #include <sys/stat.h>
41 #include <unistd.h>
42
43 static struct util_hash_table *dev_hash = NULL;
44
45 static int vmw_dev_compare(void *key1, void *key2)
46 {
47    return (major(*(dev_t *)key1) == major(*(dev_t *)key2) &&
48            minor(*(dev_t *)key1) == minor(*(dev_t *)key2)) ? 0 : 1;
49 }
50
51 static unsigned vmw_dev_hash(void *key)
52 {
53    return (major(*(dev_t *) key) << 16) | minor(*(dev_t *) key);
54 }
55
56 /* Called from vmw_drm_create_screen(), creates and initializes the
57  * vmw_winsys_screen structure, which is the main entity in this
58  * module.
59  * First, check whether a vmw_winsys_screen object already exists for
60  * this device, and in that case return that one, making sure that we
61  * have our own file descriptor open to DRM.
62  */
63
64 struct vmw_winsys_screen *
65 vmw_winsys_create( int fd )
66 {
67    struct vmw_winsys_screen *vws;
68    struct stat stat_buf;
69
70    if (dev_hash == NULL) {
71       dev_hash = util_hash_table_create(vmw_dev_hash, vmw_dev_compare);
72       if (dev_hash == NULL)
73          return NULL;
74    }
75
76    if (fstat(fd, &stat_buf))
77       return NULL;
78
79    vws = util_hash_table_get(dev_hash, &stat_buf.st_rdev);
80    if (vws) {
81       vws->open_count++;
82       return vws;
83    }
84
85    vws = CALLOC_STRUCT(vmw_winsys_screen);
86    if (!vws)
87       goto out_no_vws;
88
89    vws->device = stat_buf.st_rdev;
90    vws->open_count = 1;
91    vws->ioctl.drm_fd = dup(fd);
92    vws->base.have_gb_dma = TRUE;
93    vws->base.need_to_rebind_resources = FALSE;
94
95    if (!vmw_ioctl_init(vws))
96       goto out_no_ioctl;
97
98    vws->fence_ops = vmw_fence_ops_create(vws);
99    if (!vws->fence_ops)
100       goto out_no_fence_ops;
101
102    if(!vmw_pools_init(vws))
103       goto out_no_pools;
104
105    if (!vmw_winsys_screen_init_svga(vws))
106       goto out_no_svga;
107
108    if (util_hash_table_set(dev_hash, &vws->device, vws) != PIPE_OK)
109       goto out_no_hash_insert;
110
111    return vws;
112 out_no_hash_insert:
113 out_no_svga:
114    vmw_pools_cleanup(vws);
115 out_no_pools:
116    vws->fence_ops->destroy(vws->fence_ops);
117 out_no_fence_ops:
118    vmw_ioctl_cleanup(vws);
119 out_no_ioctl:
120    close(vws->ioctl.drm_fd);
121    FREE(vws);
122 out_no_vws:
123    return NULL;
124 }
125
126 void
127 vmw_winsys_destroy(struct vmw_winsys_screen *vws)
128 {
129    if (--vws->open_count == 0) {
130       util_hash_table_remove(dev_hash, &vws->device);
131       vmw_pools_cleanup(vws);
132       vws->fence_ops->destroy(vws->fence_ops);
133       vmw_ioctl_cleanup(vws);
134       close(vws->ioctl.drm_fd);
135       FREE(vws);
136    }
137 }