renderer: fix compressed transfer gets

This code ended up in the other file and really wasn't necessary
there.

Remove the transfer code from virglrenderer.c, move into main
renderer file, and match it with the corresponding transfer
reader.

This should at least fix the crash in compressed textures
with ARB_get_texture_sub_image
macos/master
Dave Airlie 9 years ago
parent 94a415e3c7
commit 4385520930
  1. 38
      src/virglrenderer.c
  2. 71
      src/vrend_renderer.c
  3. 12
      src/vrend_renderer.h

@ -188,44 +188,6 @@ static void *dev_cookie;
static struct vrend_if_cbs virgl_cbs; static struct vrend_if_cbs virgl_cbs;
void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset,
struct iovec *iov, int num_iovs)
{
vrend_write_to_iovec(iov, num_iovs, offset, data, bytes);
}
void vrend_transfer_write_tex_return(struct pipe_resource *res,
struct pipe_box *box,
uint32_t level,
uint32_t dst_stride,
uint64_t offset,
struct iovec *iov,
int num_iovs,
void *myptr, int size, int invert)
{
int elsize = util_format_get_blocksize(res->format);
int h;
uint32_t myoffset = offset;
uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * elsize;
// uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, box->width) * elsize;
if (!invert && (stride == util_format_get_nblocksx(res->format, box->width) * elsize))
vrend_write_to_iovec(iov, num_iovs, offset, myptr, size);
else if (invert) {
for (h = box->height - 1; h >= 0; h--) {
void *sptr = myptr + (h * elsize * box->width);
vrend_write_to_iovec(iov, num_iovs, myoffset, sptr, box->width * elsize);
myoffset += stride;
}
} else {
for (h = 0; h < box->height; h++) {
void *sptr = myptr + (h * elsize * box->width);
vrend_write_to_iovec(iov, num_iovs, myoffset, sptr, box->width * elsize);
myoffset += stride;
}
}
}
static void virgl_write_fence(uint32_t fence_id) static void virgl_write_fence(uint32_t fence_id)
{ {
rcbs->write_fence(dev_cookie, fence_id); rcbs->write_fence(dev_cookie, fence_id);

@ -3904,7 +3904,7 @@ static void vrend_scale_depth(void *ptr, int size, float scale_val)
} }
} }
static void copy_transfer_data(struct pipe_resource *res, static void read_transfer_data(struct pipe_resource *res,
struct iovec *iov, struct iovec *iov,
unsigned int num_iovs, unsigned int num_iovs,
void *data, void *data,
@ -3913,11 +3913,11 @@ static void copy_transfer_data(struct pipe_resource *res,
uint64_t offset, bool invert) uint64_t offset, bool invert)
{ {
int blsize = util_format_get_blocksize(res->format); int blsize = util_format_get_blocksize(res->format);
GLuint size = vrend_get_iovec_size(iov, num_iovs); uint32_t size = vrend_get_iovec_size(iov, num_iovs);
GLuint send_size = util_format_get_nblocks(res->format, box->width, uint32_t send_size = util_format_get_nblocks(res->format, box->width,
box->height) * blsize * box->depth; box->height) * blsize * box->depth;
GLuint bwx = util_format_get_nblocksx(res->format, box->width) * blsize; uint32_t bwx = util_format_get_nblocksx(res->format, box->width) * blsize;
GLuint bh = util_format_get_nblocksy(res->format, box->height); uint32_t bh = util_format_get_nblocksy(res->format, box->height);
int h; int h;
uint32_t myoffset = offset; uint32_t myoffset = offset;
@ -3940,6 +3940,43 @@ static void copy_transfer_data(struct pipe_resource *res,
} }
} }
static void write_transfer_data(struct pipe_resource *res,
struct iovec *iov,
unsigned num_iovs,
void *data,
uint32_t dst_stride,
struct pipe_box *box,
uint32_t level,
uint64_t offset,
bool invert)
{
int blsize = util_format_get_blocksize(res->format);
uint32_t size = vrend_get_iovec_size(iov, num_iovs);
uint32_t send_size = util_format_get_nblocks(res->format, box->width,
box->height) * blsize * box->depth;
uint32_t bwx = util_format_get_nblocksx(res->format, box->width) * blsize;
uint32_t bh = util_format_get_nblocksy(res->format, box->height);
int h;
uint32_t myoffset = offset;
uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * blsize;
if ((send_size == size || bh == 1) && !invert) {
vrend_write_to_iovec(iov, num_iovs, offset, data, send_size);
} else if (invert) {
for (h = bh - 1; h >= 0; h--) {
void *ptr = data + (h * bwx);
vrend_write_to_iovec(iov, num_iovs, myoffset, ptr, bwx);
myoffset += stride;
}
} else {
for (h = 0; h < bh; h++) {
void *ptr = data + (h * bwx);
vrend_write_to_iovec(iov, num_iovs, myoffset, ptr, bwx);
myoffset += stride;
}
}
}
static bool check_transfer_bounds(struct vrend_resource *res, static bool check_transfer_bounds(struct vrend_resource *res,
const struct vrend_transfer_info *info) const struct vrend_transfer_info *info)
{ {
@ -4103,7 +4140,7 @@ 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;
copy_transfer_data(&res->base, iov, num_iovs, data, stride, read_transfer_data(&res->base, iov, num_iovs, data, stride,
info->box, info->offset, invert); info->box, info->offset, invert);
} else { } else {
data = iov[0].iov_base + info->offset; data = iov[0].iov_base + info->offset;
@ -4246,7 +4283,7 @@ static int vrend_transfer_send_getteximage(struct vrend_context *ctx,
const struct vrend_transfer_info *info) const struct vrend_transfer_info *info)
{ {
GLenum format, type; GLenum format, type;
uint32_t send_size, tex_size; uint32_t tex_size;
void *data; void *data;
int elsize = util_format_get_blocksize(res->base.format); int elsize = util_format_get_blocksize(res->base.format);
int compressed = util_format_is_compressed(res->base.format); int compressed = util_format_is_compressed(res->base.format);
@ -4266,8 +4303,6 @@ static int vrend_transfer_send_getteximage(struct vrend_context *ctx,
tex_size = util_format_get_nblocks(res->base.format, u_minify(res->base.width0, info->level), u_minify(res->base.height0, info->level)) * util_format_get_blocksize(res->base.format) * depth; tex_size = util_format_get_nblocks(res->base.format, u_minify(res->base.width0, info->level), u_minify(res->base.height0, info->level)) * util_format_get_blocksize(res->base.format) * depth;
send_size = util_format_get_nblocks(res->base.format, info->box->width, info->box->height) * util_format_get_blocksize(res->base.format) * info->box->depth;
if (info->box->z && res->target != GL_TEXTURE_CUBE_MAP) { if (info->box->z && res->target != GL_TEXTURE_CUBE_MAP) {
send_offset = util_format_get_nblocks(res->base.format, u_minify(res->base.width0, info->level), u_minify(res->base.height0, info->level)) * util_format_get_blocksize(res->base.format) * info->box->z; send_offset = util_format_get_nblocks(res->base.format, u_minify(res->base.width0, info->level), u_minify(res->base.height0, info->level)) * util_format_get_blocksize(res->base.format) * info->box->z;
} }
@ -4312,9 +4347,9 @@ static int vrend_transfer_send_getteximage(struct vrend_context *ctx,
glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4);
vrend_transfer_write_tex_return(&res->base, info->box, info->level, write_transfer_data(&res->base, iov, num_iovs, data + send_offset,
info->stride, info->offset, iov, num_iovs, info->stride, info->box, info->level, info->offset,
data + send_offset, send_size, FALSE); false);
free(data); free(data);
return 0; return 0;
} }
@ -4351,7 +4386,7 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
need_temp = 1; need_temp = 1;
if (need_temp) { if (need_temp) {
send_size = info->box->width * info->box->height * info->box->depth * util_format_get_blocksize(res->base.format); send_size = util_format_get_nblocks(res->base.format, info->box->width, info->box->height) * info->box->depth * util_format_get_blocksize(res->base.format);
data = malloc(send_size); data = malloc(send_size);
if (!data) { if (!data) {
fprintf(stderr,"malloc failed %d\n", send_size); fprintf(stderr,"malloc failed %d\n", send_size);
@ -4431,9 +4466,9 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
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) {
vrend_transfer_write_tex_return(&res->base, info->box, info->level, write_transfer_data(&res->base, iov, num_iovs, data,
info->stride, info->offset, iov, num_iovs, info->stride, info->box, info->level, info->offset,
data, send_size, separate_invert); separate_invert);
free(data); free(data);
} }
return 0; return 0;
@ -4446,7 +4481,7 @@ static int vrend_renderer_transfer_send_iov(struct vrend_context *ctx,
{ {
if (res->target == 0 && res->ptr) { if (res->target == 0 && res->ptr) {
uint32_t send_size = info->box->width * util_format_get_blocksize(res->base.format); uint32_t send_size = info->box->width * util_format_get_blocksize(res->base.format);
vrend_transfer_write_return(res->ptr + info->box->x, send_size, info->offset, iov, num_iovs); vrend_write_to_iovec(iov, num_iovs, info->offset, res->ptr + info->box->x, send_size);
return 0; return 0;
} }
@ -4463,7 +4498,7 @@ static int vrend_renderer_transfer_send_iov(struct vrend_context *ctx,
if (!data) if (!data)
fprintf(stderr,"unable to open buffer for reading %d\n", res->target); fprintf(stderr,"unable to open buffer for reading %d\n", res->target);
else else
vrend_transfer_write_return(data, send_size, info->offset, iov, num_iovs); vrend_write_to_iovec(iov, num_iovs, info->offset, data, send_size);
glUnmapBuffer(res->target); glUnmapBuffer(res->target);
} else { } else {
bool can_readpixels = true; bool can_readpixels = true;

@ -275,18 +275,6 @@ void vrend_set_uniform_buffer(struct vrend_context *ctx, uint32_t shader,
uint32_t index, uint32_t offset, uint32_t length, uint32_t index, uint32_t offset, uint32_t length,
uint32_t res_handle); uint32_t res_handle);
void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset,
struct iovec *iov, int iovec_cnt);
void vrend_transfer_write_tex_return(struct pipe_resource *res,
struct pipe_box *box,
uint32_t level,
uint32_t dst_stride,
uint64_t offset,
struct iovec *iov,
int num_iovs,
void *myptr, int size, int invert);
void vrend_renderer_fini(void); void vrend_renderer_fini(void);
int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw); int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw);

Loading…
Cancel
Save