diff options
Diffstat (limited to 'mesalib/src/gallium')
-rw-r--r-- | mesalib/src/gallium/auxiliary/Makefile.sources | 1 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blit.c | 3 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.c | 181 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.h | 11 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_debug.c | 3 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_dump_state.c | 2 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c | 8 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_inlines.h | 9 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_suballoc.c | 132 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_suballoc.h | 48 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_surface.c | 167 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_surface.h | 7 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_surfaces.c | 4 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_surfaces.h | 6 |
14 files changed, 364 insertions, 218 deletions
diff --git a/mesalib/src/gallium/auxiliary/Makefile.sources b/mesalib/src/gallium/auxiliary/Makefile.sources index 724178535..e54e9201c 100644 --- a/mesalib/src/gallium/auxiliary/Makefile.sources +++ b/mesalib/src/gallium/auxiliary/Makefile.sources @@ -130,6 +130,7 @@ C_SOURCES := \ util/u_slab.c \ util/u_snprintf.c \ util/u_staging.c \ + util/u_suballoc.c \ util/u_surface.c \ util/u_surfaces.c \ util/u_texture.c \ diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index ab1549e2d..9fe15b810 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/src/gallium/auxiliary/util/u_blit.c @@ -666,6 +666,7 @@ util_blit_pixels(struct blit_state *ctx, cso_save_geometry_shader(ctx->cso); cso_save_vertex_elements(ctx->cso); cso_save_aux_vertex_buffer_slot(ctx->cso); + cso_save_render_condition(ctx->cso); /* set misc state we care about */ if (writemask) @@ -677,6 +678,7 @@ util_blit_pixels(struct blit_state *ctx, cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); cso_set_stream_outputs(ctx->cso, 0, NULL, 0); + cso_set_render_condition(ctx->cso, NULL, 0); /* default sampler state */ ctx->sampler.normalized_coords = normalized; @@ -799,6 +801,7 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_vertex_elements(ctx->cso); cso_restore_aux_vertex_buffer_slot(ctx->cso); cso_restore_stream_outputs(ctx->cso); + cso_restore_render_condition(ctx->cso); pipe_sampler_view_reference(&sampler_view, NULL); if (dst_surface != dst) diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index e788b6594..7c7e06219 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -1053,29 +1053,6 @@ void util_blitter_custom_clear_depth(struct blitter_context *blitter, 0, PIPE_FORMAT_NONE, &color, depth, 0, NULL, custom_dsa); } -static -boolean is_overlap(int dstx, int dsty, int dstz, - const struct pipe_box *srcbox) -{ - struct pipe_box src = *srcbox; - - if (src.width < 0) { - src.x += src.width; - src.width = -src.width; - } - if (src.height < 0) { - src.y += src.height; - src.height = -src.height; - } - if (src.depth < 0) { - src.z += src.depth; - src.depth = -src.depth; - } - return src.x < dstx+src.width && src.x+src.width > dstx && - src.y < dsty+src.height && src.y+src.height > dsty && - src.z < dstz+src.depth && src.z+src.depth > dstz; -} - void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, struct pipe_resource *dst, unsigned dstlevel, @@ -1083,12 +1060,6 @@ void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, const struct pipe_box *srcbox) { memset(dst_templ, 0, sizeof(*dst_templ)); - dst_templ->format = dst->format; - if (util_format_is_depth_or_stencil(dst->format)) { - dst_templ->usage = PIPE_BIND_DEPTH_STENCIL; - } else { - dst_templ->usage = PIPE_BIND_RENDER_TARGET; - } dst_templ->format = util_format_linear(dst->format); dst_templ->u.tex.level = dstlevel; dst_templ->u.tex.first_layer = dstz; @@ -1267,11 +1238,6 @@ void util_blitter_blit_generic(struct blitter_context *blitter, return; } - /* Sanity checks. */ - if (dst->texture == src->texture && - dst->u.tex.level == src->u.tex.first_level) { - assert(!is_overlap(dstx, dsty, 0, srcbox)); - } /* XXX should handle 3d regions */ assert(srcbox->depth == 1); @@ -1743,7 +1709,6 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter, surf_tmpl.u.tex.level = dst_level; surf_tmpl.u.tex.first_layer = dst_layer; surf_tmpl.u.tex.last_layer = dst_layer; - surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl); @@ -1822,149 +1787,3 @@ void util_blitter_custom_color(struct blitter_context *blitter, blitter_restore_render_cond(ctx); blitter_unset_running_flag(ctx); } - -/* Return whether this is an RGBA, Z, S, or combined ZS format. - */ -static unsigned get_format_mask(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - assert(desc); - - if (util_format_has_depth(desc)) { - if (util_format_has_stencil(desc)) { - return PIPE_MASK_ZS; - } else { - return PIPE_MASK_Z; - } - } else { - if (util_format_has_stencil(desc)) { - return PIPE_MASK_S; - } else { - return PIPE_MASK_RGBA; - } - } -} - -/* Return if the box is totally inside the resource. - */ -static boolean is_box_inside_resource(const struct pipe_resource *res, - const struct pipe_box *box, - unsigned level) -{ - unsigned width = 1, height = 1, depth = 1; - - switch (res->target) { - case PIPE_BUFFER: - width = res->width0; - height = 1; - depth = 1; - break; - case PIPE_TEXTURE_1D: - width = u_minify(res->width0, level); - height = 1; - depth = 1; - break; - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_RECT: - width = u_minify(res->width0, level); - height = u_minify(res->height0, level); - depth = 1; - break; - case PIPE_TEXTURE_3D: - width = u_minify(res->width0, level); - height = u_minify(res->height0, level); - depth = u_minify(res->depth0, level); - break; - case PIPE_TEXTURE_CUBE: - width = u_minify(res->width0, level); - height = u_minify(res->height0, level); - depth = 6; - break; - case PIPE_TEXTURE_1D_ARRAY: - width = u_minify(res->width0, level); - height = 1; - depth = res->array_size; - break; - case PIPE_TEXTURE_2D_ARRAY: - width = u_minify(res->width0, level); - height = u_minify(res->height0, level); - depth = res->array_size; - break; - case PIPE_TEXTURE_CUBE_ARRAY: - width = u_minify(res->width0, level); - height = u_minify(res->height0, level); - depth = res->array_size; - assert(res->array_size % 6 == 0); - break; - case PIPE_MAX_TEXTURE_TYPES:; - } - - return box->x >= 0 && - box->x + box->width <= (int) width && - box->y >= 0 && - box->y + box->height <= (int) height && - box->z >= 0 && - box->z + box->depth <= (int) depth; -} - -static unsigned get_sample_count(const struct pipe_resource *res) -{ - return res->nr_samples ? res->nr_samples : 1; -} - -boolean util_try_blit_via_copy_region(struct pipe_context *ctx, - const struct pipe_blit_info *blit) -{ - unsigned mask = get_format_mask(blit->dst.format); - - /* No format conversions. */ - if (blit->src.resource->format != blit->src.format || - blit->dst.resource->format != blit->dst.format || - !util_is_format_compatible( - util_format_description(blit->src.resource->format), - util_format_description(blit->dst.resource->format))) { - return FALSE; - } - - /* No masks, no filtering, no scissor. */ - if ((blit->mask & mask) != mask || - blit->filter != PIPE_TEX_FILTER_NEAREST || - blit->scissor_enable) { - return FALSE; - } - - /* No flipping. */ - if (blit->src.box.width < 0 || - blit->src.box.height < 0 || - blit->src.box.depth < 0) { - return FALSE; - } - - /* No scaling. */ - if (blit->src.box.width != blit->dst.box.width || - blit->src.box.height != blit->dst.box.height || - blit->src.box.depth != blit->dst.box.depth) { - return FALSE; - } - - /* No out-of-bounds access. */ - if (!is_box_inside_resource(blit->src.resource, &blit->src.box, - blit->src.level) || - !is_box_inside_resource(blit->dst.resource, &blit->dst.box, - blit->dst.level)) { - return FALSE; - } - - /* Sample counts must match. */ - if (get_sample_count(blit->src.resource) != - get_sample_count(blit->dst.resource)) { - return FALSE; - } - - ctx->resource_copy_region(ctx, blit->dst.resource, blit->dst.level, - blit->dst.box.x, blit->dst.box.y, blit->dst.box.z, - blit->src.resource, blit->src.level, - &blit->src.box); - return TRUE; -} diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h index 99175409b..0b5e4aa45 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.h +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h @@ -152,17 +152,6 @@ void util_blitter_draw_rectangle(struct blitter_context *blitter, enum blitter_attrib_type type, const union pipe_color_union *attrib); -/** - * Try to do a blit using resource_copy_region. The function calls - * resource_copy_region if the blit description is compatible with it. - * - * It returns TRUE if the blit was done using resource_copy_region. - * - * It returns FALSE otherwise and the caller must fall back to a more generic - * codepath for the blit operation. (e.g. by using u_blitter) - */ -boolean util_try_blit_via_copy_region(struct pipe_context *ctx, - const struct pipe_blit_info *blit); /* * These states must be saved before any of the following functions are called: diff --git a/mesalib/src/gallium/auxiliary/util/u_debug.c b/mesalib/src/gallium/auxiliary/util/u_debug.c index ee97b7adb..ce472b020 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug.c @@ -537,8 +537,7 @@ void debug_dump_texture(struct pipe_context *pipe, return; /* XXX for now, just dump image for layer=0, level=0 */ - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); - u_surface_default_template(&surf_tmpl, texture, 0 /* no bind flag - not a surface */); + u_surface_default_template(&surf_tmpl, texture); surface = pipe->create_surface(pipe, texture, &surf_tmpl); if (surface) { debug_dump_surface(pipe, prefix, surface); diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c index f5d8b4373..09faffe73 100644 --- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c +++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c @@ -661,8 +661,6 @@ util_dump_surface(FILE *stream, const struct pipe_surface *state) util_dump_member(stream, uint, state, width); util_dump_member(stream, uint, state, height); - util_dump_member(stream, uint, state, usage); - util_dump_member(stream, ptr, state, texture); util_dump_member(stream, uint, state, u.tex.level); util_dump_member(stream, uint, state, u.tex.first_layer); diff --git a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c index 48ebdb9fa..e1f18f39c 100644 --- a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1566,6 +1566,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_viewport(ctx->cso); cso_save_vertex_elements(ctx->cso); cso_save_aux_vertex_buffer_slot(ctx->cso); + cso_save_render_condition(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, is_depth ? &ctx->blend_keep_color : @@ -1576,6 +1577,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_sample_mask(ctx->cso, ~0); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); cso_set_stream_outputs(ctx->cso, 0, NULL, 0); + cso_set_render_condition(ctx->cso, NULL, 0); set_fragment_shader(ctx, type, is_depth); set_vertex_shader(ctx); @@ -1615,10 +1617,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, } else layer = face; - memset(&surf_templ, 0, sizeof(surf_templ)); - u_surface_default_template(&surf_templ, pt, - is_depth ? PIPE_BIND_DEPTH_STENCIL : - PIPE_BIND_RENDER_TARGET); + u_surface_default_template(&surf_templ, pt); surf_templ.u.tex.level = dstLevel; surf_templ.u.tex.first_layer = layer; surf_templ.u.tex.last_layer = layer; @@ -1699,4 +1698,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_vertex_elements(ctx->cso); cso_restore_stream_outputs(ctx->cso); cso_restore_aux_vertex_buffer_slot(ctx->cso); + cso_restore_render_condition(ctx->cso); } diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h index 469f95461..582aacdca 100644 --- a/mesalib/src/gallium/auxiliary/util/u_inlines.h +++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h @@ -188,14 +188,12 @@ pipe_so_target_reference(struct pipe_stream_output_target **ptr, static INLINE void pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps, - struct pipe_resource *pt, unsigned level, unsigned layer, - unsigned flags) + struct pipe_resource *pt, unsigned level, unsigned layer) { pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); - ps->usage = flags; ps->u.tex.level = level; ps->u.tex.first_layer = ps->u.tex.last_layer = layer; ps->context = ctx; @@ -203,12 +201,11 @@ pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps, static INLINE void pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps, - struct pipe_resource *pt, unsigned level, unsigned layer, - unsigned flags) + struct pipe_resource *pt, unsigned level, unsigned layer) { ps->texture = 0; pipe_reference_init(&ps->reference, 1); - pipe_surface_reset(ctx, ps, pt, level, layer, flags); + pipe_surface_reset(ctx, ps, pt, level, layer); } /* Return true if the surfaces are equal. */ diff --git a/mesalib/src/gallium/auxiliary/util/u_suballoc.c b/mesalib/src/gallium/auxiliary/util/u_suballoc.c new file mode 100644 index 000000000..efa9a0c5e --- /dev/null +++ b/mesalib/src/gallium/auxiliary/util/u_suballoc.c @@ -0,0 +1,132 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * Copyright 2012 Marek Olšák <maraeo@gmail.com> + * All Rights Reserved. + * + * 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 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 AUTHORS AND/OR ITS 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. + * + **************************************************************************/ + +/* A simple allocator that suballocates memory from a large buffer. */ + +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "pipe/p_context.h" +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "u_suballoc.h" + + +struct u_suballocator { + struct pipe_context *pipe; + + unsigned size; /* Size of the whole buffer, in bytes. */ + unsigned alignment; /* Alignment of each sub-allocation. */ + unsigned bind; /* Bitmask of PIPE_BIND_* flags. */ + unsigned usage; /* One of PIPE_USAGE_* flags. */ + boolean zero_buffer_memory; /* If the buffer contents should be zeroed. */ + + struct pipe_resource *buffer; /* The buffer we suballocate from. */ + unsigned offset; /* Aligned offset pointing at the first unused byte. */ +}; + + +/** + * Create a suballocator. + * + * \p zero_buffer_memory determines whether the buffer contents should be + * cleared to 0 after the allocation. + */ +struct u_suballocator * +u_suballocator_create(struct pipe_context *pipe, unsigned size, + unsigned alignment, unsigned bind, unsigned usage, + boolean zero_buffer_memory) +{ + struct u_suballocator *allocator = CALLOC_STRUCT(u_suballocator); + if (!allocator) + return NULL; + + allocator->pipe = pipe; + allocator->size = align(size, alignment); + allocator->alignment = alignment; + allocator->bind = bind; + allocator->usage = usage; + allocator->zero_buffer_memory = zero_buffer_memory; + return allocator; +} + +void +u_suballocator_destroy(struct u_suballocator *allocator) +{ + pipe_resource_reference(&allocator->buffer, NULL); + FREE(allocator); +} + +void +u_suballocator_alloc(struct u_suballocator *allocator, unsigned size, + unsigned *out_offset, struct pipe_resource **outbuf) +{ + unsigned alloc_size = align(size, allocator->alignment); + + /* Don't allow allocations larger than the buffer size. */ + if (alloc_size > allocator->size) + goto fail; + + /* Make sure we have enough space in the buffer. */ + if (!allocator->buffer || + allocator->offset + alloc_size > allocator->size) { + /* Allocate a new buffer. */ + pipe_resource_reference(&allocator->buffer, NULL); + allocator->offset = 0; + allocator->buffer = + pipe_buffer_create(allocator->pipe->screen, allocator->bind, + allocator->usage, allocator->size); + if (!allocator->buffer) + goto fail; + + /* Clear the memory if needed. */ + if (allocator->zero_buffer_memory) { + struct pipe_transfer *transfer = NULL; + void *ptr; + + ptr = pipe_buffer_map(allocator->pipe, allocator->buffer, + PIPE_TRANSFER_WRITE, &transfer); + memset(ptr, 0, allocator->size); + pipe_buffer_unmap(allocator->pipe, transfer); + } + } + + assert(allocator->offset % allocator->alignment == 0); + assert(allocator->offset < allocator->buffer->width0); + assert(allocator->offset + alloc_size <= allocator->buffer->width0); + + /* Return the buffer. */ + *out_offset = allocator->offset; + pipe_resource_reference(outbuf, allocator->buffer); + + allocator->offset += alloc_size; + return; + +fail: + pipe_resource_reference(outbuf, NULL); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_suballoc.h b/mesalib/src/gallium/auxiliary/util/u_suballoc.h new file mode 100644 index 000000000..1f5550ffa --- /dev/null +++ b/mesalib/src/gallium/auxiliary/util/u_suballoc.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * Copyright 2012 Marek Olšák <maraeo@gmail.com> + * All Rights Reserved. + * + * 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 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 AUTHORS AND/OR ITS 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. + * + **************************************************************************/ + +/* A simple allocator that suballocates memory from a large buffer. */ + +#ifndef U_SUBALLOC +#define U_SUBALLOC + +struct u_suballocator; + +struct u_suballocator * +u_suballocator_create(struct pipe_context *pipe, unsigned size, + unsigned alignment, unsigned bind, unsigned usage, + boolean zero_buffer_memory); + +void +u_suballocator_destroy(struct u_suballocator *allocator); + +void +u_suballocator_alloc(struct u_suballocator *allocator, unsigned size, + unsigned *out_offset, struct pipe_resource **outbuf); + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.c b/mesalib/src/gallium/auxiliary/util/u_surface.c index 2c197c3df..5e771c950 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surface.c +++ b/mesalib/src/gallium/auxiliary/util/u_surface.c @@ -49,14 +49,11 @@ */ void u_surface_default_template(struct pipe_surface *surf, - const struct pipe_resource *texture, - unsigned bind) + const struct pipe_resource *texture) { memset(surf, 0, sizeof(*surf)); surf->format = texture->format; - /* XXX should filter out all non-rt/ds bind flags ? */ - surf->usage = bind; } /** @@ -110,7 +107,7 @@ util_create_rgba_texture(struct pipe_context *pipe, return FALSE; /* create surface */ - u_surface_default_template(&surf_templ, *textureOut, bind); + u_surface_default_template(&surf_templ, *textureOut); return TRUE; } @@ -531,3 +528,163 @@ util_clear_depth_stencil(struct pipe_context *pipe, pipe->transfer_unmap(pipe, dst_trans); } } + + +/* Return whether this is an RGBA, Z, S, or combined ZS format. + */ +static unsigned +get_format_mask(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + + if (util_format_has_depth(desc)) { + if (util_format_has_stencil(desc)) { + return PIPE_MASK_ZS; + } else { + return PIPE_MASK_Z; + } + } else { + if (util_format_has_stencil(desc)) { + return PIPE_MASK_S; + } else { + return PIPE_MASK_RGBA; + } + } +} + +/* Return if the box is totally inside the resource. + */ +static boolean +is_box_inside_resource(const struct pipe_resource *res, + const struct pipe_box *box, + unsigned level) +{ + unsigned width = 1, height = 1, depth = 1; + + switch (res->target) { + case PIPE_BUFFER: + width = res->width0; + height = 1; + depth = 1; + break; + case PIPE_TEXTURE_1D: + width = u_minify(res->width0, level); + height = 1; + depth = 1; + break; + case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_RECT: + width = u_minify(res->width0, level); + height = u_minify(res->height0, level); + depth = 1; + break; + case PIPE_TEXTURE_3D: + width = u_minify(res->width0, level); + height = u_minify(res->height0, level); + depth = u_minify(res->depth0, level); + break; + case PIPE_TEXTURE_CUBE: + width = u_minify(res->width0, level); + height = u_minify(res->height0, level); + depth = 6; + break; + case PIPE_TEXTURE_1D_ARRAY: + width = u_minify(res->width0, level); + height = 1; + depth = res->array_size; + break; + case PIPE_TEXTURE_2D_ARRAY: + width = u_minify(res->width0, level); + height = u_minify(res->height0, level); + depth = res->array_size; + break; + case PIPE_TEXTURE_CUBE_ARRAY: + width = u_minify(res->width0, level); + height = u_minify(res->height0, level); + depth = res->array_size; + assert(res->array_size % 6 == 0); + break; + case PIPE_MAX_TEXTURE_TYPES:; + } + + return box->x >= 0 && + box->x + box->width <= (int) width && + box->y >= 0 && + box->y + box->height <= (int) height && + box->z >= 0 && + box->z + box->depth <= (int) depth; +} + +static unsigned +get_sample_count(const struct pipe_resource *res) +{ + return res->nr_samples ? res->nr_samples : 1; +} + +/** + * Try to do a blit using resource_copy_region. The function calls + * resource_copy_region if the blit description is compatible with it. + * + * It returns TRUE if the blit was done using resource_copy_region. + * + * It returns FALSE otherwise and the caller must fall back to a more generic + * codepath for the blit operation. (e.g. by using u_blitter) + */ +boolean +util_try_blit_via_copy_region(struct pipe_context *ctx, + const struct pipe_blit_info *blit) +{ + unsigned mask = get_format_mask(blit->dst.format); + + /* No format conversions. */ + if (blit->src.resource->format != blit->src.format || + blit->dst.resource->format != blit->dst.format || + !util_is_format_compatible( + util_format_description(blit->src.resource->format), + util_format_description(blit->dst.resource->format))) { + return FALSE; + } + + /* No masks, no filtering, no scissor. */ + if ((blit->mask & mask) != mask || + blit->filter != PIPE_TEX_FILTER_NEAREST || + blit->scissor_enable) { + return FALSE; + } + + /* No flipping. */ + if (blit->src.box.width < 0 || + blit->src.box.height < 0 || + blit->src.box.depth < 0) { + return FALSE; + } + + /* No scaling. */ + if (blit->src.box.width != blit->dst.box.width || + blit->src.box.height != blit->dst.box.height || + blit->src.box.depth != blit->dst.box.depth) { + return FALSE; + } + + /* No out-of-bounds access. */ + if (!is_box_inside_resource(blit->src.resource, &blit->src.box, + blit->src.level) || + !is_box_inside_resource(blit->dst.resource, &blit->dst.box, + blit->dst.level)) { + return FALSE; + } + + /* Sample counts must match. */ + if (get_sample_count(blit->src.resource) != + get_sample_count(blit->dst.resource)) { + return FALSE; + } + + ctx->resource_copy_region(ctx, blit->dst.resource, blit->dst.level, + blit->dst.box.x, blit->dst.box.y, blit->dst.box.z, + blit->src.resource, blit->src.level, + &blit->src.box); + return TRUE; +} diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.h b/mesalib/src/gallium/auxiliary/util/u_surface.h index dd4d5785e..fe950c818 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surface.h +++ b/mesalib/src/gallium/auxiliary/util/u_surface.h @@ -42,8 +42,7 @@ extern "C" { extern void u_surface_default_template(struct pipe_surface *view, - const struct pipe_resource *texture, - unsigned bind); + const struct pipe_resource *texture); extern boolean util_create_rgba_texture(struct pipe_context *ctx, @@ -98,6 +97,10 @@ util_clear_depth_stencil(struct pipe_context *pipe, unsigned dstx, unsigned dsty, unsigned width, unsigned height); +extern boolean +util_try_blit_via_copy_region(struct pipe_context *ctx, + const struct pipe_blit_info *blit); + #ifdef __cplusplus } diff --git a/mesalib/src/gallium/auxiliary/util/u_surfaces.c b/mesalib/src/gallium/auxiliary/util/u_surfaces.c index b0cfec2a8..c2f2b74c9 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surfaces.c +++ b/mesalib/src/gallium/auxiliary/util/u_surfaces.c @@ -32,7 +32,7 @@ boolean util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_context *ctx, struct pipe_resource *pt, - unsigned level, unsigned layer, unsigned flags, + unsigned level, unsigned layer, struct pipe_surface **res) { struct pipe_surface *ps; @@ -65,7 +65,7 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, return FALSE; } - pipe_surface_init(ctx, ps, pt, level, layer, flags); + pipe_surface_init(ctx, ps, pt, level, layer); if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) cso_hash_insert(us->u.hash, (layer << 8) | level, ps); diff --git a/mesalib/src/gallium/auxiliary/util/u_surfaces.h b/mesalib/src/gallium/auxiliary/util/u_surfaces.h index 9581feda7..1605215cb 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surfaces.h +++ b/mesalib/src/gallium/auxiliary/util/u_surfaces.h @@ -46,14 +46,14 @@ struct util_surfaces boolean util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_context *ctx, struct pipe_resource *pt, - unsigned level, unsigned layer, unsigned flags, + unsigned level, unsigned layer, struct pipe_surface **res); /* fast inline path for the very common case */ static INLINE boolean util_surfaces_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_context *ctx, struct pipe_resource *pt, - unsigned level, unsigned layer, unsigned flags, + unsigned level, unsigned layer, struct pipe_surface **res) { if(likely((pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT) && us->u.array)) @@ -67,7 +67,7 @@ util_surfaces_get(struct util_surfaces *us, unsigned surface_struct_size, } } - return util_surfaces_do_get(us, surface_struct_size, ctx, pt, level, layer, flags, res); + return util_surfaces_do_get(us, surface_struct_size, ctx, pt, level, layer, res); } static INLINE struct pipe_surface * |