X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_texture.c;h=90a059ca69a5769ca509fabc06180f3d4d9e1f05;hb=a245c05dd3a1ca48204dd84252e6964aba91d4df;hp=98dc6ec74d1d3eac00210a8da4e89248a69ee01b;hpb=eb0d46490332091b2ee247f32a1f08a04e1fe00f;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 98dc6ec74d1..90a059ca69a 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -50,6 +50,8 @@ #include "state_tracker/st_public.h" #include "state_tracker/st_texture.h" #include "state_tracker/st_gen_mipmap.h" +#include "state_tracker/st_inlines.h" +#include "state_tracker/st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -57,6 +59,7 @@ #include "util/u_tile.h" #include "util/u_blit.h" #include "util/u_surface.h" +#include "util/u_math.h" #define DBG if (0) printf @@ -235,18 +238,6 @@ do_memcpy(void *dest, const void *src, size_t n) } -static int -logbase2(int n) -{ - GLint i = 1, log2 = 0; - while (n > i) { - i *= 2; - log2++; - } - return log2; -} - - /** * Return default texture usage bitmask for the given texture format. */ @@ -333,14 +324,16 @@ guess_and_alloc_texture(struct st_context *st, * pagetable arrangements. */ if ((stObj->base.MinFilter == GL_NEAREST || - stObj->base.MinFilter == GL_LINEAR) && + stObj->base.MinFilter == GL_LINEAR || + stImage->base._BaseFormat == GL_DEPTH_COMPONENT || + stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) && stImage->level == firstLevel) { lastLevel = firstLevel; } else { - GLuint l2width = logbase2(width); - GLuint l2height = logbase2(height); - GLuint l2depth = logbase2(depth); + GLuint l2width = util_logbase2(width); + GLuint l2height = util_logbase2(height); + GLuint l2depth = util_logbase2(depth); lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); } @@ -417,7 +410,6 @@ compress_with_blit(GLcontext * ctx, const GLuint dstImageOffsets[1] = {0}; struct st_texture_image *stImage = st_texture_image(texImage); struct pipe_screen *screen = ctx->st->pipe->screen; - const GLuint face = _mesa_tex_target_to_face(target); const struct gl_texture_format *mesa_format; struct pipe_texture templ; struct pipe_texture *src_tex; @@ -465,10 +457,10 @@ compress_with_blit(GLcontext * ctx, /* Put user's tex data into the temporary texture */ - tex_xfer = screen->get_tex_transfer(screen, src_tex, - face, level, 0, - PIPE_TRANSFER_WRITE, - 0, 0, width, height); /* x, y, w, h */ + tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex, + 0, 0, 0, /* face, level are zero */ + PIPE_TRANSFER_WRITE, + 0, 0, width, height); /* x, y, w, h */ map = screen->transfer_map(screen, tex_xfer); mesa_format->StoreImage(ctx, 2, GL_RGBA, mesa_format, @@ -526,10 +518,17 @@ st_TexImage(GLcontext * ctx, GLint texelBytes, sizeInBytes; GLuint dstRowStride; struct gl_pixelstore_attrib unpackNB; + enum pipe_transfer_usage transfer_usage; DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); + /* switch to "normal" */ + if (stObj->surface_based) { + _mesa_clear_texture_object(ctx, texObj); + stObj->surface_based = GL_FALSE; + } + /* gallium does not support texture borders, strip it off */ if (border) { strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB); @@ -672,16 +671,23 @@ st_TexImage(GLcontext * ctx, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth, format, type, pixels, unpack, texImage)) { - return; + goto done; } } if (stImage->pt) { + if (format == GL_DEPTH_COMPONENT && + pf_is_depth_and_stencil(stImage->pt->format)) + transfer_usage = PIPE_TRANSFER_READ_WRITE; + else + transfer_usage = PIPE_TRANSFER_WRITE; + texImage->Data = st_texture_image_map(ctx->st, stImage, 0, - PIPE_TRANSFER_WRITE, 0, 0, + transfer_usage, 0, 0, stImage->base.Width, stImage->base.Height); - dstRowStride = stImage->transfer->stride; + if(stImage->transfer) + dstRowStride = stImage->transfer->stride; } else { /* Allocate regular memory and store the image there temporarily. */ @@ -738,7 +744,7 @@ st_TexImage(GLcontext * ctx, st_texture_image_unmap(ctx->st, stImage); /* map next slice of 3D texture */ texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1, - PIPE_TRANSFER_WRITE, 0, 0, + transfer_usage, 0, 0, stImage->base.Width, stImage->base.Height); src += srcImageStride; @@ -748,6 +754,7 @@ st_TexImage(GLcontext * ctx, _mesa_unmap_teximage_pbo(ctx, unpack); +done: if (stImage->pt && texImage->Data) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; @@ -858,9 +865,10 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, PIPE_TEX_MIPFILTER_NEAREST); /* map the dst_surface so we can read from it */ - tex_xfer = screen->get_tex_transfer(screen, dst_texture, 0, 0, 0, - PIPE_TRANSFER_READ, - 0, 0, width, height); + tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), + dst_texture, 0, 0, 0, + PIPE_TRANSFER_READ, + 0, 0, width, height); pixels = _mesa_map_readpix_pbo(ctx, &ctx->Pack, pixels); @@ -937,8 +945,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, /* Image is stored in hardware format in a buffer managed by the * kernel. Need to explicitly map and unmap it. */ + unsigned face = _mesa_tex_target_to_face(target); - st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, + st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, PIPE_TRANSFER_READ); texImage->Data = st_texture_image_map(ctx->st, stImage, 0, @@ -1035,6 +1044,8 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, _mesa_image_image_stride(packing, width, height, format, type); GLint i; const GLubyte *src; + /* init to silence warning only: */ + enum pipe_transfer_usage transfer_usage = PIPE_TRANSFER_WRITE; DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), @@ -1058,7 +1069,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, packing, texImage)) { - return; + goto done; } } @@ -1066,10 +1077,18 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, * from uploading the buffer under us. */ if (stImage->pt) { - st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, - PIPE_TRANSFER_WRITE); + unsigned face = _mesa_tex_target_to_face(target); + + if (format == GL_DEPTH_COMPONENT && + pf_is_depth_and_stencil(stImage->pt->format)) + transfer_usage = PIPE_TRANSFER_READ_WRITE; + else + transfer_usage = PIPE_TRANSFER_WRITE; + + st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, + transfer_usage); texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, - PIPE_TRANSFER_WRITE, + transfer_usage, xoffset, yoffset, width, height); } @@ -1100,23 +1119,24 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, /* map next slice of 3D texture */ texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i + 1, - PIPE_TRANSFER_WRITE, + transfer_usage, xoffset, yoffset, width, height); src += srcImageStride; } } - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); +done: if (stImage->pt) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } + + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + ctx->Driver.GenerateMipmap(ctx, target, texObj); + } } @@ -1164,6 +1184,90 @@ st_TexSubImage1D(GLcontext *ctx, GLenum target, GLint level, } +static void +st_CompressedTexSubImage1D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + assert(0); +} + + +static void +st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLint height, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct st_texture_image *stImage = st_texture_image(texImage); + struct pipe_format_block block; + int srcBlockStride; + int dstBlockStride; + int y; + + if (stImage->pt) { + unsigned face = _mesa_tex_target_to_face(target); + + st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, + PIPE_TRANSFER_WRITE); + texImage->Data = st_texture_image_map(ctx->st, stImage, 0, + PIPE_TRANSFER_WRITE, + xoffset, yoffset, + width, height); + + block = stImage->pt->block; + srcBlockStride = pf_get_stride(&block, width); + dstBlockStride = stImage->transfer->stride; + } else { + assert(stImage->pt); + /* TODO find good values for block and strides */ + /* TODO also adjust texImage->data for yoffset/xoffset */ + return; + } + + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage"); + return; + } + + assert(xoffset % block.width == 0); + assert(yoffset % block.height == 0); + assert(width % block.width == 0); + assert(height % block.height == 0); + + for (y = 0; y < height; y += block.height) { + /* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */ + const char *src = (const char*)data + srcBlockStride * pf_get_nblocksy(&block, y); + char *dst = (char*)texImage->Data + dstBlockStride * pf_get_nblocksy(&block, y); + memcpy(dst, src, pf_get_stride(&block, width)); + } + + if (stImage->pt) { + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = NULL; + } +} + + +static void +st_CompressedTexSubImage3D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLint height, GLint depth, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + assert(0); +} + + /** * Do a CopyTexSubImage operation using a read transfer from the source, @@ -1185,6 +1289,7 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, struct pipe_screen *screen = pipe->screen; struct pipe_transfer *src_trans; GLvoid *texDest; + enum pipe_transfer_usage transfer_usage; assert(width <= MAX_WIDTH); @@ -1192,20 +1297,23 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, srcY = strb->Base.Height - srcY - height; } - st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, - PIPE_TRANSFER_READ); + src_trans = st_cond_flush_get_tex_transfer( st_context(ctx), + strb->texture, + 0, 0, 0, + PIPE_TRANSFER_READ, + srcX, srcY, + width, height); - src_trans = screen->get_tex_transfer( screen, - strb->texture, - 0, 0, 0, - PIPE_TRANSFER_READ, - srcX, srcY, - width, height); + if (baseFormat == GL_DEPTH_COMPONENT && + pf_is_depth_and_stencil(stImage->pt->format)) + transfer_usage = PIPE_TRANSFER_READ_WRITE; + else + transfer_usage = PIPE_TRANSFER_WRITE; st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0, - PIPE_TRANSFER_WRITE); + transfer_usage); - texDest = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE, + texDest = st_texture_image_map(ctx->st, stImage, 0, transfer_usage, destX, destY, width, height); if (baseFormat == GL_DEPTH_COMPONENT || @@ -1315,8 +1423,12 @@ st_copy_texsubimage(GLcontext *ctx, GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; - /* any rendering in progress must complete before we grab the fb image */ - st_finish(ctx->st); + /* any rendering in progress must flushed before we grab the fb image */ + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + + /* make sure finalize_textures has been called? + */ + if (0) st_validate_state(ctx->st); /* determine if copying depth or color data */ if (texBaseFormat == GL_DEPTH_COMPONENT || @@ -1331,6 +1443,39 @@ st_copy_texsubimage(GLcontext *ctx, strb = st_renderbuffer(fb->_ColorReadBuffer); } + if (!strb || !strb->surface || !stImage->pt) { + debug_printf("%s: null strb or stImage\n", __FUNCTION__); + return; + } + + if (srcX < 0) { + width -= -srcX; + destX += -srcX; + srcX = 0; + } + + if (srcY < 0) { + height -= -srcY; + destY += -srcY; + srcY = 0; + } + + if (destX < 0) { + width -= -destX; + srcX += -destX; + destX = 0; + } + + if (destY < 0) { + height -= -destY; + srcY += -destY; + destY = 0; + } + + if (width < 0 || height < 0) + return; + + assert(strb); assert(strb->surface); assert(stImage->pt); @@ -1589,7 +1734,7 @@ copy_image_data_to_texture(struct st_context *st, PIPE_TRANSFER_WRITE); - st_texture_image_data(st->pipe, + st_texture_image_data(st, stObj->pt, stImage->face, dstLevel, @@ -1779,6 +1924,9 @@ st_init_texture_functions(struct dd_function_table *functions) functions->TexSubImage1D = st_TexSubImage1D; functions->TexSubImage2D = st_TexSubImage2D; functions->TexSubImage3D = st_TexSubImage3D; + functions->CompressedTexSubImage1D = st_CompressedTexSubImage1D; + functions->CompressedTexSubImage2D = st_CompressedTexSubImage2D; + functions->CompressedTexSubImage3D = st_CompressedTexSubImage3D; functions->CopyTexImage1D = st_CopyTexImage1D; functions->CopyTexImage2D = st_CopyTexImage2D; functions->CopyTexSubImage1D = st_CopyTexSubImage1D;