X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_texture.c;h=9619dd290ed5ec01b788d56d040f19784d77d38b;hb=c06258dd0297e1fe7910f48a59aa0de79029ce39;hp=eb861586c4aa6291cead750c4d106ee2b08147ef;hpb=e42d00b3f4503a0840575c8e5f4517a66c8af613;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index eb861586c4a..9619dd290ed 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -73,22 +73,38 @@ gl_target_to_pipe(GLenum target) { switch (target) { case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: return PIPE_TEXTURE_1D; case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: case GL_TEXTURE_EXTERNAL_OES: return PIPE_TEXTURE_2D; case GL_TEXTURE_RECTANGLE_NV: + case GL_PROXY_TEXTURE_RECTANGLE_NV: return PIPE_TEXTURE_RECT; case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: return PIPE_TEXTURE_3D; case GL_TEXTURE_CUBE_MAP_ARB: + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return PIPE_TEXTURE_CUBE; case GL_TEXTURE_1D_ARRAY_EXT: + case GL_PROXY_TEXTURE_1D_ARRAY_EXT: return PIPE_TEXTURE_1D_ARRAY; case GL_TEXTURE_2D_ARRAY_EXT: + case GL_PROXY_TEXTURE_2D_ARRAY_EXT: return PIPE_TEXTURE_2D_ARRAY; case GL_TEXTURE_BUFFER: return PIPE_BUFFER; + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return PIPE_TEXTURE_CUBE_ARRAY; default: assert(0); return 0; @@ -237,36 +253,6 @@ default_bindings(struct st_context *st, enum pipe_format format) } -/** Return number of image dimensions (1, 2 or 3) for a texture target. */ -static GLuint -get_texture_dims(GLenum target) -{ - switch (target) { - case GL_TEXTURE_1D: - case GL_TEXTURE_1D_ARRAY_EXT: - case GL_TEXTURE_BUFFER: - return 1; - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - case GL_TEXTURE_RECTANGLE_NV: - case GL_TEXTURE_2D_ARRAY_EXT: - case GL_TEXTURE_EXTERNAL_OES: - return 2; - case GL_TEXTURE_3D: - return 3; - default: - assert(0 && "invalid texture target in get_texture_dims()"); - return 1; - } -} - - /** * Given the size of a mipmap image, try to compute the size of the level=0 * mipmap image. @@ -281,32 +267,57 @@ guess_base_level_size(GLenum target, GLuint width, GLuint height, GLuint depth, GLuint level, GLuint *width0, GLuint *height0, GLuint *depth0) { - const GLuint dims = get_texture_dims(target); - assert(width >= 1); assert(height >= 1); assert(depth >= 1); if (level > 0) { - /* Depending on the image's size, we can't always make a guess here */ - if ((dims >= 1 && width == 1) || - (dims >= 2 && height == 1) || - (dims >= 3 && depth == 1)) { - /* we can't determine the image size at level=0 */ - return GL_FALSE; - } + /* Guess the size of the base level. + * Depending on the image's size, we can't always make a guess here. + */ + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + width <<= level; + break; + + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_ARRAY: + /* We can't make a good guess here, because the base level dimensions + * can be non-square. + */ + if (width == 1 || height == 1) { + return GL_FALSE; + } + width <<= level; + height <<= level; + break; + + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY: + width <<= level; + height <<= level; + break; + + case GL_TEXTURE_3D: + /* We can't make a good guess here, because the base level dimensions + * can be non-cube. + */ + if (width == 1 || height == 1 || depth == 1) { + return GL_FALSE; + } + width <<= level; + height <<= level; + depth <<= level; + break; + + case GL_TEXTURE_RECTANGLE: + break; - /* grow the image size until we hit level = 0 */ - while (level > 0) { - if (width > 1) - width <<= 1; - if (height > 1) - height <<= 1; - if (depth > 1) - depth <<= 1; - level--; + default: + assert(0); } - } + } *width0 = width; *height0 = height; @@ -362,6 +373,8 @@ guess_and_alloc_texture(struct st_context *st, */ if ((stObj->base.Sampler.MinFilter == GL_NEAREST || stObj->base.Sampler.MinFilter == GL_LINEAR || + (stObj->base.BaseLevel == 0 && + stObj->base.MaxLevel == 0) || stImage->base._BaseFormat == GL_DEPTH_COMPONENT || stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) && !stObj->base.GenerateMipmap && @@ -415,20 +428,18 @@ guess_and_alloc_texture(struct st_context *st, */ static GLboolean st_AllocTextureImageBuffer(struct gl_context *ctx, - struct gl_texture_image *texImage, - gl_format format, GLsizei width, - GLsizei height, GLsizei depth) + struct gl_texture_image *texImage) { 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; DBG("%s\n", __FUNCTION__); - assert(width > 0); - assert(height > 0); - assert(depth > 0); assert(!stImage->TexData); assert(!stImage->pt); /* xxx this might be wrong */ @@ -500,8 +511,6 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, */ static void prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type) { struct gl_texture_object *texObj = texImage->TexObject; @@ -518,11 +527,13 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, /* oops, need to init this image again */ texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, format, type); + texImage->InternalFormat, format, + type); _mesa_init_teximage_fields(ctx, texImage, - width, height, depth, border, - internalFormat, texFormat); + texImage->Width, texImage->Height, + texImage->Depth, texImage->Border, + texImage->InternalFormat, texFormat); stObj->surface_based = GL_FALSE; } @@ -532,29 +543,21 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, static void st_TexImage(struct gl_context * ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack) { - prep_teximage(ctx, texImage, internalFormat, width, height, depth, border, - format, type); - _mesa_store_teximage(ctx, dims, texImage, internalFormat, width, height, depth, - border, format, type, pixels, unpack); + prep_teximage(ctx, texImage, format, type); + _mesa_store_teximage(ctx, dims, texImage, format, type, pixels, unpack); } static void -st_CompressedTexImage2D(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid *data) +st_CompressedTexImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *texImage, + GLsizei imageSize, const GLvoid *data) { - prep_teximage(ctx, texImage, internalFormat, width, 1, 1, border, - GL_NONE, GL_NONE); - _mesa_store_compressed_teximage2d(ctx, texImage, internalFormat, width, - height, border, imageSize, data); + prep_teximage(ctx, texImage, GL_NONE, GL_NONE); + _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data); } @@ -572,76 +575,58 @@ decompress_with_blit(struct gl_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(texImage->TexObject); - struct pipe_sampler_view *src_view; const GLuint width = texImage->Width; const GLuint height = texImage->Height; - struct pipe_surface *dst_surface; struct pipe_resource *dst_texture; + struct pipe_blit_info blit; + unsigned bind = (PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_READ); struct pipe_transfer *tex_xfer; - unsigned bind = (PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */ - PIPE_BIND_TRANSFER_READ); + ubyte *map; /* create temp / dest surface */ - if (!util_create_rgba_surface(pipe, width, height, bind, - &dst_texture, &dst_surface)) { - _mesa_problem(ctx, "util_create_rgba_surface() failed " + if (!util_create_rgba_texture(pipe, width, height, bind, + &dst_texture)) { + _mesa_problem(ctx, "util_create_rgba_texture() failed " "in decompress_with_blit()"); return; } - /* Disable conditional rendering. */ - if (st->render_condition) { - pipe->render_condition(pipe, NULL, 0); - } - - /* Create sampler view that limits fetches to the source mipmap level */ - { - struct pipe_sampler_view sv_temp; - - u_sampler_view_default_template(&sv_temp, stObj->pt, stObj->pt->format); - - sv_temp.u.tex.first_level = - sv_temp.u.tex.last_level = texImage->Level; - - src_view = pipe->create_sampler_view(pipe, stObj->pt, &sv_temp); - if (!src_view) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); - return; - } - } + blit.src.resource = stObj->pt; + blit.src.level = texImage->Level; + blit.src.format = util_format_linear(stObj->pt->format); + blit.dst.resource = dst_texture; + blit.dst.level = 0; + blit.dst.format = dst_texture->format; + blit.src.box.x = blit.dst.box.x = 0; + blit.src.box.y = blit.dst.box.y = 0; + blit.src.box.z = 0; /* XXX compressed array textures? */ + blit.dst.box.z = 0; + blit.src.box.width = blit.dst.box.width = width; + blit.src.box.height = blit.dst.box.height = height; + blit.src.box.depth = blit.dst.box.depth = 1; + blit.mask = PIPE_MASK_RGBA; + blit.filter = PIPE_TEX_FILTER_NEAREST; + blit.scissor_enable = FALSE; /* blit/render/decompress */ - util_blit_pixels_tex(st->blit, - src_view, /* pipe_resource (src) */ - 0, 0, /* src x0, y0 */ - width, height, /* src x1, y1 */ - dst_surface, /* pipe_surface (dst) */ - 0, 0, /* dst x0, y0 */ - width, height, /* dst x1, y1 */ - 0.0, /* z */ - PIPE_TEX_MIPFILTER_NEAREST); - - /* Restore conditional rendering state. */ - if (st->render_condition) { - pipe->render_condition(pipe, st->render_condition, - st->condition_mode); - } - - /* map the dst_surface so we can read from it */ - tex_xfer = pipe_get_transfer(pipe, - dst_texture, 0, 0, - PIPE_TRANSFER_READ, - 0, 0, width, height); + st->pipe->blit(st->pipe, &blit); pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); + map = pipe_transfer_map(pipe, dst_texture, 0, 0, + PIPE_TRANSFER_READ, + 0, 0, width, height, &tex_xfer); + if (!map) { + goto end; + } + /* copy/pack data into user buffer */ if (_mesa_format_matches_format_and_type(stImage->base.TexFormat, format, type, ctx->Pack.SwapBytes)) { /* memcpy */ const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format); - ubyte *map = pipe_transfer_map(pipe, tex_xfer); + /* map the dst_surface so we can read from it */ GLuint row; for (row = 0; row < height; row++) { GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, @@ -657,7 +642,7 @@ decompress_with_blit(struct gl_context * ctx, enum pipe_format pformat = util_format_linear(dst_texture->format); GLfloat *rgba; - rgba = (GLfloat *) malloc(width * 4 * sizeof(GLfloat)); + rgba = malloc(width * 4 * sizeof(GLfloat)); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); goto end; @@ -672,7 +657,7 @@ decompress_with_blit(struct gl_context * ctx, debug_printf("%s: fallback format translation\n", __FUNCTION__); /* get float[4] rgba row from surface */ - pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1, + pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1, pformat, rgba); _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, @@ -683,14 +668,11 @@ decompress_with_blit(struct gl_context * ctx, } end: - _mesa_unmap_pbo_dest(ctx, &ctx->Pack); - - pipe->transfer_destroy(pipe, tex_xfer); - - /* destroy the temp / dest surface */ - util_destroy_rgba_surface(dst_texture, dst_surface); + if (map) + pipe_transfer_unmap(pipe, tex_xfer); - pipe_sampler_view_release(pipe, &src_view); + _mesa_unmap_pbo_dest(ctx, &ctx->Pack); + pipe_resource_reference(&dst_texture, NULL); } @@ -740,6 +722,7 @@ fallback_copy_texsubimage(struct gl_context *ctx, struct pipe_transfer *src_trans; GLvoid *texDest; enum pipe_transfer_usage transfer_usage; + void *map; if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s: fallback processing\n", __FUNCTION__); @@ -748,13 +731,13 @@ fallback_copy_texsubimage(struct gl_context *ctx, srcY = strb->Base.Height - srcY - height; } - src_trans = pipe_get_transfer(pipe, - strb->texture, - strb->rtt_level, - strb->rtt_face + strb->rtt_slice, - PIPE_TRANSFER_READ, - srcX, srcY, - width, height); + map = pipe_transfer_map(pipe, + strb->texture, + strb->rtt_level, + strb->rtt_face + strb->rtt_slice, + PIPE_TRANSFER_READ, + srcX, srcY, + width, height, &src_trans); if ((baseFormat == GL_DEPTH_COMPONENT || baseFormat == GL_DEPTH_STENCIL) && @@ -784,16 +767,17 @@ fallback_copy_texsubimage(struct gl_context *ctx, yStep = 1; } - data = (uint *) malloc(width * sizeof(uint)); + data = malloc(width * sizeof(uint)); if (data) { /* To avoid a large temp memory allocation, do copy row by row */ for (row = 0; row < height; row++, srcY += yStep) { - pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data); + pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data); if (scaleOrBias) { _mesa_scale_and_bias_depth_uint(ctx, width, data); } - pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data); + pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1, + data); } } else { @@ -805,7 +789,7 @@ fallback_copy_texsubimage(struct gl_context *ctx, else { /* RGBA format */ GLfloat *tempSrc = - (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); + malloc(width * height * 4 * sizeof(GLfloat)); if (tempSrc && texDest) { const GLint dims = 2; @@ -821,7 +805,7 @@ fallback_copy_texsubimage(struct gl_context *ctx, /* XXX this usually involves a lot of int/float conversion. * try to avoid that someday. */ - pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height, + pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height, util_format_linear(strb->texture->format), tempSrc); @@ -844,12 +828,11 @@ fallback_copy_texsubimage(struct gl_context *ctx, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); } - if (tempSrc) - free(tempSrc); + free(tempSrc); } st_texture_image_unmap(st, stImage); - pipe->transfer_destroy(pipe, src_trans); + pipe->transfer_unmap(pipe, src_trans); } @@ -928,23 +911,21 @@ compatible_src_dst_formats(struct gl_context *ctx, * Note: srcY=0=Bottom of renderbuffer (GL convention) */ static void -st_copy_texsubimage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint destX, GLint destY, GLint destZ, - struct gl_renderbuffer *rb, - GLint srcX, GLint srcY, - GLsizei width, GLsizei height) +st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *texImage, + GLint destX, GLint destY, GLint destZ, + struct gl_renderbuffer *rb, + GLint srcX, GLint srcY, GLsizei width, GLsizei height) { struct st_texture_image *stImage = st_texture_image(texImage); const GLenum texBaseFormat = texImage->_BaseFormat; - struct gl_framebuffer *fb = ctx->ReadBuffer; - struct st_renderbuffer *strb; + struct st_renderbuffer *strb = st_renderbuffer(rb); struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; enum pipe_format dest_format, src_format; GLboolean matching_base_formats; - GLuint format_writemask, sample_count; + GLuint color_writemask, zs_writemask, sample_count; struct pipe_surface *dest_surface = NULL; GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); struct pipe_surface surf_tmpl; @@ -955,16 +936,6 @@ st_copy_texsubimage(struct gl_context *ctx, */ if (0) st_validate_state(st); - /* determine if copying depth or color data */ - if (texBaseFormat == GL_DEPTH_COMPONENT || - texBaseFormat == GL_DEPTH_STENCIL) { - strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); - } - else { - /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ - strb = st_renderbuffer(fb->_ColorReadBuffer); - } - if (!strb || !strb->surface || !stImage->pt) { debug_printf("%s: null strb or stImage\n", __FUNCTION__); return; @@ -999,19 +970,37 @@ st_copy_texsubimage(struct gl_context *ctx, goto fallback; } + if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { + /* 1D arrays might be thought of as 2D images but the actual layout + * might not be that way. At some points, we convert OpenGL's 1D + * array 'height' into gallium 'layers' and that prevents the blit + * utility code from doing the right thing. Simpy use the memcpy-based + * fallback. + */ + goto fallback; + } + if (matching_base_formats && src_format == dest_format && !do_flip) { /* use surface_copy() / blit */ struct pipe_box src_box; + unsigned dstLevel; + u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer, width, height, &src_box); + /* If stImage->pt is an independent image (not a pointer into a full + * mipmap) stImage->pt.last_level will be zero and we need to use that + * as the dest level. + */ + dstLevel = MIN2(stImage->base.Level, stImage->pt->last_level); + /* for resource_copy_region(), y=0=top, always */ pipe->resource_copy_region(pipe, /* dest */ stImage->pt, - stImage->base.Level, + dstLevel, destX, destY, destZ + stImage->base.Face, /* src */ strb->texture, @@ -1025,15 +1014,17 @@ st_copy_texsubimage(struct gl_context *ctx, } if (texBaseFormat == GL_DEPTH_COMPONENT) { - format_writemask = TGSI_WRITEMASK_XYZW; + color_writemask = 0; + zs_writemask = BLIT_WRITEMASK_Z; dst_usage = PIPE_BIND_DEPTH_STENCIL; } else { - format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); + color_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); + zs_writemask = 0; dst_usage = PIPE_BIND_RENDER_TARGET; } - if (!format_writemask || + if ((!color_writemask && !zs_writemask) || !screen->is_format_supported(screen, src_format, PIPE_TEXTURE_2D, sample_count, PIPE_BIND_SAMPLER_VIEW) || @@ -1066,17 +1057,17 @@ st_copy_texsubimage(struct gl_context *ctx, dest_surface = pipe->create_surface(pipe, stImage->pt, &surf_tmpl); - util_blit_pixels_writemask(st->blit, - strb->texture, - strb->surface->u.tex.level, - srcX, srcY0, - srcX + width, srcY1, - strb->surface->u.tex.first_layer, - dest_surface, - destX, destY, - destX + width, destY + height, - 0.0, PIPE_TEX_MIPFILTER_NEAREST, - format_writemask); + util_blit_pixels(st->blit, + strb->texture, + strb->surface->u.tex.level, + srcX, srcY0, + srcX + width, srcY1, + strb->surface->u.tex.first_layer, + dest_surface, + destX, destY, + destX + width, destY + height, + 0.0, PIPE_TEX_MIPFILTER_NEAREST, + color_writemask, zs_writemask); pipe_surface_reference(&dest_surface, NULL); /* Restore conditional rendering state. */ @@ -1096,49 +1087,6 @@ fallback: } - -static void -st_CopyTexSubImage1D(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, - struct gl_renderbuffer *rb, - GLint x, GLint y, GLsizei width) -{ - const GLint yoffset = 0, zoffset = 0; - const GLsizei height = 1; - st_copy_texsubimage(ctx, texImage, - xoffset, yoffset, zoffset, /* destX,Y,Z */ - rb, x, y, width, height); /* src X, Y, size */ -} - - -static void -st_CopyTexSubImage2D(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, - struct gl_renderbuffer *rb, - GLint x, GLint y, GLsizei width, GLsizei height) -{ - const GLint zoffset = 0; - st_copy_texsubimage(ctx, texImage, - xoffset, yoffset, zoffset, /* destX,Y,Z */ - rb, x, y, width, height); /* src X, Y, size */ -} - - -static void -st_CopyTexSubImage3D(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - struct gl_renderbuffer *rb, - GLint x, GLint y, GLsizei width, GLsizei height) -{ - st_copy_texsubimage(ctx, texImage, - xoffset, yoffset, zoffset, /* destX,Y,Z */ - rb, x, y, width, height); /* src X, Y, size */ -} - - /** * Copy image data from stImage into the texture object 'stObj' at level * 'dstLevel'. @@ -1163,11 +1111,19 @@ copy_image_data_to_texture(struct st_context *st, /* Copy potentially with the blitter: */ GLuint src_level; - if (stImage->pt != stObj->pt) + if (stImage->pt->last_level == 0) src_level = 0; else src_level = stImage->base.Level; + assert(src_level <= stImage->pt->last_level); + assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width); + assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY || + u_minify(stImage->pt->height0, src_level) == stImage->base.Height); + assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY || + stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY || + u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth); + st_texture_image_copy(st->pipe, stObj->pt, dstLevel, /* dest texture, level */ stImage->pt, src_level, /* src texture, level */ @@ -1342,7 +1298,7 @@ st_AllocTextureStorage(struct gl_context *ctx, GLsizei levels, GLsizei width, GLsizei height, GLsizei depth) { - const GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); struct st_context *st = st_context(ctx); struct st_texture_object *stObj = st_texture_object(texObj); GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings; @@ -1391,6 +1347,57 @@ st_AllocTextureStorage(struct gl_context *ctx, } +static GLboolean +st_TestProxyTexImage(struct gl_context *ctx, GLenum target, + GLint level, gl_format format, + GLint width, GLint height, + GLint depth, GLint border) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + + if (width == 0 || height == 0 || depth == 0) { + /* zero-sized images are legal, and always fit! */ + return GL_TRUE; + } + + if (pipe->screen->can_create_resource) { + /* Ask the gallium driver if the texture is too large */ + struct gl_texture_object *texObj = + _mesa_get_current_tex_object(ctx, target); + struct pipe_resource pt; + + /* Setup the pipe_resource object + */ + memset(&pt, 0, sizeof(pt)); + + pt.target = gl_target_to_pipe(target); + pt.format = st_mesa_format_to_pipe_format(format); + + st_gl_texture_dims_to_pipe_dims(target, + width, height, depth, + &pt.width0, &pt.height0, + &pt.depth0, &pt.array_size); + + if (level == 0 && (texObj->Sampler.MinFilter == GL_LINEAR || + texObj->Sampler.MinFilter == GL_NEAREST)) { + /* assume just one mipmap level */ + pt.last_level = 0; + } + else { + /* assume a full set of mipmaps */ + pt.last_level = _mesa_logbase2(MAX3(width, height, depth)); + } + + return pipe->screen->can_create_resource(pipe->screen, &pt); + } + else { + /* Use core Mesa fallback */ + return _mesa_test_proxy_teximage(ctx, target, level, format, + width, height, depth, border); + } +} + void st_init_texture_functions(struct dd_function_table *functions) @@ -1398,18 +1405,14 @@ st_init_texture_functions(struct dd_function_table *functions) functions->ChooseTextureFormat = st_ChooseTextureFormat; functions->TexImage = st_TexImage; functions->TexSubImage = _mesa_store_texsubimage; - functions->CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; - functions->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; - functions->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; - functions->CopyTexSubImage1D = st_CopyTexSubImage1D; - functions->CopyTexSubImage2D = st_CopyTexSubImage2D; - functions->CopyTexSubImage3D = st_CopyTexSubImage3D; + functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage; + functions->CopyTexSubImage = st_CopyTexSubImage; functions->GenerateMipmap = st_generate_mipmap; functions->GetTexImage = st_GetTexImage; /* compressed texture functions */ - functions->CompressedTexImage2D = st_CompressedTexImage2D; + functions->CompressedTexImage = st_CompressedTexImage; functions->GetCompressedTexImage = _mesa_get_compressed_teximage; functions->NewTextureObject = st_NewTextureObject; @@ -1422,7 +1425,7 @@ st_init_texture_functions(struct dd_function_table *functions) functions->UnmapTextureImage = st_UnmapTextureImage; /* XXX Temporary until we can query pipe's texture sizes */ - functions->TestProxyTexImage = _mesa_test_proxy_teximage; + functions->TestProxyTexImage = st_TestProxyTexImage; functions->AllocTextureStorage = st_AllocTextureStorage; }