/* * Copyright © 2012 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "glthread_marshal.h" #include "dispatch.h" #include "uniforms.h" #include "api_exec_decl.h" void _mesa_glthread_ProgramChanged(struct gl_context *ctx) { struct glthread_state *glthread = &ctx->GLThread; /* Track the last change to shader programs. */ _mesa_glthread_fence_call(ctx, &glthread->LastProgramChangeBatch); } uint32_t _mesa_unmarshal_GetActiveUniform(struct gl_context *ctx, const struct marshal_cmd_GetActiveUniform *restrict cmd) { unreachable("never executed"); return 0; } static void wait_for_glLinkProgram(struct gl_context *ctx) { /* Wait for the last glLinkProgram call. */ _mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastProgramChangeBatch); } void GLAPIENTRY _mesa_marshal_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar * name) { GET_CURRENT_CONTEXT(ctx); /* This will generate GL_INVALID_OPERATION, as it should. */ if (ctx->GLThread.inside_begin_end) { _mesa_glthread_finish_before(ctx, "GetActiveUniform"); CALL_GetActiveUniform(ctx->Dispatch.Current, (program, index, bufSize, length, size, type, name)); return; } wait_for_glLinkProgram(ctx); /* We can execute glGetActiveUniform without syncing if we are sync'd to * the last calls of glLinkProgram and glDeleteProgram because shader * object IDs and their contents are immutable after those calls and * also thread-safe because they are shared between contexts. * glCreateShaderProgram calls glLinkProgram internally and it always * syncs, so it doesn't need any handling. */ _mesa_GetActiveUniform_impl(program, index, bufSize, length, size, type, name, true); } uint32_t _mesa_unmarshal_GetUniformLocation(struct gl_context *ctx, const struct marshal_cmd_GetUniformLocation *restrict cmd) { unreachable("never executed"); return 0; } GLint GLAPIENTRY _mesa_marshal_GetUniformLocation(GLuint program, const GLchar *name) { GET_CURRENT_CONTEXT(ctx); /* This will generate GL_INVALID_OPERATION, as it should. */ if (ctx->GLThread.inside_begin_end) { _mesa_glthread_finish_before(ctx, "GetUniformLocation"); return CALL_GetUniformLocation(ctx->Dispatch.Current, (program, name)); } wait_for_glLinkProgram(ctx); /* This is thread-safe. See the comment in _mesa_marshal_GetActiveUniform. */ return _mesa_GetUniformLocation_impl(program, name, true); }