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