#include "main/context.h"
#include "ir.h"
#include "../glsl/program.h"
+#include "../glsl/ir_uniform.h"
extern "C" {
#include "main/image.h"
}
/**
+ * Propagate some values from uniform backing storage to driver storage
+ *
+ * Values propagated from uniform backing storage to driver storage
+ * have all format / type conversions previously requested by the
+ * driver applied. This function is most often called by the
+ * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
+ * etc.
+ *
+ * \param uni Uniform whose data is to be propagated to driver storage
+ * \param array_index If \c uni is an array, this is the element of
+ * the array to be propagated.
+ * \param count Number of array elements to propagate.
+ */
+extern "C" void
+_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
+ unsigned array_index,
+ unsigned count)
+{
+ unsigned i;
+
+ /* vector_elements and matrix_columns can be 0 for samplers.
+ */
+ const unsigned components = MAX2(1, uni->type->vector_elements);
+ const unsigned vectors = MAX2(1, uni->type->matrix_columns);
+
+ /* Store the data in the driver's requested type in the driver's storage
+ * areas.
+ */
+ unsigned src_vector_byte_stride = components * 4;
+
+ for (i = 0; i < uni->num_driver_storage; i++) {
+ struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
+ uint8_t *dst = (uint8_t *) store->data;
+ const unsigned extra_stride =
+ store->element_stride - (vectors * store->vector_stride);
+ const uint8_t *src =
+ (uint8_t *) (&uni->storage[array_index * (components * vectors)].i);
+
+#if 0
+ printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
+ "extra_stride=%u\n",
+ __func__, dst, array_index, components,
+ vectors, count, store->vector_stride, extra_stride);
+#endif
+
+ dst += array_index * store->element_stride;
+
+ switch (store->format) {
+ case uniform_native:
+ case uniform_bool_int_0_1: {
+ unsigned j;
+ unsigned v;
+
+ for (j = 0; j < count; j++) {
+ for (v = 0; v < vectors; v++) {
+ memcpy(dst, src, src_vector_byte_stride);
+ src += src_vector_byte_stride;
+ dst += store->vector_stride;
+ }
+
+ dst += extra_stride;
+ }
+ break;
+ }
+
+ case uniform_int_float:
+ case uniform_bool_float: {
+ const int *isrc = (const int *) src;
+ unsigned j;
+ unsigned v;
+ unsigned c;
+
+ for (j = 0; j < count; j++) {
+ for (v = 0; v < vectors; v++) {
+ for (c = 0; c < components; c++) {
+ ((float *) dst)[c] = (float) *isrc;
+ isrc++;
+ }
+
+ dst += store->vector_stride;
+ }
+
+ dst += extra_stride;
+ }
+ break;
+ }
+
+ case uniform_bool_int_0_not0: {
+ const int *isrc = (const int *) src;
+ unsigned j;
+ unsigned v;
+ unsigned c;
+
+ for (j = 0; j < count; j++) {
+ for (v = 0; v < vectors; v++) {
+ for (c = 0; c < components; c++) {
+ ((int *) dst)[c] = *isrc == 0 ? 0 : ~0;
+ isrc++;
+ }
+
+ dst += store->vector_stride;
+ }
+
+ dst += extra_stride;
+ }
+ break;
+ }
+
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ }
+}
+
+/**
* Called via glUniform*() functions.
*/
extern "C" void