Пример #1
0
/**
 * 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;
      }
   }
}
Пример #2
0
/**
 * 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 */
   }
}
Пример #3
0
/**
 * 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;
}
Пример #4
0
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;
}