[Mesa-dev] [PATCH 6/9] st/mesa: simplify and fix st_GetTexSubImage
Nicolai Hähnle
nhaehnle at gmail.com
Wed Nov 9 15:01:54 UTC 2016
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
By using _mesa_image_address, the code becomes simpler _and_ fixes the bug
that GL_PACK_SKIP_IMAGES was applied even on non-3D textures.
Also, converting a whole slice at a time simplifies the format translation
fallback path.
Fixes parts of GL45-CTS.gtf32.GL3Tests.packed_pixels.packed_pixels_pixelstore.
---
src/mesa/state_tracker/st_cb_texture.c | 71 +++++++++++-----------------------
1 file changed, 23 insertions(+), 48 deletions(-)
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 45f0448..078330f 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -1819,20 +1819,21 @@ st_GetTexSubImage(struct gl_context * ctx,
struct pipe_screen *screen = pipe->screen;
struct st_texture_image *stImage = st_texture_image(texImage);
struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
struct pipe_resource *src = stObj->pt;
struct pipe_resource *dst = NULL;
struct pipe_resource dst_templ;
enum pipe_format dst_format, src_format;
mesa_format mesa_format;
GLenum gl_target = texImage->TexObject->Target;
enum pipe_texture_target pipe_target;
+ unsigned dims;
struct pipe_blit_info blit;
unsigned bind;
struct pipe_transfer *tex_xfer;
ubyte *map = NULL;
boolean done = FALSE;
assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
st_flush_bitmap_cache(st);
@@ -2007,104 +2008,78 @@ st_GetTexSubImage(struct gl_context * ctx,
pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ,
0, 0, 0, width, height, depth, &tex_xfer);
if (!map) {
goto end;
}
mesa_format = st_pipe_format_to_mesa_format(dst_format);
+ dims = _mesa_get_texture_dimensions(gl_target);
/* copy/pack data into user buffer */
if (_mesa_format_matches_format_and_type(mesa_format, format, type,
ctx->Pack.SwapBytes, NULL)) {
/* memcpy */
const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
GLuint row, slice;
for (slice = 0; slice < depth; slice++) {
- if (gl_target == GL_TEXTURE_1D_ARRAY) {
- /* 1D array textures.
- * We need to convert gallium coords to GL coords.
- */
- void *dest = _mesa_image_address3d(&ctx->Pack, pixels,
- width, depth, format,
- type, 0, slice, 0);
+ ubyte *slice_map = map;
+
+ for (row = 0; row < height; row++) {
+ void *dest = _mesa_image_address(dims, &ctx->Pack, pixels,
+ width, height, format, type,
+ slice, row, 0);
+
memcpy(dest, map, bytesPerRow);
- }
- else {
- ubyte *slice_map = map;
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address3d(&ctx->Pack, pixels,
- width, height, format,
- type, slice, row, 0);
- memcpy(dest, slice_map, bytesPerRow);
- slice_map += tex_xfer->stride;
- }
+ slice_map += tex_xfer->stride;
}
+
map += tex_xfer->layer_stride;
}
}
else {
/* format translation via floats */
- GLuint row, slice;
+ GLuint slice;
GLfloat *rgba;
uint32_t dstMesaFormat;
int dstStride, srcStride;
assert(util_format_is_compressed(src->format));
- rgba = malloc(width * 4 * sizeof(GLfloat));
+ rgba = malloc(width * height * 4 * sizeof(GLfloat));
if (!rgba) {
goto end;
}
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback format translation\n", __func__);
dstMesaFormat = _mesa_format_from_format_and_type(format, type);
dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type);
srcStride = 4 * width * sizeof(GLfloat);
for (slice = 0; slice < depth; slice++) {
- if (gl_target == GL_TEXTURE_1D_ARRAY) {
- /* 1D array textures.
- * We need to convert gallium coords to GL coords.
- */
- void *dest = _mesa_image_address3d(&ctx->Pack, pixels,
- width, depth, format,
- type, 0, slice, 0);
+ void *dest = _mesa_image_address(dims, &ctx->Pack, pixels,
+ width, height, format, type,
+ slice, 0, 0);
- /* get float[4] rgba row from surface */
- pipe_get_tile_rgba_format(tex_xfer, map, 0, 0, width, 1,
- dst_format, rgba);
+ /* get float[4] rgba row from surface */
+ pipe_get_tile_rgba_format(tex_xfer, map, 0, 0, width, height,
+ dst_format, rgba);
+
+ _mesa_format_convert(dest, dstMesaFormat, dstStride,
+ rgba, RGBA32_FLOAT, srcStride,
+ width, height, NULL);
- _mesa_format_convert(dest, dstMesaFormat, dstStride,
- rgba, RGBA32_FLOAT, srcStride,
- width, 1, NULL);
- }
- else {
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address3d(&ctx->Pack, pixels,
- width, height, format,
- type, slice, row, 0);
-
- /* get float[4] rgba row from surface */
- pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1,
- dst_format, rgba);
-
- _mesa_format_convert(dest, dstMesaFormat, dstStride,
- rgba, RGBA32_FLOAT, srcStride,
- width, 1, NULL);
- }
- }
map += tex_xfer->layer_stride;
}
free(rgba);
}
done = TRUE;
end:
if (map)
pipe_transfer_unmap(pipe, tex_xfer);
--
2.7.4
More information about the mesa-dev
mailing list