#include "main/shaderobj.h"
#include "main/transformfeedback.h"
#include "main/uniforms.h"
-#include "glsl/glsl_parser_extras.h"
-#include "glsl/ir.h"
-#include "glsl/ir_uniform.h"
-#include "glsl/program.h"
+#include "compiler/glsl/glsl_parser_extras.h"
+#include "compiler/glsl/ir.h"
+#include "compiler/glsl/ir_uniform.h"
+#include "compiler/glsl/program.h"
#include "program/program.h"
#include "program/prog_print.h"
#include "program/prog_parameter.h"
case GL_TESS_EVALUATION_SHADER:
return ctx == NULL || _mesa_has_tessellation(ctx);
case GL_COMPUTE_SHADER:
- return ctx == NULL || ctx->Extensions.ARB_compute_shader;
+ return ctx == NULL || _mesa_has_compute_shaders(ctx);
default:
return false;
}
GLuint name;
if (!_mesa_validate_shader_target(ctx, type)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(%s)",
+ _mesa_enum_to_string(type));
return 0;
}
+ _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
sh = ctx->Driver.NewShader(ctx, name, type);
- _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
+ _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh);
+ _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
return name;
}
GLuint name;
struct gl_shader_program *shProg;
+ _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
+
name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
shProg = _mesa_new_shader_program(name);
- _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
+ _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg);
assert(shProg->RefCount == 1);
+ _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
+
return name;
}
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = _mesa_longest_attribute_name_length(shProg);
return;
- case GL_ACTIVE_UNIFORMS:
- *params = shProg->NumUniformStorage - shProg->NumHiddenUniforms;
+ case GL_ACTIVE_UNIFORMS: {
+ unsigned i;
+ const unsigned num_uniforms =
+ shProg->NumUniformStorage - shProg->NumHiddenUniforms;
+ for (*params = 0, i = 0; i < num_uniforms; i++) {
+ if (!shProg->UniformStorage[i].is_shader_storage)
+ (*params)++;
+ }
return;
+ }
case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
unsigned i;
GLint max_len = 0;
shProg->NumUniformStorage - shProg->NumHiddenUniforms;
for (i = 0; i < num_uniforms; i++) {
+ if (shProg->UniformStorage[i].is_shader_storage)
+ continue;
+
/* Add one for the terminating NUL character for a non-array, and
* 4 for the "[0]" and the NUL for an array.
*/
if (!has_ubo)
break;
- for (i = 0; i < shProg->NumBufferInterfaceBlocks; i++) {
+ for (i = 0; i < shProg->NumUniformBlocks; i++) {
/* Add one for the terminating NUL character.
*/
- const GLint len = strlen(shProg->BufferInterfaceBlocks[i].Name) + 1;
+ const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;
if (len > max_len)
max_len = len;
/* free old shader source string and install new one */
free((void *)sh->Source);
sh->Source = source;
- sh->CompileStatus = GL_FALSE;
#ifdef DEBUG
sh->SourceChecksum = _mesa_str_checksum(sh->Source);
#endif
/**
* Compile a shader.
*/
-static void
-compile_shader(struct gl_context *ctx, GLuint shaderObj)
+void
+_mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh)
{
- struct gl_shader *sh;
-
- sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
if (!sh)
return;
/**
* Link a program's shaders.
*/
-static void
-link_program(struct gl_context *ctx, GLuint program)
+void
+_mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
{
- struct gl_shader_program *shProg;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
if (!shProg)
return;
if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL))
shProg = NULL;
+ if (shProg)
+ _mesa_shader_program_init_subroutine_defaults(shProg);
+
if (*target != shProg) {
/* Program is current, flush it */
if (shTarget == ctx->_Shader) {
use_shader_program(ctx, i, shProg, &ctx->Shader);
_mesa_active_program(ctx, shProg, "glUseProgram");
- _mesa_shader_program_init_subroutine_defaults(shProg);
if (ctx->Driver.UseProgram)
ctx->Driver.UseProgram(ctx, shProg);
}
void GLAPIENTRY
-_mesa_CompileShader(GLhandleARB shaderObj)
+_mesa_CompileShader(GLuint shaderObj)
{
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
- compile_shader(ctx, shaderObj);
+ _mesa_compile_shader(ctx, _mesa_lookup_shader_err(ctx, shaderObj,
+ "glCompileShader"));
}
{
if (MESA_VERBOSE & VERBOSE_API) {
GET_CURRENT_CONTEXT(ctx);
- _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj);
+ _mesa_debug(ctx, "glDeleteObjectARB(%lu)\n", (unsigned long)obj);
}
if (obj) {
void GLAPIENTRY
-_mesa_GetShaderSource(GLhandleARB shader, GLsizei maxLength,
- GLsizei *length, GLcharARB *sourceOut)
+_mesa_GetShaderSource(GLuint shader, GLsizei maxLength,
+ GLsizei *length, GLchar *sourceOut)
{
GET_CURRENT_CONTEXT(ctx);
get_shader_source(ctx, shader, maxLength, length, sourceOut);
void GLAPIENTRY
-_mesa_LinkProgram(GLhandleARB programObj)
+_mesa_LinkProgram(GLuint programObj)
{
GET_CURRENT_CONTEXT(ctx);
- link_program(ctx, programObj);
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glLinkProgram %u\n", programObj);
+ _mesa_link_program(ctx, _mesa_lookup_shader_program_err(ctx, programObj,
+ "glLinkProgram"));
}
#if defined(HAVE_SHA1)
* and pass it to _mesa_shader_source().
*/
void GLAPIENTRY
-_mesa_ShaderSource(GLhandleARB shaderObj, GLsizei count,
- const GLcharARB * const * string, const GLint * length)
+_mesa_ShaderSource(GLuint shaderObj, GLsizei count,
+ const GLchar * const * string, const GLint * length)
{
GET_CURRENT_CONTEXT(ctx);
GLint *offsets;
void GLAPIENTRY
-_mesa_UseProgram(GLhandleARB program)
+_mesa_UseProgram(GLuint program)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg;
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glUseProgram %u\n", program);
+
if (_mesa_is_xfb_active_and_unpaused(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glUseProgram(transform feedback active)");
void GLAPIENTRY
-_mesa_ValidateProgram(GLhandleARB program)
+_mesa_ValidateProgram(GLuint program)
{
GET_CURRENT_CONTEXT(ctx);
validate_program(ctx, program);
{
switch (type) {
case MESA_SHADER_VERTEX:
- dst->UsesClipDistanceOut = src->Vert.UsesClipDistance;
+ dst->ClipDistanceArraySize = src->Vert.ClipDistanceArraySize;
+ dst->CullDistanceArraySize = src->Vert.CullDistanceArraySize;
break;
case MESA_SHADER_TESS_CTRL: {
struct gl_tess_ctrl_program *dst_tcp =
dst_tep->Spacing = src->TessEval.Spacing;
dst_tep->VertexOrder = src->TessEval.VertexOrder;
dst_tep->PointMode = src->TessEval.PointMode;
- dst->UsesClipDistanceOut = src->TessEval.UsesClipDistance;
+ dst->ClipDistanceArraySize = src->TessEval.ClipDistanceArraySize;
+ dst->CullDistanceArraySize = src->TessEval.CullDistanceArraySize;
break;
}
case MESA_SHADER_GEOMETRY: {
dst_gp->Invocations = src->Geom.Invocations;
dst_gp->InputType = src->Geom.InputType;
dst_gp->OutputType = src->Geom.OutputType;
- dst->UsesClipDistanceOut = src->Geom.UsesClipDistance;
+ dst->ClipDistanceArraySize = src->Geom.ClipDistanceArraySize;
+ dst->CullDistanceArraySize = src->Geom.CullDistanceArraySize;
dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;
dst_gp->UsesStreams = src->Geom.UsesStreams;
break;
int i;
for (i = 0; i < 3; i++)
dst_cp->LocalSize[i] = src->Comp.LocalSize[i];
+ dst_cp->SharedSize = src->Comp.SharedSize;
break;
}
default:
}
if (shader) {
- _mesa_ShaderSource(shader, count, strings, NULL);
+ struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
- compile_shader(ctx, shader);
+ _mesa_ShaderSource(shader, count, strings, NULL);
+ _mesa_compile_shader(ctx, sh);
program = create_shader_program(ctx);
if (program) {
struct gl_shader_program *shProg;
- struct gl_shader *sh;
GLint compiled = GL_FALSE;
shProg = _mesa_lookup_shader_program(ctx, program);
- sh = _mesa_lookup_shader(ctx, shader);
shProg->SeparateShader = GL_TRUE;
get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
if (compiled) {
attach_shader(ctx, program, shader);
- link_program(ctx, program);
+ _mesa_link_program(ctx, shProg);
detach_shader(ctx, program, shader);
#if 0
resource_type = _mesa_shader_stage_to_subroutine(stage);
res = _mesa_program_resource_find_name(shProg, resource_type, name, NULL);
if (!res) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return -1;
}
return;
}
+ if (index >= sh->NumSubroutineUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name);
+ return;
+ }
+
switch (pname) {
case GL_NUM_COMPATIBLE_SUBROUTINES: {
res = _mesa_program_resource_find_index(shProg, resource_type, index);
res = _mesa_program_resource_find_index(shProg, resource_type, index);
if (res) {
values[0] = strlen(_mesa_program_resource_name(res)) + 1
- + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);;
+ + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
}
break;
default:
i = 0;
do {
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+ if (uni == NULL) {
+ i++;
+ continue;
+ }
+
int uni_count = uni->array_elements ? uni->array_elements : 1;
int j, k;
i = 0;
do {
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+ if (uni == NULL) {
+ i++;
+ continue;
+ }
+
int uni_count = uni->array_elements ? uni->array_elements : 1;
memcpy(&uni->storage[0], &indices[i],
sizeof(GLuint) * uni_count);
- uni->initialized = true;
_mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
i += uni_count;
} while(i < count);
values[0] = sh->NumSubroutineUniformRemapTable;
break;
case GL_ACTIVE_SUBROUTINE_UNIFORMS:
- values[0] = sh->NumSubroutineUniformTypes;
+ values[0] = sh->NumSubroutineUniforms;
break;
case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
{
for (j = 0; j < uni_count; j++)
memcpy(&uni->storage[j], &val, sizeof(int));
- uni->initialized = true;
+
_mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
}
}