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