mesa: Allow setting GL_TEXTURE_MAX_LEVEL to 0 with GL_TEXTURE_RECTANGLE.
[mesa.git] / src / mesa / main / get.c
index fa48195cdf43fac52bfd66c54f91bb2caef00e74..6d95790086531b998837da68484c36a86634ec3a 100644 (file)
@@ -28,6 +28,7 @@
 #include "blend.h"
 #include "enable.h"
 #include "enums.h"
+#include "errors.h"
 #include "extensions.h"
 #include "get.h"
 #include "macros.h"
@@ -182,7 +183,7 @@ union value {
 #define CONTEXT_FIELD(field, type) \
    LOC_CONTEXT, type, offsetof(struct gl_context, field)
 #define ARRAY_FIELD(field, type) \
-   LOC_ARRAY, type, offsetof(struct gl_array_object, field)
+   LOC_ARRAY, type, offsetof(struct gl_vertex_array_object, field)
 #undef CONST /* already defined through windows.h */
 #define CONST(value) \
    LOC_CONTEXT, TYPE_CONST, value
@@ -362,7 +363,6 @@ EXTRA_EXT(EXT_stencil_two_side);
 EXTRA_EXT(EXT_depth_bounds_test);
 EXTRA_EXT(ARB_depth_clamp);
 EXTRA_EXT(ATI_fragment_shader);
-EXTRA_EXT(EXT_framebuffer_blit);
 EXTRA_EXT(EXT_provoking_vertex);
 EXTRA_EXT(ARB_fragment_shader);
 EXTRA_EXT(ARB_fragment_program);
@@ -383,14 +383,18 @@ EXTRA_EXT(OES_EGL_image_external);
 EXTRA_EXT(ARB_blend_func_extended);
 EXTRA_EXT(ARB_uniform_buffer_object);
 EXTRA_EXT(ARB_timer_query);
-EXTRA_EXT(ARB_map_buffer_alignment);
 EXTRA_EXT(ARB_texture_cube_map_array);
 EXTRA_EXT(ARB_texture_buffer_range);
 EXTRA_EXT(ARB_texture_multisample);
 EXTRA_EXT(ARB_texture_gather);
+EXTRA_EXT(ARB_separate_shader_objects);
 EXTRA_EXT(ARB_shader_atomic_counters);
 EXTRA_EXT(ARB_draw_indirect);
 EXTRA_EXT(ARB_shader_image_load_store);
+EXTRA_EXT(ARB_viewport_array);
+EXTRA_EXT(ARB_compute_shader);
+EXTRA_EXT(ARB_gpu_shader5);
+EXTRA_EXT2(ARB_transform_feedback3, ARB_gpu_shader5);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
@@ -643,7 +647,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
    case GL_TEXTURE_COORD_ARRAY_SIZE:
    case GL_TEXTURE_COORD_ARRAY_TYPE:
    case GL_TEXTURE_COORD_ARRAY_STRIDE:
-      array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)];
+      array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)];
       v->value_int = *(GLuint *) ((char *) array + d->offset);
       break;
 
@@ -691,15 +695,15 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       break;
 
    case GL_VIEWPORT:
-      v->value_float_4[0] = ctx->Viewport.X;
-      v->value_float_4[1] = ctx->Viewport.Y;
-      v->value_float_4[2] = ctx->Viewport.Width;
-      v->value_float_4[3] = ctx->Viewport.Height;
+      v->value_float_4[0] = ctx->ViewportArray[0].X;
+      v->value_float_4[1] = ctx->ViewportArray[0].Y;
+      v->value_float_4[2] = ctx->ViewportArray[0].Width;
+      v->value_float_4[3] = ctx->ViewportArray[0].Height;
       break;
 
    case GL_DEPTH_RANGE:
-      v->value_double_2[0] = ctx->Viewport.Near;
-      v->value_double_2[1] = ctx->Viewport.Far;
+      v->value_double_2[0] = ctx->ViewportArray[0].Near;
+      v->value_double_2[1] = ctx->ViewportArray[0].Far;
       break;
 
    case GL_ACTIVE_STENCIL_FACE_EXT:
@@ -829,7 +833,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
    case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB:
    case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB:
       buffer_obj = (struct gl_buffer_object **)
-        ((char *) ctx->Array.ArrayObj + d->offset);
+        ((char *) ctx->Array.VAO + d->offset);
       v->value_int = (*buffer_obj)->Name;
       break;
    case GL_ARRAY_BUFFER_BINDING_ARB:
@@ -837,10 +841,10 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       break;
    case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
       v->value_int =
-        ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].BufferObj->Name;
+        ctx->Array.VAO->VertexBinding[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].BufferObj->Name;
       break;
    case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
-      v->value_int = ctx->Array.ArrayObj->ElementArrayBufferObj->Name;
+      v->value_int = ctx->Array.VAO->IndexBufferObj->Name;
       break;
 
    /* ARB_copy_buffer */
@@ -870,6 +874,18 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       v->value_int = ctx->TransformFeedback.CurrentObject->Name;
       break;
    case GL_CURRENT_PROGRAM:
+      /* The Changelog of the ARB_separate_shader_objects spec says:
+       *
+       * 24 25 Jul 2011  pbrown  Remove the language erroneously deleting
+       *                         CURRENT_PROGRAM.  In the EXT extension, this
+       *                         token was aliased to ACTIVE_PROGRAM_EXT, and
+       *                         was used to indicate the last program set by
+       *                         either ActiveProgramEXT or UseProgram.  In
+       *                         the ARB extension, the SSO active programs
+       *                         are now program pipeline object state and
+       *                         CURRENT_PROGRAM should still be used to query
+       *                         the last program set by UseProgram (bug 7822).
+       */
       v->value_int =
         ctx->Shader.ActiveProgram ? ctx->Shader.ActiveProgram->Name : 0;
       break;
@@ -881,7 +897,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
         ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
       break;
    case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
-      v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_POINT_SIZE].BufferObj->Name;
+      v->value_int = ctx->Array.VAO->VertexBinding[VERT_ATTRIB_POINT_SIZE].BufferObj->Name;
       break;
 
    case GL_FOG_COLOR:
@@ -971,6 +987,26 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
          _mesa_problem(ctx, "driver doesn't implement GetTimestamp");
       }
       break;
+   /* GL_KHR_DEBUG */
+   case GL_DEBUG_LOGGED_MESSAGES:
+      {
+         struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+         v->value_int = debug ? debug->NumMessages : 0;
+      }
+      break;
+   case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+      {
+         struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+         v->value_int = debug ? debug->NextMsgLength : 0;
+      }
+      break;
+   case GL_DEBUG_GROUP_STACK_DEPTH:
+      {
+         struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+         v->value_int = debug ? debug->GroupStackDepth : 0;
+      }
+      break;
+
    /* GL_ARB_shader_atomic_counters */
    case GL_ATOMIC_COUNTER_BUFFER_BINDING:
       v->value_int = ctx->AtomicBuffer->Name;
@@ -979,6 +1015,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
    case GL_DRAW_INDIRECT_BUFFER_BINDING:
       v->value_int = ctx->DrawIndirectBuffer->Name;
       break;
+   /* GL_ARB_separate_shader_objects */
+   case GL_PROGRAM_PIPELINE_BINDING:
+      if (ctx->Pipeline.Current) {
+         v->value_int = ctx->Pipeline.Current->Name;
+      } else {
+         v->value_int = 0;
+      }
+      break;
    }
 }
 
@@ -1189,7 +1233,7 @@ find_value(const char *func, GLenum pname, void **p, union value *v)
       *p = ((char *) ctx + d->offset);
       return d;
    case LOC_ARRAY:
-      *p = ((char *) ctx->Array.ArrayObj + d->offset);
+      *p = ((char *) ctx->Array.VAO + d->offset);
       return d;
    case LOC_TEXUNIT:
       unit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -1246,6 +1290,8 @@ _mesa_GetBooleanv(GLenum pname, GLboolean *params)
       params[0] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[0]);
       break;
 
+   case TYPE_DOUBLEN_2:
+      params[1] = FLOAT_TO_BOOLEAN(((GLdouble *) p)[1]);
    case TYPE_DOUBLEN:
       params[0] = FLOAT_TO_BOOLEAN(((GLdouble *) p)[0]);
       break;
@@ -1332,6 +1378,8 @@ _mesa_GetFloatv(GLenum pname, GLfloat *params)
       params[0] = ((GLfloat *) p)[0];
       break;
 
+   case TYPE_DOUBLEN_2:
+      params[1] = (GLfloat) (((GLdouble *) p)[1]);
    case TYPE_DOUBLEN:
       params[0] = (GLfloat) (((GLdouble *) p)[0]);
       break;
@@ -1424,6 +1472,8 @@ _mesa_GetIntegerv(GLenum pname, GLint *params)
       params[0] = FLOAT_TO_INT(((GLfloat *) p)[0]);
       break;
 
+   case TYPE_DOUBLEN_2:
+      params[1] = FLOAT_TO_INT(((GLdouble *) p)[1]);
    case TYPE_DOUBLEN:
       params[0] = FLOAT_TO_INT(((GLdouble *) p)[0]);
       break;
@@ -1516,6 +1566,8 @@ _mesa_GetInteger64v(GLenum pname, GLint64 *params)
       params[0] = FLOAT_TO_INT64(((GLfloat *) p)[0]);
       break;
 
+   case TYPE_DOUBLEN_2:
+      params[1] = FLOAT_TO_INT64(((GLdouble *) p)[1]);
    case TYPE_DOUBLEN:
       params[0] = FLOAT_TO_INT64(((GLdouble *) p)[0]);
       break;
@@ -1602,6 +1654,8 @@ _mesa_GetDoublev(GLenum pname, GLdouble *params)
       params[0] = ((GLfloat *) p)[0];
       break;
 
+   case TYPE_DOUBLEN_2:
+      params[1] = ((GLdouble *) p)[1];
    case TYPE_DOUBLEN:
       params[0] = ((GLdouble *) p)[0];
       break;
@@ -1730,6 +1784,31 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
       v->value_int_4[3] = ctx->Color.ColorMask[index][ACOMP] ? 1 : 0;
       return TYPE_INT_4;
 
+   case GL_SCISSOR_BOX:
+      if (index >= ctx->Const.MaxViewports)
+         goto invalid_value;
+      v->value_int_4[0] = ctx->Scissor.ScissorArray[index].X;
+      v->value_int_4[1] = ctx->Scissor.ScissorArray[index].Y;
+      v->value_int_4[2] = ctx->Scissor.ScissorArray[index].Width;
+      v->value_int_4[3] = ctx->Scissor.ScissorArray[index].Height;
+      return TYPE_INT_4;
+
+   case GL_VIEWPORT:
+      if (index >= ctx->Const.MaxViewports)
+         goto invalid_value;
+      v->value_float_4[0] = ctx->ViewportArray[index].X;
+      v->value_float_4[1] = ctx->ViewportArray[index].Y;
+      v->value_float_4[2] = ctx->ViewportArray[index].Width;
+      v->value_float_4[3] = ctx->ViewportArray[index].Height;
+      return TYPE_FLOAT_4;
+
+   case GL_DEPTH_RANGE:
+      if (index >= ctx->Const.MaxViewports)
+         goto invalid_value;
+      v->value_double_2[0] = ctx->ViewportArray[index].Near;
+      v->value_double_2[1] = ctx->ViewportArray[index].Far;
+      return TYPE_DOUBLEN_2;
+
    case GL_TRANSFORM_FEEDBACK_BUFFER_START:
       if (index >= ctx->Const.MaxTransformFeedbackBuffers)
         goto invalid_value;
@@ -1817,7 +1896,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
           goto invalid_enum;
       if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs)
           goto invalid_value;
-      v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
+      v->value_int = ctx->Array.VAO->VertexBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
       return TYPE_INT;
 
    case GL_VERTEX_BINDING_OFFSET:
@@ -1825,7 +1904,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
           goto invalid_enum;
       if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs)
           goto invalid_value;
-      v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].Offset;
+      v->value_int = ctx->Array.VAO->VertexBinding[VERT_ATTRIB_GENERIC(index)].Offset;
       return TYPE_INT;
 
    case GL_VERTEX_BINDING_STRIDE:
@@ -1833,7 +1912,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
           goto invalid_enum;
       if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs)
           goto invalid_value;
-      v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride;
+      v->value_int = ctx->Array.VAO->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride;
 
    /* ARB_shader_image_load_store */
    case GL_IMAGE_BINDING_NAME: {
@@ -1893,6 +1972,22 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
 
       v->value_int = ctx->ImageUnits[index].Format;
       return TYPE_INT;
+
+   case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
+      if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_compute_shader)
+         goto invalid_enum;
+      if (index >= 3)
+         goto invalid_value;
+      v->value_int = ctx->Const.MaxComputeWorkGroupCount[index];
+      return TYPE_INT;
+
+   case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
+      if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_compute_shader)
+         goto invalid_enum;
+      if (index >= 3)
+         goto invalid_value;
+      v->value_int = ctx->Const.MaxComputeWorkGroupSize[index];
+      return TYPE_INT;
    }
 
  invalid_enum:
@@ -1923,7 +2018,7 @@ _mesa_GetBooleani_v( GLenum pname, GLuint index, GLboolean *params )
       params[3] = INT_TO_BOOLEAN(v.value_int_4[3]);
       break;
    case TYPE_INT64:
-      params[0] = INT64_TO_BOOLEAN(v.value_int);
+      params[0] = INT64_TO_BOOLEAN(v.value_int64);
       break;
    default:
       ; /* nothing - GL error was recorded */
@@ -1938,6 +2033,26 @@ _mesa_GetIntegeri_v( GLenum pname, GLuint index, GLint *params )
       find_value_indexed("glGetIntegeri_v", pname, index, &v);
 
    switch (type) {
+   case TYPE_FLOAT_4:
+   case TYPE_FLOATN_4:
+      params[3] = IROUND(v.value_float_4[3]);
+   case TYPE_FLOAT_3:
+   case TYPE_FLOATN_3:
+      params[2] = IROUND(v.value_float_4[2]);
+   case TYPE_FLOAT_2:
+   case TYPE_FLOATN_2:
+      params[1] = IROUND(v.value_float_4[1]);
+   case TYPE_FLOAT:
+   case TYPE_FLOATN:
+      params[0] = IROUND(v.value_float_4[0]);
+      break;
+
+   case TYPE_DOUBLEN_2:
+      params[1] = IROUND(v.value_double_2[1]);
+   case TYPE_DOUBLEN:
+      params[0] = IROUND(v.value_double_2[0]);
+      break;
+
    case TYPE_INT:
       params[0] = v.value_int;
       break;
@@ -1948,7 +2063,7 @@ _mesa_GetIntegeri_v( GLenum pname, GLuint index, GLint *params )
       params[3] = v.value_int_4[3];
       break;
    case TYPE_INT64:
-      params[0] = INT64_TO_INT(v.value_int);
+      params[0] = INT64_TO_INT(v.value_int64);
       break;
    default:
       ; /* nothing - GL error was recorded */
@@ -1973,13 +2088,157 @@ _mesa_GetInteger64i_v( GLenum pname, GLuint index, GLint64 *params )
       params[3] = v.value_int_4[3];
       break;
    case TYPE_INT64:
-      params[0] = v.value_int;
+      params[0] = v.value_int64;
       break;
    default:
       ; /* nothing - GL error was recorded */
    }
 }
 
+void GLAPIENTRY
+_mesa_GetFloati_v(GLenum pname, GLuint index, GLfloat *params)
+{
+   int i;
+   GLmatrix *m;
+   union value v;
+   enum value_type type =
+      find_value_indexed("glGetFloati_v", pname, index, &v);
+
+   switch (type) {
+   case TYPE_FLOAT_4:
+   case TYPE_FLOATN_4:
+      params[3] = v.value_float_4[3];
+   case TYPE_FLOAT_3:
+   case TYPE_FLOATN_3:
+      params[2] = v.value_float_4[2];
+   case TYPE_FLOAT_2:
+   case TYPE_FLOATN_2:
+      params[1] = v.value_float_4[1];
+   case TYPE_FLOAT:
+   case TYPE_FLOATN:
+      params[0] = v.value_float_4[0];
+      break;
+
+   case TYPE_DOUBLEN_2:
+      params[1] = (GLfloat) v.value_double_2[1];
+   case TYPE_DOUBLEN:
+      params[0] = (GLfloat) v.value_double_2[0];
+      break;
+
+   case TYPE_INT_4:
+      params[3] = (GLfloat) v.value_int_4[3];
+   case TYPE_INT_3:
+      params[2] = (GLfloat) v.value_int_4[2];
+   case TYPE_INT_2:
+   case TYPE_ENUM_2:
+      params[1] = (GLfloat) v.value_int_4[1];
+   case TYPE_INT:
+   case TYPE_ENUM:
+      params[0] = (GLfloat) v.value_int_4[0];
+      break;
+
+   case TYPE_INT_N:
+      for (i = 0; i < v.value_int_n.n; i++)
+        params[i] = INT_TO_FLOAT(v.value_int_n.ints[i]);
+      break;
+
+   case TYPE_INT64:
+      params[0] = (GLfloat) v.value_int64;
+      break;
+
+   case TYPE_BOOLEAN:
+      params[0] = BOOLEAN_TO_FLOAT(v.value_bool);
+      break;
+
+   case TYPE_MATRIX:
+      m = *(GLmatrix **) &v;
+      for (i = 0; i < 16; i++)
+        params[i] = m->m[i];
+      break;
+
+   case TYPE_MATRIX_T:
+      m = *(GLmatrix **) &v;
+      for (i = 0; i < 16; i++)
+        params[i] = m->m[transpose[i]];
+      break;
+
+   default:
+      ;
+   }
+}
+
+void GLAPIENTRY
+_mesa_GetDoublei_v(GLenum pname, GLuint index, GLdouble *params)
+{
+   int i;
+   GLmatrix *m;
+   union value v;
+   enum value_type type =
+      find_value_indexed("glGetDoublei_v", pname, index, &v);
+
+   switch (type) {
+   case TYPE_FLOAT_4:
+   case TYPE_FLOATN_4:
+      params[3] = (GLdouble) v.value_float_4[3];
+   case TYPE_FLOAT_3:
+   case TYPE_FLOATN_3:
+      params[2] = (GLdouble) v.value_float_4[2];
+   case TYPE_FLOAT_2:
+   case TYPE_FLOATN_2:
+      params[1] = (GLdouble) v.value_float_4[1];
+   case TYPE_FLOAT:
+   case TYPE_FLOATN:
+      params[0] = (GLdouble) v.value_float_4[0];
+      break;
+
+   case TYPE_DOUBLEN_2:
+      params[1] = v.value_double_2[1];
+   case TYPE_DOUBLEN:
+      params[0] = v.value_double_2[0];
+      break;
+
+   case TYPE_INT_4:
+      params[3] = (GLdouble) v.value_int_4[3];
+   case TYPE_INT_3:
+      params[2] = (GLdouble) v.value_int_4[2];
+   case TYPE_INT_2:
+   case TYPE_ENUM_2:
+      params[1] = (GLdouble) v.value_int_4[1];
+   case TYPE_INT:
+   case TYPE_ENUM:
+      params[0] = (GLdouble) v.value_int_4[0];
+      break;
+
+   case TYPE_INT_N:
+      for (i = 0; i < v.value_int_n.n; i++)
+        params[i] = (GLdouble) INT_TO_FLOAT(v.value_int_n.ints[i]);
+      break;
+
+   case TYPE_INT64:
+      params[0] = (GLdouble) v.value_int64;
+      break;
+
+   case TYPE_BOOLEAN:
+      params[0] = (GLdouble) BOOLEAN_TO_FLOAT(v.value_bool);
+      break;
+
+   case TYPE_MATRIX:
+      m = *(GLmatrix **) &v;
+      for (i = 0; i < 16; i++)
+        params[i] = (GLdouble) m->m[i];
+      break;
+
+   case TYPE_MATRIX_T:
+      m = *(GLmatrix **) &v;
+      for (i = 0; i < 16; i++)
+        params[i] = (GLdouble) m->m[transpose[i]];
+      break;
+
+   default:
+      ;
+   }
+}
+
 void GLAPIENTRY
 _mesa_GetFixedv(GLenum pname, GLfixed *params)
 {
@@ -2011,6 +2270,8 @@ _mesa_GetFixedv(GLenum pname, GLfixed *params)
       params[0] = FLOAT_TO_FIXED(((GLfloat *) p)[0]);
       break;
 
+   case TYPE_DOUBLEN_2:
+      params[1] = FLOAT_TO_FIXED(((GLdouble *) p)[1]);
    case TYPE_DOUBLEN:
       params[0] = FLOAT_TO_FIXED(((GLdouble *) p)[0]);
       break;