diff options
Diffstat (limited to 'mesalib/src/gallium')
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_range.h | 89 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_surface.c | 55 |
2 files changed, 135 insertions, 9 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_range.h b/mesalib/src/gallium/auxiliary/util/u_range.h new file mode 100644 index 000000000..4b1d0d1be --- /dev/null +++ b/mesalib/src/gallium/auxiliary/util/u_range.h @@ -0,0 +1,89 @@ +/* + * Copyright 2013 Marek Olšák <maraeo@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/** + * @file + * 1D integer range, capable of the union and intersection operations. + * + * It only maintains a single interval which is extended when the union is + * done. This implementation is partially thread-safe (readers are not + * protected by a lock). + * + * @author Marek Olšák + */ + +#ifndef U_RANGE_H +#define U_RANGE_H + +#include "os/os_thread.h" + +struct util_range { + unsigned start; /* inclusive */ + unsigned end; /* exclusive */ + + /* for the range to be consistent with multiple contexts: */ + pipe_mutex write_mutex; +}; + + +static INLINE void +util_range_set_empty(struct util_range *range) +{ + range->start = ~0; + range->end = 0; +} + +/* This is like a union of two sets. */ +static INLINE void +util_range_add(struct util_range *range, unsigned start, unsigned end) +{ + if (start < range->start || end > range->end) { + pipe_mutex_lock(range->write_mutex); + range->start = MIN2(start, range->start); + range->end = MAX2(end, range->end); + pipe_mutex_unlock(range->write_mutex); + } +} + +static INLINE boolean +util_ranges_intersect(struct util_range *range, unsigned start, unsigned end) +{ + return MAX2(start, range->start) < MIN2(end, range->end); +} + + +/* Init/deinit */ + +static INLINE void +util_range_init(struct util_range *range) +{ + pipe_mutex_init(range->write_mutex); + util_range_set_empty(range); +} + +static INLINE void +util_range_destroy(struct util_range *range) +{ + pipe_mutex_destroy(range->write_mutex); +} + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.c b/mesalib/src/gallium/auxiliary/util/u_surface.c index b948b46d2..5c3a655d6 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surface.c +++ b/mesalib/src/gallium/auxiliary/util/u_surface.c @@ -322,21 +322,58 @@ util_clear_render_target(struct pipe_context *pipe, assert(dst->texture); if (!dst->texture) return; - /* XXX: should handle multiple layers */ - dst_map = pipe_transfer_map(pipe, - dst->texture, - dst->u.tex.level, - dst->u.tex.first_layer, - PIPE_TRANSFER_WRITE, - dstx, dsty, width, height, &dst_trans); + + if (dst->texture->target == PIPE_BUFFER) { + /* + * The fill naturally works on the surface format, however + * the transfer uses resource format which is just bytes for buffers. + */ + unsigned dx, w; + unsigned pixstride = util_format_get_blocksize(dst->format); + dx = (dst->u.buf.first_element + dstx) * pixstride; + w = width * pixstride; + dst_map = pipe_transfer_map(pipe, + dst->texture, + 0, 0, + PIPE_TRANSFER_WRITE, + dx, 0, w, 1, + &dst_trans); + } + else { + /* XXX: should handle multiple layers */ + dst_map = pipe_transfer_map(pipe, + dst->texture, + dst->u.tex.level, + dst->u.tex.first_layer, + PIPE_TRANSFER_WRITE, + dstx, dsty, width, height, &dst_trans); + + } assert(dst_map); if (dst_map) { + enum pipe_format format = dst->format; assert(dst_trans->stride > 0); - util_pack_color(color->f, dst->texture->format, &uc); - util_fill_rect(dst_map, dst->texture->format, + if (util_format_is_pure_integer(format)) { + /* + * We expect int/uint clear values here, though some APIs + * might disagree (but in any case util_pack_color() + * couldn't handle it)... + */ + if (util_format_is_pure_sint(format)) { + util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1); + } + else { + assert(util_format_is_pure_uint(format)); + util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1); + } + } + else { + util_pack_color(color->f, dst->format, &uc); + } + util_fill_rect(dst_map, dst->format, dst_trans->stride, 0, 0, width, height, &uc); |