diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_blit.c | 115 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_blit.h | 9 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_texcopy.c | 12 | 
3 files changed, 113 insertions, 23 deletions
| diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index d03fbfa07d..ea626d942d 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -389,14 +389,49 @@ static GLboolean validate_buffers(struct r300_context *r300,      return GL_TRUE;  } +/** + * Calculate texcoords for given image region. + * Output values are [minx, maxx, miny, maxy] + */ +static void calc_tex_coords(float img_width, float img_height, +                            float x, float y, +                            float reg_width, float reg_height, +                            unsigned flip_y, float *buf) +{ +    buf[0] = x / img_width; +    buf[1] = buf[0] + reg_width / img_width; +    buf[2] = y / img_height; +    buf[3] = buf[2] + reg_height / img_height; +    if (flip_y) +    { +        float tmp = buf[2]; +        buf[2] = 1.0 - buf[3]; +        buf[3] = 1.0 - tmp; +    } +} +  static void emit_draw_packet(struct r300_context *r300, -                             float src_width, float src_height, -                             float dst_width, float dst_height) +                             unsigned src_width, unsigned src_height, +                             unsigned src_x_offset, unsigned src_y_offset, +                             unsigned dst_x_offset, unsigned dst_y_offset, +                             unsigned reg_width, unsigned reg_height, +                             unsigned flip_y)  { -    float verts[] = { 0.0, 0.0, 0.0, 1.0, -                      0.0, dst_height, 0.0, 1.0 - dst_height/src_height, -                      dst_width, dst_height, dst_width/src_width, 1.0 - dst_height/src_height, -                      dst_width, 0.0, dst_width/src_width, 1.0 }; +    float texcoords[4]; + +    calc_tex_coords(src_width, src_height, +                    src_x_offset, src_y_offset, +                    reg_width, reg_height, +                    flip_y, texcoords); + +    float verts[] = { dst_x_offset, dst_y_offset, +                      texcoords[0], texcoords[3], +                      dst_x_offset, dst_y_offset + reg_height, +                      texcoords[0], texcoords[2], +                      dst_x_offset + reg_width, dst_y_offset + reg_height, +                      texcoords[1], texcoords[2], +                      dst_x_offset + reg_width, dst_y_offset, +                      texcoords[1], texcoords[3] };      BATCH_LOCALS(&r300->radeon); @@ -461,6 +496,30 @@ static void emit_cb_setup(struct r300_context *r300,      END_BATCH();  } +/** + * Copy a region of [@a width x @a height] pixels from source buffer + * to destination buffer. + * @param[in] r300 r300 context + * @param[in] src_bo source radeon buffer object + * @param[in] src_offset offset of the source image in the @a src_bo + * @param[in] src_mesaformat source image format + * @param[in] src_pitch aligned source image width + * @param[in] src_width source image width + * @param[in] src_height source image height + * @param[in] src_x_offset x offset in the source image + * @param[in] src_y_offset y offset in the source image + * @param[in] dst_bo destination radeon buffer object + * @param[in] dst_offset offset of the destination image in the @a dst_bo + * @param[in] dst_mesaformat destination image format + * @param[in] dst_pitch aligned destination image width + * @param[in] dst_width destination image width + * @param[in] dst_height destination image height + * @param[in] dst_x_offset x offset in the destination image + * @param[in] dst_y_offset y offset in the destination image + * @param[in] width region width + * @param[in] height region height + * @param[in] flip_y set if y coords of the source image need to be flipped + */  GLboolean r300_blit(struct r300_context *r300,                      struct radeon_bo *src_bo,                      intptr_t src_offset, @@ -468,30 +527,48 @@ GLboolean r300_blit(struct r300_context *r300,                      unsigned src_pitch,                      unsigned src_width,                      unsigned src_height, +                    unsigned src_x_offset, +                    unsigned src_y_offset,                      struct radeon_bo *dst_bo,                      intptr_t dst_offset,                      gl_format dst_mesaformat,                      unsigned dst_pitch,                      unsigned dst_width, -                    unsigned dst_height) +                    unsigned dst_height, +                    unsigned dst_x_offset, +                    unsigned dst_y_offset, +                    unsigned reg_width, +                    unsigned reg_height, +                    unsigned flip_y)  { -    /* Need to clamp the destination size to make sure -     * we don't write outside of the buffer +    /* Need to clamp the region size to make sure +     * we don't read outside of the source buffer +     * or write outside of the destination buffer.       */ -    dst_width = MIN2(dst_width, src_width); -    dst_height = MIN2(src_height, dst_height); +    if (reg_width + src_x_offset > src_width) +        reg_width = src_width - src_x_offset; +    if (reg_height + src_y_offset > src_height) +        reg_height = src_height - src_y_offset; +    if (reg_width + dst_x_offset > dst_width) +        reg_width = dst_width - dst_x_offset; +    if (reg_height + dst_y_offset > dst_height) +        reg_height = dst_height - dst_y_offset;      if (src_bo == dst_bo) {          return GL_FALSE;      }      if (0) { -        fprintf(stderr, "src: width %d, height %d, pitch %d, format %s\n", +        fprintf(stderr, "src: size [%d x %d], pitch %d, " +                "offset [%d x %d], format %s, bo %p\n",                  src_width, src_height, src_pitch, -                _mesa_get_format_name(src_mesaformat)); -        fprintf(stderr, "dst: width %d, height %d, pitch %d, format %s\n", -                dst_width, dst_height, dst_pitch, -                _mesa_get_format_name(dst_mesaformat)); +                src_offset, src_y_offset, +                _mesa_get_format_name(src_mesaformat), +                src_bo); +        fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n", +                dst_pitch, dst_x_offset, dst_y_offset, +                _mesa_get_format_name(dst_mesaformat), dst_bo); +        fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);      }      if (!validate_buffers(r300, src_bo, dst_bo)) @@ -516,7 +593,11 @@ GLboolean r300_blit(struct r300_context *r300,      emit_cb_setup(r300, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height); -    emit_draw_packet(r300, src_width, src_height, dst_width, dst_height); +    emit_draw_packet(r300, src_width, src_height, +                     src_x_offset, src_y_offset, +                     dst_x_offset, dst_y_offset, +                     reg_width, reg_height, +                     flip_y);      r300EmitCacheFlush(r300); diff --git a/src/mesa/drivers/dri/r300/r300_blit.h b/src/mesa/drivers/dri/r300/r300_blit.h index 28ffd4ea42..dc21e88098 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.h +++ b/src/mesa/drivers/dri/r300/r300_blit.h @@ -37,11 +37,18 @@ GLboolean r300_blit(struct r300_context *r300,                      unsigned src_pitch,                      unsigned src_width,                      unsigned src_height, +                    unsigned src_x_offset, +                    unsigned src_y_offset,                      struct radeon_bo *dst_bo,                      intptr_t dst_offset,                      gl_format dst_mesaformat,                      unsigned dst_pitch,                      unsigned dst_width, -                    unsigned dst_height); +                    unsigned dst_height, +                    unsigned dst_x_offset, +                    unsigned dst_y_offset, +                    unsigned width, +                    unsigned height, +                    unsigned flip_y);  #endif // R300_BLIT_H
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/r300_texcopy.c b/src/mesa/drivers/dri/r300/r300_texcopy.c index 893c8586f7..ebc9c05b8a 100644 --- a/src/mesa/drivers/dri/r300/r300_texcopy.c +++ b/src/mesa/drivers/dri/r300/r300_texcopy.c @@ -37,6 +37,8 @@  #include "r300_blit.h"  #include <main/debug.h> +// TODO: +// need to pass correct pitch for small dst textures!  static GLboolean  do_copy_texsubimage(GLcontext *ctx,                      GLenum target, GLint level, @@ -64,10 +66,8 @@ do_copy_texsubimage(GLcontext *ctx,      assert(timg->base.Width >= dstx + width);      assert(timg->base.Height >= dsty + height); -    intptr_t src_offset = rrb->draw_offset + x * rrb->cpp + y * rrb->pitch; +    intptr_t src_offset = rrb->draw_offset;      intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, _mesa_tex_target_to_face(target), level); -    dst_offset += dstx * _mesa_get_format_bytes(timg->base.TexFormat) + -                  dsty * _mesa_format_row_stride(timg->base.TexFormat, timg->base.Width);      if (src_offset % 32 || dst_offset % 32) {          return GL_FALSE; @@ -85,8 +85,10 @@ do_copy_texsubimage(GLcontext *ctx,      /* blit from src buffer to texture */      return r300_blit(r300, rrb->bo, src_offset, rrb->base.Format, rrb->pitch/rrb->cpp, -                     rrb->base.Width, rrb->base.Height, timg->mt->bo ? timg->mt->bo : timg->bo, dst_offset, -                     timg->base.TexFormat, timg->base.Width, width, height); +                     rrb->base.Width, rrb->base.Height, x, y, +                     timg->mt->bo, dst_offset, timg->base.TexFormat, +                     timg->base.Width, timg->base.Width, timg->base.Height, +                     dstx, dsty, width, height, 1);  }  static void | 
