diff options
Diffstat (limited to 'src/mesa')
27 files changed, 539 insertions, 371 deletions
| diff --git a/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.c b/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.c index 49e04d81ec..ed223977e2 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.c @@ -307,20 +307,6 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)  } -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ -   struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); -   if (fence) { -      driFenceReference(fence); -      driFenceFinish(fence, -                     DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, -                     GL_FALSE); -      driFenceUnReference(fence); -   } -} - -  /*  This is the only way buffers get added to the validate list.   */  boolean diff --git a/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.h b/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.h index 82feafa21f..2c943e68e5 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/intel_winsys/intel_batchbuffer.h @@ -72,8 +72,6 @@ struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context *intel);  void intel_batchbuffer_free(struct intel_batchbuffer *batch); -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); -  struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer                                                  *batch); diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys.h b/src/mesa/drivers/dri/intel_winsys/intel_winsys.h index 89e63e0a79..f944cd23c3 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_winsys.h +++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys.h @@ -32,7 +32,9 @@ struct intel_context;  struct pipe_context;  struct pipe_winsys;  struct pipe_buffer_handle; +struct pipe_fence;  struct _DriBufferObject; +struct _DriFenceObject;  struct pipe_winsys *  intel_create_pipe_winsys( int fd ); @@ -66,5 +68,20 @@ pipe_bo( struct _DriBufferObject *bo )  } +/* Turn the pipe opaque buffer pointer into a dri_bufmgr opaque + * buffer pointer... + */ +static INLINE struct _DriFenceObject * +dri_fo( struct pipe_fence *bo ) +{ +   return (struct _DriFenceObject *)bo; +} + +static INLINE struct pipe_fence * +pipe_fo( struct _DriFenceObject *bo ) +{ +   return (struct pipe_fence *)bo; +} +  #endif diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c b/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c index 8e0eea4392..d73b309fd4 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c @@ -111,19 +111,62 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, -static void intel_i915_batch_flush( struct i915_winsys *sws ) +static void +intel_i915_batch_flush( struct i915_winsys *sws,  +                        struct pipe_fence **fence )  {     struct intel_context *intel = intel_i915_winsys(sws)->intel; +   struct pipe_fence *tmp_fence; +    +   tmp_fence = pipe_fo(intel_batchbuffer_flush( intel->batch )); +    +   /* this also increases the fence reference count, which is not done inside +    * intel_batchbuffer_flush call above +    */ +   sws->fence_reference(sws, fence, tmp_fence); +} -   intel_batchbuffer_flush( intel->batch ); -//   if (0) intel_i915_batch_wait_idle( sws ); + +static void  +intel_i915_fence_reference( struct i915_winsys *sws,  +                            struct pipe_fence **dst_fence, +                            struct pipe_fence *src_fence ) +{ +   struct _DriFenceObject **dri_dst_fence = (struct _DriFenceObject **)dst_fence; +   struct _DriFenceObject *dri_src_fence = (struct _DriFenceObject *)src_fence; +    +   if(dri_src_fence) +      driFenceReference(dri_src_fence); +    +   if(*dri_dst_fence) +      driFenceUnReference(*dri_dst_fence); +    +   *dri_dst_fence = dri_src_fence;  } -static void intel_i915_batch_finish( struct i915_winsys *sws ) +static int  +intel_i915_fence_is_signalled( struct i915_winsys *sws, +                               struct pipe_fence *fence )  { -   struct intel_context *intel = intel_i915_winsys(sws)->intel; -   intel_batchbuffer_finish( intel->batch ); +   struct _DriFenceObject *dri_fence = dri_fo(fence); +   if (fence) +      return driFenceSignaled(dri_fence, +                       DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW); +   return 1; +} + + +static int  +intel_i915_fence_wait( struct i915_winsys *sws, +                       struct pipe_fence *fence ) +{ +   struct _DriFenceObject *dri_fence = dri_fo(fence); +   if (fence) +      driFenceFinish(dri_fence, +                     DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, +                     GL_FALSE); +   return 1;  } @@ -143,7 +186,10 @@ intel_create_i915simple( struct intel_context *intel,     iws->winsys.batch_dword = intel_i915_batch_dword;     iws->winsys.batch_reloc = intel_i915_batch_reloc;     iws->winsys.batch_flush = intel_i915_batch_flush; -   iws->winsys.batch_finish = intel_i915_batch_finish; +   iws->winsys.fence_reference = intel_i915_fence_reference; +   iws->winsys.fence_is_signalled = intel_i915_fence_is_signalled; +   iws->winsys.fence_wait = intel_i915_fence_wait; +        iws->intel = intel;     /* Create the i915simple context: diff --git a/src/mesa/pipe/draw/draw_validate.c b/src/mesa/pipe/draw/draw_validate.c index fdeb1be8ca..4e8f986b27 100644 --- a/src/mesa/pipe/draw/draw_validate.c +++ b/src/mesa/pipe/draw/draw_validate.c @@ -85,6 +85,7 @@ static void validate_begin( struct draw_stage *stage )     /* Clip stage      */ +   if (!draw->rasterizer->bypass_clipping)     {        draw->pipeline.clip->next = next;        next = draw->pipeline.clip; diff --git a/src/mesa/pipe/draw/draw_vertex_fetch.c b/src/mesa/pipe/draw/draw_vertex_fetch.c index eca10e89fb..b510a4dbba 100644 --- a/src/mesa/pipe/draw/draw_vertex_fetch.c +++ b/src/mesa/pipe/draw/draw_vertex_fetch.c @@ -37,6 +37,10 @@  #include "pipe/tgsi/exec/tgsi_core.h" + +#define DBG 0 + +  /**   * Fetch a float[4] vertex attribute from memory, doing format/type   * conversion as needed. @@ -96,7 +100,9 @@ void draw_vertex_fetch( struct draw_context *draw,     for (j = 0; j < count; j++) {        uint attr; -      /*printf("fetch vertex %u: \n", j);*/ +#if DBG +      printf("fetch vertex %u: \n", j); +#endif        /* loop over vertex attributes (vertex shader inputs) */        for (attr = 0; attr < draw->vertex_shader->state->num_inputs; attr++) { @@ -111,7 +117,9 @@ void draw_vertex_fetch( struct draw_context *draw,           fetch_attrib4(src, draw->vertex_element[attr].src_format, p); -         /*printf("  %u: %f %f %f %f\n", attr, p[0], p[1], p[2], p[3]);*/ +#if DBG +         printf("  %u: %f %f %f %f\n", attr, p[0], p[1], p[2], p[3]); +#endif           /* Transform to AoS xxxx/yyyy/zzzz/wwww representation:            */ diff --git a/src/mesa/pipe/i915simple/i915_batch.h b/src/mesa/pipe/i915simple/i915_batch.h index fb88cd6db0..603d193f62 100644 --- a/src/mesa/pipe/i915simple/i915_batch.h +++ b/src/mesa/pipe/i915simple/i915_batch.h @@ -44,11 +44,11 @@  #define ADVANCE_BATCH() -#define FLUSH_BATCH() do { 				\ -   if (0) i915_dump_batchbuffer( i915 );		\ -   i915->winsys->batch_flush( i915->winsys );		\ -   i915->batch_start = NULL;				\ -   i915->hardware_dirty = ~0;				\ +#define FLUSH_BATCH() do { 						\ +   if (0) i915_dump_batchbuffer( i915 );				\ +   i915->winsys->batch_flush( i915->winsys, &i915->last_fence );	\ +   i915->batch_start = NULL;						\ +   i915->hardware_dirty = ~0;						\  } while (0)  #endif  diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c index e43274dc66..f5d770ce0d 100644 --- a/src/mesa/pipe/i915simple/i915_context.c +++ b/src/mesa/pipe/i915simple/i915_context.c @@ -175,6 +175,8 @@ static void i915_destroy( struct pipe_context *pipe )     draw_destroy( i915->draw ); +   i915->winsys->fence_reference( i915->winsys, &i915->last_fence, NULL ); +        free( i915 );  } diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index ee430ebc90..488682f852 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -80,6 +80,7 @@ +struct pipe_fence;  struct i915_cache_context;  /* Use to calculate differences between state emitted to hardware and @@ -184,6 +185,8 @@ struct i915_context     unsigned dirty;     unsigned *batch_start; +    +   struct pipe_fence *last_fence;     /** Vertex buffer */     struct pipe_buffer_handle *vbo; diff --git a/src/mesa/pipe/i915simple/i915_flush.c b/src/mesa/pipe/i915simple/i915_flush.c index 3c2069b827..1044cb1bdb 100644 --- a/src/mesa/pipe/i915simple/i915_flush.c +++ b/src/mesa/pipe/i915simple/i915_flush.c @@ -69,7 +69,8 @@ static void i915_flush( struct pipe_context *pipe,     FLUSH_BATCH();     if (flags & PIPE_FLUSH_WAIT) { -      i915->winsys->batch_finish(i915->winsys); +      if( i915->last_fence ) +	 i915->winsys->fence_wait(i915->winsys, i915->last_fence);     }  } diff --git a/src/mesa/pipe/i915simple/i915_winsys.h b/src/mesa/pipe/i915simple/i915_winsys.h index 2c0f335d34..386ed745d3 100644 --- a/src/mesa/pipe/i915simple/i915_winsys.h +++ b/src/mesa/pipe/i915simple/i915_winsys.h @@ -52,6 +52,7 @@  struct pipe_buffer_handle;  struct pipe_winsys; +struct pipe_fence;  /** @@ -97,8 +98,28 @@ struct i915_winsys {  			unsigned access_flags,  			unsigned delta ); -   void (*batch_flush)( struct i915_winsys *sws ); -   void (*batch_finish)( struct i915_winsys *sws ); +   /** +    * Flush the batch buffer. +    *  +    * Fence argument must point to NULL or to a previous fence, and the caller  +    * must call fence_reference when done with the fence. +    */ +   void (*batch_flush)( struct i915_winsys *sws, +                        struct pipe_fence **fence ); + + +   /* Fence  +    */ +   void (*fence_reference)( struct i915_winsys *sws,  +                            struct pipe_fence **dst_fence, +                            struct pipe_fence *src_fence ); + +   int (*fence_is_signalled)( struct i915_winsys *sws, +                              struct pipe_fence *fence ); +    +   int (*fence_wait)( struct i915_winsys *sws, +                      struct pipe_fence *fence ); +  };  #define I915_BUFFER_ACCESS_WRITE   0x1  diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 848c32701f..570f44e24e 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -92,6 +92,7 @@ struct pipe_rasterizer_state     unsigned line_stipple_enable:1;     unsigned line_stipple_factor:8;  /**< [1..256] actually */     unsigned line_stipple_pattern:16; +   unsigned bypass_clipping:1;     float line_width;     float point_size;           /**< used when no per-vertex size */ diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile index 2cbd9e5b51..59628531cc 100644 --- a/src/mesa/pipe/softpipe/Makefile +++ b/src/mesa/pipe/softpipe/Makefile @@ -18,6 +18,7 @@ DRIVER_SOURCES = \  	sp_quad_colormask.c \  	sp_quad_coverage.c \  	sp_quad_depth_test.c \ +	sp_quad_earlyz.c \  	sp_quad_fs.c \  	sp_quad_occlusion.c \  	sp_quad_output.c \ diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index be4da0ec64..d5e68c189d 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -161,6 +161,7 @@ static void softpipe_destroy( struct pipe_context *pipe )     draw_destroy( softpipe->draw );     softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); +   softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );     softpipe->quad.shade->destroy( softpipe->quad.shade );     softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );     softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); @@ -369,6 +370,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,     /* setup quad rendering stages */     softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); +   softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);     softpipe->quad.shade = sp_quad_shade_stage(softpipe);     softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);     softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index a411969bc0..872766101d 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -134,6 +134,7 @@ struct softpipe_context {     /** Software quad rendering pipeline */     struct {        struct quad_stage *polygon_stipple; +      struct quad_stage *earlyz;        struct quad_stage *shade;        struct quad_stage *alpha_test;        struct quad_stage *stencil_test; diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c index 429497e9b2..5a0df6de9d 100644 --- a/src/mesa/pipe/softpipe/sp_quad.c +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -28,24 +28,52 @@  #include "sp_context.h" +#include "sp_state.h" +#include "pipe/tgsi/exec/tgsi_token.h" +static void +sp_push_quad_first( +   struct softpipe_context *sp, +   struct quad_stage       *quad ) +{ +   quad->next = sp->quad.first; +   sp->quad.first = quad; +} + +static void +sp_build_depth_stencil( +   struct softpipe_context *sp ) +{ +   if (sp->depth_stencil->stencil.front_enabled || +       sp->depth_stencil->stencil.back_enabled) { +      sp_push_quad_first( sp, sp->quad.stencil_test ); +   } +   else if (sp->depth_stencil->depth.enabled && +            sp->framebuffer.zbuf) { +      sp_push_quad_first( sp, sp->quad.depth_test ); +   } +}  void  sp_build_quad_pipeline(struct softpipe_context *sp)  { +   boolean  early_depth_test = +               sp->depth_stencil->depth.enabled && +               sp->framebuffer.zbuf && +               !sp->alpha_test->enabled && +               sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION; +     /* build up the pipeline in reverse order... */     sp->quad.first = sp->quad.output;     if (sp->blend->colormask != 0xf) { -      sp->quad.colormask->next = sp->quad.first; -      sp->quad.first = sp->quad.colormask; +      sp_push_quad_first( sp, sp->quad.colormask );     }     if (sp->blend->blend_enable ||         sp->blend->logicop_enable) { -      sp->quad.blend->next = sp->quad.first; -      sp->quad.first = sp->quad.blend; +      sp_push_quad_first( sp, sp->quad.blend );     }     if (sp->framebuffer.num_cbufs == 1) { @@ -54,46 +82,38 @@ sp_build_quad_pipeline(struct softpipe_context *sp)     }     else {        /* insert bufloop stage */ -      sp->quad.bufloop->next = sp->quad.first; -      sp->quad.first = sp->quad.bufloop; +      sp_push_quad_first( sp, sp->quad.bufloop );     }     if (sp->depth_stencil->depth.occlusion_count) { -      sp->quad.occlusion->next = sp->quad.first; -      sp->quad.first = sp->quad.occlusion; +      sp_push_quad_first( sp, sp->quad.occlusion );     }     if (sp->rasterizer->poly_smooth ||         sp->rasterizer->line_smooth ||         sp->rasterizer->point_smooth) { -      sp->quad.coverage->next = sp->quad.first; -      sp->quad.first = sp->quad.coverage; +      sp_push_quad_first( sp, sp->quad.coverage );     } -   if (   sp->depth_stencil->stencil.front_enabled -       || sp->depth_stencil->stencil.back_enabled) { -      sp->quad.stencil_test->next = sp->quad.first; -      sp->quad.first = sp->quad.stencil_test; -   } -   else if (sp->depth_stencil->depth.enabled && -            sp->framebuffer.zbuf) { -      sp->quad.depth_test->next = sp->quad.first; -      sp->quad.first = sp->quad.depth_test; +   if (!early_depth_test) { +      sp_build_depth_stencil( sp );     }     if (sp->alpha_test->enabled) { -      sp->quad.alpha_test->next = sp->quad.first; -      sp->quad.first = sp->quad.alpha_test; +      sp_push_quad_first( sp, sp->quad.alpha_test );     }     /* XXX always enable shader? */     if (1) { -      sp->quad.shade->next = sp->quad.first; -      sp->quad.first = sp->quad.shade; +      sp_push_quad_first( sp, sp->quad.shade ); +   } + +   if (early_depth_test) { +      sp_build_depth_stencil( sp ); +      sp_push_quad_first( sp, sp->quad.earlyz );     }     if (sp->rasterizer->poly_stipple_enable) { -      sp->quad.polygon_stipple->next = sp->quad.first; -      sp->quad.first = sp->quad.polygon_stipple; +      sp_push_quad_first( sp, sp->quad.polygon_stipple );     }  } diff --git a/src/mesa/pipe/softpipe/sp_quad.h b/src/mesa/pipe/softpipe/sp_quad.h index 534541122b..f1e0281764 100644 --- a/src/mesa/pipe/softpipe/sp_quad.h +++ b/src/mesa/pipe/softpipe/sp_quad.h @@ -51,6 +51,7 @@ struct quad_stage {  struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_earlyz_stage( struct softpipe_context *softpipe );  struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );  struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );  struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe ); diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c index f7e93af784..3318189621 100644 --- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c +++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c @@ -119,6 +119,21 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)           }        }        break; +   case PIPE_FORMAT_Z24_S8: +      { +         float scale = (float) ((1 << 24) - 1); + +         for (j = 0; j < QUAD_SIZE; j++) { +            qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale); +         } + +         for (j = 0; j < QUAD_SIZE; j++) { +            int x = quad->x0 % TILE_SIZE + (j & 1); +            int y = quad->y0 % TILE_SIZE + (j >> 1); +            bzzzz[j] = tile->data.depth32[y][x] >> 8; +         } +      } +      break;     default:        assert(0);     } @@ -210,6 +225,15 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)              tile->data.depth32[y][x] = s8z24;           }           break; +      case PIPE_FORMAT_Z24_S8: +         for (j = 0; j < QUAD_SIZE; j++) { +            int x = quad->x0 % TILE_SIZE + (j & 1); +            int y = quad->y0 % TILE_SIZE + (j >> 1); +            uint z24s8 = tile->data.depth32[y][x]; +            z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 24); +            tile->data.depth32[y][x] = z24s8; +         } +         break;        default:           assert(0);        } diff --git a/src/mesa/pipe/softpipe/sp_quad_earlyz.c b/src/mesa/pipe/softpipe/sp_quad_earlyz.c new file mode 100644 index 0000000000..89fab2dd35 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_earlyz.c @@ -0,0 +1,92 @@ +/************************************************************************** + *  + * 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. + *  + **************************************************************************/ + +/** + * \brief  Quad early-z testing + */ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_headers.h" +#include "sp_quad.h" + + +/** + * All this stage does is compute the quad's Z values (which is normally + * done by the shading stage). + * The next stage will do the actual depth test. + */ +static void +earlyz_quad( +   struct quad_stage    *qs, +   struct quad_header   *quad ) +{ +   const float fx = (float) quad->x0; +   const float fy = (float) quad->y0; +   const float dzdx = quad->coef[0].dadx[2]; +   const float dzdy = quad->coef[0].dady[2]; +   const float z0 = quad->coef[0].a0[2] + dzdx * fx + dzdy * fy; + +   quad->outputs.depth[0] = z0; +   quad->outputs.depth[1] = z0 + dzdx; +   quad->outputs.depth[2] = z0 + dzdy; +   quad->outputs.depth[3] = z0 + dzdx + dzdy; + +   if (qs->next) { +      qs->next->run( qs->next, quad ); +   } +} + +static void +earlyz_begin( +   struct quad_stage *qs ) +{ +   if (qs->next) { +      qs->next->begin( qs->next ); +   } +} + +static void +earlyz_destroy( +   struct quad_stage *qs ) +{ +   FREE( qs ); +} + +struct quad_stage * +sp_quad_earlyz_stage( +   struct softpipe_context *softpipe ) +{ +   struct quad_stage *stage = CALLOC_STRUCT( quad_stage ); + +   stage->softpipe = softpipe; +   stage->begin = earlyz_begin; +   stage->run = earlyz_quad; +   stage->destroy = earlyz_destroy; + +   return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index 17fb10ea72..ed14dac18e 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -104,6 +104,10 @@ shade_quad(     machine->Inputs[0].xyzw[0].f[2] = fx;     machine->Inputs[0].xyzw[0].f[3] = fx + 1.0f; +   /* XXX for OpenGL we need to invert the Y pos here (y=0=top). +    * but that'll mess up linear/perspective interpolation of other +    * attributes... +    */     machine->Inputs[0].xyzw[1].f[0] = fy;     machine->Inputs[0].xyzw[1].f[1] = fy;     machine->Inputs[0].xyzw[1].f[2] = fy + 1.0f; diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c index 831ad8bad0..0149b20f48 100644 --- a/src/mesa/pipe/softpipe/sp_quad_stencil.c +++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c @@ -241,6 +241,13 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)           stencilVals[j] = tile->data.depth32[y][x] >> 24;        }        break; +   case PIPE_FORMAT_Z24_S8: +      for (j = 0; j < QUAD_SIZE; j++) { +         int x = quad->x0 % TILE_SIZE + (j & 1); +         int y = quad->y0 % TILE_SIZE + (j >> 1); +         stencilVals[j] = tile->data.depth32[y][x] & 0xff; +      } +      break;     case PIPE_FORMAT_U_S8:        for (j = 0; j < QUAD_SIZE; j++) {           int x = quad->x0 % TILE_SIZE + (j & 1); @@ -300,6 +307,15 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)           tile->data.depth32[y][x] = s8z24;        }        break; +   case PIPE_FORMAT_Z24_S8: +      for (j = 0; j < QUAD_SIZE; j++) { +         int x = quad->x0 % TILE_SIZE + (j & 1); +         int y = quad->y0 % TILE_SIZE + (j >> 1); +         uint z24s8 = tile->data.depth32[y][x]; +         z24s8 = (z24s8 & 0xffffff00) | stencilVals[j]; +         tile->data.depth32[y][x] = z24s8; +      } +      break;     case PIPE_FORMAT_U_S8:        for (j = 0; j < QUAD_SIZE; j++) {           int x = quad->x0 % TILE_SIZE + (j & 1); diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index ccaf38de3e..b7c9d4f004 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -461,6 +461,40 @@ s8z24_get_tile(struct pipe_surface *ps,  } +/*** PIPE_FORMAT_Z24_S8 ***/ + +/** + * Return Z component as four float in [0,1].  Stencil part ignored. + */ +static void +z24s8_get_tile(struct pipe_surface *ps, +               unsigned x, unsigned y, unsigned w, unsigned h, float *p) +{ +   const uint *src +      = ((const uint *) (ps->region->map + ps->offset)) +      + y * ps->region->pitch + x; +   const double scale = 1.0 / ((1 << 24) - 1); +   unsigned i, j; +   unsigned w0 = w; + +   assert(ps->format == PIPE_FORMAT_Z24_S8); + +   CLIP_TILE; + +   for (i = 0; i < h; i++) { +      float *pRow = p; +      for (j = 0; j < w; j++) { +         pRow[j * 4 + 0] = +         pRow[j * 4 + 1] = +         pRow[j * 4 + 2] = +         pRow[j * 4 + 3] = (float) (scale * (src[j] >> 8)); +      } +      src += ps->region->pitch; +      p += 4 * w0; +   } +} + +  /**   * Called via pipe->get_tex_surface()   * XXX is this in the right place? @@ -601,6 +635,9 @@ softpipe_get_tile_rgba(struct pipe_context *pipe,     case PIPE_FORMAT_S8_Z24:        s8z24_get_tile(ps, x, y, w, h, p);        break; +   case PIPE_FORMAT_Z24_S8: +      z24s8_get_tile(ps, x, y, w, h, p); +      break;     default:        assert(0);     } @@ -645,6 +682,9 @@ softpipe_put_tile_rgba(struct pipe_context *pipe,     case PIPE_FORMAT_S8_Z24:        /*s8z24_put_tile(ps, x, y, w, h, p);*/        break; +   case PIPE_FORMAT_Z24_S8: +      /*z24s8_put_tile(ps, x, y, w, h, p);*/ +      break;     default:        assert(0);     } diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index 19c06323e1..ea0c8b8f91 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -166,6 +166,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,        return;     is_depth_stencil = (ps->format == PIPE_FORMAT_S8_Z24 || +                       ps->format == PIPE_FORMAT_Z24_S8 ||                         ps->format == PIPE_FORMAT_U_Z16 ||                         ps->format == PIPE_FORMAT_U_Z32 ||                         ps->format == PIPE_FORMAT_U_S8); @@ -203,6 +204,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe,     struct pipe_surface *ps = tc->surface;     boolean is_depth_stencil        = (ps->format == PIPE_FORMAT_S8_Z24 || +         ps->format == PIPE_FORMAT_Z24_S8 ||           ps->format == PIPE_FORMAT_U_Z16 ||           ps->format == PIPE_FORMAT_U_Z32 ||           ps->format == PIPE_FORMAT_U_S8); @@ -268,6 +270,17 @@ sp_get_cached_tile(struct softpipe_context *softpipe,                 }              }              break; +         case PIPE_FORMAT_Z24_S8: +            { +               uint clear_val = ((uint) (tc->clear_value[0] * 0xffffff)) << 8; +               clear_val |= ((uint) tc->clear_value[1]) & 0xff; +               for (i = 0; i < TILE_SIZE; i++) { +                  for (j = 0; j < TILE_SIZE; j++) { +                     tile->data.depth32[i][j] = clear_val; +                  } +               } +            } +            break;           case PIPE_FORMAT_U_S8:              {                 ubyte clear_val = (uint) tc->clear_value[0]; diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.c b/src/mesa/pipe/tgsi/exec/tgsi_exec.c index 5c2fecb3e3..ea6c5021b3 100644 --- a/src/mesa/pipe/tgsi/exec/tgsi_exec.c +++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.c @@ -1346,17 +1346,15 @@ linear_interpolation(     unsigned attrib,     unsigned chan )  { -   unsigned i; - -   for( i = 0; i < QUAD_SIZE; i++ ) { -      const float x = mach->Inputs[0].xyzw[0].f[i]; -      const float y = mach->Inputs[0].xyzw[1].f[i]; - -      mach->Inputs[attrib].xyzw[chan].f[i] = -         mach->InterpCoefs[attrib].a0[chan] + -         mach->InterpCoefs[attrib].dadx[chan] * x + -         mach->InterpCoefs[attrib].dady[chan] * y; -   } +   const float x = mach->Inputs[0].xyzw[0].f[0]; +   const float y = mach->Inputs[0].xyzw[1].f[0]; +   const float dadx = mach->InterpCoefs[attrib].dadx[chan]; +   const float dady = mach->InterpCoefs[attrib].dady[chan]; +   const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; +   mach->Inputs[attrib].xyzw[chan].f[0] = a0; +   mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx; +   mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady; +   mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady;  }  static void @@ -1365,20 +1363,15 @@ perspective_interpolation(     unsigned attrib,     unsigned chan )  { -   unsigned i; - -   for( i = 0; i < QUAD_SIZE; i++ ) { -      const float x = mach->Inputs[0].xyzw[0].f[i]; -      const float y = mach->Inputs[0].xyzw[1].f[i]; -      /* WPOS.w here is really 1/w */ -      const float w = 1.0f / mach->Inputs[0].xyzw[3].f[i]; -      assert(mach->Inputs[0].xyzw[3].f[i] != 0.0); - -      mach->Inputs[attrib].xyzw[chan].f[i] = -         (mach->InterpCoefs[attrib].a0[chan] + -         mach->InterpCoefs[attrib].dadx[chan] * x + -         mach->InterpCoefs[attrib].dady[chan] * y) * w; -   } +   const float x = mach->Inputs[0].xyzw[0].f[0]; +   const float y = mach->Inputs[0].xyzw[1].f[0]; +   const float dadx = mach->InterpCoefs[attrib].dadx[chan]; +   const float dady = mach->InterpCoefs[attrib].dady[chan]; +   const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; +   mach->Inputs[attrib].xyzw[chan].f[0] = a0 / mach->Inputs[0].xyzw[3].f[0]; +   mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / mach->Inputs[0].xyzw[3].f[1]; +   mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / mach->Inputs[0].xyzw[3].f[2]; +   mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / mach->Inputs[0].xyzw[3].f[3];  } diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index 5b97c1ee34..5279cb1cd4 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -25,353 +25,229 @@   *    **************************************************************************/ - /* -  * Authors: -  *   Brian Paul -  */ +/** + * 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/feedback.h"  #include "main/macros.h"  #include "st_context.h"  #include "st_atom.h" -#include "st_cache.h"  #include "st_draw.h" -#include "st_program.h"  #include "st_cb_rasterpos.h"  #include "st_draw.h" -#include "st_format.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_winsys.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_private.h"  #include "shader/prog_instruction.h" +#include "vbo/vbo.h" -static void -setup_vertex_attribs(GLcontext *ctx) +/** + * Our special drawing pipeline stage (replaces rasterization). + */ +struct rastpos_stage  { -   struct pipe_context *pipe = ctx->st->pipe; -   const struct cso_vertex_shader *vs = ctx->st->state.vs; -   const struct st_vertex_program *stvp = ctx->st->vp; -   uint slot; +   struct draw_stage stage;   /**< Base class */ +   GLcontext *ctx;            /**< Rendering context */ -   /* all attributes come from the default attribute buffer */ -   { -      struct pipe_vertex_buffer vbuffer; -      vbuffer.buffer = ctx->st->default_attrib_buffer; -      vbuffer.buffer_offset = 0; -      vbuffer.pitch = 0; /* must be zero! */ -      vbuffer.max_index = 1; -      pipe->set_vertex_buffer(pipe, 0, &vbuffer); -   } +   /* 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; +}; -   for (slot = 0; slot < vs->state.num_inputs; slot++) { -      struct pipe_vertex_element velement; -      const GLuint attr = stvp->index_to_input[slot]; -      velement.src_offset = attr * 4 * sizeof(GLfloat); -      velement.vertex_buffer_index = 0; -      velement.dst_offset = 0; -      velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; -      pipe->set_vertex_element(pipe, slot, &velement); -   } +static INLINE struct rastpos_stage * +rastpos_stage( struct draw_stage *stage ) +{ +   return (struct rastpos_stage *) stage;  } -  static void -setup_feedback(GLcontext *ctx) +rastpos_begin( struct draw_stage *stage )  { -   struct pipe_context *pipe = ctx->st->pipe; -   const struct pipe_shader_state *vs = &ctx->st->state.vs->state; -   struct pipe_feedback_state feedback; -   uint i; - -   memset(&feedback, 0, sizeof(feedback)); -   feedback.enabled = 1; -   feedback.interleaved = 1; -   feedback.discard = 1; -   feedback.num_attribs = 0; - -   /* feedback all results from vertex shader */ -   for (i = 0; i < vs->num_outputs; i++) { -      feedback.attrib[feedback.num_attribs] = i; -      feedback.size[feedback.num_attribs] = 4; -      feedback.num_attribs++; -   } - -   if (pipe->set_feedback_state) -      pipe->set_feedback_state(pipe, &feedback); +   /* no-op */  } +static void +rastpos_end( struct draw_stage *stage ) +{ +   /* no-op */ +} - - - -/** - * Clip a point against the view volume. - * - * \param v vertex vector describing the point to clip. - *  - * \return zero if outside view volume, or one if inside. - */ -static GLuint -viewclip_point( const GLfloat v[] ) +static void +rastpos_reset_stipple_counter( struct draw_stage *stage )  { -   if (   v[0] > v[3] || v[0] < -v[3] -       || v[1] > v[3] || v[1] < -v[3] -       || v[2] > v[3] || v[2] < -v[3] ) { -      return 0; -   } -   else { -      return 1; -   } +   /* no-op */  } +static void +rastpos_tri( struct draw_stage *stage, struct prim_header *prim ) +{ +   /* should never get here */ +   assert(0); +} -/** - * Clip a point against the far/near Z clipping planes. - * - * \param v vertex vector describing the point to clip. - *  - * \return zero if outside view volume, or one if inside. - */ -static GLuint -viewclip_point_z( const GLfloat v[] ) +static void +rastpos_line( struct draw_stage *stage, struct prim_header *prim )  { -   if (v[2] > v[3] || v[2] < -v[3] ) { -      return 0; -   } -   else { -      return 1; -   } +   /* should never get here */ +   assert(0);  }  /** - * Clip a point against the user clipping planes. - *  - * \param ctx GL context. - * \param v vertex vector describing the point to clip. - *  - * \return zero if the point was clipped, or one otherwise. + * Update a raster pos attribute from the vertex result if it's present, + * else copy the current attrib.   */ -static GLuint -userclip_point( GLcontext *ctx, const GLfloat v[] ) +static void +update_attrib(GLcontext *ctx, const GLuint *outputMapping, +              const struct vertex_header *vert, +              GLfloat *dest, +              GLuint result, GLuint defaultAttrib)  { -   GLuint p; - -   for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { -      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { -	 GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0] -		     + v[1] * ctx->Transform._ClipUserPlane[p][1] -		     + v[2] * ctx->Transform._ClipUserPlane[p][2] -		     + v[3] * ctx->Transform._ClipUserPlane[p][3]; -         if (dot < 0.0F) { -            return 0; -         } -      } -   } - -   return 1; +   const GLfloat *src; +   const GLuint k = outputMapping[result]; +   if (k != ~0) +      src = vert->data[k]; +   else +      src = ctx->Current.Attrib[defaultAttrib]; +   COPY_4V(dest, src);  }  /** - * Update the current raster position. - * Do clip testing, etc. here. + * Normally, this function would render a GL_POINT.   */  static void -update_rasterpos(GLcontext *ctx, -                 const float clipPos[4], -                 const float color0[4], -                 const float color1[4], -                 const float *fog, -                 const float *tex) +rastpos_point(struct draw_stage *stage, struct prim_header *prim)  { -   uint i; -   float d, ndc[3]; +   struct rastpos_stage *rs = rastpos_stage(stage); +   GLcontext *ctx = rs->ctx; +   struct st_context *st = ctx->st; +   const GLfloat height = ctx->DrawBuffer->Height; +   const GLuint *outputMapping = st->vertex_result_to_slot; +   const GLfloat *pos; +   GLuint i; -   /* clip to view volume */ -   if (ctx->Transform.RasterPositionUnclipped) { -      /* GL_IBM_rasterpos_clip: only clip against Z */ -      if (viewclip_point_z(clipPos) == 0) { -         ctx->Current.RasterPosValid = GL_FALSE; -         return; -      } -   } -   else if (viewclip_point(clipPos) == 0) { -      /* Normal OpenGL behaviour */ -      ctx->Current.RasterPosValid = GL_FALSE; -      return; -   } +   /* if we get here, we didn't get clipped */ +   ctx->Current.RasterPosValid = GL_TRUE; -   /* clip to user clipping planes */ -   if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clipPos)) { -      ctx->Current.RasterPosValid = GL_FALSE; -      return; -   } +   /* update raster pos */ +   pos = prim->v[0]->data[0]; +   ctx->Current.RasterPos[0] = pos[0]; +   ctx->Current.RasterPos[1] = height - 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 current raster position -    */ -   /* ndc = clip / W */ -   d = (clipPos[3] == 0.0F) ? 1.0F : 1.0F / clipPos[3]; -   ndc[0] = clipPos[0] * d; -   ndc[1] = clipPos[1] * d; -   ndc[2] = clipPos[2] * d; -   /* wincoord = viewport_mapping(ndc) */ -   ctx->Current.RasterPos[0] = (ndc[0] * ctx->Viewport._WindowMap.m[MAT_SX] -                                + ctx->Viewport._WindowMap.m[MAT_TX]); -   ctx->Current.RasterPos[1] = (ndc[1] * ctx->Viewport._WindowMap.m[MAT_SY] -                                + ctx->Viewport._WindowMap.m[MAT_TY]); -   ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport._WindowMap.m[MAT_SZ] -                                + ctx->Viewport._WindowMap.m[MAT_TZ]) -                               / ctx->DrawBuffer->_DepthMaxF; -   ctx->Current.RasterPos[3] = clipPos[3]; +   update_attrib(ctx, outputMapping, prim->v[0], +                 ctx->Current.RasterSecondaryColor, +                 VERT_RESULT_COL1, VERT_ATTRIB_COLOR1); -   /* compute raster distance */ -#if 0 -   if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) -      ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; -   else { -      /* XXX we don't have an eye coord! */ -      ctx->Current.RasterDistance = -         SQRTF( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] ); +   for (i = 0; i < MAX_TEXTURE_UNITS; i++) { +      update_attrib(ctx, outputMapping, prim->v[0], +                    ctx->Current.RasterTexCoords[i], +                    VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);     } -#else -   ctx->Current.RasterDistance = fog[0]; -#endif +} -   /* colors and texcoords */ -   COPY_4FV(ctx->Current.RasterColor, color0); -   COPY_4FV(ctx->Current.RasterSecondaryColor, color1); -   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { -      COPY_4FV(ctx->Current.RasterTexCoords + i, tex + i *4); -   } -   ctx->Current.RasterPosValid = GL_TRUE; +/** + * Create rasterpos "drawing" stage. + */ +static struct rastpos_stage * +new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw) +{ +   struct rastpos_stage *rs = CALLOC_STRUCT(rastpos_stage); -   if (ctx->RenderMode == GL_SELECT) { -      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); -   } -} +   rs->stage.draw = draw; +   rs->stage.next = NULL; +   rs->stage.begin = rastpos_begin; +   rs->stage.point = rastpos_point; +   rs->stage.line = rastpos_line; +   rs->stage.tri = rastpos_tri; +   rs->stage.end = rastpos_end; +   rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter; +   rs->ctx = ctx; +   return rs; +}  static void  st_RasterPos(GLcontext *ctx, const GLfloat v[4])  { -   const struct st_context *st = ctx->st; -   struct pipe_context *pipe = st->pipe; -   float *buf_map; -   struct pipe_feedback_buffer fb_buf; - -   st_validate_state(ctx->st); - -   /* setup vertex buffers */ -   setup_vertex_attribs(ctx); +   struct st_context *st = ctx->st; +   struct draw_context *draw = st->draw; +   struct rastpos_stage *rs; -   /* -    * Load the default attribute buffer with current attribs. -    */ -   { -      struct pipe_buffer_handle *buf = st->default_attrib_buffer; -      const unsigned size = sizeof(ctx->Current.Attrib); -      const void *data = ctx->Current.Attrib; -      /* colors, texcoords, etc */ -      pipe->winsys->buffer_data(pipe->winsys, buf,  -                                size, data,  -                                PIPE_BUFFER_USAGE_VERTEX); -      /* position */ -      pipe->winsys->buffer_subdata(pipe->winsys, buf, -                                   0, /* offset */ -                                   4 * sizeof(float), /* size */ -                                   v); /* data */ -   } - - -   /* setup feedback state */ -   setup_feedback(ctx); - -   /* setup vertex feedback buffer */ -   { -      fb_buf.size = 8 * 4 * sizeof(float); -      fb_buf.buffer = pipe->winsys->buffer_create(pipe->winsys, 0); -      fb_buf.start_offset = 0; -      pipe->winsys->buffer_data(pipe->winsys, fb_buf.buffer, -                                fb_buf.size, -                                NULL, /* data */ -                                PIPE_BUFFER_USAGE_VERTEX); -      if (pipe->set_feedback_buffer) -         pipe->set_feedback_buffer(pipe, 0, &fb_buf); +   if (st->rastpos_stage) { +      /* get rastpos stage info */ +      rs = rastpos_stage(st->rastpos_stage);     } +   else { +      /* create rastpos draw stage */ +      GLuint i; +      rs = new_draw_rastpos_stage(ctx, draw); +      st->rastpos_stage = &rs->stage; -   /* draw a point */ -   pipe->draw_arrays(pipe, GL_POINTS, 0, 1); - -   /* get feedback */ -   buf_map = (float *) pipe->winsys->buffer_map(pipe->winsys, fb_buf.buffer, -                                                PIPE_BUFFER_FLAG_READ); - -   /* extract values and update rasterpos state */ -   { -      const GLuint *outputMapping = st->vertex_result_to_slot; -      const float *pos, *color0, *color1, *fog, *tex0; -      float *buf = buf_map; - -      assert(outputMapping[VERT_RESULT_HPOS] != ~0); -      pos = buf; -      buf += 4; - -      if (outputMapping[VERT_RESULT_COL0] != ~0) { -         color0 = buf; -         buf += 4; -      } -      else { -         color0 = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; +      /* one-time init */ +      for (i = 0; i < VERT_ATTRIB_MAX; i++) { +         rs->array[i].Size = 4; +         rs->array[i].Type = GL_FLOAT; +         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];        } -      if (outputMapping[VERT_RESULT_COL1] != ~0) { -         color1 = buf; -         buf += 4; -      } -      else { -         color1 = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; -      } +      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; +   } -      if (outputMapping[VERT_RESULT_FOGC] != ~0) { -         fog = buf; -         buf += 4; -      } -      else { -         fog = ctx->Current.Attrib[VERT_ATTRIB_FOG]; -      } +   /* plug our rastpos stage into the draw module */ +   draw_set_rasterize_stage(st->draw, st->rastpos_stage); -      if (outputMapping[VERT_RESULT_TEX0] != ~0) { -         tex0 = buf; -         buf += 4; -      } -      else { -         tex0 = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; -      } +   /* make sure everything's up to date */ +   st_validate_state(ctx->st); -      update_rasterpos(ctx, pos, color0, color1, fog, tex0); -   } +   /* This will get set only if rastpos_point(), above, gets called */ +   ctx->Current.RasterPosValid = GL_FALSE; -   /* free vertex feedback buffer */ -   pipe->winsys->buffer_unmap(pipe->winsys, fb_buf.buffer); -   pipe->winsys->buffer_reference(pipe->winsys, &fb_buf.buffer, NULL); +   /* All vertex attribs but position were previously initialized above. +    * Just plug in position pointer now. +    */ +   rs->array[0].Ptr = (GLubyte *) v; -   /* restore pipe state */ -   if (pipe->set_feedback_state) -      pipe->set_feedback_state(pipe, &st->state.feedback); +   /* draw the point */ +   st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, 0, 1);  } +  void st_init_rasterpos_functions(struct dd_function_table *functions)  {     functions->RasterPos = st_RasterPos; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 82e133911f..a6045230a0 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -68,9 +68,10 @@ struct st_context     struct pipe_context *pipe; -   struct draw_context *draw;  /**< For selection/feedback */ +   struct draw_context *draw;  /**< For selection/feedback/rastpos only */     struct draw_stage *feedback_stage;  /**< For GL_FEEDBACK rendermode */     struct draw_stage *selection_stage;  /**< For GL_SELECT rendermode */ +   struct draw_stage *rastpos_stage;  /**< For glRasterPos */     /* Some state is contained in constant objects.      * Other state is just parameter values. diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 3e2ed6cada..3b6d829145 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -318,7 +318,7 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,  /**   * Set the (private) draw module's post-transformed vertex format when in - * GL_SELECT or GL_FEEDBACK mode. + * GL_SELECT or GL_FEEDBACK mode or for glRasterPos.   */  static void  set_feedback_vertex_format(GLcontext *ctx) @@ -328,7 +328,14 @@ set_feedback_vertex_format(GLcontext *ctx)     enum interp_mode interp[PIPE_MAX_SHADER_OUTPUTS];     GLuint n, i; -   if (ctx->RenderMode == GL_FEEDBACK) { +   if (ctx->RenderMode == GL_SELECT) { +      assert(ctx->RenderMode == GL_SELECT); +      n = 1; +      attrs[0] = FORMAT_4F; +      interp[0] = INTERP_NONE; +   } +   else { +      /* GL_FEEDBACK, or glRasterPos */        /* emit all attribs (pos, color, texcoord) as GLfloat[4] */        n = st->state.vs->state.num_outputs;        for (i = 0; i < n; i++) { @@ -336,19 +343,14 @@ set_feedback_vertex_format(GLcontext *ctx)           interp[i] = INTERP_NONE;        }     } -   else { -      assert(ctx->RenderMode == GL_SELECT); -      n = 1; -      attrs[0] = FORMAT_4F; -      interp[0] = INTERP_NONE; -   }     draw_set_vertex_attributes(st->draw, attrs, interp, n);  }  /** - * Called by VBO to draw arrays when in selection or feedback mode. + * Called by VBO to draw arrays when in selection or feedback mode and + * to implement glRasterPos.   * This is very much like the normal draw_vbo() function above.   * Look at code refactoring some day.   * Might move this into the failover module some day. @@ -373,8 +375,6 @@ st_feedback_draw_vbo(GLcontext *ctx,     GLuint attr, i;     ubyte *mapped_constants; -   assert(ctx->RenderMode == GL_SELECT || -          ctx->RenderMode == GL_FEEDBACK);     assert(draw);     st_validate_state(ctx->st); | 
