1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2009 VMware, Inc. 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 "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file shared.c
27 * Shared-context state
28 */
29
30
31 #include "mtypes.h"
32 #include "hash.h"
33 #include "atifragshader.h"
34 #include "bufferobj.h"
35 #include "shared.h"
36 #include "program/program.h"
37 #include "dlist.h"
38 #include "externalobjects.h"
39 #include "samplerobj.h"
40 #include "shaderapi.h"
41 #include "shaderobj.h"
42 #include "syncobj.h"
43 #include "texobj.h"
44 #include "texturebindless.h"
45 #include "pipe/p_screen.h"
46
47 #include "util/hash_table.h"
48 #include "util/set.h"
49 #include "util/u_memory.h"
50 #include "util/u_process.h"
51
52 static void
53 free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared);
54
55 /**
56 * Allocate and initialize a shared context state structure.
57 * Initializes the display list, texture objects and vertex programs hash
58 * tables, allocates the texture objects. If it runs out of memory, frees
59 * everything already allocated before returning NULL.
60 *
61 * \return pointer to a gl_shared_state structure on success, or NULL on
62 * failure.
63 */
64 struct gl_shared_state *
_mesa_alloc_shared_state(struct gl_context * ctx,const struct st_config_options * options)65 _mesa_alloc_shared_state(struct gl_context *ctx,
66 const struct st_config_options *options)
67 {
68 struct gl_shared_state *shared;
69 GLuint i;
70
71 shared = CALLOC_STRUCT(gl_shared_state);
72 if (!shared)
73 return NULL;
74
75 simple_mtx_init(&shared->Mutex, mtx_plain);
76
77 const char *driver_name = ctx->screen->get_name(ctx->screen);
78 bool is_virgl_guest = !strcmp(driver_name, "virgl");
79 const char *process_name = util_get_process_name();
80 bool is_virgl_host = strstr(process_name, "qemu-system") == process_name ||
81 strstr(process_name, "crosvm") ||
82 strstr(process_name, "virgl_test_server");
83
84 /* Enable GL name reuse for all drivers by default except virgl, which
85 * is hopelessly broken.
86 *
87 * To disable it, set reuse_gl_names=0 in the environment.
88 */
89 if (!is_virgl_guest && !is_virgl_host)
90 shared->ReuseGLNames = options->reuse_gl_names != 0;
91
92 _mesa_InitHashTable(&shared->DisplayList, shared->ReuseGLNames);
93 _mesa_InitHashTable(&shared->TexObjects, shared->ReuseGLNames);
94 _mesa_InitHashTable(&shared->Programs, shared->ReuseGLNames);
95
96 shared->DefaultVertexProgram =
97 ctx->Driver.NewProgram(ctx, MESA_SHADER_VERTEX, 0, true);
98 shared->DefaultFragmentProgram =
99 ctx->Driver.NewProgram(ctx, MESA_SHADER_FRAGMENT, 0, true);
100
101 _mesa_InitHashTable(&shared->ATIShaders, shared->ReuseGLNames);
102 shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
103
104 _mesa_InitHashTable(&shared->ShaderObjects, shared->ReuseGLNames);
105
106 _mesa_InitHashTable(&shared->BufferObjects, shared->ReuseGLNames);
107 shared->ZombieBufferObjects = _mesa_set_create(NULL, _mesa_hash_pointer,
108 _mesa_key_pointer_equal);
109
110 /* GL_ARB_sampler_objects */
111 _mesa_InitHashTable(&shared->SamplerObjects, shared->ReuseGLNames);
112
113 /* GL_ARB_bindless_texture */
114 _mesa_init_shared_handles(shared);
115
116 /* ARB_shading_language_include */
117 _mesa_init_shader_includes(shared);
118 simple_mtx_init(&shared->ShaderIncludeMutex, mtx_plain);
119
120 /* Create default texture objects */
121 for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
122 /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
123 static const GLenum targets[] = {
124 GL_TEXTURE_2D_MULTISAMPLE,
125 GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
126 GL_TEXTURE_CUBE_MAP_ARRAY,
127 GL_TEXTURE_BUFFER,
128 GL_TEXTURE_2D_ARRAY_EXT,
129 GL_TEXTURE_1D_ARRAY_EXT,
130 GL_TEXTURE_EXTERNAL_OES,
131 GL_TEXTURE_CUBE_MAP,
132 GL_TEXTURE_3D,
133 GL_TEXTURE_RECTANGLE_NV,
134 GL_TEXTURE_2D,
135 GL_TEXTURE_1D
136 };
137 STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
138 shared->DefaultTex[i] = _mesa_new_texture_object(ctx, 0, targets[i]);
139 /* Need to explicitly set/overwrite the TargetIndex field here since
140 * the call to _mesa_tex_target_to_index() in NewTextureObject() may
141 * fail if the texture target is not supported.
142 */
143 shared->DefaultTex[i]->TargetIndex = i;
144 }
145
146 /* sanity check */
147 assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
148
149 /* Mutex and timestamp for texobj state validation */
150 simple_mtx_init(&shared->TexMutex, mtx_plain);
151 shared->TextureStateStamp = 0;
152
153 _mesa_InitHashTable(&shared->FrameBuffers, shared->ReuseGLNames);
154 _mesa_InitHashTable(&shared->RenderBuffers, shared->ReuseGLNames);
155
156 shared->SyncObjects = _mesa_set_create(NULL, _mesa_hash_pointer,
157 _mesa_key_pointer_equal);
158
159 _mesa_InitHashTable(&shared->MemoryObjects, shared->ReuseGLNames);
160 _mesa_InitHashTable(&shared->SemaphoreObjects, shared->ReuseGLNames);
161
162 shared->GLThread.NoLockDuration = ONE_SECOND_IN_NS;
163
164 return shared;
165 }
166
167
168 /**
169 * Callback for deleting a display list. Called by _mesa_DeleteHashTable().
170 */
171 static void
delete_displaylist_cb(void * data,void * userData)172 delete_displaylist_cb(void *data, void *userData)
173 {
174 struct gl_display_list *list = (struct gl_display_list *) data;
175 struct gl_context *ctx = (struct gl_context *) userData;
176 _mesa_delete_list(ctx, list);
177 }
178
179
180 /**
181 * Callback for deleting a texture object. Called by _mesa_DeleteHashTable().
182 */
183 static void
delete_texture_cb(void * data,void * userData)184 delete_texture_cb(void *data, void *userData)
185 {
186 struct gl_texture_object *texObj = (struct gl_texture_object *) data;
187 struct gl_context *ctx = (struct gl_context *) userData;
188 _mesa_delete_texture_object(ctx, texObj);
189 }
190
191
192 /**
193 * Callback for deleting a program object. Called by _mesa_DeleteHashTable().
194 */
195 static void
delete_program_cb(void * data,void * userData)196 delete_program_cb(void *data, void *userData)
197 {
198 struct gl_program *prog = (struct gl_program *) data;
199 struct gl_context *ctx = (struct gl_context *) userData;
200 if(prog != &_mesa_DummyProgram) {
201 assert(prog->RefCount == 1); /* should only be referenced by hash table */
202 prog->RefCount = 0; /* now going away */
203 _mesa_delete_program(ctx, prog);
204 }
205 }
206
207
208 /**
209 * Callback for deleting an ATI fragment shader object.
210 * Called by _mesa_DeleteHashTable().
211 */
212 static void
delete_fragshader_cb(void * data,void * userData)213 delete_fragshader_cb(void *data, void *userData)
214 {
215 struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
216 struct gl_context *ctx = (struct gl_context *) userData;
217 _mesa_delete_ati_fragment_shader(ctx, shader);
218 }
219
220
221 /**
222 * Callback for deleting a buffer object. Called by _mesa_DeleteHashTable().
223 */
224 static void
delete_bufferobj_cb(void * data,void * userData)225 delete_bufferobj_cb(void *data, void *userData)
226 {
227 struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
228 struct gl_context *ctx = (struct gl_context *) userData;
229
230 _mesa_buffer_unmap_all_mappings(ctx, bufObj);
231 _mesa_reference_buffer_object(ctx, &bufObj, NULL);
232 }
233
234
235 /**
236 * Callback for freeing shader program data. Call it before delete_shader_cb
237 * to avoid memory access error.
238 */
239 static void
free_shader_program_data_cb(void * data,void * userData)240 free_shader_program_data_cb(void *data, void *userData)
241 {
242 struct gl_context *ctx = (struct gl_context *) userData;
243 struct gl_shader_program *shProg = (struct gl_shader_program *) data;
244
245 if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
246 _mesa_free_shader_program_data(ctx, shProg);
247 }
248 }
249
250
251 /**
252 * Callback for deleting shader and shader programs objects.
253 * Called by _mesa_DeleteHashTable().
254 */
255 static void
delete_shader_cb(void * data,void * userData)256 delete_shader_cb(void *data, void *userData)
257 {
258 struct gl_context *ctx = (struct gl_context *) userData;
259 struct gl_shader *sh = (struct gl_shader *) data;
260 if (_mesa_validate_shader_target(ctx, sh->Type)) {
261 _mesa_delete_shader(ctx, sh);
262 }
263 else {
264 struct gl_shader_program *shProg = (struct gl_shader_program *) data;
265 assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
266 _mesa_delete_shader_program(ctx, shProg);
267 }
268 }
269
270
271 /**
272 * Callback for deleting a framebuffer object. Called by _mesa_DeleteHashTable()
273 */
274 static void
delete_framebuffer_cb(void * data,UNUSED void * userData)275 delete_framebuffer_cb(void *data, UNUSED void *userData)
276 {
277 struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
278 /* The fact that the framebuffer is in the hashtable means its refcount
279 * is one, but we're removing from the hashtable now. So clear refcount.
280 */
281 /*assert(fb->RefCount == 1);*/
282 fb->RefCount = 0;
283
284 /* NOTE: Delete should always be defined but there are two reports
285 * of it being NULL (bugs 13507, 14293). Work-around for now.
286 */
287 if (fb->Delete)
288 fb->Delete(fb);
289 }
290
291
292 /**
293 * Callback for deleting a renderbuffer object. Called by _mesa_DeleteHashTable()
294 */
295 static void
delete_renderbuffer_cb(void * data,void * userData)296 delete_renderbuffer_cb(void *data, void *userData)
297 {
298 struct gl_context *ctx = (struct gl_context *) userData;
299 struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
300 rb->RefCount = 0; /* see comment for FBOs above */
301 if (rb->Delete)
302 rb->Delete(ctx, rb);
303 }
304
305
306 /**
307 * Callback for deleting a sampler object. Called by _mesa_DeleteHashTable()
308 */
309 static void
delete_sampler_object_cb(void * data,void * userData)310 delete_sampler_object_cb(void *data, void *userData)
311 {
312 struct gl_context *ctx = (struct gl_context *) userData;
313 struct gl_sampler_object *sampObj = (struct gl_sampler_object *) data;
314 _mesa_reference_sampler_object(ctx, &sampObj, NULL);
315 }
316
317 /**
318 * Callback for deleting a memory object. Called by _mesa_DeleteHashTable().
319 */
320 static void
delete_memory_object_cb(void * data,void * userData)321 delete_memory_object_cb(void *data, void *userData)
322 {
323 struct gl_memory_object *memObj = (struct gl_memory_object *) data;
324 struct gl_context *ctx = (struct gl_context *) userData;
325 _mesa_delete_memory_object(ctx, memObj);
326 }
327
328 /**
329 * Callback for deleting a memory object. Called by _mesa_DeleteHashTable().
330 */
331 static void
delete_semaphore_object_cb(void * data,void * userData)332 delete_semaphore_object_cb(void *data, void *userData)
333 {
334 struct gl_semaphore_object *semObj = (struct gl_semaphore_object *) data;
335 struct gl_context *ctx = (struct gl_context *) userData;
336 _mesa_delete_semaphore_object(ctx, semObj);
337 }
338
339 /**
340 * Deallocate a shared state object and all children structures.
341 *
342 * \param ctx GL context.
343 * \param shared shared state pointer.
344 *
345 * Frees the display lists, the texture objects (calling the driver texture
346 * deletion callback to free its private data) and the vertex programs, as well
347 * as their hash tables.
348 *
349 * \sa alloc_shared_state().
350 */
351 static void
free_shared_state(struct gl_context * ctx,struct gl_shared_state * shared)352 free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
353 {
354 GLuint i;
355
356 /* Free the dummy/fallback texture objects */
357 for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
358 for (unsigned j = 0; j < ARRAY_SIZE(shared->FallbackTex[0]); j++) {
359 if (shared->FallbackTex[i][j])
360 _mesa_delete_texture_object(ctx, shared->FallbackTex[i][j]);
361 }
362 }
363
364 /*
365 * Free display lists
366 */
367 _mesa_DeinitHashTable(&shared->DisplayList, delete_displaylist_cb, ctx);
368 free(shared->small_dlist_store.ptr);
369 util_idalloc_fini(&shared->small_dlist_store.free_idx);
370
371 _mesa_HashWalk(&shared->ShaderObjects, free_shader_program_data_cb, ctx);
372 _mesa_DeinitHashTable(&shared->ShaderObjects, delete_shader_cb, ctx);
373 _mesa_DeinitHashTable(&shared->Programs, delete_program_cb, ctx);
374
375 if (shared->DefaultVertexProgram)
376 _mesa_reference_program(ctx, &shared->DefaultVertexProgram, NULL);
377
378 if (shared->DefaultFragmentProgram)
379 _mesa_reference_program(ctx, &shared->DefaultFragmentProgram, NULL);
380
381 if (shared->DefaultFragmentShader)
382 _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader);
383
384 _mesa_DeinitHashTable(&shared->ATIShaders, delete_fragshader_cb, ctx);
385 _mesa_DeinitHashTable(&shared->BufferObjects, delete_bufferobj_cb, ctx);
386
387 if (shared->ZombieBufferObjects) {
388 set_foreach(shared->ZombieBufferObjects, entry) {
389 assert(!"ZombieBufferObjects should be empty");
390 }
391 _mesa_set_destroy(shared->ZombieBufferObjects, NULL);
392 }
393
394 _mesa_DeinitHashTable(&shared->FrameBuffers, delete_framebuffer_cb, ctx);
395 _mesa_DeinitHashTable(&shared->RenderBuffers, delete_renderbuffer_cb, ctx);
396
397 if (shared->SyncObjects) {
398 set_foreach(shared->SyncObjects, entry) {
399 _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key, 1);
400 }
401
402 _mesa_set_destroy(shared->SyncObjects, NULL);
403 }
404
405 _mesa_DeinitHashTable(&shared->SamplerObjects, delete_sampler_object_cb,
406 ctx);
407
408 /*
409 * Free texture objects (after FBOs since some textures might have
410 * been bound to FBOs).
411 */
412 /* the default textures */
413 for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
414 if (shared->DefaultTex[i])
415 _mesa_delete_texture_object(ctx, shared->DefaultTex[i]);
416 }
417
418 /* all other textures */
419 _mesa_DeinitHashTable(&shared->TexObjects, delete_texture_cb, ctx);
420
421 _mesa_free_shared_handles(shared);
422
423 /* ARB_shading_language_include */
424 _mesa_destroy_shader_includes(shared);
425 simple_mtx_destroy(&shared->ShaderIncludeMutex);
426
427 _mesa_DeinitHashTable(&shared->MemoryObjects, delete_memory_object_cb,
428 ctx);
429 _mesa_DeinitHashTable(&shared->SemaphoreObjects,
430 delete_semaphore_object_cb, ctx);
431
432 simple_mtx_destroy(&shared->Mutex);
433 simple_mtx_destroy(&shared->TexMutex);
434
435 FREE(shared);
436 }
437
438
439 /**
440 * gl_shared_state objects are ref counted.
441 * If ptr's refcount goes to zero, free the shared state.
442 */
443 void
_mesa_reference_shared_state(struct gl_context * ctx,struct gl_shared_state ** ptr,struct gl_shared_state * state)444 _mesa_reference_shared_state(struct gl_context *ctx,
445 struct gl_shared_state **ptr,
446 struct gl_shared_state *state)
447 {
448 if (*ptr == state)
449 return;
450
451 if (*ptr) {
452 /* unref old state */
453 struct gl_shared_state *old = *ptr;
454 GLboolean delete;
455
456 simple_mtx_lock(&old->Mutex);
457 assert(old->RefCount >= 1);
458 old->RefCount--;
459 delete = (old->RefCount == 0);
460 simple_mtx_unlock(&old->Mutex);
461
462 if (delete) {
463 free_shared_state(ctx, old);
464 }
465
466 *ptr = NULL;
467 }
468
469 if (state) {
470 /* reference new state */
471 simple_mtx_lock(&state->Mutex);
472 state->RefCount++;
473 *ptr = state;
474 simple_mtx_unlock(&state->Mutex);
475 }
476 }
477