blob: d994958d7d0c157591982e5a33df748a4d81e2a6 [file]
/*
* 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);
}