#include "main/format_utils.h"
#include "main/glformats.h"
#include "main/image.h"
-#include "util/imports.h"
+
#include "main/macros.h"
#include "main/mipmap.h"
#include "main/pack.h"
_mesa_delete_texture_object(ctx, texObj);
}
+/**
+ * Called via ctx->Driver.TextureRemovedFromShared()
+ * When texture is removed from ctx->Shared->TexObjects we lose
+ * the ability to clean up views on context destruction, which may
+ * lead to dangling pointers to destroyed contexts.
+ * Release the views to prevent this.
+ */
+static void
+st_TextureReleaseAllSamplerViews(struct gl_context *ctx,
+ struct gl_texture_object *texObj)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_texture_object *stObj = st_texture_object(texObj);
+
+ st_texture_release_all_sampler_views(st, stObj);
+}
/** called via ctx->Driver.FreeTextureImageBuffer() */
static void
stImage->transfer = NULL;
stImage->num_transfers = 0;
- if (stImage->compressed_data) {
+ if (stImage->compressed_data &&
+ pipe_reference(&stImage->compressed_data->reference, NULL)) {
+ free(stImage->compressed_data->ptr);
free(stImage->compressed_data);
stImage->compressed_data = NULL;
}
if (!st_compressed_format_fallback(st, texImage->TexFormat))
return;
- if (stImage->compressed_data)
+ if (stImage->compressed_data &&
+ pipe_reference(&stImage->compressed_data->reference, NULL)) {
+ free(stImage->compressed_data->ptr);
free(stImage->compressed_data);
+ }
unsigned data_size = _mesa_format_image_size(texImage->TexFormat,
texImage->Width2,
texImage->Height2,
texImage->Depth2);
- stImage->compressed_data =
+ stImage->compressed_data = ST_CALLOC_STRUCT(st_compressed_data);
+ stImage->compressed_data->ptr =
malloc(data_size * _mesa_num_tex_faces(texImage->TexObject->Target));
+ pipe_reference_init(&stImage->compressed_data->reference, 1);
}
_mesa_format_row_stride(texImage->TexFormat, texImage->Width2);
unsigned block_size = _mesa_get_format_bytes(texImage->TexFormat);
+ assert(stImage->compressed_data);
*mapOut = itransfer->temp_data =
- stImage->compressed_data +
+ stImage->compressed_data->ptr +
(z * y_blocks + (y / blk_h)) * stride +
(x / blk_w) * block_size;
itransfer->map = map;
struct st_context *st = st_context(ctx);
struct st_texture_image *stImage = st_texture_image(texImage);
struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
- const GLuint level = texImage->Level;
GLuint width = texImage->Width;
GLuint height = texImage->Height;
GLuint depth = texImage->Depth;
stObj->needs_validation = true;
compressed_tex_fallback_allocate(st, stImage);
+ const bool allowAllocateToStObj = !stObj->pt ||
+ stObj->pt->last_level == 0 ||
+ texImage->Level == 0;
- /* Look if the parent texture object has space for this image */
- if (stObj->pt &&
- level <= stObj->pt->last_level &&
- st_texture_match_image(st, stObj->pt, texImage)) {
- /* this image will fit in the existing texture object's memory */
- pipe_resource_reference(&stImage->pt, stObj->pt);
- return GL_TRUE;
- }
+ if (allowAllocateToStObj) {
+ /* Look if the parent texture object has space for this image */
+ if (stObj->pt &&
+ st_texture_match_image(st, stObj->pt, texImage)) {
+ /* this image will fit in the existing texture object's memory */
+ pipe_resource_reference(&stImage->pt, stObj->pt);
+ assert(stImage->pt);
+ return GL_TRUE;
+ }
- /* The parent texture object does not have space for this image */
+ /* The parent texture object does not have space for this image */
- pipe_resource_reference(&stObj->pt, NULL);
- st_texture_release_all_sampler_views(st, stObj);
+ pipe_resource_reference(&stObj->pt, NULL);
+ st_texture_release_all_sampler_views(st, stObj);
- if (!guess_and_alloc_texture(st, stObj, stImage)) {
- /* Probably out of memory.
- * Try flushing any pending rendering, then retry.
- */
- st_finish(st);
if (!guess_and_alloc_texture(st, stObj, stImage)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- return GL_FALSE;
+ /* Probably out of memory.
+ * Try flushing any pending rendering, then retry.
+ */
+ st_finish(st);
+ if (!guess_and_alloc_texture(st, stObj, stImage)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return GL_FALSE;
+ }
}
}
/* Try texture_subdata, which should be the fastest memcpy path. */
if (pixels &&
- !_mesa_is_bufferobj(unpack->BufferObj) &&
+ !unpack->BufferObj &&
_mesa_texstore_can_use_memcpy(ctx, texImage->_BaseFormat,
texImage->TexFormat, format, type,
unpack)) {
goto fallback;
}
- if (_mesa_is_bufferobj(unpack->BufferObj)) {
+ if (unpack->BufferObj) {
if (try_pbo_upload(ctx, dims, texImage, format, type, dst_format,
xoffset, yoffset, zoffset,
width, height, depth, pixels, unpack))
goto fallback;
}
- if (!_mesa_is_bufferobj(ctx->Unpack.BufferObj))
+ if (!ctx->Unpack.BufferObj)
goto fallback;
if (st_compressed_format_fallback(st, texImage->TexFormat))
PIPE_TRANSFER_READ,
srcX, srcY,
width, height, &src_trans);
+ if (!map) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
+ return;
+ }
if ((baseFormat == GL_DEPTH_COMPONENT ||
baseFormat == GL_DEPTH_STENCIL) &&
destX, destY, slice,
dst_width, dst_height, dst_depth,
&transfer);
+ if (!texDest) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
+ goto err;
+ }
if (baseFormat == GL_DEPTH_COMPONENT ||
baseFormat == GL_DEPTH_STENCIL) {
GLfloat *tempSrc =
malloc(width * height * 4 * sizeof(GLfloat));
- if (tempSrc && texDest) {
+ if (tempSrc) {
const GLint dims = 2;
GLint dstRowStride;
struct gl_texture_image *texImage = &stImage->base;
}
st_texture_image_unmap(st, stImage, slice);
+err:
pipe->transfer_unmap(pipe, src_trans);
}
}
else {
/* assume a full set of mipmaps */
- pt.last_level = _mesa_logbase2(MAX3(width, height, depth));
+ pt.last_level = util_logbase2(MAX3(width, height, depth));
}
return pipe->screen->can_create_resource(pipe->screen, &pt);
for (face = 0; face < numFaces; face++) {
struct st_texture_image *stImage =
st_texture_image(texObj->Image[face][level]);
+ struct st_texture_image *origImage =
+ st_texture_image(origTexObj->Image[face][level]);
pipe_resource_reference(&stImage->pt, tex->pt);
+ if (origImage &&
+ origImage->compressed_data) {
+ pipe_reference(NULL,
+ &origImage->compressed_data->reference);
+ stImage->compressed_data = origImage->compressed_data;
+ }
}
}
functions->NewTextureImage = st_NewTextureImage;
functions->DeleteTextureImage = st_DeleteTextureImage;
functions->DeleteTexture = st_DeleteTextureObject;
+ functions->TextureRemovedFromShared = st_TextureReleaseAllSamplerViews;
functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer;
functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer;
functions->MapTextureImage = st_MapTextureImage;