shared.c revision 7ec681f3
14a49301eSmrg/*
24a49301eSmrg * Mesa 3-D graphics library
34a49301eSmrg *
44a49301eSmrg * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
54a49301eSmrg *
64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a
74a49301eSmrg * copy of this software and associated documentation files (the "Software"),
84a49301eSmrg * to deal in the Software without restriction, including without limitation
94a49301eSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
104a49301eSmrg * and/or sell copies of the Software, and to permit persons to whom the
114a49301eSmrg * Software is furnished to do so, subject to the following conditions:
124a49301eSmrg *
134a49301eSmrg * The above copyright notice and this permission notice shall be included
144a49301eSmrg * in all copies or substantial portions of the Software.
154a49301eSmrg *
164a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
174a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
184a49301eSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
234a49301eSmrg */
244a49301eSmrg
254a49301eSmrg/**
264a49301eSmrg * \file shared.c
274a49301eSmrg * Shared-context state
284a49301eSmrg */
294a49301eSmrg
307ec681f3Smrg
314a49301eSmrg#include "mtypes.h"
324a49301eSmrg#include "hash.h"
333464ebd5Sriastradh#include "atifragshader.h"
344a49301eSmrg#include "bufferobj.h"
354a49301eSmrg#include "shared.h"
363464ebd5Sriastradh#include "program/program.h"
374a49301eSmrg#include "dlist.h"
383464ebd5Sriastradh#include "samplerobj.h"
39af69d88dSmrg#include "shaderapi.h"
403464ebd5Sriastradh#include "shaderobj.h"
414a49301eSmrg#include "syncobj.h"
4201e04c3fSmrg#include "texturebindless.h"
433464ebd5Sriastradh
44af69d88dSmrg#include "util/hash_table.h"
4501e04c3fSmrg#include "util/set.h"
467ec681f3Smrg#include "util/u_memory.h"
4701e04c3fSmrg
4801e04c3fSmrgstatic void
4901e04c3fSmrgfree_shared_state(struct gl_context *ctx, struct gl_shared_state *shared);
504a49301eSmrg
514a49301eSmrg/**
524a49301eSmrg * Allocate and initialize a shared context state structure.
534a49301eSmrg * Initializes the display list, texture objects and vertex programs hash
544a49301eSmrg * tables, allocates the texture objects. If it runs out of memory, frees
554a49301eSmrg * everything already allocated before returning NULL.
564a49301eSmrg *
574a49301eSmrg * \return pointer to a gl_shared_state structure on success, or NULL on
584a49301eSmrg * failure.
594a49301eSmrg */
604a49301eSmrgstruct gl_shared_state *
613464ebd5Sriastradh_mesa_alloc_shared_state(struct gl_context *ctx)
624a49301eSmrg{
634a49301eSmrg   struct gl_shared_state *shared;
644a49301eSmrg   GLuint i;
654a49301eSmrg
664a49301eSmrg   shared = CALLOC_STRUCT(gl_shared_state);
674a49301eSmrg   if (!shared)
684a49301eSmrg      return NULL;
694a49301eSmrg
7001e04c3fSmrg   simple_mtx_init(&shared->Mutex, mtx_plain);
714a49301eSmrg
724a49301eSmrg   shared->DisplayList = _mesa_NewHashTable();
7301e04c3fSmrg   shared->BitmapAtlas = _mesa_NewHashTable();
744a49301eSmrg   shared->TexObjects = _mesa_NewHashTable();
754a49301eSmrg   shared->Programs = _mesa_NewHashTable();
764a49301eSmrg
77af69d88dSmrg   shared->DefaultVertexProgram =
787ec681f3Smrg      ctx->Driver.NewProgram(ctx, MESA_SHADER_VERTEX, 0, true);
79af69d88dSmrg   shared->DefaultFragmentProgram =
807ec681f3Smrg      ctx->Driver.NewProgram(ctx, MESA_SHADER_FRAGMENT, 0, true);
814a49301eSmrg
824a49301eSmrg   shared->ATIShaders = _mesa_NewHashTable();
834a49301eSmrg   shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
844a49301eSmrg
854a49301eSmrg   shared->ShaderObjects = _mesa_NewHashTable();
864a49301eSmrg
874a49301eSmrg   shared->BufferObjects = _mesa_NewHashTable();
887ec681f3Smrg   shared->ZombieBufferObjects = _mesa_set_create(NULL, _mesa_hash_pointer,
897ec681f3Smrg                                                  _mesa_key_pointer_equal);
904a49301eSmrg
913464ebd5Sriastradh   /* GL_ARB_sampler_objects */
923464ebd5Sriastradh   shared->SamplerObjects = _mesa_NewHashTable();
933464ebd5Sriastradh
9401e04c3fSmrg   /* GL_ARB_bindless_texture */
9501e04c3fSmrg   _mesa_init_shared_handles(shared);
9601e04c3fSmrg
977ec681f3Smrg   /* ARB_shading_language_include */
987ec681f3Smrg   _mesa_init_shader_includes(shared);
997ec681f3Smrg   simple_mtx_init(&shared->ShaderIncludeMutex, mtx_plain);
1004a49301eSmrg
1014a49301eSmrg   /* Create default texture objects */
1024a49301eSmrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
1034a49301eSmrg      /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
104af69d88dSmrg      static const GLenum targets[] = {
105af69d88dSmrg         GL_TEXTURE_2D_MULTISAMPLE,
106af69d88dSmrg         GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
107af69d88dSmrg         GL_TEXTURE_CUBE_MAP_ARRAY,
1083464ebd5Sriastradh         GL_TEXTURE_BUFFER,
1094a49301eSmrg         GL_TEXTURE_2D_ARRAY_EXT,
1104a49301eSmrg         GL_TEXTURE_1D_ARRAY_EXT,
111af69d88dSmrg         GL_TEXTURE_EXTERNAL_OES,
1124a49301eSmrg         GL_TEXTURE_CUBE_MAP,
1134a49301eSmrg         GL_TEXTURE_3D,
1144a49301eSmrg         GL_TEXTURE_RECTANGLE_NV,
1154a49301eSmrg         GL_TEXTURE_2D,
1164a49301eSmrg         GL_TEXTURE_1D
1174a49301eSmrg      };
11801e04c3fSmrg      STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
1194a49301eSmrg      shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]);
12001e04c3fSmrg      /* Need to explicitly set/overwrite the TargetIndex field here since
12101e04c3fSmrg       * the call to _mesa_tex_target_to_index() in NewTextureObject() may
12201e04c3fSmrg       * fail if the texture target is not supported.
12301e04c3fSmrg       */
12401e04c3fSmrg      shared->DefaultTex[i]->TargetIndex = i;
1254a49301eSmrg   }
1264a49301eSmrg
1274a49301eSmrg   /* sanity check */
1284a49301eSmrg   assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
1294a49301eSmrg
1304a49301eSmrg   /* Mutex and timestamp for texobj state validation */
131af69d88dSmrg   mtx_init(&shared->TexMutex, mtx_recursive);
1324a49301eSmrg   shared->TextureStateStamp = 0;
1334a49301eSmrg
1344a49301eSmrg   shared->FrameBuffers = _mesa_NewHashTable();
1354a49301eSmrg   shared->RenderBuffers = _mesa_NewHashTable();
1364a49301eSmrg
13701e04c3fSmrg   shared->SyncObjects = _mesa_set_create(NULL, _mesa_hash_pointer,
13801e04c3fSmrg                                          _mesa_key_pointer_equal);
13901e04c3fSmrg
14001e04c3fSmrg   shared->MemoryObjects = _mesa_NewHashTable();
14101e04c3fSmrg   shared->SemaphoreObjects = _mesa_NewHashTable();
1424a49301eSmrg
1434a49301eSmrg   return shared;
1444a49301eSmrg}
1454a49301eSmrg
1464a49301eSmrg
1474a49301eSmrg/**
1484a49301eSmrg * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
1494a49301eSmrg */
1504a49301eSmrgstatic void
1517ec681f3Smrgdelete_displaylist_cb(void *data, void *userData)
1524a49301eSmrg{
1534a49301eSmrg   struct gl_display_list *list = (struct gl_display_list *) data;
1543464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
1554a49301eSmrg   _mesa_delete_list(ctx, list);
1564a49301eSmrg}
1574a49301eSmrg
1584a49301eSmrg
15901e04c3fSmrg/**
16001e04c3fSmrg * Callback for deleting a bitmap atlas.  Called by _mesa_HashDeleteAll().
16101e04c3fSmrg */
16201e04c3fSmrgstatic void
1637ec681f3Smrgdelete_bitmap_atlas_cb(void *data, void *userData)
16401e04c3fSmrg{
16501e04c3fSmrg   struct gl_bitmap_atlas *atlas = (struct gl_bitmap_atlas *) data;
16601e04c3fSmrg   struct gl_context *ctx = (struct gl_context *) userData;
16701e04c3fSmrg   _mesa_delete_bitmap_atlas(ctx, atlas);
16801e04c3fSmrg}
16901e04c3fSmrg
17001e04c3fSmrg
1714a49301eSmrg/**
1724a49301eSmrg * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
1734a49301eSmrg */
1744a49301eSmrgstatic void
1757ec681f3Smrgdelete_texture_cb(void *data, void *userData)
1764a49301eSmrg{
1774a49301eSmrg   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
1783464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
1794a49301eSmrg   ctx->Driver.DeleteTexture(ctx, texObj);
1804a49301eSmrg}
1814a49301eSmrg
1824a49301eSmrg
1834a49301eSmrg/**
1844a49301eSmrg * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
1854a49301eSmrg */
1864a49301eSmrgstatic void
1877ec681f3Smrgdelete_program_cb(void *data, void *userData)
1884a49301eSmrg{
1894a49301eSmrg   struct gl_program *prog = (struct gl_program *) data;
1903464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
1914a49301eSmrg   if(prog != &_mesa_DummyProgram) {
19201e04c3fSmrg      assert(prog->RefCount == 1); /* should only be referenced by hash table */
1934a49301eSmrg      prog->RefCount = 0;  /* now going away */
1944a49301eSmrg      ctx->Driver.DeleteProgram(ctx, prog);
1954a49301eSmrg   }
1964a49301eSmrg}
1974a49301eSmrg
1984a49301eSmrg
1994a49301eSmrg/**
2004a49301eSmrg * Callback for deleting an ATI fragment shader object.
2014a49301eSmrg * Called by _mesa_HashDeleteAll().
2024a49301eSmrg */
2034a49301eSmrgstatic void
2047ec681f3Smrgdelete_fragshader_cb(void *data, void *userData)
2054a49301eSmrg{
2064a49301eSmrg   struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
2073464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
2084a49301eSmrg   _mesa_delete_ati_fragment_shader(ctx, shader);
2094a49301eSmrg}
2104a49301eSmrg
2114a49301eSmrg
2124a49301eSmrg/**
2134a49301eSmrg * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
2144a49301eSmrg */
2154a49301eSmrgstatic void
2167ec681f3Smrgdelete_bufferobj_cb(void *data, void *userData)
2174a49301eSmrg{
2184a49301eSmrg   struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
2193464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
220af69d88dSmrg
221af69d88dSmrg   _mesa_buffer_unmap_all_mappings(ctx, bufObj);
2224a49301eSmrg   _mesa_reference_buffer_object(ctx, &bufObj, NULL);
2234a49301eSmrg}
2244a49301eSmrg
2254a49301eSmrg
2264a49301eSmrg/**
2274a49301eSmrg * Callback for freeing shader program data. Call it before delete_shader_cb
2284a49301eSmrg * to avoid memory access error.
2294a49301eSmrg */
2304a49301eSmrgstatic void
2317ec681f3Smrgfree_shader_program_data_cb(void *data, void *userData)
2324a49301eSmrg{
2333464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
2344a49301eSmrg   struct gl_shader_program *shProg = (struct gl_shader_program *) data;
2354a49301eSmrg
2364a49301eSmrg   if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
2374a49301eSmrg       _mesa_free_shader_program_data(ctx, shProg);
2384a49301eSmrg   }
2394a49301eSmrg}
2404a49301eSmrg
2414a49301eSmrg
2424a49301eSmrg/**
2434a49301eSmrg * Callback for deleting shader and shader programs objects.
2444a49301eSmrg * Called by _mesa_HashDeleteAll().
2454a49301eSmrg */
2464a49301eSmrgstatic void
2477ec681f3Smrgdelete_shader_cb(void *data, void *userData)
2484a49301eSmrg{
2493464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
2504a49301eSmrg   struct gl_shader *sh = (struct gl_shader *) data;
251af69d88dSmrg   if (_mesa_validate_shader_target(ctx, sh->Type)) {
25201e04c3fSmrg      _mesa_delete_shader(ctx, sh);
2534a49301eSmrg   }
2544a49301eSmrg   else {
2554a49301eSmrg      struct gl_shader_program *shProg = (struct gl_shader_program *) data;
25601e04c3fSmrg      assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
25701e04c3fSmrg      _mesa_delete_shader_program(ctx, shProg);
2584a49301eSmrg   }
2594a49301eSmrg}
2604a49301eSmrg
2614a49301eSmrg
2624a49301eSmrg/**
2634a49301eSmrg * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
2644a49301eSmrg */
2654a49301eSmrgstatic void
2667ec681f3Smrgdelete_framebuffer_cb(void *data, UNUSED void *userData)
2674a49301eSmrg{
2684a49301eSmrg   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2694a49301eSmrg   /* The fact that the framebuffer is in the hashtable means its refcount
2704a49301eSmrg    * is one, but we're removing from the hashtable now.  So clear refcount.
2714a49301eSmrg    */
2724a49301eSmrg   /*assert(fb->RefCount == 1);*/
2734a49301eSmrg   fb->RefCount = 0;
2744a49301eSmrg
2754a49301eSmrg   /* NOTE: Delete should always be defined but there are two reports
2764a49301eSmrg    * of it being NULL (bugs 13507, 14293).  Work-around for now.
2774a49301eSmrg    */
2784a49301eSmrg   if (fb->Delete)
2794a49301eSmrg      fb->Delete(fb);
2804a49301eSmrg}
2814a49301eSmrg
2824a49301eSmrg
2834a49301eSmrg/**
2844a49301eSmrg * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
2854a49301eSmrg */
2864a49301eSmrgstatic void
2877ec681f3Smrgdelete_renderbuffer_cb(void *data, void *userData)
2884a49301eSmrg{
289af69d88dSmrg   struct gl_context *ctx = (struct gl_context *) userData;
2904a49301eSmrg   struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
2914a49301eSmrg   rb->RefCount = 0;  /* see comment for FBOs above */
2924a49301eSmrg   if (rb->Delete)
293af69d88dSmrg      rb->Delete(ctx, rb);
2944a49301eSmrg}
2954a49301eSmrg
2964a49301eSmrg
2973464ebd5Sriastradh/**
2983464ebd5Sriastradh * Callback for deleting a sampler object. Called by _mesa_HashDeleteAll()
2993464ebd5Sriastradh */
3003464ebd5Sriastradhstatic void
3017ec681f3Smrgdelete_sampler_object_cb(void *data, void *userData)
3023464ebd5Sriastradh{
3033464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
3043464ebd5Sriastradh   struct gl_sampler_object *sampObj = (struct gl_sampler_object *) data;
3053464ebd5Sriastradh   _mesa_reference_sampler_object(ctx, &sampObj, NULL);
3063464ebd5Sriastradh}
3073464ebd5Sriastradh
30801e04c3fSmrg/**
30901e04c3fSmrg * Callback for deleting a memory object.  Called by _mesa_HashDeleteAll().
31001e04c3fSmrg */
31101e04c3fSmrgstatic void
3127ec681f3Smrgdelete_memory_object_cb(void *data, void *userData)
31301e04c3fSmrg{
31401e04c3fSmrg   struct gl_memory_object *memObj = (struct gl_memory_object *) data;
31501e04c3fSmrg   struct gl_context *ctx = (struct gl_context *) userData;
31601e04c3fSmrg   ctx->Driver.DeleteMemoryObject(ctx, memObj);
31701e04c3fSmrg}
31801e04c3fSmrg
31901e04c3fSmrg/**
32001e04c3fSmrg * Callback for deleting a memory object.  Called by _mesa_HashDeleteAll().
32101e04c3fSmrg */
32201e04c3fSmrgstatic void
3237ec681f3Smrgdelete_semaphore_object_cb(void *data, void *userData)
32401e04c3fSmrg{
32501e04c3fSmrg   struct gl_semaphore_object *semObj = (struct gl_semaphore_object *) data;
32601e04c3fSmrg   struct gl_context *ctx = (struct gl_context *) userData;
32701e04c3fSmrg   ctx->Driver.DeleteSemaphoreObject(ctx, semObj);
32801e04c3fSmrg}
3293464ebd5Sriastradh
3304a49301eSmrg/**
3314a49301eSmrg * Deallocate a shared state object and all children structures.
3324a49301eSmrg *
3334a49301eSmrg * \param ctx GL context.
3344a49301eSmrg * \param shared shared state pointer.
3357ec681f3Smrg *
3364a49301eSmrg * Frees the display lists, the texture objects (calling the driver texture
3374a49301eSmrg * deletion callback to free its private data) and the vertex programs, as well
3384a49301eSmrg * as their hash tables.
3394a49301eSmrg *
3404a49301eSmrg * \sa alloc_shared_state().
3414a49301eSmrg */
3424a49301eSmrgstatic void
3433464ebd5Sriastradhfree_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
3444a49301eSmrg{
3454a49301eSmrg   GLuint i;
3464a49301eSmrg
347af69d88dSmrg   /* Free the dummy/fallback texture objects */
348af69d88dSmrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
349af69d88dSmrg      if (shared->FallbackTex[i])
350af69d88dSmrg         ctx->Driver.DeleteTexture(ctx, shared->FallbackTex[i]);
351af69d88dSmrg   }
3523464ebd5Sriastradh
3534a49301eSmrg   /*
3544a49301eSmrg    * Free display lists
3554a49301eSmrg    */
35601e04c3fSmrg   if (shared->DisplayList) {
35701e04c3fSmrg      _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx);
35801e04c3fSmrg      _mesa_DeleteHashTable(shared->DisplayList);
3597ec681f3Smrg      free(shared->small_dlist_store.ptr);
3607ec681f3Smrg      util_idalloc_fini(&shared->small_dlist_store.free_idx);
36101e04c3fSmrg   }
3624a49301eSmrg
36301e04c3fSmrg   if (shared->BitmapAtlas) {
36401e04c3fSmrg      _mesa_HashDeleteAll(shared->BitmapAtlas, delete_bitmap_atlas_cb, ctx);
36501e04c3fSmrg      _mesa_DeleteHashTable(shared->BitmapAtlas);
36601e04c3fSmrg   }
3674a49301eSmrg
36801e04c3fSmrg   if (shared->ShaderObjects) {
36901e04c3fSmrg      _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx);
37001e04c3fSmrg      _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx);
37101e04c3fSmrg      _mesa_DeleteHashTable(shared->ShaderObjects);
37201e04c3fSmrg   }
3734a49301eSmrg
37401e04c3fSmrg   if (shared->Programs) {
37501e04c3fSmrg      _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx);
37601e04c3fSmrg      _mesa_DeleteHashTable(shared->Programs);
37701e04c3fSmrg   }
37801e04c3fSmrg
37901e04c3fSmrg   if (shared->DefaultVertexProgram)
38001e04c3fSmrg      _mesa_reference_program(ctx, &shared->DefaultVertexProgram, NULL);
38101e04c3fSmrg
38201e04c3fSmrg   if (shared->DefaultFragmentProgram)
38301e04c3fSmrg      _mesa_reference_program(ctx, &shared->DefaultFragmentProgram, NULL);
3844a49301eSmrg
38501e04c3fSmrg   if (shared->DefaultFragmentShader)
38601e04c3fSmrg      _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader);
38701e04c3fSmrg
38801e04c3fSmrg   if (shared->ATIShaders) {
38901e04c3fSmrg      _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx);
39001e04c3fSmrg      _mesa_DeleteHashTable(shared->ATIShaders);
39101e04c3fSmrg   }
3924a49301eSmrg
39301e04c3fSmrg   if (shared->BufferObjects) {
39401e04c3fSmrg      _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx);
39501e04c3fSmrg      _mesa_DeleteHashTable(shared->BufferObjects);
39601e04c3fSmrg   }
3974a49301eSmrg
3987ec681f3Smrg   if (shared->ZombieBufferObjects) {
3997ec681f3Smrg      set_foreach(shared->ZombieBufferObjects, entry) {
4007ec681f3Smrg         assert(!"ZombieBufferObjects should be empty");
4017ec681f3Smrg      }
4027ec681f3Smrg      _mesa_set_destroy(shared->ZombieBufferObjects, NULL);
4037ec681f3Smrg   }
4047ec681f3Smrg
40501e04c3fSmrg   if (shared->FrameBuffers) {
40601e04c3fSmrg      _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx);
40701e04c3fSmrg      _mesa_DeleteHashTable(shared->FrameBuffers);
40801e04c3fSmrg   }
4094a49301eSmrg
41001e04c3fSmrg   if (shared->RenderBuffers) {
41101e04c3fSmrg      _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx);
41201e04c3fSmrg      _mesa_DeleteHashTable(shared->RenderBuffers);
41301e04c3fSmrg   }
4144a49301eSmrg
41501e04c3fSmrg   if (shared->SyncObjects) {
416af69d88dSmrg      set_foreach(shared->SyncObjects, entry) {
41701e04c3fSmrg         _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key, 1);
4184a49301eSmrg      }
41901e04c3fSmrg
42001e04c3fSmrg      _mesa_set_destroy(shared->SyncObjects, NULL);
4214a49301eSmrg   }
4223464ebd5Sriastradh
42301e04c3fSmrg   if (shared->SamplerObjects) {
42401e04c3fSmrg      _mesa_HashDeleteAll(shared->SamplerObjects, delete_sampler_object_cb,
42501e04c3fSmrg                          ctx);
42601e04c3fSmrg      _mesa_DeleteHashTable(shared->SamplerObjects);
42701e04c3fSmrg   }
4284a49301eSmrg
4294a49301eSmrg   /*
4304a49301eSmrg    * Free texture objects (after FBOs since some textures might have
4314a49301eSmrg    * been bound to FBOs).
4324a49301eSmrg    */
43301e04c3fSmrg   assert(ctx->Driver.DeleteTexture);
4344a49301eSmrg   /* the default textures */
4354a49301eSmrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
43601e04c3fSmrg      if (shared->DefaultTex[i])
43701e04c3fSmrg         ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]);
4384a49301eSmrg   }
4394a49301eSmrg
4404a49301eSmrg   /* all other textures */
44101e04c3fSmrg   if (shared->TexObjects) {
44201e04c3fSmrg      _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx);
44301e04c3fSmrg      _mesa_DeleteHashTable(shared->TexObjects);
44401e04c3fSmrg   }
44501e04c3fSmrg
44601e04c3fSmrg   _mesa_free_shared_handles(shared);
44701e04c3fSmrg
4487ec681f3Smrg   /* ARB_shading_language_include */
4497ec681f3Smrg   _mesa_destroy_shader_includes(shared);
4507ec681f3Smrg   simple_mtx_destroy(&shared->ShaderIncludeMutex);
4517ec681f3Smrg
45201e04c3fSmrg   if (shared->MemoryObjects) {
45301e04c3fSmrg      _mesa_HashDeleteAll(shared->MemoryObjects, delete_memory_object_cb, ctx);
45401e04c3fSmrg      _mesa_DeleteHashTable(shared->MemoryObjects);
45501e04c3fSmrg   }
45601e04c3fSmrg
45701e04c3fSmrg   if (shared->SemaphoreObjects) {
45801e04c3fSmrg      _mesa_HashDeleteAll(shared->SemaphoreObjects, delete_semaphore_object_cb, ctx);
45901e04c3fSmrg      _mesa_DeleteHashTable(shared->SemaphoreObjects);
46001e04c3fSmrg   }
4614a49301eSmrg
46201e04c3fSmrg   simple_mtx_destroy(&shared->Mutex);
463af69d88dSmrg   mtx_destroy(&shared->TexMutex);
4644a49301eSmrg
465cdc920a0Smrg   free(shared);
4664a49301eSmrg}
4674a49301eSmrg
4684a49301eSmrg
4694a49301eSmrg/**
470af69d88dSmrg * gl_shared_state objects are ref counted.
471af69d88dSmrg * If ptr's refcount goes to zero, free the shared state.
4724a49301eSmrg */
4734a49301eSmrgvoid
474af69d88dSmrg_mesa_reference_shared_state(struct gl_context *ctx,
475af69d88dSmrg                             struct gl_shared_state **ptr,
476af69d88dSmrg                             struct gl_shared_state *state)
4774a49301eSmrg{
478af69d88dSmrg   if (*ptr == state)
479af69d88dSmrg      return;
480af69d88dSmrg
481af69d88dSmrg   if (*ptr) {
482af69d88dSmrg      /* unref old state */
483af69d88dSmrg      struct gl_shared_state *old = *ptr;
484af69d88dSmrg      GLboolean delete;
485af69d88dSmrg
48601e04c3fSmrg      simple_mtx_lock(&old->Mutex);
487af69d88dSmrg      assert(old->RefCount >= 1);
488af69d88dSmrg      old->RefCount--;
489af69d88dSmrg      delete = (old->RefCount == 0);
49001e04c3fSmrg      simple_mtx_unlock(&old->Mutex);
491af69d88dSmrg
492af69d88dSmrg      if (delete) {
493af69d88dSmrg         free_shared_state(ctx, old);
494af69d88dSmrg      }
4954a49301eSmrg
496af69d88dSmrg      *ptr = NULL;
497af69d88dSmrg   }
4984a49301eSmrg
499af69d88dSmrg   if (state) {
500af69d88dSmrg      /* reference new state */
50101e04c3fSmrg      simple_mtx_lock(&state->Mutex);
502af69d88dSmrg      state->RefCount++;
503af69d88dSmrg      *ptr = state;
50401e04c3fSmrg      simple_mtx_unlock(&state->Mutex);
5054a49301eSmrg   }
5064a49301eSmrg}
507