Exemple #1
0
/**
 * Check if given blend destination factor is legal.
 * \return GL_TRUE if legal, GL_FALSE otherwise.
 */
static GLboolean
legal_dst_factor(const struct gl_context *ctx, GLenum factor)
{
   switch (factor) {
   case GL_DST_COLOR:
   case GL_ONE_MINUS_DST_COLOR:
   case GL_ZERO:
   case GL_ONE:
   case GL_SRC_COLOR:
   case GL_ONE_MINUS_SRC_COLOR:
   case GL_SRC_ALPHA:
   case GL_ONE_MINUS_SRC_ALPHA:
   case GL_DST_ALPHA:
   case GL_ONE_MINUS_DST_ALPHA:
      return GL_TRUE;
   case GL_CONSTANT_COLOR:
   case GL_ONE_MINUS_CONSTANT_COLOR:
   case GL_CONSTANT_ALPHA:
   case GL_ONE_MINUS_CONSTANT_ALPHA:
      return _mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES2;
   case GL_SRC_ALPHA_SATURATE:
      return (_mesa_is_desktop_gl(ctx)
              && ctx->Extensions.ARB_blend_func_extended)
         || _mesa_is_gles3(ctx);
   case GL_SRC1_COLOR:
   case GL_SRC1_ALPHA:
   case GL_ONE_MINUS_SRC1_COLOR:
   case GL_ONE_MINUS_SRC1_ALPHA:
      return _mesa_is_desktop_gl(ctx)
         && ctx->Extensions.ARB_blend_func_extended;
   default:
      return GL_FALSE;
   }
}
Exemple #2
0
void GLAPIENTRY
_mesa_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize,
                     GLsizei *length, GLchar *label)
{
   GET_CURRENT_CONTEXT(ctx);
   const char *callerstr;
   char **labelPtr;

   if (_mesa_is_desktop_gl(ctx))
      callerstr = "glGetObjectLabel";
   else
      callerstr = "glGetObjectLabelKHR";

   if (bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr,
                  bufSize);
      return;
   }

   labelPtr = get_label_pointer(ctx, identifier, name, callerstr);
   if (!labelPtr)
      return;

   copy_label(*labelPtr, label, length, bufSize);
}
Exemple #3
0
void GLAPIENTRY
_mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length,
                        GLchar *label)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr;
   const char *callerstr;
   char **labelPtr;

   if (_mesa_is_desktop_gl(ctx))
      callerstr = "glGetObjectPtrLabel";
   else
      callerstr = "glGetObjectPtrLabelKHR";

   if (bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr,
                  bufSize);
      return;
   }

   if (!_mesa_validate_sync(ctx, syncObj)) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)",
                  callerstr);
      return;
   }

   labelPtr = &syncObj->Label;

   copy_label(*labelPtr, label, length, bufSize);
}
Exemple #4
0
/**
 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(),
 * etc?  The set of legal values depends on whether geometry shaders/programs
 * are supported.
 * Note: This may be called during display list compilation.
 */
bool
_mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode)
{
   switch (mode) {
   case GL_POINTS:
   case GL_LINES:
   case GL_LINE_LOOP:
   case GL_LINE_STRIP:
   case GL_TRIANGLES:
   case GL_TRIANGLE_STRIP:
   case GL_TRIANGLE_FAN:
      return true;
   case GL_QUADS:
   case GL_QUAD_STRIP:
   case GL_POLYGON:
      return (ctx->API == API_OPENGL_COMPAT);
   case GL_LINES_ADJACENCY:
   case GL_LINE_STRIP_ADJACENCY:
   case GL_TRIANGLES_ADJACENCY:
   case GL_TRIANGLE_STRIP_ADJACENCY:
      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
   default:
      return false;
   }
}
static void
setup_glsl_blit_framebuffer(struct gl_context *ctx,
                            struct blit_state *blit,
                            const struct gl_framebuffer *drawFb,
                            struct gl_renderbuffer *src_rb,
                            GLenum target, GLenum filter,
                            bool is_scaled_blit,
                            bool do_depth)
{
   unsigned texcoord_size;
   bool is_target_multisample = target == GL_TEXTURE_2D_MULTISAMPLE ||
                                target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
   bool is_filter_scaled_resolve = filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
                                   filter == GL_SCALED_RESOLVE_NICEST_EXT;

   /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */
   assert(_mesa_is_desktop_gl(ctx) || target == GL_TEXTURE_2D);

   texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0);

   _mesa_meta_setup_vertex_objects(ctx, &blit->VAO, &blit->buf_obj, true,
                                   2, texcoord_size, 0);

   if (is_target_multisample && is_filter_scaled_resolve && is_scaled_blit) {
      setup_glsl_msaa_blit_scaled_shader(ctx, blit, src_rb, target, filter);
   } else if (is_target_multisample) {
      setup_glsl_msaa_blit_shader(ctx, blit, drawFb, src_rb, target);
   } else {
      _mesa_meta_setup_blit_shader(ctx, target, do_depth,
                                   do_depth ? &blit->shaders_with_depth
                                            : &blit->shaders_without_depth);
   }
}
Exemple #6
0
/**
 * Return whether an image format should be supported based on the current API
 * version of the context.
 */
static bool
is_image_format_supported(const struct gl_context *ctx, GLenum format)
{
   switch (format) {
   /* Formats supported on both desktop and ES GL, c.f. table 8.27 of the
    * OpenGL ES 3.1 specification.
    */
   case GL_RGBA32F:
   case GL_RGBA16F:
   case GL_R32F:
   case GL_RGBA32UI:
   case GL_RGBA16UI:
   case GL_RGBA8UI:
   case GL_R32UI:
   case GL_RGBA32I:
   case GL_RGBA16I:
   case GL_RGBA8I:
   case GL_R32I:
   case GL_RGBA8:
   case GL_RGBA8_SNORM:
      return true;

   /* Formats supported on unextended desktop GL and the original
    * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2
    * specification.
    */
   case GL_RG32F:
   case GL_RG16F:
   case GL_R11F_G11F_B10F:
   case GL_R16F:
   case GL_RGB10_A2UI:
   case GL_RG32UI:
   case GL_RG16UI:
   case GL_RG8UI:
   case GL_R16UI:
   case GL_R8UI:
   case GL_RG32I:
   case GL_RG16I:
   case GL_RG8I:
   case GL_R16I:
   case GL_R8I:
   case GL_RGBA16:
   case GL_RGB10_A2:
   case GL_RG16:
   case GL_RG8:
   case GL_R16:
   case GL_R8:
   case GL_RGBA16_SNORM:
   case GL_RG16_SNORM:
   case GL_RG8_SNORM:
   case GL_R16_SNORM:
   case GL_R8_SNORM:
      return _mesa_is_desktop_gl(ctx);

   default:
      return false;
   }
}
Exemple #7
0
struct gl_image_unit
_mesa_default_image_unit(struct gl_context *ctx)
{
   const GLenum format = _mesa_is_desktop_gl(ctx) ? GL_R8 : GL_R32UI;
   const struct gl_image_unit u = {
      .Access = GL_READ_ONLY,
      .Format = format,
      ._ActualFormat = _mesa_get_shader_image_format(format)
   };
   return u;
}
Exemple #8
0
/**
 * Initialize the dispatch table with the VBO functions for drawing.
 */
void
vbo_initialize_exec_dispatch(const struct gl_context *ctx,
                             struct _glapi_table *exec)
{
   SET_DrawArrays(exec, vbo_exec_DrawArrays);
   SET_DrawElements(exec, vbo_exec_DrawElements);

   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements);
   }

   SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements);

   if (ctx->API == API_OPENGL_COMPAT) {
      SET_Rectf(exec, vbo_exec_Rectf);
      SET_EvalMesh1(exec, vbo_exec_EvalMesh1);
      SET_EvalMesh2(exec, vbo_exec_EvalMesh2);
   }

   if (_mesa_is_desktop_gl(ctx)) {
      SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex);
      SET_DrawRangeElementsBaseVertex(exec, vbo_exec_DrawRangeElementsBaseVertex);
      SET_MultiDrawElementsBaseVertex(exec, vbo_exec_MultiDrawElementsBaseVertex);
      SET_DrawArraysInstancedBaseInstance(exec, vbo_exec_DrawArraysInstancedBaseInstance);
      SET_DrawElementsInstancedBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseInstance);
      SET_DrawElementsInstancedBaseVertex(exec, vbo_exec_DrawElementsInstancedBaseVertex);
      SET_DrawElementsInstancedBaseVertexBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
   }

   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
      SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
   }

   if (_mesa_is_desktop_gl(ctx)) {
      SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
      SET_DrawTransformFeedbackStream(exec, vbo_exec_DrawTransformFeedbackStream);
      SET_DrawTransformFeedbackInstanced(exec, vbo_exec_DrawTransformFeedbackInstanced);
      SET_DrawTransformFeedbackStreamInstanced(exec, vbo_exec_DrawTransformFeedbackStreamInstanced);
   }
}
Exemple #9
0
/**
 * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
 * into the corresponding Mesa texture target index.
 * Note that proxy targets are not valid here.
 * \return TEXTURE_x_INDEX or -1 if target is invalid
 */
static GLint
target_enum_to_index(struct gl_context *ctx, GLenum target)
{
   switch (target) {
   case GL_TEXTURE_1D:
      return _mesa_is_desktop_gl(ctx) ? TEXTURE_1D_INDEX : -1;
   case GL_TEXTURE_2D:
      return TEXTURE_2D_INDEX;
   case GL_TEXTURE_3D:
      return TEXTURE_3D_INDEX;
   case GL_TEXTURE_CUBE_MAP_ARB:
      return ctx->Extensions.ARB_texture_cube_map
         ? TEXTURE_CUBE_INDEX : -1;
   case GL_TEXTURE_RECTANGLE_NV:
      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle
         ? TEXTURE_RECT_INDEX : -1;
   case GL_TEXTURE_1D_ARRAY_EXT:
      return _mesa_is_desktop_gl(ctx)
         && (ctx->Extensions.EXT_texture_array
             || ctx->Extensions.MESA_texture_array)
         ? TEXTURE_1D_ARRAY_INDEX : -1;
   case GL_TEXTURE_2D_ARRAY_EXT:
      return (_mesa_is_desktop_gl(ctx)
              && (ctx->Extensions.EXT_texture_array
                  || ctx->Extensions.MESA_texture_array))
         || _mesa_is_gles3(ctx)
         ? TEXTURE_2D_ARRAY_INDEX : -1;
   case GL_TEXTURE_BUFFER_ARB:
      return _mesa_is_desktop_gl(ctx)
         && ctx->Extensions.ARB_texture_buffer_object
         ? TEXTURE_BUFFER_INDEX : -1;
   case GL_TEXTURE_EXTERNAL_OES:
      return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external
         ? TEXTURE_EXTERNAL_INDEX : -1;
   case GL_TEXTURE_CUBE_MAP_ARRAY:
      return TEXTURE_CUBE_ARRAY_INDEX;
   default:
      return -1;
   }
}
Exemple #10
0
/**
 * Confirm that the a shader type is valid and supported by the implementation
 *
 * \param ctx   Current GL context
 * \param type  Shader target
 *
 */
static bool
validate_shader_target(const struct gl_context *ctx, GLenum type)
{
   switch (type) {
   case GL_FRAGMENT_SHADER:
      return ctx->Extensions.ARB_fragment_shader;
   case GL_VERTEX_SHADER:
      return ctx->Extensions.ARB_vertex_shader;
   case GL_GEOMETRY_SHADER_ARB:
      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
   default:
      return false;
   }
}
Exemple #11
0
/**
 * Called via glMinSampleShadingARB
 */
void GLAPIENTRY
_mesa_MinSampleShading(GLclampf value)
{
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->Extensions.ARB_sample_shading || !_mesa_is_desktop_gl(ctx)) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glMinSampleShading");
      return;
   }

   FLUSH_VERTICES(ctx, 0);

   ctx->Multisample.MinSampleShadingValue = CLAMP(value, 0.0, 1.0);
   ctx->NewState |= _NEW_MULTISAMPLE;
}
static GLuint
set_sampler_cube_map_seamless(struct gl_context *ctx,
                              struct gl_sampler_object *samp, GLboolean param)
{
   if (!_mesa_is_desktop_gl(ctx)
       || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
      return INVALID_PNAME;

   if (samp->CubeMapSeamless == param)
      return GL_FALSE;

   if (param != GL_TRUE && param != GL_FALSE)
      return INVALID_VALUE;

   flush(ctx);
   samp->CubeMapSeamless = param;
   return GL_TRUE;
}
Exemple #13
0
void GLAPIENTRY
_mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length,
                  const GLchar *label)
{
   GET_CURRENT_CONTEXT(ctx);
   const char *callerstr;
   char **labelPtr;

   if (_mesa_is_desktop_gl(ctx))
      callerstr = "glObjectLabel";
   else
      callerstr = "glObjectLabelKHR";

   labelPtr = get_label_pointer(ctx, identifier, name, callerstr);
   if (!labelPtr)
      return;

   set_label(ctx, labelPtr, label, length, callerstr);
}
Exemple #14
0
/**
 * Fixes up the context for GLES23 with our default-to-sRGB-capable behavior
 * on window system framebuffers.
 *
 * Desktop GL is fairly reasonable in its handling of sRGB: You can ask if
 * your renderbuffer can do sRGB encode, and you can flip a switch that does
 * sRGB encode if the renderbuffer can handle it.  You can ask specifically
 * for a visual where you're guaranteed to be capable, but it turns out that
 * everyone just makes all their ARGB8888 visuals capable and doesn't offer
 * incapable ones, becuase there's no difference between the two in resources
 * used.  Applications thus get built that accidentally rely on the default
 * visual choice being sRGB, so we make ours sRGB capable.  Everything sounds
 * great...
 *
 * But for GLES2/3, they decided that it was silly to not turn on sRGB encode
 * for sRGB renderbuffers you made with the GL_EXT_texture_sRGB equivalent.
 * So they removed the enable knob and made it "if the renderbuffer is sRGB
 * capable, do sRGB encode".  Then, for your window system renderbuffers, you
 * can ask for sRGB visuals and get sRGB encode, or not ask for sRGB visuals
 * and get no sRGB encode (assuming that both kinds of visual are available).
 * Thus our choice to support sRGB by default on our visuals for desktop would
 * result in broken rendering of GLES apps that aren't expecting sRGB encode.
 *
 * Unfortunately, renderbuffer setup happens before a context is created.  So
 * in intel_screen.c we always set up sRGB, and here, if you're a GLES2/3
 * context (without an sRGB visual, though we don't have sRGB visuals exposed
 * yet), we go turn that back off before anyone finds out.
 */
static void
intel_gles3_srgb_workaround(struct brw_context *brw,
                            struct gl_framebuffer *fb)
{
   struct gl_context *ctx = &brw->ctx;

   if (_mesa_is_desktop_gl(ctx) || !fb->Visual.sRGBCapable)
      return;

   /* Some day when we support the sRGB capable bit on visuals available for
    * GLES, we'll need to respect that and not disable things here.
    */
   fb->Visual.sRGBCapable = false;
   for (int i = 0; i < BUFFER_COUNT; i++) {
      if (fb->Attachment[i].Renderbuffer &&
          fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_SARGB8) {
         fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_ARGB8888;
      }
   }
}
Exemple #15
0
static void
setup_glsl_blit_framebuffer(struct gl_context *ctx,
                            struct blit_state *blit,
                            struct gl_renderbuffer *src_rb,
                            GLenum target)
{
   unsigned texcoord_size;

   /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */
   assert(_mesa_is_desktop_gl(ctx) || target == GL_TEXTURE_2D);

   texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0);

   _mesa_meta_setup_vertex_objects(&blit->VAO, &blit->VBO, true,
                                   2, texcoord_size, 0);

   if (target == GL_TEXTURE_2D_MULTISAMPLE ||
       target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
      setup_glsl_msaa_blit_shader(ctx, blit, src_rb, target);
   } else {
      _mesa_meta_setup_blit_shader(ctx, target, &blit->shaders);
   }
}
Exemple #16
0
/** Convert GL datatype enum into a <type>_BIT value seen above */
static GLbitfield
type_to_bit(const struct gl_context *ctx, GLenum type)
{
   switch (type) {
   case GL_BOOL:
      return BOOL_BIT;
   case GL_BYTE:
      return BYTE_BIT;
   case GL_UNSIGNED_BYTE:
      return UNSIGNED_BYTE_BIT;
   case GL_SHORT:
      return SHORT_BIT;
   case GL_UNSIGNED_SHORT:
      return UNSIGNED_SHORT_BIT;
   case GL_INT:
      return INT_BIT;
   case GL_UNSIGNED_INT:
      return UNSIGNED_INT_BIT;
   case GL_HALF_FLOAT:
      if (ctx->Extensions.ARB_half_float_vertex)
         return HALF_BIT;
      else
         return 0x0;
   case GL_FLOAT:
      return FLOAT_BIT;
   case GL_DOUBLE:
      return DOUBLE_BIT;
   case GL_FIXED:
      return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
   case GL_UNSIGNED_INT_2_10_10_10_REV:
      return UNSIGNED_INT_2_10_10_10_REV_BIT;
   case GL_INT_2_10_10_10_REV:
      return INT_2_10_10_10_REV_BIT;
   default:
      return 0;
   }
}
Exemple #17
0
/**
 * glGetProgramiv() - get shader program state.
 * Note that this is for GLSL shader programs, not ARB vertex/fragment
 * programs (see glGetProgramivARB).
 */
static void
get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params)
{
   struct gl_shader_program *shProg
      = _mesa_lookup_shader_program(ctx, program);

   /* Is transform feedback available in this context?
    */
   const bool has_xfb =
      (ctx->API == API_OPENGL && ctx->Extensions.EXT_transform_feedback)
      || ctx->API == API_OPENGL_CORE
      || _mesa_is_gles3(ctx);

   /* Are geometry shaders available in this context?
    */
   const bool has_gs =
      _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;

   /* Are uniform buffer objects available in this context?
    */
   const bool has_ubo =
      (ctx->API == API_OPENGL && ctx->Extensions.ARB_uniform_buffer_object)
      || ctx->API == API_OPENGL_CORE
      || _mesa_is_gles3(ctx);

   if (!shProg) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
      return;
   }

   switch (pname) {
   case GL_DELETE_STATUS:
      *params = shProg->DeletePending;
      return;
   case GL_LINK_STATUS:
      *params = shProg->LinkStatus;
      return;
   case GL_VALIDATE_STATUS:
      *params = shProg->Validated;
      return;
   case GL_INFO_LOG_LENGTH:
      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
      return;
   case GL_ATTACHED_SHADERS:
      *params = shProg->NumShaders;
      return;
   case GL_ACTIVE_ATTRIBUTES:
      *params = _mesa_count_active_attribs(shProg);
      return;
   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
      *params = _mesa_longest_attribute_name_length(shProg);
      return;
   case GL_ACTIVE_UNIFORMS:
      *params = shProg->NumUserUniformStorage;
      return;
   case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
      unsigned i;
      GLint max_len = 0;

      for (i = 0; i < shProg->NumUserUniformStorage; i++) {
	 /* Add one for the terminating NUL character.
	  */
	 const GLint len = strlen(shProg->UniformStorage[i].name) + 1;

	 if (len > max_len)
	    max_len = len;
      }

      *params = max_len;
      return;
   }
   case GL_TRANSFORM_FEEDBACK_VARYINGS:
      if (!has_xfb)
         break;
      *params = shProg->TransformFeedback.NumVarying;
      return;
   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
      if (!has_xfb)
         break;
      *params = longest_feedback_varying_name(shProg) + 1;
      return;
   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
      if (!has_xfb)
         break;
      *params = shProg->TransformFeedback.BufferMode;
      return;
   case GL_GEOMETRY_VERTICES_OUT_ARB:
      if (!has_gs)
         break;
      *params = shProg->Geom.VerticesOut;
      return;
   case GL_GEOMETRY_INPUT_TYPE_ARB:
      if (!has_gs)
         break;
      *params = shProg->Geom.InputType;
      return;
   case GL_GEOMETRY_OUTPUT_TYPE_ARB:
      if (!has_gs)
         break;
      *params = shProg->Geom.OutputType;
      return;
   case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
      unsigned i;
      GLint max_len = 0;

      if (!has_ubo)
         break;

      for (i = 0; i < shProg->NumUniformBlocks; i++) {
	 /* Add one for the terminating NUL character.
	  */
	 const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;

	 if (len > max_len)
	    max_len = len;
      }

      *params = max_len;
      return;
   }
   case GL_ACTIVE_UNIFORM_BLOCKS:
      if (!has_ubo)
         break;

      *params = shProg->NumUniformBlocks;
      return;
   default:
      break;
   }

   _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
               _mesa_lookup_enum_by_nr(pname));
}
Exemple #18
0
/**
 * Install per-vertex functions into the API dispatch table for display
 * list compilation.
 */
void
_mesa_install_save_vtxfmt(struct gl_context *ctx, const GLvertexformat *vfmt)
{
   if (_mesa_is_desktop_gl(ctx))
      install_vtxfmt( ctx, ctx->Save, vfmt );
}
Exemple #19
0
/**
 * Called via glUniform*() functions.
 */
extern "C" void
_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
	      GLint location, GLsizei count,
              const GLvoid *values,
              enum glsl_base_type basicType,
              unsigned src_components)
{
   unsigned offset;
   int size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;

   struct gl_uniform_storage *const uni =
      validate_uniform_parameters(ctx, shProg, location, count,
                                  &offset, "glUniform");
   if (uni == NULL)
      return;

   if (uni->type->is_matrix()) {
      /* Can't set matrix uniforms (like mat4) with glUniform */
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glUniform%u(uniform \"%s\"@%d is matrix)",
                  src_components, uni->name, location);
      return;
   }

   /* Verify that the types are compatible.
    */
   const unsigned components = uni->type->is_sampler()
      ? 1 : uni->type->vector_elements;

   if (components != src_components) {
      /* glUniformN() must match float/vecN type */
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glUniform%u(\"%s\"@%u has %u components, not %u)",
                  src_components, uni->name, location,
                  components, src_components);
      return;
   }

   bool match;
   switch (uni->type->base_type) {
   case GLSL_TYPE_BOOL:
      match = (basicType != GLSL_TYPE_DOUBLE);
      break;
   case GLSL_TYPE_SAMPLER:
      match = (basicType == GLSL_TYPE_INT);
      break;
   case GLSL_TYPE_IMAGE:
      match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
      break;
   default:
      match = (basicType == uni->type->base_type);
      break;
   }

   if (!match) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glUniform%u(\"%s\"@%d is %s, not %s)",
                  src_components, uni->name, location,
                  glsl_type_name(uni->type->base_type),
                  glsl_type_name(basicType));
      return;
   }

   if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
      log_uniform(values, basicType, components, 1, count,
		  false, shProg, location, uni);
   }

   /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
    *
    *     "Setting a sampler's value to i selects texture image unit number
    *     i. The values of i range from zero to the implementation- dependent
    *     maximum supported number of texture image units."
    *
    * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
    * the PDF) says:
    *
    *     "Error         Description                    Offending command
    *                                                   ignored?
    *     ...
    *     INVALID_VALUE  Numeric argument out of range  Yes"
    *
    * Based on that, when an invalid sampler is specified, we generate a
    * GL_INVALID_VALUE error and ignore the command.
    */
   if (uni->type->is_sampler()) {
      for (int i = 0; i < count; i++) {
	 const unsigned texUnit = ((unsigned *) values)[i];

         /* check that the sampler (tex unit index) is legal */
         if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
            _mesa_error(ctx, GL_INVALID_VALUE,
                        "glUniform1i(invalid sampler/tex unit index for "
			"uniform %d)",
                        location);
            return;
         }
      }
   }

   if (uni->type->is_image()) {
      for (int i = 0; i < count; i++) {
         const int unit = ((GLint *) values)[i];

         /* check that the image unit is legal */
         if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
            _mesa_error(ctx, GL_INVALID_VALUE,
                        "glUniform1i(invalid image unit index for uniform %d)",
                        location);
            return;
         }
      }
   }

   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
    *
    *     "When loading N elements starting at an arbitrary position k in a
    *     uniform declared as an array, elements k through k + N - 1 in the
    *     array will be replaced with the new values. Values for any array
    *     element that exceeds the highest array element index used, as
    *     reported by GetActiveUniform, will be ignored by the GL."
    *
    * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
    * will have already generated an error.
    */
   if (uni->array_elements != 0) {
      count = MIN2(count, (int) (uni->array_elements - offset));
   }

   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);

   /* Store the data in the "actual type" backing storage for the uniform.
    */
   if (!uni->type->is_boolean()) {
      memcpy(&uni->storage[size_mul * components * offset], values,
	     sizeof(uni->storage[0]) * components * count * size_mul);
   } else {
      const union gl_constant_value *src =
	 (const union gl_constant_value *) values;
      union gl_constant_value *dst = &uni->storage[components * offset];
      const unsigned elems = components * count;

      for (unsigned i = 0; i < elems; i++) {
	 if (basicType == GLSL_TYPE_FLOAT) {
            dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
	 } else {
            dst[i].i = src[i].i != 0    ? ctx->Const.UniformBooleanTrue : 0;
	 }
      }
   }

   uni->initialized = true;

   _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);

   /* If the uniform is a sampler, do the extra magic necessary to propagate
    * the changes through.
    */
   if (uni->type->is_sampler()) {
      bool flushed = false;
      for (int i = 0; i < MESA_SHADER_STAGES; i++) {
	 struct gl_shader *const sh = shProg->_LinkedShaders[i];

	 /* If the shader stage doesn't use the sampler uniform, skip this.
	  */
	 if (sh == NULL || !uni->sampler[i].active)
	    continue;

         for (int j = 0; j < count; j++) {
            sh->SamplerUnits[uni->sampler[i].index + offset + j] =
               ((unsigned *) values)[j];
         }

	 struct gl_program *const prog = sh->Program;

	 assert(sizeof(prog->SamplerUnits) == sizeof(sh->SamplerUnits));

	 /* Determine if any of the samplers used by this shader stage have
	  * been modified.
	  */
	 bool changed = false;
	 for (unsigned j = 0; j < ARRAY_SIZE(prog->SamplerUnits); j++) {
	    if ((sh->active_samplers & (1U << j)) != 0
		&& (prog->SamplerUnits[j] != sh->SamplerUnits[j])) {
	       changed = true;
	       break;
	    }
	 }

	 if (changed) {
	    if (!flushed) {
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
	       flushed = true;
	    }

	    memcpy(prog->SamplerUnits,
		   sh->SamplerUnits,
		   sizeof(sh->SamplerUnits));

	    _mesa_update_shader_textures_used(shProg, prog);
            if (ctx->Driver.SamplerUniformChange)
	       ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
	 }
      }
   }

   /* If the uniform is an image, update the mapping from image
    * uniforms to image units present in the shader data structure.
    */
   if (uni->type->is_image()) {
      for (int i = 0; i < MESA_SHADER_STAGES; i++) {
	 if (uni->image[i].active) {
            struct gl_shader *sh = shProg->_LinkedShaders[i];

            for (int j = 0; j < count; j++)
               sh->ImageUnits[uni->image[i].index + offset + j] =
                  ((GLint *) values)[j];
         }
      }

      ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
   }
}
Exemple #20
0
/**
 * Check if the given texture target is a legal texture object target
 * for a glTexStorage() command.
 * This is a bit different than legal_teximage_target() when it comes
 * to cube maps.
 */
static bool
legal_texobj_target(const struct gl_context *ctx, GLuint dims, GLenum target)
{
   if (dims < 1 || dims > 3) {
      _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims);
      return false;
   }

   switch (dims) {
   case 2:
      switch (target) {
      case GL_TEXTURE_2D:
         return true;
      case GL_TEXTURE_CUBE_MAP:
         return ctx->Extensions.ARB_texture_cube_map;
      }
      break;
   case 3:
      switch (target) {
      case GL_TEXTURE_3D:
         return true;
      case GL_TEXTURE_2D_ARRAY:
         return ctx->Extensions.EXT_texture_array;
      case GL_TEXTURE_CUBE_MAP_ARRAY:
         return _mesa_has_texture_cube_map_array(ctx);
      }
      break;
   }

   if (!_mesa_is_desktop_gl(ctx))
      return false;

   switch (dims) {
   case 1:
      switch (target) {
      case GL_TEXTURE_1D:
      case GL_PROXY_TEXTURE_1D:
         return true;
      default:
         return false;
      }
   case 2:
      switch (target) {
      case GL_PROXY_TEXTURE_2D:
         return true;
      case GL_PROXY_TEXTURE_CUBE_MAP:
         return ctx->Extensions.ARB_texture_cube_map;
      case GL_TEXTURE_RECTANGLE:
      case GL_PROXY_TEXTURE_RECTANGLE:
         return ctx->Extensions.NV_texture_rectangle;
      case GL_TEXTURE_1D_ARRAY:
      case GL_PROXY_TEXTURE_1D_ARRAY:
         return ctx->Extensions.EXT_texture_array;
      default:
         return false;
      }
   case 3:
      switch (target) {
      case GL_PROXY_TEXTURE_3D:
         return true;
      case GL_PROXY_TEXTURE_2D_ARRAY:
         return ctx->Extensions.EXT_texture_array;
      case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
         return ctx->Extensions.ARB_texture_cube_map_array;
      default:
         return false;
      }
   default:
      unreachable("impossible dimensions");
   }
}
Exemple #21
0
/**
 * Use the per-vertex functions found in <vfmt> to initialize the given
 * API dispatch table.
 */
static void
install_vtxfmt(struct gl_context *ctx, struct _glapi_table *tab,
               const GLvertexformat *vfmt)
{
   assert(ctx->Version > 0);

   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_Color4f(tab, vfmt->Color4f);
   }

   if (ctx->API == API_OPENGL_COMPAT) {
      _mesa_install_arrayelt_vtxfmt(tab, vfmt);
      SET_Color3f(tab, vfmt->Color3f);
      SET_Color3fv(tab, vfmt->Color3fv);
      SET_Color4fv(tab, vfmt->Color4fv);
      SET_EdgeFlag(tab, vfmt->EdgeFlag);
   }

   if (ctx->API == API_OPENGL_COMPAT) {
      _mesa_install_eval_vtxfmt(tab, vfmt);
   }

   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_Materialfv(tab, vfmt->Materialfv);
      SET_MultiTexCoord4fARB(tab, vfmt->MultiTexCoord4fARB);
      SET_Normal3f(tab, vfmt->Normal3f);
   }

   if (ctx->API == API_OPENGL_COMPAT) {
      SET_FogCoordfEXT(tab, vfmt->FogCoordfEXT);
      SET_FogCoordfvEXT(tab, vfmt->FogCoordfvEXT);
      SET_Indexf(tab, vfmt->Indexf);
      SET_Indexfv(tab, vfmt->Indexfv);
      SET_MultiTexCoord1fARB(tab, vfmt->MultiTexCoord1fARB);
      SET_MultiTexCoord1fvARB(tab, vfmt->MultiTexCoord1fvARB);
      SET_MultiTexCoord2fARB(tab, vfmt->MultiTexCoord2fARB);
      SET_MultiTexCoord2fvARB(tab, vfmt->MultiTexCoord2fvARB);
      SET_MultiTexCoord3fARB(tab, vfmt->MultiTexCoord3fARB);
      SET_MultiTexCoord3fvARB(tab, vfmt->MultiTexCoord3fvARB);
      SET_MultiTexCoord4fvARB(tab, vfmt->MultiTexCoord4fvARB);
      SET_Normal3fv(tab, vfmt->Normal3fv);
   }

   if (ctx->API == API_OPENGL_COMPAT) {
      SET_SecondaryColor3fEXT(tab, vfmt->SecondaryColor3fEXT);
      SET_SecondaryColor3fvEXT(tab, vfmt->SecondaryColor3fvEXT);
      SET_TexCoord1f(tab, vfmt->TexCoord1f);
      SET_TexCoord1fv(tab, vfmt->TexCoord1fv);
      SET_TexCoord2f(tab, vfmt->TexCoord2f);
      SET_TexCoord2fv(tab, vfmt->TexCoord2fv);
      SET_TexCoord3f(tab, vfmt->TexCoord3f);
      SET_TexCoord3fv(tab, vfmt->TexCoord3fv);
      SET_TexCoord4f(tab, vfmt->TexCoord4f);
      SET_TexCoord4fv(tab, vfmt->TexCoord4fv);
      SET_Vertex2f(tab, vfmt->Vertex2f);
      SET_Vertex2fv(tab, vfmt->Vertex2fv);
      SET_Vertex3f(tab, vfmt->Vertex3f);
      SET_Vertex3fv(tab, vfmt->Vertex3fv);
      SET_Vertex4f(tab, vfmt->Vertex4f);
      SET_Vertex4fv(tab, vfmt->Vertex4fv);
   }

   if (ctx->API == API_OPENGL_COMPAT) {
      _mesa_install_dlist_vtxfmt(tab, vfmt);   /* glCallList / glCallLists */

      SET_Begin(tab, vfmt->Begin);
      SET_End(tab, vfmt->End);
      SET_PrimitiveRestartNV(tab, vfmt->PrimitiveRestartNV);

      SET_Rectf(tab, vfmt->Rectf);
   }

   SET_DrawArrays(tab, vfmt->DrawArrays);
   SET_DrawElements(tab, vfmt->DrawElements);
   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_DrawRangeElements(tab, vfmt->DrawRangeElements);
   }

   SET_MultiDrawElementsEXT(tab, vfmt->MultiDrawElementsEXT);

   if (_mesa_is_desktop_gl(ctx)) {
      SET_DrawElementsBaseVertex(tab, vfmt->DrawElementsBaseVertex);
      SET_DrawRangeElementsBaseVertex(tab, vfmt->DrawRangeElementsBaseVertex);
      SET_MultiDrawElementsBaseVertex(tab, vfmt->MultiDrawElementsBaseVertex);
      SET_DrawArraysInstancedBaseInstance(tab, vfmt->DrawArraysInstancedBaseInstance);
      SET_DrawElementsInstancedBaseInstance(tab, vfmt->DrawElementsInstancedBaseInstance);
      SET_DrawElementsInstancedBaseVertex(tab, vfmt->DrawElementsInstancedBaseVertex);
      SET_DrawElementsInstancedBaseVertexBaseInstance(tab, vfmt->DrawElementsInstancedBaseVertexBaseInstance);
   }

   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_DrawArraysInstancedARB(tab, vfmt->DrawArraysInstanced);
      SET_DrawElementsInstancedARB(tab, vfmt->DrawElementsInstanced);
   }

   if (_mesa_is_desktop_gl(ctx)) {
      SET_DrawTransformFeedback(tab, vfmt->DrawTransformFeedback);
      SET_DrawTransformFeedbackStream(tab, vfmt->DrawTransformFeedbackStream);
      SET_DrawTransformFeedbackInstanced(tab,
                                         vfmt->DrawTransformFeedbackInstanced);
      SET_DrawTransformFeedbackStreamInstanced(tab,
                                               vfmt->DrawTransformFeedbackStreamInstanced);
   }

   /* Originally for GL_NV_vertex_program, this is also used by dlist.c */
   if (ctx->API == API_OPENGL_COMPAT) {
      SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV);
      SET_VertexAttrib1fvNV(tab, vfmt->VertexAttrib1fvNV);
      SET_VertexAttrib2fNV(tab, vfmt->VertexAttrib2fNV);
      SET_VertexAttrib2fvNV(tab, vfmt->VertexAttrib2fvNV);
      SET_VertexAttrib3fNV(tab, vfmt->VertexAttrib3fNV);
      SET_VertexAttrib3fvNV(tab, vfmt->VertexAttrib3fvNV);
      SET_VertexAttrib4fNV(tab, vfmt->VertexAttrib4fNV);
      SET_VertexAttrib4fvNV(tab, vfmt->VertexAttrib4fvNV);
   }

   if (ctx->API != API_OPENGLES) {
      SET_VertexAttrib1fARB(tab, vfmt->VertexAttrib1fARB);
      SET_VertexAttrib1fvARB(tab, vfmt->VertexAttrib1fvARB);
      SET_VertexAttrib2fARB(tab, vfmt->VertexAttrib2fARB);
      SET_VertexAttrib2fvARB(tab, vfmt->VertexAttrib2fvARB);
      SET_VertexAttrib3fARB(tab, vfmt->VertexAttrib3fARB);
      SET_VertexAttrib3fvARB(tab, vfmt->VertexAttrib3fvARB);
      SET_VertexAttrib4fARB(tab, vfmt->VertexAttrib4fARB);
      SET_VertexAttrib4fvARB(tab, vfmt->VertexAttrib4fvARB);
   }

   /* GL_EXT_gpu_shader4 / OpenGL 3.0 */
   if (_mesa_is_desktop_gl(ctx)) {
      SET_VertexAttribI1iEXT(tab, vfmt->VertexAttribI1i);
      SET_VertexAttribI2iEXT(tab, vfmt->VertexAttribI2i);
      SET_VertexAttribI3iEXT(tab, vfmt->VertexAttribI3i);
      SET_VertexAttribI2ivEXT(tab, vfmt->VertexAttribI2iv);
      SET_VertexAttribI3ivEXT(tab, vfmt->VertexAttribI3iv);

      SET_VertexAttribI1uiEXT(tab, vfmt->VertexAttribI1ui);
      SET_VertexAttribI2uiEXT(tab, vfmt->VertexAttribI2ui);
      SET_VertexAttribI3uiEXT(tab, vfmt->VertexAttribI3ui);
      SET_VertexAttribI2uivEXT(tab, vfmt->VertexAttribI2uiv);
      SET_VertexAttribI3uivEXT(tab, vfmt->VertexAttribI3uiv);
   }

   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_VertexAttribI4iEXT(tab, vfmt->VertexAttribI4i);
      SET_VertexAttribI4ivEXT(tab, vfmt->VertexAttribI4iv);
      SET_VertexAttribI4uiEXT(tab, vfmt->VertexAttribI4ui);
      SET_VertexAttribI4uivEXT(tab, vfmt->VertexAttribI4uiv);
   }

   if (ctx->API == API_OPENGL_COMPAT) {
      /* GL_ARB_vertex_type_10_10_10_2_rev / GL 3.3 */
      SET_VertexP2ui(tab, vfmt->VertexP2ui);
      SET_VertexP2uiv(tab, vfmt->VertexP2uiv);
      SET_VertexP3ui(tab, vfmt->VertexP3ui);
      SET_VertexP3uiv(tab, vfmt->VertexP3uiv);
      SET_VertexP4ui(tab, vfmt->VertexP4ui);
      SET_VertexP4uiv(tab, vfmt->VertexP4uiv);

      SET_TexCoordP1ui(tab, vfmt->TexCoordP1ui);
      SET_TexCoordP1uiv(tab, vfmt->TexCoordP1uiv);
      SET_TexCoordP2ui(tab, vfmt->TexCoordP2ui);
      SET_TexCoordP2uiv(tab, vfmt->TexCoordP2uiv);
      SET_TexCoordP3ui(tab, vfmt->TexCoordP3ui);
      SET_TexCoordP3uiv(tab, vfmt->TexCoordP3uiv);
      SET_TexCoordP4ui(tab, vfmt->TexCoordP4ui);
      SET_TexCoordP4uiv(tab, vfmt->TexCoordP4uiv);

      SET_MultiTexCoordP1ui(tab, vfmt->MultiTexCoordP1ui);
      SET_MultiTexCoordP2ui(tab, vfmt->MultiTexCoordP2ui);
      SET_MultiTexCoordP3ui(tab, vfmt->MultiTexCoordP3ui);
      SET_MultiTexCoordP4ui(tab, vfmt->MultiTexCoordP4ui);
      SET_MultiTexCoordP1uiv(tab, vfmt->MultiTexCoordP1uiv);
      SET_MultiTexCoordP2uiv(tab, vfmt->MultiTexCoordP2uiv);
      SET_MultiTexCoordP3uiv(tab, vfmt->MultiTexCoordP3uiv);
      SET_MultiTexCoordP4uiv(tab, vfmt->MultiTexCoordP4uiv);

      SET_NormalP3ui(tab, vfmt->NormalP3ui);
      SET_NormalP3uiv(tab, vfmt->NormalP3uiv);

      SET_ColorP3ui(tab, vfmt->ColorP3ui);
      SET_ColorP4ui(tab, vfmt->ColorP4ui);
      SET_ColorP3uiv(tab, vfmt->ColorP3uiv);
      SET_ColorP4uiv(tab, vfmt->ColorP4uiv);

      SET_SecondaryColorP3ui(tab, vfmt->SecondaryColorP3ui);
      SET_SecondaryColorP3uiv(tab, vfmt->SecondaryColorP3uiv);
   }

   if (_mesa_is_desktop_gl(ctx)) {
      SET_VertexAttribP1ui(tab, vfmt->VertexAttribP1ui);
      SET_VertexAttribP2ui(tab, vfmt->VertexAttribP2ui);
      SET_VertexAttribP3ui(tab, vfmt->VertexAttribP3ui);
      SET_VertexAttribP4ui(tab, vfmt->VertexAttribP4ui);

      SET_VertexAttribP1uiv(tab, vfmt->VertexAttribP1uiv);
      SET_VertexAttribP2uiv(tab, vfmt->VertexAttribP2uiv);
      SET_VertexAttribP3uiv(tab, vfmt->VertexAttribP3uiv);
      SET_VertexAttribP4uiv(tab, vfmt->VertexAttribP4uiv);
   }
}
Exemple #22
0
/**
 * Create a framebuffer from a manager interface.
 */
static struct st_framebuffer *
st_framebuffer_create(struct st_context *st,
                      struct st_framebuffer_iface *stfbi)
{
   struct st_framebuffer *stfb;
   struct gl_config mode;
   gl_buffer_index idx;

   if (!stfbi)
      return NULL;

   stfb = CALLOC_STRUCT(st_framebuffer);
   if (!stfb)
      return NULL;

   st_visual_to_context_mode(stfbi->visual, &mode);

   /*
    * For desktop GL, sRGB framebuffer write is controlled by both the
    * capability of the framebuffer and GL_FRAMEBUFFER_SRGB.  We should
    * advertise the capability when the pipe driver (and core Mesa) supports
    * it so that applications can enable sRGB write when they want to.
    *
    * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB.  When
    * the attribute is GLX_TRUE, it tells the st manager to pick a color
    * format such that util_format_srgb(visual->color_format) can be supported
    * by the pipe driver.  We still need to advertise the capability here.
    *
    * For GLES, however, sRGB framebuffer write is controlled only by the
    * capability of the framebuffer.  There is GL_EXT_sRGB_write_control to
    * give applications the control back, but sRGB write is still enabled by
    * default.  To avoid unexpected results, we should not advertise the
    * capability.  This could change when we add support for
    * EGL_KHR_gl_colorspace.
    */
   if (_mesa_is_desktop_gl(st->ctx)) {
      struct pipe_screen *screen = st->pipe->screen;
      const enum pipe_format srgb_format =
         util_format_srgb(stfbi->visual->color_format);

      if (srgb_format != PIPE_FORMAT_NONE &&
          st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE &&
          screen->is_format_supported(screen, srgb_format,
                                      PIPE_TEXTURE_2D, stfbi->visual->samples,
                                      PIPE_BIND_RENDER_TARGET))
         mode.sRGBCapable = GL_TRUE;
   }

   _mesa_initialize_window_framebuffer(&stfb->Base, &mode);

   stfb->iface = stfbi;
   stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1;

   /* add the color buffer */
   idx = stfb->Base._ColorDrawBufferIndexes[0];
   if (!st_framebuffer_add_renderbuffer(stfb, idx)) {
      free(stfb);
      return NULL;
   }

   st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH);
   st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM);

   stfb->stamp = 0;
   st_framebuffer_update_attachments(stfb);

   return stfb;
}
Exemple #23
0
void GLAPIENTRY
_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
                          GLsizei bufSize, GLint *params)
{
   GLint buffer[16];
   GLsizei count = 0;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!ctx->Extensions.ARB_internalformat_query) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ");
      return;
   }

   assert(ctx->Driver.QuerySamplesForFormat != NULL);

   /* The ARB_internalformat_query spec says:
    *
    *     "If the <target> parameter to GetInternalformativ is not one of
    *     TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY or RENDERBUFFER
    *     then an INVALID_ENUM error is generated."
    */
   switch (target) {
   case GL_RENDERBUFFER:
      break;

   case GL_TEXTURE_2D_MULTISAMPLE:
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
      /* These enums are only valid if ARB_texture_multisample is supported */
      if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample)
         break;

   default:
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetInternalformativ(target=%s)",
                  _mesa_lookup_enum_by_nr(target));
      return;
   }

   /* The ARB_internalformat_query spec says:
    *
    *     "If the <internalformat> parameter to GetInternalformativ is not
    *     color-, depth- or stencil-renderable, then an INVALID_ENUM error is
    *     generated."
    *
    * Page 243 of the GLES 3.0.4 spec says this for GetInternalformativ:
    *
    *     "internalformat must be color-renderable, depth-renderable or
    *     stencilrenderable (as defined in section 4.4.4)."
    *
    * Section 4.4.4 on page 212 of the same spec says:
    *
    *     "An internal format is color-renderable if it is one of the
    *     formats from table 3.13 noted as color-renderable or if it
    *     is unsized format RGBA or RGB."
    *
    * Therefore, we must accept GL_RGB and GL_RGBA here.
    */
   if (internalformat != GL_RGB && internalformat != GL_RGBA &&
       _mesa_base_fbo_format(ctx, internalformat) == 0) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetInternalformativ(internalformat=%s)",
                  _mesa_lookup_enum_by_nr(internalformat));
      return;
   }

   /* The ARB_internalformat_query spec says:
    *
    *     "If the <bufSize> parameter to GetInternalformativ is negative, then
    *     an INVALID_VALUE error is generated."
    */
   if (bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetInternalformativ(target=%s)",
                  _mesa_lookup_enum_by_nr(target));
      return;
   }

   switch (pname) {
   case GL_SAMPLES:
      count = ctx->Driver.QuerySamplesForFormat(ctx, target,
            internalformat, buffer);
      break;
   case GL_NUM_SAMPLE_COUNTS: {
      if (_mesa_is_gles3(ctx) && _mesa_is_enum_format_integer(internalformat)) {
         /* From GL ES 3.0 specification, section 6.1.15 page 236: "Since
          * multisampling is not supported for signed and unsigned integer
          * internal formats, the value of NUM_SAMPLE_COUNTS will be zero
          * for such formats.
          */
         buffer[0] = 0;
         count = 1;
      } else {
         size_t num_samples;

         /* The driver can return 0, and we should pass that along to the
          * application.  The ARB decided that ARB_internalformat_query should
          * behave as ARB_internalformat_query2 in this situation.
          *
          * The ARB_internalformat_query2 spec says:
          *
          *     "- NUM_SAMPLE_COUNTS: The number of sample counts that would be
          *        returned by querying SAMPLES is returned in <params>.
          *        * If <internalformat> is not color-renderable,
          *          depth-renderable, or stencil-renderable (as defined in
          *          section 4.4.4), or if <target> does not support multiple
          *          samples (ie other than TEXTURE_2D_MULTISAMPLE,
          *          TEXTURE_2D_MULTISAMPLE_ARRAY, or RENDERBUFFER), 0 is
          *          returned."
          */
         num_samples =  ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer);

         /* QuerySamplesForFormat writes some stuff to buffer, so we have to
          * separately over-write it with the requested value.
          */
         buffer[0] = (GLint) num_samples;
         count = 1;
      }
      break;
   }
   default:
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetInternalformativ(pname=%s)",
                  _mesa_lookup_enum_by_nr(pname));
      return;
   }

   if (bufSize != 0 && params == NULL) {
      /* Emit a warning to aid application debugging, but go ahead and do the
       * memcpy (and probably crash) anyway.
       */
      _mesa_warning(ctx,
                    "glGetInternalformativ(bufSize = %d, but params = NULL)",
                    bufSize);
   }

   /* Copy the data from the temporary buffer to the buffer supplied by the
    * application.  Clamp the size of the copy to the size supplied by the
    * application.
    */
   memcpy(params, buffer, MIN2(count, bufSize) * sizeof(GLint));

   return;
}
Exemple #24
0
void GLAPIENTRY
_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
                          GLsizei bufSize, GLint *params)
{
   GLint buffer[16];
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   /* ARB_internalformat_query is also mandatory for ARB_internalformat_query2 */
   if (!(_mesa_has_ARB_internalformat_query(ctx) ||
         _mesa_is_gles3(ctx))) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ");
      return;
   }

   assert(ctx->Driver.QueryInternalFormat != NULL);

   if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params))
      return;

   /* initialize the contents of the temporary buffer */
   memcpy(buffer, params, MIN2(bufSize, 16) * sizeof(GLint));

   /* Use the 'unsupported' response defined by the spec for every pname
    * as the default answer.
    */
   _set_default_response(pname, buffer);

   if (!_is_target_supported(ctx, target) ||
       !_is_internalformat_supported(ctx, target, internalformat) ||
       !_is_resource_supported(ctx, target, internalformat, pname))
      goto end;

   switch (pname) {
   case GL_SAMPLES:
      /* fall-through */
   case GL_NUM_SAMPLE_COUNTS:
      /* The ARB_internalformat_query2 sets the response as 'unsupported' for
       * SAMPLES and NUM_SAMPLE_COUNTS:
       *
       *     "If <internalformat> is not color-renderable, depth-renderable, or
       *     stencil-renderable (as defined in section 4.4.4), or if <target>
       *     does not support multiple samples (ie other than
       *     TEXTURE_2D_MULTISAMPLE,  TEXTURE_2D_MULTISAMPLE_ARRAY,
       *     or RENDERBUFFER)."
       */
      if ((target != GL_RENDERBUFFER &&
           target != GL_TEXTURE_2D_MULTISAMPLE &&
           target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) ||
          !_is_renderable(ctx, internalformat))
         goto end;

      /* The GL ES 3.0 specification, section 6.1.15 page 236 says:
       *
       *     "Since multisampling is not supported for signed and unsigned
       *     integer internal formats, the value of NUM_SAMPLE_COUNTS will be
       *     zero for such formats.
       *
       * Since OpenGL ES 3.1 adds support for multisampled integer formats, we
       * have to check the version for 30 exactly.
       */
      if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 &&
          ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) {
         goto end;
      }

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_INTERNALFORMAT_SUPPORTED:
      /* Having a supported <internalformat> is implemented as a prerequisite
       * for all the <pnames>. Thus,  if we reach this point, the internalformat is
       * supported.
       */
      buffer[0] = GL_TRUE;
      break;

   case GL_INTERNALFORMAT_PREFERRED:
      /* The ARB_internalformat_query2 spec says:
       *
       *     "- INTERNALFORMAT_PREFERRED: The implementation-preferred internal
       *     format for representing resources of the specified <internalformat> is
       *     returned in <params>.
       *
       * Therefore, we let the driver answer. Note that if we reach this
       * point, it means that the internalformat is supported, so the driver
       * is called just to try to get a preferred format. If not supported,
       * GL_NONE was already returned and the driver is not called.
       */
      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_INTERNALFORMAT_RED_SIZE:
   case GL_INTERNALFORMAT_GREEN_SIZE:
   case GL_INTERNALFORMAT_BLUE_SIZE:
   case GL_INTERNALFORMAT_ALPHA_SIZE:
   case GL_INTERNALFORMAT_DEPTH_SIZE:
   case GL_INTERNALFORMAT_STENCIL_SIZE:
   case GL_INTERNALFORMAT_SHARED_SIZE:
   case GL_INTERNALFORMAT_RED_TYPE:
   case GL_INTERNALFORMAT_GREEN_TYPE:
   case GL_INTERNALFORMAT_BLUE_TYPE:
   case GL_INTERNALFORMAT_ALPHA_TYPE:
   case GL_INTERNALFORMAT_DEPTH_TYPE:
   case GL_INTERNALFORMAT_STENCIL_TYPE: {
      GLint baseformat;
      mesa_format texformat;

      if (target != GL_RENDERBUFFER) {
         if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true))
            goto end;

         baseformat = _mesa_base_tex_format(ctx, internalformat);
      } else {
         baseformat = _mesa_base_fbo_format(ctx, internalformat);
      }

      /* Let the driver choose the texture format.
       *
       * Disclaimer: I am considering that drivers use for renderbuffers the
       * same format-choice logic as for textures.
       */
      texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat,
                                                  GL_NONE /*format */, GL_NONE /* type */);

      if (texformat == MESA_FORMAT_NONE || baseformat <= 0)
         goto end;

      /* Implementation based on what Mesa does for glGetTexLevelParameteriv
       * and glGetRenderbufferParameteriv functions.
       */
      if (pname == GL_INTERNALFORMAT_SHARED_SIZE) {
         if (_mesa_has_EXT_texture_shared_exponent(ctx) &&
             target != GL_TEXTURE_BUFFER &&
             target != GL_RENDERBUFFER &&
             texformat == MESA_FORMAT_R9G9B9E5_FLOAT) {
            buffer[0] = 5;
         }
         goto end;
      }

      if (!_mesa_base_format_has_channel(baseformat, pname))
         goto end;

      switch (pname) {
      case GL_INTERNALFORMAT_DEPTH_SIZE:
         if (ctx->API != API_OPENGL_CORE &&
             !_mesa_has_ARB_depth_texture(ctx) &&
             target != GL_RENDERBUFFER &&
             target != GL_TEXTURE_BUFFER)
            goto end;
         /* fallthrough */
      case GL_INTERNALFORMAT_RED_SIZE:
      case GL_INTERNALFORMAT_GREEN_SIZE:
      case GL_INTERNALFORMAT_BLUE_SIZE:
      case GL_INTERNALFORMAT_ALPHA_SIZE:
      case GL_INTERNALFORMAT_STENCIL_SIZE:
         buffer[0] = _mesa_get_format_bits(texformat, pname);
         break;

      case GL_INTERNALFORMAT_DEPTH_TYPE:
         if (!_mesa_has_ARB_texture_float(ctx))
            goto end;
         /* fallthrough */
      case GL_INTERNALFORMAT_RED_TYPE:
      case GL_INTERNALFORMAT_GREEN_TYPE:
      case GL_INTERNALFORMAT_BLUE_TYPE:
      case GL_INTERNALFORMAT_ALPHA_TYPE:
      case GL_INTERNALFORMAT_STENCIL_TYPE:
         buffer[0]  = _mesa_get_format_datatype(texformat);
         break;

      default:
         break;

      }
      break;
   }

      /* For WIDTH/HEIGHT/DEPTH/LAYERS there is no reason to think that the
       * returned values should be different to the values returned by
       * GetInteger with MAX_TEXTURE_SIZE, MAX_3D_TEXTURE_SIZE, etc.*/
   case GL_MAX_WIDTH:
   case GL_MAX_HEIGHT:
   case GL_MAX_DEPTH: {
      GLenum get_pname;
      GLint dimensions;
      GLint min_dimensions;

      /* From query2:MAX_HEIGHT spec (as example):
       *
       * "If the resource does not have at least two dimensions, or if the
       * resource is unsupported, zero is returned."
       */
      dimensions = _get_target_dimensions(target);
      min_dimensions = _get_min_dimensions(pname);
      if (dimensions < min_dimensions)
         goto end;

      get_pname = _equivalent_size_pname(target, pname);
      if (get_pname == 0)
         goto end;

      _mesa_GetIntegerv(get_pname, buffer);
      break;
   }

   case GL_MAX_LAYERS:
      if (!_mesa_has_EXT_texture_array(ctx))
         goto end;

      if (!_mesa_is_array_texture(target))
         goto end;

      _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer);
      break;

   case GL_MAX_COMBINED_DIMENSIONS:{
      GLint64 combined_value = 1;
      GLenum max_dimensions_pnames[] = {
         GL_MAX_WIDTH,
         GL_MAX_HEIGHT,
         GL_MAX_DEPTH,
         GL_SAMPLES
      };
      unsigned i;
      GLint current_value;

      /* Combining the dimensions. Note that for array targets, this would
       * automatically include the value of MAX_LAYERS, as that value is
       * returned as MAX_HEIGHT or MAX_DEPTH */
      for (i = 0; i < 4; i++) {
         if (max_dimensions_pnames[i] == GL_SAMPLES &&
             !_is_multisample_target(target))
            continue;

         _mesa_GetInternalformativ(target, internalformat,
                                   max_dimensions_pnames[i],
                                   1, &current_value);

         if (current_value != 0)
            combined_value *= current_value;
      }

      if (_mesa_is_cube_map_texture(target))
         combined_value *= 6;

      /* We pack the 64-bit value on two 32-bit values. Calling the 32-bit
       * query, this would work as far as the value can be hold on a 32-bit
       * signed integer. For the 64-bit query, the wrapper around the 32-bit
       * query will unpack the value */
      memcpy(buffer, &combined_value, sizeof(GLint64));
      break;
   }

   case GL_COLOR_COMPONENTS:
      /* The ARB_internalformat_query2 spec says:
       *
       *     "- COLOR_COMPONENTS: If the internal format contains any color
       *     components (R, G, B, or A), TRUE is returned in <params>.
       *     If the internal format is unsupported or contains no color
       *     components, FALSE is returned."
       */
      if (_mesa_is_color_format(internalformat))
         buffer[0] = GL_TRUE;
      break;

   case GL_DEPTH_COMPONENTS:
      /* The ARB_internalformat_query2 spec says:
       *
       *     "- DEPTH_COMPONENTS: If the internal format contains a depth
       *     component (D), TRUE is returned in <params>. If the internal format
       *     is unsupported or contains no depth component, FALSE is returned."
       */
      if (_mesa_is_depth_format(internalformat) ||
          _mesa_is_depthstencil_format(internalformat))
         buffer[0] = GL_TRUE;
      break;

   case GL_STENCIL_COMPONENTS:
      /* The ARB_internalformat_query2 spec says:
       *
       *     "- STENCIL_COMPONENTS: If the internal format contains a stencil
       *     component (S), TRUE is returned in <params>. If the internal format
       *     is unsupported or contains no stencil component, FALSE is returned.
       */
      if (_mesa_is_stencil_format(internalformat) ||
          _mesa_is_depthstencil_format(internalformat))
         buffer[0] = GL_TRUE;
      break;

   case GL_COLOR_RENDERABLE:
   case GL_DEPTH_RENDERABLE:
   case GL_STENCIL_RENDERABLE:
      if (!_is_renderable(ctx, internalformat))
         goto end;

      if (pname == GL_COLOR_RENDERABLE) {
         if (!_mesa_is_color_format(internalformat))
            goto end;
      } else {
         GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
         if (baseFormat != GL_DEPTH_STENCIL &&
             ((pname == GL_DEPTH_RENDERABLE && baseFormat != GL_DEPTH_COMPONENT) ||
              (pname == GL_STENCIL_RENDERABLE && baseFormat != GL_STENCIL_INDEX)))
            goto end;
      }

      buffer[0] = GL_TRUE;
      break;

   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
      if (!_mesa_has_EXT_texture_array(ctx) ||
          _legal_target_for_framebuffer_texture_layer(ctx, target))
         goto end;
      /* fallthrough */
   case GL_FRAMEBUFFER_RENDERABLE:
   case GL_FRAMEBUFFER_BLEND:
      if (!_mesa_has_ARB_framebuffer_object(ctx))
         goto end;

      if (target == GL_TEXTURE_BUFFER ||
          !_is_renderable(ctx, internalformat))
         goto end;

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_READ_PIXELS:
   case GL_READ_PIXELS_FORMAT:
   case GL_READ_PIXELS_TYPE:
      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_TEXTURE_IMAGE_FORMAT:
   case GL_GET_TEXTURE_IMAGE_FORMAT:
   case GL_TEXTURE_IMAGE_TYPE:
   case GL_GET_TEXTURE_IMAGE_TYPE:
      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_MIPMAP:
   case GL_MANUAL_GENERATE_MIPMAP:
   case GL_AUTO_GENERATE_MIPMAP:
      if (!_mesa_is_valid_generate_texture_mipmap_target(ctx, target) ||
          !_mesa_is_valid_generate_texture_mipmap_internalformat(ctx,
                                                              internalformat)) {
         goto end;
      }

      if (pname == GL_MIPMAP) {
         buffer[0] = GL_TRUE;
         goto end;
      }
      else if (pname == GL_MANUAL_GENERATE_MIPMAP) {
         if (!_mesa_has_ARB_framebuffer_object(ctx))
            goto end;
      }
      else {
         /* From ARB_internalformat_query2:
          *    "Dependencies on OpenGL 3.2 (Core Profile)
          *     In core profiles for OpenGL 3.2 and later versions, queries
          *     for the AUTO_GENERATE_MIPMAP <pname> return the appropriate
          *     unsupported response."
          */
         if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 32)
            goto end;
      }

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_COLOR_ENCODING:
      if (!_mesa_is_color_format(internalformat))
         goto end;

      if (_mesa_is_srgb_format(internalformat))
         buffer[0] = GL_SRGB;
      else
         buffer[0] = GL_LINEAR;
      break;

   case GL_SRGB_READ:
      if (!_mesa_has_EXT_texture_sRGB(ctx) ||
          !_mesa_is_srgb_format(internalformat)) {
         goto end;
      }

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_SRGB_WRITE:
      if (!_mesa_has_EXT_framebuffer_sRGB(ctx) ||
          !_mesa_is_color_format(internalformat)) {
         goto end;
      }

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_SRGB_DECODE_ARB:
      /* Presence of EXT_texture_sRGB_decode was already verified */
      if (!_mesa_has_EXT_texture_sRGB(ctx) ||
          target == GL_RENDERBUFFER ||
          !_mesa_is_srgb_format(internalformat)) {
         goto end;
      }

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_FILTER:
      /* If it doesn't allow to set sampler parameters then it would not allow
       * to set a filter different to GL_NEAREST. In practice, this method
       * only filters out MULTISAMPLE/MULTISAMPLE_ARRAY */
      if (!_mesa_target_allows_setting_sampler_parameters(target))
         goto end;

      if (_mesa_is_enum_format_integer(internalformat))
         goto end;

      if (target == GL_TEXTURE_BUFFER)
         goto end;

      /* At this point we know that multi-texel filtering is supported. We
       * need to call the driver to know if it is CAVEAT_SUPPORT or
       * FULL_SUPPORT.
       */
      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_VERTEX_TEXTURE:
   case GL_TESS_CONTROL_TEXTURE:
   case GL_TESS_EVALUATION_TEXTURE:
   case GL_GEOMETRY_TEXTURE:
   case GL_FRAGMENT_TEXTURE:
   case GL_COMPUTE_TEXTURE:
      if (target == GL_RENDERBUFFER)
         goto end;

      if ((pname == GL_TESS_CONTROL_TEXTURE ||
           pname == GL_TESS_EVALUATION_TEXTURE) &&
          !_mesa_has_tessellation(ctx))
         goto end;

      if (pname == GL_GEOMETRY_TEXTURE && !_mesa_has_geometry_shaders(ctx))
         goto end;

      if (pname == GL_COMPUTE_TEXTURE && !_mesa_has_compute_shaders(ctx))
         goto end;

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_TEXTURE_GATHER:
   case GL_TEXTURE_GATHER_SHADOW:
      if (!_mesa_has_ARB_texture_gather(ctx))
         goto end;

      /* fallthrough */
   case GL_TEXTURE_SHADOW:
      /* Only depth or depth-stencil image formats make sense in shadow
         samplers */
      if (pname != GL_TEXTURE_GATHER &&
          !_mesa_is_depth_format(internalformat) &&
          !_mesa_is_depthstencil_format(internalformat))
         goto end;

      /* Validate the target for shadow and gather operations */
      switch (target) {
      case GL_TEXTURE_2D:
      case GL_TEXTURE_2D_ARRAY:
      case GL_TEXTURE_CUBE_MAP:
      case GL_TEXTURE_CUBE_MAP_ARRAY:
      case GL_TEXTURE_RECTANGLE:
         break;

      case GL_TEXTURE_1D:
      case GL_TEXTURE_1D_ARRAY:
         /* 1D and 1DArray textures are not admitted in gather operations */
         if (pname != GL_TEXTURE_SHADOW)
            goto end;
         break;

      default:
         goto end;
      }

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_SHADER_IMAGE_LOAD:
   case GL_SHADER_IMAGE_STORE:
      if (!_mesa_has_ARB_shader_image_load_store(ctx))
         goto end;

      /* We call to _mesa_is_shader_image_format_supported
       * using "internalformat" as parameter, because the
       * the ARB_internalformat_query2 spec says:
       * "In this case the <internalformat> is the value of the <format>
       * parameter that is passed to BindImageTexture."
       */
      if (target == GL_RENDERBUFFER ||
          !_mesa_is_shader_image_format_supported(ctx, internalformat))
         goto end;

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_SHADER_IMAGE_ATOMIC:
      if (!_mesa_has_ARB_shader_image_load_store(ctx))
         goto end;

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_IMAGE_TEXEL_SIZE: {
      mesa_format image_format;

      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
          target == GL_RENDERBUFFER)
         goto end;

      image_format = _mesa_get_shader_image_format(internalformat);
      if (image_format == MESA_FORMAT_NONE)
         goto end;

      /* We return bits */
      buffer[0] = (_mesa_get_format_bytes(image_format) * 8);
      break;
   }

   case GL_IMAGE_COMPATIBILITY_CLASS:
      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
          target == GL_RENDERBUFFER)
         goto end;

      buffer[0] = _mesa_get_image_format_class(internalformat);
      break;

   case GL_IMAGE_PIXEL_FORMAT: {
      GLint base_format;

      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
          target == GL_RENDERBUFFER ||
          !_mesa_is_shader_image_format_supported(ctx, internalformat))
         goto end;

      base_format = _mesa_base_tex_format(ctx, internalformat);
      if (base_format == -1)
         goto end;

      if (_mesa_is_enum_format_integer(internalformat))
         buffer[0] = _mesa_base_format_to_integer_format(base_format);
      else
         buffer[0] = base_format;
      break;
   }

   case GL_IMAGE_PIXEL_TYPE: {
      mesa_format image_format;
      GLenum datatype;
      GLuint comps;

      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
          target == GL_RENDERBUFFER)
         goto end;

      image_format = _mesa_get_shader_image_format(internalformat);
      if (image_format == MESA_FORMAT_NONE)
         goto end;

      _mesa_uncompressed_format_to_type_and_comps(image_format, &datatype,
                                                  &comps);
      if (!datatype)
         goto end;

      buffer[0] = datatype;
      break;
   }

   case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: {
      if (!_mesa_has_ARB_shader_image_load_store(ctx))
         goto end;

      if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true))
         goto end;

      /* From spec: "Equivalent to calling GetTexParameter with <value> set
       * to IMAGE_FORMAT_COMPATIBILITY_TYPE."
       *
       * GetTexParameter just returns
       * tex_obj->ImageFormatCompatibilityType. We create a fake tex_obj
       * just with the purpose of getting the value.
       */
      struct gl_texture_object *tex_obj = _mesa_new_texture_object(ctx, 0, target);
      buffer[0] = tex_obj->ImageFormatCompatibilityType;
      _mesa_delete_texture_object(ctx, tex_obj);

      break;
   }

   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
      if (target == GL_RENDERBUFFER)
         goto end;

      if (!_mesa_is_depthstencil_format(internalformat)) {
         if (((pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST ||
               pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) &&
              !_mesa_is_depth_format(internalformat)) ||
             ((pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST ||
               pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) &&
              !_mesa_is_stencil_format(internalformat)))
            goto end;
      }

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_TEXTURE_COMPRESSED:
      buffer[0] = _mesa_is_compressed_format(ctx, internalformat);
      break;

   case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
   case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
   case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: {
      mesa_format mesaformat;
      GLint block_size;

      mesaformat = _mesa_glenum_to_compressed_format(internalformat);
      if (mesaformat == MESA_FORMAT_NONE)
         goto end;

      block_size = _mesa_get_format_bytes(mesaformat);
      assert(block_size > 0);

      if (pname == GL_TEXTURE_COMPRESSED_BLOCK_SIZE) {
         buffer[0] = block_size;
      } else {
         GLuint bwidth, bheight;

         /* Returns the width and height in pixels. We return bytes */
         _mesa_get_format_block_size(mesaformat, &bwidth, &bheight);
         assert(bwidth > 0 && bheight > 0);

         if (pname == GL_TEXTURE_COMPRESSED_BLOCK_WIDTH)
            buffer[0] = block_size / bheight;
         else
            buffer[0] = block_size / bwidth;
      }
      break;
   }

   case GL_CLEAR_BUFFER:
      if (target != GL_TEXTURE_BUFFER)
         goto end;

      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                      buffer);
      break;

   case GL_TEXTURE_VIEW:
   case GL_VIEW_COMPATIBILITY_CLASS:
      if (!_mesa_has_ARB_texture_view(ctx) ||
          target == GL_TEXTURE_BUFFER ||
          target == GL_RENDERBUFFER)
         goto end;

      if (pname == GL_TEXTURE_VIEW) {
         ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
                                         buffer);
      } else {
         GLenum view_class = _mesa_texture_view_lookup_view_class(ctx,
                                                                  internalformat);
         if (view_class == GL_FALSE)
            goto end;

         buffer[0] = view_class;
      }
      break;

   default:
      unreachable("bad param");
   }

 end:
   if (bufSize != 0 && params == NULL) {
      /* Emit a warning to aid application debugging, but go ahead and do the
       * memcpy (and probably crash) anyway.
       */
      _mesa_warning(ctx,
                    "glGetInternalformativ(bufSize = %d, but params = NULL)",
                    bufSize);
   }

   /* Copy the data from the temporary buffer to the buffer supplied by the
    * application.  Clamp the size of the copy to the size supplied by the
    * application.
    */
   memcpy(params, buffer, MIN2(bufSize, 16) * sizeof(GLint));

   return;
}
Exemple #25
0
static bool
_is_target_supported(struct gl_context *ctx, GLenum target)
{
   /* The ARB_internalformat_query2 spec says:
    *
    *     "if a particular type of <target> is not supported by the
    *     implementation the "unsupported" answer should be given.
    *     This is not an error."
    *
    * For OpenGL ES, queries can only be used with GL_RENDERBUFFER or MS.
    */
   switch(target){
   case GL_TEXTURE_1D:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_3D:
      if (!_mesa_is_desktop_gl(ctx))
         return false;
      break;

   case GL_TEXTURE_1D_ARRAY:
      if (!_mesa_has_EXT_texture_array(ctx))
         return false;
      break;

   case GL_TEXTURE_2D_ARRAY:
      if (!_mesa_has_EXT_texture_array(ctx))
         return false;
      break;

   case GL_TEXTURE_CUBE_MAP:
      if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx))
         return false;
      break;

   case GL_TEXTURE_CUBE_MAP_ARRAY:
      if (!_mesa_has_ARB_texture_cube_map_array(ctx))
         return false;
      break;

   case GL_TEXTURE_RECTANGLE:
      if (!_mesa_has_ARB_texture_rectangle(ctx))
          return false;
      break;

   case GL_TEXTURE_BUFFER:
      if (!_mesa_has_ARB_texture_buffer_object(ctx))
         return false;
      break;

   case GL_RENDERBUFFER:
      if (!(_mesa_has_ARB_framebuffer_object(ctx) ||
            _mesa_is_gles3(ctx)))
         return false;
      break;

   case GL_TEXTURE_2D_MULTISAMPLE:
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
      if (!(_mesa_has_ARB_texture_multisample(ctx) ||
            _mesa_is_gles31(ctx)))
         return false;
      break;

   default:
      unreachable("invalid target");
   }

   return true;
}
Exemple #26
0
void GLAPIENTRY
_mesa_Hint( GLenum target, GLenum mode )
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glHint %s %s\n",
                  _mesa_enum_to_string(target),
                  _mesa_enum_to_string(mode));

   if (mode != GL_NICEST && mode != GL_FASTEST && mode != GL_DONT_CARE) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glHint(mode)");
      return;
   }

   switch (target) {
      case GL_FOG_HINT:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_target;
         if (ctx->Hint.Fog == mode)
	    return;
	 FLUSH_VERTICES(ctx, _NEW_HINT);
         ctx->Hint.Fog = mode;
         break;
      case GL_LINE_SMOOTH_HINT:
         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
            goto invalid_target;
         if (ctx->Hint.LineSmooth == mode)
	    return;
	 FLUSH_VERTICES(ctx, _NEW_HINT);
         ctx->Hint.LineSmooth = mode;
         break;
      case GL_PERSPECTIVE_CORRECTION_HINT:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_target;
         if (ctx->Hint.PerspectiveCorrection == mode)
	    return;
	 FLUSH_VERTICES(ctx, _NEW_HINT);
         ctx->Hint.PerspectiveCorrection = mode;
         break;
      case GL_POINT_SMOOTH_HINT:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_target;
         if (ctx->Hint.PointSmooth == mode)
	    return;
	 FLUSH_VERTICES(ctx, _NEW_HINT);
         ctx->Hint.PointSmooth = mode;
         break;
      case GL_POLYGON_SMOOTH_HINT:
         if (!_mesa_is_desktop_gl(ctx))
            goto invalid_target;
         if (ctx->Hint.PolygonSmooth == mode)
	    return;
	 FLUSH_VERTICES(ctx, _NEW_HINT);
         ctx->Hint.PolygonSmooth = mode;
         break;

      /* GL_ARB_texture_compression */
      case GL_TEXTURE_COMPRESSION_HINT_ARB:
         if (!_mesa_is_desktop_gl(ctx))
            goto invalid_target;
	 if (ctx->Hint.TextureCompression == mode)
	    return;
	 FLUSH_VERTICES(ctx, _NEW_HINT);
	 ctx->Hint.TextureCompression = mode;
         break;

      /* GL_SGIS_generate_mipmap */
      case GL_GENERATE_MIPMAP_HINT_SGIS:
         if (ctx->API == API_OPENGL_CORE)
            goto invalid_target;
         if (ctx->Hint.GenerateMipmap == mode)
            return;
	 FLUSH_VERTICES(ctx, _NEW_HINT);
	 ctx->Hint.GenerateMipmap = mode;
         break;

      /* GL_ARB_fragment_shader */
      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
         if (ctx->API == API_OPENGLES || !ctx->Extensions.ARB_fragment_shader)
            goto invalid_target;
         if (ctx->Hint.FragmentShaderDerivative == mode)
            return;
         FLUSH_VERTICES(ctx, _NEW_HINT);
         ctx->Hint.FragmentShaderDerivative = mode;
         break;

      default:
         goto invalid_target;
   }
   return;

invalid_target:
   _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
   return;
}
Exemple #27
0
/**
 * Return pointer-valued state, such as a vertex array pointer.
 *
 * \param pname  names state to be queried
 * \param params  returns the pointer value
 *
 * \sa glGetPointerv().
 *
 * Tries to get the specified pointer via dd_function_table::GetPointerv,
 * otherwise gets the specified pointer from the current context.
 */
void GLAPIENTRY
_mesa_GetPointerv( GLenum pname, GLvoid **params )
{
   GET_CURRENT_CONTEXT(ctx);
   const GLuint clientUnit = ctx->Array.ActiveTexture;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!params)
      return;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname));

   switch (pname) {
      case GL_VERTEX_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Ptr;
         break;
      case GL_NORMAL_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr;
         break;
      case GL_COLOR_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr;
         break;
      case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr;
         break;
      case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Ptr;
         break;
      case GL_INDEX_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr;
         break;
      case GL_TEXTURE_COORD_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr;
         break;
      case GL_EDGE_FLAG_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr;
         break;
      case GL_FEEDBACK_BUFFER_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = ctx->Feedback.Buffer;
         break;
      case GL_SELECTION_BUFFER_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = ctx->Select.Buffer;
         break;
      case GL_POINT_SIZE_ARRAY_POINTER_OES:
         if (ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr;
         break;
      case GL_DEBUG_CALLBACK_FUNCTION_ARB:
         if (!_mesa_is_desktop_gl(ctx))
            goto invalid_pname;
         *params = (GLvoid *) ctx->Debug.Callback;
         break;
      case GL_DEBUG_CALLBACK_USER_PARAM_ARB:
         if (!_mesa_is_desktop_gl(ctx))
            goto invalid_pname;
         *params = ctx->Debug.CallbackData;
         break;
      default:
         goto invalid_pname;
   }

   return;

invalid_pname:
   _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" );
   return;
}
Exemple #28
0
void GLAPIENTRY
_mesa_PixelStorei( GLenum pname, GLint param )
{
    /* NOTE: this call can't be compiled into the display list */
    GET_CURRENT_CONTEXT(ctx);

    switch (pname) {
    case GL_PACK_SWAP_BYTES:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
        break;
    case GL_PACK_LSB_FIRST:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
        break;
    case GL_PACK_ROW_LENGTH:
        if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.RowLength = param;
        break;
    case GL_PACK_IMAGE_HEIGHT:
        if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.ImageHeight = param;
        break;
    case GL_PACK_SKIP_PIXELS:
        if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.SkipPixels = param;
        break;
    case GL_PACK_SKIP_ROWS:
        if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.SkipRows = param;
        break;
    case GL_PACK_SKIP_IMAGES:
        if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.SkipImages = param;
        break;
    case GL_PACK_ALIGNMENT:
        if (param!=1 && param!=2 && param!=4 && param!=8)
            goto invalid_value_error;
        ctx->Pack.Alignment = param;
        break;
    case GL_PACK_INVERT_MESA:
        if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.MESA_pack_invert)
            goto invalid_enum_error;
        ctx->Pack.Invert = param;
        break;
    case GL_PACK_COMPRESSED_BLOCK_WIDTH:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.CompressedBlockWidth = param;
        break;
    case GL_PACK_COMPRESSED_BLOCK_HEIGHT:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.CompressedBlockHeight = param;
        break;
    case GL_PACK_COMPRESSED_BLOCK_DEPTH:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.CompressedBlockDepth = param;
        break;
    case GL_PACK_COMPRESSED_BLOCK_SIZE:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Pack.CompressedBlockSize = param;
        break;

    case GL_UNPACK_SWAP_BYTES:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
        break;
    case GL_UNPACK_LSB_FIRST:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
        break;
    case GL_UNPACK_ROW_LENGTH:
        if (ctx->API == API_OPENGLES)
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.RowLength = param;
        break;
    case GL_UNPACK_IMAGE_HEIGHT:
        if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.ImageHeight = param;
        break;
    case GL_UNPACK_SKIP_PIXELS:
        if (ctx->API == API_OPENGLES)
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.SkipPixels = param;
        break;
    case GL_UNPACK_SKIP_ROWS:
        if (ctx->API == API_OPENGLES)
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.SkipRows = param;
        break;
    case GL_UNPACK_SKIP_IMAGES:
        if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
            goto invalid_enum_error;
        if (param < 0)
            goto invalid_value_error;
        ctx->Unpack.SkipImages = param;
        break;
    case GL_UNPACK_ALIGNMENT:
        if (param!=1 && param!=2 && param!=4 && param!=8)
            goto invalid_value_error;
        ctx->Unpack.Alignment = param;
        break;
    case GL_UNPACK_COMPRESSED_BLOCK_WIDTH:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.CompressedBlockWidth = param;
        break;
    case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.CompressedBlockHeight = param;
        break;
    case GL_UNPACK_COMPRESSED_BLOCK_DEPTH:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.CompressedBlockDepth = param;
        break;
    case GL_UNPACK_COMPRESSED_BLOCK_SIZE:
        if (!_mesa_is_desktop_gl(ctx))
            goto invalid_enum_error;
        if (param<0)
            goto invalid_value_error;
        ctx->Unpack.CompressedBlockSize = param;
        break;
    default:
        goto invalid_enum_error;
    }

    return;

invalid_enum_error:
    _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
    return;

invalid_value_error:
    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
    return;
}
Exemple #29
0
/**
 * Initialize a dispatch table with pointers to Mesa's immediate-mode
 * commands.
 *
 * Pointers to glBegin()/glEnd() object commands and a few others
 * are provided via the GLvertexformat interface.
 *
 * \param ctx  GL context to which \c exec belongs.
 * \param exec dispatch table.
 */
struct _glapi_table *
_mesa_create_exec_table(struct gl_context *ctx)
{
   struct _glapi_table *exec;

   exec = _mesa_alloc_dispatch_table(_gloffset_COUNT);
   if (exec == NULL)
      return NULL;

#if _HAVE_FULL_GL
   _mesa_loopback_init_api_table( exec );
#endif

   /* load the dispatch slots we understand */
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_AlphaFunc(exec, _mesa_AlphaFunc);
   }

   SET_BlendFunc(exec, _mesa_BlendFunc);
   SET_Clear(exec, _mesa_Clear);
   SET_ClearColor(exec, _mesa_ClearColor);
   SET_ClearStencil(exec, _mesa_ClearStencil);
   SET_ColorMask(exec, _mesa_ColorMask);
   SET_CullFace(exec, _mesa_CullFace);
   SET_Disable(exec, _mesa_Disable);
#if FEATURE_draw_read_buffer
   if (ctx->API == API_OPENGL || ctx->API == API_OPENGL_CORE)
      SET_DrawBuffer(exec, _mesa_DrawBuffer);

   SET_ReadBuffer(exec, _mesa_ReadBuffer);
#endif
   SET_Enable(exec, _mesa_Enable);
   SET_Finish(exec, _mesa_Finish);
   SET_Flush(exec, _mesa_Flush);
   SET_FrontFace(exec, _mesa_FrontFace);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_Frustum(exec, _mesa_Frustum);
   }
   SET_GetError(exec, _mesa_GetError);
   SET_GetFloatv(exec, _mesa_GetFloatv);
   SET_GetString(exec, _mesa_GetString);
   if (ctx->API == API_OPENGL) {
      SET_LineStipple(exec, _mesa_LineStipple);
   }
   SET_LineWidth(exec, _mesa_LineWidth);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_LoadIdentity(exec, _mesa_LoadIdentity);
      SET_LoadMatrixf(exec, _mesa_LoadMatrixf);
   }
   if (ctx->API != API_OPENGLES2) {
      SET_LogicOp(exec, _mesa_LogicOp);
   }
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_MatrixMode(exec, _mesa_MatrixMode);
      SET_MultMatrixf(exec, _mesa_MultMatrixf);
      SET_Ortho(exec, _mesa_Ortho);
   }
   SET_PixelStorei(exec, _mesa_PixelStorei);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_PopMatrix(exec, _mesa_PopMatrix);
      SET_PushMatrix(exec, _mesa_PushMatrix);
      SET_Rotatef(exec, _mesa_Rotatef);
      SET_Scalef(exec, _mesa_Scalef);
   }
   SET_Scissor(exec, _mesa_Scissor);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_ShadeModel(exec, _mesa_ShadeModel);
   }
   SET_StencilFunc(exec, _mesa_StencilFunc);
   SET_StencilMask(exec, _mesa_StencilMask);
   SET_StencilOp(exec, _mesa_StencilOp);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_TexEnvfv(exec, _mesa_TexEnvfv);
      SET_TexEnvi(exec, _mesa_TexEnvi);
   }
   SET_TexImage2D(exec, _mesa_TexImage2D);
   SET_TexParameteri(exec, _mesa_TexParameteri);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_Translatef(exec, _mesa_Translatef);
   }
   SET_Viewport(exec, _mesa_Viewport);

   if (ctx->API == API_OPENGL) {
      _mesa_init_accum_dispatch(exec);
      _mesa_init_dlist_dispatch(exec);
   }

   SET_ClearDepth(exec, _mesa_ClearDepth);
   if (ctx->API == API_OPENGL) {
      SET_ClearIndex(exec, _mesa_ClearIndex);
      SET_ClipPlane(exec, _mesa_ClipPlane);
      SET_ColorMaterial(exec, _mesa_ColorMaterial);
   }
   SET_DepthFunc(exec, _mesa_DepthFunc);
   SET_DepthMask(exec, _mesa_DepthMask);
   SET_DepthRange(exec, _mesa_DepthRange);

   if (ctx->API != API_OPENGLES2 && ctx->API != API_OPENGL_CORE) {
      _mesa_init_drawpix_dispatch(exec);
   }
   if (ctx->API == API_OPENGL) {
      _mesa_init_feedback_dispatch(exec);
   }

   if (ctx->API == API_OPENGL) {
      SET_FogCoordPointerEXT(exec, _mesa_FogCoordPointerEXT);
      SET_Fogf(exec, _mesa_Fogf);
      SET_Fogfv(exec, _mesa_Fogfv);
      SET_Fogi(exec, _mesa_Fogi);
      SET_Fogiv(exec, _mesa_Fogiv);
      SET_GetClipPlane(exec, _mesa_GetClipPlane);
   }
   SET_GetBooleanv(exec, _mesa_GetBooleanv);
   SET_GetDoublev(exec, _mesa_GetDoublev);
   SET_GetIntegerv(exec, _mesa_GetIntegerv);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_GetLightfv(exec, _mesa_GetLightfv);
      SET_GetLightiv(exec, _mesa_GetLightiv);
      SET_GetMaterialfv(exec, _mesa_GetMaterialfv);
      SET_GetMaterialiv(exec, _mesa_GetMaterialiv);
      SET_GetPolygonStipple(exec, _mesa_GetPolygonStipple);
      SET_GetTexEnvfv(exec, _mesa_GetTexEnvfv);
      SET_GetTexEnviv(exec, _mesa_GetTexEnviv);
   }
   if (ctx->API != API_OPENGLES2) {
      SET_GetTexLevelParameterfv(exec, _mesa_GetTexLevelParameterfv);
      SET_GetTexLevelParameteriv(exec, _mesa_GetTexLevelParameteriv);
   }
   SET_GetTexParameterfv(exec, _mesa_GetTexParameterfv);
   SET_GetTexParameteriv(exec, _mesa_GetTexParameteriv);
   if (ctx->API != API_OPENGLES2) {
      SET_GetTexImage(exec, _mesa_GetTexImage);
   }
   SET_Hint(exec, _mesa_Hint);
   if (ctx->API == API_OPENGL) {
      SET_IndexMask(exec, _mesa_IndexMask);
   }
   SET_IsEnabled(exec, _mesa_IsEnabled);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_LightModelf(exec, _mesa_LightModelf);
      SET_LightModelfv(exec, _mesa_LightModelfv);
      SET_LightModeli(exec, _mesa_LightModeli);
      SET_LightModeliv(exec, _mesa_LightModeliv);
      SET_Lightf(exec, _mesa_Lightf);
      SET_Lightfv(exec, _mesa_Lightfv);
      SET_Lighti(exec, _mesa_Lighti);
      SET_Lightiv(exec, _mesa_Lightiv);
      SET_LoadMatrixd(exec, _mesa_LoadMatrixd);
   }

   if (ctx->API == API_OPENGL) {
      _mesa_init_eval_dispatch(exec);
      SET_MultMatrixd(exec, _mesa_MultMatrixd);
      _mesa_init_pixel_dispatch(exec);
   }

   if (ctx->API != API_OPENGLES2) {
      SET_PixelStoref(exec, _mesa_PixelStoref);
   }

   SET_PointSize(exec, _mesa_PointSize);

   if (ctx->API != API_OPENGLES2) {
      SET_PolygonMode(exec, _mesa_PolygonMode);
   }

   SET_PolygonOffset(exec, _mesa_PolygonOffset);
   if (ctx->API == API_OPENGL) {
      SET_PolygonStipple(exec, _mesa_PolygonStipple);
      _mesa_init_attrib_dispatch(exec);
      _mesa_init_rastpos_dispatch(exec);
   }

   SET_ReadPixels(exec, _mesa_ReadPixels);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_Rotated(exec, _mesa_Rotated);
      SET_Scaled(exec, _mesa_Scaled);
      SET_SecondaryColorPointerEXT(exec, _mesa_SecondaryColorPointerEXT);
      SET_TexEnvf(exec, _mesa_TexEnvf);
      SET_TexEnviv(exec, _mesa_TexEnviv);
   }

   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      _mesa_init_texgen_dispatch(exec);
   }

   if (ctx->API != API_OPENGLES2) {
      SET_TexImage1D(exec, _mesa_TexImage1D);
   }
   SET_TexParameterf(exec, _mesa_TexParameterf);
   SET_TexParameterfv(exec, _mesa_TexParameterfv);
   SET_TexParameteriv(exec, _mesa_TexParameteriv);
   if (ctx->API == API_OPENGL) {
      SET_Translated(exec, _mesa_Translated);
   }

   /* 1.1 */
   SET_BindTexture(exec, _mesa_BindTexture);
   SET_DeleteTextures(exec, _mesa_DeleteTextures);
   SET_GenTextures(exec, _mesa_GenTextures);
#if _HAVE_FULL_GL
   if (ctx->API == API_OPENGL) {
      SET_AreTexturesResident(exec, _mesa_AreTexturesResident);
      SET_ColorPointer(exec, _mesa_ColorPointer);
   }
   if (ctx->API != API_OPENGLES2) {
      SET_CopyTexImage1D(exec, _mesa_CopyTexImage1D);
      SET_CopyTexSubImage1D(exec, _mesa_CopyTexSubImage1D);
      SET_TexSubImage1D(exec, _mesa_TexSubImage1D);
   }

   SET_CopyTexImage2D(exec, _mesa_CopyTexImage2D);
   SET_CopyTexSubImage2D(exec, _mesa_CopyTexSubImage2D);
   SET_TexSubImage2D(exec, _mesa_TexSubImage2D);

   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_DisableClientState(exec, _mesa_DisableClientState);
      SET_EdgeFlagPointer(exec, _mesa_EdgeFlagPointer);
      SET_EnableClientState(exec, _mesa_EnableClientState);
      SET_GetPointerv(exec, _mesa_GetPointerv);
      SET_IndexPointer(exec, _mesa_IndexPointer);
      SET_InterleavedArrays(exec, _mesa_InterleavedArrays);
   }
   SET_IsTexture(exec, _mesa_IsTexture);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_NormalPointer(exec, _mesa_NormalPointer);
      SET_PrioritizeTextures(exec, _mesa_PrioritizeTextures);
      SET_TexCoordPointer(exec, _mesa_TexCoordPointer);
   }
   if (ctx->API != API_OPENGL_CORE) {
      SET_VertexPointer(exec, _mesa_VertexPointer);
   }
#endif

   /* 1.2 */
#if _HAVE_FULL_GL
   SET_CopyTexSubImage3D(exec, _mesa_CopyTexSubImage3D);
   SET_TexImage3D(exec, _mesa_TexImage3D);
   SET_TexSubImage3D(exec, _mesa_TexSubImage3D);
#endif

   /* OpenGL 1.2  GL_ARB_imaging */
   SET_BlendColor(exec, _mesa_BlendColor);
   SET_BlendEquation(exec, _mesa_BlendEquation);
   SET_BlendEquationSeparateEXT(exec, _mesa_BlendEquationSeparateEXT);

   if (ctx->API == API_OPENGL) {
      _mesa_init_colortable_dispatch(exec);
      _mesa_init_convolve_dispatch(exec);
      _mesa_init_histogram_dispatch(exec);
   }

   /* OpenGL 2.0 */
   SET_StencilFuncSeparate(exec, _mesa_StencilFuncSeparate);
   SET_StencilMaskSeparate(exec, _mesa_StencilMaskSeparate);
   SET_StencilOpSeparate(exec, _mesa_StencilOpSeparate);

#if FEATURE_ARB_shader_objects
   _mesa_init_shader_dispatch(exec);
   _mesa_init_shader_uniform_dispatch(exec);
#endif

   /* 2. GL_EXT_blend_color */
#if 0
/*    SET_BlendColorEXT(exec, _mesa_BlendColorEXT); */
#endif

   /* 3. GL_EXT_polygon_offset */
#if _HAVE_FULL_GL
   if (ctx->API == API_OPENGL) {
      SET_PolygonOffsetEXT(exec, _mesa_PolygonOffsetEXT);
   }
#endif

   /* 6. GL_EXT_texture3d */
#if 0
/*    SET_CopyTexSubImage3DEXT(exec, _mesa_CopyTexSubImage3D); */
/*    SET_TexImage3DEXT(exec, _mesa_TexImage3DEXT); */
/*    SET_TexSubImage3DEXT(exec, _mesa_TexSubImage3D); */
#endif

   /* 11. GL_EXT_histogram */
#if 0
   if (ctx->API == API_OPENGL) {
      SET_GetHistogramEXT(exec, _mesa_GetHistogram);
      SET_GetHistogramParameterfvEXT(exec, _mesa_GetHistogramParameterfv);
      SET_GetHistogramParameterivEXT(exec, _mesa_GetHistogramParameteriv);
      SET_GetMinmaxEXT(exec, _mesa_GetMinmax);
      SET_GetMinmaxParameterfvEXT(exec, _mesa_GetMinmaxParameterfv);
      SET_GetMinmaxParameterivEXT(exec, _mesa_GetMinmaxParameteriv);
   }
#endif

   /* 14. SGI_color_table */
#if 0
   if (ctx->API == API_OPENGL) {
      SET_ColorTableSGI(exec, _mesa_ColorTable);
      SET_ColorSubTableSGI(exec, _mesa_ColorSubTable);
      SET_GetColorTableSGI(exec, _mesa_GetColorTable);
      SET_GetColorTableParameterfvSGI(exec, _mesa_GetColorTableParameterfv);
      SET_GetColorTableParameterivSGI(exec, _mesa_GetColorTableParameteriv);
   }
#endif

   /* 30. GL_EXT_vertex_array */
#if _HAVE_FULL_GL
   if (ctx->API == API_OPENGL) {
      SET_ColorPointerEXT(exec, _mesa_ColorPointerEXT);
      SET_EdgeFlagPointerEXT(exec, _mesa_EdgeFlagPointerEXT);
      SET_IndexPointerEXT(exec, _mesa_IndexPointerEXT);
      SET_NormalPointerEXT(exec, _mesa_NormalPointerEXT);
      SET_TexCoordPointerEXT(exec, _mesa_TexCoordPointerEXT);
      SET_VertexPointerEXT(exec, _mesa_VertexPointerEXT);
   }
#endif

   /* 37. GL_EXT_blend_minmax */
#if 0
   SET_BlendEquationEXT(exec, _mesa_BlendEquationEXT);
#endif

   /* 54. GL_EXT_point_parameters */
#if _HAVE_FULL_GL
   SET_PointParameterfEXT(exec, _mesa_PointParameterf);
   SET_PointParameterfvEXT(exec, _mesa_PointParameterfv);
#endif

   /* 95. GL_ARB_ES2_compatibility */
   SET_ClearDepthf(exec, _mesa_ClearDepthf);
   SET_DepthRangef(exec, _mesa_DepthRangef);

   /* 97. GL_EXT_compiled_vertex_array */
#if _HAVE_FULL_GL
   if (ctx->API == API_OPENGL) {
      SET_LockArraysEXT(exec, _mesa_LockArraysEXT);
      SET_UnlockArraysEXT(exec, _mesa_UnlockArraysEXT);
   }
#endif

   /* 148. GL_EXT_multi_draw_arrays */
#if _HAVE_FULL_GL
   SET_MultiDrawArraysEXT(exec, _mesa_MultiDrawArraysEXT);
#endif

   /* 173. GL_INGR_blend_func_separate */
#if _HAVE_FULL_GL
   SET_BlendFuncSeparateEXT(exec, _mesa_BlendFuncSeparateEXT);
#endif

   /* 196. GL_MESA_resize_buffers */
#if _HAVE_FULL_GL
   SET_ResizeBuffersMESA(exec, _mesa_ResizeBuffersMESA);
#endif

   /* 197. GL_MESA_window_pos */
   /* part of _mesa_init_rastpos_dispatch(exec); */

   /* 200. GL_IBM_multimode_draw_arrays */
#if _HAVE_FULL_GL
   if (ctx->API != API_OPENGLES2) {
      SET_MultiModeDrawArraysIBM(exec, _mesa_MultiModeDrawArraysIBM);
      SET_MultiModeDrawElementsIBM(exec, _mesa_MultiModeDrawElementsIBM);
   }
#endif

   /* 233. GL_NV_vertex_program */
#if FEATURE_NV_vertex_program
   if (ctx->API == API_OPENGL) {
      SET_BindProgramNV(exec, _mesa_BindProgram);
      SET_DeleteProgramsNV(exec, _mesa_DeletePrograms);
      SET_ExecuteProgramNV(exec, _mesa_ExecuteProgramNV);
      SET_GenProgramsNV(exec, _mesa_GenPrograms);
      SET_AreProgramsResidentNV(exec, _mesa_AreProgramsResidentNV);
      SET_RequestResidentProgramsNV(exec, _mesa_RequestResidentProgramsNV);
      SET_GetProgramParameterfvNV(exec, _mesa_GetProgramParameterfvNV);
      SET_GetProgramParameterdvNV(exec, _mesa_GetProgramParameterdvNV);
      SET_GetProgramivNV(exec, _mesa_GetProgramivNV);
      SET_GetProgramStringNV(exec, _mesa_GetProgramStringNV);
      SET_GetTrackMatrixivNV(exec, _mesa_GetTrackMatrixivNV);
      SET_GetVertexAttribdvNV(exec, _mesa_GetVertexAttribdvNV);
      SET_GetVertexAttribfvNV(exec, _mesa_GetVertexAttribfvNV);
      SET_GetVertexAttribivNV(exec, _mesa_GetVertexAttribivNV);
      SET_IsProgramNV(exec, _mesa_IsProgramARB);
      SET_LoadProgramNV(exec, _mesa_LoadProgramNV);
      SET_ProgramEnvParameter4dARB(exec, _mesa_ProgramEnvParameter4dARB); /* alias to ProgramParameter4dNV */
      SET_ProgramEnvParameter4dvARB(exec, _mesa_ProgramEnvParameter4dvARB);  /* alias to ProgramParameter4dvNV */
      SET_ProgramEnvParameter4fARB(exec, _mesa_ProgramEnvParameter4fARB);  /* alias to ProgramParameter4fNV */
      SET_ProgramEnvParameter4fvARB(exec, _mesa_ProgramEnvParameter4fvARB);  /* alias to ProgramParameter4fvNV */
      SET_ProgramParameters4dvNV(exec, _mesa_ProgramParameters4dvNV);
      SET_ProgramParameters4fvNV(exec, _mesa_ProgramParameters4fvNV);
      SET_TrackMatrixNV(exec, _mesa_TrackMatrixNV);
      SET_VertexAttribPointerNV(exec, _mesa_VertexAttribPointerNV);
      /* glVertexAttrib*NV functions handled in api_loopback.c */
   }
#endif
   SET_GetVertexAttribPointervNV(exec, _mesa_GetVertexAttribPointervNV);

   /* 273. GL_APPLE_vertex_array_object */
   if (ctx->API == API_OPENGL) {
      SET_BindVertexArrayAPPLE(exec, _mesa_BindVertexArrayAPPLE);
      SET_GenVertexArraysAPPLE(exec, _mesa_GenVertexArraysAPPLE);
   }
   /* Reused by ARB_vertex_array_object / OES_vertex_array_object */
   SET_DeleteVertexArraysAPPLE(exec, _mesa_DeleteVertexArraysAPPLE);
   SET_IsVertexArrayAPPLE(exec, _mesa_IsVertexArrayAPPLE);

   /* 282. GL_NV_fragment_program */
#if FEATURE_NV_fragment_program
   if (ctx->API == API_OPENGL) {
      SET_ProgramNamedParameter4fNV(exec, _mesa_ProgramNamedParameter4fNV);
      SET_ProgramNamedParameter4dNV(exec, _mesa_ProgramNamedParameter4dNV);
      SET_ProgramNamedParameter4fvNV(exec, _mesa_ProgramNamedParameter4fvNV);
      SET_ProgramNamedParameter4dvNV(exec, _mesa_ProgramNamedParameter4dvNV);
      SET_GetProgramNamedParameterfvNV(exec, _mesa_GetProgramNamedParameterfvNV);
      SET_GetProgramNamedParameterdvNV(exec, _mesa_GetProgramNamedParameterdvNV);
      SET_ProgramLocalParameter4dARB(exec, _mesa_ProgramLocalParameter4dARB);
      SET_ProgramLocalParameter4dvARB(exec, _mesa_ProgramLocalParameter4dvARB);
      SET_ProgramLocalParameter4fARB(exec, _mesa_ProgramLocalParameter4fARB);
      SET_ProgramLocalParameter4fvARB(exec, _mesa_ProgramLocalParameter4fvARB);
      SET_GetProgramLocalParameterdvARB(exec, _mesa_GetProgramLocalParameterdvARB);
      SET_GetProgramLocalParameterfvARB(exec, _mesa_GetProgramLocalParameterfvARB);
   }
#endif

   /* 262. GL_NV_point_sprite */
#if _HAVE_FULL_GL
   SET_PointParameteriNV(exec, _mesa_PointParameteri);
   SET_PointParameterivNV(exec, _mesa_PointParameteriv);
#endif

   /* 268. GL_EXT_stencil_two_side */
#if _HAVE_FULL_GL
   if (ctx->API == API_OPENGL) {
      SET_ActiveStencilFaceEXT(exec, _mesa_ActiveStencilFaceEXT);
   }
#endif

   /* 285. GL_NV_primitive_restart */
   if (ctx->API != API_OPENGLES2) {
      SET_PrimitiveRestartIndexNV(exec, _mesa_PrimitiveRestartIndex);
   }

   /* ???. GL_EXT_depth_bounds_test */
   if (ctx->API != API_OPENGLES2) {
      SET_DepthBoundsEXT(exec, _mesa_DepthBoundsEXT);
   }

   /* 352. GL_EXT_transform_feedback */
   /* ARB 93. GL_ARB_transform_feedback2 */
   if (ctx->API != API_OPENGLES2) {
      _mesa_init_transform_feedback_dispatch(exec);
   }

   /* 364. GL_EXT_provoking_vertex */
   if (ctx->API != API_OPENGLES2) {
      SET_ProvokingVertexEXT(exec, _mesa_ProvokingVertexEXT);
   }

   /* ARB 1. GL_ARB_multitexture */
#if _HAVE_FULL_GL
   SET_ActiveTextureARB(exec, _mesa_ActiveTextureARB);
   if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) {
      SET_ClientActiveTextureARB(exec, _mesa_ClientActiveTextureARB);
   }
#endif

   /* ARB 3. GL_ARB_transpose_matrix */
#if _HAVE_FULL_GL
   if (ctx->API == API_OPENGL) {
      SET_LoadTransposeMatrixdARB(exec, _mesa_LoadTransposeMatrixdARB);
      SET_LoadTransposeMatrixfARB(exec, _mesa_LoadTransposeMatrixfARB);
      SET_MultTransposeMatrixdARB(exec, _mesa_MultTransposeMatrixdARB);
      SET_MultTransposeMatrixfARB(exec, _mesa_MultTransposeMatrixfARB);
   }
#endif

   /* ARB 5. GL_ARB_multisample */
#if _HAVE_FULL_GL
   SET_SampleCoverageARB(exec, _mesa_SampleCoverageARB);
#endif

   /* ARB 12. GL_ARB_texture_compression */
#if _HAVE_FULL_GL
   if (ctx->API != API_OPENGLES2) {
      SET_CompressedTexImage1DARB(exec, _mesa_CompressedTexImage1DARB);
      SET_CompressedTexSubImage1DARB(exec, _mesa_CompressedTexSubImage1DARB);
      SET_GetCompressedTexImageARB(exec, _mesa_GetCompressedTexImageARB);
   }

   SET_CompressedTexImage3DARB(exec, _mesa_CompressedTexImage3DARB);
   SET_CompressedTexImage2DARB(exec, _mesa_CompressedTexImage2DARB);
   SET_CompressedTexSubImage3DARB(exec, _mesa_CompressedTexSubImage3DARB);
   SET_CompressedTexSubImage2DARB(exec, _mesa_CompressedTexSubImage2DARB);

   /* ARB 104. GL_ARB_robustness */
   if (ctx->API != API_OPENGLES2) {
      SET_GetnCompressedTexImageARB(exec, _mesa_GetnCompressedTexImageARB);
   }
#endif

   /* ARB 14. GL_ARB_point_parameters */
   /* reuse EXT_point_parameters functions */

   /* ARB 26. GL_ARB_vertex_program */
   /* ARB 27. GL_ARB_fragment_program */
#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
   /* glVertexAttrib1sARB aliases glVertexAttrib1sNV */
   /* glVertexAttrib1fARB aliases glVertexAttrib1fNV */
   /* glVertexAttrib1dARB aliases glVertexAttrib1dNV */
   /* glVertexAttrib2sARB aliases glVertexAttrib2sNV */
   /* glVertexAttrib2fARB aliases glVertexAttrib2fNV */
   /* glVertexAttrib2dARB aliases glVertexAttrib2dNV */
   /* glVertexAttrib3sARB aliases glVertexAttrib3sNV */
   /* glVertexAttrib3fARB aliases glVertexAttrib3fNV */
   /* glVertexAttrib3dARB aliases glVertexAttrib3dNV */
   /* glVertexAttrib4sARB aliases glVertexAttrib4sNV */
   /* glVertexAttrib4fARB aliases glVertexAttrib4fNV */
   /* glVertexAttrib4dARB aliases glVertexAttrib4dNV */
   /* glVertexAttrib4NubARB aliases glVertexAttrib4NubNV */
   /* glVertexAttrib1svARB aliases glVertexAttrib1svNV */
   /* glVertexAttrib1fvARB aliases glVertexAttrib1fvNV */
   /* glVertexAttrib1dvARB aliases glVertexAttrib1dvNV */
   /* glVertexAttrib2svARB aliases glVertexAttrib2svNV */
   /* glVertexAttrib2fvARB aliases glVertexAttrib2fvNV */
   /* glVertexAttrib2dvARB aliases glVertexAttrib2dvNV */
   /* glVertexAttrib3svARB aliases glVertexAttrib3svNV */
   /* glVertexAttrib3fvARB aliases glVertexAttrib3fvNV */
   /* glVertexAttrib3dvARB aliases glVertexAttrib3dvNV */
   /* glVertexAttrib4svARB aliases glVertexAttrib4svNV */
   /* glVertexAttrib4fvARB aliases glVertexAttrib4fvNV */
   /* glVertexAttrib4dvARB aliases glVertexAttrib4dvNV */
   /* glVertexAttrib4NubvARB aliases glVertexAttrib4NubvNV */
   /* glVertexAttrib4bvARB handled in api_loopback.c */
   /* glVertexAttrib4ivARB handled in api_loopback.c */
   /* glVertexAttrib4ubvARB handled in api_loopback.c */
   /* glVertexAttrib4usvARB handled in api_loopback.c */
   /* glVertexAttrib4uivARB handled in api_loopback.c */
   /* glVertexAttrib4NbvARB handled in api_loopback.c */
   /* glVertexAttrib4NsvARB handled in api_loopback.c */
   /* glVertexAttrib4NivARB handled in api_loopback.c */
   /* glVertexAttrib4NusvARB handled in api_loopback.c */
   /* glVertexAttrib4NuivARB handled in api_loopback.c */
   SET_VertexAttribPointerARB(exec, _mesa_VertexAttribPointerARB);
   SET_EnableVertexAttribArrayARB(exec, _mesa_EnableVertexAttribArrayARB);
   SET_DisableVertexAttribArrayARB(exec, _mesa_DisableVertexAttribArrayARB);
   if (ctx->API != API_OPENGLES2) {
      SET_ProgramStringARB(exec, _mesa_ProgramStringARB);
      /* glBindProgramARB aliases glBindProgramNV */
      /* glDeleteProgramsARB aliases glDeleteProgramsNV */
      /* glGenProgramsARB aliases glGenProgramsNV */
      /* glIsProgramARB aliases glIsProgramNV */
      SET_GetVertexAttribdvARB(exec, _mesa_GetVertexAttribdvARB);
   }

   SET_GetVertexAttribfvARB(exec, _mesa_GetVertexAttribfvARB);
   SET_GetVertexAttribivARB(exec, _mesa_GetVertexAttribivARB);
   /* glGetVertexAttribPointervARB aliases glGetVertexAttribPointervNV */
   if (ctx->API == API_OPENGL) {
      SET_ProgramEnvParameter4dARB(exec, _mesa_ProgramEnvParameter4dARB);
      SET_ProgramEnvParameter4dvARB(exec, _mesa_ProgramEnvParameter4dvARB);
      SET_ProgramEnvParameter4fARB(exec, _mesa_ProgramEnvParameter4fARB);
      SET_ProgramEnvParameter4fvARB(exec, _mesa_ProgramEnvParameter4fvARB);
      SET_ProgramLocalParameter4dARB(exec, _mesa_ProgramLocalParameter4dARB);
      SET_ProgramLocalParameter4dvARB(exec, _mesa_ProgramLocalParameter4dvARB);
      SET_ProgramLocalParameter4fARB(exec, _mesa_ProgramLocalParameter4fARB);
      SET_ProgramLocalParameter4fvARB(exec, _mesa_ProgramLocalParameter4fvARB);
      SET_GetProgramEnvParameterdvARB(exec, _mesa_GetProgramEnvParameterdvARB);
      SET_GetProgramEnvParameterfvARB(exec, _mesa_GetProgramEnvParameterfvARB);
      SET_GetProgramLocalParameterdvARB(exec, _mesa_GetProgramLocalParameterdvARB);
      SET_GetProgramLocalParameterfvARB(exec, _mesa_GetProgramLocalParameterfvARB);
      SET_GetProgramStringARB(exec, _mesa_GetProgramStringARB);
   }
   SET_GetProgramivARB(exec, _mesa_GetProgramivARB);
#endif

   /* ARB 28. GL_ARB_vertex_buffer_object */
   _mesa_init_bufferobj_dispatch(ctx, exec);

   /* ARB 29. GL_ARB_occlusion_query */
   if (ctx->API != API_OPENGLES2) {
      _mesa_init_queryobj_dispatch(exec);
   }

   /* ARB 37. GL_ARB_draw_buffers */
#if FEATURE_draw_read_buffer
   SET_DrawBuffersARB(exec, _mesa_DrawBuffersARB);
#endif

   /* ARB 66. GL_ARB_sync */
   if (ctx->API != API_OPENGLES2) {
      _mesa_init_sync_dispatch(exec);
   }

   /* ARB 104. GL_ARB_debug_output */
   if (ctx->API != API_OPENGLES2) {
      _mesa_init_errors_dispatch(exec);
   }

   /* ARB 105. GL_ARB_robustness */
   if (ctx->API != API_OPENGLES2) {
      SET_GetGraphicsResetStatusARB(exec, _mesa_GetGraphicsResetStatusARB);
      SET_GetnPolygonStippleARB(exec, _mesa_GetnPolygonStippleARB);
      SET_GetnTexImageARB(exec, _mesa_GetnTexImageARB);
      SET_ReadnPixelsARB(exec, _mesa_ReadnPixelsARB);
   }

  /* GL_ATI_fragment_shader */
   if (ctx->API == API_OPENGL) {
      _mesa_init_ati_fragment_shader_dispatch(exec);
   }

  /* GL_ATI_envmap_bumpmap */
   if (ctx->API == API_OPENGL) {
      SET_GetTexBumpParameterivATI(exec, _mesa_GetTexBumpParameterivATI);
      SET_GetTexBumpParameterfvATI(exec, _mesa_GetTexBumpParameterfvATI);
      SET_TexBumpParameterivATI(exec, _mesa_TexBumpParameterivATI);
      SET_TexBumpParameterfvATI(exec, _mesa_TexBumpParameterfvATI);
   }

#if FEATURE_EXT_framebuffer_object
   SET_IsRenderbufferEXT(exec, _mesa_IsRenderbufferEXT);
   SET_BindRenderbufferEXT(exec, _mesa_BindRenderbufferEXT);
   SET_DeleteRenderbuffersEXT(exec, _mesa_DeleteRenderbuffersEXT);
   SET_GenRenderbuffersEXT(exec, _mesa_GenRenderbuffersEXT);
   SET_RenderbufferStorageEXT(exec, _mesa_RenderbufferStorageEXT);
   SET_GetRenderbufferParameterivEXT(exec, _mesa_GetRenderbufferParameterivEXT);
   SET_IsFramebufferEXT(exec, _mesa_IsFramebufferEXT);
   SET_BindFramebufferEXT(exec, _mesa_BindFramebufferEXT);
   SET_DeleteFramebuffersEXT(exec, _mesa_DeleteFramebuffersEXT);
   SET_GenFramebuffersEXT(exec, _mesa_GenFramebuffersEXT);
   SET_CheckFramebufferStatusEXT(exec, _mesa_CheckFramebufferStatusEXT);
   if (ctx->API != API_OPENGLES2) {
      SET_FramebufferTexture1DEXT(exec, _mesa_FramebufferTexture1DEXT);
   }
   SET_FramebufferTexture2DEXT(exec, _mesa_FramebufferTexture2DEXT);
   SET_FramebufferTexture3DEXT(exec, _mesa_FramebufferTexture3DEXT);
   SET_FramebufferRenderbufferEXT(exec, _mesa_FramebufferRenderbufferEXT);
   SET_GetFramebufferAttachmentParameterivEXT(exec, _mesa_GetFramebufferAttachmentParameterivEXT);
   SET_GenerateMipmapEXT(exec, _mesa_GenerateMipmapEXT);
#endif

#if FEATURE_EXT_framebuffer_blit
   if (ctx->API != API_OPENGLES2) {
      SET_BlitFramebufferEXT(exec, _mesa_BlitFramebufferEXT);
   }
#endif

   /* GL_EXT_gpu_program_parameters */
#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
   if (ctx->API == API_OPENGL) {
      SET_ProgramEnvParameters4fvEXT(exec, _mesa_ProgramEnvParameters4fvEXT);
      SET_ProgramLocalParameters4fvEXT(exec, _mesa_ProgramLocalParameters4fvEXT);
   }
#endif

   /* GL_MESA_texture_array / GL_EXT_texture_array */
#if FEATURE_EXT_framebuffer_object
   if (ctx->API != API_OPENGLES2) {
      SET_FramebufferTextureLayerEXT(exec, _mesa_FramebufferTextureLayerEXT);
   }
#endif

   /* GL_ATI_separate_stencil */
   if (ctx->API == API_OPENGL) {
      SET_StencilFuncSeparateATI(exec, _mesa_StencilFuncSeparateATI);
   }

#if FEATURE_ARB_framebuffer_object
   /* The ARB_fbo functions are the union of
    * GL_EXT_fbo, GL_EXT_framebuffer_blit, GL_EXT_texture_array
    */
   if (ctx->API != API_OPENGLES2) {
      SET_RenderbufferStorageMultisample(exec, _mesa_RenderbufferStorageMultisample);
   }
#endif

#if FEATURE_ARB_map_buffer_range
   if (ctx->API != API_OPENGLES2) {
      SET_MapBufferRange(exec, _mesa_MapBufferRange);
      SET_FlushMappedBufferRange(exec, _mesa_FlushMappedBufferRange);
   }
#endif

   /* GL_ARB_copy_buffer */
   if (ctx->API != API_OPENGLES2) {
      SET_CopyBufferSubData(exec, _mesa_CopyBufferSubData);
   }

   /* GL_ARB_vertex_array_object / GL_OES_vertex_array_object */
   SET_BindVertexArray(exec, _mesa_BindVertexArray);
   SET_GenVertexArrays(exec, _mesa_GenVertexArrays);

   /* GL_EXT_draw_buffers2 */
   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_ColorMaskIndexedEXT(exec, _mesa_ColorMaskIndexed);
      SET_GetBooleanIndexedvEXT(exec, _mesa_GetBooleanIndexedv);
      SET_GetIntegerIndexedvEXT(exec, _mesa_GetIntegerIndexedv);
      SET_EnableIndexedEXT(exec, _mesa_EnableIndexed);
      SET_DisableIndexedEXT(exec, _mesa_DisableIndexed);
      SET_IsEnabledIndexedEXT(exec, _mesa_IsEnabledIndexed);
   }

   /* GL_NV_conditional_render */
   if (ctx->API != API_OPENGLES2) {
      SET_BeginConditionalRenderNV(exec, _mesa_BeginConditionalRender);
      SET_EndConditionalRenderNV(exec, _mesa_EndConditionalRender);
   }

#if FEATURE_OES_EGL_image
   SET_EGLImageTargetTexture2DOES(exec, _mesa_EGLImageTargetTexture2DOES);
   SET_EGLImageTargetRenderbufferStorageOES(exec, _mesa_EGLImageTargetRenderbufferStorageOES);
#endif

#if FEATURE_APPLE_object_purgeable
   if (ctx->API != API_OPENGLES2) {
      SET_ObjectPurgeableAPPLE(exec, _mesa_ObjectPurgeableAPPLE);
      SET_ObjectUnpurgeableAPPLE(exec, _mesa_ObjectUnpurgeableAPPLE);
      SET_GetObjectParameterivAPPLE(exec, _mesa_GetObjectParameterivAPPLE);
   }
#endif

#if FEATURE_ARB_geometry_shader4
   if (ctx->API != API_OPENGLES2) {
      SET_FramebufferTextureARB(exec, _mesa_FramebufferTextureARB);
      SET_FramebufferTextureFaceARB(exec, _mesa_FramebufferTextureFaceARB);
   }
#endif

   if (ctx->API != API_OPENGLES2) {
      SET_ClampColorARB(exec, _mesa_ClampColorARB);
   }

   /* GL_EXT_texture_integer */
   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_ClearColorIiEXT(exec, _mesa_ClearColorIiEXT);
      SET_ClearColorIuiEXT(exec, _mesa_ClearColorIuiEXT);
   }
   if (ctx->API != API_OPENGLES2) {
      SET_GetTexParameterIivEXT(exec, _mesa_GetTexParameterIiv);
      SET_GetTexParameterIuivEXT(exec, _mesa_GetTexParameterIuiv);
      SET_TexParameterIivEXT(exec, _mesa_TexParameterIiv);
      SET_TexParameterIuivEXT(exec, _mesa_TexParameterIuiv);
   }

   /* GL_EXT_gpu_shader4 / OpenGL 3.0 */
   if (ctx->API != API_OPENGLES2) {
      SET_GetVertexAttribIivEXT(exec, _mesa_GetVertexAttribIiv);
      SET_GetVertexAttribIuivEXT(exec, _mesa_GetVertexAttribIuiv);
      SET_VertexAttribIPointerEXT(exec, _mesa_VertexAttribIPointer);
   }

   /* GL 3.0 (functions not covered by other extensions) */
   if (ctx->API != API_OPENGLES2) {
      SET_ClearBufferiv(exec, _mesa_ClearBufferiv);
      SET_ClearBufferuiv(exec, _mesa_ClearBufferuiv);
      SET_ClearBufferfv(exec, _mesa_ClearBufferfv);
      SET_ClearBufferfi(exec, _mesa_ClearBufferfi);
      SET_GetStringi(exec, _mesa_GetStringi);
      SET_ClampColor(exec, _mesa_ClampColorARB);
   }

   /* GL_ARB_instanced_arrays */
   if (ctx->API != API_OPENGLES2) {
      SET_VertexAttribDivisorARB(exec, _mesa_VertexAttribDivisor);
   }

   /* GL_ARB_draw_buffer_blend */
   if (ctx->API != API_OPENGLES2) {
      SET_BlendFunciARB(exec, _mesa_BlendFunci);
      SET_BlendFuncSeparateiARB(exec, _mesa_BlendFuncSeparatei);
      SET_BlendEquationiARB(exec, _mesa_BlendEquationi);
      SET_BlendEquationSeparateiARB(exec, _mesa_BlendEquationSeparatei);
   }

   /* GL_NV_texture_barrier */
   if (ctx->API != API_OPENGLES2) {
      SET_TextureBarrierNV(exec, _mesa_TextureBarrierNV);
   }
 
   /* GL_ARB_texture_buffer_object */
   if (ctx->API != API_OPENGLES2) {
      SET_TexBufferARB(exec, _mesa_TexBuffer);
   }

   /* GL_ARB_texture_storage */
   if (ctx->API != API_OPENGLES2) {
      SET_TexStorage1D(exec, _mesa_TexStorage1D);
      SET_TextureStorage1DEXT(exec, _mesa_TextureStorage1DEXT);
   }
   SET_TexStorage2D(exec, _mesa_TexStorage2D);
   SET_TexStorage3D(exec, _mesa_TexStorage3D);
   SET_TextureStorage2DEXT(exec, _mesa_TextureStorage2DEXT);
   SET_TextureStorage3DEXT(exec, _mesa_TextureStorage3DEXT);

#if FEATURE_ARB_sampler_objects
   if (ctx->API != API_OPENGLES2) {
      _mesa_init_sampler_object_dispatch(exec);
   }
#endif

   if (_mesa_is_desktop_gl(ctx)) {
      SET_InvalidateTexSubImage(exec, _mesa_InvalidateTexSubImage);
      SET_InvalidateTexImage(exec, _mesa_InvalidateTexImage);
   }

   if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
      SET_InvalidateSubFramebuffer(exec, _mesa_InvalidateSubFramebuffer);
      SET_InvalidateFramebuffer(exec, _mesa_InvalidateFramebuffer);
   }

   return exec;
}
void GLAPIENTRY
_mesa_PointParameterfv( GLenum pname, const GLfloat *params)
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   /* Drivers that support point sprites must also support point parameters.
    * If point parameters aren't supported, then this function shouldn't even
    * exist.
    */
   ASSERT(!(ctx->Extensions.ARB_point_sprite
            || ctx->Extensions.NV_point_sprite)
          || ctx->Extensions.EXT_point_parameters);

   if (!ctx->Extensions.EXT_point_parameters) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "unsupported function called (unsupported extension)");
      return;
   }

   switch (pname) {
      case GL_DISTANCE_ATTENUATION_EXT:
         if (TEST_EQ_3V(ctx->Point.Params, params))
            return;
         FLUSH_VERTICES(ctx, _NEW_POINT);
         COPY_3V(ctx->Point.Params, params);
         ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 ||
                                   ctx->Point.Params[1] != 0.0 ||
                                   ctx->Point.Params[2] != 0.0);

         if (ctx->Point._Attenuated)
            ctx->_TriangleCaps |= DD_POINT_ATTEN;
         else
            ctx->_TriangleCaps &= ~DD_POINT_ATTEN;
         break;
      case GL_POINT_SIZE_MIN_EXT:
         if (params[0] < 0.0F) {
            _mesa_error( ctx, GL_INVALID_VALUE,
                         "glPointParameterf[v]{EXT,ARB}(param)" );
            return;
         }
         if (ctx->Point.MinSize == params[0])
            return;
         FLUSH_VERTICES(ctx, _NEW_POINT);
         ctx->Point.MinSize = params[0];
         break;
      case GL_POINT_SIZE_MAX_EXT:
         if (params[0] < 0.0F) {
            _mesa_error( ctx, GL_INVALID_VALUE,
                         "glPointParameterf[v]{EXT,ARB}(param)" );
            return;
         }
         if (ctx->Point.MaxSize == params[0])
            return;
         FLUSH_VERTICES(ctx, _NEW_POINT);
         ctx->Point.MaxSize = params[0];
         break;
      case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
         if (params[0] < 0.0F) {
            _mesa_error( ctx, GL_INVALID_VALUE,
                         "glPointParameterf[v]{EXT,ARB}(param)" );
            return;
         }
         if (ctx->Point.Threshold == params[0])
            return;
         FLUSH_VERTICES(ctx, _NEW_POINT);
         ctx->Point.Threshold = params[0];
         break;
      case GL_POINT_SPRITE_R_MODE_NV:
         /* This is one area where ARB_point_sprite and NV_point_sprite
	  * differ.  In ARB_point_sprite the POINT_SPRITE_R_MODE is
	  * always ZERO.  NV_point_sprite adds the S and R modes.
	  */
         if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_point_sprite) {
            GLenum value = (GLenum) params[0];
            if (value != GL_ZERO && value != GL_S && value != GL_R) {
               _mesa_error(ctx, GL_INVALID_VALUE,
                           "glPointParameterf[v]{EXT,ARB}(param)");
               return;
            }
            if (ctx->Point.SpriteRMode == value)
               return;
            FLUSH_VERTICES(ctx, _NEW_POINT);
            ctx->Point.SpriteRMode = value;
         }
         else {
            _mesa_error(ctx, GL_INVALID_ENUM,
                        "glPointParameterf[v]{EXT,ARB}(pname)");
            return;
         }
         break;
      case GL_POINT_SPRITE_COORD_ORIGIN:
	 /* GL_POINT_SPRITE_COORD_ORIGIN was added to point sprites when the
	  * extension was merged into OpenGL 2.0.
	  */
         if ((ctx->API == API_OPENGL && ctx->Version >= 20)
             || ctx->API == API_OPENGL_CORE) {
            GLenum value = (GLenum) params[0];
            if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) {
               _mesa_error(ctx, GL_INVALID_VALUE,
                           "glPointParameterf[v]{EXT,ARB}(param)");
               return;
            }
            if (ctx->Point.SpriteOrigin == value)
               return;
            FLUSH_VERTICES(ctx, _NEW_POINT);
            ctx->Point.SpriteOrigin = value;
         }
         else {
            _mesa_error(ctx, GL_INVALID_ENUM,
                        "glPointParameterf[v]{EXT,ARB}(pname)");
            return;
         }
         break;
      default:
         _mesa_error( ctx, GL_INVALID_ENUM,
                      "glPointParameterf[v]{EXT,ARB}(pname)" );
         return;
   }

   if (ctx->Driver.PointParameterfv)
      (*ctx->Driver.PointParameterfv)(ctx, pname, params);
}