vrend: use the row-stride when directly reading back to an IOV

When guest mesa does a glReadPixel call, it expects the data to be placed
with correct row strides into the readback buffer. While for calls that
invert or require more then one IOV this is done in write_transfer_data,
for a read that only uses a small area and offset making it fit into the
first IOV this was not done. Consequently, in this case configure the
PACK_ROW_LENGTH accordingly.

v2: fix whitespace issues

This fixes a number of piglits:
   arb_copy_image-targets (for texture_2d source or dest, non-compressed)
   arb_get_texture_multisample/sample_position
   arb_texture_rectangle/fbo-blit rect
   arb_get_texture__sub_image-cubemap

Reviewed-by: Elie Tournier <elie.tournier@collabora.com>
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Signed-off-by: Jakob Bornecrantz <jakob@collabora.com>
macos/master
Gert Wollny 6 years ago committed by Jakob Bornecrantz
parent 34809ef704
commit 42e2a4ca7d
  1. 9
      src/vrend_renderer.c

@ -5908,6 +5908,7 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
uint32_t h = u_minify(res->base.height0, info->level); uint32_t h = u_minify(res->base.height0, info->level);
int elsize = util_format_get_blocksize(res->base.format); int elsize = util_format_get_blocksize(res->base.format);
float depth_scale; float depth_scale;
int row_stride = info->stride;
vrend_use_program(ctx, 0); vrend_use_program(ctx, 0);
@ -5933,6 +5934,8 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
} else { } else {
send_size = iov[0].iov_len - info->offset; send_size = iov[0].iov_len - info->offset;
data = myptr; data = myptr;
if (!row_stride)
row_stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, info->level));
} }
if (res->readback_fb_id == 0 || (int)res->readback_fb_level != info->level || if (res->readback_fb_id == 0 || (int)res->readback_fb_level != info->level ||
@ -5960,8 +5963,8 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
glPixelStorei(GL_PACK_INVERT_MESA, 1); glPixelStorei(GL_PACK_INVERT_MESA, 1);
if (!vrend_format_is_ds(res->base.format)) if (!vrend_format_is_ds(res->base.format))
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
if (!need_temp && info->stride) if (!need_temp && row_stride)
glPixelStorei(GL_PACK_ROW_LENGTH, info->stride / elsize); glPixelStorei(GL_PACK_ROW_LENGTH, row_stride);
switch (elsize) { switch (elsize) {
case 1: case 1:
@ -6032,7 +6035,7 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
} }
if (has_feature(feat_mesa_invert) && actually_invert) if (has_feature(feat_mesa_invert) && actually_invert)
glPixelStorei(GL_PACK_INVERT_MESA, 0); glPixelStorei(GL_PACK_INVERT_MESA, 0);
if (!need_temp && info->stride) if (!need_temp && row_stride)
glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4);
if (need_temp) { if (need_temp) {

Loading…
Cancel
Save