img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
img->WidthLog2 = _mesa_logbase2(img->Width2);
- img->NumSamples = 0;
- img->FixedSampleLocations = GL_TRUE;
-
switch(target) {
case GL_TEXTURE_1D:
case GL_TEXTURE_BUFFER:
}
if (xoffset + subWidth > (GLint) destImage->Width) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset+width)", func);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset %d + width %d > %u)", func,
+ xoffset, subWidth, destImage->Width);
return GL_TRUE;
}
return GL_TRUE;
}
if (yoffset + subHeight > (GLint) destImage->Height) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset+height)", func);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset %d + height %d > %u)",
+ func, yoffset, subHeight, destImage->Height);
return GL_TRUE;
}
}
if (target == GL_TEXTURE_CUBE_MAP)
depth = 6;
if (zoffset + subDepth > depth) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset+depth)", func);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset %d + depth %d > %u)",
+ func, zoffset, subDepth, depth);
return GL_TRUE;
}
}
GLenum type, GLenum internalFormat,
GLuint dimensions, const char *callerName)
{
- GLenum err;
-
- if (_mesa_is_gles3(ctx)) {
- err = _mesa_es3_error_check_format_and_type(ctx, format, type,
- internalFormat);
- if (err != GL_NO_ERROR) {
- _mesa_error(ctx, err,
- "%s(format = %s, type = %s, internalformat = %s)",
- callerName, _mesa_enum_to_string(format),
- _mesa_enum_to_string(type),
- _mesa_enum_to_string(internalFormat));
- return true;
- }
- }
- else {
- err = _mesa_es_error_check_format_and_type(ctx, format, type, dimensions);
- if (err != GL_NO_ERROR) {
- _mesa_error(ctx, err, "%s(format = %s, type = %s)",
- callerName, _mesa_enum_to_string(format),
- _mesa_enum_to_string(type));
- return true;
- }
+ GLenum err = _mesa_es3_error_check_format_and_type(ctx, format, type,
+ internalFormat);
+ if (err != GL_NO_ERROR) {
+ _mesa_error(ctx, err,
+ "%s(format = %s, type = %s, internalformat = %s)",
+ callerName, _mesa_enum_to_string(format),
+ _mesa_enum_to_string(type),
+ _mesa_enum_to_string(internalFormat));
+ return true;
}
return false;
texImage = _mesa_select_tex_image(texObj, target, level);
if (!texImage) {
/* non-existant texture level */
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture image)",
- callerName);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)",
+ callerName, level);
return GL_TRUE;
}
_mesa_is_enum_format_unsigned_int(internalFormat) !=
_mesa_is_enum_format_unsigned_int(rb_internal_format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexImage%dD(signed vs unsigned integer)", dimensions);
+ "glCopyTexImage%dD(signed vs unsigned integer)",
+ dimensions);
return GL_TRUE;
}
}
if (!texImage) {
/* destination image does not exist */
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(invalid texture image)", caller);
+ "%s(invalid texture level %d)", caller, level);
return GL_TRUE;
}
/* see if we've already chosen a format for the previous level */
if (level > 0) {
struct gl_texture_image *prevImage =
- _mesa_select_tex_image(texObj, target, level - 1);
+ _mesa_select_tex_image(texObj, target, level - 1);
/* See if the prev level is defined and has an internal format which
* matches the new internal format.
*/
}
}
- /* If the application requested compression to an S3TC format but we don't
- * have the DXTn library, force a generic compressed format instead.
- */
- if (internalFormat != format && format != GL_NONE) {
- const GLenum before = internalFormat;
-
- switch (internalFormat) {
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- if (!ctx->Mesa_DXTn)
- internalFormat = GL_COMPRESSED_RGB;
- break;
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- if (!ctx->Mesa_DXTn)
- internalFormat = GL_COMPRESSED_RGBA;
- break;
- default:
- break;
- }
-
- if (before != internalFormat) {
- _mesa_warning(ctx,
- "DXT compression requested (%s), "
- "but libtxc_dxtn library not installed. Using %s "
- "instead.",
- _mesa_enum_to_string(before),
- _mesa_enum_to_string(internalFormat));
- }
- }
-
- /* choose format from scratch */
f = ctx->Driver.ChooseTextureFormat(ctx, target, internalFormat,
format, type);
assert(f != MESA_FORMAT_NONE);
if (!dimensionsOK) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s%uD(invalid width or height or depth)",
- func, dims);
+ "%s%uD(invalid width=%d or height=%d or depth=%d)",
+ func, dims, width, height, depth);
return;
}
* rarely-tested software fallback rendering.
*/
if (border && ctx->Const.StripTextureBorder) {
- strip_texture_border(target, &width, &height, &depth, unpack,
- &unpack_no_border);
+ strip_texture_border(target, &width, &height, &depth, unpack,
+ &unpack_no_border);
border = 0;
- unpack = &unpack_no_border;
+ unpack = &unpack_no_border;
}
if (ctx->NewState & _NEW_PIXEL)
- _mesa_update_state(ctx);
+ _mesa_update_state(ctx);
_mesa_lock_texture(ctx, texObj);
{
- texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ texImage = _mesa_get_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
- }
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
+ }
else {
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
}
}
+
/* This is a wrapper around teximage() so that we can force the KHR_no_error
* logic to be inlined without inlining the function into all the callers.
*/
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
ctx->Driver.EGLImageTargetTexture2D(ctx, target,
- texObj, texImage, image);
+ texObj, texImage, image);
_mesa_dirty_texobj(ctx, texObj);
}
* Implement all the glTextureSubImage1/2/3D() functions.
* Must split this out this way because of GL_TEXTURE_CUBE_MAP.
*/
-static void
+static ALWAYS_INLINE void
texturesubimage(struct gl_context *ctx, GLuint dims,
GLuint texture, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid *pixels,
- const char *callerName)
+ const char *callerName, bool no_error)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
_mesa_enum_to_string(type), pixels);
/* Get the texture object by Name. */
- texObj = _mesa_lookup_texture_err(ctx, texture, callerName);
- if (!texObj)
- return;
-
- /* check target (proxies not allowed) */
- if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%s)",
- callerName, _mesa_enum_to_string(texObj->Target));
- return;
+ if (!no_error) {
+ texObj = _mesa_lookup_texture_err(ctx, texture, callerName);
+ if (!texObj)
+ return;
+ } else {
+ texObj = _mesa_lookup_texture(ctx, texture);
}
- if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level,
- xoffset, yoffset, zoffset,
- width, height, depth, format, type,
- pixels, true, callerName)) {
- return; /* error was detected */
- }
+ if (!no_error) {
+ /* check target (proxies not allowed) */
+ if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%s)",
+ callerName, _mesa_enum_to_string(texObj->Target));
+ return;
+ }
+ if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth, format, type,
+ pixels, true, callerName)) {
+ return; /* error was detected */
+ }
+ }
/* Must handle special case GL_TEXTURE_CUBE_MAP. */
if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
* It seems reasonable to check for cube completeness of an arbitrary
* level here so that the image data has a consistent format and size.
*/
- if (!_mesa_cube_level_complete(texObj, level)) {
+ if (!no_error && !_mesa_cube_level_complete(texObj, level)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTextureSubImage%uD(cube map incomplete)",
dims);
}
+static void
+texturesubimage_error(struct gl_context *ctx, GLuint dims,
+ GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const char *callerName)
+{
+ texturesubimage(ctx, dims, texture, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels, callerName,
+ false);
+}
+
+
+static void
+texturesubimage_no_error(struct gl_context *ctx, GLuint dims,
+ GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const char *callerName)
+{
+ texturesubimage(ctx, dims, texture, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels, callerName,
+ true);
+}
+
+
void GLAPIENTRY
_mesa_TexSubImage1D_no_error(GLenum target, GLint level,
GLint xoffset, GLsizei width,
format, type, pixels, "glTexSubImage3D");
}
+
+void GLAPIENTRY
+_mesa_TextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ texturesubimage_no_error(ctx, 1, texture, level, xoffset, 0, 0, width, 1, 1,
+ format, type, pixels, "glTextureSubImage1D");
+}
+
+
void GLAPIENTRY
_mesa_TextureSubImage1D(GLuint texture, GLint level,
GLint xoffset, GLsizei width,
const GLvoid *pixels)
{
GET_CURRENT_CONTEXT(ctx);
- texturesubimage(ctx, 1, texture, level,
- xoffset, 0, 0,
- width, 1, 1,
- format, type, pixels, "glTextureSubImage1D");
+ texturesubimage_error(ctx, 1, texture, level, xoffset, 0, 0, width, 1, 1,
+ format, type, pixels, "glTextureSubImage1D");
+}
+
+
+void GLAPIENTRY
+_mesa_TextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ texturesubimage_no_error(ctx, 2, texture, level, xoffset, yoffset, 0, width,
+ height, 1, format, type, pixels,
+ "glTextureSubImage2D");
}
const GLvoid *pixels)
{
GET_CURRENT_CONTEXT(ctx);
- texturesubimage(ctx, 2, texture, level,
- xoffset, yoffset, 0,
- width, height, 1,
- format, type, pixels, "glTextureSubImage2D");
+ texturesubimage_error(ctx, 2, texture, level, xoffset, yoffset, 0, width,
+ height, 1, format, type, pixels,
+ "glTextureSubImage2D");
+}
+
+
+void GLAPIENTRY
+_mesa_TextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum format,
+ GLenum type, const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ texturesubimage_no_error(ctx, 3, texture, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels,
+ "glTextureSubImage3D");
}
const GLvoid *pixels)
{
GET_CURRENT_CONTEXT(ctx);
- texturesubimage(ctx, 3, texture, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels, "glTextureSubImage3D");
+ texturesubimage_error(ctx, 3, texture, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels,
+ "glTextureSubImage3D");
}
}
}
+
static void
copytexsubimage_by_slice(struct gl_context *ctx,
struct gl_texture_image *texImage,
}
}
+
static GLboolean
formats_differ_in_component_sizes(mesa_format f1, mesa_format f2)
{
/**
* Implement the glCopyTexImage1/2D() functions.
*/
-static void
+static ALWAYS_INLINE void
copyteximage(struct gl_context *ctx, GLuint dims,
GLenum target, GLint level, GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
+ GLint x, GLint y, GLsizei width, GLsizei height, GLint border,
+ bool no_error)
{
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- const GLuint face = _mesa_tex_target_to_face(target);
+ struct gl_texture_object *texObj;
mesa_format texFormat;
- struct gl_renderbuffer *rb;
FLUSH_VERTICES(ctx, 0);
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
- if (copytexture_error_check(ctx, dims, target, level, internalFormat,
- width, height, border))
- return;
+ if (!no_error) {
+ if (copytexture_error_check(ctx, dims, target, level, internalFormat,
+ width, height, border))
+ return;
- if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height,
- 1, border)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage%uD(invalid width or height)", dims);
- return;
+ if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height,
+ 1, border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%uD(invalid width=%d or height=%d)",
+ dims, width, height);
+ return;
+ }
}
texObj = _mesa_get_current_tex_object(ctx, target);
if (texImage && can_avoid_reallocation(texImage, internalFormat, texFormat,
x, y, width, height, border)) {
_mesa_unlock_texture(ctx, texObj);
- copy_texture_sub_image_err(ctx, dims, texObj, target, level, 0, 0, 0,
- x, y, width, height,"CopyTexImage");
+ if (no_error) {
+ copy_texture_sub_image_no_error(ctx, dims, texObj, target, level, 0,
+ 0, 0, x, y, width, height);
+ } else {
+ copy_texture_sub_image_err(ctx, dims, texObj, target, level, 0, 0,
+ 0, x, y, width, height,"CopyTexImage");
+ }
return;
}
}
_mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_LOW, "glCopyTexImage "
"can't avoid reallocating texture storage\n");
- rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
+ if (!no_error && _mesa_is_gles3(ctx)) {
+ struct gl_renderbuffer *rb =
+ _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
- if (_mesa_is_gles3(ctx)) {
if (_mesa_is_enum_format_unsized(internalFormat)) {
/* Conversion from GL_RGB10_A2 source buffer format is not allowed in
* OpenGL ES 3.0. Khronos bug# 9807.
x += border;
width -= border * 2;
if (dims == 2) {
- y += border;
- height -= border * 2;
+ y += border;
+ height -= border * 2;
}
border = 0;
}
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
}
else {
GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
+ const GLuint face = _mesa_tex_target_to_face(target);
/* Free old texture image */
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
}
+static void
+copyteximage_err(struct gl_context *ctx, GLuint dims, GLenum target,
+ GLint level, GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border)
+{
+ copyteximage(ctx, dims, target, level, internalFormat, x, y, width, height,
+ border, false);
+}
+
+
+static void
+copyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target,
+ GLint level, GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border)
+{
+ copyteximage(ctx, dims, target, level, internalFormat, x, y, width, height,
+ border, true);
+}
+
void GLAPIENTRY
_mesa_CopyTexImage1D( GLenum target, GLint level,
GLsizei width, GLint border )
{
GET_CURRENT_CONTEXT(ctx);
- copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
+ copyteximage_err(ctx, 1, target, level, internalFormat, x, y, width, 1,
+ border);
}
-
void GLAPIENTRY
_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border )
{
GET_CURRENT_CONTEXT(ctx);
- copyteximage(ctx, 2, target, level, internalFormat,
- x, y, width, height, border);
+ copyteximage_err(ctx, 2, target, level, internalFormat,
+ x, y, width, height, border);
+}
+
+
+void GLAPIENTRY
+_mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLint border)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ copyteximage_no_error(ctx, 1, target, level, internalFormat, x, y, width, 1,
+ border);
}
+void GLAPIENTRY
+_mesa_CopyTexImage2D_no_error(GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ copyteximage_no_error(ctx, 2, target, level, internalFormat,
+ x, y, width, height, border);
+}
+
void GLAPIENTRY
-_mesa_CopyTexSubImage1D( GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width )
+_mesa_CopyTexSubImage1D(GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width)
{
struct gl_texture_object* texObj;
const char *self = "glCopyTexSubImage1D";
x, y, width, 1, self);
}
+
void GLAPIENTRY
-_mesa_CopyTexSubImage2D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
+_mesa_CopyTexSubImage2D(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
{
struct gl_texture_object* texObj;
const char *self = "glCopyTexSubImage2D";
}
-
void GLAPIENTRY
-_mesa_CopyTexSubImage3D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
+_mesa_CopyTexSubImage3D(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
{
struct gl_texture_object* texObj;
const char *self = "glCopyTexSubImage3D";
zoffset, x, y, width, height, self);
}
+
void GLAPIENTRY
_mesa_CopyTextureSubImage1D(GLuint texture, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width)
0, x, y, width, 1, self);
}
+
void GLAPIENTRY
_mesa_CopyTextureSubImage2D(GLuint texture, GLint level,
GLint xoffset, GLint yoffset,
}
-
void GLAPIENTRY
_mesa_CopyTextureSubImage3D(GLuint texture, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
x, y, width, 1);
}
+
void GLAPIENTRY
_mesa_CopyTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLint x, GLint y, GLsizei width,
yoffset, 0, x, y, width, height);
}
+
void GLAPIENTRY
_mesa_CopyTexSubImage3D_no_error(GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLint zoffset, GLint x, GLint y,
yoffset, zoffset, x, y, width, height);
}
+
void GLAPIENTRY
_mesa_CopyTextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset,
GLint x, GLint y, GLsizei width)
xoffset, 0, 0, x, y, width, 1);
}
+
void GLAPIENTRY
_mesa_CopyTextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset,
GLint yoffset, GLint x, GLint y,
xoffset, yoffset, 0, x, y, width, height);
}
+
void GLAPIENTRY
_mesa_CopyTextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset,
GLint yoffset, GLint zoffset, GLint x,
return true;
}
+
static struct gl_texture_object *
get_tex_obj_for_clear(struct gl_context *ctx,
const char *function,
return texObj;
}
+
+/**
+ * For clearing cube textures, the zoffset and depth parameters indicate
+ * which cube map faces are to be cleared. This is the one case where we
+ * need to be concerned with multiple gl_texture_images. This function
+ * returns the array of texture images to clear for cube maps, or one
+ * texture image otherwise.
+ * \return number of texture images, 0 for error, 6 for cube, 1 otherwise.
+ */
static int
get_tex_images_for_clear(struct gl_context *ctx,
const char *function,
struct gl_texture_image **texImages)
{
GLenum target;
- int i;
+ int numFaces, i;
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
}
if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
- for (i = 0; i < MAX_FACES; i++) {
- target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
-
- texImages[i] = _mesa_select_tex_image(texObj, target, level);
- if (texImages[i] == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(invalid level)", function);
- return 0;
- }
- }
-
- return MAX_FACES;
+ target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ numFaces = MAX_FACES;
+ }
+ else {
+ target = texObj->Target;
+ numFaces = 1;
}
- texImages[0] = _mesa_select_tex_image(texObj, texObj->Target, level);
-
- if (texImages[0] == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
- return 0;
+ for (i = 0; i < numFaces; i++) {
+ texImages[i] = _mesa_select_tex_image(texObj, target + i, level);
+ if (texImages[i] == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
+ return 0;
+ }
}
- return 1;
+ return numFaces;
}
+
void GLAPIENTRY
-_mesa_ClearTexSubImage( GLuint texture, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const void *data )
+_mesa_ClearTexSubImage(GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const void *data)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_texture_object *texObj;
minDepth = -(int) texImages[0]->Border;
maxDepth = texImages[0]->Depth;
} else {
+ assert(numImages == MAX_FACES);
minDepth = 0;
maxDepth = numImages;
}
}
if (numImages == 1) {
- if (check_clear_tex_image(ctx, "glClearTexSubImage",
- texImages[0],
+ if (check_clear_tex_image(ctx, "glClearTexSubImage", texImages[0],
format, type, data, clearValue[0])) {
ctx->Driver.ClearTexSubImage(ctx,
texImages[0],
data ? clearValue[0] : NULL);
}
} else {
+ /* loop over cube face images */
for (i = zoffset; i < zoffset + depth; i++) {
- if (!check_clear_tex_image(ctx, "glClearTexSubImage",
- texImages[i],
+ assert(i < MAX_FACES);
+ if (!check_clear_tex_image(ctx, "glClearTexSubImage", texImages[i],
format, type, data, clearValue[i]))
goto out;
}
_mesa_unlock_texture(ctx, texObj);
}
+
void GLAPIENTRY
_mesa_ClearTexImage( GLuint texture, GLint level,
GLenum format, GLenum type, const void *data )
texObj, level, texImages);
for (i = 0; i < numImages; i++) {
- if (!check_clear_tex_image(ctx, "glClearTexImage",
- texImages[i],
- format, type, data,
- clearValue[i]))
+ if (!check_clear_tex_image(ctx, "glClearTexImage", texImages[i], format,
+ type, data, clearValue[i]))
goto out;
}
/* this will catch any invalid compressed format token */
if (!_mesa_is_compressed_format(ctx, format)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "%s(format)", callerName);
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(format)", callerName);
return GL_TRUE;
}
if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "%s(level=%d)",
- callerName, level);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level);
return GL_TRUE;
}
expectedSize = compressed_tex_size(width, height, depth, format);
if (expectedSize != imageSize) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "%s(size=%d)",
- callerName, imageSize);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", callerName, imageSize);
return GL_TRUE;
}
texImage = _mesa_select_tex_image(texObj, target, level);
if (!texImage) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(invalid texture image)",
- callerName);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)",
+ callerName, level);
return GL_TRUE;
}
if ((GLint) format != texImage->InternalFormat) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(format=%s)",
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s)",
callerName, _mesa_enum_to_string(format));
return GL_TRUE;
}
if (compressedteximage_only_format(ctx, format)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(format=%s cannot be updated)",
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s cannot be updated)",
callerName, _mesa_enum_to_string(format));
return GL_TRUE;
}
- if (error_check_subtexture_negative_dimensions(ctx, dims,
- width, height, depth,
- callerName)) {
+ if (error_check_subtexture_negative_dimensions(ctx, dims, width, height,
+ depth, callerName)) {
return GL_TRUE;
}
- if (error_check_subtexture_dimensions(ctx, dims,
- texImage, xoffset, yoffset, zoffset,
- width, height, depth,
+ if (error_check_subtexture_dimensions(ctx, dims, texImage, xoffset, yoffset,
+ zoffset, width, height, depth,
callerName)) {
return GL_TRUE;
}
const GLvoid *data, bool dsa, bool no_error,
const char *caller)
{
- struct gl_texture_object *texObj;
+ struct gl_texture_object *texObj = NULL;
struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
}
/* Copy in each face. */
- for (int i = 0; i < 6; ++i) {
+ for (int i = zoffset; i < zoffset + depth; ++i) {
texImage = texObj->Image[i][level];
assert(texImage);
compressed_texture_sub_image(ctx, 3, texObj, texImage,
texObj->Target, level, xoffset, yoffset,
- zoffset, width, height, 1, format,
+ 0, width, height, 1, format,
imageSize, pixels);
/* Compressed images don't have a client format */
}
}
+static void
+compressed_tex_sub_image_error(unsigned dim, GLenum target, GLuint texture,
+ GLint level, GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width, GLsizei height,
+ GLsizei depth, GLenum format, GLsizei imageSize,
+ const GLvoid *data, bool dsa,
+ const char *caller)
+{
+ compressed_tex_sub_image(dim, target, texture, level, xoffset, yoffset,
+ zoffset, width, height, depth, format, imageSize,
+ data, dsa, false, caller);
+}
+
+static void
+compressed_tex_sub_image_no_error(unsigned dim, GLenum target, GLuint texture,
+ GLint level, GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width, GLsizei height,
+ GLsizei depth, GLenum format, GLsizei imageSize,
+ const GLvoid *data, bool dsa,
+ const char *caller)
+{
+ compressed_tex_sub_image(dim, target, texture, level, xoffset, yoffset,
+ zoffset, width, height, depth, format, imageSize,
+ data, dsa, true, caller);
+}
void GLAPIENTRY
_mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level,
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(1, target, 0, level, xoffset, 0, 0, width,
- 1, 1, format, imageSize, data, false, true,
- "glCompressedTexSubImage1D");
+ compressed_tex_sub_image_no_error(1, target, 0, level, xoffset, 0, 0, width,
+ 1, 1, format, imageSize, data, false,
+ "glCompressedTexSubImage1D");
}
GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
- compressed_tex_sub_image(1, target, 0, level, xoffset, 0, 0, width, 1, 1,
- format, imageSize, data, false, false,
- "glCompressedTexSubImage1D");
+ compressed_tex_sub_image_error(1, target, 0, level, xoffset, 0, 0, width, 1,
+ 1, format, imageSize, data, false,
+ "glCompressedTexSubImage1D");
}
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(1, 0, texture, level, xoffset, 0, 0, width, 1, 1,
- format, imageSize, data, true, true,
- "glCompressedTextureSubImage1D");
+ compressed_tex_sub_image_no_error(1, 0, texture, level, xoffset, 0, 0, width,
+ 1, 1, format, imageSize, data, true,
+ "glCompressedTextureSubImage1D");
}
GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
- compressed_tex_sub_image(1, 0, texture, level, xoffset, 0, 0, width, 1, 1,
- format, imageSize, data, true, false,
- "glCompressedTextureSubImage1D");
+ compressed_tex_sub_image_error(1, 0, texture, level, xoffset, 0, 0, width,
+ 1, 1, format, imageSize, data, true,
+ "glCompressedTextureSubImage1D");
}
void GLAPIENTRY
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(2, target, 0, level, xoffset, yoffset, 0, width,
- height, 1, format, imageSize, data, false, true,
- "glCompressedTexSubImage2D");
+ compressed_tex_sub_image_no_error(2, target, 0, level, xoffset, yoffset, 0,
+ width, height, 1, format, imageSize, data,
+ false, "glCompressedTexSubImage2D");
}
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(2, target, 0, level, xoffset, yoffset, 0, width,
- height, 1, format, imageSize, data, false, false,
- "glCompressedTexSubImage2D");
+ compressed_tex_sub_image_error(2, target, 0, level, xoffset, yoffset, 0,
+ width, height, 1, format, imageSize, data,
+ false, "glCompressedTexSubImage2D");
}
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, width,
- height, 1, format, imageSize, data, true, true,
- "glCompressedTextureSubImage2D");
+ compressed_tex_sub_image_no_error(2, 0, texture, level, xoffset, yoffset, 0,
+ width, height, 1, format, imageSize, data,
+ true, "glCompressedTextureSubImage2D");
}
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, width,
- height, 1, format, imageSize, data, true, false,
- "glCompressedTextureSubImage2D");
+ compressed_tex_sub_image_error(2, 0, texture, level, xoffset, yoffset, 0,
+ width, height, 1, format, imageSize, data,
+ true, "glCompressedTextureSubImage2D");
}
void GLAPIENTRY
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, zoffset,
- width, height, depth, format, imageSize, data,
- false, true, "glCompressedTexSubImage3D");
+ compressed_tex_sub_image_no_error(3, target, 0, level, xoffset, yoffset,
+ zoffset, width, height, depth, format,
+ imageSize, data, false,
+ "glCompressedTexSubImage3D");
}
void GLAPIENTRY
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data)
{
- compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, zoffset,
- width, height, depth, format, imageSize, data,
- false, false, "glCompressedTexSubImage3D");
+ compressed_tex_sub_image_error(3, target, 0, level, xoffset, yoffset,
+ zoffset, width, height, depth, format,
+ imageSize, data, false,
+ "glCompressedTexSubImage3D");
}
void GLAPIENTRY
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, zoffset,
- width, height, depth, format, imageSize, data,
- true, true, "glCompressedTextureSubImage3D");
+ compressed_tex_sub_image_no_error(3, 0, texture, level, xoffset, yoffset,
+ zoffset, width, height, depth, format,
+ imageSize, data, true,
+ "glCompressedTextureSubImage3D");
}
void GLAPIENTRY
GLenum format, GLsizei imageSize,
const GLvoid *data)
{
- compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, zoffset,
- width, height, depth, format, imageSize, data,
- true, false, "glCompressedTextureSubImage3D");
+ compressed_tex_sub_image_error(3, 0, texture, level, xoffset, yoffset,
+ zoffset, width, height, depth, format,
+ imageSize, data, true,
+ "glCompressedTextureSubImage3D");
}
-static mesa_format
-get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
+mesa_format
+_mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
{
if (ctx->API == API_OPENGL_COMPAT) {
switch (internalFormat) {
_mesa_validate_texbuffer_format(const struct gl_context *ctx,
GLenum internalFormat)
{
- mesa_format format = get_texbuffer_format(ctx, internalFormat);
+ mesa_format format = _mesa_get_texbuffer_format(ctx, internalFormat);
GLenum datatype;
if (format == MESA_FORMAT_NONE)
static void
texture_image_multisample(struct gl_context *ctx, GLuint dims,
struct gl_texture_object *texObj,
+ struct gl_memory_object *memObj,
GLenum target, GLsizei samples,
GLint internalformat, GLsizei width,
GLsizei height, GLsizei depth,
GLboolean fixedsamplelocations,
- GLboolean immutable, const char *func)
+ GLboolean immutable, GLuint64 offset,
+ const char *func)
{
struct gl_texture_image *texImage;
GLboolean sizeOK, dimensionsOK, samplesOK;
else {
if (!dimensionsOK) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s(invalid width or height)", func);
+ "%s(invalid width=%d or height=%d)", func, width, height);
return;
}
samples, fixedsamplelocations);
if (width > 0 && height > 0 && depth > 0) {
- if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1,
- width, height, depth)) {
- /* tidy up the texture image state. strictly speaking,
- * we're allowed to just leave this in whatever state we
- * like, but being tidy is good.
- */
- _mesa_init_teximage_fields(ctx, texImage,
- 0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE);
+ if (memObj) {
+ if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx, texObj,
+ memObj, 1, width,
+ height, depth,
+ offset)) {
+
+ _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0,
+ internalformat, texFormat);
+ }
+ } else {
+ if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1,
+ width, height, depth)) {
+ /* tidy up the texture image state. strictly speaking,
+ * we're allowed to just leave this in whatever state we
+ * like, but being tidy is good.
+ */
+ _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0,
+ internalformat, texFormat);
+ }
}
}
if (!texObj)
return;
- texture_image_multisample(ctx, 2, texObj, target, samples,
+ texture_image_multisample(ctx, 2, texObj, NULL, target, samples,
internalformat, width, height, 1,
- fixedsamplelocations, GL_FALSE,
+ fixedsamplelocations, GL_FALSE, 0,
"glTexImage2DMultisample");
}
if (!texObj)
return;
- texture_image_multisample(ctx, 3, texObj, target, samples,
+ texture_image_multisample(ctx, 3, texObj, NULL, target, samples,
internalformat, width, height, depth,
- fixedsamplelocations, GL_FALSE,
+ fixedsamplelocations, GL_FALSE, 0,
"glTexImage3DMultisample");
}
if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2))
return;
- texture_image_multisample(ctx, 2, texObj, target, samples,
+ texture_image_multisample(ctx, 2, texObj, NULL, target, samples,
internalformat, width, height, 1,
- fixedsamplelocations, GL_TRUE,
+ fixedsamplelocations, GL_TRUE, 0,
"glTexStorage2DMultisample");
}
if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3))
return;
- texture_image_multisample(ctx, 3, texObj, target, samples,
+ texture_image_multisample(ctx, 3, texObj, NULL, target, samples,
internalformat, width, height, depth,
- fixedsamplelocations, GL_TRUE,
+ fixedsamplelocations, GL_TRUE, 0,
"glTexStorage3DMultisample");
}
if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2))
return;
- texture_image_multisample(ctx, 2, texObj, texObj->Target, samples,
- internalformat, width, height, 1,
- fixedsamplelocations, GL_TRUE,
+ texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target,
+ samples, internalformat, width, height, 1,
+ fixedsamplelocations, GL_TRUE, 0,
"glTextureStorage2DMultisample");
}
if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3))
return;
- texture_image_multisample(ctx, 3, texObj, texObj->Target, samples,
+ texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples,
internalformat, width, height, depth,
- fixedsamplelocations, GL_TRUE,
+ fixedsamplelocations, GL_TRUE, 0,
"glTextureStorage3DMultisample");
}
+
+void
+_mesa_texture_storage_ms_memory(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_object *texObj,
+ struct gl_memory_object *memObj,
+ GLenum target, GLsizei samples,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint64 offset, const char* func)
+{
+ assert(memObj);
+
+ texture_image_multisample(ctx, dims, texObj, memObj, target, samples,
+ internalFormat, width, height, depth,
+ fixedSampleLocations, GL_TRUE, offset,
+ func);
+}