[Mesa-dev] [PATCH 05/17] mesa: add packing support for setting uniforms
Timothy Arceri
tarceri at itsqueeze.com
Sun Jun 25 01:31:37 UTC 2017
---
src/mesa/main/uniform_query.cpp | 73 ++++++++++++++++++++++++++++++-----------
1 file changed, 54 insertions(+), 19 deletions(-)
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index b13f506..0b22683 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -329,22 +329,28 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
!uni->is_bindless) {
/* Non-bindless samplers/images are represented using unsigned integer
* 32-bit, while bindless handles are 64-bit.
*/
dmul = 1;
}
/* Calculate the source base address *BEFORE* modifying elements to
* account for the size of the user's buffer.
*/
- const union gl_constant_value *const src =
- &uni->storage[offset * elements * dmul];
+ const union gl_constant_value *src;
+ if (ctx->Const.PackedDriverUniformStorage &&
+ (uni->is_bindless || !uni->type->contains_opaque())) {
+ src = (gl_constant_value *) uni->driver_storage[0].data +
+ (offset * elements * dmul);
+ } else {
+ src = &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_UINT64 || returnType == GLSL_TYPE_INT64);
/* doubles have a different size than the other 3 types */
unsigned bytes = sizeof(src[0]) * elements * rmul;
if (bufSize < 0 || bytes > (unsigned) bufSize) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetnUniform*vARB(out of bounds: bufSize is %d,"
@@ -1021,42 +1027,43 @@ _mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
assert(index < MESA_SHADER_STAGES);
new_driver_state |= ctx->DriverFlags.NewShaderConstants[index];
}
FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS);
ctx->NewDriverState |= new_driver_state;
}
static void
-copy_uniforms_to_storage(struct gl_uniform_storage *uni,
+copy_uniforms_to_storage(gl_constant_value *storage,
+ struct gl_uniform_storage *uni,
struct gl_context *ctx, GLsizei count,
const GLvoid *values, const int size_mul,
const unsigned offset, const unsigned components,
enum glsl_base_type basicType)
{
if (!uni->type->is_boolean() && !uni->is_bindless) {
- memcpy(&uni->storage[size_mul * components * offset], values,
- sizeof(uni->storage[0]) * components * count * size_mul);
+ memcpy(storage, values,
+ sizeof(storage[0]) * components * count * size_mul);
} else if (uni->is_bindless) {
const union gl_constant_value *src =
(const union gl_constant_value *) values;
- GLuint64 *dst = (GLuint64 *)&uni->storage[components * offset].i;
+ GLuint64 *dst = (GLuint64 *)&storage->i;
const unsigned elems = components * count;
for (unsigned i = 0; i < elems; i++) {
dst[i] = src[i].i;
}
} else {
const union gl_constant_value *src =
(const union gl_constant_value *) values;
- union gl_constant_value *dst = &uni->storage[components * offset];
+ union gl_constant_value *dst = storage;
const unsigned elems = components * count;
for (unsigned i = 0; i < elems; i++) {
if (basicType == GLSL_TYPE_FLOAT) {
dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
} else {
dst[i].i = src[i].i != 0 ? ctx->Const.UniformBooleanTrue : 0;
}
}
}
@@ -1118,24 +1125,37 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
/* We check samplers for changes and flush if needed in the sampler
* handling code further down, so just skip them here.
*/
if (!uni->type->is_sampler()) {
_mesa_flush_vertices_for_uniforms(ctx, uni);
}
/* Store the data in the "actual type" backing storage for the uniform.
*/
- copy_uniforms_to_storage(uni, ctx, count, values, size_mul, offset,
- components, basicType);
+ gl_constant_value *storage;
+ if (ctx->Const.PackedDriverUniformStorage &&
+ (uni->is_bindless || !uni->type->contains_opaque())) {
+ for (unsigned s = 0; s < uni->num_driver_storage; s++) {
+ storage = (gl_constant_value *)
+ uni->driver_storage[s].data + (size_mul * offset * components);
+
+ copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
+ offset, components, basicType);
+ }
+ } else {
+ storage = &uni->storage[size_mul * components * offset];
+ copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
+ offset, components, basicType);
- _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
+ _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
+ }
/* If the uniform is a sampler, do the extra magic necessary to propagate
* the changes through.
*/
if (uni->type->is_sampler()) {
bool flushed = false;
shProg->SamplersValidated = GL_TRUE;
for (int i = 0; i < MESA_SHADER_STAGES; i++) {
@@ -1213,53 +1233,53 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
}
}
}
ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
}
}
static void
-copy_uniform_matrix_to_storage(struct gl_uniform_storage *const uni,
+copy_uniform_matrix_to_storage(gl_constant_value *storage,
GLsizei count, const void *values,
const unsigned size_mul, const unsigned offset,
const unsigned components,
const unsigned vectors, bool transpose,
unsigned cols, unsigned rows,
enum glsl_base_type basicType)
{
const unsigned elements = components * vectors;
if (!transpose) {
- memcpy(&uni->storage[size_mul * elements * offset], values,
- sizeof(uni->storage[0]) * elements * count * size_mul);
+ memcpy(storage, values,
+ sizeof(storage[0]) * elements * count * size_mul);
} else if (basicType == GLSL_TYPE_FLOAT) {
/* Copy and transpose the matrix.
*/
const float *src = (const float *)values;
- float *dst = &uni->storage[elements * offset].f;
+ float *dst = &storage->f;
for (int i = 0; i < count; i++) {
for (unsigned r = 0; r < rows; r++) {
for (unsigned c = 0; c < cols; c++) {
dst[(c * components) + r] = src[c + (r * vectors)];
}
}
dst += elements;
src += elements;
}
} else {
assert(basicType == GLSL_TYPE_DOUBLE);
const double *src = (const double *)values;
- double *dst = (double *)&uni->storage[elements * offset].f;
+ double *dst = (double *)&storage->f;
for (int i = 0; i < count; i++) {
for (unsigned r = 0; r < rows; r++) {
for (unsigned c = 0; c < cols; c++) {
dst[(c * components) + r] = src[c + (r * vectors)];
}
}
dst += elements;
src += elements;
@@ -1360,25 +1380,40 @@ _mesa_uniform_matrix(GLint location, GLsizei count,
* will have already generated an error.
*/
if (uni->array_elements != 0) {
count = MIN2(count, (int) (uni->array_elements - offset));
}
_mesa_flush_vertices_for_uniforms(ctx, uni);
/* Store the data in the "actual type" backing storage for the uniform.
*/
- copy_uniform_matrix_to_storage(uni, count, values, size_mul, offset,
- components, vectors, transpose, cols, rows,
- basicType);
+ gl_constant_value *storage;
+ const unsigned elements = components * vectors;
+ if (ctx->Const.PackedDriverUniformStorage) {
+ for (unsigned s = 0; s < uni->num_driver_storage; s++) {
+ storage = (gl_constant_value *)
+ uni->driver_storage[s].data + (size_mul * offset * elements);
+
+ copy_uniform_matrix_to_storage(storage, count, values, size_mul,
+ offset, components, vectors,
+ transpose, cols, rows, basicType);
+ }
+ } else {
+ storage = &uni->storage[size_mul * elements * offset];
+ copy_uniform_matrix_to_storage(storage, count, values, size_mul, offset,
+ components, vectors, transpose, cols,
+ rows, basicType);
- _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
+ if (uni->array_elements != 0)
+ _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
+ }
}
static void
update_bound_bindless_sampler_flag(struct gl_program *prog)
{
unsigned i;
if (likely(!prog->sh.HasBoundBindlessSampler))
return;
--
2.9.4
More information about the mesa-dev
mailing list