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

Loading…
Cancel
Save