*/
#include <stdlib.h>
+#include <inttypes.h> /* for PRIx64 macro */
#include "main/core.h"
#include "main/context.h"
#include "compiler/glsl/ir_uniform.h"
#include "compiler/glsl/glsl_parser_extras.h"
#include "compiler/glsl/program.h"
-#include "program/hash_table.h"
#include "util/bitscan.h"
}
static struct gl_uniform_storage *
-validate_uniform_parameters(struct gl_context *ctx,
- struct gl_shader_program *shProg,
- GLint location, GLsizei count,
- unsigned *array_index,
- const char *caller)
+validate_uniform_parameters(GLint location, GLsizei count,
+ unsigned *array_index,
+ struct gl_context *ctx,
+ struct gl_shader_program *shProg,
+ const char *caller)
{
if (shProg == NULL) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
/* Check that the given location is in bounds of uniform remap table.
* Unlinked programs will have NumUniformRemapTable == 0, so we can take
- * the shProg->LinkStatus check out of the main path.
+ * the shProg->data->LinkStatus check out of the main path.
*/
if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) {
- if (!shProg->LinkStatus)
+ if (!shProg->data->LinkStatus)
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
caller);
else
}
if (location == -1) {
- if (!shProg->LinkStatus)
+ if (!shProg->data->LinkStatus)
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
caller);
unsigned offset;
struct gl_uniform_storage *const uni =
- validate_uniform_parameters(ctx, shProg, location, 1,
- &offset, "glGetUniform");
+ validate_uniform_parameters(location, 1, &offset,
+ ctx, shProg, "glGetUniform");
if (uni == NULL) {
/* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1
* spec says:
&uni->storage[offset * elements * dmul];
assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
- returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE);
+ returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE ||
+ returnType == GLSL_TYPE_UINT64 || returnType == GLSL_TYPE_INT64);
/* doubles have a different size than the other 3 types */
unsigned bytes = sizeof(src[0]) * elements * rmul;
&&
(uni->type->base_type == GLSL_TYPE_INT
|| uni->type->base_type == GLSL_TYPE_UINT
- || uni->type->base_type == GLSL_TYPE_SAMPLER
- || uni->type->base_type == GLSL_TYPE_IMAGE))) {
+ || uni->type->is_sampler()
+ || uni->type->is_image()))
+ || ((returnType == GLSL_TYPE_UINT64 ||
+ returnType == GLSL_TYPE_INT64 ) &&
+ (uni->type->base_type == GLSL_TYPE_UINT64 ||
+ uni->type->base_type == GLSL_TYPE_INT64))) {
memcpy(paramsOut, src, bytes);
} else {
union gl_constant_value *const dst =
dst[didx].f = tmp;
break;
}
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &src[sidx].u, sizeof(tmp));
+ dst[didx].f = tmp;
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &src[sidx].i, sizeof(tmp));
+ dst[didx].f = tmp;
+ break;
+ }
default:
assert(!"Should not get here.");
break;
memcpy(&dst[didx].f, &tmp, sizeof(tmp));
break;
}
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmpu;
+ double tmp;
+ memcpy(&tmpu, &src[sidx].u, sizeof(tmpu));
+ tmp = tmpu;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ int64_t tmpi;
+ double tmp;
+ memcpy(&tmpi, &src[sidx].i, sizeof(tmpi));
+ tmp = tmpi;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
default:
assert(!"Should not get here.");
break;
dst[didx].i = IROUNDD(tmp);
break;
}
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &src[sidx].u, sizeof(tmp));
+ dst[didx].i = tmp;
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ int64_t tmp;
+ memcpy(&tmp, &src[sidx].i, sizeof(tmp));
+ dst[didx].i = tmp;
+ break;
+ }
default:
assert(!"Should not get here.");
break;
}
break;
-
+ case GLSL_TYPE_INT64:
+ case GLSL_TYPE_UINT64:
+ switch (uni->type->base_type) {
+ case GLSL_TYPE_UINT: {
+ uint64_t tmp = src[sidx].u;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE: {
+ int64_t tmp = src[sidx].i;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_BOOL: {
+ int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_FLOAT: {
+ int64_t tmp = src[sidx].f;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ break;
default:
assert(!"Should not get here.");
break;
case GLSL_TYPE_INT:
printf("%d ", v[i].i);
break;
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
+ printf("%" PRIu64 " ", tmp);
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ int64_t tmp;
+ memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
+ printf("%" PRId64 " ", tmp);
+ break;
+ }
case GLSL_TYPE_FLOAT:
printf("%g ", v[i].f);
break;
return "float";
case GLSL_TYPE_DOUBLE:
return "double";
+ case GLSL_TYPE_UINT64:
+ return "uint64";
+ case GLSL_TYPE_INT64:
+ return "int64";
case GLSL_TYPE_BOOL:
return "bool";
case GLSL_TYPE_SAMPLER:
* Called via glUniform*() functions.
*/
extern "C" void
-_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
- GLint location, GLsizei count,
- const GLvoid *values,
- enum glsl_base_type basicType,
- unsigned src_components)
+_mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
+ struct gl_context *ctx, struct gl_shader_program *shProg,
+ enum glsl_base_type basicType, unsigned src_components)
{
unsigned offset;
int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1;
struct gl_uniform_storage *const uni =
- validate_uniform_parameters(ctx, shProg, location, count,
- &offset, "glUniform");
+ validate_uniform_parameters(location, count, &offset,
+ ctx, shProg, "glUniform");
if (uni == NULL)
return;
for (int i = 0; i < MESA_SHADER_STAGES; i++) {
struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
- /* If the shader stage doesn't use the sampler uniform, skip this.
- */
- if (sh == NULL || !uni->opaque[i].active)
+ /* If the shader stage doesn't use the sampler uniform, skip this. */
+ if (!uni->opaque[i].active)
continue;
+ bool changed = false;
for (int j = 0; j < count; j++) {
- sh->SamplerUnits[uni->opaque[i].index + offset + j] =
- ((unsigned *) values)[j];
+ unsigned unit = uni->opaque[i].index + offset + j;
+ if (sh->Program->SamplerUnits[unit] != ((unsigned *) values)[j]) {
+ sh->Program->SamplerUnits[unit] = ((unsigned *) values)[j];
+ changed = true;
+ }
}
- struct gl_program *const prog = sh->Program;
-
- assert(sizeof(prog->SamplerUnits) == sizeof(sh->SamplerUnits));
-
- /* Determine if any of the samplers used by this shader stage have
- * been modified.
- */
- bool changed = false;
- GLbitfield mask = sh->active_samplers;
- while (mask) {
- const int j = u_bit_scan(&mask);
- if (prog->SamplerUnits[j] != sh->SamplerUnits[j]) {
- changed = true;
- break;
- }
- }
-
if (changed) {
if (!flushed) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
flushed = true;
}
+ struct gl_program *const prog = sh->Program;
_mesa_update_shader_textures_used(shProg, prog);
if (ctx->Driver.SamplerUniformChange)
ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
for (int j = 0; j < count; j++)
- sh->ImageUnits[uni->opaque[i].index + offset + j] =
+ sh->Program->sh.ImageUnits[uni->opaque[i].index + offset + j] =
((GLint *) values)[j];
}
}
* Note: cols=2, rows=4 ==> array[2] of vec4
*/
extern "C" void
-_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
- GLuint cols, GLuint rows,
- GLint location, GLsizei count,
- GLboolean transpose,
- const GLvoid *values, enum glsl_base_type basicType)
+_mesa_uniform_matrix(GLint location, GLsizei count,
+ GLboolean transpose, const void *values,
+ struct gl_context *ctx, struct gl_shader_program *shProg,
+ GLuint cols, GLuint rows, enum glsl_base_type basicType)
{
unsigned offset;
- unsigned vectors;
- unsigned components;
- unsigned elements;
- int size_mul;
struct gl_uniform_storage *const uni =
- validate_uniform_parameters(ctx, shProg, location, count,
- &offset, "glUniformMatrix");
+ validate_uniform_parameters(location, count, &offset,
+ ctx, shProg, "glUniformMatrix");
if (uni == NULL)
return;
}
assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE);
- size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
+ const unsigned size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
assert(!uni->type->is_sampler());
- vectors = uni->type->matrix_columns;
- components = uni->type->vector_elements;
+ const unsigned vectors = uni->type->matrix_columns;
+ const unsigned components = uni->type->vector_elements;
/* Verify that the types are compatible. This is greatly simplified for
* matrices because they can only have a float base type.
/* Store the data in the "actual type" backing storage for the uniform.
*/
- elements = components * vectors;
+ const unsigned elements = components * vectors;
if (!transpose) {
memcpy(&uni->storage[size_mul * elements * offset], values,
char *errMsg, size_t errMsgLength)
{
/* Shader does not have samplers. */
- if (shProg->NumUniformStorage == 0)
+ if (shProg->data->NumUniformStorage == 0)
return true;
if (!shProg->SamplersValidated) {
GLbitfield mask;
GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
- struct gl_linked_shader *shader;
unsigned active_samplers = 0;
- const struct gl_shader_program **shProg =
- (const struct gl_shader_program **) pipeline->CurrentProgram;
+ const struct gl_program **prog =
+ (const struct gl_program **) pipeline->CurrentProgram;
memset(TexturesUsed, 0, sizeof(TexturesUsed));
for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
- if (!shProg[idx])
- continue;
-
- shader = shProg[idx]->_LinkedShaders[idx];
- if (!shader || !shader->Program)
+ if (!prog[idx])
continue;
- mask = shader->Program->SamplersUsed;
+ mask = prog[idx]->SamplersUsed;
while (mask) {
const int s = u_bit_scan(&mask);
- GLuint unit = shader->SamplerUnits[s];
- GLuint tgt = shader->SamplerTargets[s];
+ GLuint unit = prog[idx]->SamplerUnits[s];
+ GLuint tgt = prog[idx]->sh.SamplerTargets[s];
/* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
* great job of eliminating unused uniforms currently so for now
ralloc_asprintf(pipeline,
"Program %d: "
"Texture unit %d is accessed with 2 different types",
- shProg[idx]->Name, unit);
+ prog[idx]->Id, unit);
return false;
}
TexturesUsed[unit] |= (1 << tgt);
}
- active_samplers += shader->num_samplers;
+ active_samplers += prog[idx]->info.num_textures;
}
if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {