From b47d13f4255b9708ff52fa80c11fabe53540cdea Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 7 Jun 2013 21:10:59 +0200 Subject: [PATCH] util: fix util_clear_render_target and util_clear_depth_stencil layer handling These functions must clear all bound layers, not just the first. Reviewed-by: Jose Fonseca Reviewed-by: Brian Paul --- src/gallium/auxiliary/util/u_surface.c | 190 ++++++++++++++----------- 1 file changed, 103 insertions(+), 87 deletions(-) diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 5c3a655d628..77d04ba7244 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -307,6 +307,7 @@ no_src_map: * cpp > 4 looks like a gross hack at best... * Plus can't use these transfer fallbacks when clearing * multisampled surfaces for instance. + * Clears all bound layers. */ void util_clear_render_target(struct pipe_context *pipe, @@ -316,8 +317,9 @@ util_clear_render_target(struct pipe_context *pipe, unsigned width, unsigned height) { struct pipe_transfer *dst_trans; - void *dst_map; + ubyte *dst_map; union util_color uc; + unsigned max_layer, layer; assert(dst->texture); if (!dst->texture) @@ -332,6 +334,7 @@ util_clear_render_target(struct pipe_context *pipe, unsigned pixstride = util_format_get_blocksize(dst->format); dx = (dst->u.buf.first_element + dstx) * pixstride; w = width * pixstride; + max_layer = 0; dst_map = pipe_transfer_map(pipe, dst->texture, 0, 0, @@ -340,14 +343,13 @@ util_clear_render_target(struct pipe_context *pipe, &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); - + max_layer = dst->u.tex.last_layer - dst->u.tex.first_layer; + dst_map = pipe_transfer_map_3d(pipe, + dst->texture, + dst->u.tex.level, + PIPE_TRANSFER_WRITE, + dstx, dsty, dst->u.tex.first_layer, + width, height, max_layer, &dst_trans); } assert(dst_map); @@ -373,9 +375,13 @@ util_clear_render_target(struct pipe_context *pipe, else { util_pack_color(color->f, dst->format, &uc); } - util_fill_rect(dst_map, dst->format, - dst_trans->stride, - 0, 0, width, height, &uc); + + for (layer = 0; layer <= max_layer; layer++) { + util_fill_rect(dst_map, dst->format, + dst_trans->stride, + 0, 0, width, height, &uc); + dst_map += dst_trans->layer_stride; + } pipe->transfer_unmap(pipe, dst_trans); } @@ -386,6 +392,7 @@ util_clear_render_target(struct pipe_context *pipe, * sw fallback doesn't look terribly useful here. * Plus can't use these transfer fallbacks when clearing * multisampled surfaces for instance. + * Clears all bound layers. */ void util_clear_depth_stencil(struct pipe_context *pipe, @@ -400,6 +407,7 @@ util_clear_depth_stencil(struct pipe_context *pipe, struct pipe_transfer *dst_trans; ubyte *dst_map; boolean need_rmw = FALSE; + unsigned max_layer, layer; if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && @@ -409,102 +417,110 @@ util_clear_depth_stencil(struct pipe_context *pipe, assert(dst->texture); if (!dst->texture) return; - dst_map = pipe_transfer_map(pipe, - dst->texture, - dst->u.tex.level, - dst->u.tex.first_layer, - (need_rmw ? PIPE_TRANSFER_READ_WRITE : - PIPE_TRANSFER_WRITE), - dstx, dsty, width, height, &dst_trans); + + max_layer = dst->u.tex.last_layer - dst->u.tex.first_layer; + dst_map = pipe_transfer_map_3d(pipe, + dst->texture, + dst->u.tex.level, + (need_rmw ? PIPE_TRANSFER_READ_WRITE : + PIPE_TRANSFER_WRITE), + dstx, dsty, dst->u.tex.first_layer, + width, height, max_layer + 1, &dst_trans); assert(dst_map); if (dst_map) { unsigned dst_stride = dst_trans->stride; uint64_t zstencil = util_pack64_z_stencil(format, depth, stencil); + ubyte *dst_layer = dst_map; unsigned i, j; assert(dst_trans->stride > 0); - switch (util_format_get_blocksize(format)) { - case 1: - assert(format == PIPE_FORMAT_S8_UINT); - if(dst_stride == width) - memset(dst_map, (uint8_t) zstencil, height * width); - else { - for (i = 0; i < height; i++) { - memset(dst_map, (uint8_t) zstencil, width); - dst_map += dst_stride; - } - } - break; - case 2: - assert(format == PIPE_FORMAT_Z16_UNORM); - for (i = 0; i < height; i++) { - uint16_t *row = (uint16_t *)dst_map; - for (j = 0; j < width; j++) - *row++ = (uint16_t) zstencil; - dst_map += dst_stride; + for (layer = 0; layer <= max_layer; layer++) { + dst_map = dst_layer; + + switch (util_format_get_blocksize(format)) { + case 1: + assert(format == PIPE_FORMAT_S8_UINT); + if(dst_stride == width) + memset(dst_map, (uint8_t) zstencil, height * width); + else { + for (i = 0; i < height; i++) { + memset(dst_map, (uint8_t) zstencil, width); + dst_map += dst_stride; + } } - break; - case 4: - if (!need_rmw) { + break; + case 2: + assert(format == PIPE_FORMAT_Z16_UNORM); for (i = 0; i < height; i++) { - uint32_t *row = (uint32_t *)dst_map; + uint16_t *row = (uint16_t *)dst_map; for (j = 0; j < width; j++) - *row++ = (uint32_t) zstencil; + *row++ = (uint16_t) zstencil; dst_map += dst_stride; + } + break; + case 4: + if (!need_rmw) { + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst_map; + for (j = 0; j < width; j++) + *row++ = (uint32_t) zstencil; + dst_map += dst_stride; + } } - } - else { - uint32_t dst_mask; - if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) - dst_mask = 0x00ffffff; else { - assert(format == PIPE_FORMAT_S8_UINT_Z24_UNORM); - dst_mask = 0xffffff00; - } - if (clear_flags & PIPE_CLEAR_DEPTH) - dst_mask = ~dst_mask; - for (i = 0; i < height; i++) { - uint32_t *row = (uint32_t *)dst_map; - for (j = 0; j < width; j++) { - uint32_t tmp = *row & dst_mask; - *row++ = tmp | ((uint32_t) zstencil & ~dst_mask); + uint32_t dst_mask; + if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) + dst_mask = 0x00ffffff; + else { + assert(format == PIPE_FORMAT_S8_UINT_Z24_UNORM); + dst_mask = 0xffffff00; + } + if (clear_flags & PIPE_CLEAR_DEPTH) + dst_mask = ~dst_mask; + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst_map; + for (j = 0; j < width; j++) { + uint32_t tmp = *row & dst_mask; + *row++ = tmp | ((uint32_t) zstencil & ~dst_mask); + } + dst_map += dst_stride; } - dst_map += dst_stride; } - } - break; - case 8: - if (!need_rmw) { - for (i = 0; i < height; i++) { - uint64_t *row = (uint64_t *)dst_map; - for (j = 0; j < width; j++) - *row++ = zstencil; - dst_map += dst_stride; + break; + case 8: + if (!need_rmw) { + for (i = 0; i < height; i++) { + uint64_t *row = (uint64_t *)dst_map; + for (j = 0; j < width; j++) + *row++ = zstencil; + dst_map += dst_stride; + } } - } - else { - uint64_t src_mask; - - if (clear_flags & PIPE_CLEAR_DEPTH) - src_mask = 0x00000000ffffffffull; - else - src_mask = 0x000000ff00000000ull; - - for (i = 0; i < height; i++) { - uint64_t *row = (uint64_t *)dst_map; - for (j = 0; j < width; j++) { - uint64_t tmp = *row & ~src_mask; - *row++ = tmp | (zstencil & src_mask); + else { + uint64_t src_mask; + + if (clear_flags & PIPE_CLEAR_DEPTH) + src_mask = 0x00000000ffffffffull; + else + src_mask = 0x000000ff00000000ull; + + for (i = 0; i < height; i++) { + uint64_t *row = (uint64_t *)dst_map; + for (j = 0; j < width; j++) { + uint64_t tmp = *row & ~src_mask; + *row++ = tmp | (zstencil & src_mask); + } + dst_map += dst_stride; } - dst_map += dst_stride; } + break; + default: + assert(0); + break; } - break; - default: - assert(0); - break; + dst_layer += dst_trans->layer_stride; } pipe->transfer_unmap(pipe, dst_trans); -- 2.30.2