2 * Copyright (c) 2015 Etnaviv Project
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 * Christian Gmeiner <christian.gmeiner@gmail.com>
29 #include "util/u_hash_table.h"
30 #include "util/u_memory.h"
32 #include "etnaviv/etnaviv_screen.h"
33 #include "etnaviv/hw/common.xml.h"
34 #include "etnaviv_drm_public.h"
38 static struct pipe_screen
*
39 screen_create(struct renderonly
*ro
)
41 struct etna_device
*dev
;
46 dev
= etna_device_new_dup(ro
->gpu_fd
);
48 fprintf(stderr
, "Error creating device\n");
53 gpu
= etna_gpu_new(dev
, i
);
55 fprintf(stderr
, "Error creating gpu\n");
59 /* Look for a 3D capable GPU */
60 int ret
= etna_gpu_get_param(gpu
, ETNA_GPU_FEATURES_0
, &val
);
61 if (ret
== 0 && (val
& chipFeatures_PIPE_3D
))
67 return etna_screen_create(dev
, gpu
, ro
);
70 static struct util_hash_table
*etna_tab
= NULL
;
72 static mtx_t etna_screen_mutex
= _MTX_INITIALIZER_NP
;
75 etna_drm_screen_destroy(struct pipe_screen
*pscreen
)
77 struct etna_screen
*screen
= etna_screen(pscreen
);
80 mtx_lock(&etna_screen_mutex
);
81 destroy
= --screen
->refcnt
== 0;
83 int fd
= etna_device_fd(screen
->dev
);
84 util_hash_table_remove(etna_tab
, intptr_to_pointer(fd
));
86 mtx_unlock(&etna_screen_mutex
);
89 pscreen
->destroy
= screen
->winsys_priv
;
90 pscreen
->destroy(pscreen
);
94 static unsigned hash_fd(void *key
)
96 int fd
= pointer_to_intptr(key
);
101 return stat
.st_dev
^ stat
.st_ino
^ stat
.st_rdev
;
104 static int compare_fd(void *key1
, void *key2
)
106 int fd1
= pointer_to_intptr(key1
);
107 int fd2
= pointer_to_intptr(key2
);
108 struct stat stat1
, stat2
;
113 return stat1
.st_dev
!= stat2
.st_dev
||
114 stat1
.st_ino
!= stat2
.st_ino
||
115 stat1
.st_rdev
!= stat2
.st_rdev
;
119 etna_drm_screen_create_renderonly(struct renderonly
*ro
)
121 struct pipe_screen
*pscreen
= NULL
;
123 mtx_lock(&etna_screen_mutex
);
125 etna_tab
= util_hash_table_create(hash_fd
, compare_fd
);
130 pscreen
= util_hash_table_get(etna_tab
, intptr_to_pointer(ro
->gpu_fd
));
132 etna_screen(pscreen
)->refcnt
++;
134 pscreen
= screen_create(ro
);
136 int fd
= etna_device_fd(etna_screen(pscreen
)->dev
);
137 util_hash_table_set(etna_tab
, intptr_to_pointer(fd
), pscreen
);
139 /* Bit of a hack, to avoid circular linkage dependency,
140 * ie. pipe driver having to call in to winsys, we
141 * override the pipe drivers screen->destroy() */
142 etna_screen(pscreen
)->winsys_priv
= pscreen
->destroy
;
143 pscreen
->destroy
= etna_drm_screen_destroy
;
148 mtx_unlock(&etna_screen_mutex
);
153 etna_drm_screen_create(int fd
)
155 struct renderonly ro
= {
156 .create_for_resource
= renderonly_create_gpu_import_for_resource
,
161 return etna_drm_screen_create_renderonly(&ro
);