summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-12-20 02:09:56 +0100
committerMarek Olšák <[email protected]>2013-01-04 14:06:09 +0100
commit5daba187c987b1fe607d395c70748c6e331f59c4 (patch)
tree32fbca8988409df33b86d3d8f084474a125abc96 /src/mesa
parent0aecb174ce5d2d5c25e1076e8d0cdcb68e9a3b5c (diff)
st/mesa: try to find the format matching format+type in decompressed_with_blit
There was the fast path based on _mesa_format_matches_format_and_type for GetTexImage, but it never worked, because the Mesa format we were testing there was always compressed. Further testing showed that the fast path had been completely broken. In this commit, the somewhat limited helper util_create_rgba_texture is no longer used and instead, custom code for the texture creation is added, which tries to find the best matching RGBA8 format, so that we can hit the fast path *always* if the read format is a variant of RGBA8 and supported by the driver. Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 77d06503d65..28fdaa573f9 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -572,30 +572,61 @@ decompress_with_blit(struct gl_context * ctx,
{
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(texImage->TexObject);
+ struct pipe_screen *screen = pipe->screen;
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
- struct pipe_resource *dst_texture;
+ const GLuint depth = texImage->Depth;
+ struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt;
+ struct pipe_resource *dst;
+ struct pipe_resource dst_templ;
+ enum pipe_format pipe_format;
+ gl_format mesa_format;
+ GLenum gl_target = texImage->TexObject->Target;
+ enum pipe_texture_target pipe_target;
struct pipe_blit_info blit;
unsigned bind = (PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_READ);
struct pipe_transfer *tex_xfer;
ubyte *map;
- /* create temp / dest surface */
- if (!util_create_rgba_texture(pipe, width, height, bind,
- &dst_texture)) {
- _mesa_problem(ctx, "util_create_rgba_texture() failed "
- "in decompress_with_blit()");
+ /* GetTexImage only returns a single face for cubemaps. */
+ if (gl_target == GL_TEXTURE_CUBE_MAP) {
+ gl_target = GL_TEXTURE_2D;
+ }
+
+ pipe_target = gl_target_to_pipe(gl_target);
+
+ /* Find the best match for the format+type combo. */
+ pipe_format = st_choose_format(pipe->screen, GL_RGBA8, format, type,
+ pipe_target, 0, bind);
+ if (pipe_format == PIPE_FORMAT_NONE) {
+ /* unable to get an rgba format!?! */
+ _mesa_problem(ctx, "%s: cannot find a supported format", __func__);
return;
}
- blit.src.resource = stObj->pt;
+ /* create the destination texture */
+ memset(&dst_templ, 0, sizeof(dst_templ));
+ dst_templ.target = pipe_target;
+ dst_templ.format = pipe_format;
+ dst_templ.bind = bind;
+ dst_templ.usage = PIPE_USAGE_STAGING;
+
+ st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
+ &dst_templ.width0, &dst_templ.height0,
+ &dst_templ.depth0, &dst_templ.array_size);
+
+ dst = screen->resource_create(screen, &dst_templ);
+ if (!dst) {
+ _mesa_problem(ctx, "%s: cannot create a temporary texture", __func__);
+ return;
+ }
+
+ blit.src.resource = src;
blit.src.level = texImage->Level;
- blit.src.format = util_format_linear(stObj->pt->format);
- blit.dst.resource = dst_texture;
+ blit.src.format = util_format_linear(src->format);
+ blit.dst.resource = dst;
blit.dst.level = 0;
- blit.dst.format = dst_texture->format;
+ blit.dst.format = dst->format;
blit.src.box.x = blit.dst.box.x = 0;
blit.src.box.y = blit.dst.box.y = 0;
blit.src.box.z = texImage->Face;
@@ -612,19 +643,20 @@ decompress_with_blit(struct gl_context * ctx,
pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
- map = pipe_transfer_map(pipe, dst_texture, 0, 0,
+ map = pipe_transfer_map(pipe, dst, 0, 0,
PIPE_TRANSFER_READ,
0, 0, width, height, &tex_xfer);
if (!map) {
goto end;
}
+ mesa_format = st_pipe_format_to_mesa_format(pipe_format);
+
/* copy/pack data into user buffer */
- if (_mesa_format_matches_format_and_type(stImage->base.TexFormat,
- format, type,
+ if (_mesa_format_matches_format_and_type(mesa_format, format, type,
ctx->Pack.SwapBytes)) {
/* memcpy */
- const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format);
+ const uint bytesPerRow = width * util_format_get_blocksize(pipe_format);
/* map the dst_surface so we can read from it */
GLuint row;
for (row = 0; row < height; row++) {
@@ -633,12 +665,11 @@ decompress_with_blit(struct gl_context * ctx,
memcpy(dest, map, bytesPerRow);
map += tex_xfer->stride;
}
- pipe_transfer_unmap(pipe, tex_xfer);
}
else {
/* format translation via floats */
GLuint row;
- enum pipe_format pformat = util_format_linear(dst_texture->format);
+ enum pipe_format pformat = util_format_linear(dst->format);
GLfloat *rgba;
rgba = malloc(width * 4 * sizeof(GLfloat));
@@ -671,7 +702,7 @@ end:
pipe_transfer_unmap(pipe, tex_xfer);
_mesa_unmap_pbo_dest(ctx, &ctx->Pack);
- pipe_resource_reference(&dst_texture, NULL);
+ pipe_resource_reference(&dst, NULL);
}