Пример #1
0
/**
 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(),
 * etc?  Also, do additional checking related to transformation feedback.
 * Note: this function cannot be called during glNewList(GL_COMPILE) because
 * this code depends on current transform feedback state.
 */
GLboolean
_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
{
   bool valid_enum = _mesa_is_valid_prim_mode(ctx, mode);

   if (!valid_enum) {
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
      return GL_FALSE;
   }

   /* From the GL_EXT_transform_feedback spec:
    *
    *     "The error INVALID_OPERATION is generated if Begin, or any command
    *      that performs an explicit Begin, is called when:
    *
    *      * a geometry shader is not active and <mode> does not match the
    *        allowed begin modes for the current transform feedback state as
    *        given by table X.1.
    *
    *      * a geometry shader is active and the output primitive type of the
    *        geometry shader does not match the allowed begin modes for the
    *        current transform feedback state as given by table X.1.
    *
    */
   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
      GLboolean pass = GL_TRUE;

      switch (mode) {
      case GL_POINTS:
         pass = ctx->TransformFeedback.Mode == GL_POINTS;
	 break;
      case GL_LINES:
      case GL_LINE_STRIP:
      case GL_LINE_LOOP:
         pass = ctx->TransformFeedback.Mode == GL_LINES;
	 break;
      default:
         pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
	 break;
      }
      if (!pass) {
	 _mesa_error(ctx, GL_INVALID_OPERATION,
		     "%s(mode=%s vs transform feedback %s)",
		     name,
		     _mesa_lookup_prim_by_nr(mode),
		     _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode));
	 return GL_FALSE;
      }
   }

   return GL_TRUE;
}
Пример #2
0
static void
vbo_print_vertex_list(struct gl_context *ctx, void *data, FILE *f)
{
   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data;
   GLuint i;
   struct gl_buffer_object *buffer = node->vertex_store ?
      node->vertex_store->bufferobj : NULL;
   (void) ctx;

   fprintf(f, "VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize "
           "buffer %p\n",
           node->count, node->prim_count, node->vertex_size,
           buffer);

   for (i = 0; i < node->prim_count; i++) {
      struct _mesa_prim *prim = &node->prim[i];
      fprintf(f, "   prim %d: %s%s %d..%d %s %s\n",
             i,
             _mesa_lookup_prim_by_nr(prim->mode),
             prim->weak ? " (weak)" : "",
             prim->start,
             prim->start + prim->count,
             (prim->begin) ? "BEGIN" : "(wrap)",
             (prim->end) ? "END" : "(wrap)");
   }
}
Пример #3
0
static void
vbo_print_vertex_list(struct gl_context *ctx, void *data)
{
   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data;
   GLuint i;
   (void) ctx;

   printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
          node->count, node->prim_count, node->vertex_size);

   for (i = 0; i < node->prim_count; i++) {
      struct _mesa_prim *prim = &node->prim[i];
      _mesa_debug(NULL, "   prim %d: %s%s %d..%d %s %s\n",
                  i,
                  _mesa_lookup_prim_by_nr(prim->mode),
                  prim->weak ? " (weak)" : "",
                  prim->start,
                  prim->start + prim->count,
                  (prim->begin) ? "BEGIN" : "(wrap)",
                  (prim->end) ? "END" : "(wrap)");
   }
}
Пример #4
0
static void
vbo_exec_debug_verts(struct vbo_exec_context *exec)
{
   GLuint count = exec->vtx.vert_count;
   GLuint i;

   printf("%s: %u vertices %d primitives, %d vertsize\n",
          __func__,
          count,
          exec->vtx.prim_count,
          exec->vtx.vertex_size);

   for (i = 0 ; i < exec->vtx.prim_count ; i++) {
      struct _mesa_prim *prim = &exec->vtx.prim[i];
      printf("   prim %d: %s %d..%d %s %s\n",
             i,
             _mesa_lookup_prim_by_nr(prim->mode),
             prim->start,
             prim->start + prim->count,
             prim->begin ? "BEGIN" : "(wrap)",
             prim->end ? "END" : "(wrap)");
   }
}
Пример #5
0
/**
 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(),
 * etc?  Also, do additional checking related to transformation feedback.
 * Note: this function cannot be called during glNewList(GL_COMPILE) because
 * this code depends on current transform feedback state.
 * Also, do additional checking related to tessellation shaders.
 */
GLboolean
_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
{
   bool valid_enum = _mesa_is_valid_prim_mode(ctx, mode);

   if (!valid_enum) {
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
      return GL_FALSE;
   }

   /* From the OpenGL 4.5 specification, section 11.3.1:
    *
    * The error INVALID_OPERATION is generated if Begin, or any command that
    * implicitly calls Begin, is called when a geometry shader is active and:
    *
    * * the input primitive type of the current geometry shader is
    *   POINTS and <mode> is not POINTS,
    *
    * * the input primitive type of the current geometry shader is
    *   LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP,
    *
    * * the input primitive type of the current geometry shader is
    *   TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or
    *   TRIANGLE_FAN,
    *
    * * the input primitive type of the current geometry shader is
    *   LINES_ADJACENCY_ARB and <mode> is not LINES_ADJACENCY_ARB or
    *   LINE_STRIP_ADJACENCY_ARB, or
    *
    * * the input primitive type of the current geometry shader is
    *   TRIANGLES_ADJACENCY_ARB and <mode> is not
    *   TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB.
    *
    * The GL spec doesn't mention any interaction with tessellation, which
    * is clearly a spec bug. The same rule should apply, but instead of
    * the draw primitive mode, the tessellation evaluation shader primitive
    * mode should be used for the checking.
   */
   if (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) {
      const GLenum geom_mode =
         ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]->
            _LinkedShaders[MESA_SHADER_GEOMETRY]->Geom.InputType;
      struct gl_shader_program *tes =
         ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
      GLenum mode_before_gs = mode;

      if (tes) {
         struct gl_shader *tes_sh = tes->_LinkedShaders[MESA_SHADER_TESS_EVAL];
         if (tes_sh->TessEval.PointMode)
            mode_before_gs = GL_POINTS;
         else if (tes_sh->TessEval.PrimitiveMode == GL_ISOLINES)
            mode_before_gs = GL_LINES;
         else
            /* the GL_QUADS mode generates triangles too */
            mode_before_gs = GL_TRIANGLES;
      }

      switch (mode_before_gs) {
      case GL_POINTS:
         valid_enum = (geom_mode == GL_POINTS);
         break;
      case GL_LINES:
      case GL_LINE_LOOP:
      case GL_LINE_STRIP:
         valid_enum = (geom_mode == GL_LINES);
         break;
      case GL_TRIANGLES:
      case GL_TRIANGLE_STRIP:
      case GL_TRIANGLE_FAN:
         valid_enum = (geom_mode == GL_TRIANGLES);
         break;
      case GL_QUADS:
      case GL_QUAD_STRIP:
      case GL_POLYGON:
         valid_enum = false;
         break;
      case GL_LINES_ADJACENCY:
      case GL_LINE_STRIP_ADJACENCY:
         valid_enum = (geom_mode == GL_LINES_ADJACENCY);
         break;
      case GL_TRIANGLES_ADJACENCY:
      case GL_TRIANGLE_STRIP_ADJACENCY:
         valid_enum = (geom_mode == GL_TRIANGLES_ADJACENCY);
         break;
      default:
         valid_enum = false;
         break;
      }
      if (!valid_enum) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(mode=%s vs geometry shader input %s)",
                     name,
                     _mesa_lookup_prim_by_nr(mode_before_gs),
                     _mesa_lookup_prim_by_nr(geom_mode));
         return GL_FALSE;
      }
   }

   /* From the OpenGL 4.0 (Core Profile) spec (section 2.12):
    *
    *     "Tessellation operates only on patch primitives. If tessellation is
    *      active, any command that transfers vertices to the GL will
    *      generate an INVALID_OPERATION error if the primitive mode is not
    *      PATCHES.
    *      Patch primitives are not supported by pipeline stages below the
    *      tessellation evaluation shader. If there is no active program
    *      object or the active program object does not contain a tessellation
    *      evaluation shader, the error INVALID_OPERATION is generated by any
    *      command that transfers vertices to the GL if the primitive mode is
    *      PATCHES."
    *
    */
   if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL] ||
       ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]) {
      if (mode != GL_PATCHES) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "only GL_PATCHES valid with tessellation");
         return GL_FALSE;
      }
   }
   else {
      if (mode == GL_PATCHES) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "GL_PATCHES only valid with tessellation");
         return GL_FALSE;
      }
   }

   /* From the GL_EXT_transform_feedback spec:
    *
    *     "The error INVALID_OPERATION is generated if Begin, or any command
    *      that performs an explicit Begin, is called when:
    *
    *      * a geometry shader is not active and <mode> does not match the
    *        allowed begin modes for the current transform feedback state as
    *        given by table X.1.
    *
    *      * a geometry shader is active and the output primitive type of the
    *        geometry shader does not match the allowed begin modes for the
    *        current transform feedback state as given by table X.1.
    *
    */
   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
      GLboolean pass = GL_TRUE;

      if(ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) {
         switch (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]->
                    _LinkedShaders[MESA_SHADER_GEOMETRY]->Geom.OutputType) {
         case GL_POINTS:
            pass = ctx->TransformFeedback.Mode == GL_POINTS;
            break;
         case GL_LINE_STRIP:
            pass = ctx->TransformFeedback.Mode == GL_LINES;
            break;
         case GL_TRIANGLE_STRIP:
            pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
            break;
         default:
            pass = GL_FALSE;
         }
      }
      else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) {
         struct gl_shader_program *tes =
            ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
         struct gl_shader *tes_sh = tes->_LinkedShaders[MESA_SHADER_TESS_EVAL];
         if (tes_sh->TessEval.PointMode)
            pass = ctx->TransformFeedback.Mode == GL_POINTS;
         else if (tes_sh->TessEval.PrimitiveMode == GL_ISOLINES)
            pass = ctx->TransformFeedback.Mode == GL_LINES;
         else
            pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
      }
      else {
         switch (mode) {
         case GL_POINTS:
            pass = ctx->TransformFeedback.Mode == GL_POINTS;
            break;
         case GL_LINES:
         case GL_LINE_STRIP:
         case GL_LINE_LOOP:
            pass = ctx->TransformFeedback.Mode == GL_LINES;
            break;
         default:
            pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
            break;
         }
      }
      if (!pass) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                         "%s(mode=%s vs transform feedback %s)",
                         name,
                         _mesa_lookup_prim_by_nr(mode),
                         _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode));
         return GL_FALSE;
      }
   }

   return GL_TRUE;
}
Пример #6
0
/**
 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(),
 * etc?  Also, do additional checking related to transformation feedback.
 * Note: this function cannot be called during glNewList(GL_COMPILE) because
 * this code depends on current transform feedback state.
 */
GLboolean
_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
{
   bool valid_enum = _mesa_is_valid_prim_mode(ctx, mode);

   if (!valid_enum) {
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
      return GL_FALSE;
   }

   /* From the ARB_geometry_shader4 spec:
    *
    * The error INVALID_OPERATION is generated if Begin, or any command that
    * implicitly calls Begin, is called when a geometry shader is active and:
    *
    * * the input primitive type of the current geometry shader is
    *   POINTS and <mode> is not POINTS,
    *
    * * the input primitive type of the current geometry shader is
    *   LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP,
    *
    * * the input primitive type of the current geometry shader is
    *   TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or
    *   TRIANGLE_FAN,
    *
    * * the input primitive type of the current geometry shader is
    *   LINES_ADJACENCY_ARB and <mode> is not LINES_ADJACENCY_ARB or
    *   LINE_STRIP_ADJACENCY_ARB, or
    *
    * * the input primitive type of the current geometry shader is
    *   TRIANGLES_ADJACENCY_ARB and <mode> is not
    *   TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB.
    *
   */
   if (ctx->Shader.CurrentGeometryProgram) {
      const GLenum geom_mode =
         ctx->Shader.CurrentGeometryProgram->Geom.InputType;
      switch (mode) {
      case GL_POINTS:
         valid_enum = (geom_mode == GL_POINTS);
         break;
      case GL_LINES:
      case GL_LINE_LOOP:
      case GL_LINE_STRIP:
         valid_enum = (geom_mode == GL_LINES);
         break;
      case GL_TRIANGLES:
      case GL_TRIANGLE_STRIP:
      case GL_TRIANGLE_FAN:
         valid_enum = (geom_mode == GL_TRIANGLES);
         break;
      case GL_QUADS:
      case GL_QUAD_STRIP:
      case GL_POLYGON:
         valid_enum = false;
         break;
      case GL_LINES_ADJACENCY:
      case GL_LINE_STRIP_ADJACENCY:
         valid_enum = (geom_mode == GL_LINES_ADJACENCY);
         break;
      case GL_TRIANGLES_ADJACENCY:
      case GL_TRIANGLE_STRIP_ADJACENCY:
         valid_enum = (geom_mode == GL_TRIANGLES_ADJACENCY);
         break;
      default:
         valid_enum = false;
         break;
      }
      if (!valid_enum) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(mode=%s vs geometry shader input %s)",
                     name,
                     _mesa_lookup_prim_by_nr(mode),
                     _mesa_lookup_prim_by_nr(geom_mode));
         return GL_FALSE;
      }
   }

   /* From the GL_EXT_transform_feedback spec:
    *
    *     "The error INVALID_OPERATION is generated if Begin, or any command
    *      that performs an explicit Begin, is called when:
    *
    *      * a geometry shader is not active and <mode> does not match the
    *        allowed begin modes for the current transform feedback state as
    *        given by table X.1.
    *
    *      * a geometry shader is active and the output primitive type of the
    *        geometry shader does not match the allowed begin modes for the
    *        current transform feedback state as given by table X.1.
    *
    */
   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
      GLboolean pass = GL_TRUE;

      switch (mode) {
      case GL_POINTS:
         pass = ctx->TransformFeedback.Mode == GL_POINTS;
	 break;
      case GL_LINES:
      case GL_LINE_STRIP:
      case GL_LINE_LOOP:
         pass = ctx->TransformFeedback.Mode == GL_LINES;
	 break;
      default:
         pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
	 break;
      }
      if (!pass) {
	 _mesa_error(ctx, GL_INVALID_OPERATION,
		     "%s(mode=%s vs transform feedback %s)",
		     name,
		     _mesa_lookup_prim_by_nr(mode),
		     _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode));
	 return GL_FALSE;
      }
   }

   return GL_TRUE;
}