shared.c revision 01e04c3f
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
304a49301eSmrg#include "imports.h"
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"
4601e04c3fSmrg
4701e04c3fSmrgstatic void
4801e04c3fSmrgfree_shared_state(struct gl_context *ctx, struct gl_shared_state *shared);
494a49301eSmrg
504a49301eSmrg/**
514a49301eSmrg * Allocate and initialize a shared context state structure.
524a49301eSmrg * Initializes the display list, texture objects and vertex programs hash
534a49301eSmrg * tables, allocates the texture objects. If it runs out of memory, frees
544a49301eSmrg * everything already allocated before returning NULL.
554a49301eSmrg *
564a49301eSmrg * \return pointer to a gl_shared_state structure on success, or NULL on
574a49301eSmrg * failure.
584a49301eSmrg */
594a49301eSmrgstruct gl_shared_state *
603464ebd5Sriastradh_mesa_alloc_shared_state(struct gl_context *ctx)
614a49301eSmrg{
624a49301eSmrg   struct gl_shared_state *shared;
634a49301eSmrg   GLuint i;
644a49301eSmrg
654a49301eSmrg   shared = CALLOC_STRUCT(gl_shared_state);
664a49301eSmrg   if (!shared)
674a49301eSmrg      return NULL;
684a49301eSmrg
6901e04c3fSmrg   simple_mtx_init(&shared->Mutex, mtx_plain);
704a49301eSmrg
714a49301eSmrg   shared->DisplayList = _mesa_NewHashTable();
7201e04c3fSmrg   shared->BitmapAtlas = _mesa_NewHashTable();
734a49301eSmrg   shared->TexObjects = _mesa_NewHashTable();
744a49301eSmrg   shared->Programs = _mesa_NewHashTable();
754a49301eSmrg
76af69d88dSmrg   shared->DefaultVertexProgram =
7701e04c3fSmrg      ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0, true);
78af69d88dSmrg   shared->DefaultFragmentProgram =
7901e04c3fSmrg      ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0, true);
804a49301eSmrg
814a49301eSmrg   shared->ATIShaders = _mesa_NewHashTable();
824a49301eSmrg   shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
834a49301eSmrg
844a49301eSmrg   shared->ShaderObjects = _mesa_NewHashTable();
854a49301eSmrg
864a49301eSmrg   shared->BufferObjects = _mesa_NewHashTable();
874a49301eSmrg
883464ebd5Sriastradh   /* GL_ARB_sampler_objects */
893464ebd5Sriastradh   shared->SamplerObjects = _mesa_NewHashTable();
903464ebd5Sriastradh
9101e04c3fSmrg   /* GL_ARB_bindless_texture */
9201e04c3fSmrg   _mesa_init_shared_handles(shared);
9301e04c3fSmrg
944a49301eSmrg   /* Allocate the default buffer object */
9501e04c3fSmrg   shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0);
9601e04c3fSmrg   if (!shared->NullBufferObj)
9701e04c3fSmrg      goto fail;
984a49301eSmrg
994a49301eSmrg   /* Create default texture objects */
1004a49301eSmrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
1014a49301eSmrg      /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
102af69d88dSmrg      static const GLenum targets[] = {
103af69d88dSmrg         GL_TEXTURE_2D_MULTISAMPLE,
104af69d88dSmrg         GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
105af69d88dSmrg         GL_TEXTURE_CUBE_MAP_ARRAY,
1063464ebd5Sriastradh         GL_TEXTURE_BUFFER,
1074a49301eSmrg         GL_TEXTURE_2D_ARRAY_EXT,
1084a49301eSmrg         GL_TEXTURE_1D_ARRAY_EXT,
109af69d88dSmrg         GL_TEXTURE_EXTERNAL_OES,
1104a49301eSmrg         GL_TEXTURE_CUBE_MAP,
1114a49301eSmrg         GL_TEXTURE_3D,
1124a49301eSmrg         GL_TEXTURE_RECTANGLE_NV,
1134a49301eSmrg         GL_TEXTURE_2D,
1144a49301eSmrg         GL_TEXTURE_1D
1154a49301eSmrg      };
11601e04c3fSmrg      STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
1174a49301eSmrg      shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]);
11801e04c3fSmrg      /* Need to explicitly set/overwrite the TargetIndex field here since
11901e04c3fSmrg       * the call to _mesa_tex_target_to_index() in NewTextureObject() may
12001e04c3fSmrg       * fail if the texture target is not supported.
12101e04c3fSmrg       */
12201e04c3fSmrg      shared->DefaultTex[i]->TargetIndex = i;
1234a49301eSmrg   }
1244a49301eSmrg
1254a49301eSmrg   /* sanity check */
1264a49301eSmrg   assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
1274a49301eSmrg
1284a49301eSmrg   /* Mutex and timestamp for texobj state validation */
129af69d88dSmrg   mtx_init(&shared->TexMutex, mtx_recursive);
1304a49301eSmrg   shared->TextureStateStamp = 0;
1314a49301eSmrg
1324a49301eSmrg   shared->FrameBuffers = _mesa_NewHashTable();
1334a49301eSmrg   shared->RenderBuffers = _mesa_NewHashTable();
1344a49301eSmrg
13501e04c3fSmrg   shared->SyncObjects = _mesa_set_create(NULL, _mesa_hash_pointer,
13601e04c3fSmrg                                          _mesa_key_pointer_equal);
13701e04c3fSmrg
13801e04c3fSmrg   shared->MemoryObjects = _mesa_NewHashTable();
13901e04c3fSmrg   shared->SemaphoreObjects = _mesa_NewHashTable();
1404a49301eSmrg
1414a49301eSmrg   return shared;
14201e04c3fSmrg
14301e04c3fSmrgfail:
14401e04c3fSmrg   free_shared_state(ctx, shared);
14501e04c3fSmrg   return NULL;
1464a49301eSmrg}
1474a49301eSmrg
1484a49301eSmrg
1494a49301eSmrg/**
1504a49301eSmrg * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
1514a49301eSmrg */
1524a49301eSmrgstatic void
1534a49301eSmrgdelete_displaylist_cb(GLuint id, void *data, void *userData)
1544a49301eSmrg{
1554a49301eSmrg   struct gl_display_list *list = (struct gl_display_list *) data;
1563464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
1574a49301eSmrg   _mesa_delete_list(ctx, list);
1584a49301eSmrg}
1594a49301eSmrg
1604a49301eSmrg
16101e04c3fSmrg/**
16201e04c3fSmrg * Callback for deleting a bitmap atlas.  Called by _mesa_HashDeleteAll().
16301e04c3fSmrg */
16401e04c3fSmrgstatic void
16501e04c3fSmrgdelete_bitmap_atlas_cb(GLuint id, void *data, void *userData)
16601e04c3fSmrg{
16701e04c3fSmrg   struct gl_bitmap_atlas *atlas = (struct gl_bitmap_atlas *) data;
16801e04c3fSmrg   struct gl_context *ctx = (struct gl_context *) userData;
16901e04c3fSmrg   _mesa_delete_bitmap_atlas(ctx, atlas);
17001e04c3fSmrg}
17101e04c3fSmrg
17201e04c3fSmrg
1734a49301eSmrg/**
1744a49301eSmrg * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
1754a49301eSmrg */
1764a49301eSmrgstatic void
1774a49301eSmrgdelete_texture_cb(GLuint id, void *data, void *userData)
1784a49301eSmrg{
1794a49301eSmrg   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
1803464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
1814a49301eSmrg   ctx->Driver.DeleteTexture(ctx, texObj);
1824a49301eSmrg}
1834a49301eSmrg
1844a49301eSmrg
1854a49301eSmrg/**
1864a49301eSmrg * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
1874a49301eSmrg */
1884a49301eSmrgstatic void
1894a49301eSmrgdelete_program_cb(GLuint id, void *data, void *userData)
1904a49301eSmrg{
1914a49301eSmrg   struct gl_program *prog = (struct gl_program *) data;
1923464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
1934a49301eSmrg   if(prog != &_mesa_DummyProgram) {
19401e04c3fSmrg      assert(prog->RefCount == 1); /* should only be referenced by hash table */
1954a49301eSmrg      prog->RefCount = 0;  /* now going away */
1964a49301eSmrg      ctx->Driver.DeleteProgram(ctx, prog);
1974a49301eSmrg   }
1984a49301eSmrg}
1994a49301eSmrg
2004a49301eSmrg
2014a49301eSmrg/**
2024a49301eSmrg * Callback for deleting an ATI fragment shader object.
2034a49301eSmrg * Called by _mesa_HashDeleteAll().
2044a49301eSmrg */
2054a49301eSmrgstatic void
2064a49301eSmrgdelete_fragshader_cb(GLuint id, void *data, void *userData)
2074a49301eSmrg{
2084a49301eSmrg   struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
2093464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
2104a49301eSmrg   _mesa_delete_ati_fragment_shader(ctx, shader);
2114a49301eSmrg}
2124a49301eSmrg
2134a49301eSmrg
2144a49301eSmrg/**
2154a49301eSmrg * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
2164a49301eSmrg */
2174a49301eSmrgstatic void
2184a49301eSmrgdelete_bufferobj_cb(GLuint id, void *data, void *userData)
2194a49301eSmrg{
2204a49301eSmrg   struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
2213464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
222af69d88dSmrg
223af69d88dSmrg   _mesa_buffer_unmap_all_mappings(ctx, bufObj);
2244a49301eSmrg   _mesa_reference_buffer_object(ctx, &bufObj, NULL);
2254a49301eSmrg}
2264a49301eSmrg
2274a49301eSmrg
2284a49301eSmrg/**
2294a49301eSmrg * Callback for freeing shader program data. Call it before delete_shader_cb
2304a49301eSmrg * to avoid memory access error.
2314a49301eSmrg */
2324a49301eSmrgstatic void
2334a49301eSmrgfree_shader_program_data_cb(GLuint id, void *data, void *userData)
2344a49301eSmrg{
2353464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
2364a49301eSmrg   struct gl_shader_program *shProg = (struct gl_shader_program *) data;
2374a49301eSmrg
2384a49301eSmrg   if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
2394a49301eSmrg       _mesa_free_shader_program_data(ctx, shProg);
2404a49301eSmrg   }
2414a49301eSmrg}
2424a49301eSmrg
2434a49301eSmrg
2444a49301eSmrg/**
2454a49301eSmrg * Callback for deleting shader and shader programs objects.
2464a49301eSmrg * Called by _mesa_HashDeleteAll().
2474a49301eSmrg */
2484a49301eSmrgstatic void
2494a49301eSmrgdelete_shader_cb(GLuint id, void *data, void *userData)
2504a49301eSmrg{
2513464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
2524a49301eSmrg   struct gl_shader *sh = (struct gl_shader *) data;
253af69d88dSmrg   if (_mesa_validate_shader_target(ctx, sh->Type)) {
25401e04c3fSmrg      _mesa_delete_shader(ctx, sh);
2554a49301eSmrg   }
2564a49301eSmrg   else {
2574a49301eSmrg      struct gl_shader_program *shProg = (struct gl_shader_program *) data;
25801e04c3fSmrg      assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
25901e04c3fSmrg      _mesa_delete_shader_program(ctx, shProg);
2604a49301eSmrg   }
2614a49301eSmrg}
2624a49301eSmrg
2634a49301eSmrg
2644a49301eSmrg/**
2654a49301eSmrg * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
2664a49301eSmrg */
2674a49301eSmrgstatic void
2684a49301eSmrgdelete_framebuffer_cb(GLuint id, void *data, void *userData)
2694a49301eSmrg{
2704a49301eSmrg   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2714a49301eSmrg   /* The fact that the framebuffer is in the hashtable means its refcount
2724a49301eSmrg    * is one, but we're removing from the hashtable now.  So clear refcount.
2734a49301eSmrg    */
2744a49301eSmrg   /*assert(fb->RefCount == 1);*/
2754a49301eSmrg   fb->RefCount = 0;
2764a49301eSmrg
2774a49301eSmrg   /* NOTE: Delete should always be defined but there are two reports
2784a49301eSmrg    * of it being NULL (bugs 13507, 14293).  Work-around for now.
2794a49301eSmrg    */
2804a49301eSmrg   if (fb->Delete)
2814a49301eSmrg      fb->Delete(fb);
2824a49301eSmrg}
2834a49301eSmrg
2844a49301eSmrg
2854a49301eSmrg/**
2864a49301eSmrg * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
2874a49301eSmrg */
2884a49301eSmrgstatic void
2894a49301eSmrgdelete_renderbuffer_cb(GLuint id, void *data, void *userData)
2904a49301eSmrg{
291af69d88dSmrg   struct gl_context *ctx = (struct gl_context *) userData;
2924a49301eSmrg   struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
2934a49301eSmrg   rb->RefCount = 0;  /* see comment for FBOs above */
2944a49301eSmrg   if (rb->Delete)
295af69d88dSmrg      rb->Delete(ctx, rb);
2964a49301eSmrg}
2974a49301eSmrg
2984a49301eSmrg
2993464ebd5Sriastradh/**
3003464ebd5Sriastradh * Callback for deleting a sampler object. Called by _mesa_HashDeleteAll()
3013464ebd5Sriastradh */
3023464ebd5Sriastradhstatic void
3033464ebd5Sriastradhdelete_sampler_object_cb(GLuint id, void *data, void *userData)
3043464ebd5Sriastradh{
3053464ebd5Sriastradh   struct gl_context *ctx = (struct gl_context *) userData;
3063464ebd5Sriastradh   struct gl_sampler_object *sampObj = (struct gl_sampler_object *) data;
3073464ebd5Sriastradh   _mesa_reference_sampler_object(ctx, &sampObj, NULL);
3083464ebd5Sriastradh}
3093464ebd5Sriastradh
31001e04c3fSmrg/**
31101e04c3fSmrg * Callback for deleting a memory object.  Called by _mesa_HashDeleteAll().
31201e04c3fSmrg */
31301e04c3fSmrgstatic void
31401e04c3fSmrgdelete_memory_object_cb(GLuint id, void *data, void *userData)
31501e04c3fSmrg{
31601e04c3fSmrg   struct gl_memory_object *memObj = (struct gl_memory_object *) data;
31701e04c3fSmrg   struct gl_context *ctx = (struct gl_context *) userData;
31801e04c3fSmrg   ctx->Driver.DeleteMemoryObject(ctx, memObj);
31901e04c3fSmrg}
32001e04c3fSmrg
32101e04c3fSmrg/**
32201e04c3fSmrg * Callback for deleting a memory object.  Called by _mesa_HashDeleteAll().
32301e04c3fSmrg */
32401e04c3fSmrgstatic void
32501e04c3fSmrgdelete_semaphore_object_cb(GLuint id, void *data, void *userData)
32601e04c3fSmrg{
32701e04c3fSmrg   struct gl_semaphore_object *semObj = (struct gl_semaphore_object *) data;
32801e04c3fSmrg   struct gl_context *ctx = (struct gl_context *) userData;
32901e04c3fSmrg   ctx->Driver.DeleteSemaphoreObject(ctx, semObj);
33001e04c3fSmrg}
3313464ebd5Sriastradh
3324a49301eSmrg/**
3334a49301eSmrg * Deallocate a shared state object and all children structures.
3344a49301eSmrg *
3354a49301eSmrg * \param ctx GL context.
3364a49301eSmrg * \param shared shared state pointer.
3374a49301eSmrg *
3384a49301eSmrg * Frees the display lists, the texture objects (calling the driver texture
3394a49301eSmrg * deletion callback to free its private data) and the vertex programs, as well
3404a49301eSmrg * as their hash tables.
3414a49301eSmrg *
3424a49301eSmrg * \sa alloc_shared_state().
3434a49301eSmrg */
3444a49301eSmrgstatic void
3453464ebd5Sriastradhfree_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
3464a49301eSmrg{
3474a49301eSmrg   GLuint i;
3484a49301eSmrg
349af69d88dSmrg   /* Free the dummy/fallback texture objects */
350af69d88dSmrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
351af69d88dSmrg      if (shared->FallbackTex[i])
352af69d88dSmrg         ctx->Driver.DeleteTexture(ctx, shared->FallbackTex[i]);
353af69d88dSmrg   }
3543464ebd5Sriastradh
3554a49301eSmrg   /*
3564a49301eSmrg    * Free display lists
3574a49301eSmrg    */
35801e04c3fSmrg   if (shared->DisplayList) {
35901e04c3fSmrg      _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx);
36001e04c3fSmrg      _mesa_DeleteHashTable(shared->DisplayList);
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
39801e04c3fSmrg   if (shared->FrameBuffers) {
39901e04c3fSmrg      _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx);
40001e04c3fSmrg      _mesa_DeleteHashTable(shared->FrameBuffers);
40101e04c3fSmrg   }
4024a49301eSmrg
40301e04c3fSmrg   if (shared->RenderBuffers) {
40401e04c3fSmrg      _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx);
40501e04c3fSmrg      _mesa_DeleteHashTable(shared->RenderBuffers);
40601e04c3fSmrg   }
4074a49301eSmrg
40801e04c3fSmrg   if (shared->NullBufferObj)
40901e04c3fSmrg      _mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL);
4104a49301eSmrg
41101e04c3fSmrg   if (shared->SyncObjects) {
412af69d88dSmrg      set_foreach(shared->SyncObjects, entry) {
41301e04c3fSmrg         _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key, 1);
4144a49301eSmrg      }
41501e04c3fSmrg
41601e04c3fSmrg      _mesa_set_destroy(shared->SyncObjects, NULL);
4174a49301eSmrg   }
4183464ebd5Sriastradh
41901e04c3fSmrg   if (shared->SamplerObjects) {
42001e04c3fSmrg      _mesa_HashDeleteAll(shared->SamplerObjects, delete_sampler_object_cb,
42101e04c3fSmrg                          ctx);
42201e04c3fSmrg      _mesa_DeleteHashTable(shared->SamplerObjects);
42301e04c3fSmrg   }
4244a49301eSmrg
4254a49301eSmrg   /*
4264a49301eSmrg    * Free texture objects (after FBOs since some textures might have
4274a49301eSmrg    * been bound to FBOs).
4284a49301eSmrg    */
42901e04c3fSmrg   assert(ctx->Driver.DeleteTexture);
4304a49301eSmrg   /* the default textures */
4314a49301eSmrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
43201e04c3fSmrg      if (shared->DefaultTex[i])
43301e04c3fSmrg         ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]);
4344a49301eSmrg   }
4354a49301eSmrg
4364a49301eSmrg   /* all other textures */
43701e04c3fSmrg   if (shared->TexObjects) {
43801e04c3fSmrg      _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx);
43901e04c3fSmrg      _mesa_DeleteHashTable(shared->TexObjects);
44001e04c3fSmrg   }
44101e04c3fSmrg
44201e04c3fSmrg   _mesa_free_shared_handles(shared);
44301e04c3fSmrg
44401e04c3fSmrg   if (shared->MemoryObjects) {
44501e04c3fSmrg      _mesa_HashDeleteAll(shared->MemoryObjects, delete_memory_object_cb, ctx);
44601e04c3fSmrg      _mesa_DeleteHashTable(shared->MemoryObjects);
44701e04c3fSmrg   }
44801e04c3fSmrg
44901e04c3fSmrg   if (shared->SemaphoreObjects) {
45001e04c3fSmrg      _mesa_HashDeleteAll(shared->SemaphoreObjects, delete_semaphore_object_cb, ctx);
45101e04c3fSmrg      _mesa_DeleteHashTable(shared->SemaphoreObjects);
45201e04c3fSmrg   }
4534a49301eSmrg
45401e04c3fSmrg   simple_mtx_destroy(&shared->Mutex);
455af69d88dSmrg   mtx_destroy(&shared->TexMutex);
4564a49301eSmrg
457cdc920a0Smrg   free(shared);
4584a49301eSmrg}
4594a49301eSmrg
4604a49301eSmrg
4614a49301eSmrg/**
462af69d88dSmrg * gl_shared_state objects are ref counted.
463af69d88dSmrg * If ptr's refcount goes to zero, free the shared state.
4644a49301eSmrg */
4654a49301eSmrgvoid
466af69d88dSmrg_mesa_reference_shared_state(struct gl_context *ctx,
467af69d88dSmrg                             struct gl_shared_state **ptr,
468af69d88dSmrg                             struct gl_shared_state *state)
4694a49301eSmrg{
470af69d88dSmrg   if (*ptr == state)
471af69d88dSmrg      return;
472af69d88dSmrg
473af69d88dSmrg   if (*ptr) {
474af69d88dSmrg      /* unref old state */
475af69d88dSmrg      struct gl_shared_state *old = *ptr;
476af69d88dSmrg      GLboolean delete;
477af69d88dSmrg
47801e04c3fSmrg      simple_mtx_lock(&old->Mutex);
479af69d88dSmrg      assert(old->RefCount >= 1);
480af69d88dSmrg      old->RefCount--;
481af69d88dSmrg      delete = (old->RefCount == 0);
48201e04c3fSmrg      simple_mtx_unlock(&old->Mutex);
483af69d88dSmrg
484af69d88dSmrg      if (delete) {
485af69d88dSmrg         free_shared_state(ctx, old);
486af69d88dSmrg      }
4874a49301eSmrg
488af69d88dSmrg      *ptr = NULL;
489af69d88dSmrg   }
4904a49301eSmrg
491af69d88dSmrg   if (state) {
492af69d88dSmrg      /* reference new state */
49301e04c3fSmrg      simple_mtx_lock(&state->Mutex);
494af69d88dSmrg      state->RefCount++;
495af69d88dSmrg      *ptr = state;
49601e04c3fSmrg      simple_mtx_unlock(&state->Mutex);
4974a49301eSmrg   }
4984a49301eSmrg}
499