Example #1
0
File: blend.c Project: etnaviv/mesa
/**
 * Initialization of the context's Color attribute group.
 *
 * \param ctx GL context.
 *
 * Initializes the related fields in the context color attribute group,
 * __struct gl_contextRec::Color.
 */
void _mesa_init_color( struct gl_context * ctx )
{
   GLuint i;

   /* Color buffer group */
   ctx->Color.IndexMask = ~0u;
   memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
   ctx->Color.ClearIndex = 0;
   ASSIGN_4V( ctx->Color.ClearColor.f, 0, 0, 0, 0 );
   ctx->Color.AlphaEnabled = GL_FALSE;
   ctx->Color.AlphaFunc = GL_ALWAYS;
   ctx->Color.AlphaRef = 0;
   ctx->Color.BlendEnabled = 0x0;
   for (i = 0; i < ARRAY_SIZE(ctx->Color.Blend); i++) {
      ctx->Color.Blend[i].SrcRGB = GL_ONE;
      ctx->Color.Blend[i].DstRGB = GL_ZERO;
      ctx->Color.Blend[i].SrcA = GL_ONE;
      ctx->Color.Blend[i].DstA = GL_ZERO;
      ctx->Color.Blend[i].EquationRGB = GL_FUNC_ADD;
      ctx->Color.Blend[i].EquationA = GL_FUNC_ADD;
   }
   ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
   ASSIGN_4V( ctx->Color.BlendColorUnclamped, 0.0, 0.0, 0.0, 0.0 );
   ctx->Color.IndexLogicOpEnabled = GL_FALSE;
   ctx->Color.ColorLogicOpEnabled = GL_FALSE;
   ctx->Color.LogicOp = GL_COPY;
   ctx->Color.DitherFlag = GL_TRUE;

   /* GL_FRONT is not possible on GLES. Instead GL_BACK will render to either
    * the front or the back buffer depending on the config */
   if (ctx->Visual.doubleBufferMode || _mesa_is_gles(ctx)) {
      ctx->Color.DrawBuffer[0] = GL_BACK;
   }
   else {
      ctx->Color.DrawBuffer[0] = GL_FRONT;
   }

   ctx->Color.ClampFragmentColor = ctx->API == API_OPENGL_COMPAT ?
                                   GL_FIXED_ONLY_ARB : GL_FALSE;
   ctx->Color._ClampFragmentColor = GL_FALSE;
   ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;

   /* GLES 1/2/3 behaves as though GL_FRAMEBUFFER_SRGB is always enabled
    * if EGL_KHR_gl_colorspace has been used to request sRGB.
    */
   ctx->Color.sRGBEnabled = _mesa_is_gles(ctx);

   ctx->Color.BlendCoherent = true;
}
Example #2
0
void GLAPIENTRY
_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
                       GLboolean layered, GLint layer, GLenum access,
                       GLenum format)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_image_unit *u;

   if (!validate_bind_image_texture(ctx, unit, texture, level,
                                    layered, layer, access, format))
      return;

   u = &ctx->ImageUnits[unit];

   FLUSH_VERTICES(ctx, 0);
   ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;

   if (texture) {
      struct gl_texture_object *t = _mesa_lookup_texture(ctx, texture);

      if (!t) {
         _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)");
         return;
      }

      /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES
       * 3.1 spec:
       *
       * "An INVALID_OPERATION error is generated if texture is not the name
       *  of an immutable texture object."
       */
      if (_mesa_is_gles(ctx) && !t->Immutable) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glBindImageTexture(!immutable)");
         return;
      }

      _mesa_reference_texobj(&u->TexObj, t);
   } else {
      _mesa_reference_texobj(&u->TexObj, NULL);
   }

   u->Level = level;
   u->Access = access;
   u->Format = format;
   u->_ActualFormat = _mesa_get_shader_image_format(format);

   if (u->TexObj && _mesa_tex_target_is_layered(u->TexObj->Target)) {
      u->Layered = layered;
      u->Layer = layer;
      u->_Layer = (u->Layered ? 0 : u->Layer);
   } else {
      u->Layered = GL_FALSE;
      u->Layer = 0;
   }

   if (ctx->Driver.BindImageTexture)
      ctx->Driver.BindImageTexture(ctx, u, u->TexObj, level, layered,
                                   layer, access, format);
}
Example #3
0
/**
 * Attach shader to a shader program.
 */
static void
attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
{
   struct gl_shader_program *shProg;
   struct gl_shader *sh;
   GLuint i, n;

   const bool same_type_disallowed = _mesa_is_gles(ctx);

   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
   if (!shProg)
      return;

   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
   if (!sh) {
      return;
   }

   n = shProg->NumShaders;
   for (i = 0; i < n; i++) {
      if (shProg->Shaders[i] == sh) {
         /* The shader is already attched to this program.  The
          * GL_ARB_shader_objects spec says:
          *
          *     "The error INVALID_OPERATION is generated by AttachObjectARB
          *     if <obj> is already attached to <containerObj>."
          */
         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
         return;
      } else if (same_type_disallowed &&
                 shProg->Shaders[i]->Type == sh->Type) {
        /* Shader with the same type is already attached to this program,
         * OpenGL ES 2.0 and 3.0 specs say:
         *
         *      "Multiple shader objects of the same type may not be attached
         *      to a single program object. [...] The error INVALID_OPERATION
         *      is generated if [...] another shader object of the same type
         *      as shader is already attached to program."
         */
         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
         return;
      }
   }

   /* grow list */
   shProg->Shaders = (struct gl_shader **)
      _mesa_realloc(shProg->Shaders,
                    n * sizeof(struct gl_shader *),
                    (n + 1) * sizeof(struct gl_shader *));
   if (!shProg->Shaders) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
      return;
   }

   /* append */
   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
   shProg->NumShaders++;
}
static size_t
brw_query_samples_for_format(struct gl_context *ctx, GLenum target,
                             GLenum internalFormat, int samples[16])
{
   struct brw_context *brw = brw_context(ctx);
   const struct gen_device_info *devinfo = &brw->screen->devinfo;

   (void) target;
   (void) internalFormat;

   switch (devinfo->gen) {
   case 11:
   case 10:
   case 9:
      samples[0] = 16;
      samples[1] = 8;
      samples[2] = 4;
      samples[3] = 2;
      return 4;

   case 8:
      samples[0] = 8;
      samples[1] = 4;
      samples[2] = 2;
      return 3;

   case 7:
      if (internalFormat == GL_RGBA32F && _mesa_is_gles(ctx)) {
         /* For GLES, we are allowed to return a smaller number of samples for
          * GL_RGBA32F. See OpenGLES 3.2 spec, section 20.3.1 Internal Format
          * Query Parameters, under SAMPLES:
          *
          * "A value less than or equal to the value of MAX_SAMPLES, if
          *  internalformat is RGBA16F, R32F, RG32F, or RGBA32F."
          *
          * In brw_render_target_supported, we prevent formats with a size
          * greater than 8 bytes from using 8x MSAA on gen7.
          */
         samples[0] = 4;
         return 1;
      } else {
         samples[0] = 8;
         samples[1] = 4;
         return 2;
      }

   case 6:
      samples[0] = 4;
      return 1;

   default:
      assert(devinfo->gen < 6);
      samples[0] = 1;
      return 1;
   }
}
Example #5
0
File: texobj.c Project: RAOF/mesa
/**
 * 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 ctx->API == API_OPENGL_CORE &&
             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;
   case GL_TEXTURE_2D_MULTISAMPLE:
      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
         ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
         ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1;
   default:
      return -1;
   }
}
Example #6
0
/**
 * Generate all the mipmap levels below the base level.
 * Note: this GL function would be more useful if one could specify a
 * cube face, a set of array slices, etc.
 */
void GLAPIENTRY
_mesa_GenerateMipmap(GLenum target)
{
   struct gl_texture_image *srcImage;
   struct gl_texture_object *texObj;
   GLboolean error;

   GET_CURRENT_CONTEXT(ctx);

   FLUSH_VERTICES(ctx, 0);

   switch (target) {
   case GL_TEXTURE_1D:
      error = _mesa_is_gles(ctx);
      break;
   case GL_TEXTURE_2D:
      error = GL_FALSE;
      break;
   case GL_TEXTURE_3D:
      error = ctx->API == API_OPENGLES;
      break;
   case GL_TEXTURE_CUBE_MAP:
      error = !ctx->Extensions.ARB_texture_cube_map;
      break;
   case GL_TEXTURE_1D_ARRAY:
      error = _mesa_is_gles(ctx) || !ctx->Extensions.EXT_texture_array;
      break;
   case GL_TEXTURE_2D_ARRAY:
      error = (_mesa_is_gles(ctx) && ctx->Version < 30)
         || !ctx->Extensions.EXT_texture_array;
      break;
   case GL_TEXTURE_CUBE_MAP_ARRAY:
      error = _mesa_is_gles(ctx) ||
              !ctx->Extensions.ARB_texture_cube_map_array;
      break;
   default:
      error = GL_TRUE;
   }

   if (error) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target=%s)",
                  _mesa_lookup_enum_by_nr(target));
      return;
   }

   texObj = _mesa_get_current_tex_object(ctx, target);

   if (texObj->BaseLevel >= texObj->MaxLevel) {
      /* nothing to do */
      return;
   }

   if (texObj->Target == GL_TEXTURE_CUBE_MAP &&
       !_mesa_cube_complete(texObj)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGenerateMipmap(incomplete cube map)");
      return;
   }

   _mesa_lock_texture(ctx, texObj);

   srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
   if (!srcImage) {
      _mesa_unlock_texture(ctx, texObj);
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGenerateMipmap(zero size base image)");
      return;
   }

   if (_mesa_is_enum_format_integer(srcImage->InternalFormat) ||
       _mesa_is_depthstencil_format(srcImage->InternalFormat) ||
       _mesa_is_stencil_format(srcImage->InternalFormat)) {
      _mesa_unlock_texture(ctx, texObj);
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGenerateMipmap(invalid internal format)");
      return;
   }

   if (target == GL_TEXTURE_CUBE_MAP) {
      GLuint face;
      for (face = 0; face < 6; face++)
	 ctx->Driver.GenerateMipmap(ctx,
				    GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face,
				    texObj);
   }
   else {
      ctx->Driver.GenerateMipmap(ctx, target, texObj);
   }
   _mesa_unlock_texture(ctx, texObj);
}
Example #7
0
/**
 * Helper routine used by glDrawBuffer and glDrawBuffersARB.
 * Given a GLenum naming one or more color buffers (such as
 * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags.
 */
static GLbitfield
draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer)
{
   switch (buffer) {
      case GL_NONE:
         return 0;
      case GL_FRONT:
         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
      case GL_BACK:
         if (_mesa_is_gles(ctx)) {
            /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL
             * ES 3.0.1 specification says:
             *
             *     "When draw buffer zero is BACK, color values are written
             *     into the sole buffer for single-buffered contexts, or into
             *     the back buffer for double-buffered contexts."
             *
             * Since there is no stereo rendering in ES 3.0, only return the
             * LEFT bits.  This also satisfies the "n must be 1" requirement.
             *
             * We also do this for GLES 1 and 2 because those APIs have no
             * concept of selecting the front and back buffer anyway and it's
             * convenient to be able to maintain the magic behaviour of
             * GL_BACK in that case.
             */
            if (ctx->DrawBuffer->Visual.doubleBufferMode)
               return BUFFER_BIT_BACK_LEFT;
            return BUFFER_BIT_FRONT_LEFT;
         }
         return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
      case GL_RIGHT:
         return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
      case GL_FRONT_RIGHT:
         return BUFFER_BIT_FRONT_RIGHT;
      case GL_BACK_RIGHT:
         return BUFFER_BIT_BACK_RIGHT;
      case GL_BACK_LEFT:
         return BUFFER_BIT_BACK_LEFT;
      case GL_FRONT_AND_BACK:
         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT
              | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
      case GL_LEFT:
         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT;
      case GL_FRONT_LEFT:
         return BUFFER_BIT_FRONT_LEFT;
      case GL_AUX0:
         return BUFFER_BIT_AUX0;
      case GL_AUX1:
      case GL_AUX2:
      case GL_AUX3:
         return 1 << BUFFER_COUNT; /* invalid, but not BAD_MASK */
      case GL_COLOR_ATTACHMENT0_EXT:
         return BUFFER_BIT_COLOR0;
      case GL_COLOR_ATTACHMENT1_EXT:
         return BUFFER_BIT_COLOR1;
      case GL_COLOR_ATTACHMENT2_EXT:
         return BUFFER_BIT_COLOR2;
      case GL_COLOR_ATTACHMENT3_EXT:
         return BUFFER_BIT_COLOR3;
      case GL_COLOR_ATTACHMENT4_EXT:
         return BUFFER_BIT_COLOR4;
      case GL_COLOR_ATTACHMENT5_EXT:
         return BUFFER_BIT_COLOR5;
      case GL_COLOR_ATTACHMENT6_EXT:
         return BUFFER_BIT_COLOR6;
      case GL_COLOR_ATTACHMENT7_EXT:
         return BUFFER_BIT_COLOR7;
      default:
         /* error */
         return BAD_MASK;
   }
}
Example #8
0
void GLAPIENTRY
_mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
		      GLenum format, GLenum type, GLsizei bufSize,
                      GLvoid *pixels )
{
   GLenum err = GL_NO_ERROR;
   struct gl_renderbuffer *rb;

   GET_CURRENT_CONTEXT(ctx);

   FLUSH_VERTICES(ctx, 0);
   FLUSH_CURRENT(ctx, 0);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
                  width, height,
                  _mesa_lookup_enum_by_nr(format),
                  _mesa_lookup_enum_by_nr(type),
                  pixels);

   if (width < 0 || height < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE,
                   "glReadPixels(width=%d height=%d)", width, height );
      return;
   }

   if (ctx->NewState)
      _mesa_update_state(ctx);

   if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                  "glReadPixels(incomplete framebuffer)" );
      return;
   }

   rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
   if (rb == NULL) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glReadPixels(read buffer)");
      return;
   }

   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
    * combinations of format and type that can be used.
    *
    * Technically, only two combinations are actually allowed:
    * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
    * preferred combination.  This code doesn't know what that preferred
    * combination is, and Mesa can handle anything valid.  Just work instead.
    */
   if (_mesa_is_gles(ctx)) {
      if (ctx->API == API_OPENGLES2 &&
          _mesa_is_color_format(format) &&
          _mesa_get_color_read_format(ctx) == format &&
          _mesa_get_color_read_type(ctx) == type) {
         err = GL_NO_ERROR;
      } else if (ctx->Version < 30) {
         err = _mesa_es_error_check_format_and_type(format, type, 2);
         if (err == GL_NO_ERROR) {
            if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
               err = GL_INVALID_OPERATION;
            }
         }
      } else {
         err = read_pixels_es3_error_check(format, type, rb);
      }

      if (err == GL_NO_ERROR && (format == GL_DEPTH_COMPONENT
          || format == GL_DEPTH_STENCIL)) {
         err = GL_INVALID_ENUM;
      }

      if (err != GL_NO_ERROR) {
         _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
                     _mesa_lookup_enum_by_nr(format),
                     _mesa_lookup_enum_by_nr(type));
         return;
      }
   }

   err = _mesa_error_check_format_and_type(ctx, format, type);
   if (err != GL_NO_ERROR) {
      _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
                  _mesa_lookup_enum_by_nr(format),
                  _mesa_lookup_enum_by_nr(type));
      return;
   }

   if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
       ctx->ReadBuffer->Visual.samples > 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
      return;
   }

   if (!_mesa_source_buffer_exists(ctx, format)) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
      return;
   }

   /* Check that the destination format and source buffer are both
    * integer-valued or both non-integer-valued.
    */
   if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
      const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
      const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
      const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
      if (dstInteger != srcInteger) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glReadPixels(integer / non-integer format mismatch");
         return;
      }
   }

   if (width == 0 || height == 0)
      return; /* nothing to do */

   if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
                                  format, type, bufSize, pixels)) {
      if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glReadPixels(out of bounds PBO access)");
      } else {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glReadnPixelsARB(out of bounds access:"
                     " bufSize (%d) is too small)", bufSize);
      }
      return;
   }

   if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
       _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
      /* buffer is mapped - that's an error */
      _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
      return;
   }

   ctx->Driver.ReadPixels(ctx, x, y, width, height,
			  format, type, &ctx->Pack, pixels);
}
Example #9
0
/**
 * Clear buffers.
 *
 * \param mask bit-mask indicating the buffers to be cleared.
 *
 * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState
 * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
 * etc. If the rasterization mode is set to GL_RENDER then requests the driver
 * to clear the buffers, via the dd_function_table::Clear callback.
 */
void GLAPIENTRY
_mesa_Clear( GLbitfield mask )
{
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_VERTICES(ctx, 0);

    FLUSH_CURRENT(ctx, 0);

    if (MESA_VERBOSE & VERBOSE_API)
        _mesa_debug(ctx, "glClear 0x%x\n", mask);

    if (mask & ~(GL_COLOR_BUFFER_BIT |
                 GL_DEPTH_BUFFER_BIT |
                 GL_STENCIL_BUFFER_BIT |
                 GL_ACCUM_BUFFER_BIT)) {
        /* invalid bit set */
        _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
        return;
    }

    /* Accumulation buffers were removed in core contexts, and they never
     * existed in OpenGL ES.
     */
    if ((mask & GL_ACCUM_BUFFER_BIT) != 0
            && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) {
        _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)");
        return;
    }

    if (ctx->NewState) {
        _mesa_update_state( ctx );	/* update _Xmin, etc */
    }

    if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
        _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                    "glClear(incomplete framebuffer)");
        return;
    }

    if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 ||
            ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax ||
            ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax)
        return;

    if (ctx->RasterDiscard)
        return;

    if (ctx->RenderMode == GL_RENDER) {
        GLbitfield bufferMask;

        /* don't clear depth buffer if depth writing disabled */
        if (!ctx->Depth.Mask)
            mask &= ~GL_DEPTH_BUFFER_BIT;

        /* Build the bitmask to send to device driver's Clear function.
         * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
         * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
         * BUFFER_BIT_COLORn flags.
         */
        bufferMask = 0;
        if (mask & GL_COLOR_BUFFER_BIT) {
            GLuint i;
            for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
                GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];

                if (buf >= 0) {
                    bufferMask |= 1 << buf;
                }
            }
        }

        if ((mask & GL_DEPTH_BUFFER_BIT)
                && ctx->DrawBuffer->Visual.haveDepthBuffer) {
            bufferMask |= BUFFER_BIT_DEPTH;
        }

        if ((mask & GL_STENCIL_BUFFER_BIT)
                && ctx->DrawBuffer->Visual.haveStencilBuffer) {
            bufferMask |= BUFFER_BIT_STENCIL;
        }

        if ((mask & GL_ACCUM_BUFFER_BIT)
                && ctx->DrawBuffer->Visual.haveAccumBuffer) {
            bufferMask |= BUFFER_BIT_ACCUM;
        }

        ASSERT(ctx->Driver.Clear);
        ctx->Driver.Clear(ctx, bufferMask);
    }
}
Example #10
0
/**
 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
 * functions.
 *
 * \param func  name of calling function used for error reporting
 * \param attrib  the attribute array index to update
 * \param legalTypes  bitmask of *_BIT above indicating legal datatypes
 * \param sizeMin  min allowable size value
 * \param sizeMax  max allowable size value (may also be BGRA_OR_4)
 * \param size  components per element (1, 2, 3 or 4)
 * \param type  datatype of each component (GL_FLOAT, GL_INT, etc)
 * \param stride  stride between elements, in elements
 * \param normalized  are integer types converted to floats in [-1, 1]?
 * \param integer  integer-valued values (will not be normalized to [-1,1])
 * \param ptr  the address (or offset inside VBO) of the array data
 */
static void
update_array(struct gl_context *ctx,
             const char *func,
             GLuint attrib, GLbitfield legalTypesMask,
             GLint sizeMin, GLint sizeMax,
             GLint size, GLenum type, GLsizei stride,
             GLboolean normalized, GLboolean integer,
             const GLvoid *ptr)
{
   struct gl_client_array *array;
   GLbitfield typeBit;
   GLsizei elementSize;
   GLenum format = GL_RGBA;

   if (_mesa_is_gles(ctx)) {
      /* Once Mesa gets support for GL_OES_vertex_half_float this mask will
       * change.  Adding support for this extension isn't quite as trivial as
       * we'd like because ES uses a different enum value for GL_HALF_FLOAT.
       */
      legalTypesMask &= ~(FIXED_GL_BIT | HALF_BIT | DOUBLE_BIT);

      /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
       * 3.0.  The 2_10_10_10 types are added in OpenGL ES 3.0 or
       * GL_OES_vertex_type_10_10_10_2.
       */
      if (ctx->Version < 30) {
         legalTypesMask &= ~(UNSIGNED_INT_BIT
                             | INT_BIT
                             | UNSIGNED_INT_2_10_10_10_REV_BIT
                             | INT_2_10_10_10_REV_BIT);
      }

      /* BGRA ordering is not supported in ES contexts.
       */
      if (sizeMax == BGRA_OR_4)
         sizeMax = 4;
   } else {
      legalTypesMask &= ~FIXED_ES_BIT;

      if (!ctx->Extensions.ARB_ES2_compatibility)
         legalTypesMask &= ~FIXED_GL_BIT;

      if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
         legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
                             INT_2_10_10_10_REV_BIT);
   }

   typeBit = type_to_bit(ctx, type);
   if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
                  func, _mesa_lookup_enum_by_nr(type));
      return;
   }

   /* Do size parameter checking.
    * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
    * must be handled specially.
    */
   if (ctx->Extensions.EXT_vertex_array_bgra &&
       sizeMax == BGRA_OR_4 &&
       size == GL_BGRA) {
      GLboolean bgra_error = GL_FALSE;

      if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
         if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
             type != GL_INT_2_10_10_10_REV &&
             type != GL_UNSIGNED_BYTE)
            bgra_error = GL_TRUE;
      } else if (type != GL_UNSIGNED_BYTE)
         bgra_error = GL_TRUE;

      if (bgra_error) {
         _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func);
         return;
      }
      format = GL_BGRA;
      size = 4;
   }
   else if (size < sizeMin || size > sizeMax || size > 4) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
      return;
   }

   if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
       (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
        type == GL_INT_2_10_10_10_REV) && size != 4) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
      return;
   }

   ASSERT(size <= 4);

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

   if (ctx->Array.ArrayObj->ARBsemantics &&
       !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) {
      /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs.
       * Generate GL_INVALID_OPERATION if that's not true.
       */
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
      return;
   }

   elementSize = _mesa_sizeof_type(type) * size;

   array = &ctx->Array.ArrayObj->VertexAttrib[attrib];
   array->Size = size;
   array->Type = type;
   array->Format = format;
   array->Stride = stride;
   array->StrideB = stride ? stride : elementSize;
   array->Normalized = normalized;
   array->Integer = integer;
   array->Ptr = (const GLubyte *) ptr;
   array->_ElementSize = elementSize;

   _mesa_reference_buffer_object(ctx, &array->BufferObj,
                                 ctx->Array.ArrayBufferObj);

   ctx->NewState |= _NEW_ARRAY;
   ctx->Array.ArrayObj->NewArrays |= VERT_BIT(attrib);
}
Example #11
0
/**
 * Return list of (and count of) all specific texture compression
 * formats that are supported.
 *
 * Some formats are \b not returned by this function.  The
 * \c GL_COMPRESSED_TEXTURE_FORMATS query only returns formats that are
 * "suitable for general-purpose usage."  All texture compression extensions
 * have taken this to mean either linear RGB or linear RGBA.
 *
 * The GL_ARB_texture_compress_rgtc spec says:
 *
 *    "19) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and
 *        GL_COMPRESSED_TEXTURE_FORMATS queries return the RGTC formats?
 *
 *        RESOLVED:  No.
 *
 *        The OpenGL 2.1 specification says "The only values returned
 *        by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those
 *        corresponding to formats suitable for general-purpose usage.
 *        The renderer will not enumerate formats with restrictions that
 *        need to be specifically understood prior to use."
 *
 *        Compressed textures with just red or red-green components are
 *        not general-purpose so should not be returned by these queries
 *        because they have restrictions.
 *
 *        Applications that seek to use the RGTC formats should do so
 *        by looking for this extension's name in the string returned by
 *        glGetString(GL_EXTENSIONS) rather than
 *        what GL_NUM_COMPRESSED_TEXTURE_FORMATS and
 *        GL_COMPRESSED_TEXTURE_FORMATS return."
 *
 * There is nearly identical wording in the GL_EXT_texture_compression_rgtc
 * spec.
 *
 * The GL_EXT_texture_rRGB spec says:
 *
 *    "22) Should the new COMPRESSED_SRGB_* formats be listed in an
 *        implementation's GL_COMPRESSED_TEXTURE_FORMATS list?
 *
 *        RESOLVED:  No.  Section 3.8.1 says formats listed by
 *        GL_COMPRESSED_TEXTURE_FORMATS are "suitable for general-purpose
 *        usage."  The non-linear distribution of red, green, and
 *        blue for these sRGB compressed formats makes them not really
 *        general-purpose."
 *
 * The GL_EXT_texture_compression_latc spec says:
 *
 *    "16) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and
 *        GL_COMPRESSED_TEXTURE_FORMATS queries return the LATC formats?
 *
 *        RESOLVED:  No.
 *
 *        The OpenGL 2.1 specification says "The only values returned
 *        by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those
 *        corresponding to formats suitable for general-purpose usage.
 *        The renderer will not enumerate formats with restrictions that
 *        need to be specifically understood prior to use."
 *
 *        Historically, OpenGL implementation have advertised the RGB and
 *        RGBA versions of the S3TC extensions compressed format tokens
 *        through this mechanism.
 *
 *        The specification is not sufficiently clear about what "suitable
 *        for general-purpose usage" means.  Historically that seems to mean
 *        unsigned RGB or unsigned RGBA.  The DXT1 format supporting alpha
 *        (GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) is not exposed in the list (at
 *        least for NVIDIA drivers) because the alpha is always 1.0 expect
 *        when it is 0.0 when RGB is required to be black.  NVIDIA's even
 *        limits itself to true linear RGB or RGBA formats, specifically
 *        not including EXT_texture_sRGB's sRGB S3TC compressed formats.
 *
 *        Adding luminance and luminance-alpha texture formats (and
 *        certainly signed versions of luminance and luminance-alpha
 *        formats!) invites potential comptaibility problems with old
 *        applications using this mechanism since old applications are
 *        unlikely to expect non-RGB or non-RGBA formats to be advertised
 *        through this mechanism.  However no specific misinteractions
 *        with old applications is known.
 *
 *        Applications that seek to use the LATC formats should do so
 *        by looking for this extension's name in the string returned by
 *        glGetString(GL_EXTENSIONS) rather than
 *        what GL_NUM_COMPRESSED_TEXTURE_FORMATS and
 *        GL_COMPRESSED_TEXTURE_FORMATS return."
 *
 * There is no formal spec for GL_ATI_texture_compression_3dc.  Since the
 * formats added by this extension are luminance-alpha formats, it is
 * reasonable to expect them to follow the same rules as
 * GL_EXT_texture_compression_latc.  At the very least, Catalyst 11.6 does not
 * expose the 3dc formats through this mechanism.
 *
 * The spec for GL_ARB_texture_compression_bptc doesn't mention whether it
 * should be included in GL_COMPRESSED_TEXTURE_FORMATS. However as it takes a
 * very long time to compress the textures in this format it's probably not
 * very useful as a general format where the GL will have to compress it on
 * the fly.
 *
 * \param ctx  the GL context
 * \param formats  the resulting format list (may be NULL).
 *
 * \return number of formats.
 */
GLuint
_mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats)
{
   GLint discard_formats[100];
   GLuint n = 0;

   if (!formats) {
      formats = discard_formats;
   }

   if (_mesa_is_desktop_gl(ctx) &&
       ctx->Extensions.TDFX_texture_compression_FXT1) {
      formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX;
      formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX;
   }

   if (ctx->Extensions.EXT_texture_compression_s3tc) {
      formats[n++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
      formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
      formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;

      /* The ES and desktop GL specs diverge here.
       *
       * In desktop OpenGL, the driver can perform online compression of
       * uncompressed texture data.  GL_NUM_COMPRESSED_TEXTURE_FORMATS and
       * GL_COMPRESSED_TEXTURE_FORMATS give the application a list of
       * formats that it could ask the driver to compress with some
       * expectation of quality.  The GL_ARB_texture_compression spec
       * calls this "suitable for general-purpose usage."  As noted
       * above, this means GL_COMPRESSED_RGBA_S3TC_DXT1_EXT is not
       * included in the list.
       *
       * In OpenGL ES, the driver never performs compression.
       * GL_NUM_COMPRESSED_TEXTURE_FORMATS and
       * GL_COMPRESSED_TEXTURE_FORMATS give the application a list of
       * formats that the driver can receive from the application.  It
       * is the *complete* list of formats.  The
       * GL_EXT_texture_compression_s3tc spec says:
       *
       *     "New State for OpenGL ES 2.0.25 and 3.0.2 Specifications
       *
       *         The queries for NUM_COMPRESSED_TEXTURE_FORMATS and
       *         COMPRESSED_TEXTURE_FORMATS include
       *         COMPRESSED_RGB_S3TC_DXT1_EXT,
       *         COMPRESSED_RGBA_S3TC_DXT1_EXT,
       *         COMPRESSED_RGBA_S3TC_DXT3_EXT, and
       *         COMPRESSED_RGBA_S3TC_DXT5_EXT."
       *
       * Note that the addition is only to the OpenGL ES specification!
       */
      if (_mesa_is_gles(ctx)) {
         formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
      }
   }

   /* The GL_OES_compressed_ETC1_RGB8_texture spec says:
    *
    *     "New State
    *
    *         The queries for NUM_COMPRESSED_TEXTURE_FORMATS and
    *         COMPRESSED_TEXTURE_FORMATS include ETC1_RGB8_OES."
    */
   if (_mesa_is_gles(ctx)
       && ctx->Extensions.OES_compressed_ETC1_RGB8_texture) {
      formats[n++] = GL_ETC1_RGB8_OES;
   }

   if (ctx->API == API_OPENGLES) {
      formats[n++] = GL_PALETTE4_RGB8_OES;
      formats[n++] = GL_PALETTE4_RGBA8_OES;
      formats[n++] = GL_PALETTE4_R5_G6_B5_OES;
      formats[n++] = GL_PALETTE4_RGBA4_OES;
      formats[n++] = GL_PALETTE4_RGB5_A1_OES;
      formats[n++] = GL_PALETTE8_RGB8_OES;
      formats[n++] = GL_PALETTE8_RGBA8_OES;
      formats[n++] = GL_PALETTE8_R5_G6_B5_OES;
      formats[n++] = GL_PALETTE8_RGBA4_OES;
      formats[n++] = GL_PALETTE8_RGB5_A1_OES;
   }

   if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) {
      formats[n++] = GL_COMPRESSED_RGB8_ETC2;
      formats[n++] = GL_COMPRESSED_RGBA8_ETC2_EAC;
      formats[n++] = GL_COMPRESSED_R11_EAC;
      formats[n++] = GL_COMPRESSED_RG11_EAC;
      formats[n++] = GL_COMPRESSED_SIGNED_R11_EAC;
      formats[n++] = GL_COMPRESSED_SIGNED_RG11_EAC;
      formats[n++] = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
   }

   if (_mesa_is_gles3(ctx)) {
      formats[n++] = GL_COMPRESSED_SRGB8_ETC2;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
      formats[n++] = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
   }

   /* The KHR_texture_compression_astc_hdr spec says:
    *
    *    "Interactions with OpenGL 4.2
    *
    *        OpenGL 4.2 supports the feature that compressed textures can be
    *        compressed online, by passing the compressed texture format enum
    *        as the internal format when uploading a texture using TexImage1D,
    *        TexImage2D or TexImage3D (see Section 3.9.3, Texture Image
    *        Specification, subsection Encoding of Special Internal Formats).
    *
    *        Due to the complexity of the ASTC compression algorithm, it is
    *        not usually suitable for online use, and therefore ASTC support
    *        will be limited to pre-compressed textures only. Where on-device
    *        compression is required, a domain-specific limited compressor
    *        will typically be used, and this is therefore not suitable for
    *        implementation in the driver.
    *
    *        In particular, the ASTC format specifiers will not be added to
    *        Table 3.14, and thus will not be accepted by the TexImage*D
    *        functions, and will not be returned by the (already deprecated)
    *        COMPRESSED_TEXTURE_FORMATS query."
    *
    * The ES and the desktop specs diverge here. In OpenGL ES, the
    * COMPRESSED_TEXTURE_FORMATS query returns the set of supported specific
    * compressed formats.
    */
   if (ctx->API == API_OPENGLES2 &&
       ctx->Extensions.KHR_texture_compression_astc_ldr) {
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
   }

   if (_mesa_is_gles3(ctx) &&
       ctx->Extensions.OES_texture_compression_astc) {
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_3x3x3_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_4x3x3_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_4x4x3_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_4x4x4_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_5x4x4_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_5x5x4_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_5x5x5_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_6x5x5_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_6x6x5_OES;
      formats[n++] = GL_COMPRESSED_RGBA_ASTC_6x6x6_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES;
      formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES;
   }

   assert(n <= ARRAY_SIZE(discard_formats));

   return n;
}
Example #12
0
void GLAPIENTRY
_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
{
   struct gl_sampler_object *sampObj;
   GLuint res;
   GET_CURRENT_CONTEXT(ctx);

   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
   if (!sampObj) {
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
       *
       *     "An INVALID_OPERATION error is generated if sampler is not the name
       *     of a sampler object previously returned from a call to GenSamplers."
       *
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
       */
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
                  "glSamplerParameteriv(sampler %u)", sampler);
      return;
   }

   switch (pname) {
   case GL_TEXTURE_WRAP_S:
      res = set_sampler_wrap_s(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_WRAP_T:
      res = set_sampler_wrap_t(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_WRAP_R:
      res = set_sampler_wrap_r(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_MIN_FILTER:
      res = set_sampler_min_filter(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_MAG_FILTER:
      res = set_sampler_mag_filter(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_MIN_LOD:
      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
      break;
   case GL_TEXTURE_MAX_LOD:
      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
      break;
   case GL_TEXTURE_LOD_BIAS:
      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
      break;
   case GL_TEXTURE_COMPARE_MODE:
      res = set_sampler_compare_mode(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_COMPARE_FUNC:
      res = set_sampler_compare_func(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
      break;
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
      res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_SRGB_DECODE_EXT:
      res = set_sampler_srgb_decode(ctx, sampObj, params[0]);
      break;
   case GL_TEXTURE_BORDER_COLOR:
      {
         GLfloat c[4];
         c[0] = INT_TO_FLOAT(params[0]);
         c[1] = INT_TO_FLOAT(params[1]);
         c[2] = INT_TO_FLOAT(params[2]);
         c[3] = INT_TO_FLOAT(params[3]);
         res = set_sampler_border_colorf(ctx, sampObj, c);
      }
      break;
   default:
      res = INVALID_PNAME;
   }

   switch (res) {
   case GL_FALSE:
      /* no change */
      break;
   case GL_TRUE:
      /* state change - we do nothing special at this time */
      break;
   case INVALID_PNAME:
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n",
                  _mesa_enum_to_string(pname));
      break;
   case INVALID_PARAM:
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n",
                  params[0]);
      break;
   case INVALID_VALUE:
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n",
                  params[0]);
      break;
   default:
      ;
   }
}
Example #13
0
void GLAPIENTRY
_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
{
   struct gl_sampler_object *sampObj;
   GET_CURRENT_CONTEXT(ctx);

   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
   if (!sampObj) {
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
       *
       *     "An INVALID_OPERATION error is generated if sampler is not the name
       *     of a sampler object previously returned from a call to GenSamplers."
       *
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
       */
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
                  "glGetSamplerParameterfv(sampler %u)", sampler);
      return;
   }

   switch (pname) {
   case GL_TEXTURE_WRAP_S:
      *params = (GLfloat) sampObj->WrapS;
      break;
   case GL_TEXTURE_WRAP_T:
      *params = (GLfloat) sampObj->WrapT;
      break;
   case GL_TEXTURE_WRAP_R:
      *params = (GLfloat) sampObj->WrapR;
      break;
   case GL_TEXTURE_MIN_FILTER:
      *params = (GLfloat) sampObj->MinFilter;
      break;
   case GL_TEXTURE_MAG_FILTER:
      *params = (GLfloat) sampObj->MagFilter;
      break;
   case GL_TEXTURE_MIN_LOD:
      *params = sampObj->MinLod;
      break;
   case GL_TEXTURE_MAX_LOD:
      *params = sampObj->MaxLod;
      break;
   case GL_TEXTURE_LOD_BIAS:
      *params = sampObj->LodBias;
      break;
   case GL_TEXTURE_COMPARE_MODE:
      if (!ctx->Extensions.ARB_shadow)
         goto invalid_pname;
      *params = (GLfloat) sampObj->CompareMode;
      break;
   case GL_TEXTURE_COMPARE_FUNC:
      if (!ctx->Extensions.ARB_shadow)
         goto invalid_pname;
      *params = (GLfloat) sampObj->CompareFunc;
      break;
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
      *params = sampObj->MaxAnisotropy;
      break;
   case GL_TEXTURE_BORDER_COLOR:
      params[0] = sampObj->BorderColor.f[0];
      params[1] = sampObj->BorderColor.f[1];
      params[2] = sampObj->BorderColor.f[2];
      params[3] = sampObj->BorderColor.f[3];
      break;
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
         goto invalid_pname;
      *params = (GLfloat) sampObj->CubeMapSeamless;
      break;
   case GL_TEXTURE_SRGB_DECODE_EXT:
      if (!ctx->Extensions.EXT_texture_sRGB_decode)
         goto invalid_pname;
      *params = (GLfloat) sampObj->sRGBDecode;
      break;
   default:
      goto invalid_pname;
   }
   return;

invalid_pname:
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)",
               _mesa_enum_to_string(pname));
}
Example #14
0
/**
 * Test if an image format is a supported compressed format.
 * \param format the internal format token provided by the user.
 * \return GL_TRUE if compressed, GL_FALSE if uncompressed
 */
GLboolean
_mesa_is_compressed_format(struct gl_context *ctx, GLenum format)
{
   switch (format) {
   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      return ctx->Extensions.EXT_texture_compression_s3tc;
   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      return (_mesa_is_desktop_gl(ctx) &&
	      ctx->Extensions.EXT_texture_compression_s3tc) ||
	     (ctx->API == API_OPENGLES2 &&
	      ctx->Extensions.ANGLE_texture_compression_dxt);
   case GL_RGB_S3TC:
   case GL_RGB4_S3TC:
   case GL_RGBA_S3TC:
   case GL_RGBA4_S3TC:
      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.S3_s3tc;
   case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
      return _mesa_is_desktop_gl(ctx)
         && ctx->Extensions.EXT_texture_sRGB
         && ctx->Extensions.EXT_texture_compression_s3tc;
   case GL_COMPRESSED_RGB_FXT1_3DFX:
   case GL_COMPRESSED_RGBA_FXT1_3DFX:
      return _mesa_is_desktop_gl(ctx)
         && ctx->Extensions.TDFX_texture_compression_FXT1;
   case GL_COMPRESSED_RED_RGTC1:
   case GL_COMPRESSED_SIGNED_RED_RGTC1:
   case GL_COMPRESSED_RG_RGTC2:
   case GL_COMPRESSED_SIGNED_RG_RGTC2:
      return _mesa_is_desktop_gl(ctx)
         && ctx->Extensions.ARB_texture_compression_rgtc;
   case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
   case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
   case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
   case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
      return ctx->API == API_OPENGL_COMPAT
         && ctx->Extensions.EXT_texture_compression_latc;
   case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
      return ctx->API == API_OPENGL_COMPAT
         && ctx->Extensions.ATI_texture_compression_3dc;
   case GL_ETC1_RGB8_OES:
      return _mesa_is_gles(ctx)
         && ctx->Extensions.OES_compressed_ETC1_RGB8_texture;
   case GL_PALETTE4_RGB8_OES:
   case GL_PALETTE4_RGBA8_OES:
   case GL_PALETTE4_R5_G6_B5_OES:
   case GL_PALETTE4_RGBA4_OES:
   case GL_PALETTE4_RGB5_A1_OES:
   case GL_PALETTE8_RGB8_OES:
   case GL_PALETTE8_RGBA8_OES:
   case GL_PALETTE8_R5_G6_B5_OES:
   case GL_PALETTE8_RGBA4_OES:
   case GL_PALETTE8_RGB5_A1_OES:
      return ctx->API == API_OPENGLES;
   default:
      return GL_FALSE;
   }
}
Example #15
0
File: blit.c Project: airlied/mesa
void
_mesa_blit_framebuffer(struct gl_context *ctx,
                       struct gl_framebuffer *readFb,
                       struct gl_framebuffer *drawFb,
                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                       GLbitfield mask, GLenum filter, const char *func)
{
   const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
                                     GL_DEPTH_BUFFER_BIT |
                                     GL_STENCIL_BUFFER_BIT);

   FLUSH_VERTICES(ctx, 0);

   /* Update completeness status of readFb and drawFb. */
   _mesa_update_framebuffer(ctx, readFb, drawFb);

   /* Make sure drawFb has an initialized bounding box. */
   _mesa_update_draw_buffer_bounds(ctx, drawFb);

   if (!readFb || !drawFb) {
      /* This will normally never happen but someday we may want to
       * support MakeCurrent() with no drawables.
       */
      return;
   }

   /* check for complete framebuffers */
   if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
       readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                  "%s(incomplete draw/read buffers)", func);
      return;
   }

   if (!is_valid_blit_filter(ctx, filter)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
                  _mesa_enum_to_string(filter));
      return;
   }

   if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
        filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
        (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
                  _mesa_enum_to_string(filter));
      return;
   }

   if (mask & ~legalMaskBits) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
      return;
   }

   /* depth/stencil must be blitted with nearest filtering */
   if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
        && filter != GL_NEAREST) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
             "%s(depth/stencil requires GL_NEAREST filter)", func);
      return;
   }

   /* get color read/draw renderbuffers */
   if (mask & GL_COLOR_BUFFER_BIT) {
      const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
      const struct gl_renderbuffer *colorDrawRb = NULL;
      GLuint i;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if (!colorReadRb || numColorDrawBuffers == 0) {
         mask &= ~GL_COLOR_BUFFER_BIT;
      }
      else {
         for (i = 0; i < numColorDrawBuffers; i++) {
            colorDrawRb = drawFb->_ColorDrawBuffers[i];
            if (!colorDrawRb)
               continue;

            /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
             * ES 3.0.1 spec says:
             *
             *     "If the source and destination buffers are identical, an
             *     INVALID_OPERATION error is generated. Different mipmap
             *     levels of a texture, different layers of a three-
             *     dimensional texture or two-dimensional array texture, and
             *     different faces of a cube map texture do not constitute
             *     identical buffers."
             */
            if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "%s(source and destination color "
                           "buffer cannot be the same)", func);
               return;
            }

            if (!compatible_color_datatypes(colorReadRb->Format,
                                            colorDrawRb->Format)) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "%s(color buffer datatypes mismatch)", func);
               return;
            }
            /* extra checks for multisample copies... */
            if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
               /* color formats must match on GLES. This isn't checked on
                * desktop GL because the GL 4.4 spec was changed to allow it.
                * In the section entitled “Changes in the released
                * Specification of July 22, 2013” it says:
                *
                * “Relax BlitFramebuffer in section 18.3.1 so that format
                *  conversion can take place during multisample blits, since
                *  drivers already allow this and some apps depend on it.”
                */
               if (_mesa_is_gles(ctx) &&
                   !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
                  _mesa_error(ctx, GL_INVALID_OPERATION,
                         "%s(bad src/dst multisample pixel formats)", func);
                  return;
               }
            }
         }
         if (filter != GL_NEAREST) {
            /* From EXT_framebuffer_multisample_blit_scaled specification:
             * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
             * if filter is not NEAREST and read buffer contains integer data."
             */
            GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
            if (type == GL_INT || type == GL_UNSIGNED_INT) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "%s(integer color type)", func);
               return;
            }
         }
      }
   }

   if (mask & GL_STENCIL_BUFFER_BIT) {
      struct gl_renderbuffer *readRb =
         readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
      struct gl_renderbuffer *drawRb =
         drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if ((readRb == NULL) || (drawRb == NULL)) {
         mask &= ~GL_STENCIL_BUFFER_BIT;
      }
      else {
         int read_z_bits, draw_z_bits;

         if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(source and destination stencil "
                        "buffer cannot be the same)", func);
            return;
         }

         if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
             _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
            /* There is no need to check the stencil datatype here, because
             * there is only one: GL_UNSIGNED_INT.
             */
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(stencil attachment format mismatch)", func);
            return;
         }

         read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
         draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);

         /* If both buffers also have depth data, the depth formats must match
          * as well.  If one doesn't have depth, it's not blitted, so we should
          * ignore the depth format check.
          */
         if (read_z_bits > 0 && draw_z_bits > 0 &&
             (read_z_bits != draw_z_bits ||
              _mesa_get_format_datatype(readRb->Format) !=
              _mesa_get_format_datatype(drawRb->Format))) {

            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(stencil attachment depth format mismatch)", func);
            return;
         }
      }
   }

   if (mask & GL_DEPTH_BUFFER_BIT) {
      struct gl_renderbuffer *readRb =
         readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
      struct gl_renderbuffer *drawRb =
         drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if ((readRb == NULL) || (drawRb == NULL)) {
         mask &= ~GL_DEPTH_BUFFER_BIT;
      }
      else {
         int read_s_bit, draw_s_bit;

         if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(source and destination depth "
                        "buffer cannot be the same)", func);
            return;
         }

         if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
              _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
             (_mesa_get_format_datatype(readRb->Format) !=
              _mesa_get_format_datatype(drawRb->Format))) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(depth attachment format mismatch)", func);
            return;
         }

         read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
         draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);

         /* If both buffers also have stencil data, the stencil formats must
          * match as well.  If one doesn't have stencil, it's not blitted, so
          * we should ignore the stencil format check.
          */
         if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(depth attachment stencil bits mismatch)", func);
            return;
         }
      }
   }


   if (_mesa_is_gles3(ctx)) {
      /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
       * 3.0.1 spec says:
       *
       *     "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero,
       *     an INVALID_OPERATION error is generated."
       */
      if (drawFb->Visual.samples > 0) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(destination samples must be 0)", func);
         return;
      }

      /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
       * 3.0.1 spec says:
       *
       *     "If SAMPLE_BUFFERS for the read framebuffer is greater than zero,
       *     no copy is performed and an INVALID_OPERATION error is generated
       *     if the formats of the read and draw framebuffers are not
       *     identical or if the source and destination rectangles are not
       *     defined with the same (X0, Y0) and (X1, Y1) bounds."
       *
       * The format check was made above because desktop OpenGL has the same
       * requirement.
       */
      if (readFb->Visual.samples > 0
          && (srcX0 != dstX0 || srcY0 != dstY0
              || srcX1 != dstX1 || srcY1 != dstY1)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(bad src/dst multisample region)", func);
         return;
      }
   } else {
      if (readFb->Visual.samples > 0 &&
          drawFb->Visual.samples > 0 &&
          readFb->Visual.samples != drawFb->Visual.samples) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(mismatched samples)", func);
         return;
      }

      /* extra checks for multisample copies... */
      if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
          (filter == GL_NEAREST || filter == GL_LINEAR)) {
         /* src and dest region sizes must be the same */
         if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
             abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(bad src/dst multisample region sizes)", func);
            return;
         }
      }
   }

   /* Debug code */
   if (DEBUG_BLIT) {
      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
      const struct gl_renderbuffer *colorDrawRb = NULL;
      GLuint i = 0;

      printf("%s(%d, %d, %d, %d,  %d, %d, %d, %d,"
             " 0x%x, 0x%x)\n", func,
             srcX0, srcY0, srcX1, srcY1,
             dstX0, dstY0, dstX1, dstY1,
             mask, filter);

      if (colorReadRb) {
         const struct gl_renderbuffer_attachment *att;

         att = find_attachment(readFb, colorReadRb);
         printf("  Src FBO %u  RB %u (%dx%d)  ",
                readFb->Name, colorReadRb->Name,
                colorReadRb->Width, colorReadRb->Height);
         if (att && att->Texture) {
            printf("Tex %u  tgt 0x%x  level %u  face %u",
                   att->Texture->Name,
                   att->Texture->Target,
                   att->TextureLevel,
                   att->CubeMapFace);
         }
         printf("\n");

         /* Print all active color render buffers */
         for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
            colorDrawRb = drawFb->_ColorDrawBuffers[i];
            if (!colorDrawRb)
               continue;

            att = find_attachment(drawFb, colorDrawRb);
            printf("  Dst FBO %u  RB %u (%dx%d)  ",
                   drawFb->Name, colorDrawRb->Name,
                   colorDrawRb->Width, colorDrawRb->Height);
            if (att && att->Texture) {
               printf("Tex %u  tgt 0x%x  level %u  face %u",
                      att->Texture->Name,
                      att->Texture->Target,
                      att->TextureLevel,
                      att->CubeMapFace);
            }
            printf("\n");
         }
      }
   }

   if (!mask ||
       (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
       (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
      return;
   }

   assert(ctx->Driver.BlitFramebuffer);
   ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
                               srcX0, srcY0, srcX1, srcY1,
                               dstX0, dstY0, dstX1, dstY1,
                               mask, filter);
}
Example #16
0
/**
 * Choose an appropriate texture format given the format, type and
 * internalFormat parameters passed to glTexImage().
 *
 * \param ctx  the GL context.
 * \param internalFormat  user's prefered internal texture format.
 * \param format  incoming image pixel format.
 * \param type  incoming image data type.
 *
 * \return a pointer to a gl_texture_format object which describes the
 * choosen texture format, or NULL on failure.
 * 
 * This is called via dd_function_table::ChooseTextureFormat.  Hardware drivers
 * will typically override this function with a specialized version.
 */
gl_format
_mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
                        GLint internalFormat, GLenum format, GLenum type)
{
   (void) format;
   (void) type;

   switch (internalFormat) {
      /* shallow RGBA formats */
      case 4:
      case GL_RGBA:
	 if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
	    RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB4444);
	 } else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
	    RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB1555);
         } else if (type == GL_UNSIGNED_INT_2_10_10_10_REV) {
            RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB2101010);
         }
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;

      case GL_RGBA8:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;
      case GL_RGB5_A1:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB1555);
	 break;
      case GL_RGBA2:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB4444_REV); /* just to test another format*/
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB4444);
	 break;
      case GL_RGBA4:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB4444);
	 break;

      /* deep RGBA formats */
      case GL_RGB10_A2:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB2101010);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;
      case GL_RGBA12:
      case GL_RGBA16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;

      /* shallow RGB formats */
      case 3:
      case GL_RGB:
         if (type == GL_UNSIGNED_INT_2_10_10_10_REV) {
            RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB2101010);
         }
         /* fallthrough */
      case GL_RGB8:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_XRGB8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;
      case GL_R3_G3_B2:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB332);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565_REV);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_XRGB8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;
      case GL_RGB4:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565_REV); /* just to test another format */
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565);
	 break;
      case GL_RGB5:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565);
	 break;

      /* deep RGB formats */
      case GL_RGB10:
      case GL_RGB12:
      case GL_RGB16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_XRGB8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;

      /* Alpha formats */
      case GL_ALPHA:
      case GL_ALPHA4:
      case GL_ALPHA8:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_A8);
	 break;

      case GL_ALPHA12:
      case GL_ALPHA16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_A16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_A8);
	 break;

      /* Luminance formats */
      case 1:
      case GL_LUMINANCE:
      case GL_LUMINANCE4:
      case GL_LUMINANCE8:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_L8);
	 break;

      case GL_LUMINANCE12:
      case GL_LUMINANCE16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_L16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_L8);
	 break;

      /* Luminance/Alpha formats */
      case GL_LUMINANCE4_ALPHA4:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL44);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL88);
	 break;

      case 2:
      case GL_LUMINANCE_ALPHA:
      case GL_LUMINANCE6_ALPHA2:
      case GL_LUMINANCE8_ALPHA8:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL88);
	 break;

      case GL_LUMINANCE12_ALPHA4:
      case GL_LUMINANCE12_ALPHA12:
      case GL_LUMINANCE16_ALPHA16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL1616);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL88);
	 break;

      case GL_INTENSITY:
      case GL_INTENSITY4:
      case GL_INTENSITY8:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_I8);
	 break;

      case GL_INTENSITY12:
      case GL_INTENSITY16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_I16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_I8);
	 break;

      default:
         ; /* fallthrough */
   }

   if (ctx->Extensions.ARB_depth_texture) {
      switch (internalFormat) {
         case GL_DEPTH_COMPONENT:
         case GL_DEPTH_COMPONENT24:
         case GL_DEPTH_COMPONENT32:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_Z32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_X8_Z24);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_S8_Z24);
	    break;
         case GL_DEPTH_COMPONENT16:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_Z16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_X8_Z24);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_S8_Z24);
         default:
            ; /* fallthrough */
      }
   }

   switch (internalFormat) {
      case GL_COMPRESSED_ALPHA_ARB:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_A8);
	 break;
      case GL_COMPRESSED_LUMINANCE_ARB:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_L8);
	 break;
      case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL88);
	 break;
      case GL_COMPRESSED_INTENSITY_ARB:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_I8);
	 break;
      case GL_COMPRESSED_RGB_ARB:
         /* We don't use texture compression for 1D and 1D array textures.
          * For 1D textures, compressions doesn't buy us much.
          * For 1D ARRAY textures, there's complicated issues with updating
          * sub-regions on non-block boundaries with glCopyTexSubImage, among
          * other issues.  FWIW, the GL_EXT_texture_array extension prohibits
          * 1D ARRAY textures in S3TC format.
          */
         if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) {
            if (ctx->Extensions.EXT_texture_compression_s3tc ||
                ctx->Extensions.ANGLE_texture_compression_dxt)
               RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
            if (ctx->Extensions.TDFX_texture_compression_FXT1)
               RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FXT1);
         }
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_XRGB8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;
      case GL_COMPRESSED_RGBA_ARB:
         /* We don't use texture compression for 1D and 1D array textures. */
         if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) {
            if (ctx->Extensions.EXT_texture_compression_s3tc ||
                ctx->Extensions.ANGLE_texture_compression_dxt)
               RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */
            if (ctx->Extensions.TDFX_texture_compression_FXT1)
               RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FXT1);
         }
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA8888);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;
      default:
         ; /* fallthrough */
   }

   if (ctx->Extensions.ARB_ES2_compatibility) {
      switch (internalFormat) {
         case GL_RGB565:
            RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565);
            break;
         default:
         ; /* fallthrough */
      }
   }

   if (ctx->Extensions.MESA_ycbcr_texture) {
      if (internalFormat == GL_YCBCR_MESA) {
         if (type == GL_UNSIGNED_SHORT_8_8_MESA)
	    RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR);
         else
	    RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR_REV);
      }
   }

   /* For non-generic compressed format we assert two things:
    *
    * 1. The format has already been validated against the set of available
    *    extensions.
    *
    * 2. The driver only enables the extension if it supports all of the
    *    formats that are part of that extension.
    */
   switch (internalFormat) {
   case GL_COMPRESSED_RGB_FXT1_3DFX:
      return MESA_FORMAT_RGB_FXT1;
   case GL_COMPRESSED_RGBA_FXT1_3DFX:
      return MESA_FORMAT_RGBA_FXT1;
   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   case GL_RGB_S3TC:
   case GL_RGB4_S3TC:
      return MESA_FORMAT_RGB_DXT1;
   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      return MESA_FORMAT_RGBA_DXT1;
   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
   case GL_RGBA_S3TC:
   case GL_RGBA4_S3TC:
      return MESA_FORMAT_RGBA_DXT3;
   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      return MESA_FORMAT_RGBA_DXT5;
   case GL_COMPRESSED_RED_RGTC1:
      return MESA_FORMAT_RED_RGTC1;
   case GL_COMPRESSED_SIGNED_RED_RGTC1:
      return MESA_FORMAT_SIGNED_RED_RGTC1;
   case GL_COMPRESSED_RG_RGTC2:
      return MESA_FORMAT_RG_RGTC2;
   case GL_COMPRESSED_SIGNED_RG_RGTC2:
      return MESA_FORMAT_SIGNED_RG_RGTC2;
   case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
      return MESA_FORMAT_L_LATC1;
   case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
      return MESA_FORMAT_SIGNED_L_LATC1;
   case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
      return MESA_FORMAT_LA_LATC2;
   case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
      return MESA_FORMAT_SIGNED_LA_LATC2;
   case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
      return MESA_FORMAT_LA_LATC2;
   case GL_ETC1_RGB8_OES:
      return MESA_FORMAT_ETC1_RGB8;
   case GL_COMPRESSED_RGB8_ETC2:
      return MESA_FORMAT_ETC2_RGB8;
   case GL_COMPRESSED_SRGB8_ETC2:
      return MESA_FORMAT_ETC2_SRGB8;
   case GL_COMPRESSED_RGBA8_ETC2_EAC:
      return MESA_FORMAT_ETC2_RGBA8_EAC;
   case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
      return MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC;
   case GL_COMPRESSED_R11_EAC:
      return MESA_FORMAT_ETC2_R11_EAC;
   case GL_COMPRESSED_RG11_EAC:
      return MESA_FORMAT_ETC2_RG11_EAC;
   case GL_COMPRESSED_SIGNED_R11_EAC:
      return MESA_FORMAT_ETC2_SIGNED_R11_EAC;
   case GL_COMPRESSED_SIGNED_RG11_EAC:
      return MESA_FORMAT_ETC2_SIGNED_RG11_EAC;
   case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
      return MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
   case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
      return MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
   case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
      return MESA_FORMAT_SRGB_DXT1;
   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
      return MESA_FORMAT_SRGBA_DXT1;
   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
      return MESA_FORMAT_SRGBA_DXT3;
   case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
      return MESA_FORMAT_SRGBA_DXT5;
   default:
      ; /* fallthrough */
   }

   if (ctx->Extensions.ARB_texture_float) {
      switch (internalFormat) {
         case GL_ALPHA16F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    break;
         case GL_ALPHA32F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    break;
         case GL_LUMINANCE16F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    break;
         case GL_LUMINANCE32F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    break;
         case GL_LUMINANCE_ALPHA16F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    break;
         case GL_LUMINANCE_ALPHA32F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    break;
         case GL_INTENSITY16F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    break;
         case GL_INTENSITY32F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    break;
         case GL_RGB16F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    break;
         case GL_RGB32F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    break;
         case GL_RGBA16F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    break;
         case GL_RGBA32F_ARB:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	    break;
         default:
            ; /* fallthrough */
      }
   }

   if (ctx->Extensions.EXT_texture_shared_exponent) {
      switch (internalFormat) {
         case GL_RGB9_E5:
            ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_RGB9_E5_FLOAT]);
            return MESA_FORMAT_RGB9_E5_FLOAT;
         default:
            ; /* fallthrough */
      }
   }

   if (ctx->Extensions.EXT_packed_float) {
      switch (internalFormat) {
         case GL_R11F_G11F_B10F:
            ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_R11_G11_B10_FLOAT]);
            return MESA_FORMAT_R11_G11_B10_FLOAT;
         default:
            ; /* fallthrough */
      }
   }

   if (ctx->Extensions.EXT_packed_depth_stencil) {
      switch (internalFormat) {
         case GL_DEPTH_STENCIL_EXT:
         case GL_DEPTH24_STENCIL8_EXT:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_S8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_S8_Z24);
	    break;
         default:
            ; /* fallthrough */
      }
   }

   if (ctx->Extensions.ARB_depth_buffer_float) {
      switch (internalFormat) {
         case GL_DEPTH_COMPONENT32F:
            ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT]);
            return MESA_FORMAT_Z32_FLOAT;
         case GL_DEPTH32F_STENCIL8:
            ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT_X24S8]);
            return MESA_FORMAT_Z32_FLOAT_X24S8;
         default:
            ; /* fallthrough */
      }
   }

   if (ctx->Extensions.ATI_envmap_bumpmap) {
      switch (internalFormat) {
         case GL_DUDV_ATI:
         case GL_DU8DV8_ATI:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_DUDV8);
	    break;
         default:
            ; /* fallthrough */
      }
   }

   if (ctx->Extensions.EXT_texture_snorm) {
      switch (internalFormat) {
         case GL_RED_SNORM:
         case GL_R8_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_R8);
	    break;
         case GL_RG_SNORM:
         case GL_RG8_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RG88_REV);
	    break;
         case GL_RGB_SNORM:
         case GL_RGB8_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBX8888);
	    /* FALLTHROUGH */
         case GL_RGBA_SNORM:
         case GL_RGBA8_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
	    break;
         case GL_ALPHA_SNORM:
         case GL_ALPHA8_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_A8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
            break;
         case GL_LUMINANCE_SNORM:
         case GL_LUMINANCE8_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_L8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBX8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
            break;
         case GL_LUMINANCE_ALPHA_SNORM:
         case GL_LUMINANCE8_ALPHA8_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_AL88);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
            break;
         case GL_INTENSITY_SNORM:
         case GL_INTENSITY8_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_I8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
            break;
         case GL_R16_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_R16);
	    break;
         case GL_RG16_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_GR1616);
	    break;
         case GL_RGB16_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGB_16);
	    /* FALLTHROUGH */
         case GL_RGBA16_SNORM:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA_16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
	    break;
         case GL_ALPHA16_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_A16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA_16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
            break;
         case GL_LUMINANCE16_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_L16);
	    /* FALLTHROUGH */
         case GL_LUMINANCE16_ALPHA16_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_AL1616);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA_16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
            break;
         case GL_INTENSITY16_SNORM:
            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_I16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA_16);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888_REV);
            break;
         default:
            ; /* fall-through */
      }
   }

   if (ctx->Extensions.EXT_texture_sRGB) {
      switch (internalFormat) {
         case GL_SRGB_EXT:
         case GL_SRGB8_EXT:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         case GL_SRGB_ALPHA_EXT:
         case GL_SRGB8_ALPHA8_EXT:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         case GL_SLUMINANCE_EXT:
         case GL_SLUMINANCE8_EXT:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SL8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         case GL_SLUMINANCE_ALPHA_EXT:
         case GL_SLUMINANCE8_ALPHA8_EXT:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SLA8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         case GL_COMPRESSED_SLUMINANCE_EXT:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SL8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SLA8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         case GL_COMPRESSED_SRGB_EXT:
            if (ctx->Extensions.EXT_texture_compression_s3tc)
	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         case GL_COMPRESSED_SRGB_ALPHA_EXT:
            if (ctx->Extensions.EXT_texture_compression_s3tc)
	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA8);
	    RETURN_IF_SUPPORTED(MESA_FORMAT_SARGB8);
	    break;
         default:
            ; /* fallthrough */
      }
   }

   if (ctx->Extensions.EXT_texture_integer) {
      switch (internalFormat) {
      case GL_ALPHA8UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_UINT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
         break;
      case GL_ALPHA16UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_UINT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16);
         break;
      case GL_ALPHA32UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_UINT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32);
         break;
      case GL_ALPHA8I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_INT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT8);
         break;
      case GL_ALPHA16I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_INT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT16);
         break;
      case GL_ALPHA32I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_INT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
         break;
      case GL_LUMINANCE8UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_UINT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
         break;
      case GL_LUMINANCE16UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_UINT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16);
         break;
      case GL_LUMINANCE32UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_UINT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32);
         break;
      case GL_LUMINANCE8I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_INT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT8);
         break;
      case GL_LUMINANCE16I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_INT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT16);
         break;
      case GL_LUMINANCE32I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_INT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
         break;
      case GL_LUMINANCE_ALPHA8UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
         break;
      case GL_LUMINANCE_ALPHA16UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16);
         break;
      case GL_LUMINANCE_ALPHA32UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32);
         break;
      case GL_LUMINANCE_ALPHA8I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_INT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT8);
         break;
      case GL_LUMINANCE_ALPHA16I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_INT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT16);
         break;
      case GL_LUMINANCE_ALPHA32I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_INT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
         break;
      case GL_INTENSITY8UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_UINT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
         break;
      case GL_INTENSITY16UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_UINT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16);
         break;
      case GL_INTENSITY32UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_UINT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32);
         break;
      case GL_INTENSITY8I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_INT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT8);
         break;
      case GL_INTENSITY16I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_INT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT16);
         break;
      case GL_INTENSITY32I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_INT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
         break;
      }
   }

   if (ctx->Version >= 30 ||
       ctx->Extensions.EXT_texture_integer) {
      switch (internalFormat) {
      case GL_RGB8UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
         break;
      case GL_RGB16UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16);
         break;
      case GL_RGB32UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32);
         break;
      case GL_RGB8I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_INT8);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT8);
         break;
      case GL_RGB16I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_INT16);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT16);
         break;
      case GL_RGB32I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_INT32);
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
         break;
      case GL_RGBA8UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
         break;
      case GL_RGBA16UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16);
         break;
      case GL_RGBA32UI_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32);
         break;
      case GL_RGBA8I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT8);
         break;
      case GL_RGBA16I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT16);
         break;
      case GL_RGBA32I_EXT:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
         break;
      }
   }

   if (ctx->Extensions.ARB_texture_rg) {
      switch (internalFormat) {
      case GL_R8:
      case GL_RED:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_R8);
	 break;

      case GL_COMPRESSED_RED:
         if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY)
            RETURN_IF_SUPPORTED(MESA_FORMAT_RED_RGTC1);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_R8);
	 break;

      case GL_R16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_R16);
	 break;

      case GL_RG:
      case GL_RG8:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_GR88);
	 break;

      case GL_COMPRESSED_RG:
         if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY)
            RETURN_IF_SUPPORTED(MESA_FORMAT_RG_RGTC2);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_GR88);
	 break;

      case GL_RG16:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_GR1616);
	 break;

      default:
         ; /* fallthrough */
      }
   }

   if (ctx->Extensions.ARB_texture_rg && ctx->Extensions.ARB_texture_float) {
      switch (internalFormat) {
      case GL_R16F:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	 break;
      case GL_R32F:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	 break;
      case GL_RG16F:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	 break;
      case GL_RG32F:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16);
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
	 break;

      default:
         ; /* fallthrough */
      }
   }

   if (ctx->Version >= 30 ||
       (ctx->Extensions.ARB_texture_rg &&
        ctx->Extensions.EXT_texture_integer)) {
      switch (internalFormat) {
      case GL_R8UI:
         RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT8);
         break;
      case GL_RG8UI:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT8);
         break;
      case GL_R16UI:
         RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT16);
	 break;
      case GL_RG16UI:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT16);
         break;
      case GL_R32UI:
         RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT32);
         break;
      case GL_RG32UI:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT32);
         break;
      case GL_R8I:
         RETURN_IF_SUPPORTED(MESA_FORMAT_R_INT8);
         break;
      case GL_RG8I:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RG_INT8);
         break;
      case GL_R16I:
         RETURN_IF_SUPPORTED(MESA_FORMAT_R_INT16);
         break;
      case GL_RG16I:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RG_INT16);
         break;
      case GL_R32I:
         RETURN_IF_SUPPORTED(MESA_FORMAT_R_INT32);
         break;
      case GL_RG32I:
         RETURN_IF_SUPPORTED(MESA_FORMAT_RG_INT32);
         break;
      default:
         break;
      }
   }

   if (ctx->Extensions.ARB_texture_rgb10_a2ui) {
      switch (internalFormat) {
      case GL_RGB10_A2UI:
         RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB2101010_UINT);
         RETURN_IF_SUPPORTED(MESA_FORMAT_ABGR2101010_UINT);
         break;
      default:
         break;
      }
   }
   /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0).
    */
   if (_mesa_is_gles(ctx)) {
      switch (internalFormat) {
      case GL_BGRA:
	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
	 break;

      default:
         ; /* fallthrough */
      }
   }

   _mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()",
                 _mesa_lookup_enum_by_nr(internalFormat));
   return MESA_FORMAT_NONE;
}
Example #17
0
static bool
compressed_format_compatible(const struct gl_context *ctx,
                             GLenum compressedFormat, GLenum otherFormat)
{
   enum mesa_block_class compressedClass, otherClass;

   /* Two view-incompatible compressed formats are never compatible. */
   if (_mesa_is_compressed_format(ctx, otherFormat)) {
      return false;
   }

   /*
    * From ARB_copy_image spec:
    *    Table 4.X.1 (Compatible internal formats for copying between
    *                 compressed and uncompressed internal formats)
    *    ---------------------------------------------------------------------
    *    | Texel / | Uncompressed      |                                     |
    *    | Block   | internal format   | Compressed internal format          |
    *    | size    |                   |                                     |
    *    ---------------------------------------------------------------------
    *    | 128-bit | RGBA32UI,         | COMPRESSED_RGBA_S3TC_DXT3_EXT,      |
    *    |         | RGBA32I,          | COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,|
    *    |         | RGBA32F           | COMPRESSED_RGBA_S3TC_DXT5_EXT,      |
    *    |         |                   | COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,|
    *    |         |                   | COMPRESSED_RG_RGTC2,                |
    *    |         |                   | COMPRESSED_SIGNED_RG_RGTC2,         |
    *    |         |                   | COMPRESSED_RGBA_BPTC_UNORM,         |
    *    |         |                   | COMPRESSED_SRGB_ALPHA_BPTC_UNORM,   |
    *    |         |                   | COMPRESSED_RGB_BPTC_SIGNED_FLOAT,   |
    *    |         |                   | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT  |
    *    ---------------------------------------------------------------------
    *    | 64-bit  | RGBA16F, RG32F,   | COMPRESSED_RGB_S3TC_DXT1_EXT,       |
    *    |         | RGBA16UI, RG32UI, | COMPRESSED_SRGB_S3TC_DXT1_EXT,      |
    *    |         | RGBA16I, RG32I,   | COMPRESSED_RGBA_S3TC_DXT1_EXT,      |
    *    |         | RGBA16,           | COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,|
    *    |         | RGBA16_SNORM      | COMPRESSED_RED_RGTC1,               |
    *    |         |                   | COMPRESSED_SIGNED_RED_RGTC1         |
    *    ---------------------------------------------------------------------
    */

   switch (compressedFormat) {
      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
      case GL_COMPRESSED_RG_RGTC2:
      case GL_COMPRESSED_SIGNED_RG_RGTC2:
      case GL_COMPRESSED_RGBA_BPTC_UNORM:
      case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
      case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
      case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
         compressedClass = BLOCK_CLASS_128_BITS;
         break;
      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
      case GL_COMPRESSED_RED_RGTC1:
      case GL_COMPRESSED_SIGNED_RED_RGTC1:
         compressedClass = BLOCK_CLASS_64_BITS;
         break;
      case GL_COMPRESSED_RGBA8_ETC2_EAC:
      case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
      case GL_COMPRESSED_RG11_EAC:
      case GL_COMPRESSED_SIGNED_RG11_EAC:
         if (_mesa_is_gles(ctx))
            compressedClass = BLOCK_CLASS_128_BITS;
         else
            return false;
         break;
      case GL_COMPRESSED_RGB8_ETC2:
      case GL_COMPRESSED_SRGB8_ETC2:
      case GL_COMPRESSED_R11_EAC:
      case GL_COMPRESSED_SIGNED_R11_EAC:
      case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
      case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
         if (_mesa_is_gles(ctx))
            compressedClass = BLOCK_CLASS_64_BITS;
         else
            return false;
         break;
      default:
         if (_mesa_is_gles(ctx) && _mesa_is_astc_format(compressedFormat))
            compressedClass = BLOCK_CLASS_128_BITS;
         else
            return false;
         break;
   }

   switch (otherFormat) {
      case GL_RGBA32UI:
      case GL_RGBA32I:
      case GL_RGBA32F:
         otherClass = BLOCK_CLASS_128_BITS;
         break;
      case GL_RGBA16F:
      case GL_RG32F:
      case GL_RGBA16UI:
      case GL_RG32UI:
      case GL_RGBA16I:
      case GL_RG32I:
      case GL_RGBA16:
      case GL_RGBA16_SNORM:
         otherClass = BLOCK_CLASS_64_BITS;
         break;
      default:
         return false;
   }

   return compressedClass == otherClass;
}