From abacebe06d9f3d2fe1b7d256bd86cddbfa592a85 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 17 Dec 2011 13:43:14 +0100 Subject: libX11 libxtrans mesa xserver git update 17 dec 2011 --- mesalib/src/gallium/auxiliary/util/u_blit.c | 6 + mesalib/src/gallium/auxiliary/util/u_blitter.c | 105 ++- mesalib/src/gallium/auxiliary/util/u_blitter.h | 29 + .../src/gallium/auxiliary/util/u_debug_describe.c | 10 + .../src/gallium/auxiliary/util/u_debug_describe.h | 100 +-- mesalib/src/gallium/auxiliary/util/u_dump_state.c | 19 + mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c | 3 + mesalib/src/gallium/auxiliary/util/u_inlines.h | 930 +++++++++++---------- .../src/gallium/auxiliary/util/u_simple_shaders.c | 498 +++++------ .../src/gallium/auxiliary/util/u_simple_shaders.h | 174 ++-- 10 files changed, 1038 insertions(+), 836 deletions(-) (limited to 'mesalib/src/gallium/auxiliary/util') diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index 3a0d7d424..bba0031d7 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/src/gallium/auxiliary/util/u_blit.c @@ -529,6 +529,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); cso_save_fragment_sampler_views(ctx->cso); + cso_save_stream_outputs(ctx->cso); cso_save_viewport(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); @@ -546,6 +547,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + cso_set_stream_outputs(ctx->cso, 0, NULL, 0); /* sampler */ ctx->sampler.normalized_coords = normalized; @@ -622,6 +624,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); cso_restore_vertex_buffers(ctx->cso); + cso_restore_stream_outputs(ctx->cso); pipe_sampler_view_reference(&sampler_view, NULL); if (dst_surface != dst) @@ -722,6 +725,7 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); cso_save_fragment_sampler_views(ctx->cso); + cso_save_stream_outputs(ctx->cso); cso_save_viewport(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); @@ -737,6 +741,7 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + cso_set_stream_outputs(ctx->cso, 0, NULL, 0); /* sampler */ ctx->sampler.normalized_coords = normalized; @@ -801,4 +806,5 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); cso_restore_vertex_buffers(ctx->cso); + cso_restore_stream_outputs(ctx->cso); } diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index f5cc5cb3b..3c501814e 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -63,6 +63,7 @@ struct blitter_context_priv /* Constant state objects. */ /* Vertex shaders. */ void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ + void *vs_pos_only; /**< Vertex shader which passes pos to the output.*/ /* Fragment shaders. */ /* The shader at index i outputs color to color buffers 0,1,...,i-1. */ @@ -87,15 +88,18 @@ struct blitter_context_priv void *dsa_keep_depth_stencil; void *dsa_keep_depth_write_stencil; + /* Vertex elements states. */ void *velem_state; void *velem_uint_state; void *velem_sint_state; + void *velem_state_readbuf; /* Sampler state. */ void *sampler_state; /* Rasterizer state. */ void *rs_state; + void *rs_discard_state; /* Viewport state. */ struct pipe_viewport_state viewport; @@ -109,6 +113,7 @@ struct blitter_context_priv boolean has_geometry_shader; boolean vertex_has_integers; + boolean has_stream_out; }; static void blitter_draw_rectangle(struct blitter_context *blitter, @@ -148,6 +153,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->base.saved_num_sampler_views = ~0; ctx->base.saved_num_sampler_states = ~0; ctx->base.saved_num_vertex_buffers = ~0; + ctx->base.saved_num_so_targets = ~0; ctx->has_geometry_shader = pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, @@ -155,6 +161,9 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->vertex_has_integers = pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS); + ctx->has_stream_out = + pipe->screen->get_param(pipe->screen, + PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0; /* blend state objects */ memset(&blend, 0, sizeof(blend)); @@ -205,7 +214,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) rs_state.flatshade = 1; ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); - /* vertex elements state */ + if (ctx->has_stream_out) { + rs_state.rasterizer_discard = 1; + ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state); + } + + /* vertex elements states */ memset(&velem[0], 0, sizeof(velem[0]) * 2); for (i = 0; i < 2; i++) { velem[i].src_offset = i * 4 * sizeof(float); @@ -229,9 +243,14 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); } + if (ctx->has_stream_out) { + velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ctx->velem_state_readbuf = pipe->create_vertex_elements_state(pipe, 1, &velem[0]); + } + /* fragment shaders are created on-demand */ - /* vertex shader */ + /* vertex shaders */ { const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC }; @@ -240,6 +259,20 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) util_make_vertex_passthrough_shader(pipe, 2, semantic_names, semantic_indices); } + if (ctx->has_stream_out) { + struct pipe_stream_output_info so; + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION }; + const uint semantic_indices[] = { 0 }; + + memset(&so, 0, sizeof(so)); + so.num_outputs = 1; + so.output[0].register_mask = TGSI_WRITEMASK_XYZW; + so.stride = 4; + + ctx->vs_pos_only = + util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names, + semantic_indices, &so); + } /* set invariant vertex coordinates */ for (i = 0; i < 4; i++) @@ -269,12 +302,18 @@ void util_blitter_destroy(struct blitter_context *blitter) pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); pipe->delete_rasterizer_state(pipe, ctx->rs_state); + if (ctx->rs_discard_state) + pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state); pipe->delete_vs_state(pipe, ctx->vs); + if (ctx->vs_pos_only) + pipe->delete_vs_state(pipe, ctx->vs_pos_only); pipe->delete_vertex_elements_state(pipe, ctx->velem_state); if (ctx->vertex_has_integers) { pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state); pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state); } + if (ctx->velem_state_readbuf) + pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf); for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { if (ctx->fs_texfetch_col[i]) @@ -319,6 +358,7 @@ static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx) ctx->base.saved_velem_state != INVALID_PTR && ctx->base.saved_vs != INVALID_PTR && (!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR) && + (!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0) && ctx->base.saved_rs_state != INVALID_PTR); } @@ -354,6 +394,18 @@ static void blitter_restore_vertex_states(struct blitter_context_priv *ctx) ctx->base.saved_gs = INVALID_PTR; } + /* Stream outputs. */ + if (ctx->has_stream_out) { + pipe->set_stream_output_targets(pipe, + ctx->base.saved_num_so_targets, + ctx->base.saved_so_targets, ~0); + + for (i = 0; i < ctx->base.saved_num_so_targets; i++) + pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL); + + ctx->base.saved_num_so_targets = ~0; + } + /* Rasterizer. */ pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state); ctx->base.saved_rs_state = INVALID_PTR; @@ -1160,3 +1212,52 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, blitter_restore_fb_state(ctx); blitter_unset_running_flag(ctx); } + +void util_blitter_copy_buffer(struct blitter_context *blitter, + struct pipe_resource *dst, + unsigned dstx, + struct pipe_resource *src, + unsigned srcx, + unsigned size) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + struct pipe_context *pipe = ctx->base.pipe; + struct pipe_vertex_buffer vb; + struct pipe_stream_output_target *so_target; + + /* Drivers not capable of Stream Out should not call this function + * in the first place. */ + assert(ctx->has_stream_out); + + /* Some alignment is required. */ + if (srcx % 4 != 0 || dstx % 4 != 0 || size % 16 != 0 || + !ctx->has_stream_out) { + struct pipe_box box; + u_box_1d(srcx, size, &box); + util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box); + return; + } + + blitter_set_running_flag(ctx); + blitter_check_saved_vertex_states(ctx); + + vb.buffer = src; + vb.buffer_offset = srcx; + vb.stride = 4; + + pipe->set_vertex_buffers(pipe, 1, &vb); + pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf); + pipe->bind_vs_state(pipe, ctx->vs_pos_only); + if (ctx->has_geometry_shader) + pipe->bind_gs_state(pipe, NULL); + pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state); + + so_target = pipe->create_stream_output_target(pipe, dst, dstx, size); + pipe->set_stream_output_targets(pipe, 1, &so_target, 0); + + util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 16); + + blitter_restore_vertex_states(ctx); + blitter_unset_running_flag(ctx); + pipe_so_target_reference(&so_target, NULL); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h index 3e1457ae0..f605a7e7a 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.h +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h @@ -104,6 +104,9 @@ struct blitter_context int saved_num_vertex_buffers; struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS]; + + int saved_num_so_targets; + struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS]; }; /** @@ -131,6 +134,7 @@ struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) * - vertex elements * - vertex shader * - geometry shader (if supported) + * - stream output targets (if supported) * - rasterizer state */ @@ -213,6 +217,17 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0); +/** + * Copy data from one buffer to another using the Stream Output functionality. + * Some alignment is required, otherwise software fallback is used. + */ +void util_blitter_copy_buffer(struct blitter_context *blitter, + struct pipe_resource *dst, + unsigned dstx, + struct pipe_resource *src, + unsigned srcx, + unsigned size); + /** * Clear a region of a (color) surface to a constant value. * @@ -379,6 +394,20 @@ util_blitter_save_vertex_buffers(struct blitter_context *blitter, num_vertex_buffers); } +static INLINE void +util_blitter_save_so_targets(struct blitter_context *blitter, + int num_targets, + struct pipe_stream_output_target **targets) +{ + unsigned i; + assert(num_targets <= Elements(blitter->saved_so_targets)); + + blitter->saved_num_so_targets = num_targets; + for (i = 0; i < num_targets; i++) + pipe_so_target_reference(&blitter->saved_so_targets[i], + targets[i]); +} + #ifdef __cplusplus } #endif diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_describe.c b/mesalib/src/gallium/auxiliary/util/u_debug_describe.c index 3574accc0..df73ed83e 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_describe.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug_describe.c @@ -79,3 +79,13 @@ debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr) debug_describe_resource(res, ptr->texture); util_sprintf(buf, "pipe_sampler_view<%s,%s>", res, util_format_short_name(ptr->format)); } + +void +debug_describe_so_target(char* buf, + const struct pipe_stream_output_target *ptr) +{ + char res[128]; + debug_describe_resource(res, ptr->buffer); + util_sprintf(buf, "pipe_stream_output_target<%s,%u,%u>", res, + ptr->buffer_offset, ptr->buffer_size); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_describe.h b/mesalib/src/gallium/auxiliary/util/u_debug_describe.h index 447e838e4..4f7882b0b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_describe.h +++ b/mesalib/src/gallium/auxiliary/util/u_debug_describe.h @@ -1,49 +1,51 @@ -/************************************************************************** - * - * Copyright 2010 Luca Barbieri - * - * 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, sublicense, 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 NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - * - **************************************************************************/ - -#ifndef U_DEBUG_DESCRIBE_H_ -#define U_DEBUG_DESCRIBE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct pipe_reference; -struct pipe_resource; -struct pipe_surface; -struct pipe_sampler_view; - -/* a 256-byte buffer is necessary and sufficient */ -void debug_describe_reference(char* buf, const struct pipe_reference*ptr); -void debug_describe_resource(char* buf, const struct pipe_resource *ptr); -void debug_describe_surface(char* buf, const struct pipe_surface *ptr); -void debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr); - -#ifdef __cplusplus -} -#endif - -#endif /* U_DEBUG_DESCRIBE_H_ */ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + **************************************************************************/ + +#ifndef U_DEBUG_DESCRIBE_H_ +#define U_DEBUG_DESCRIBE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct pipe_reference; +struct pipe_resource; +struct pipe_surface; +struct pipe_sampler_view; + +/* a 256-byte buffer is necessary and sufficient */ +void debug_describe_reference(char* buf, const struct pipe_reference*ptr); +void debug_describe_resource(char* buf, const struct pipe_resource *ptr); +void debug_describe_surface(char* buf, const struct pipe_surface *ptr); +void debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr); +void debug_describe_so_target(char* buf, + const struct pipe_stream_output_target *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* U_DEBUG_DESCRIBE_H_ */ diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c index 917d7cd35..91f4aae69 100644 --- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c +++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c @@ -423,6 +423,7 @@ void util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state) { char str[8192]; + unsigned i; if(!state) { util_dump_null(stream); @@ -437,6 +438,24 @@ util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state) util_dump_string(stream, str); util_dump_member_end(stream); + util_dump_member_begin(stream, "stream_output"); + util_dump_struct_begin(stream, "pipe_stream_output_info"); + util_dump_member(stream, uint, &state->stream_output, num_outputs); + util_dump_member(stream, uint, &state->stream_output, stride); + util_dump_array_begin(stream); + for(i = 0; i < state->stream_output.num_outputs; ++i) { + util_dump_elem_begin(stream); + util_dump_struct_begin(stream, ""); /* anonymous */ + util_dump_member(stream, uint, &state->stream_output.output[i], register_index); + util_dump_member(stream, uint, &state->stream_output.output[i], register_mask); + util_dump_member(stream, uint, &state->stream_output.output[i], output_buffer); + util_dump_struct_end(stream); + util_dump_elem_end(stream); + } + util_dump_array_end(stream); + util_dump_struct_end(stream); + util_dump_member_end(stream); + util_dump_struct_end(stream); } diff --git a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c index 436a0e424..7cce815be 100644 --- a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1558,6 +1558,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); cso_save_fragment_sampler_views(ctx->cso); + cso_save_stream_outputs(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); @@ -1572,6 +1573,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + cso_set_stream_outputs(ctx->cso, 0, NULL, 0); set_fragment_shader(ctx, type); set_vertex_shader(ctx); @@ -1688,4 +1690,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_viewport(ctx->cso); cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); + cso_restore_stream_outputs(ctx->cso); } diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h index ad47439d0..44283909a 100644 --- a/mesalib/src/gallium/auxiliary/util/u_inlines.h +++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h @@ -1,459 +1,471 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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 TUNGSTEN GRAPHICS 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. - * - **************************************************************************/ - -#ifndef U_INLINES_H -#define U_INLINES_H - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_screen.h" -#include "util/u_debug.h" -#include "util/u_debug_describe.h" -#include "util/u_debug_refcnt.h" -#include "util/u_atomic.h" -#include "util/u_box.h" -#include "util/u_math.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Reference counting helper functions. - */ - - -static INLINE void -pipe_reference_init(struct pipe_reference *reference, unsigned count) -{ - p_atomic_set(&reference->count, count); -} - -static INLINE boolean -pipe_is_referenced(struct pipe_reference *reference) -{ - return p_atomic_read(&reference->count) != 0; -} - -/** - * Update reference counting. - * The old thing pointed to, if any, will be unreferenced. - * Both 'ptr' and 'reference' may be NULL. - * \return TRUE if the object's refcount hits zero and should be destroyed. - */ -static INLINE boolean -pipe_reference_described(struct pipe_reference *ptr, - struct pipe_reference *reference, - debug_reference_descriptor get_desc) -{ - boolean destroy = FALSE; - - if(ptr != reference) { - /* bump the reference.count first */ - if (reference) { - assert(pipe_is_referenced(reference)); - p_atomic_inc(&reference->count); - debug_reference(reference, get_desc, 1); - } - - if (ptr) { - assert(pipe_is_referenced(ptr)); - if (p_atomic_dec_zero(&ptr->count)) { - destroy = TRUE; - } - debug_reference(ptr, get_desc, -1); - } - } - - return destroy; -} - -static INLINE boolean -pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference) -{ - return pipe_reference_described(ptr, reference, - (debug_reference_descriptor)debug_describe_reference); -} - -static INLINE void -pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) -{ - struct pipe_surface *old_surf = *ptr; - - if (pipe_reference_described(&(*ptr)->reference, &surf->reference, - (debug_reference_descriptor)debug_describe_surface)) - old_surf->context->surface_destroy(old_surf->context, old_surf); - *ptr = surf; -} - -static INLINE void -pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex) -{ - struct pipe_resource *old_tex = *ptr; - - if (pipe_reference_described(&(*ptr)->reference, &tex->reference, - (debug_reference_descriptor)debug_describe_resource)) - old_tex->screen->resource_destroy(old_tex->screen, old_tex); - *ptr = tex; -} - -static INLINE void -pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view) -{ - struct pipe_sampler_view *old_view = *ptr; - - if (pipe_reference_described(&(*ptr)->reference, &view->reference, - (debug_reference_descriptor)debug_describe_sampler_view)) - old_view->context->sampler_view_destroy(old_view->context, old_view); - *ptr = view; -} - -static INLINE void -pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps, - struct pipe_resource *pt, unsigned level, unsigned layer, - unsigned flags) -{ - 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; -} - -static INLINE void -pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps, - struct pipe_resource *pt, unsigned level, unsigned layer, - unsigned flags) -{ - ps->texture = 0; - pipe_reference_init(&ps->reference, 1); - pipe_surface_reset(ctx, ps, pt, level, layer, flags); -} - -/* Return true if the surfaces are equal. */ -static INLINE boolean -pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2) -{ - return s1->texture == s2->texture && - s1->format == s2->format && - (s1->texture->target != PIPE_BUFFER || - (s1->u.buf.first_element == s2->u.buf.first_element && - s1->u.buf.last_element == s2->u.buf.last_element)) && - (s1->texture->target == PIPE_BUFFER || - (s1->u.tex.level == s2->u.tex.level && - s1->u.tex.first_layer == s2->u.tex.first_layer && - s1->u.tex.last_layer == s2->u.tex.last_layer)); -} - -/* - * Convenience wrappers for screen buffer functions. - */ - -static INLINE struct pipe_resource * -pipe_buffer_create( struct pipe_screen *screen, - unsigned bind, - unsigned usage, - unsigned size ) -{ - struct pipe_resource buffer; - memset(&buffer, 0, sizeof buffer); - buffer.target = PIPE_BUFFER; - buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ - buffer.bind = bind; - buffer.usage = usage; - buffer.flags = 0; - buffer.width0 = size; - buffer.height0 = 1; - buffer.depth0 = 1; - buffer.array_size = 1; - return screen->resource_create(screen, &buffer); -} - - -static INLINE struct pipe_resource * -pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size, - unsigned usage ) -{ - return screen->user_buffer_create(screen, ptr, size, usage); -} - -static INLINE void * -pipe_buffer_map_range(struct pipe_context *pipe, - struct pipe_resource *buffer, - unsigned offset, - unsigned length, - unsigned usage, - struct pipe_transfer **transfer) -{ - struct pipe_box box; - void *map; - - assert(offset < buffer->width0); - assert(offset + length <= buffer->width0); - assert(length); - - u_box_1d(offset, length, &box); - - *transfer = pipe->get_transfer( pipe, - buffer, - 0, - usage, - &box); - - if (*transfer == NULL) - return NULL; - - map = pipe->transfer_map( pipe, *transfer ); - if (map == NULL) { - pipe->transfer_destroy( pipe, *transfer ); - *transfer = NULL; - return NULL; - } - - /* Match old screen->buffer_map_range() behaviour, return pointer - * to where the beginning of the buffer would be: - */ - return (void *)((char *)map - offset); -} - - -static INLINE void * -pipe_buffer_map(struct pipe_context *pipe, - struct pipe_resource *buffer, - unsigned usage, - struct pipe_transfer **transfer) -{ - return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer); -} - - -static INLINE void -pipe_buffer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - if (transfer) { - pipe->transfer_unmap(pipe, transfer); - pipe->transfer_destroy(pipe, transfer); - } -} - -static INLINE void -pipe_buffer_flush_mapped_range(struct pipe_context *pipe, - struct pipe_transfer *transfer, - unsigned offset, - unsigned length) -{ - struct pipe_box box; - int transfer_offset; - - assert(length); - assert(transfer->box.x <= offset); - assert(offset + length <= transfer->box.x + transfer->box.width); - - /* Match old screen->buffer_flush_mapped_range() behaviour, where - * offset parameter is relative to the start of the buffer, not the - * mapped range. - */ - transfer_offset = offset - transfer->box.x; - - u_box_1d(transfer_offset, length, &box); - - pipe->transfer_flush_region(pipe, transfer, &box); -} - -static INLINE void -pipe_buffer_write(struct pipe_context *pipe, - struct pipe_resource *buf, - unsigned offset, - unsigned size, - const void *data) -{ - struct pipe_box box; - unsigned usage = PIPE_TRANSFER_WRITE; - - if (offset == 0 && size == buf->width0) { - usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; - } else { - usage |= PIPE_TRANSFER_DISCARD_RANGE; - } - - u_box_1d(offset, size, &box); - - pipe->transfer_inline_write( pipe, - buf, - 0, - usage, - &box, - data, - size, - 0); -} - -/** - * Special case for writing non-overlapping ranges. - * - * We can avoid GPU/CPU synchronization when writing range that has never - * been written before. - */ -static INLINE void -pipe_buffer_write_nooverlap(struct pipe_context *pipe, - struct pipe_resource *buf, - unsigned offset, unsigned size, - const void *data) -{ - struct pipe_box box; - - u_box_1d(offset, size, &box); - - pipe->transfer_inline_write(pipe, - buf, - 0, - (PIPE_TRANSFER_WRITE | - PIPE_TRANSFER_NOOVERWRITE), - &box, - data, - 0, 0); -} - -static INLINE void -pipe_buffer_read(struct pipe_context *pipe, - struct pipe_resource *buf, - unsigned offset, - unsigned size, - void *data) -{ - struct pipe_transfer *src_transfer; - ubyte *map; - - map = (ubyte *) pipe_buffer_map_range(pipe, - buf, - offset, size, - PIPE_TRANSFER_READ, - &src_transfer); - - if (map) - memcpy(data, map + offset, size); - - pipe_buffer_unmap(pipe, src_transfer); -} - -static INLINE struct pipe_transfer * -pipe_get_transfer( struct pipe_context *context, - struct pipe_resource *resource, - unsigned level, unsigned layer, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, - unsigned w, unsigned h) -{ - struct pipe_box box; - u_box_2d_zslice( x, y, layer, w, h, &box ); - return context->get_transfer( context, - resource, - level, - usage, - &box ); -} - -static INLINE void * -pipe_transfer_map( struct pipe_context *context, - struct pipe_transfer *transfer ) -{ - return context->transfer_map( context, transfer ); -} - -static INLINE void -pipe_transfer_unmap( struct pipe_context *context, - struct pipe_transfer *transfer ) -{ - context->transfer_unmap( context, transfer ); -} - - -static INLINE void -pipe_transfer_destroy( struct pipe_context *context, - struct pipe_transfer *transfer ) -{ - context->transfer_destroy(context, transfer); -} - - -static INLINE boolean util_get_offset( - const struct pipe_rasterizer_state *templ, - unsigned fill_mode) -{ - switch(fill_mode) { - case PIPE_POLYGON_MODE_POINT: - return templ->offset_point; - case PIPE_POLYGON_MODE_LINE: - return templ->offset_line; - case PIPE_POLYGON_MODE_FILL: - return templ->offset_tri; - default: - assert(0); - return FALSE; - } -} - -/** - * This function is used to copy an array of pipe_vertex_buffer structures, - * while properly referencing the pipe_vertex_buffer::buffer member. - * - * \sa util_copy_framebuffer_state - */ -static INLINE void util_copy_vertex_buffers(struct pipe_vertex_buffer *dst, - unsigned *dst_count, - const struct pipe_vertex_buffer *src, - unsigned src_count) -{ - unsigned i; - - /* Reference the buffers of 'src' in 'dst'. */ - for (i = 0; i < src_count; i++) { - pipe_resource_reference(&dst[i].buffer, src[i].buffer); - } - /* Unreference the rest of the buffers in 'dst'. */ - for (; i < *dst_count; i++) { - pipe_resource_reference(&dst[i].buffer, NULL); - } - - /* Update the size of 'dst' and copy over the other members - * of pipe_vertex_buffer. */ - *dst_count = src_count; - memcpy(dst, src, src_count * sizeof(struct pipe_vertex_buffer)); -} - -#ifdef __cplusplus -} -#endif - -#endif /* U_INLINES_H */ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#ifndef U_INLINES_H +#define U_INLINES_H + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_screen.h" +#include "util/u_debug.h" +#include "util/u_debug_describe.h" +#include "util/u_debug_refcnt.h" +#include "util/u_atomic.h" +#include "util/u_box.h" +#include "util/u_math.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Reference counting helper functions. + */ + + +static INLINE void +pipe_reference_init(struct pipe_reference *reference, unsigned count) +{ + p_atomic_set(&reference->count, count); +} + +static INLINE boolean +pipe_is_referenced(struct pipe_reference *reference) +{ + return p_atomic_read(&reference->count) != 0; +} + +/** + * Update reference counting. + * The old thing pointed to, if any, will be unreferenced. + * Both 'ptr' and 'reference' may be NULL. + * \return TRUE if the object's refcount hits zero and should be destroyed. + */ +static INLINE boolean +pipe_reference_described(struct pipe_reference *ptr, + struct pipe_reference *reference, + debug_reference_descriptor get_desc) +{ + boolean destroy = FALSE; + + if(ptr != reference) { + /* bump the reference.count first */ + if (reference) { + assert(pipe_is_referenced(reference)); + p_atomic_inc(&reference->count); + debug_reference(reference, get_desc, 1); + } + + if (ptr) { + assert(pipe_is_referenced(ptr)); + if (p_atomic_dec_zero(&ptr->count)) { + destroy = TRUE; + } + debug_reference(ptr, get_desc, -1); + } + } + + return destroy; +} + +static INLINE boolean +pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference) +{ + return pipe_reference_described(ptr, reference, + (debug_reference_descriptor)debug_describe_reference); +} + +static INLINE void +pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) +{ + struct pipe_surface *old_surf = *ptr; + + if (pipe_reference_described(&(*ptr)->reference, &surf->reference, + (debug_reference_descriptor)debug_describe_surface)) + old_surf->context->surface_destroy(old_surf->context, old_surf); + *ptr = surf; +} + +static INLINE void +pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex) +{ + struct pipe_resource *old_tex = *ptr; + + if (pipe_reference_described(&(*ptr)->reference, &tex->reference, + (debug_reference_descriptor)debug_describe_resource)) + old_tex->screen->resource_destroy(old_tex->screen, old_tex); + *ptr = tex; +} + +static INLINE void +pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view) +{ + struct pipe_sampler_view *old_view = *ptr; + + if (pipe_reference_described(&(*ptr)->reference, &view->reference, + (debug_reference_descriptor)debug_describe_sampler_view)) + old_view->context->sampler_view_destroy(old_view->context, old_view); + *ptr = view; +} + +static INLINE void +pipe_so_target_reference(struct pipe_stream_output_target **ptr, + struct pipe_stream_output_target *target) +{ + struct pipe_stream_output_target *old = *ptr; + + if (pipe_reference_described(&(*ptr)->reference, &target->reference, + (debug_reference_descriptor)debug_describe_so_target)) + old->context->stream_output_target_destroy(old->context, old); + *ptr = target; +} + +static INLINE void +pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps, + struct pipe_resource *pt, unsigned level, unsigned layer, + unsigned flags) +{ + 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; +} + +static INLINE void +pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps, + struct pipe_resource *pt, unsigned level, unsigned layer, + unsigned flags) +{ + ps->texture = 0; + pipe_reference_init(&ps->reference, 1); + pipe_surface_reset(ctx, ps, pt, level, layer, flags); +} + +/* Return true if the surfaces are equal. */ +static INLINE boolean +pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2) +{ + return s1->texture == s2->texture && + s1->format == s2->format && + (s1->texture->target != PIPE_BUFFER || + (s1->u.buf.first_element == s2->u.buf.first_element && + s1->u.buf.last_element == s2->u.buf.last_element)) && + (s1->texture->target == PIPE_BUFFER || + (s1->u.tex.level == s2->u.tex.level && + s1->u.tex.first_layer == s2->u.tex.first_layer && + s1->u.tex.last_layer == s2->u.tex.last_layer)); +} + +/* + * Convenience wrappers for screen buffer functions. + */ + +static INLINE struct pipe_resource * +pipe_buffer_create( struct pipe_screen *screen, + unsigned bind, + unsigned usage, + unsigned size ) +{ + struct pipe_resource buffer; + memset(&buffer, 0, sizeof buffer); + buffer.target = PIPE_BUFFER; + buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ + buffer.bind = bind; + buffer.usage = usage; + buffer.flags = 0; + buffer.width0 = size; + buffer.height0 = 1; + buffer.depth0 = 1; + buffer.array_size = 1; + return screen->resource_create(screen, &buffer); +} + + +static INLINE struct pipe_resource * +pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size, + unsigned usage ) +{ + return screen->user_buffer_create(screen, ptr, size, usage); +} + +static INLINE void * +pipe_buffer_map_range(struct pipe_context *pipe, + struct pipe_resource *buffer, + unsigned offset, + unsigned length, + unsigned usage, + struct pipe_transfer **transfer) +{ + struct pipe_box box; + void *map; + + assert(offset < buffer->width0); + assert(offset + length <= buffer->width0); + assert(length); + + u_box_1d(offset, length, &box); + + *transfer = pipe->get_transfer( pipe, + buffer, + 0, + usage, + &box); + + if (*transfer == NULL) + return NULL; + + map = pipe->transfer_map( pipe, *transfer ); + if (map == NULL) { + pipe->transfer_destroy( pipe, *transfer ); + *transfer = NULL; + return NULL; + } + + /* Match old screen->buffer_map_range() behaviour, return pointer + * to where the beginning of the buffer would be: + */ + return (void *)((char *)map - offset); +} + + +static INLINE void * +pipe_buffer_map(struct pipe_context *pipe, + struct pipe_resource *buffer, + unsigned usage, + struct pipe_transfer **transfer) +{ + return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer); +} + + +static INLINE void +pipe_buffer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + if (transfer) { + pipe->transfer_unmap(pipe, transfer); + pipe->transfer_destroy(pipe, transfer); + } +} + +static INLINE void +pipe_buffer_flush_mapped_range(struct pipe_context *pipe, + struct pipe_transfer *transfer, + unsigned offset, + unsigned length) +{ + struct pipe_box box; + int transfer_offset; + + assert(length); + assert(transfer->box.x <= offset); + assert(offset + length <= transfer->box.x + transfer->box.width); + + /* Match old screen->buffer_flush_mapped_range() behaviour, where + * offset parameter is relative to the start of the buffer, not the + * mapped range. + */ + transfer_offset = offset - transfer->box.x; + + u_box_1d(transfer_offset, length, &box); + + pipe->transfer_flush_region(pipe, transfer, &box); +} + +static INLINE void +pipe_buffer_write(struct pipe_context *pipe, + struct pipe_resource *buf, + unsigned offset, + unsigned size, + const void *data) +{ + struct pipe_box box; + unsigned usage = PIPE_TRANSFER_WRITE; + + if (offset == 0 && size == buf->width0) { + usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; + } else { + usage |= PIPE_TRANSFER_DISCARD_RANGE; + } + + u_box_1d(offset, size, &box); + + pipe->transfer_inline_write( pipe, + buf, + 0, + usage, + &box, + data, + size, + 0); +} + +/** + * Special case for writing non-overlapping ranges. + * + * We can avoid GPU/CPU synchronization when writing range that has never + * been written before. + */ +static INLINE void +pipe_buffer_write_nooverlap(struct pipe_context *pipe, + struct pipe_resource *buf, + unsigned offset, unsigned size, + const void *data) +{ + struct pipe_box box; + + u_box_1d(offset, size, &box); + + pipe->transfer_inline_write(pipe, + buf, + 0, + (PIPE_TRANSFER_WRITE | + PIPE_TRANSFER_NOOVERWRITE), + &box, + data, + 0, 0); +} + +static INLINE void +pipe_buffer_read(struct pipe_context *pipe, + struct pipe_resource *buf, + unsigned offset, + unsigned size, + void *data) +{ + struct pipe_transfer *src_transfer; + ubyte *map; + + map = (ubyte *) pipe_buffer_map_range(pipe, + buf, + offset, size, + PIPE_TRANSFER_READ, + &src_transfer); + + if (map) + memcpy(data, map + offset, size); + + pipe_buffer_unmap(pipe, src_transfer); +} + +static INLINE struct pipe_transfer * +pipe_get_transfer( struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, unsigned layer, + enum pipe_transfer_usage usage, + unsigned x, unsigned y, + unsigned w, unsigned h) +{ + struct pipe_box box; + u_box_2d_zslice( x, y, layer, w, h, &box ); + return context->get_transfer( context, + resource, + level, + usage, + &box ); +} + +static INLINE void * +pipe_transfer_map( struct pipe_context *context, + struct pipe_transfer *transfer ) +{ + return context->transfer_map( context, transfer ); +} + +static INLINE void +pipe_transfer_unmap( struct pipe_context *context, + struct pipe_transfer *transfer ) +{ + context->transfer_unmap( context, transfer ); +} + + +static INLINE void +pipe_transfer_destroy( struct pipe_context *context, + struct pipe_transfer *transfer ) +{ + context->transfer_destroy(context, transfer); +} + + +static INLINE boolean util_get_offset( + const struct pipe_rasterizer_state *templ, + unsigned fill_mode) +{ + switch(fill_mode) { + case PIPE_POLYGON_MODE_POINT: + return templ->offset_point; + case PIPE_POLYGON_MODE_LINE: + return templ->offset_line; + case PIPE_POLYGON_MODE_FILL: + return templ->offset_tri; + default: + assert(0); + return FALSE; + } +} + +/** + * This function is used to copy an array of pipe_vertex_buffer structures, + * while properly referencing the pipe_vertex_buffer::buffer member. + * + * \sa util_copy_framebuffer_state + */ +static INLINE void util_copy_vertex_buffers(struct pipe_vertex_buffer *dst, + unsigned *dst_count, + const struct pipe_vertex_buffer *src, + unsigned src_count) +{ + unsigned i; + + /* Reference the buffers of 'src' in 'dst'. */ + for (i = 0; i < src_count; i++) { + pipe_resource_reference(&dst[i].buffer, src[i].buffer); + } + /* Unreference the rest of the buffers in 'dst'. */ + for (; i < *dst_count; i++) { + pipe_resource_reference(&dst[i].buffer, NULL); + } + + /* Update the size of 'dst' and copy over the other members + * of pipe_vertex_buffer. */ + *dst_count = src_count; + memcpy(dst, src, src_count * sizeof(struct pipe_vertex_buffer)); +} + +#ifdef __cplusplus +} +#endif + +#endif /* U_INLINES_H */ diff --git a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c index 141763190..320c0f7a8 100644 --- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c @@ -1,243 +1,255 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * Copyright 2009 Marek Olšák - * - * 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 TUNGSTEN GRAPHICS 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. - * - **************************************************************************/ - -/** - * @file - * Simple vertex/fragment shader generators. - * - * @author Brian Paul - Marek Olšák - */ - - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_state.h" -#include "util/u_simple_shaders.h" -#include "util/u_debug.h" -#include "tgsi/tgsi_ureg.h" - - - -/** - * Make simple vertex pass-through shader. - * \param num_attribs number of attributes to pass through - * \param semantic_names array of semantic names for each attribute - * \param semantic_indexes array of semantic indexes for each attribute - */ -void * -util_make_vertex_passthrough_shader(struct pipe_context *pipe, - uint num_attribs, - const uint *semantic_names, - const uint *semantic_indexes) -{ - struct ureg_program *ureg; - uint i; - - ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); - if (ureg == NULL) - return NULL; - - for (i = 0; i < num_attribs; i++) { - struct ureg_src src; - struct ureg_dst dst; - - src = ureg_DECL_vs_input( ureg, i ); - - dst = ureg_DECL_output( ureg, - semantic_names[i], - semantic_indexes[i]); - - ureg_MOV( ureg, dst, src ); - } - - ureg_END( ureg ); - - return ureg_create_shader_and_destroy( ureg, pipe ); -} - - -/** - * Make simple fragment texture shader: - * IMM {0,0,0,1} // (if writemask != 0xf) - * MOV OUT[0], IMM[0] // (if writemask != 0xf) - * TEX OUT[0].writemask, IN[0], SAMP[0], 2D; - * END; - * - * \param tex_target one of PIPE_TEXTURE_x - * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE - * \param writemask mask of TGSI_WRITEMASK_x - */ -void * -util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode, - unsigned writemask ) -{ - struct ureg_program *ureg; - struct ureg_src sampler; - struct ureg_src tex; - struct ureg_dst out; - - assert(interp_mode == TGSI_INTERPOLATE_LINEAR || - interp_mode == TGSI_INTERPOLATE_PERSPECTIVE); - - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) - return NULL; - - sampler = ureg_DECL_sampler( ureg, 0 ); - - tex = ureg_DECL_fs_input( ureg, - TGSI_SEMANTIC_GENERIC, 0, - interp_mode ); - - out = ureg_DECL_output( ureg, - TGSI_SEMANTIC_COLOR, - 0 ); - - if (writemask != TGSI_WRITEMASK_XYZW) { - struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); - - ureg_MOV( ureg, out, imm ); - } - - ureg_TEX( ureg, - ureg_writemask(out, writemask), - tex_target, tex, sampler ); - ureg_END( ureg ); - - return ureg_create_shader_and_destroy( ureg, pipe ); -} - - -/** - * Make a simple fragment shader that sets the output color to a color - * taken from a texture. - * \param tex_target one of PIPE_TEXTURE_x - */ -void * -util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, - unsigned interp_mode) -{ - return util_make_fragment_tex_shader_writemask( pipe, - tex_target, - interp_mode, - TGSI_WRITEMASK_XYZW ); -} - - -/** - * Make a simple fragment texture shader which reads an X component from - * a texture and writes it as depth. - */ -void * -util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode) -{ - struct ureg_program *ureg; - struct ureg_src sampler; - struct ureg_src tex; - struct ureg_dst out, depth; - struct ureg_src imm; - - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) - return NULL; - - sampler = ureg_DECL_sampler( ureg, 0 ); - - tex = ureg_DECL_fs_input( ureg, - TGSI_SEMANTIC_GENERIC, 0, - interp_mode ); - - out = ureg_DECL_output( ureg, - TGSI_SEMANTIC_COLOR, - 0 ); - - depth = ureg_DECL_output( ureg, - TGSI_SEMANTIC_POSITION, - 0 ); - - imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); - - ureg_MOV( ureg, out, imm ); - - ureg_TEX( ureg, - ureg_writemask(depth, TGSI_WRITEMASK_Z), - tex_target, tex, sampler ); - ureg_END( ureg ); - - return ureg_create_shader_and_destroy( ureg, pipe ); -} - - -/** - * Make simple fragment color pass-through shader. - */ -void * -util_make_fragment_passthrough_shader(struct pipe_context *pipe) -{ - return util_make_fragment_cloneinput_shader(pipe, 1, TGSI_SEMANTIC_COLOR, - TGSI_INTERPOLATE_PERSPECTIVE); -} - - -/** - * Make a fragment shader that copies the input color to N output colors. - */ -void * -util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, - int input_semantic, - int input_interpolate) -{ - struct ureg_program *ureg; - struct ureg_src src; - struct ureg_dst dst[PIPE_MAX_COLOR_BUFS]; - int i; - - assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); - - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) - return NULL; - - src = ureg_DECL_fs_input( ureg, input_semantic, 0, - input_interpolate ); - - for (i = 0; i < num_cbufs; i++) - dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i ); - - for (i = 0; i < num_cbufs; i++) - ureg_MOV( ureg, dst[i], src ); - - ureg_END( ureg ); - - return ureg_create_shader_and_destroy( ureg, pipe ); -} +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * Copyright 2009 Marek Olšák + * + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +/** + * @file + * Simple vertex/fragment shader generators. + * + * @author Brian Paul + Marek Olšák + */ + + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" +#include "util/u_simple_shaders.h" +#include "util/u_debug.h" +#include "tgsi/tgsi_ureg.h" + + + +/** + * Make simple vertex pass-through shader. + * \param num_attribs number of attributes to pass through + * \param semantic_names array of semantic names for each attribute + * \param semantic_indexes array of semantic indexes for each attribute + */ +void * +util_make_vertex_passthrough_shader(struct pipe_context *pipe, + uint num_attribs, + const uint *semantic_names, + const uint *semantic_indexes) +{ + return util_make_vertex_passthrough_shader_with_so(pipe, num_attribs, + semantic_names, + semantic_indexes, NULL); +} + +void * +util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, + uint num_attribs, + const uint *semantic_names, + const uint *semantic_indexes, + const struct pipe_stream_output_info *so) +{ + struct ureg_program *ureg; + uint i; + + ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); + if (ureg == NULL) + return NULL; + + for (i = 0; i < num_attribs; i++) { + struct ureg_src src; + struct ureg_dst dst; + + src = ureg_DECL_vs_input( ureg, i ); + + dst = ureg_DECL_output( ureg, + semantic_names[i], + semantic_indexes[i]); + + ureg_MOV( ureg, dst, src ); + } + + ureg_END( ureg ); + + return ureg_create_shader_with_so_and_destroy( ureg, pipe, so ); +} + + +/** + * Make simple fragment texture shader: + * IMM {0,0,0,1} // (if writemask != 0xf) + * MOV OUT[0], IMM[0] // (if writemask != 0xf) + * TEX OUT[0].writemask, IN[0], SAMP[0], 2D; + * END; + * + * \param tex_target one of PIPE_TEXTURE_x + * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE + * \param writemask mask of TGSI_WRITEMASK_x + */ +void * +util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, + unsigned tex_target, + unsigned interp_mode, + unsigned writemask ) +{ + struct ureg_program *ureg; + struct ureg_src sampler; + struct ureg_src tex; + struct ureg_dst out; + + assert(interp_mode == TGSI_INTERPOLATE_LINEAR || + interp_mode == TGSI_INTERPOLATE_PERSPECTIVE); + + ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); + if (ureg == NULL) + return NULL; + + sampler = ureg_DECL_sampler( ureg, 0 ); + + tex = ureg_DECL_fs_input( ureg, + TGSI_SEMANTIC_GENERIC, 0, + interp_mode ); + + out = ureg_DECL_output( ureg, + TGSI_SEMANTIC_COLOR, + 0 ); + + if (writemask != TGSI_WRITEMASK_XYZW) { + struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); + + ureg_MOV( ureg, out, imm ); + } + + ureg_TEX( ureg, + ureg_writemask(out, writemask), + tex_target, tex, sampler ); + ureg_END( ureg ); + + return ureg_create_shader_and_destroy( ureg, pipe ); +} + + +/** + * Make a simple fragment shader that sets the output color to a color + * taken from a texture. + * \param tex_target one of PIPE_TEXTURE_x + */ +void * +util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, + unsigned interp_mode) +{ + return util_make_fragment_tex_shader_writemask( pipe, + tex_target, + interp_mode, + TGSI_WRITEMASK_XYZW ); +} + + +/** + * Make a simple fragment texture shader which reads an X component from + * a texture and writes it as depth. + */ +void * +util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, + unsigned tex_target, + unsigned interp_mode) +{ + struct ureg_program *ureg; + struct ureg_src sampler; + struct ureg_src tex; + struct ureg_dst out, depth; + struct ureg_src imm; + + ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); + if (ureg == NULL) + return NULL; + + sampler = ureg_DECL_sampler( ureg, 0 ); + + tex = ureg_DECL_fs_input( ureg, + TGSI_SEMANTIC_GENERIC, 0, + interp_mode ); + + out = ureg_DECL_output( ureg, + TGSI_SEMANTIC_COLOR, + 0 ); + + depth = ureg_DECL_output( ureg, + TGSI_SEMANTIC_POSITION, + 0 ); + + imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); + + ureg_MOV( ureg, out, imm ); + + ureg_TEX( ureg, + ureg_writemask(depth, TGSI_WRITEMASK_Z), + tex_target, tex, sampler ); + ureg_END( ureg ); + + return ureg_create_shader_and_destroy( ureg, pipe ); +} + + +/** + * Make simple fragment color pass-through shader. + */ +void * +util_make_fragment_passthrough_shader(struct pipe_context *pipe) +{ + return util_make_fragment_cloneinput_shader(pipe, 1, TGSI_SEMANTIC_COLOR, + TGSI_INTERPOLATE_PERSPECTIVE); +} + + +/** + * Make a fragment shader that copies the input color to N output colors. + */ +void * +util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, + int input_semantic, + int input_interpolate) +{ + struct ureg_program *ureg; + struct ureg_src src; + struct ureg_dst dst[PIPE_MAX_COLOR_BUFS]; + int i; + + assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); + + ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); + if (ureg == NULL) + return NULL; + + src = ureg_DECL_fs_input( ureg, input_semantic, 0, + input_interpolate ); + + for (i = 0; i < num_cbufs; i++) + dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i ); + + for (i = 0; i < num_cbufs; i++) + ureg_MOV( ureg, dst[i], src ); + + ureg_END( ureg ); + + return ureg_create_shader_and_destroy( ureg, pipe ); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h index 9a0fe6375..5f31b72c4 100644 --- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h @@ -1,83 +1,91 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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 TUNGSTEN GRAPHICS 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. - * - **************************************************************************/ - - -#ifndef U_SIMPLE_SHADERS_H -#define U_SIMPLE_SHADERS_H - - -#include "pipe/p_compiler.h" - - -struct pipe_context; -struct pipe_shader_state; - - -#ifdef __cplusplus -extern "C" { -#endif - - -extern void * -util_make_vertex_passthrough_shader(struct pipe_context *pipe, - uint num_attribs, - const uint *semantic_names, - const uint *semantic_indexes); - - -extern void * -util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode, - unsigned writemask); - -extern void * -util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, - unsigned interp_mode); - - -extern void * -util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode); - - -extern void * -util_make_fragment_passthrough_shader(struct pipe_context *pipe); - - -extern void * -util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, - int input_semantic, - int input_interpolate); - -#ifdef __cplusplus -} -#endif - - -#endif +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + + +#ifndef U_SIMPLE_SHADERS_H +#define U_SIMPLE_SHADERS_H + + +#include "pipe/p_compiler.h" + + +struct pipe_context; +struct pipe_shader_state; +struct pipe_stream_output_info; + + +#ifdef __cplusplus +extern "C" { +#endif + + +extern void * +util_make_vertex_passthrough_shader(struct pipe_context *pipe, + uint num_attribs, + const uint *semantic_names, + const uint *semantic_indexes); + +extern void * +util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, + uint num_attribs, + const uint *semantic_names, + const uint *semantic_indexes, + const struct pipe_stream_output_info *so); + + +extern void * +util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, + unsigned tex_target, + unsigned interp_mode, + unsigned writemask); + +extern void * +util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, + unsigned interp_mode); + + +extern void * +util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, + unsigned tex_target, + unsigned interp_mode); + + +extern void * +util_make_fragment_passthrough_shader(struct pipe_context *pipe); + + +extern void * +util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, + int input_semantic, + int input_interpolate); + +#ifdef __cplusplus +} +#endif + + +#endif -- cgit v1.2.3