• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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