diff options
Diffstat (limited to 'src/gallium/auxiliary/util/u_surface.c')
-rw-r--r-- | src/gallium/auxiliary/util/u_surface.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 5b42afd0dab..b17dd74fd37 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -116,6 +116,130 @@ util_create_rgba_texture(struct pipe_context *pipe, /** + * Copy 2D rect from one place to another. + * Position and sizes are in pixels. + * src_stride may be negative to do vertical flip of pixels from source. + */ +void +util_copy_rect(ubyte * dst, + enum pipe_format format, + unsigned dst_stride, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + const ubyte * src, + int src_stride, + unsigned src_x, + unsigned src_y) +{ + unsigned i; + int src_stride_pos = src_stride < 0 ? -src_stride : src_stride; + int blocksize = util_format_get_blocksize(format); + int blockwidth = util_format_get_blockwidth(format); + int blockheight = util_format_get_blockheight(format); + + assert(blocksize > 0); + assert(blockwidth > 0); + assert(blockheight > 0); + + dst_x /= blockwidth; + dst_y /= blockheight; + width = (width + blockwidth - 1)/blockwidth; + height = (height + blockheight - 1)/blockheight; + src_x /= blockwidth; + src_y /= blockheight; + + dst += dst_x * blocksize; + src += src_x * blocksize; + dst += dst_y * dst_stride; + src += src_y * src_stride_pos; + width *= blocksize; + + if (width == dst_stride && width == src_stride) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_stride; + src += src_stride; + } + } +} + + +void +util_fill_rect(ubyte * dst, + enum pipe_format format, + unsigned dst_stride, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + union util_color *uc) +{ + const struct util_format_description *desc = util_format_description(format); + unsigned i, j; + unsigned width_size; + int blocksize = desc->block.bits / 8; + int blockwidth = desc->block.width; + int blockheight = desc->block.height; + + assert(blocksize > 0); + assert(blockwidth > 0); + assert(blockheight > 0); + + dst_x /= blockwidth; + dst_y /= blockheight; + width = (width + blockwidth - 1)/blockwidth; + height = (height + blockheight - 1)/blockheight; + + dst += dst_x * blocksize; + dst += dst_y * dst_stride; + width_size = width * blocksize; + + switch (blocksize) { + case 1: + if(dst_stride == width_size) + memset(dst, uc->ub, height * width_size); + else { + for (i = 0; i < height; i++) { + memset(dst, uc->ub, width_size); + dst += dst_stride; + } + } + break; + case 2: + for (i = 0; i < height; i++) { + uint16_t *row = (uint16_t *)dst; + for (j = 0; j < width; j++) + *row++ = uc->us; + dst += dst_stride; + } + break; + case 4: + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst; + for (j = 0; j < width; j++) + *row++ = uc->ui; + dst += dst_stride; + } + break; + default: + for (i = 0; i < height; i++) { + ubyte *row = dst; + for (j = 0; j < width; j++) { + memcpy(row, uc, blocksize); + row += blocksize; + } + dst += dst_stride; + } + break; + } +} + + +/** * Fallback function for pipe->resource_copy_region(). * Note: (X,Y)=(0,0) is always the upper-left corner. */ |