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"
31 #include "util/u_pointer.h"
33 #include "etnaviv/etnaviv_screen.h"
34 #include "etnaviv/hw/common.xml.h"
35 #include "etnaviv_drm_public.h"
39 static struct pipe_screen
*
40 screen_create(struct renderonly
*ro
)
42 struct etna_device
*dev
;
47 dev
= etna_device_new_dup(ro
->gpu_fd
);
49 fprintf(stderr
, "Error creating device\n");
54 gpu
= etna_gpu_new(dev
, i
);
56 fprintf(stderr
, "Error creating gpu\n");
60 /* Look for a 3D capable GPU */
61 int ret
= etna_gpu_get_param(gpu
, ETNA_GPU_FEATURES_0
, &val
);
62 if (ret
== 0 && (val
& chipFeatures_PIPE_3D
))
68 return etna_screen_create(dev
, gpu
, ro
);
71 static struct hash_table
*etna_tab
= NULL
;
73 static mtx_t etna_screen_mutex
= _MTX_INITIALIZER_NP
;
76 etna_drm_screen_destroy(struct pipe_screen
*pscreen
)
78 struct etna_screen
*screen
= etna_screen(pscreen
);
81 mtx_lock(&etna_screen_mutex
);
82 destroy
= --screen
->refcnt
== 0;
84 int fd
= etna_device_fd(screen
->dev
);
85 _mesa_hash_table_remove_key(etna_tab
, intptr_to_pointer(fd
));
87 mtx_unlock(&etna_screen_mutex
);
90 pscreen
->destroy
= screen
->winsys_priv
;
91 pscreen
->destroy(pscreen
);
96 etna_drm_screen_create_renderonly(struct renderonly
*ro
)
98 struct pipe_screen
*pscreen
= NULL
;
100 mtx_lock(&etna_screen_mutex
);
102 etna_tab
= util_hash_table_create_fd_keys();
107 pscreen
= util_hash_table_get(etna_tab
, intptr_to_pointer(ro
->gpu_fd
));
109 etna_screen(pscreen
)->refcnt
++;
111 pscreen
= screen_create(ro
);
113 int fd
= etna_device_fd(etna_screen(pscreen
)->dev
);
114 _mesa_hash_table_insert(etna_tab
, intptr_to_pointer(fd
), pscreen
);
116 /* Bit of a hack, to avoid circular linkage dependency,
117 * ie. pipe driver having to call in to winsys, we
118 * override the pipe drivers screen->destroy() */
119 etna_screen(pscreen
)->winsys_priv
= pscreen
->destroy
;
120 pscreen
->destroy
= etna_drm_screen_destroy
;
125 mtx_unlock(&etna_screen_mutex
);
130 etna_drm_screen_create(int fd
)
132 struct renderonly ro
= {
133 .create_for_resource
= renderonly_create_gpu_import_for_resource
,
138 return etna_drm_screen_create_renderonly(&ro
);