#include "main/shaderobj.h"
#include "main/uniforms.h"
#include "main/enums.h"
-#include "ir_uniform.h"
-#include "glsl_types.h"
+#include "compiler/glsl/ir_uniform.h"
+#include "compiler/glsl_types.h"
#include "program/program.h"
+#include "util/bitscan.h"
/**
* Update the vertex/fragment program's TexturesUsed array.
_mesa_update_shader_textures_used(struct gl_shader_program *shProg,
struct gl_program *prog)
{
- GLuint s;
- struct gl_shader *shader =
+ GLbitfield mask = prog->SamplersUsed;
+ struct gl_linked_shader *shader =
shProg->_LinkedShaders[_mesa_program_enum_to_shader_stage(prog->Target)];
assert(shader);
shProg->SamplersValidated = GL_TRUE;
- for (s = 0; s < MAX_SAMPLERS; s++) {
- if (prog->SamplersUsed & (1 << s)) {
- GLuint unit = shader->SamplerUnits[s];
- GLuint tgt = shader->SamplerTargets[s];
- assert(unit < ARRAY_SIZE(prog->TexturesUsed));
- assert(tgt < NUM_TEXTURE_TARGETS);
-
- /* The types of the samplers associated with a particular texture
- * unit must be an exact match. Page 74 (page 89 of the PDF) of the
- * OpenGL 3.3 core spec says:
- *
- * "It is not allowed to have variables of different sampler
- * types pointing to the same texture image unit within a program
- * object."
- */
- if (prog->TexturesUsed[unit] & ~(1 << tgt))
- shProg->SamplersValidated = GL_FALSE;
-
- prog->TexturesUsed[unit] |= (1 << tgt);
- }
+ while (mask) {
+ const int s = u_bit_scan(&mask);
+ GLuint unit = shader->SamplerUnits[s];
+ GLuint tgt = shader->SamplerTargets[s];
+ assert(unit < ARRAY_SIZE(prog->TexturesUsed));
+ assert(tgt < NUM_TEXTURE_TARGETS);
+
+ /* The types of the samplers associated with a particular texture
+ * unit must be an exact match. Page 74 (page 89 of the PDF) of the
+ * OpenGL 3.3 core spec says:
+ *
+ * "It is not allowed to have variables of different sampler
+ * types pointing to the same texture image unit within a program
+ * object."
+ */
+ if (prog->TexturesUsed[unit] & ~(1 << tgt))
+ shProg->SamplersValidated = GL_FALSE;
+
+ prog->TexturesUsed[unit] |= (1 << tgt);
}
}
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 2, 2, location, count, transpose, value, GL_FLOAT);
+ 2, 2, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 3, 3, location, count, transpose, value, GL_FLOAT);
+ 3, 3, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 4, 4, location, count, transpose, value, GL_FLOAT);
+ 4, 4, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
/** Same as above with direct state access **/
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix2fv");
- _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix3fv");
- _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix4fv");
- _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 2, 3, location, count, transpose, value, GL_FLOAT);
+ 2, 3, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 3, 2, location, count, transpose, value, GL_FLOAT);
+ 3, 2, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 2, 4, location, count, transpose, value, GL_FLOAT);
+ 2, 4, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 4, 2, location, count, transpose, value, GL_FLOAT);
+ 4, 2, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 3, 4, location, count, transpose, value, GL_FLOAT);
+ 3, 4, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 4, 3, location, count, transpose, value, GL_FLOAT);
+ 4, 3, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
/** Same as above with direct state access **/
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix2x3fv");
- _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix3x2fv");
- _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix2x4fv");
- _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix4x2fv");
- _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix3x4fv");
- _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix4x3fv");
- _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GL_FLOAT);
+ _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GLSL_TYPE_FLOAT);
}
if (shProg->UniformBlocks[uniformBlockIndex].Binding !=
uniformBlockBinding) {
- int i;
FLUSH_VERTICES(ctx, 0);
ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;
shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding;
+ }
+}
- for (i = 0; i < MESA_SHADER_STAGES; i++) {
- int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex];
+void GLAPIENTRY
+_mesa_ShaderStorageBlockBinding(GLuint program,
+ GLuint shaderStorageBlockIndex,
+ GLuint shaderStorageBlockBinding)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg;
- if (stage_index != -1) {
- struct gl_shader *sh = shProg->_LinkedShaders[i];
- sh->UniformBlocks[stage_index].Binding = uniformBlockBinding;
- }
- }
+ if (!ctx->Extensions.ARB_shader_storage_buffer_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderStorageBlockBinding");
+ return;
}
-}
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glShaderStorageBlockBinding");
+ if (!shProg)
+ return;
+
+ if (shaderStorageBlockIndex >= shProg->NumShaderStorageBlocks) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glShaderStorageBlockBinding(block index %u >= %u)",
+ shaderStorageBlockIndex, shProg->NumShaderStorageBlocks);
+ return;
+ }
+
+ if (shaderStorageBlockBinding >= ctx->Const.MaxShaderStorageBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glShaderStorageBlockBinding(block binding %u >= %u)",
+ shaderStorageBlockBinding,
+ ctx->Const.MaxShaderStorageBufferBindings);
+ return;
+ }
+
+ if (shProg->ShaderStorageBlocks[shaderStorageBlockIndex].Binding !=
+ shaderStorageBlockBinding) {
+
+ FLUSH_VERTICES(ctx, 0);
+ ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
+
+ shProg->ShaderStorageBlocks[shaderStorageBlockIndex].Binding =
+ shaderStorageBlockBinding;
+ }
+}
/**
* Generic program resource property query.
GL_REFERENCED_BY_FRAGMENT_SHADER, params,
caller);
return;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER:
+ _mesa_program_resource_prop(shProg, res, index,
+ GL_REFERENCED_BY_COMPUTE_SHADER, params,
+ caller);
+ return;
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(pname 0x%x (%s))", caller, pname,
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 2, 2, location, count, transpose, value, GL_DOUBLE);
+ 2, 2, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 3, 3, location, count, transpose, value, GL_DOUBLE);
+ 3, 3, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 4, 4, location, count, transpose, value, GL_DOUBLE);
+ 4, 4, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 2, 3, location, count, transpose, value, GL_DOUBLE);
+ 2, 3, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 3, 2, location, count, transpose, value, GL_DOUBLE);
+ 3, 2, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 2, 4, location, count, transpose, value, GL_DOUBLE);
+ 2, 4, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 4, 2, location, count, transpose, value, GL_DOUBLE);
+ 4, 2, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 3, 4, location, count, transpose, value, GL_DOUBLE);
+ 3, 4, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
{
GET_CURRENT_CONTEXT(ctx);
_mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
- 4, 3, location, count, transpose, value, GL_DOUBLE);
+ 4, 3, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix2dv");
- _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix3dv");
- _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix4dv");
- _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix2x3dv");
- _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix3x2dv");
- _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix2x4dv");
- _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix4x2dv");
- _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix3x4dv");
- _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}
void GLAPIENTRY
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glProgramUniformMatrix4x3dv");
- _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GL_DOUBLE);
+ _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GLSL_TYPE_DOUBLE);
}