aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/state_tracker/st_cb_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/state_tracker/st_cb_texture.c')
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c102
1 files changed, 92 insertions, 10 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index 260df09f5..76bf78bbf 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -460,6 +460,91 @@ guess_and_alloc_texture(struct st_context *st,
/**
+ * Called via ctx->Driver.AllocTextureImageBuffer().
+ * If the texture object/buffer already has space for the indicated image,
+ * we're done. Otherwise, allocate memory for the new texture image.
+ * XXX This function and st_TexImage() have some duplicated code. That
+ * can be cleaned up in the future.
+ */
+static GLboolean
+st_AllocTextureImageBuffer(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
+ gl_format format, GLsizei width,
+ GLsizei height, GLsizei depth)
+{
+ 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;
+
+ DBG("%s\n", __FUNCTION__);
+
+ assert(width > 0);
+ assert(height > 0);
+ assert(depth > 0);
+ assert(!texImage->Data);
+ assert(!stImage->pt); /* xxx this might be wrong */
+
+ /* Look if the parent texture object has space for this image */
+ if (stObj->pt &&
+ level <= stObj->pt->last_level &&
+ st_texture_match_image(stObj->pt, texImage)) {
+ /* this image will fit in the existing texture object's memory */
+ pipe_resource_reference(&stImage->pt, stObj->pt);
+ return GL_TRUE;
+ }
+
+ /* The parent texture object does not have space for this image */
+
+ pipe_resource_reference(&stObj->pt, NULL);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+
+ 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;
+ }
+ }
+
+ if (stObj->pt &&
+ st_texture_match_image(stObj->pt, texImage)) {
+ /* The image will live in the object's mipmap memory */
+ pipe_resource_reference(&stImage->pt, stObj->pt);
+ assert(stImage->pt);
+ return GL_TRUE;
+ }
+ else {
+ /* Create a new, temporary texture/resource/buffer to hold this
+ * one texture image.
+ */
+ enum pipe_format format =
+ st_mesa_format_to_pipe_format(texImage->TexFormat);
+ GLuint bindings = default_bindings(st, format);
+ GLuint ptWidth, ptHeight, ptDepth, ptLayers;
+
+ st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
+ width, height, depth,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+
+ stImage->pt = st_texture_create(st,
+ gl_target_to_pipe(stObj->base.Target),
+ format,
+ 0, /* lastLevel */
+ ptWidth,
+ ptHeight,
+ ptDepth,
+ ptLayers,
+ bindings);
+ return stImage->pt != NULL;
+ }
+}
+
+
+/**
* Adjust pixel unpack params and image dimensions to strip off the
* texture border.
* Gallium doesn't support texture borders. They've seldem been used
@@ -815,15 +900,14 @@ st_CompressedTexImage2D(struct gl_context *ctx, GLenum target, GLint level,
* a textured quad. Store the results in the user's buffer.
*/
static void
-decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
+decompress_with_blit(struct gl_context * ctx,
GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct st_texture_image *stImage = st_texture_image(texImage);
- struct st_texture_object *stObj = st_texture_object(texObj);
+ struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
struct pipe_sampler_view *src_view =
st_get_texture_sampler_view(stObj, pipe);
const GLuint width = texImage->Width;
@@ -848,7 +932,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
}
/* Choose the source mipmap level */
- src_view->u.tex.first_level = src_view->u.tex.last_level = level;
+ src_view->u.tex.first_level = src_view->u.tex.last_level = texImage->Level;
/* blit/render/decompress */
util_blit_pixels_tex(st->blit,
@@ -925,9 +1009,8 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
* Called via ctx->Driver.GetTexImage()
*/
static void
-st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level,
+st_GetTexImage(struct gl_context * ctx,
GLenum format, GLenum type, GLvoid * pixels,
- struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
struct st_texture_image *stImage = st_texture_image(texImage);
@@ -938,12 +1021,10 @@ st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level,
* faster than using the fallback code in texcompress.c.
* Note that we only expect RGBA formats (no Z/depth formats).
*/
- decompress_with_blit(ctx, target, level, format, type, pixels,
- texObj, texImage);
+ decompress_with_blit(ctx, format, type, pixels, texImage);
}
else {
- _mesa_get_teximage(ctx, target, level, format, type, pixels,
- texObj, texImage);
+ _mesa_get_teximage(ctx, format, type, pixels, texImage);
}
}
@@ -1841,6 +1922,7 @@ st_init_texture_functions(struct dd_function_table *functions)
functions->NewTextureImage = st_NewTextureImage;
functions->DeleteTextureImage = st_DeleteTextureImage;
functions->DeleteTexture = st_DeleteTextureObject;
+ functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer;
functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer;
functions->MapTextureImage = st_MapTextureImage;
functions->UnmapTextureImage = st_UnmapTextureImage;