aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/gallium/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/gallium/auxiliary')
-rw-r--r--mesalib/src/gallium/auxiliary/Makefile.sources1
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blit.c3
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c181
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.h11
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_debug.c3
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_dump_state.c2
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c8
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_inlines.h9
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_suballoc.c132
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_suballoc.h48
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_surface.c167
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_surface.h7
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_surfaces.c4
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_surfaces.h6
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 *