}
}
+#if FEATURE_EXT_texture_sRGB
+ if (ctx->Extensions.EXT_texture_sRGB) {
+ switch (internalFormat) {
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_COMPRESSED_SRGB_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ return GL_RGB;
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_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 GL_RGBA;
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+ return GL_LUMINANCE_ALPHA;
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ return GL_LUMINANCE;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
+#endif /* FEATURE_EXT_texture_sRGB */
+
return -1; /* error */
}
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
+#if FEATURE_EXT_texture_sRGB
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ case GL_COMPRESSED_SRGB_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_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:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+#endif /* FEATURE_EXT_texture_sRGB */
return GL_TRUE;
case GL_YCBCR_MESA: /* not considered to be RGB */
default:
return GL_TRUE;
}
+#if FEATURE_EXT_texture_sRGB
+ if (destTex->InternalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT ||
+ destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ||
+ destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ||
+ destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) {
+ if ((width & 0x3) || (height & 0x3) ||
+ (xoffset & 0x3) || (yoffset & 0x3))
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexSubImage%dD(size or offset not multiple of 4)",
+ dimensions);
+ return GL_TRUE;
+ }
+#endif
+
if (destTex->IsCompressed) {
const struct gl_texture_unit *texUnit;
const struct gl_texture_image *texImage;
if (expectedSize != imageSize)
return GL_INVALID_VALUE;
+#if FEATURE_EXT_texture_sRGB
+ if ((internalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT ||
+ internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ||
+ internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ||
+ internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT)
+ && border != 0) {
+ return GL_INVALID_OPERATION;
+ }
+#endif
+
return GL_NO_ERROR;
}
}
+#if FEATURE_EXT_texture_sRGB
+
+/**
+ * Test if given texture image is an sRGB format.
+ */
+static GLboolean
+is_srgb_teximage(const struct gl_texture_image *texImage)
+{
+ switch (texImage->TexFormat->MesaFormat) {
+ case MESA_FORMAT_SRGB8:
+ case MESA_FORMAT_SRGBA8:
+ case MESA_FORMAT_SL8:
+ case MESA_FORMAT_SLA8:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+#endif /* FEATURE_EXT_texture_sRGB */
+
/**
* This is the software fallback for Driver.GetTexImage().
_mesa_swap2((GLushort *) dest, width);
}
}
+#if FEATURE_EXT_texture_sRGB
+ else if (is_srgb_teximage(texImage)) {
+ /* no pixel transfer and no non-linear to linear conversion */
+ const GLint comps = texImage->TexFormat->TexelBytes;
+ const GLint rowstride = comps * texImage->RowStride;
+ MEMCPY(dest,
+ (const GLubyte *) texImage->Data + row * rowstride,
+ comps * width * sizeof(GLubyte));
+ }
+#endif /* FEATURE_EXT_texture_sRGB */
else {
/* general case: convert row to RGBA format */
GLfloat rgba[MAX_WIDTH][4];