vrend: Use the transfer layer stride for transfers to the host

This is required to be able to properly handle transfers with
data layouts that are different from the resource layout.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
macos/master
Alexandros Frantzis 6 years ago committed by Gurchetan Singh
parent 0bb764b6cf
commit 23ccf5c1a9
  1. 41
      src/vrend_renderer.c

@ -6284,22 +6284,22 @@ static void vrend_scale_depth(void *ptr, int size, float scale_val)
}
}
static void read_transfer_data(struct pipe_resource *res,
struct iovec *iov,
static void read_transfer_data(struct iovec *iov,
unsigned int num_iovs,
char *data,
enum pipe_format format,
uint64_t offset,
uint32_t src_stride,
uint32_t src_layer_stride,
struct pipe_box *box,
uint32_t level,
uint64_t offset,
bool invert)
{
int blsize = util_format_get_blocksize(res->format);
int blsize = util_format_get_blocksize(format);
uint32_t size = vrend_get_iovec_size(iov, num_iovs);
uint32_t send_size = util_format_get_nblocks(res->format, box->width,
uint32_t send_size = util_format_get_nblocks(format, box->width,
box->height) * blsize * box->depth;
uint32_t bwx = util_format_get_nblocksx(res->format, box->width) * blsize;
int32_t bh = util_format_get_nblocksy(res->format, box->height);
uint32_t bwx = util_format_get_nblocksx(format, box->width) * blsize;
int32_t bh = util_format_get_nblocksy(format, box->height);
int d, h;
if ((send_size == size || bh == 1) && !invert && box->depth == 1)
@ -6307,7 +6307,7 @@ static void read_transfer_data(struct pipe_resource *res,
else {
if (invert) {
for (d = 0; d < box->depth; d++) {
uint32_t myoffset = offset + d * src_stride * u_minify(res->height0, level);
uint32_t myoffset = offset + d * src_layer_stride;
for (h = bh - 1; h >= 0; h--) {
void *ptr = data + (h * bwx) + d * (bh * bwx);
vrend_read_from_iovec(iov, num_iovs, myoffset, ptr, bwx);
@ -6316,7 +6316,7 @@ static void read_transfer_data(struct pipe_resource *res,
}
} else {
for (d = 0; d < box->depth; d++) {
uint32_t myoffset = offset + d * src_stride * u_minify(res->height0, level);
uint32_t myoffset = offset + d * src_layer_stride;
for (h = 0; h < bh; h++) {
void *ptr = data + (h * bwx) + d * (bh * bwx);
vrend_read_from_iovec(iov, num_iovs, myoffset, ptr, bwx);
@ -6561,6 +6561,7 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
float depth_scale;
GLuint send_size = 0;
uint32_t stride = info->stride;
uint32_t layer_stride = info->layer_stride;
if (ctx)
vrend_use_program(ctx, 0);
@ -6570,6 +6571,10 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
if (!stride)
stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, info->level)) * elsize;
if (!layer_stride)
layer_stride = util_format_get_2d_size(res->base.format, stride,
u_minify(res->base.height0, info->level));
compressed = util_format_is_compressed(res->base.format);
if (num_iovs > 1 || compressed) {
need_temp = true;
@ -6587,15 +6592,15 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
data = malloc(send_size);
if (!data)
return ENOMEM;
read_transfer_data(&res->base, iov, num_iovs, data, stride,
info->box, info->level, info->offset, invert);
read_transfer_data(iov, num_iovs, data, res->base.format, info->offset,
stride, layer_stride, info->box, invert);
} else {
data = (char*)iov[0].iov_base + info->offset;
}
if (stride && !need_temp) {
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / elsize);
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, u_minify(res->base.height0, info->level));
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, layer_stride / stride);
} else
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@ -7434,7 +7439,7 @@ static void vrend_resource_copy_fallback(struct vrend_resource *src_res,
const struct pipe_box *src_box)
{
char *tptr;
uint32_t total_size, src_stride, dst_stride;
uint32_t total_size, src_stride, dst_stride, src_layer_stride;
GLenum glformat, gltype;
int elsize = util_format_get_blocksize(dst_res->base.format);
int compressed = util_format_is_compressed(dst_res->base.format);
@ -7483,8 +7488,12 @@ static void vrend_resource_copy_fallback(struct vrend_resource *src_res,
src_stride = util_format_get_nblocksx(src_res->base.format,
u_minify(src_res->base.width0, src_level)) * elsize;
read_transfer_data(&src_res->base, src_res->iov, src_res->num_iovs, tptr,
src_stride, &box, src_level, src_offset, false);
src_layer_stride = util_format_get_2d_size(src_res->base.format,
src_stride,
u_minify(src_res->base.height0, src_level));
read_transfer_data(src_res->iov, src_res->num_iovs, tptr,
src_res->base.format, src_offset,
src_stride, src_layer_stride, &box, false);
/* When on GLES sync the iov that backs the dst resource because
* we might need it in a chain copy A->B, B->C */
write_transfer_data(&dst_res->base, dst_res->iov, dst_res->num_iovs, tptr,

Loading…
Cancel
Save