/** * Determine the number of rows and columns occupied by a uniform * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4), * the number of rows = 1 and cols = number of elements in the vector. */ static void get_uniform_rows_cols(const struct gl_program_parameter *p, GLint *rows, GLint *cols) { get_matrix_dims(p->DataType, rows, cols); if (*rows == 0 && *cols == 0) { /* not a matrix type, probably a float or vector */ if (p->Size <= 4) { *rows = 1; *cols = p->Size; } else { *rows = p->Size / 4 + 1; if (p->Size % 4 == 0) *cols = 4; else *cols = p->Size % 4; } } }
/** * Set a matrix-valued program parameter. */ static void set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, GLuint index, GLuint offset, GLuint count, GLuint rows, GLuint cols, GLboolean transpose, const GLfloat *values) { GLuint mat, row, col; GLuint src = 0; const struct gl_program_parameter * param = &program->Parameters->Parameters[index]; const GLuint slots = (param->Size + 3) / 4; const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType); GLint nr, nc; /* check that the number of rows, columns is correct */ get_matrix_dims(param->DataType, &nr, &nc); if (rows != nr || cols != nc) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(matrix size mismatch)"); return; } if ((GLint) param->Size <= typeSize) { /* non-array: count must be at most one; count == 0 is handled by the loop below */ if (count > 1) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(uniform is not an array)"); return; } } /* * Note: the _columns_ of a matrix are stored in program registers, not * the rows. So, the loops below look a little funny. * XXX could optimize this a bit... */ /* loop over matrices */ for (mat = 0; mat < count; mat++) { /* each matrix: */ for (col = 0; col < cols; col++) { GLfloat *v; if (offset >= slots) { /* Ignore writes beyond the end of (the used part of) an array */ return; } v = program->Parameters->ParameterValues[index + offset]; for (row = 0; row < rows; row++) { if (transpose) { v[row] = values[src + row * cols + col]; } else { v[row] = values[src + col * rows + row]; } } offset++; } src += rows * cols; /* next matrix */ } }
/** * Called via glGetUniformLocation(). * * The return value will encode two values, the uniform location and an * offset (used for arrays, structs). */ GLint _mesa_get_uniform_location(GLcontext *ctx, struct gl_shader_program *shProg, const GLchar *name) { GLint offset = 0, location = -1; if (shProg->LinkStatus == GL_FALSE) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)"); return -1; } /* XXX we should return -1 if the uniform was declared, but not * actually used. */ /* XXX we need to be able to parse uniform names for structs and arrays * such as: * mymatrix[1] * mystruct.field1 */ { /* handle 1-dimension arrays here... */ char *c = strchr(name, '['); if (c) { /* truncate name at [ */ const GLint len = c - name; GLchar *newName = malloc(len + 1); if (!newName) return -1; /* out of mem */ memcpy(newName, name, len); newName[len] = 0; location = _mesa_lookup_uniform(shProg->Uniforms, newName); if (location >= 0) { const GLint element = atoi(c + 1); if (element > 0) { /* get type of the uniform array element */ struct gl_program_parameter *p; p = get_uniform_parameter(shProg, location); if (p) { GLint rows, cols; get_matrix_dims(p->DataType, &rows, &cols); if (rows < 1) rows = 1; offset = element * rows; } } } free(newName); } } if (location < 0) { location = _mesa_lookup_uniform(shProg->Uniforms, name); } if (location >= 0) { merge_location_offset(&location, offset); } return location; }
int display(list<string>::iterator &ifname, bool signd, bool load, list<string> *mats) { //cout << "displaying " << ifname->c_str() << endl; // conf mode if (conf) return display_net<T>(ifname, signd, load, mats); // mat mode if (is_matrix(ifname->c_str())) { idxdim d = get_matrix_dims(ifname->c_str()); if (interleaved) d.shift_dim(0, 2); if (save_individually || print || !(d.order() == 2 || (d.order() == 3 && (d.dim(2) == 1 || d.dim(2) == 3)))) { // this is probably not an image, just display info and print matrix string type; get_matrix_type(ifname->c_str(), type); idx<T> m = load_matrix<T>(ifname->c_str()); cout << "Matrix " << ifname->c_str() << " is of type " << type << " with dimensions " << d << " (min " << idx_min(m) << ", max " << idx_max(m) << ", mean " << idx_mean(m) << "):" << endl; m.print(); if (has_multiple_matrices(ifname->c_str())) { midx<T> ms = load_matrices<T>(ifname->c_str(), true); // saving sub-matrices if (save_individually) { cout << "Saving each sub-matrix of " << *ifname << " individually..." << endl; save_matrices_individually(ms, *ifname, true); } // printing sub-matrices cout << "This file contains " << m << " matrices: "; if (ms.order() == 1) { for (intg i = 0; i < ms.dim(0); ++i) { idx<T> tmp = ms.mget(i); cout << tmp.info() << " "; } } else if (ms.order() == 2) { for (intg i = 0; i < ms.dim(0); ++i) { for (intg j = 0; j < ms.dim(1); ++j) { idx<T> tmp = ms.mget(i, j); cout << tmp.info() << " "; } cout << endl; } } cout << endl; } else cout << "This is a single-matrix file." << endl; return 0; } } // image mode int loaded = 0; static idx<T> mat; uint h = 0, w = 0, rowh = 0, maxh = 0; list<string>::iterator fname = ifname; #ifdef __GUI__ disable_window_updates(); clear_window(); if (show_filename) { gui << at(h, w) << black_on_white() << ifname->c_str(); h += 16; } #endif maxh = h; for (uint i = 0; i < nh; ++i) { rowh = maxh; for (uint j = 0; j < nw; ++j) { if (fname == mats->end()) fname = mats->begin(); try { // if (load) mat = load_image<T>(*fname); if (print) cout << *fname << ": " << mat << endl << mat.str() << endl; // show only some channels if (chans >= 0) mat = mat.select(2, chans); loaded++; maxh = (std::max)(maxh, (uint) (rowh + mat.dim(0))); T min = 0, max = 0; #ifdef __GUI__ if (autorange || signd) { if (autorange) { min = idx_min(mat); max = idx_max(mat); } else if (signd) { T matmin = idx_min(mat); if ((double)matmin < 0) { min = -1; max = -1; } } draw_matrix(mat, rowh, w, zoom, zoom, min, max); } else draw_matrix(mat, rowh, w, zoom, zoom, (T) range[0], (T) range[1]); #endif w += mat.dim(1) + 1; } catch(string &err) { ERROR_MSG(err.c_str()); } fname++; if (fname == ifname) break ; } if (fname == ifname) break ; maxh++; w = 0; } #ifdef __GUI__ // info if (show_info) { set_text_colors(0, 0, 0, 255, 255, 255, 255, 200); gui << mat; gui << at(15, 0) << *fname; gui << at(29, 0) << "min: " << idx_min(mat) << " max: " << idx_max(mat); } // help if (show_help) { h = 0; w = 0; uint hstep = 14; set_text_colors(0, 0, 255, 255, 255, 255, 255, 200); gui << at(h, w) << "Controls:"; h += hstep; set_text_colors(0, 0, 0, 255, 255, 255, 255, 200); gui << at(h, w) << "Right/Space: next image"; h += hstep; gui << at(h, w) << "Left/Backspace: previous image"; h += hstep; gui << at(h, w) << "i: image info"; h += hstep; gui << at(h, w) << "a: auto-range (use min and max as range)"; h += hstep; gui << at(h, w) << "x/z: show more/less images on width axis"; h += hstep; gui << at(h, w) << "y/t: show more/less images on height axis"; h += hstep; gui << at(h, w) << "0,1,2: show channel 0, 1 or 2 only"; h += hstep; gui << at(h, w) << "9: show alls channels"; h += hstep; gui << at(h, w) << "h: help"; } // update title string title; title << "matshow: " << ebl::basename(ifname->c_str()); set_window_title(title.c_str()); enable_window_updates(); #endif return loaded; }