diff options
Diffstat (limited to 'mesalib')
58 files changed, 2216 insertions, 1660 deletions
| 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   */ @@ -214,6 +218,17 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,                                      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.   *   * These states must be saved in the blitter in addition to the state objects @@ -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 <maraeo@gmail.com>
 - *
 - * Permission is hereby granted, free of charge, to any person obtaining a
 - * copy of this software and associated documentation files (the
 - * "Software"), to deal in the Software without restriction, including
 - * without limitation 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 <maraeo@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation 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 diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 259041f67..1683c85e9 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -2943,43 +2943,20 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,           break;        } -      /* Set MaxLevel large enough to hold the new level when we allocate it  */ +      /* Allocate storage for the destination mipmap image(s) */ + +      /* Set MaxLevel large enough to hold the new level when we allocate it */        _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); -      /* Create empty dest image */ -      if (target == GL_TEXTURE_1D) { -         _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat, -                          dstWidth, border, -                          GL_RGBA, GL_UNSIGNED_BYTE, NULL); -      } -      else if (target == GL_TEXTURE_3D) { -         _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat, -                          dstWidth, dstHeight, dstDepth, border, -                          GL_RGBA, GL_UNSIGNED_BYTE, NULL); -      } -      else { -         /* 2D or cube */ -         _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat, -                          dstWidth, dstHeight, border, -                          GL_RGBA, GL_UNSIGNED_BYTE, NULL); - -         if (target == GL_TEXTURE_CUBE_MAP) { -            /* If texturing from a cube, we need to make sure all src faces -             * have been defined (even if we're not sampling from them.) -             * Otherwise the texture object will be 'incomplete' and -             * texturing from it will not be allowed. -             */ -            GLuint face; -            for (face = 0; face < 6; face++) { -               if (!texObj->Image[face][srcLevel] || -                   texObj->Image[face][srcLevel]->Width != srcWidth) { -                  _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, -                                   srcLevel, srcImage->InternalFormat, -                                   srcWidth, srcHeight, border, -                                   GL_RGBA, GL_UNSIGNED_BYTE, NULL); -               } -            } -         } +      if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel, +                                      dstWidth, dstHeight, dstDepth, +                                      srcImage->Border, +                                      srcImage->InternalFormat, +                                      srcImage->TexFormat)) { +         /* All done.  We either ran out of memory or we would go beyond the +          * last valid level of an immutable texture if we continued. +          */ +         break;        }        /* limit minification to src level */ diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index efdecb212..945f12752 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -474,3 +474,37 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,     return GL_TRUE;  } + + +#if FEATURE_EXT_transform_feedback + +GLboolean +_mesa_validate_DrawTransformFeedback(struct gl_context *ctx, +                                     GLenum mode, +                                     struct gl_transform_feedback_object *obj) +{ +   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + +   if (!_mesa_valid_prim_mode(ctx, mode)) { +      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawTransformFeedback(mode)"); +      return GL_FALSE; +   } + +   if (!obj) { +      _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback(name)"); +      return GL_FALSE; +   } + +   if (!obj->EndedAnytime) { +      _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback"); +      return GL_FALSE; +   } + +   if (!check_valid_to_render(ctx, "glDrawTransformFeedback")) { +      return GL_FALSE; +   } + +   return GL_TRUE; +} + +#endif diff --git a/mesalib/src/mesa/main/api_validate.h b/mesalib/src/mesa/main/api_validate.h index 7d6a66012..f4948424c 100644 --- a/mesalib/src/mesa/main/api_validate.h +++ b/mesalib/src/mesa/main/api_validate.h @@ -29,9 +29,11 @@  #include "glheader.h" +#include "mfeatures.h"  struct gl_buffer_object;  struct gl_context; +struct gl_transform_feedback_object;  extern GLuint @@ -70,5 +72,13 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,                                       const GLvoid *indices, GLsizei primcount,                                       GLint basevertex); +#if FEATURE_EXT_transform_feedback + +extern GLboolean +_mesa_validate_DrawTransformFeedback(struct gl_context *ctx, +                                     GLenum mode, +                                     struct gl_transform_feedback_object *obj); + +#endif  #endif diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index d6f70d1c4..01cfff8ab 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -964,8 +964,6 @@ struct dd_function_table {                                    struct gl_transform_feedback_object *obj);     void (*ResumeTransformFeedback)(struct gl_context *ctx,                                     struct gl_transform_feedback_object *obj); -   void (*DrawTransformFeedback)(struct gl_context *ctx, GLenum mode, -                                 struct gl_transform_feedback_object *obj);     /**      * \name GL_NV_texture_barrier interface @@ -1194,6 +1192,7 @@ typedef struct {     void (GLAPIENTRYP DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count,                                              GLenum type, const GLvoid *indices,                                              GLsizei primcount, GLint basevertex); +   void (GLAPIENTRYP DrawTransformFeedback)(GLenum mode, GLuint name);     /*@}*/     /** diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index e1acc8028..b3edae0e6 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -1422,7 +1422,7 @@ save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)        }     }     if (ctx->ExecuteFlag) { -      /*CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));*/ +      CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));     }  } @@ -1450,7 +1450,7 @@ save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)        }     }     if (ctx->ExecuteFlag) { -      /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/ +      CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));     }  } @@ -1478,7 +1478,7 @@ save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)        }     }     if (ctx->ExecuteFlag) { -      /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/ +      CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));     }  } @@ -1498,7 +1498,7 @@ save_ClearBufferfi(GLenum buffer, GLint drawbuffer,        n[4].i = stencil;     }     if (ctx->ExecuteFlag) { -      /*CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));*/ +      CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));     }  } @@ -7545,36 +7545,36 @@ execute_list(struct gl_context *ctx, GLuint list)              break;           case OPCODE_CLEAR_BUFFER_IV:              { -               /*GLint value[4]; +               GLint value[4];                 value[0] = n[3].i;                 value[1] = n[4].i;                 value[2] = n[5].i;                 value[3] = n[6].i; -               CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/ +               CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));              }              break;           case OPCODE_CLEAR_BUFFER_UIV:              { -               /*GLuint value[4]; +               GLuint value[4];                 value[0] = n[3].ui;                 value[1] = n[4].ui;                 value[2] = n[5].ui;                 value[3] = n[6].ui; -               CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/ +               CALL_ClearBufferuiv(ctx->Exec, (n[1].e, n[2].i, value));              }              break;           case OPCODE_CLEAR_BUFFER_FV:              { -               /*GLfloat value[4]; +               GLfloat value[4];                 value[0] = n[3].f;                 value[1] = n[4].f;                 value[2] = n[5].f;                 value[3] = n[6].f; -               CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/ +               CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));              }              break;           case OPCODE_CLEAR_BUFFER_FI: -            /*CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));*/ +            CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));              break;           case OPCODE_CLEAR_COLOR:              CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 611a6d0b0..912170aba 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -819,7 +819,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,                 fbo_incomplete("width or height mismatch", -1);                 return;              } -            /* check that all color buffer have same format */ +            /* check that all color buffers are the same format */              if (intFormat != GL_NONE && f != intFormat) {                 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;                 fbo_incomplete("format mismatch", -1); @@ -831,8 +831,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,              fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;              fbo_incomplete("inconsistant number of samples", i);              return; -         }             - +         }        }     } @@ -1273,7 +1272,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)     case GL_RG32I:        return ctx->Extensions.ARB_texture_rg &&               ctx->Extensions.EXT_texture_integer ? GL_RG : 0; -       +     case GL_INTENSITY8I_EXT:     case GL_INTENSITY8UI_EXT:     case GL_INTENSITY16I_EXT: @@ -1820,7 +1819,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)                    /* bind default */                    ASSERT(fb->RefCount >= 2);                    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -               }     +               }              }  	    /* remove from hash table immediately, to free the ID */ @@ -1897,6 +1896,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)     return buffer->_Status;  } +  /**   * Replicate the src attachment point. Used by framebuffer_texture() when   * the same texture is attached at GL_DEPTH_ATTACHMENT and @@ -1911,7 +1911,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,     struct gl_renderbuffer_attachment *src_att = &fb->Attachment[src];     assert(src_att->Texture != NULL); -   assert (src_att->Renderbuffer != NULL); +   assert(src_att->Renderbuffer != NULL);     _mesa_reference_texobj(&dst_att->Texture, src_att->Texture);     _mesa_reference_renderbuffer(&dst_att->Renderbuffer, src_att->Renderbuffer); @@ -1921,6 +1921,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,     dst_att->Zoffset = src_att->Zoffset;  } +  /**   * Common code called by glFramebufferTexture1D/2D/3DEXT().   */ @@ -1949,7 +1950,6 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,        return;     } -     /* The textarget, level, and zoffset parameters are only validated if      * texture is non-zero.      */ @@ -2002,7 +2002,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,           }        } -      if ((level < 0) ||  +      if ((level < 0) ||            (level >= _mesa_max_texture_levels(ctx, texObj->Target))) {           _mesa_error(ctx, GL_INVALID_VALUE,                       "glFramebufferTexture%sEXT(level)", caller); @@ -2031,7 +2031,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,  	 reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH,  	                                      BUFFER_STENCIL);        } else if (attachment == GL_STENCIL_ATTACHMENT && -	         texObj== fb->Attachment[BUFFER_DEPTH].Texture) { +	         texObj == fb->Attachment[BUFFER_DEPTH].Texture) {  	 /* As above, but with depth and stencil juxtasposed. */  	 reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,  	                                      BUFFER_DEPTH); @@ -2797,6 +2797,7 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,  }  #endif /* FEATURE_EXT_framebuffer_blit */ +  #if FEATURE_ARB_geometry_shader4  void GLAPIENTRY  _mesa_FramebufferTextureARB(GLenum target, GLenum attachment, @@ -2808,6 +2809,7 @@ _mesa_FramebufferTextureARB(GLenum target, GLenum attachment,                 "not implemented!");  } +  void GLAPIENTRY  _mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,                                  GLuint texture, GLint level, GLenum face) diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index 4f23f3dec..32d198ce8 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -1822,6 +1822,10 @@ unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst) +/** + * Unpack Z values. + * The returned values will always be in the range [0.0, 1.0]. + */  void  _mesa_unpack_float_z_row(gl_format format, GLuint n,                           const void *src, GLfloat *dst) @@ -1901,6 +1905,10 @@ unpack_uint_z_Z32(const void *src, GLuint *dst, GLuint n)  } +/** + * Unpack Z values. + * The returned values will always be in the range [0, 0xffffffff]. + */  void  _mesa_unpack_uint_z_row(gl_format format, GLuint n,                          const void *src, GLuint *dst) diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index fd6e582ec..867cb22e2 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -1803,6 +1803,81 @@ next_mipmap_level_size(GLenum target, GLint border,     }  } + +/** + * Helper function for mipmap generation. + * Make sure the specified destination mipmap level is the right size/format + * for mipmap generation.  If not, (re) allocate it. + * \return GL_TRUE if successful, GL_FALSE if mipmap generation should stop + */ +GLboolean +_mesa_prepare_mipmap_level(struct gl_context *ctx, +                           struct gl_texture_object *texObj, GLuint level, +                           GLsizei width, GLsizei height, GLsizei depth, +                           GLsizei border, GLenum intFormat, gl_format format) +{ +   const GLuint numFaces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; +   GLuint face; + +   if (texObj->Immutable) { +      /* The texture was created with glTexStorage() so the number/size of +       * mipmap levels is fixed and the storage for all images is already +       * allocated. +       */ +      if (!texObj->Image[0][level]) { +         /* No more levels to create - we're done */ +         return GL_FALSE; +      } +      else { +         /* Nothing to do - the texture memory must have already been +          * allocated to the right size so we're all set. +          */ +         return GL_TRUE; +      } +   } + +   for (face = 0; face < numFaces; face++) { +      struct gl_texture_image *dstImage; +      GLenum target; + +      if (numFaces == 1) +         target = texObj->Target; +      else +         target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; + +      dstImage = _mesa_get_tex_image(ctx, texObj, target, level); +      if (!dstImage) { +         /* out of memory */ +         return GL_FALSE; +      } + +      if (dstImage->Width != width || +          dstImage->Height != height || +          dstImage->Depth != depth || +          dstImage->Border != border || +          dstImage->InternalFormat != intFormat || +          dstImage->TexFormat != format) { +         /* need to (re)allocate image */ +         ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); + +         _mesa_init_teximage_fields(ctx, target, dstImage, +                                    width, height, depth, +                                    border, intFormat, format); + +         ctx->Driver.AllocTextureImageBuffer(ctx, dstImage, +                                             format, width, height, depth); + +         /* in case the mipmap level is part of an FBO: */ +         _mesa_update_fbo_texture(ctx, texObj, face, level); + +         ctx->NewState |= _NEW_TEXTURE; +      } +   } + +   return GL_TRUE; +} + +  static void  generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,  			     struct gl_texture_object *texObj, @@ -1841,31 +1916,20 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,        if (!nextLevel)           return; -      /* get dest gl_texture_image */ -      dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1); -      if (!dstImage) { -         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); +      if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1, +                                      dstWidth, dstHeight, dstDepth, +                                      border, srcImage->InternalFormat, +                                      srcImage->TexFormat)) {           return;        } -      /* Free old image data */ -      ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); - -      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, -                                 dstDepth, border, srcImage->InternalFormat, -                                 srcImage->TexFormat); - -      /* Alloc storage for new texture image */ -      if (!ctx->Driver.AllocTextureImageBuffer(ctx, dstImage, -                                               dstImage->TexFormat, -                                               dstWidth, dstHeight, -                                               dstDepth)) { +      /* get dest gl_texture_image */ +      dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1); +      if (!dstImage) {           _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");           return;        } -      ASSERT(dstImage->TexFormat); -        if (target == GL_TEXTURE_1D_ARRAY) {  	 srcDepth = srcHeight;  	 dstDepth = dstHeight; @@ -2052,9 +2116,7 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,           return;        } -      /* Free old image data */ -      ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); - +      /* rescale src image to dest image */        _mesa_generate_mipmap_level(target, temp_datatype, components, border,                                    srcWidth, srcHeight, srcDepth,                                    (const GLubyte **) &temp_src, @@ -2062,19 +2124,19 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,                                    dstWidth, dstHeight, dstDepth,                                    &temp_dst, temp_dst_stride); -      /* initialize new image */ -      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, -                                 dstDepth, border, srcImage->InternalFormat, -                                 srcImage->TexFormat); - -      /* Free old dest texture image buffer */ -      ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); +      if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1, +                                      dstWidth, dstHeight, dstDepth, +                                      border, srcImage->InternalFormat, +                                      srcImage->TexFormat)) { +         return; +      } -      ctx->Driver.TexImage2D(ctx, target, level + 1, -			     srcImage->InternalFormat, -			     dstWidth, dstHeight, border, -			     temp_base_format, temp_datatype, -			     temp_dst, &ctx->DefaultPacking, texObj, dstImage); +      /* The image space was allocated above so use glTexSubImage now */ +      ctx->Driver.TexSubImage2D(ctx, target, level + 1, +                                0, 0, dstWidth, dstHeight, +                                temp_base_format, temp_datatype, +                                temp_dst, &ctx->DefaultPacking, +                                texObj, dstImage);        /* swap src and dest pointers */        { diff --git a/mesalib/src/mesa/main/mipmap.h b/mesalib/src/mesa/main/mipmap.h index 1fb9146a1..072794cb6 100644 --- a/mesalib/src/mesa/main/mipmap.h +++ b/mesalib/src/mesa/main/mipmap.h @@ -41,6 +41,12 @@ _mesa_generate_mipmap_level(GLenum target,                              GLint dstRowStride); +extern GLboolean +_mesa_prepare_mipmap_level(struct gl_context *ctx, +                           struct gl_texture_object *texObj, GLuint level, +                           GLsizei width, GLsizei height, GLsizei depth, +                           GLsizei border, GLenum intFormat, gl_format format); +  extern void  _mesa_generate_mipmap(struct gl_context *ctx, GLenum target,                        struct gl_texture_object *texObj); diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 193434976..0e29dc0dc 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2355,6 +2355,8 @@ struct gl_transform_feedback_object     GLint RefCount;     GLboolean Active;  /**< Is transform feedback enabled? */     GLboolean Paused;  /**< Is transform feedback paused? */ +   GLboolean EndedAnytime; /**< Has EndTransformFeedback been called +                                at least once? */     /** The feedback buffers */     GLuint BufferNames[MAX_FEEDBACK_ATTRIBS]; diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c index c776b4160..7e60541c3 100644 --- a/mesalib/src/mesa/main/texformat.c +++ b/mesalib/src/mesa/main/texformat.c @@ -118,6 +118,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,  	 break;        case GL_R3_G3_B2:  	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB332); +	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565); +	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565_REV);  	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);  	 RETURN_IF_SUPPORTED(MESA_FORMAT_XRGB8888);  	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888); diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index ae0d51fbb..3f2418729 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -708,6 +708,14 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,        return GL_TRUE;     } +   if (!_mesa_is_legal_format_and_type(ctx, format, type)) { +      /*GL_INVALID_OPERATION is generated by a format/type +       * mismatch (see the 1.2 spec page 94, sec 3.6.4.) +       */ +      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(target)"); +      return GL_TRUE; +   } +     baseFormat = _mesa_get_format_base_format(texImage->TexFormat);     /* Make sure the requested image format is compatible with the diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 8a002b675..eccc0fd39 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -2205,9 +2205,10 @@ check_rtt_cb(GLuint key, void *data, void *userData)   * in size or format since that effects FBO completeness.   * Any FBOs rendering into the texture must be re-validated.   */ -static void -update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj, -                   GLuint face, GLuint level) +void +_mesa_update_fbo_texture(struct gl_context *ctx, +                         struct gl_texture_object *texObj, +                         GLuint face, GLuint level)  {     /* Only check this texture if it's been marked as RenderToTexture */     if (texObj->_RenderToTexture) { @@ -2502,7 +2503,7 @@ teximage(struct gl_context *ctx, GLuint dims,                 check_gen_mipmap(ctx, target, texObj, level); -               update_fbo_texture(ctx, texObj, face, level); +               _mesa_update_fbo_texture(ctx, texObj, face, level);                 /* state update */                 texObj->_Complete = GL_FALSE; @@ -2844,7 +2845,7 @@ copyteximage(struct gl_context *ctx, GLuint dims,              check_gen_mipmap(ctx, target, texObj, level); -            update_fbo_texture(ctx, texObj, face, level); +            _mesa_update_fbo_texture(ctx, texObj, face, level);              /* state update */              texObj->_Complete = GL_FALSE; diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 9cc7d5a54..d756646ce 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -80,6 +80,10 @@ _mesa_choose_texture_format(struct gl_context *ctx,                              GLenum target, GLint level,                              GLenum internalFormat, GLenum format, GLenum type); +extern void +_mesa_update_fbo_texture(struct gl_context *ctx, +                         struct gl_texture_object *texObj, +                         GLuint face, GLuint level);  extern void  _mesa_clear_texture_image(struct gl_context *ctx, diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c index 799245d4e..824f66a35 100644 --- a/mesalib/src/mesa/main/transformfeedback.c +++ b/mesalib/src/mesa/main/transformfeedback.c @@ -294,18 +294,6 @@ resume_transform_feedback(struct gl_context *ctx,     /* nop */  } -/** Default fallback for ctx->Driver.DrawTransformFeedback() */ -static void -draw_transform_feedback(struct gl_context *ctx, GLenum mode, -                        struct gl_transform_feedback_object *obj) -{ -   /* XXX to do */ -   /* -    * Get number of vertices in obj's feedback buffer. -    * Call ctx->Exec.DrawArrays(mode, 0, count); -    */ -} -  /**   * Plug in default device driver functions for transform feedback. @@ -320,7 +308,6 @@ _mesa_init_transform_feedback_functions(struct dd_function_table *driver)     driver->EndTransformFeedback = end_transform_feedback;     driver->PauseTransformFeedback = pause_transform_feedback;     driver->ResumeTransformFeedback = resume_transform_feedback; -   driver->DrawTransformFeedback = draw_transform_feedback;  } @@ -342,7 +329,6 @@ _mesa_init_transform_feedback_dispatch(struct _glapi_table *disp)     SET_IsTransformFeedback(disp, _mesa_IsTransformFeedback);     SET_PauseTransformFeedback(disp, _mesa_PauseTransformFeedback);     SET_ResumeTransformFeedback(disp, _mesa_ResumeTransformFeedback); -   SET_DrawTransformFeedback(disp, _mesa_DrawTransformFeedback);  } @@ -401,6 +387,7 @@ _mesa_EndTransformFeedback(void)     FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK);     ctx->TransformFeedback.CurrentObject->Active = GL_FALSE; +   ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE;     assert(ctx->Driver.EndTransformFeedback);     ctx->Driver.EndTransformFeedback(ctx, obj); @@ -714,8 +701,8 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, -static struct gl_transform_feedback_object * -lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) +struct gl_transform_feedback_object * +_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)  {     if (name == 0) {        return ctx->TransformFeedback.DefaultObject; @@ -780,7 +767,7 @@ _mesa_IsTransformFeedback(GLuint name)     ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); -   if (name && lookup_transform_feedback_object(ctx, name)) +   if (name && _mesa_lookup_transform_feedback_object(ctx, name))        return GL_TRUE;     else        return GL_FALSE; @@ -809,7 +796,7 @@ _mesa_BindTransformFeedback(GLenum target, GLuint name)        return;     } -   obj = lookup_transform_feedback_object(ctx, name); +   obj = _mesa_lookup_transform_feedback_object(ctx, name);     if (!obj) {        _mesa_error(ctx, GL_INVALID_OPERATION,                    "glBindTransformFeedback(name=%u)", name); @@ -844,7 +831,7 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names)     for (i = 0; i < n; i++) {        if (names[i] > 0) {           struct gl_transform_feedback_object *obj -            = lookup_transform_feedback_object(ctx, names[i]); +            = _mesa_lookup_transform_feedback_object(ctx, names[i]);           if (obj) {              if (obj->Active) {                 _mesa_error(ctx, GL_INVALID_OPERATION, @@ -912,40 +899,4 @@ _mesa_ResumeTransformFeedback(void)     ctx->Driver.ResumeTransformFeedback(ctx, obj);  } - -/** - * Draw the vertex data in a transform feedback object. - * \param mode  GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. - * \param name  the transform feedback object - * The number of vertices comes from the transform feedback object. - * User still has to setup of the vertex attribute info with - * glVertexPointer, glColorPointer, etc. - * Part of GL_ARB_transform_feedback2. - */ -void GLAPIENTRY -_mesa_DrawTransformFeedback(GLenum mode, GLuint name) -{ -   GET_CURRENT_CONTEXT(ctx); -   struct gl_transform_feedback_object *obj = -      lookup_transform_feedback_object(ctx, name); - -   if (mode > GL_POLYGON) { -      _mesa_error(ctx, GL_INVALID_ENUM, -                  "glDrawTransformFeedback(mode=0x%x)", mode); -      return; -   } -   if (!obj) { -      _mesa_error(ctx, GL_INVALID_VALUE, -                  "glDrawTransformFeedback(name = %u)", name); -      return; -   } - -   /* XXX check if EndTransformFeedback has never been called while -    * the object was bound -    */ - -   assert(ctx->Driver.DrawTransformFeedback); -   ctx->Driver.DrawTransformFeedback(ctx, mode, obj); -} -  #endif /* FEATURE_EXT_transform_feedback */ diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h index 9447effa9..8a6672d58 100644 --- a/mesalib/src/mesa/main/transformfeedback.h +++ b/mesalib/src/mesa/main/transformfeedback.h @@ -87,6 +87,9 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,  /*** GL_ARB_transform_feedback2 ***/ +struct gl_transform_feedback_object * +_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name); +  extern void GLAPIENTRY  _mesa_GenTransformFeedbacks(GLsizei n, GLuint *names); @@ -105,9 +108,6 @@ _mesa_PauseTransformFeedback(void);  extern void GLAPIENTRY  _mesa_ResumeTransformFeedback(void); -extern void GLAPIENTRY -_mesa_DrawTransformFeedback(GLenum mode, GLuint name); -  #else /* FEATURE_EXT_transform_feedback */  static inline GLboolean diff --git a/mesalib/src/mesa/main/varray.h b/mesalib/src/mesa/main/varray.h index 6fcc0a336..b6041bd78 100644 --- a/mesalib/src/mesa/main/varray.h +++ b/mesalib/src/mesa/main/varray.h @@ -245,6 +245,13 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,  				  const GLvoid *indices,  				  GLint basevertex); +#if FEATURE_EXT_transform_feedback + +extern void GLAPIENTRY +_mesa_DrawTransformFeedback(GLenum mode, GLuint name); + +#endif +  extern void GLAPIENTRY  _mesa_PrimitiveRestartIndex(GLuint index); diff --git a/mesalib/src/mesa/main/vtxfmt.c b/mesalib/src/mesa/main/vtxfmt.c index 03735d779..f3cca937d 100644 --- a/mesalib/src/mesa/main/vtxfmt.c +++ b/mesalib/src/mesa/main/vtxfmt.c @@ -107,6 +107,7 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )     SET_DrawArraysInstancedARB(tab, vfmt->DrawArraysInstanced);     SET_DrawElementsInstancedARB(tab, vfmt->DrawElementsInstanced);     SET_DrawElementsInstancedBaseVertex(tab, vfmt->DrawElementsInstancedBaseVertex); +   SET_DrawTransformFeedback(tab, vfmt->DrawTransformFeedback);     /* GL_NV_vertex_program */     SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV); diff --git a/mesalib/src/mesa/program/prog_parameter_layout.c b/mesalib/src/mesa/program/prog_parameter_layout.c index 28fca3b92..e4f2db3b3 100644 --- a/mesalib/src/mesa/program/prog_parameter_layout.c +++ b/mesalib/src/mesa/program/prog_parameter_layout.c @@ -138,6 +138,7 @@ _mesa_layout_parameters(struct asm_parser_state *state)  		      inst->SrcReg[i].Symbol->param_binding_length);  	       if (new_begin < 0) { +		  _mesa_free_parameter_list(layout);  		  return GL_FALSE;  	       } diff --git a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c index afca60976..fb1e4092c 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -266,6 +266,7 @@ get_pixel_transfer_program(struct gl_context *ctx, const struct state_key *key)     if (!fp->Base.Instructions) {        _mesa_error(ctx, GL_OUT_OF_MEMORY,                    "generating pixel transfer program"); +      _mesa_free_parameter_list(params);        return NULL;     } diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c index 250cbb226..4aa0b4e2a 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c @@ -256,9 +256,11 @@ static void update_raster_state( struct st_context *st )     /* _NEW_FRAG_CLAMP */     raster->clamp_fragment_color = ctx->Color._ClampFragmentColor; -     raster->gl_rasterization_rules = 1; +   /* _NEW_TRANSFORM */ +   raster->rasterizer_discard = ctx->TransformFeedback.RasterDiscard; +     cso_set_rasterizer(st->cso_context, raster);  } @@ -273,7 +275,8 @@ const struct st_tracked_state st_update_rasterizer = {         _NEW_POLYGON |         _NEW_PROGRAM |         _NEW_SCISSOR | -       _NEW_FRAG_CLAMP),      /* mesa state dependencies*/ +       _NEW_FRAG_CLAMP | +       _NEW_TRANSFORM),      /* mesa state dependencies*/        ST_NEW_VERTEX_PROGRAM,  /* state tracker dependencies */     },     update_raster_state     /* update function */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c index fa37be0b6..af33bcf86 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c @@ -483,6 +483,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,     cso_save_fragment_sampler_views(cso);     cso_save_viewport(cso);     cso_save_fragment_shader(cso); +   cso_save_stream_outputs(cso);     cso_save_vertex_shader(cso);     cso_save_geometry_shader(cso);     cso_save_vertex_elements(cso); @@ -542,6 +543,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,     }     cso_set_vertex_elements(cso, 3, st->velems_util_draw); +   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);     /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */     z = z * 2.0f - 1.0f; @@ -568,6 +570,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,     cso_restore_geometry_shader(cso);     cso_restore_vertex_elements(cso);     cso_restore_vertex_buffers(cso); +   cso_restore_stream_outputs(cso);  } diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 61d98aeb9..23700eeb7 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -250,6 +250,7 @@ clear_with_quad(struct gl_context *ctx,     cso_save_viewport(st->cso_context);     cso_save_clip(st->cso_context);     cso_save_fragment_shader(st->cso_context); +   cso_save_stream_outputs(st->cso_context);     cso_save_vertex_shader(st->cso_context);     cso_save_geometry_shader(st->cso_context);     cso_save_vertex_elements(st->cso_context); @@ -306,6 +307,7 @@ clear_with_quad(struct gl_context *ctx,     }     cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw); +   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);     cso_set_rasterizer(st->cso_context, &st->clear.raster); @@ -350,6 +352,7 @@ clear_with_quad(struct gl_context *ctx,     cso_restore_geometry_shader(st->cso_context);     cso_restore_vertex_elements(st->cso_context);     cso_restore_vertex_buffers(st->cso_context); +   cso_restore_stream_outputs(st->cso_context);  } diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 65b444552..318ba7d06 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -671,6 +671,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,     cso_save_samplers(cso);     cso_save_fragment_sampler_views(cso);     cso_save_fragment_shader(cso); +   cso_save_stream_outputs(cso);     cso_save_vertex_shader(cso);     cso_save_geometry_shader(cso);     cso_save_vertex_elements(cso); @@ -761,6 +762,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,     }     cso_set_vertex_elements(cso, 3, st->velems_util_draw); +   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);     /* texture state: */     cso_set_fragment_sampler_views(cso, num_sampler_view, sv); @@ -796,6 +798,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,     cso_restore_geometry_shader(cso);     cso_restore_vertex_elements(cso);     cso_restore_vertex_buffers(cso); +   cso_restore_stream_outputs(cso);     if (write_stencil) {        cso_restore_depth_stencil_alpha(cso);        cso_restore_blend(cso); diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c index 332b0d1b6..6144eb99c 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c @@ -227,6 +227,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,     cso_save_viewport(cso); +   cso_save_stream_outputs(cso);     cso_save_vertex_shader(cso);     cso_save_geometry_shader(cso);     cso_save_vertex_elements(cso); @@ -246,6 +247,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,        velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;     }     cso_set_vertex_elements(cso, numAttribs, velements); +   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);     /* viewport state: viewport matching window dims */     { @@ -281,6 +283,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,     cso_restore_geometry_shader(cso);     cso_restore_vertex_elements(cso);     cso_restore_vertex_buffers(cso); +   cso_restore_stream_outputs(cso);  } diff --git a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c index 2e9eb7265..2c21dc9a7 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c @@ -1,272 +1,273 @@ -/**************************************************************************
 - * 
 - * 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.
 - * 
 - **************************************************************************/
 -
 -/**
 - * glRasterPos implementation.  Basically render a GL_POINT with our
 - * private draw module.  Plug in a special "rasterpos" stage at the end
 - * of the 'draw' pipeline to capture the results and update the current
 - * raster pos attributes.
 - *
 - * Authors:
 - *   Brian Paul
 - */
 -
 -
 -#include "main/imports.h"
 -#include "main/macros.h"
 -#include "main/mfeatures.h"
 -#include "main/feedback.h"
 -
 -#include "st_context.h"
 -#include "st_atom.h"
 -#include "st_draw.h"
 -#include "st_cb_rasterpos.h"
 -#include "draw/draw_context.h"
 -#include "draw/draw_pipe.h"
 -#include "vbo/vbo.h"
 -
 -
 -#if FEATURE_rastpos
 -
 -/**
 - * Our special drawing pipeline stage (replaces rasterization).
 - */
 -struct rastpos_stage
 -{
 -   struct draw_stage stage;   /**< Base class */
 -   struct gl_context *ctx;            /**< Rendering context */
 -
 -   /* vertex attrib info we can setup once and re-use */
 -   struct gl_client_array array[VERT_ATTRIB_MAX];
 -   const struct gl_client_array *arrays[VERT_ATTRIB_MAX];
 -   struct _mesa_prim prim;
 -};
 -
 -
 -static INLINE struct rastpos_stage *
 -rastpos_stage( struct draw_stage *stage )
 -{
 -   return (struct rastpos_stage *) stage;
 -}
 -
 -static void
 -rastpos_flush( struct draw_stage *stage, unsigned flags )
 -{
 -   /* no-op */
 -}
 -
 -static void
 -rastpos_reset_stipple_counter( struct draw_stage *stage )
 -{
 -   /* no-op */
 -}
 -
 -static void
 -rastpos_tri( struct draw_stage *stage, struct prim_header *prim )
 -{
 -   /* should never get here */
 -   assert(0);
 -}
 -
 -static void
 -rastpos_line( struct draw_stage *stage, struct prim_header *prim )
 -{
 -   /* should never get here */
 -   assert(0);
 -}
 -
 -static void
 -rastpos_destroy(struct draw_stage *stage)
 -{
 -   free(stage);
 -}
 -
 -
 -/**
 - * Update a raster pos attribute from the vertex result if it's present,
 - * else copy the current attrib.
 - */
 -static void
 -update_attrib(struct gl_context *ctx, const GLuint *outputMapping,
 -              const struct vertex_header *vert,
 -              GLfloat *dest,
 -              GLuint result, GLuint defaultAttrib)
 -{
 -   const GLfloat *src;
 -   const GLuint k = outputMapping[result];
 -   if (k != ~0U)
 -      src = vert->data[k];
 -   else
 -      src = ctx->Current.Attrib[defaultAttrib];
 -   COPY_4V(dest, src);
 -}
 -
 -
 -/**
 - * Normally, this function would render a GL_POINT.
 - */
 -static void
 -rastpos_point(struct draw_stage *stage, struct prim_header *prim)
 -{
 -   struct rastpos_stage *rs = rastpos_stage(stage);
 -   struct gl_context *ctx = rs->ctx;
 -   struct st_context *st = st_context(ctx);
 -   const GLfloat height = (GLfloat) ctx->DrawBuffer->Height;
 -   const GLuint *outputMapping = st->vertex_result_to_slot;
 -   const GLfloat *pos;
 -   GLuint i;
 -
 -   /* if we get here, we didn't get clipped */
 -   ctx->Current.RasterPosValid = GL_TRUE;
 -
 -   /* update raster pos */
 -   pos = prim->v[0]->data[0];
 -   ctx->Current.RasterPos[0] = pos[0];
 -   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
 -      ctx->Current.RasterPos[1] = height - pos[1]; /* invert Y */
 -   else
 -      ctx->Current.RasterPos[1] = pos[1];
 -   ctx->Current.RasterPos[2] = pos[2];
 -   ctx->Current.RasterPos[3] = pos[3];
 -
 -   /* update other raster attribs */
 -   update_attrib(ctx, outputMapping, prim->v[0],
 -                 ctx->Current.RasterColor,
 -                 VERT_RESULT_COL0, VERT_ATTRIB_COLOR0);
 -
 -   update_attrib(ctx, outputMapping, prim->v[0],
 -                 ctx->Current.RasterSecondaryColor,
 -                 VERT_RESULT_COL1, VERT_ATTRIB_COLOR1);
 -
 -   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
 -      update_attrib(ctx, outputMapping, prim->v[0],
 -                    ctx->Current.RasterTexCoords[i],
 -                    VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);
 -   }
 -
 -   if (ctx->RenderMode == GL_SELECT) {
 -      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
 -   }
 -}
 -
 -
 -/**
 - * Create rasterpos "drawing" stage.
 - */
 -static struct rastpos_stage *
 -new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw)
 -{
 -   struct rastpos_stage *rs = ST_CALLOC_STRUCT(rastpos_stage);
 -   GLuint i;
 -
 -   rs->stage.draw = draw;
 -   rs->stage.next = NULL;
 -   rs->stage.point = rastpos_point;
 -   rs->stage.line = rastpos_line;
 -   rs->stage.tri = rastpos_tri;
 -   rs->stage.flush = rastpos_flush;
 -   rs->stage.destroy = rastpos_destroy;
 -   rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
 -   rs->stage.destroy = rastpos_destroy;
 -   rs->ctx = ctx;
 -
 -   for (i = 0; i < Elements(rs->array); i++) {
 -      rs->array[i].Size = 4;
 -      rs->array[i].Type = GL_FLOAT;
 -      rs->array[i].Format = GL_RGBA;
 -      rs->array[i].Stride = 0;
 -      rs->array[i].StrideB = 0;
 -      rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
 -      rs->array[i].Enabled = GL_TRUE;
 -      rs->array[i].Normalized = GL_TRUE;
 -      rs->array[i].BufferObj = NULL;
 -      rs->arrays[i] = &rs->array[i];
 -   }
 -
 -   rs->prim.mode = GL_POINTS;
 -   rs->prim.indexed = 0;
 -   rs->prim.begin = 1;
 -   rs->prim.end = 1;
 -   rs->prim.weak = 0;
 -   rs->prim.start = 0;
 -   rs->prim.count = 1;
 -
 -   return rs;
 -}
 -
 -
 -static void
 -st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
 -{
 -   struct st_context *st = st_context(ctx);
 -   struct draw_context *draw = st->draw;
 -   struct rastpos_stage *rs;
 -
 -   if (st->rastpos_stage) {
 -      /* get rastpos stage info */
 -      rs = rastpos_stage(st->rastpos_stage);
 -   }
 -   else {
 -      /* create rastpos draw stage */
 -      rs = new_draw_rastpos_stage(ctx, draw);
 -      st->rastpos_stage = &rs->stage;
 -   }
 -
 -   /* plug our rastpos stage into the draw module */
 -   draw_set_rasterize_stage(st->draw, st->rastpos_stage);
 -
 -   /* make sure everything's up to date */
 -   st_validate_state(st);
 -
 -   /* This will get set only if rastpos_point(), above, gets called */
 -   ctx->Current.RasterPosValid = GL_FALSE;
 -
 -   /* All vertex attribs but position were previously initialized above.
 -    * Just plug in position pointer now.
 -    */
 -   rs->array[0].Ptr = (GLubyte *) v;
 -
 -   /* draw the point */
 -   st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1);
 -
 -   /* restore draw's rasterization stage depending on rendermode */
 -   if (ctx->RenderMode == GL_FEEDBACK) {
 -      draw_set_rasterize_stage(draw, st->feedback_stage);
 -   }
 -   else if (ctx->RenderMode == GL_SELECT) {
 -      draw_set_rasterize_stage(draw, st->selection_stage);
 -   }
 -}
 -
 -
 -
 -void st_init_rasterpos_functions(struct dd_function_table *functions)
 -{
 -   functions->RasterPos = st_RasterPos;
 -}
 -
 -#endif /* FEATURE_rastpos */
 +/************************************************************************** + *  + * 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. + *  + **************************************************************************/ + +/** + * glRasterPos implementation.  Basically render a GL_POINT with our + * private draw module.  Plug in a special "rasterpos" stage at the end + * of the 'draw' pipeline to capture the results and update the current + * raster pos attributes. + * + * Authors: + *   Brian Paul + */ + + +#include "main/imports.h" +#include "main/macros.h" +#include "main/mfeatures.h" +#include "main/feedback.h" + +#include "st_context.h" +#include "st_atom.h" +#include "st_draw.h" +#include "st_cb_rasterpos.h" +#include "draw/draw_context.h" +#include "draw/draw_pipe.h" +#include "vbo/vbo.h" + + +#if FEATURE_rastpos + +/** + * Our special drawing pipeline stage (replaces rasterization). + */ +struct rastpos_stage +{ +   struct draw_stage stage;   /**< Base class */ +   struct gl_context *ctx;            /**< Rendering context */ + +   /* vertex attrib info we can setup once and re-use */ +   struct gl_client_array array[VERT_ATTRIB_MAX]; +   const struct gl_client_array *arrays[VERT_ATTRIB_MAX]; +   struct _mesa_prim prim; +}; + + +static INLINE struct rastpos_stage * +rastpos_stage( struct draw_stage *stage ) +{ +   return (struct rastpos_stage *) stage; +} + +static void +rastpos_flush( struct draw_stage *stage, unsigned flags ) +{ +   /* no-op */ +} + +static void +rastpos_reset_stipple_counter( struct draw_stage *stage ) +{ +   /* no-op */ +} + +static void +rastpos_tri( struct draw_stage *stage, struct prim_header *prim ) +{ +   /* should never get here */ +   assert(0); +} + +static void +rastpos_line( struct draw_stage *stage, struct prim_header *prim ) +{ +   /* should never get here */ +   assert(0); +} + +static void +rastpos_destroy(struct draw_stage *stage) +{ +   free(stage); +} + + +/** + * Update a raster pos attribute from the vertex result if it's present, + * else copy the current attrib. + */ +static void +update_attrib(struct gl_context *ctx, const GLuint *outputMapping, +              const struct vertex_header *vert, +              GLfloat *dest, +              GLuint result, GLuint defaultAttrib) +{ +   const GLfloat *src; +   const GLuint k = outputMapping[result]; +   if (k != ~0U) +      src = vert->data[k]; +   else +      src = ctx->Current.Attrib[defaultAttrib]; +   COPY_4V(dest, src); +} + + +/** + * Normally, this function would render a GL_POINT. + */ +static void +rastpos_point(struct draw_stage *stage, struct prim_header *prim) +{ +   struct rastpos_stage *rs = rastpos_stage(stage); +   struct gl_context *ctx = rs->ctx; +   struct st_context *st = st_context(ctx); +   const GLfloat height = (GLfloat) ctx->DrawBuffer->Height; +   const GLuint *outputMapping = st->vertex_result_to_slot; +   const GLfloat *pos; +   GLuint i; + +   /* if we get here, we didn't get clipped */ +   ctx->Current.RasterPosValid = GL_TRUE; + +   /* update raster pos */ +   pos = prim->v[0]->data[0]; +   ctx->Current.RasterPos[0] = pos[0]; +   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) +      ctx->Current.RasterPos[1] = height - pos[1]; /* invert Y */ +   else +      ctx->Current.RasterPos[1] = pos[1]; +   ctx->Current.RasterPos[2] = pos[2]; +   ctx->Current.RasterPos[3] = pos[3]; + +   /* update other raster attribs */ +   update_attrib(ctx, outputMapping, prim->v[0], +                 ctx->Current.RasterColor, +                 VERT_RESULT_COL0, VERT_ATTRIB_COLOR0); + +   update_attrib(ctx, outputMapping, prim->v[0], +                 ctx->Current.RasterSecondaryColor, +                 VERT_RESULT_COL1, VERT_ATTRIB_COLOR1); + +   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { +      update_attrib(ctx, outputMapping, prim->v[0], +                    ctx->Current.RasterTexCoords[i], +                    VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i); +   } + +   if (ctx->RenderMode == GL_SELECT) { +      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); +   } +} + + +/** + * Create rasterpos "drawing" stage. + */ +static struct rastpos_stage * +new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw) +{ +   struct rastpos_stage *rs = ST_CALLOC_STRUCT(rastpos_stage); +   GLuint i; + +   rs->stage.draw = draw; +   rs->stage.next = NULL; +   rs->stage.point = rastpos_point; +   rs->stage.line = rastpos_line; +   rs->stage.tri = rastpos_tri; +   rs->stage.flush = rastpos_flush; +   rs->stage.destroy = rastpos_destroy; +   rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter; +   rs->stage.destroy = rastpos_destroy; +   rs->ctx = ctx; + +   for (i = 0; i < Elements(rs->array); i++) { +      rs->array[i].Size = 4; +      rs->array[i].Type = GL_FLOAT; +      rs->array[i].Format = GL_RGBA; +      rs->array[i].Stride = 0; +      rs->array[i].StrideB = 0; +      rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i]; +      rs->array[i].Enabled = GL_TRUE; +      rs->array[i].Normalized = GL_TRUE; +      rs->array[i].BufferObj = NULL; +      rs->arrays[i] = &rs->array[i]; +   } + +   rs->prim.mode = GL_POINTS; +   rs->prim.indexed = 0; +   rs->prim.begin = 1; +   rs->prim.end = 1; +   rs->prim.weak = 0; +   rs->prim.start = 0; +   rs->prim.count = 1; + +   return rs; +} + + +static void +st_RasterPos(struct gl_context *ctx, const GLfloat v[4]) +{ +   struct st_context *st = st_context(ctx); +   struct draw_context *draw = st->draw; +   struct rastpos_stage *rs; + +   if (st->rastpos_stage) { +      /* get rastpos stage info */ +      rs = rastpos_stage(st->rastpos_stage); +   } +   else { +      /* create rastpos draw stage */ +      rs = new_draw_rastpos_stage(ctx, draw); +      st->rastpos_stage = &rs->stage; +   } + +   /* plug our rastpos stage into the draw module */ +   draw_set_rasterize_stage(st->draw, st->rastpos_stage); + +   /* make sure everything's up to date */ +   st_validate_state(st); + +   /* This will get set only if rastpos_point(), above, gets called */ +   ctx->Current.RasterPosValid = GL_FALSE; + +   /* All vertex attribs but position were previously initialized above. +    * Just plug in position pointer now. +    */ +   rs->array[0].Ptr = (GLubyte *) v; + +   /* draw the point */ +   st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1, +                        NULL); + +   /* restore draw's rasterization stage depending on rendermode */ +   if (ctx->RenderMode == GL_FEEDBACK) { +      draw_set_rasterize_stage(draw, st->feedback_stage); +   } +   else if (ctx->RenderMode == GL_SELECT) { +      draw_set_rasterize_stage(draw, st->selection_stage); +   } +} + + + +void st_init_rasterpos_functions(struct dd_function_table *functions) +{ +   functions->RasterPos = st_RasterPos; +} + +#endif /* FEATURE_rastpos */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c index 378b4822b..2fc28dc24 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c +++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c @@ -1,134 +1,197 @@ -/**************************************************************************
 - * 
 - * Copyright 2010 VMware, Inc.
 - * 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.
 - * 
 - **************************************************************************/
 -
 -
 -/**
 - * Transform feedback functions.
 - *
 - * \author Brian Paul
 - */
 -
 -
 -#include "main/imports.h"
 -#include "main/context.h"
 -#include "main/mfeatures.h"
 -#include "main/transformfeedback.h"
 -
 -#include "st_cb_xformfb.h"
 -
 -
 -#if FEATURE_EXT_transform_feedback
 -
 -#if 0
 -static struct gl_transform_feedback_object *
 -st_new_transform_feedback(struct gl_context *ctx, GLuint name)
 -{
 -   struct gl_transform_feedback_object *obj;
 -   obj = CALLOC_STRUCT(gl_transform_feedback_object);
 -   if (obj) {
 -      obj->Name = name;
 -      obj->RefCount = 1;
 -   }
 -   return obj;
 -}
 -#endif
 -
 -#if 0
 -static void
 -st_delete_transform_feedback(struct gl_context *ctx,
 -                             struct gl_transform_feedback_object *obj)
 -{
 -   GLuint i;
 -
 -   for (i = 0; i < Elements(obj->Buffers); i++) {
 -      _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL);
 -   }
 -
 -   free(obj);
 -}
 -#endif
 -
 -
 -static void
 -st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
 -                            struct gl_transform_feedback_object *obj)
 -{
 -   /* to-do */
 -}
 -
 -
 -static void
 -st_end_transform_feedback(struct gl_context *ctx,
 -                          struct gl_transform_feedback_object *obj)
 -{
 -   /* to-do */
 -}
 -
 -
 -static void
 -st_pause_transform_feedback(struct gl_context *ctx,
 -                            struct gl_transform_feedback_object *obj)
 -{
 -   /* to-do */
 -}
 -
 -
 -static void
 -st_resume_transform_feedback(struct gl_context *ctx,
 -                             struct gl_transform_feedback_object *obj)
 -{
 -   /* to-do */
 -}
 -
 -
 -static void
 -st_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
 -                           struct gl_transform_feedback_object *obj)
 -{
 -   /* XXX to do */
 -   /*
 -    * Get number of vertices in obj's feedback buffer.
 -    * Call ctx->Exec.DrawArrays(mode, 0, count);
 -    */
 -}
 -
 -
 -void
 -st_init_xformfb_functions(struct dd_function_table *functions)
 -{
 -   /* let core Mesa plug in its functions */
 -   _mesa_init_transform_feedback_functions(functions);
 -
 -   /* then override a few: */
 -   functions->BeginTransformFeedback = st_begin_transform_feedback;
 -   functions->EndTransformFeedback = st_end_transform_feedback;
 -   functions->PauseTransformFeedback = st_pause_transform_feedback;
 -   functions->ResumeTransformFeedback = st_resume_transform_feedback;
 -   functions->DrawTransformFeedback = st_draw_transform_feedback;
 -}
 -
 -#endif /* FEATURE_EXT_transform_feedback */
 +/************************************************************************** + *  + * Copyright 2010 VMware, Inc. + * 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. + *  + **************************************************************************/ + + +/** + * Transform feedback functions. + * + * \author Brian Paul + *         Marek Olšák + */ + + +#include "main/bufferobj.h" +#include "main/context.h" +#include "main/mfeatures.h" +#include "main/transformfeedback.h" + +#include "st_cb_bufferobjects.h" +#include "st_cb_xformfb.h" +#include "st_context.h" + +#include "pipe/p_context.h" +#include "util/u_draw.h" +#include "util/u_inlines.h" +#include "cso_cache/cso_context.h" + +#if FEATURE_EXT_transform_feedback + +struct st_transform_feedback_object { +   struct gl_transform_feedback_object base; + +   unsigned num_targets; +   struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS]; +}; + + +static struct gl_transform_feedback_object * +st_new_transform_feedback(struct gl_context *ctx, GLuint name) +{ +   struct st_transform_feedback_object *obj; + +   obj = CALLOC_STRUCT(st_transform_feedback_object); +   if (!obj) +      return NULL; + +   obj->base.Name = name; +   obj->base.RefCount = 1; +   return &obj->base; +} + + +static void +st_delete_transform_feedback(struct gl_context *ctx, +                             struct gl_transform_feedback_object *obj) +{ +   struct st_transform_feedback_object *sobj = +         (struct st_transform_feedback_object*)obj; +   unsigned i; + +   /* Unreference targets. */ +   for (i = 0; i < sobj->num_targets; i++) { +      pipe_so_target_reference(&sobj->targets[i], NULL); +   } + +   for (i = 0; i < Elements(sobj->base.Buffers); i++) { +      _mesa_reference_buffer_object(ctx, &sobj->base.Buffers[i], NULL); +   } + +   free(obj); +} + + +/* XXX Do we really need the mode? */ +static void +st_begin_transform_feedback(struct gl_context *ctx, GLenum mode, +                            struct gl_transform_feedback_object *obj) +{ +   struct st_context *st = st_context(ctx); +   struct pipe_context *pipe = st->pipe; +   struct st_transform_feedback_object *sobj = +         (struct st_transform_feedback_object*)obj; +   unsigned i, max_num_targets; + +   max_num_targets = MIN2(Elements(sobj->base.Buffers), +                          Elements(sobj->targets)); + +   /* Convert the transform feedback state into the gallium representation. */ +   for (i = 0; i < max_num_targets; i++) { +      struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]); + +      if (bo) { +         /* Check whether we need to recreate the target. */ +         if (!sobj->targets[i] || +             sobj->targets[i]->buffer != bo->buffer || +             sobj->targets[i]->buffer_offset != sobj->base.Offset[i] || +             sobj->targets[i]->buffer_size != sobj->base.Size[i]) { +            /* Create a new target. */ +            struct pipe_stream_output_target *so_target = +                  pipe->create_stream_output_target(pipe, bo->buffer, +                                                    sobj->base.Offset[i], +                                                    sobj->base.Size[i]); + +            pipe_so_target_reference(&sobj->targets[i], NULL); +            sobj->targets[i] = so_target; +         } + +         sobj->num_targets = i+1; +      } else { +         pipe_so_target_reference(&sobj->targets[i], NULL); +      } +   } + +   /* Start writing at the beginning of each target. */ +   cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets, +                          0); +} + + +static void +st_stop_transform_feedback(struct gl_context *ctx, +                           struct gl_transform_feedback_object *obj) +{ +   struct st_context *st = st_context(ctx); +   cso_set_stream_outputs(st->cso_context, 0, NULL, 0); +} + + +static void +st_resume_transform_feedback(struct gl_context *ctx, +                             struct gl_transform_feedback_object *obj) +{ +   struct st_context *st = st_context(ctx); +   struct st_transform_feedback_object *sobj = +         (struct st_transform_feedback_object*)obj; + +   cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets, +                          ~0); +} + +/* Set count_from_stream_output to any stream output target + * from the transform feedback object. */ +void +st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj, +                                struct pipe_draw_info *out) +{ +   struct st_transform_feedback_object *sobj = +         (struct st_transform_feedback_object*)obj; +   unsigned i; + +   for (i = 0; i < Elements(sobj->targets); i++) { +      if (sobj->targets[i]) { +         out->count_from_stream_output = sobj->targets[i]; +         return; +      } +   } + +   assert(0); +   out->count_from_stream_output = NULL; +} + + +void +st_init_xformfb_functions(struct dd_function_table *functions) +{ +   functions->NewTransformFeedback = st_new_transform_feedback; +   functions->DeleteTransformFeedback = st_delete_transform_feedback; +   functions->BeginTransformFeedback = st_begin_transform_feedback; +   functions->EndTransformFeedback = st_stop_transform_feedback; +   functions->PauseTransformFeedback = st_stop_transform_feedback; +   functions->ResumeTransformFeedback = st_resume_transform_feedback; +} + +#endif /* FEATURE_EXT_transform_feedback */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.h b/mesalib/src/mesa/state_tracker/st_cb_xformfb.h index e07f500ce..c5261b39b 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.h +++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.h @@ -1,51 +1,63 @@ -/**************************************************************************
 - * 
 - * Copyright 2010 VMware, Inc.
 - * 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.
 - * 
 - **************************************************************************/
 -
 -#ifndef ST_CB_XFORMFB_H
 -#define ST_CB_XFORMFB_H
 -
 -
 -#include "main/compiler.h"
 -#include "main/mfeatures.h"
 -
 -struct dd_function_table;
 -
 -#if FEATURE_EXT_transform_feedback
 -
 -extern void
 -st_init_xformfb_functions(struct dd_function_table *functions);
 -
 -#else
 -
 -static INLINE void
 -st_init_xformfb_functions(struct dd_function_table *functions)
 -{
 -}
 -
 -#endif /* FEATURE_EXT_transform_feedback */
 -
 -#endif /* ST_CB_XFORMFB_H */
 +/************************************************************************** + *  + * Copyright 2010 VMware, Inc. + * 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. + *  + **************************************************************************/ + +#ifndef ST_CB_XFORMFB_H +#define ST_CB_XFORMFB_H + + +#include "main/compiler.h" +#include "main/mfeatures.h" + +struct dd_function_table; +struct gl_transform_feedback_object; +struct pipe_draw_info; + +#if FEATURE_EXT_transform_feedback + +extern void +st_init_xformfb_functions(struct dd_function_table *functions); + +extern void +st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj, +                                struct pipe_draw_info *out); + +#else + +static INLINE void +st_init_xformfb_functions(struct dd_function_table *functions) +{ +} + +static INLINE void +st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj, +                                struct pipe_draw_info *out) +{ +} + +#endif /* FEATURE_EXT_transform_feedback */ + +#endif /* ST_CB_XFORMFB_H */ diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index fd1c8ee48..87a997865 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -51,6 +51,7 @@  #include "st_context.h"  #include "st_atom.h"  #include "st_cb_bufferobjects.h" +#include "st_cb_xformfb.h"  #include "st_draw.h"  #include "st_program.h" @@ -926,7 +927,8 @@ st_draw_vbo(struct gl_context *ctx,              const struct _mesa_index_buffer *ib,  	    GLboolean index_bounds_valid,              GLuint min_index, -            GLuint max_index) +            GLuint max_index, +            struct gl_transform_feedback_object *tfb_vertcount)  {     struct st_context *st = st_context(ctx);     struct pipe_context *pipe = st->pipe; @@ -1032,6 +1034,11 @@ st_draw_vbo(struct gl_context *ctx,        info.restart_index = ctx->Array.RestartIndex;     } +   /* Set info.count_from_stream_output. */ +   if (tfb_vertcount) { +      st_transform_feedback_draw_init(tfb_vertcount, &info); +   } +     /* do actual drawing */     for (i = 0; i < nr_prims; i++) {        info.mode = translate_prim( ctx, prims[i].mode ); @@ -1044,7 +1051,10 @@ st_draw_vbo(struct gl_context *ctx,           info.max_index = info.start + info.count - 1;        } -      if (info.primitive_restart) { +      if (info.count_from_stream_output) { +         pipe->draw_vbo(pipe, &info); +      } +      else if (info.primitive_restart) {           if (st->sw_primitive_restart) {              /* Handle primitive restart for drivers that doesn't support it */              handle_fallback_primitive_restart(pipe, ib, &ibuffer, &info); diff --git a/mesalib/src/mesa/state_tracker/st_draw.h b/mesalib/src/mesa/state_tracker/st_draw.h index 23e1c7821..2623cdbb1 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.h +++ b/mesalib/src/mesa/state_tracker/st_draw.h @@ -1,91 +1,93 @@ -/**************************************************************************
 - * 
 - * Copyright 2004 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.
 - * 
 - **************************************************************************/
 -
 - /*
 -  * Authors:
 -  *   Keith Whitwell <keith@tungstengraphics.com>
 -  */
 -    
 -
 -#ifndef ST_DRAW_H
 -#define ST_DRAW_H
 -
 -#include "main/compiler.h"
 -#include "main/glheader.h"
 -
 -struct _mesa_index_buffer;
 -struct _mesa_prim;
 -struct gl_client_array;
 -struct gl_context;
 -struct st_context;
 -
 -void st_init_draw( struct st_context *st );
 -
 -void st_destroy_draw( struct st_context *st );
 -
 -extern void
 -st_draw_vbo(struct gl_context *ctx,
 -            const struct gl_client_array **arrays,
 -            const struct _mesa_prim *prims,
 -            GLuint nr_prims,
 -            const struct _mesa_index_buffer *ib,
 -	    GLboolean index_bounds_valid,
 -            GLuint min_index,
 -            GLuint max_index);
 -
 -extern void
 -st_feedback_draw_vbo(struct gl_context *ctx,
 -                     const struct gl_client_array **arrays,
 -                     const struct _mesa_prim *prims,
 -                     GLuint nr_prims,
 -                     const struct _mesa_index_buffer *ib,
 -		     GLboolean index_bounds_valid,
 -                     GLuint min_index,
 -                     GLuint max_index);
 -
 -/* Internal function:
 - */
 -extern enum pipe_format
 -st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
 -                      GLboolean normalized);
 -
 -
 -/**
 - * When drawing with VBOs, the addresses specified with
 - * glVertex/Color/TexCoordPointer() are really offsets into the VBO, not real
 - * addresses.  At some point we need to convert those pointers to offsets.
 - * This function is basically a cast wrapper to avoid warnings when building
 - * in 64-bit mode.
 - */
 -static INLINE unsigned
 -pointer_to_offset(const void *ptr)
 -{
 -   return (unsigned) (((unsigned long) ptr) & 0xffffffffUL);
 -}
 -
 -
 -#endif
 +/************************************************************************** + *  + * Copyright 2004 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. + *  + **************************************************************************/ + + /* +  * Authors: +  *   Keith Whitwell <keith@tungstengraphics.com> +  */ +     + +#ifndef ST_DRAW_H +#define ST_DRAW_H + +#include "main/compiler.h" +#include "main/glheader.h" + +struct _mesa_index_buffer; +struct _mesa_prim; +struct gl_client_array; +struct gl_context; +struct st_context; + +void st_init_draw( struct st_context *st ); + +void st_destroy_draw( struct st_context *st ); + +extern void +st_draw_vbo(struct gl_context *ctx, +            const struct gl_client_array **arrays, +            const struct _mesa_prim *prims, +            GLuint nr_prims, +            const struct _mesa_index_buffer *ib, +	    GLboolean index_bounds_valid, +            GLuint min_index, +            GLuint max_index, +            struct gl_transform_feedback_object *tfb_vertcount); + +extern void +st_feedback_draw_vbo(struct gl_context *ctx, +                     const struct gl_client_array **arrays, +                     const struct _mesa_prim *prims, +                     GLuint nr_prims, +                     const struct _mesa_index_buffer *ib, +		     GLboolean index_bounds_valid, +                     GLuint min_index, +                     GLuint max_index, +                     struct gl_transform_feedback_object *tfb_vertcount); + +/* Internal function: + */ +extern enum pipe_format +st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, +                      GLboolean normalized); + + +/** + * When drawing with VBOs, the addresses specified with + * glVertex/Color/TexCoordPointer() are really offsets into the VBO, not real + * addresses.  At some point we need to convert those pointers to offsets. + * This function is basically a cast wrapper to avoid warnings when building + * in 64-bit mode. + */ +static INLINE unsigned +pointer_to_offset(const void *ptr) +{ +   return (unsigned) (((unsigned long) ptr) & 0xffffffffUL); +} + + +#endif diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c index a7e6a0f1b..4c1e67495 100644 --- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c +++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c @@ -97,7 +97,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,                       const struct _mesa_index_buffer *ib,  		     GLboolean index_bounds_valid,                       GLuint min_index, -                     GLuint max_index) +                     GLuint max_index, +                     struct gl_transform_feedback_object *tfb_vertcount)  {     struct st_context *st = st_context(ctx);     struct pipe_context *pipe = st->pipe; diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 457d5d62a..47a178b8b 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -221,6 +221,13 @@ void st_init_limits(struct st_context *st)     c->UniformBooleanTrue = ~0; +   c->MaxTransformFeedbackSeparateAttribs = +      screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS); +   c->MaxTransformFeedbackSeparateComponents = +      screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS); +   c->MaxTransformFeedbackInterleavedComponents = +      screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS); +     c->StripTextureBorder = GL_TRUE;     c->GLSLSkipStrictMaxUniformLimitCheck = @@ -682,4 +689,12 @@ void st_init_extensions(struct st_context *st)                                     PIPE_BIND_SAMPLER_VIEW))         ctx->Extensions.ARB_texture_rgb10_a2ui = GL_TRUE; +   if (screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) { +      ctx->Extensions.EXT_transform_feedback = GL_TRUE; + +      if (screen->get_param(screen, +                            PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME) != 0) { +         ctx->Extensions.ARB_transform_feedback2 = GL_TRUE; +      } +   }  } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 9ef65c8fd..b929806ad 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -5095,4 +5095,31 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)     return GL_TRUE;  } +void +st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi, +                                const GLuint outputMapping[], +                                struct pipe_stream_output_info *so) +{ +   static unsigned comps_to_mask[] = { +      0, +      TGSI_WRITEMASK_X, +      TGSI_WRITEMASK_XY, +      TGSI_WRITEMASK_XYZ, +      TGSI_WRITEMASK_XYZW +   }; +   unsigned i; +   struct gl_transform_feedback_info *info = +      &glsl_to_tgsi->shader_program->LinkedTransformFeedback; + +   for (i = 0; i < info->NumOutputs; i++) { +      assert(info->Outputs[i].NumComponents < Elements(comps_to_mask)); +      so->output[i].register_index = +         outputMapping[info->Outputs[i].OutputRegister]; +      so->output[i].register_mask = +         comps_to_mask[info->Outputs[i].NumComponents]; +      so->output[i].output_buffer = info->Outputs[i].OutputBuffer; +   } +   so->num_outputs = info->NumOutputs; +} +  } /* extern "C" */ diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h index fafe52e31..1f71f33fd 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h @@ -66,6 +66,12 @@ st_new_shader_program(struct gl_context *ctx, GLuint name);  GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog); +void +st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi, +                                const GLuint outputMapping[], +                                struct pipe_stream_output_info *so); + +  #ifdef __cplusplus  }  #endif diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index 04d3ef60f..b83c56165 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -367,6 +367,12 @@ st_translate_vertex_program(struct st_context *st,     ureg_destroy( ureg ); +   if (stvp->glsl_to_tgsi) { +      st_translate_stream_output_info(stvp->glsl_to_tgsi, +                                      stvp->result_to_output, +                                      &vpv->tgsi.stream_output); +   } +     vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi);     if (ST_DEBUG & DEBUG_TGSI) { @@ -994,6 +1000,12 @@ st_translate_geometry_program(struct st_context *st,     stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );     ureg_destroy( ureg ); +   if (stgp->glsl_to_tgsi) { +      st_translate_stream_output_info(stgp->glsl_to_tgsi, +                                      outputMapping, +                                      &stgp->tgsi.stream_output); +   } +     /* fill in new variant */     gpv->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);     gpv->key = *key; diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c index 2817ec12f..803ad2e89 100644 --- a/mesalib/src/mesa/swrast/s_blit.c +++ b/mesalib/src/mesa/swrast/s_blit.c @@ -478,7 +478,15 @@ simple_blit(struct gl_context *ctx,     ASSERT(srcX1 - srcX0 == dstX1 - dstX0);     ASSERT(srcY1 - srcY0 == dstY1 - dstY0); -   /* determine if copy should be bottom-to-top or top-to-bottom */ +   /* From the GL_ARB_framebuffer_object spec: +    * +    *     "If the source and destination buffers are identical, and the source +    *      and destination rectangles overlap, the result of the blit operation +    *      is undefined." +    * +    * However, we provide the expected result anyway by flipping the order of +    * the memcpy of rows. +    */     if (srcY0 > dstY0) {        /* src above dst: copy bottom-to-top */        yStep = 1; diff --git a/mesalib/src/mesa/swrast/s_drawpix.c b/mesalib/src/mesa/swrast/s_drawpix.c index b6c433753..7259881c1 100644 --- a/mesalib/src/mesa/swrast/s_drawpix.c +++ b/mesalib/src/mesa/swrast/s_drawpix.c @@ -625,7 +625,8 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,                                    GL_DEPTH_STENCIL_EXT, type, i, 0);           if (ctx->Depth.Mask) { -            if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24) { +            if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24 && +		type == GL_UNSIGNED_INT_24_8) {                 /* fast path 24-bit zbuffer */                 GLuint zValues[MAX_WIDTH];                 GLint j; @@ -639,7 +640,8 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,                 else                    depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);              } -            else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16) { +            else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16 && +		     type == GL_UNSIGNED_INT_24_8) {                 /* fast path 16-bit zbuffer */                 GLushort zValues[MAX_WIDTH];                 GLint j; diff --git a/mesalib/src/mesa/tnl/t_draw.c b/mesalib/src/mesa/tnl/t_draw.c index 03424d7a4..83ded1949 100644 --- a/mesalib/src/mesa/tnl/t_draw.c +++ b/mesalib/src/mesa/tnl/t_draw.c @@ -430,7 +430,8 @@ void _tnl_vbo_draw_prims(struct gl_context *ctx,  			 const struct _mesa_index_buffer *ib,  			 GLboolean index_bounds_valid,  			 GLuint min_index, -			 GLuint max_index) +			 GLuint max_index, +			 struct gl_transform_feedback_object *tfb_vertcount)  {     if (!index_bounds_valid)        vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index); diff --git a/mesalib/src/mesa/tnl/tnl.h b/mesalib/src/mesa/tnl/tnl.h index 3ca0c5ebb..d3889811e 100644 --- a/mesalib/src/mesa/tnl/tnl.h +++ b/mesalib/src/mesa/tnl/tnl.h @@ -1,103 +1,104 @@ -/*
 - * Mesa 3-D graphics library
 - * Version:  7.1
 - *
 - * Copyright (C) 1999-2007  Brian Paul   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, 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 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
 - * BRIAN PAUL 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.
 - *
 - * Authors:
 - *    Keith Whitwell <keith@tungstengraphics.com>
 - */
 -
 -#ifndef _TNL_H
 -#define _TNL_H
 -
 -#include "main/glheader.h"
 -
 -struct gl_client_array;
 -struct gl_context;
 -struct gl_program;
 -
 -
 -/* These are the public-access functions exported from tnl.  (A few
 - * more are currently hooked into dispatch directly by the module
 - * itself.)
 - */
 -extern GLboolean
 -_tnl_CreateContext( struct gl_context *ctx );
 -
 -extern void
 -_tnl_DestroyContext( struct gl_context *ctx );
 -
 -extern void
 -_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state );
 -
 -/* Functions to revive the tnl module after being unhooked from
 - * dispatch and/or driver callbacks.
 - */
 -
 -extern void
 -_tnl_wakeup( struct gl_context *ctx );
 -
 -/* Driver configuration options:
 - */
 -extern void
 -_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag );
 -
 -
 -/* Control whether T&L does per-vertex fog
 - */
 -extern void
 -_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value );
 -
 -extern void
 -_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value );
 -
 -extern GLboolean
 -_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program);
 -
 -struct _mesa_prim;
 -struct _mesa_index_buffer;
 -
 -void
 -_tnl_draw_prims( struct gl_context *ctx,
 -		 const struct gl_client_array *arrays[],
 -		 const struct _mesa_prim *prim,
 -		 GLuint nr_prims,
 -		 const struct _mesa_index_buffer *ib,
 -		 GLuint min_index,
 -		 GLuint max_index);
 -
 -void
 -_tnl_vbo_draw_prims( struct gl_context *ctx,
 -		     const struct gl_client_array *arrays[],
 -		     const struct _mesa_prim *prim,
 -		     GLuint nr_prims,
 -		     const struct _mesa_index_buffer *ib,
 -		     GLboolean index_bounds_valid,
 -		     GLuint min_index,
 -		     GLuint max_index);
 -
 -extern void
 -_mesa_load_tracked_matrices(struct gl_context *ctx);
 -
 -extern void
 -_tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]);
 -
 -#endif
 +/* + * Mesa 3-D graphics library + * Version:  7.1 + * + * Copyright (C) 1999-2007  Brian Paul   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, 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 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 + * BRIAN PAUL 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. + * + * Authors: + *    Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef _TNL_H +#define _TNL_H + +#include "main/glheader.h" + +struct gl_client_array; +struct gl_context; +struct gl_program; + + +/* These are the public-access functions exported from tnl.  (A few + * more are currently hooked into dispatch directly by the module + * itself.) + */ +extern GLboolean +_tnl_CreateContext( struct gl_context *ctx ); + +extern void +_tnl_DestroyContext( struct gl_context *ctx ); + +extern void +_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state ); + +/* Functions to revive the tnl module after being unhooked from + * dispatch and/or driver callbacks. + */ + +extern void +_tnl_wakeup( struct gl_context *ctx ); + +/* Driver configuration options: + */ +extern void +_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag ); + + +/* Control whether T&L does per-vertex fog + */ +extern void +_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value ); + +extern void +_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value ); + +extern GLboolean +_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program); + +struct _mesa_prim; +struct _mesa_index_buffer; + +void +_tnl_draw_prims( struct gl_context *ctx, +		 const struct gl_client_array *arrays[], +		 const struct _mesa_prim *prim, +		 GLuint nr_prims, +		 const struct _mesa_index_buffer *ib, +		 GLuint min_index, +		 GLuint max_index); + +void +_tnl_vbo_draw_prims( struct gl_context *ctx, +		     const struct gl_client_array *arrays[], +		     const struct _mesa_prim *prim, +		     GLuint nr_prims, +		     const struct _mesa_index_buffer *ib, +		     GLboolean index_bounds_valid, +		     GLuint min_index, +		     GLuint max_index, +		     struct gl_transform_feedback_object *tfb_vertcount ); + +extern void +_mesa_load_tracked_matrices(struct gl_context *ctx); + +extern void +_tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]); + +#endif diff --git a/mesalib/src/mesa/vbo/vbo.h b/mesalib/src/mesa/vbo/vbo.h index 9fbb07f3d..f357657af 100644 --- a/mesalib/src/mesa/vbo/vbo.h +++ b/mesalib/src/mesa/vbo/vbo.h @@ -36,6 +36,7 @@  struct gl_client_array;  struct gl_context; +struct gl_transform_feedback_object;  struct _mesa_prim {     GLuint mode:8;    /**< GL_POINTS, GL_LINES, GL_QUAD_STRIP, etc */ @@ -77,7 +78,8 @@ typedef void (*vbo_draw_func)( struct gl_context *ctx,  			       const struct _mesa_index_buffer *ib,  			       GLboolean index_bounds_valid,  			       GLuint min_index, -			       GLuint max_index ); +			       GLuint max_index, +			       struct gl_transform_feedback_object *tfb_vertcount ); diff --git a/mesalib/src/mesa/vbo/vbo_context.h b/mesalib/src/mesa/vbo/vbo_context.h index ef8a2a2b6..1a1cc928b 100644 --- a/mesalib/src/mesa/vbo/vbo_context.h +++ b/mesalib/src/mesa/vbo/vbo_context.h @@ -67,6 +67,7 @@ struct vbo_context {     struct gl_client_array *generic_currval;     struct gl_client_array *mat_currval; +   /** Map VERT_ATTRIB_x to VBO_ATTRIB_y */     GLuint map_vp_none[VERT_ATTRIB_MAX];     GLuint map_vp_arb[VERT_ATTRIB_MAX]; diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index 97221a54d..a6e41e9c5 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -34,6 +34,7 @@  #include "main/bufferobj.h"  #include "main/enums.h"  #include "main/macros.h" +#include "main/transformfeedback.h"  #include "vbo_context.h" @@ -608,7 +609,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,           /* draw one or two prims */           check_buffers_are_unmapped(exec->array.inputs);           vbo->draw_prims(ctx, exec->array.inputs, prim, primCount, NULL, -                         GL_TRUE, start, start + count - 1); +                         GL_TRUE, start, start + count - 1, NULL);        }     }     else { @@ -618,7 +619,8 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,        check_buffers_are_unmapped(exec->array.inputs);        vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL, -                      GL_TRUE, start, start + count - 1); +                      GL_TRUE, start, start + count - 1, +                      NULL);     }  } @@ -824,7 +826,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,     check_buffers_are_unmapped(exec->array.inputs);     vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, -		    index_bounds_valid, start, end ); +		    index_bounds_valid, start, end, NULL );  } @@ -1168,7 +1170,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,        check_buffers_are_unmapped(exec->array.inputs);        vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib, -		      GL_FALSE, ~0, ~0); +		      GL_FALSE, ~0, ~0, NULL);     } else {        /* render one prim at a time */        for (i = 0; i < primcount; i++) { @@ -1193,7 +1195,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,           check_buffers_are_unmapped(exec->array.inputs);           vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib, -                         GL_FALSE, ~0, ~0); +                         GL_FALSE, ~0, ~0, NULL);        }     } @@ -1245,6 +1247,76 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,  				   basevertex);  } +#if FEATURE_EXT_transform_feedback + +static void +vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, +                            struct gl_transform_feedback_object *obj, +                            GLuint numInstances) +{ +   struct vbo_context *vbo = vbo_context(ctx); +   struct vbo_exec_context *exec = &vbo->exec; +   struct _mesa_prim prim[2]; + +   vbo_bind_arrays(ctx); + +   /* Again... because we may have changed the bitmask of per-vertex varying +    * attributes.  If we regenerate the fixed-function vertex program now +    * we may be able to prune down the number of vertex attributes which we +    * need in the shader. +    */ +   if (ctx->NewState) +      _mesa_update_state(ctx); + +   /* init most fields to zero */ +   memset(prim, 0, sizeof(prim)); +   prim[0].begin = 1; +   prim[0].end = 1; +   prim[0].mode = mode; +   prim[0].num_instances = numInstances; + +   /* Maybe we should do some primitive splitting for primitive restart +    * (like in DrawArrays), but we have no way to know how many vertices +    * will be rendered. */ + +   check_buffers_are_unmapped(exec->array.inputs); +   vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL, +                   GL_TRUE, 0, 0, obj); +} + +/** + * Like DrawArrays, but take the count from a transform feedback object. + * \param mode  GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. + * \param name  the transform feedback object + * User still has to setup of the vertex attribute info with + * glVertexPointer, glColorPointer, etc. + * Part of GL_ARB_transform_feedback2. + */ +static void GLAPIENTRY +vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name) +{ +   GET_CURRENT_CONTEXT(ctx); +   struct gl_transform_feedback_object *obj = +      _mesa_lookup_transform_feedback_object(ctx, name); + +   if (MESA_VERBOSE & VERBOSE_DRAW) +      _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", +                  _mesa_lookup_enum_by_nr(mode), name); + +   if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj)) { +      return; +   } + +   FLUSH_CURRENT(ctx, 0); + +   if (!_mesa_valid_to_render(ctx, "glDrawTransformFeedback")) { +      return; +   } + +   vbo_draw_transform_feedback(ctx, mode, obj, 1); +} + +#endif  /**   * Plug in the immediate-mode vertex array drawing commands into the @@ -1263,6 +1335,7 @@ vbo_exec_array_init( struct vbo_exec_context *exec )     exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;     exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;     exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex; +   exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback;  } @@ -1338,3 +1411,13 @@ _mesa_MultiDrawElementsBaseVertex(GLenum mode,     vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,  					primcount, basevertex);  } + +#if FEATURE_EXT_transform_feedback + +void GLAPIENTRY +_mesa_DrawTransformFeedback(GLenum mode, GLuint name) +{ +   vbo_exec_DrawTransformFeedback(mode, name); +} + +#endif diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c index 4962b54e1..dd5363beb 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_draw.c +++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c @@ -411,7 +411,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped)  				       NULL,  				       GL_TRUE,  				       0, -				       exec->vtx.vert_count - 1); +				       exec->vtx.vert_count - 1, +				       NULL);  	 /* If using a real VBO, get new storage -- unless asked not to.            */ diff --git a/mesalib/src/mesa/vbo/vbo_rebase.c b/mesalib/src/mesa/vbo/vbo_rebase.c index 97c8d1297..597a8f469 100644 --- a/mesalib/src/mesa/vbo/vbo_rebase.c +++ b/mesalib/src/mesa/vbo/vbo_rebase.c @@ -233,7 +233,8 @@ void vbo_rebase_prims( struct gl_context *ctx,  	 ib,   	 GL_TRUE,  	 0,  -	 max_index - min_index ); +	 max_index - min_index, +	 NULL );     if (tmp_indices)        free(tmp_indices); diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index 9d8bada04..952136747 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -999,6 +999,16 @@ _save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,  static void GLAPIENTRY +_save_DrawTransformFeedback(GLenum mode, GLuint name) +{ +   GET_CURRENT_CONTEXT(ctx); +   (void) mode; +   (void) name; +   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback"); +} + + +static void GLAPIENTRY  _save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)  {     GET_CURRENT_CONTEXT(ctx); @@ -1347,6 +1357,7 @@ _save_vtxfmt_init(struct gl_context *ctx)     vfmt->DrawRangeElements = _save_DrawRangeElements;     vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;     vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex; +   vfmt->DrawTransformFeedback = _save_DrawTransformFeedback;     vfmt->MultiDrawElementsEXT = _save_MultiDrawElements;     vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex;  } diff --git a/mesalib/src/mesa/vbo/vbo_save_draw.c b/mesalib/src/mesa/vbo/vbo_save_draw.c index 0773786b3..fa93ca48f 100644 --- a/mesalib/src/mesa/vbo/vbo_save_draw.c +++ b/mesalib/src/mesa/vbo/vbo_save_draw.c @@ -299,7 +299,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)                                        NULL,                                        GL_TRUE,                                        0,    /* Node is a VBO, so this is ok */ -                                      node->count - 1); +                                      node->count - 1, +                                      NULL);        }     } diff --git a/mesalib/src/mesa/vbo/vbo_split_copy.c b/mesalib/src/mesa/vbo/vbo_split_copy.c index 4dcf71ef5..b53293c31 100644 --- a/mesalib/src/mesa/vbo/vbo_split_copy.c +++ b/mesalib/src/mesa/vbo/vbo_split_copy.c @@ -196,7 +196,8 @@ flush( struct copy_context *copy )  	       ©->dstib,  	       GL_TRUE,  	       0, -	       copy->dstbuf_nr - 1 ); +	       copy->dstbuf_nr - 1, +	       NULL );     /* Reset all pointers:       */ diff --git a/mesalib/src/mesa/vbo/vbo_split_inplace.c b/mesalib/src/mesa/vbo/vbo_split_inplace.c index f6aa576b6..9e596f668 100644 --- a/mesalib/src/mesa/vbo/vbo_split_inplace.c +++ b/mesalib/src/mesa/vbo/vbo_split_inplace.c @@ -89,7 +89,8 @@ static void flush_vertex( struct split_context *split )  	       split->ib ? &ib : NULL,  	       !split->ib,  	       split->min_index, -	       split->max_index); +	       split->max_index, +	       NULL);     split->dstprim_nr = 0;     split->min_index = ~0; | 
