diff options
| author | Keith Whitwell <keithw@vmware.com> | 2009-02-18 12:54:26 +0000 | 
|---|---|---|
| committer | Keith Whitwell <keithw@vmware.com> | 2009-02-18 12:54:26 +0000 | 
| commit | 89e2b9c6c24e1a0b7690b9a7502b0ea198069d10 (patch) | |
| tree | 520ef9752161f6f79851f8d44290baafd72c0a4d | |
| parent | ea4bf267e4b023b08043f91ac44592fed1736e7f (diff) | |
| parent | b57031624ef94dd3128f989acabdffa2f2a32f57 (diff) | |
Merge commit 'origin/draw-vbuf-interface'
| -rw-r--r-- | configs/default | 2 | ||||
| -rw-r--r-- | progs/demos/isosurf.c | 14 | ||||
| -rw-r--r-- | progs/trivial/.gitignore | 1 | ||||
| -rw-r--r-- | progs/trivial/Makefile | 1 | ||||
| -rw-r--r-- | progs/trivial/SConscript | 1 | ||||
| -rw-r--r-- | progs/trivial/tri-unfilled-fog.c | 152 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 91 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.h | 2 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_emit.c | 67 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 69 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 104 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_vbuf.h | 16 | ||||
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_prim_vbuf.c | 57 | ||||
| -rw-r--r-- | src/gallium/drivers/nv04/nv04_prim_vbuf.c | 22 | ||||
| -rw-r--r-- | src/gallium/drivers/nv10/nv10_prim_vbuf.c | 36 | ||||
| -rw-r--r-- | src/gallium/drivers/nv20/nv20_prim_vbuf.c | 58 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_reg.h | 88 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_swtcl_emit.c | 331 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_prim_vbuf.c | 45 | 
20 files changed, 789 insertions, 370 deletions
| diff --git a/configs/default b/configs/default index a90d46f18e..2566a860a2 100644 --- a/configs/default +++ b/configs/default @@ -92,7 +92,7 @@ EGL_DRIVERS_DIRS = demo  GALLIUM_DIRS = auxiliary drivers state_trackers  GALLIUM_AUXILIARY_DIRS = draw translate cso_cache pipebuffer tgsi sct rtasm util indices  GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple failover trace +GALLIUM_DRIVER_DIRS = softpipe #i915simple i965simple failover trace  GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)  GALLIUM_WINSYS_DIRS = xlib egl_xlib  GALLIUM_WINSYS_DRM_DIRS = diff --git a/progs/demos/isosurf.c b/progs/demos/isosurf.c index 393741cc9d..e280d8f507 100644 --- a/progs/demos/isosurf.c +++ b/progs/demos/isosurf.c @@ -69,6 +69,7 @@  #define NO_STIPPLE	0x08000000  #define POLYGON_FILL	0x10000000  #define POLYGON_LINE	0x20000000 +#define POLYGON_POINT	0x40000000  #define LIGHT_MASK		(LIT|UNLIT|REFLECT)  #define FILTER_MASK		(POINT_FILTER|LINEAR_FILTER) @@ -81,7 +82,7 @@  #define SHADE_MASK		(SHADE_SMOOTH|SHADE_FLAT)  #define FOG_MASK		(FOG|NO_FOG)  #define STIPPLE_MASK		(STIPPLE|NO_STIPPLE) -#define POLYGON_MASK		(POLYGON_FILL|POLYGON_LINE) +#define POLYGON_MASK		(POLYGON_FILL|POLYGON_LINE|POLYGON_POINT)  #define MAXVERTS 10000  static GLint maxverts = MAXVERTS; @@ -147,7 +148,7 @@ static void read_surface( char *filename )  static void print_flags( const char *msg, GLuint flags )   {     fprintf(stderr,  -	   "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", +	   "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",  	   msg, flags,  	   (flags & GLVERTEX) ? "glVertex, " : "",  	   (flags & DRAW_ARRAYS) ? "glDrawArrays, " : "", @@ -166,7 +167,8 @@ static void print_flags( const char *msg, GLuint flags )  	   (flags & MATERIALS) ? "materials, " : "",  	   (flags & FOG) ? "fog, " : "",  	   (flags & STIPPLE) ? "stipple, " : "", -	   (flags & POLYGON_LINE) ? "polygon mode line, " : ""); +	   (flags & POLYGON_LINE) ? "polygon mode line, " : "", +	   (flags & POLYGON_POINT) ? "polygon mode point, " : "");  } @@ -711,9 +713,12 @@ static void ModeMenu(int m)        if (m & POLYGON_FILL) {  	 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);        } -      else { +      else if (m & POLYGON_LINE) {  	 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);        } +      else { +	 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); +      }     }  #ifdef GL_EXT_vertex_array @@ -1089,6 +1094,7 @@ int main(int argc, char **argv)     glutAddMenuEntry("", 0);     glutAddMenuEntry("Polygon Mode Fill",     POLYGON_FILL);     glutAddMenuEntry("Polygon Mode Line",     POLYGON_LINE); +   glutAddMenuEntry("Polygon Mode Points",   POLYGON_POINT);     glutAddMenuEntry("", 0);     glutAddMenuEntry("Point Filtered",        POINT_FILTER);     glutAddMenuEntry("Linear Filtered",       LINEAR_FILTER); diff --git a/progs/trivial/.gitignore b/progs/trivial/.gitignore index d77f120b96..f58345ce3b 100644 --- a/progs/trivial/.gitignore +++ b/progs/trivial/.gitignore @@ -102,6 +102,7 @@ tri-tri  tri-unfilled  tri-unfilled-clip  tri-unfilled-edgeflag +tri-unfilled-fog  tri-unfilled-smooth  tri-unfilled-tri  tri-unfilled-tri-lit diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index dce96f6bc8..2800f3ef82 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -108,6 +108,7 @@ SOURCES = \  	tri-tex.c \  	tri-tex-3d.c \  	tri-tri.c \ +	tri-unfilled-fog.c \  	tri-unfilled-edgeflag.c \  	tri-unfilled-clip.c \  	tri-unfilled-smooth.c \ diff --git a/progs/trivial/SConscript b/progs/trivial/SConscript index 76826d9be0..d699e2b46b 100644 --- a/progs/trivial/SConscript +++ b/progs/trivial/SConscript @@ -103,6 +103,7 @@ progs = [  	'tri-tex',  	'tri-tex-3d',  	'tri-tri', +	'tri-unfilled-fog',  	'tri-unfilled-edgeflag',  	'tri-unfilled-clip',  	'tri-unfilled-smooth', diff --git a/progs/trivial/tri-unfilled-fog.c b/progs/trivial/tri-unfilled-fog.c new file mode 100644 index 0000000000..90444aecdf --- /dev/null +++ b/progs/trivial/tri-unfilled-fog.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glut.h> + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + +GLint Width = 250, Height = 250; + +GLenum doubleBuffer; + +static void Init(void) +{ +   fprintf(stderr, "GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER)); +   fprintf(stderr, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION)); +   fprintf(stderr, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR)); + +   glClearColor(0.0, 0.0, 1.0, 0.0); +} + +static void Reshape(int width, int height) +{ +   glViewport(0, 0, (GLint)width, (GLint)height); + +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); +   glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ +   switch (key) { +      case 27: +         exit(1); +   } + +   glutPostRedisplay(); +} + +static void Draw(void) +{ +   glClear(GL_COLOR_BUFFER_BIT);  + +   glEnable(GL_FOG); + +   glPolygonMode(GL_FRONT, GL_FILL); +   glPolygonMode(GL_BACK, GL_FILL); + +   glBegin(GL_TRIANGLES); +   glColor3f(0,0,.7);  +   glVertex3f( 0.7, -0.7, -30.0); +   glColor3f(.8,0,0);  +   glVertex3f( 0.7,  0.7, -30.0); +   glColor3f(0,.9,0);  +   glVertex3f(-0.7,  0.0, -30.0); +   glEnd(); + +   glPolygonMode(GL_FRONT, GL_LINE); +   glPolygonMode(GL_BACK, GL_LINE); + +   glBegin(GL_TRIANGLES); +   glColor3f(0,0,.7);  +   glVertex3f( 0.9, -0.9, -30.0); +   glColor3f(.8,0,0);  +   glVertex3f( 0.9,  0.9, -30.0); +   glColor3f(0,.9,0);  +   glVertex3f(-0.9,  0.0, -30.0); +   glEnd(); + +   glDisable(GL_FOG); + +   glFlush(); + +   if (doubleBuffer) { +      glutSwapBuffers(); +   } +} + +static GLenum Args(int argc, char **argv) +{ +   GLint i; + +   doubleBuffer = GL_FALSE; + +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "-sb") == 0) { +         doubleBuffer = GL_FALSE; +      } else if (strcmp(argv[i], "-db") == 0) { +         doubleBuffer = GL_TRUE; +      } else { +         fprintf(stderr, "%s (Bad option).\n", argv[i]); +         return GL_FALSE; +      } +   } +   return GL_TRUE; +} + +int main(int argc, char **argv) +{ +   GLenum type; + +   glutInit(&argc, argv); + +   if (Args(argc, argv) == GL_FALSE) { +      exit(1); +   } + +   glutInitWindowPosition(100, 0); glutInitWindowSize(Width, Height); + +   type = GLUT_RGB; +   type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; +   glutInitDisplayMode(type); + +   if (glutCreateWindow("Filled and unfilled fog tri") == GL_FALSE) { +      exit(1); +   } + +   Init(); + +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutDisplayFunc(Draw); +   glutMainLoop(); +   return 0; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 0c4e9412e2..12325d30d6 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -93,7 +93,6 @@ vbuf_stage( struct draw_stage *stage )  } -static void vbuf_flush_indices( struct vbuf_stage *vbuf );  static void vbuf_flush_vertices( struct vbuf_stage *vbuf );  static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); @@ -109,13 +108,12 @@ overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz )  static INLINE void   check_space( struct vbuf_stage *vbuf, unsigned nr )  { -   if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { -      vbuf_flush_vertices(vbuf); -      vbuf_alloc_vertices(vbuf); +   if (vbuf->nr_vertices + nr > vbuf->max_vertices || +       vbuf->nr_indices + nr > vbuf->max_indices) +   { +      vbuf_flush_vertices( vbuf ); +      vbuf_alloc_vertices( vbuf );     } - -   if (vbuf->nr_indices + nr > vbuf->max_indices ) -      vbuf_flush_indices(vbuf);  } @@ -202,7 +200,7 @@ vbuf_point( struct draw_stage *stage,   * will be flushed if needed and a new one allocated.   */  static void -vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) +vbuf_start_prim( struct vbuf_stage *vbuf, uint prim )  {     struct translate_key hw_key;     unsigned dst_offset; @@ -217,11 +215,7 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )      * state change.      */     vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); - -   if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { -      vbuf_flush_vertices(vbuf); -      vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); -   } +   vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);     /* Translate from pipeline vertices to hw vertices.      */ @@ -294,8 +288,8 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )     /* Allocate new buffer?      */ -   if (!vbuf->vertices) -      vbuf_alloc_vertices(vbuf); +   assert(vbuf->vertices == NULL); +   vbuf_alloc_vertices(vbuf);  } @@ -305,9 +299,9 @@ vbuf_first_tri( struct draw_stage *stage,  {     struct vbuf_stage *vbuf = vbuf_stage( stage ); -   vbuf_flush_indices( vbuf );    +   vbuf_flush_vertices( vbuf ); +   vbuf_start_prim(vbuf, PIPE_PRIM_TRIANGLES);     stage->tri = vbuf_tri; -   vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES);     stage->tri( stage, prim );  } @@ -318,9 +312,9 @@ vbuf_first_line( struct draw_stage *stage,  {     struct vbuf_stage *vbuf = vbuf_stage( stage ); -   vbuf_flush_indices( vbuf ); +   vbuf_flush_vertices( vbuf ); +   vbuf_start_prim(vbuf, PIPE_PRIM_LINES);     stage->line = vbuf_line; -   vbuf_set_prim(vbuf, PIPE_PRIM_LINES);     stage->line( stage, prim );  } @@ -331,53 +325,42 @@ vbuf_first_point( struct draw_stage *stage,  {     struct vbuf_stage *vbuf = vbuf_stage( stage ); -   vbuf_flush_indices( vbuf ); +   vbuf_flush_vertices(vbuf); +   vbuf_start_prim(vbuf, PIPE_PRIM_POINTS);     stage->point = vbuf_point; -   vbuf_set_prim(vbuf, PIPE_PRIM_POINTS);     stage->point( stage, prim );  } -static void  -vbuf_flush_indices( struct vbuf_stage *vbuf )  -{ -   if(!vbuf->nr_indices) -      return; -    -   assert((uint) (vbuf->vertex_ptr - vbuf->vertices) ==  -          vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); - -   vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); -    -   vbuf->nr_indices = 0; -} -  /**   * Flush existing vertex buffer and allocate a new one. - *  - * XXX: We separate flush-on-index-full and flush-on-vb-full, but may  - * raise issues uploading vertices if the hardware wants to flush when - * we flush.   */  static void   vbuf_flush_vertices( struct vbuf_stage *vbuf )  { -   if(vbuf->vertices) {       -      vbuf_flush_indices(vbuf); -       +   if(vbuf->vertices) { + +      vbuf->render->unmap_vertices( vbuf->render, 0, vbuf->nr_vertices - 1 ); + +      if (vbuf->nr_indices)  +      { +         vbuf->render->draw(vbuf->render,  +                            vbuf->indices,  +                            vbuf->nr_indices ); +    +         vbuf->nr_indices = 0; +      } +             /* Reset temporary vertices ids */        if(vbuf->nr_vertices)  	 draw_reset_vertex_ids( vbuf->stage.draw );        /* Free the vertex buffer */ -      vbuf->render->release_vertices(vbuf->render, -                                     vbuf->vertices, -                                     vbuf->vertex_size, -                                     vbuf->nr_vertices); +      vbuf->render->release_vertices( vbuf->render ); +        vbuf->max_vertices = vbuf->nr_vertices = 0;        vbuf->vertex_ptr = vbuf->vertices = NULL; -           }  } @@ -402,9 +385,12 @@ vbuf_alloc_vertices( struct vbuf_stage *vbuf )      * and it will flush itself if necessary to do so.  If this does      * fail, we are basically without usable hardware.      */ -   vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, -							     (ushort) vbuf->vertex_size, -							     (ushort) vbuf->max_vertices); +   vbuf->render->allocate_vertices(vbuf->render, +                                   (ushort) vbuf->vertex_size, +                                   (ushort) vbuf->max_vertices); + +   vbuf->vertices = (uint *) vbuf->render->map_vertices( vbuf->render ); +        vbuf->vertex_ptr = vbuf->vertices;  } @@ -415,14 +401,11 @@ vbuf_flush( struct draw_stage *stage, unsigned flags )  {     struct vbuf_stage *vbuf = vbuf_stage( stage ); -   vbuf_flush_indices( vbuf ); +   vbuf_flush_vertices( vbuf );     stage->point = vbuf_first_point;     stage->line = vbuf_first_line;     stage->tri = vbuf_first_tri; - -   if (flags & DRAW_FLUSH_BACKEND) -      vbuf_flush_vertices( vbuf );  } diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index c02f229110..aecaeee5b9 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -173,9 +173,7 @@ void draw_pt_emit( struct pt_emit *emit,  void draw_pt_emit_linear( struct pt_emit *emit,                            const float (*vertex_data)[4], -                          unsigned vertex_count,                            unsigned stride, -                          unsigned start,                            unsigned count );  void draw_pt_emit_destroy( struct pt_emit *emit ); diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 232dfdaed2..064e16c295 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -165,6 +165,9 @@ void draw_pt_emit( struct pt_emit *emit,      */     draw_do_flush( draw, DRAW_FLUSH_BACKEND ); +   if (vertex_count == 0) +      return; +     if (vertex_count >= UNDEFINED_VERTEX_ID) {        assert(0);        return; @@ -178,9 +181,11 @@ void draw_pt_emit( struct pt_emit *emit,        return;     } -   hw_verts = render->allocate_vertices(render, -					(ushort)translate->key.output_stride, -					(ushort)vertex_count); +   render->allocate_vertices(render, +                             (ushort)translate->key.output_stride, +                             (ushort)vertex_count); + +   hw_verts = render->map_vertices( render );     if (!hw_verts) {        assert(0);        return; @@ -201,22 +206,21 @@ void draw_pt_emit( struct pt_emit *emit,  		   vertex_count,  		   hw_verts ); +   render->unmap_vertices( render,  +                           0,  +                           vertex_count - 1 ); +     render->draw(render,  		elts,  		count); -   render->release_vertices(render, -			    hw_verts, -			    translate->key.output_stride, -			    vertex_count); +   render->release_vertices(render);  }  void draw_pt_emit_linear(struct pt_emit *emit,                           const float (*vertex_data)[4], -                         unsigned vertex_count,                           unsigned stride, -                         unsigned start,                           unsigned count)  {     struct draw_context *draw = emit->draw; @@ -231,26 +235,23 @@ void draw_pt_emit_linear(struct pt_emit *emit,      */     draw_do_flush( draw, DRAW_FLUSH_BACKEND ); -   if (count >= UNDEFINED_VERTEX_ID) { -      assert(0); -      return; -   } +   if (count >= UNDEFINED_VERTEX_ID) +      goto fail;     /* XXX: and work out some way to coordinate the render primitive      * between vbuf.c and here...      */ -   if (!draw->render->set_primitive(draw->render, emit->prim)) { -      assert(0); -      return; -   } +   if (!draw->render->set_primitive(draw->render, emit->prim))  +      goto fail; -   hw_verts = render->allocate_vertices(render, -					(ushort)translate->key.output_stride, -					(ushort)count); -   if (!hw_verts) { -      assert(0); -      return; -   } +   if (!render->allocate_vertices(render, +                                  (ushort)translate->key.output_stride, +                                  (ushort)count)) +      goto fail; + +   hw_verts = render->map_vertices( render ); +   if (!hw_verts) +      goto fail;     translate->set_buffer(translate, 0,  			 vertex_data, stride); @@ -261,12 +262,12 @@ void draw_pt_emit_linear(struct pt_emit *emit,     translate->run(translate,                    0, -                  vertex_count, +                  count,                    hw_verts);     if (0) {        unsigned i; -      for (i = 0; i < vertex_count; i++) { +      for (i = 0; i < count; i++) {           debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);           draw_dump_emitted_vertex( emit->vinfo,                                      (const uint8_t *)hw_verts +  @@ -274,13 +275,17 @@ void draw_pt_emit_linear(struct pt_emit *emit,        }     } +   render->unmap_vertices( render, 0, count - 1 ); + +   render->draw_arrays(render, 0, count); + +   render->release_vertices(render); -   render->draw_arrays(render, start, count); +   return; -   render->release_vertices(render, -			    hw_verts, -			    translate->key.output_stride, -			    vertex_count); +fail: +   assert(0); +   return;  }  struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index dcb7744b17..6b7d02a19b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -234,9 +234,11 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,        return;     } -   hw_verts = draw->render->allocate_vertices( draw->render, -                                               (ushort)feme->translate->key.output_stride, -                                               (ushort)fetch_count ); +   draw->render->allocate_vertices( draw->render, +                                    (ushort)feme->translate->key.output_stride, +                                    (ushort)fetch_count ); + +   hw_verts = draw->render->map_vertices( draw->render );     if (!hw_verts) {        assert(0);        return; @@ -259,6 +261,10 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,        }     } +   draw->render->unmap_vertices( draw->render,  +                                 0,  +                                 (ushort)(fetch_count - 1) ); +     /* XXX: Draw arrays path to avoid re-emitting index list again and      * again.      */ @@ -268,10 +274,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,     /* Done -- that was easy, wasn't it:       */ -   draw->render->release_vertices( draw->render,  -                                   hw_verts,  -                                   feme->translate->key.output_stride,  -                                   fetch_count ); +   draw->render->release_vertices( draw->render );  } @@ -288,18 +291,17 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,      */     draw_do_flush( draw, DRAW_FLUSH_BACKEND ); -   if (count >= UNDEFINED_VERTEX_ID) { -      assert(0); -      return; -   } +   if (count >= UNDEFINED_VERTEX_ID)  +      goto fail; -   hw_verts = draw->render->allocate_vertices( draw->render, -                                               (ushort)feme->translate->key.output_stride, -                                               (ushort)count ); -   if (!hw_verts) { -      assert(0); -      return; -   } +   if (!draw->render->allocate_vertices( draw->render, +                                         (ushort)feme->translate->key.output_stride, +                                         (ushort)count ))  +      goto fail; + +   hw_verts = draw->render->map_vertices( draw->render ); +   if (!hw_verts)  +      goto fail;     /* Single routine to fetch vertices and emit HW verts.      */ @@ -317,20 +319,21 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,        }     } +   draw->render->unmap_vertices( draw->render, 0, count - 1 ); +     /* XXX: Draw arrays path to avoid re-emitting index list again and      * again.      */ -   draw->render->draw_arrays( draw->render, -                              0, /*start*/ -                              count ); +   draw->render->draw_arrays( draw->render, 0, count );     /* Done -- that was easy, wasn't it:      */ -   draw->render->release_vertices( draw->render, -                                   hw_verts, -                                   feme->translate->key.output_stride, -                                   count ); +   draw->render->release_vertices( draw->render ); +   return; +fail: +   assert(0); +   return;  } @@ -351,9 +354,12 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,     if (count >= UNDEFINED_VERTEX_ID)        return FALSE; -   hw_verts = draw->render->allocate_vertices( draw->render, -                                               (ushort)feme->translate->key.output_stride, -                                               (ushort)count ); +   if (!draw->render->allocate_vertices( draw->render, +                                         (ushort)feme->translate->key.output_stride, +                                         (ushort)count )) +      return FALSE; + +   hw_verts = draw->render->map_vertices( draw->render );     if (!hw_verts)         return FALSE; @@ -364,6 +370,8 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,                           count,                           hw_verts ); +   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) ); +     /* XXX: Draw arrays path to avoid re-emitting index list again and      * again.      */ @@ -373,10 +381,7 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,     /* Done -- that was easy, wasn't it:      */ -   draw->render->release_vertices( draw->render, -                                   hw_verts, -                                   feme->translate->key.output_stride, -                                   count ); +   draw->render->release_vertices( draw->render );     return TRUE;  } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 84ffe3296a..cd9cd4b53f 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -234,19 +234,17 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,      */     draw_do_flush( draw, DRAW_FLUSH_BACKEND ); -   if (count >= UNDEFINED_VERTEX_ID) { -      assert(0); -      return; -   } +   if (count >= UNDEFINED_VERTEX_ID)  +      goto fail; -   hw_verts = draw->render->allocate_vertices( draw->render, -                                               (ushort)fse->key.output_stride, -                                               (ushort)count ); +   if (!draw->render->allocate_vertices( draw->render, +                                         (ushort)fse->key.output_stride, +                                         (ushort)count )) +      goto fail; -   if (!hw_verts) { -      assert(0); -      return; -   } +   hw_verts = draw->render->map_vertices( draw->render ); +   if (!hw_verts) +      goto fail;     /* Single routine to fetch vertices, run shader and emit HW verts.      * Clipping is done elsewhere -- either by the API or on hardware, @@ -256,13 +254,7 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,                              start, count,                              hw_verts ); -   /* Draw arrays path to avoid re-emitting index list again and -    * again. -    */ -   draw->render->draw_arrays( draw->render, -                              0, -                              count ); -    +     if (0) {        unsigned i;        for (i = 0; i < count; i++) { @@ -274,12 +266,24 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,                                     (const uint8_t *)hw_verts + fse->key.output_stride * i );        }     } +    +   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) ); +   /* Draw arrays path to avoid re-emitting index list again and +    * again. +    */ +   draw->render->draw_arrays( draw->render, +                              0, +                              count ); +    + +   draw->render->release_vertices( draw->render ); + +   return; -   draw->render->release_vertices( draw->render,  -				   hw_verts,  -				   fse->key.output_stride,  -				   count ); +fail: +   assert(0); +   return;  } @@ -298,18 +302,17 @@ fse_run(struct draw_pt_middle_end *middle,      */     draw_do_flush( draw, DRAW_FLUSH_BACKEND ); -   if (fetch_count >= UNDEFINED_VERTEX_ID) { -      assert(0); -      return; -   } +   if (fetch_count >= UNDEFINED_VERTEX_ID)  +      goto fail; -   hw_verts = draw->render->allocate_vertices( draw->render, -                                               (ushort)fse->key.output_stride, -                                               (ushort)fetch_count ); -   if (!hw_verts) { -      assert(0); -      return; -   } +   if (!draw->render->allocate_vertices( draw->render, +                                         (ushort)fse->key.output_stride, +                                         (ushort)fetch_count )) +      goto fail; + +   hw_verts = draw->render->map_vertices( draw->render );  +   if (!hw_verts)  +      goto fail;     /* Single routine to fetch vertices, run shader and emit HW verts. @@ -319,9 +322,6 @@ fse_run(struct draw_pt_middle_end *middle,                            fetch_count,                            hw_verts ); -   draw->render->draw( draw->render,  -                       draw_elts,  -                       draw_count );     if (0) {        unsigned i; @@ -333,12 +333,19 @@ fse_run(struct draw_pt_middle_end *middle,        }     } +   draw->render->unmap_vertices( draw->render, 0, (ushort)(fetch_count - 1) ); +    +   draw->render->draw( draw->render,  +                       draw_elts,  +                       draw_count ); + -   draw->render->release_vertices( draw->render,  -                                   hw_verts,  -                                   fse->key.output_stride,  -                                   fetch_count ); +   draw->render->release_vertices( draw->render ); +   return; +fail: +   assert(0); +   return;  } @@ -360,13 +367,14 @@ static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle,     if (count >= UNDEFINED_VERTEX_ID)        return FALSE; -   hw_verts = draw->render->allocate_vertices( draw->render, -                                               (ushort)fse->key.output_stride, -                                               (ushort)count ); +   if (!draw->render->allocate_vertices( draw->render, +                                         (ushort)fse->key.output_stride, +                                         (ushort)count )) +      return FALSE; -   if (!hw_verts) { +   hw_verts = draw->render->map_vertices( draw->render ); +   if (!hw_verts)         return FALSE; -   }     /* Single routine to fetch vertices, run shader and emit HW verts.      * Clipping is done elsewhere -- either by the API or on hardware, @@ -382,11 +390,9 @@ static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle,                         draw_count ); +   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) ); -   draw->render->release_vertices( draw->render,  -				   hw_verts,  -				   fse->key.output_stride,  -				   count ); +   draw->render->release_vertices( draw->render );     return TRUE;  } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index ec3b41c320..38f9b604d3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -251,9 +251,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,     else {        draw_pt_emit_linear( fpme->emit,                             (const float (*)[4])pipeline_verts->data, -                           count,                             fpme->vertex_size, -                           0, /*start*/                             count );     } diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h index a1c4c14445..cccd3bf435 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.h +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -80,9 +80,14 @@ struct vbuf_render {      * Hardware renderers will use ttm memory, others will just malloc      * something.      */ -   void *(*allocate_vertices)( struct vbuf_render *, -			       ushort vertex_size, -			       ushort nr_vertices ); +   boolean (*allocate_vertices)( struct vbuf_render *, +                                 ushort vertex_size, +                                 ushort nr_vertices ); +    +   void *(*map_vertices)( struct vbuf_render * ); +   void (*unmap_vertices)( struct vbuf_render *,  +                           ushort min_index, +                           ushort max_index );     /**      * Notify the renderer of the current primitive when it changes. @@ -109,10 +114,7 @@ struct vbuf_render {     /**      * Called when vbuf is done with this set of vertices:      */ -   void (*release_vertices)( struct vbuf_render *, -			     void *vertices,  -			     unsigned vertex_size, -			     unsigned vertices_used ); +   void (*release_vertices)( struct vbuf_render * );     void (*destroy)( struct vbuf_render * );  }; diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index 2dc2e07329..58c41840e1 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -62,7 +62,7 @@ struct i915_vbuf_render {     struct i915_context *i915;        /** Vertex size in bytes */ -   unsigned vertex_size; +   size_t vertex_size;     /** Software primitive */     unsigned prim; @@ -79,6 +79,7 @@ struct i915_vbuf_render {     size_t vbo_offset;     void *vbo_ptr;     size_t vbo_alloc_size; +   size_t vbo_max_used;  }; @@ -108,7 +109,7 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render )  } -static void * +static boolean  i915_vbuf_render_allocate_vertices( struct vbuf_render *render,                                      ushort vertex_size,                                      ushort nr_vertices ) @@ -124,7 +125,8 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,     if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {     } else {        i915->vbo_flushed = 0; -      pipe_buffer_reference(screen, &i915_render->vbo, NULL); +      if (i915_render->vbo) +         pipe_buffer_reference(screen, &i915_render->vbo, NULL);     }     if (!i915_render->vbo) { @@ -134,19 +136,49 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,                                              64,                                              I915_BUFFER_USAGE_LIT_VERTEX,                                              i915_render->vbo_size); -      i915_render->vbo_ptr = pipe_buffer_map(screen, -                                             i915_render->vbo, -                                             PIPE_BUFFER_USAGE_CPU_WRITE); -      pipe_buffer_unmap(screen, i915_render->vbo); +     } +   i915_render->vertex_size = vertex_size;     i915->vbo = i915_render->vbo;     i915->vbo_offset = i915_render->vbo_offset;     i915->dirty |= I915_NEW_VBO; +   if (!i915_render->vbo) +      return FALSE; +   return TRUE; +} + + +static void * +i915_vbuf_render_map_vertices( struct vbuf_render *render ) +{ +   struct i915_vbuf_render *i915_render = i915_vbuf_render(render); +   struct i915_context *i915 = i915_render->i915; +   struct pipe_screen *screen = i915->pipe.screen; + +   if (i915->vbo_flushed) +      debug_printf("%s bad vbo flush occured stalling on hw\n"); + +   i915_render->vbo_ptr = pipe_buffer_map(screen, +                                          i915_render->vbo, +                                          PIPE_BUFFER_USAGE_CPU_WRITE); +     return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;  } +static void +i915_vbuf_render_unmap_vertices( struct vbuf_render *render, +                                 ushort min_index, +                                 ushort max_index ) +{ +   struct i915_vbuf_render *i915_render = i915_vbuf_render(render); +   struct i915_context *i915 = i915_render->i915; +   struct pipe_screen *screen = i915->pipe.screen; + +   i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1)); +   pipe_buffer_unmap(screen, i915_render->vbo); +}  static boolean  i915_vbuf_render_set_primitive( struct vbuf_render *render,  @@ -454,18 +486,15 @@ out:  static void -i915_vbuf_render_release_vertices( struct vbuf_render *render, -			           void *vertices,  -			           unsigned vertex_size, -			           unsigned vertices_used ) +i915_vbuf_render_release_vertices( struct vbuf_render *render )  {     struct i915_vbuf_render *i915_render = i915_vbuf_render(render);     struct i915_context *i915 = i915_render->i915; -   size_t size = (size_t)vertex_size * (size_t)vertices_used;     assert(i915->vbo); -   i915_render->vbo_offset += size; +   i915_render->vbo_offset += i915_render->vbo_max_used; +   i915_render->vbo_max_used = 0;     i915->vbo = NULL;     i915->dirty |= I915_NEW_VBO;  } @@ -499,6 +528,8 @@ i915_vbuf_render_create( struct i915_context *i915 )     i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info;     i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices; +   i915_render->base.map_vertices = i915_vbuf_render_map_vertices; +   i915_render->base.unmap_vertices = i915_vbuf_render_unmap_vertices;     i915_render->base.set_primitive = i915_vbuf_render_set_primitive;     i915_render->base.draw = i915_vbuf_render_draw;     i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays; diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c index 221bee4777..f6458232ae 100644 --- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c +++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c @@ -51,7 +51,7 @@ nv04_vbuf_render_get_vertex_info( struct vbuf_render *render )  } -static void * +static boolean  nv04_vbuf_render_allocate_vertices( struct vbuf_render *render,  		ushort vertex_size,  		ushort nr_vertices ) @@ -61,9 +61,22 @@ nv04_vbuf_render_allocate_vertices( struct vbuf_render *render,  	nv04_render->buffer = (unsigned char*) MALLOC(VERTEX_BUFFER_SIZE);  	assert(!nv04_render->buffer); +	return nv04_render->buffer ? TRUE : FALSE; +} + +static void * +nv04_vbuf_render_map_vertices( struct vbuf_render *render ) +{ +	struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);  	return nv04_render->buffer;  } +static void +nv04_vbuf_render_unmap_vertices( struct vbuf_render *render, +		ushort min_index, +		ushort max_index ) +{ +}  static boolean   nv04_vbuf_render_set_primitive( struct vbuf_render *render,  @@ -244,10 +257,7 @@ nv04_vbuf_render_draw( struct vbuf_render *render,  static void -nv04_vbuf_render_release_vertices( struct vbuf_render *render, -		void *vertices,  -		unsigned vertex_size, -		unsigned vertices_used ) +nv04_vbuf_render_release_vertices( struct vbuf_render *render )  {  	struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); @@ -278,6 +288,8 @@ nv04_vbuf_render_create( struct nv04_context *nv04 )  	nv04_render->base.max_indices = 65536;   	nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info;  	nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices; +	nv04_render->base.map_vertices = nv04_vbuf_render_map_vertices; +	nv04_render->base.unmap_vertices = nv04_vbuf_render_unmap_vertices;  	nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive;  	nv04_render->base.draw = nv04_vbuf_render_draw;  	nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices; diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c index 5e5436be53..491a881806 100644 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -99,8 +99,7 @@ nv10_vbuf_render_get_vertex_info( struct vbuf_render *render )  	return &nv10->vertex_info;  } - -static void * +static boolean  nv10_vbuf_render_allocate_vertices( struct vbuf_render *render,  		ushort vertex_size,  		ushort nr_vertices ) @@ -115,11 +114,35 @@ nv10_vbuf_render_allocate_vertices( struct vbuf_render *render,  	nv10->dirty |= NV10_NEW_VTXARRAYS; +	if (nv10_render->buffer) +		return FALSE; +	return TRUE; +} + +static void * +nv10_vbuf_render_map_vertices( struct vbuf_render *render ) +{ +	struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); +	struct nv10_context *nv10 = nv10_render->nv10; +	struct pipe_winsys *winsys = nv10->pipe.winsys; +  	return winsys->buffer_map(winsys,   			nv10_render->buffer,   			PIPE_BUFFER_USAGE_CPU_WRITE);  } +static void +nv10_vbuf_render_unmap_vertices( struct vbuf_render *render, +		ushort min_index, +		ushort max_index ) +{ +	struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); +	struct nv10_context *nv10 = nv10_render->nv10; +	struct pipe_winsys *winsys = nv10->pipe.winsys; + +	assert(!nv10_render->buffer); +	winsys->buffer_unmap(winsys, nv10_render->buffer); +}  static boolean  nv10_vbuf_render_set_primitive( struct vbuf_render *render,  @@ -176,18 +199,13 @@ nv10_vbuf_render_draw( struct vbuf_render *render,  static void -nv10_vbuf_render_release_vertices( struct vbuf_render *render, -		void *vertices,  -		unsigned vertex_size, -		unsigned vertices_used ) +nv10_vbuf_render_release_vertices( struct vbuf_render *render )  {  	struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);  	struct nv10_context *nv10 = nv10_render->nv10; -	struct pipe_winsys *winsys = nv10->pipe.winsys;  	struct pipe_screen *pscreen = &nv10->screen->pipe;  	assert(nv10_render->buffer); -	winsys->buffer_unmap(winsys, nv10_render->buffer);  	pipe_buffer_reference(pscreen, &nv10_render->buffer, NULL);  } @@ -214,6 +232,8 @@ nv10_vbuf_render_create( struct nv10_context *nv10 )  	nv10_render->base.max_indices = 1024;  	nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info;  	nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices; +	nv10_render->base.map_vertices = nv10_vbuf_render_map_vertices; +	nv10_render->base.unmap_vertices = nv10_vbuf_render_unmap_vertices;  	nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive;  	nv10_render->base.draw = nv10_vbuf_render_draw;  	nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices; diff --git a/src/gallium/drivers/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c index 187136ce7b..319e1f6557 100644 --- a/src/gallium/drivers/nv20/nv20_prim_vbuf.c +++ b/src/gallium/drivers/nv20/nv20_prim_vbuf.c @@ -109,18 +109,15 @@ nv20__allocate_mbuffer(struct nv20_vbuf_render *nv20_render, size_t size)  	return nv20_render->mbuffer;  } -static void * +static void  nv20__allocate_pbuffer(struct nv20_vbuf_render *nv20_render, size_t size)  {  	struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;  	nv20_render->pbuffer = winsys->buffer_create(winsys, 64,  					PIPE_BUFFER_USAGE_VERTEX, size); -	return winsys->buffer_map(winsys, -			nv20_render->pbuffer, -			PIPE_BUFFER_USAGE_CPU_WRITE);  } -static void * +static boolean  nv20_vbuf_render_allocate_vertices( struct vbuf_render *render,  		ushort vertex_size,  		ushort nr_vertices ) @@ -137,15 +134,49 @@ nv20_vbuf_render_allocate_vertices( struct vbuf_render *render,  	 * buffer, the data will be passed directly via the fifo.  	 */  	/* XXX: Pipe vertex buffers don't work. */ -	if (0 && size > 16 * 1024) -		buf = nv20__allocate_pbuffer(nv20_render, size); -	else +	if (0 && size > 16 * 1024) { +		nv20__allocate_pbuffer(nv20_render, size); +		/* umm yeah so this is ugly */ +		buf = nv20_render->pbuffer; +	} else {  		buf = nv20__allocate_mbuffer(nv20_render, size); +	}  	if (buf)  		nv20_render->nv20->dirty |= NV20_NEW_VTXARRAYS; -	return buf; +	return buf ? TRUE : FALSE; +} + +static void * +nv20_vbuf_render_map_vertices( struct vbuf_render *render ) +{ +	struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); +	struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys; + +	if (nv20_render->pbuffer) { +		return winsys->buffer_map(winsys, +				nv20_render->pbuffer, +				PIPE_BUFFER_USAGE_CPU_WRITE); +	} else if (nv20_render->mbuffer) { +		return nv20_render->mbuffer; +	} else +		assert(0); + +	/* warnings be gone */ +	return NULL; +} + +static void +nv20_vbuf_render_unmap_vertices( struct vbuf_render *render, +		ushort min_index, +		ushort max_index ) +{ +	struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); +	struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys; + +	if (nv20_render->pbuffer) +		winsys->buffer_unmap(winsys, nv20_render->pbuffer);  }  static boolean @@ -323,18 +354,13 @@ nv20_vbuf_render_draw( struct vbuf_render *render,  static void -nv20_vbuf_render_release_vertices( struct vbuf_render *render, -		void *vertices,  -		unsigned vertex_size, -		unsigned vertices_used ) +nv20_vbuf_render_release_vertices( struct vbuf_render *render )  {  	struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);  	struct nv20_context *nv20 = nv20_render->nv20; -	struct pipe_winsys *winsys = nv20->pipe.winsys;  	struct pipe_screen *pscreen = &nv20->screen->pipe;  	if (nv20_render->pbuffer) { -		winsys->buffer_unmap(winsys, nv20_render->pbuffer);  		pipe_buffer_reference(pscreen, &nv20_render->pbuffer, NULL);  	} else if (nv20_render->mbuffer) {  		FREE(nv20_render->mbuffer); @@ -371,6 +397,8 @@ nv20_vbuf_render_create( struct nv20_context *nv20 )  	nv20_render->base.get_vertex_info = nv20_vbuf_render_get_vertex_info;  	nv20_render->base.allocate_vertices =  					nv20_vbuf_render_allocate_vertices; +	nv20_render->base.map_vertices = nv20_vbuf_render_map_vertices; +	nv20_render->base.unmap_vertices = nv20_vbuf_render_unmap_vertices;  	nv20_render->base.set_primitive = nv20_vbuf_render_set_primitive;  	nv20_render->base.draw = nv20_vbuf_render_draw;  	nv20_render->base.release_vertices = nv20_vbuf_render_release_vertices; diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 468e0a2e44..be26b13b0b 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -64,7 +64,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #define R300_SE_VPORT_ZSCALE                0x1DA8  #define R300_SE_VPORT_ZOFFSET               0x1DAC - +#define R300_VAP_PORT_IDX0		    0x2040  /*   * Vertex Array Processing (VAP) Control   */ @@ -732,8 +732,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #define R500_RS_IP_TEX_PTR_Q_SHIFT 			18  #define R500_RS_IP_COL_PTR_SHIFT 			24  #define R500_RS_IP_COL_FMT_SHIFT 			27 -#	define R500_RS_COL_PTR(x)		        (x << 24) -#       define R500_RS_COL_FMT(x)                       (x << 27) +#	define R500_RS_COL_PTR(x)		        ((x) << 24) +#       define R500_RS_COL_FMT(x)                       ((x) << 27)  /* gap */  #define R500_RS_IP_OFFSET_DIS 				(0 << 31)  #define R500_RS_IP_OFFSET_EN 				(1 << 31) @@ -1175,8 +1175,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #       define R300_RS_INTERP_SRC_SHIFT          2 /* TODO: check for removal */  #       define R300_RS_INTERP_SRC_MASK           (7 << 2) /* TODO: check for removal */  #	define R300_RS_TEX_PTR(x)		        (x << 0) -#	define R300_RS_COL_PTR(x)		        (x << 6) -#	define R300_RS_COL_FMT(x)		        (x << 9) +#	define R300_RS_COL_PTR(x)		        ((x) << 6) +#	define R300_RS_COL_FMT(x)		        ((x) << 9)  #	define R300_RS_COL_FMT_RGBA		        0  #	define R300_RS_COL_FMT_RGB0		        1  #	define R300_RS_COL_FMT_RGB1		        2 @@ -1186,10 +1186,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #	define R300_RS_COL_FMT_111A		        8  #	define R300_RS_COL_FMT_1110		        9  #	define R300_RS_COL_FMT_1111		        10 -#	define R300_RS_SEL_S(x)		                (x << 13) -#	define R300_RS_SEL_T(x)		                (x << 16) -#	define R300_RS_SEL_R(x)		                (x << 19) -#	define R300_RS_SEL_Q(x)		                (x << 22) +#	define R300_RS_SEL_S(x)		                ((x) << 13) +#	define R300_RS_SEL_T(x)		                ((x) << 16) +#	define R300_RS_SEL_R(x)		                ((x) << 19) +#	define R300_RS_SEL_Q(x)		                ((x) << 22)  #	define R300_RS_SEL_C0		                0  #	define R300_RS_SEL_C1		                1  #	define R300_RS_SEL_C2		                2 @@ -1708,7 +1708,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #   define R300_C3_SEL_R				(1 << 14)  #   define R300_C3_SEL_G				(2 << 14)  #   define R300_C3_SEL_B				(3 << 14) -#   define R300_OUT_SIGN(x)				(x << 16) +#   define R300_OUT_SIGN(x)				((x) << 16)  #   define R500_ROUND_ADJ				(1 << 20)  /* ALU @@ -2732,7 +2732,7 @@ enum {  #   define R500_ALPHA_OP_COS				13  #   define R500_ALPHA_OP_MDH				14  #   define R500_ALPHA_OP_MDV				15 -#   define R500_ALPHA_ADDRD(x)				(x << 4) +#   define R500_ALPHA_ADDRD(x)				((x) << 4)  #   define R500_ALPHA_ADDRD_REL				(1 << 11)  #  define R500_ALPHA_SEL_A_SHIFT			12  #   define R500_ALPHA_SEL_A_SRC0			(0 << 12) @@ -2776,16 +2776,16 @@ enum {  #   define R500_ALPHA_OMOD_DIV_4			(5 << 26)  #   define R500_ALPHA_OMOD_DIV_8			(6 << 26)  #   define R500_ALPHA_OMOD_DISABLE			(7 << 26) -#   define R500_ALPHA_TARGET(x)				(x << 29) +#   define R500_ALPHA_TARGET(x)				((x) << 29)  #   define R500_ALPHA_W_OMASK				(1 << 31)  #define R500_US_ALU_ALPHA_ADDR_0			0x9800 -#   define R500_ALPHA_ADDR0(x)				(x << 0) +#   define R500_ALPHA_ADDR0(x)				((x) << 0)  #   define R500_ALPHA_ADDR0_CONST			(1 << 8)  #   define R500_ALPHA_ADDR0_REL				(1 << 9) -#   define R500_ALPHA_ADDR1(x)				(x << 10) +#   define R500_ALPHA_ADDR1(x)				((x) << 10)  #   define R500_ALPHA_ADDR1_CONST			(1 << 18)  #   define R500_ALPHA_ADDR1_REL				(1 << 19) -#   define R500_ALPHA_ADDR2(x)				(x << 20) +#   define R500_ALPHA_ADDR2(x)				((x) << 20)  #   define R500_ALPHA_ADDR2_CONST			(1 << 28)  #   define R500_ALPHA_ADDR2_REL				(1 << 29)  #   define R500_ALPHA_SRCP_OP_1_MINUS_2A0		(0 << 30) @@ -2806,7 +2806,7 @@ enum {  #   define R500_ALU_RGBA_OP_SOP				(10 << 0)  #   define R500_ALU_RGBA_OP_MDH				(11 << 0)  #   define R500_ALU_RGBA_OP_MDV				(12 << 0) -#   define R500_ALU_RGBA_ADDRD(x)			(x << 4) +#   define R500_ALU_RGBA_ADDRD(x)			((x) << 4)  #   define R500_ALU_RGBA_ADDRD_REL			(1 << 11)  #  define R500_ALU_RGBA_SEL_C_SHIFT			12  #   define R500_ALU_RGBA_SEL_C_SRC0			(0 << 12) @@ -2933,16 +2933,16 @@ enum {  #   define R500_ALU_RGB_OMOD_DIV_4			(5 << 26)  #   define R500_ALU_RGB_OMOD_DIV_8			(6 << 26)  #   define R500_ALU_RGB_OMOD_DISABLE			(7 << 26) -#   define R500_ALU_RGB_TARGET(x)			(x << 29) +#   define R500_ALU_RGB_TARGET(x)			((x) << 29)  #   define R500_ALU_RGB_WMASK				(1 << 31)  #define R500_US_ALU_RGB_ADDR_0				0x9000 -#   define R500_RGB_ADDR0(x)				(x << 0) +#   define R500_RGB_ADDR0(x)				((x) << 0)  #   define R500_RGB_ADDR0_CONST				(1 << 8)  #   define R500_RGB_ADDR0_REL				(1 << 9) -#   define R500_RGB_ADDR1(x)				(x << 10) +#   define R500_RGB_ADDR1(x)				((x) << 10)  #   define R500_RGB_ADDR1_CONST				(1 << 18)  #   define R500_RGB_ADDR1_REL				(1 << 19) -#   define R500_RGB_ADDR2(x)				(x << 20) +#   define R500_RGB_ADDR2(x)				((x) << 20)  #   define R500_RGB_ADDR2_CONST				(1 << 28)  #   define R500_RGB_ADDR2_REL				(1 << 29)  #   define R500_RGB_SRCP_OP_1_MINUS_2RGB0		(0 << 30) @@ -2998,19 +2998,19 @@ enum {  /* note that these are 8 bit lengths, despite the offsets, at least for R500 */  #define R500_US_CODE_ADDR				0x4630 -#   define R500_US_CODE_START_ADDR(x)			(x << 0) -#   define R500_US_CODE_END_ADDR(x)			(x << 16) +#   define R500_US_CODE_START_ADDR(x)			((x) << 0) +#   define R500_US_CODE_END_ADDR(x)			((x) << 16)  #define R500_US_CODE_OFFSET				0x4638 -#   define R500_US_CODE_OFFSET_ADDR(x)			(x << 0) +#   define R500_US_CODE_OFFSET_ADDR(x)			((x) << 0)  #define R500_US_CODE_RANGE				0x4634 -#   define R500_US_CODE_RANGE_ADDR(x)			(x << 0) -#   define R500_US_CODE_RANGE_SIZE(x)			(x << 16) +#   define R500_US_CODE_RANGE_ADDR(x)			((x) << 0) +#   define R500_US_CODE_RANGE_SIZE(x)			((x) << 16)  #define R500_US_CONFIG					0x4600  #   define R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO		(1 << 1)  #define R500_US_FC_ADDR_0				0xa000 -#   define R500_FC_BOOL_ADDR(x)				(x << 0) -#   define R500_FC_INT_ADDR(x)				(x << 8) -#   define R500_FC_JUMP_ADDR(x)				(x << 16) +#   define R500_FC_BOOL_ADDR(x)				((x) << 0) +#   define R500_FC_INT_ADDR(x)				((x) << 8) +#   define R500_FC_JUMP_ADDR(x)				((x) << 16)  #   define R500_FC_JUMP_GLOBAL				(1 << 31)  #define R500_US_FC_BOOL_CONST				0x4620  #   define R500_FC_KBOOL(x)				(x) @@ -3031,8 +3031,8 @@ enum {  #   define R500_FC_A_OP_NONE				(0 << 6)  #   define R500_FC_A_OP_POP				(1 << 6)  #   define R500_FC_A_OP_PUSH				(2 << 6) -#   define R500_FC_JUMP_FUNC(x)				(x << 8) -#   define R500_FC_B_POP_CNT(x)				(x << 16) +#   define R500_FC_JUMP_FUNC(x)				((x) << 8) +#   define R500_FC_B_POP_CNT(x)				((x) << 16)  #   define R500_FC_B_OP0_NONE				(0 << 24)  #   define R500_FC_B_OP0_DECR				(1 << 24)  #   define R500_FC_B_OP0_INCR				(2 << 24) @@ -3041,18 +3041,18 @@ enum {  #   define R500_FC_B_OP1_INCR				(2 << 26)  #   define R500_FC_IGNORE_UNCOVERED			(1 << 28)  #define R500_US_FC_INT_CONST_0				0x4c00 -#   define R500_FC_INT_CONST_KR(x)			(x << 0) -#   define R500_FC_INT_CONST_KG(x)			(x << 8) -#   define R500_FC_INT_CONST_KB(x)			(x << 16) +#   define R500_FC_INT_CONST_KR(x)			((x) << 0) +#   define R500_FC_INT_CONST_KG(x)			((x) << 8) +#   define R500_FC_INT_CONST_KB(x)			((x) << 16)  /* _0 through _15 */  #define R500_US_FORMAT0_0				0x4640 -#   define R500_FORMAT_TXWIDTH(x)			(x << 0) -#   define R500_FORMAT_TXHEIGHT(x)			(x << 11) -#   define R500_FORMAT_TXDEPTH(x)			(x << 22) +#   define R500_FORMAT_TXWIDTH(x)			((x) << 0) +#   define R500_FORMAT_TXHEIGHT(x)			((x) << 11) +#   define R500_FORMAT_TXDEPTH(x)			((x) << 22)  #define R500_US_PIXSIZE					0x4604  #   define R500_PIX_SIZE(x)				(x)  #define R500_US_TEX_ADDR_0				0x9800 -#   define R500_TEX_SRC_ADDR(x)				(x << 0) +#   define R500_TEX_SRC_ADDR(x)				((x) << 0)  #   define R500_TEX_SRC_ADDR_REL			(1 << 7)  #   define R500_TEX_SRC_S_SWIZ_R			(0 << 8)  #   define R500_TEX_SRC_S_SWIZ_G			(1 << 8) @@ -3070,7 +3070,7 @@ enum {  #   define R500_TEX_SRC_Q_SWIZ_G			(1 << 14)  #   define R500_TEX_SRC_Q_SWIZ_B			(2 << 14)  #   define R500_TEX_SRC_Q_SWIZ_A			(3 << 14) -#   define R500_TEX_DST_ADDR(x)				(x << 16) +#   define R500_TEX_DST_ADDR(x)				((x) << 16)  #   define R500_TEX_DST_ADDR_REL			(1 << 23)  #   define R500_TEX_DST_R_SWIZ_R			(0 << 24)  #   define R500_TEX_DST_R_SWIZ_G			(1 << 24) @@ -3089,7 +3089,7 @@ enum {  #   define R500_TEX_DST_A_SWIZ_B			(2 << 30)  #   define R500_TEX_DST_A_SWIZ_A			(3 << 30)  #define R500_US_TEX_ADDR_DXDY_0				0xa000 -#   define R500_DX_ADDR(x)				(x << 0) +#   define R500_DX_ADDR(x)				((x) << 0)  #   define R500_DX_ADDR_REL				(1 << 7)  #   define R500_DX_S_SWIZ_R				(0 << 8)  #   define R500_DX_S_SWIZ_G				(1 << 8) @@ -3107,7 +3107,7 @@ enum {  #   define R500_DX_Q_SWIZ_G				(1 << 14)  #   define R500_DX_Q_SWIZ_B				(2 << 14)  #   define R500_DX_Q_SWIZ_A				(3 << 14) -#   define R500_DY_ADDR(x)				(x << 16) +#   define R500_DY_ADDR(x)				((x) << 16)  #   define R500_DY_ADDR_REL				(1 << 17)  #   define R500_DY_S_SWIZ_R				(0 << 24)  #   define R500_DY_S_SWIZ_G				(1 << 24) @@ -3126,7 +3126,7 @@ enum {  #   define R500_DY_Q_SWIZ_B				(2 << 30)  #   define R500_DY_Q_SWIZ_A				(3 << 30)  #define R500_US_TEX_INST_0				0x9000 -#   define R500_TEX_ID(x)				(x << 16) +#   define R500_TEX_ID(x)				((x) << 16)  #   define R500_TEX_INST_NOP				(0 << 22)  #   define R500_TEX_INST_LD				(1 << 22)  #   define R500_TEX_INST_TEXKILL			(2 << 22) @@ -3187,9 +3187,9 @@ enum {  #define R300_PACKET3_3D_LOAD_VBPNTR         0x00002F00  #define R300_PACKET3_INDX_BUFFER            0x00003300 -#    define R300_EB_UNK1_SHIFT                      24 -#    define R300_EB_UNK1                    (0x80<<24) -#    define R300_EB_UNK2                        0x0810 +#    define R300_INDX_BUFFER_DST_SHIFT          0 +#    define R300_INDX_BUFFER_SKIP_SHIFT         16 +#    define R300_INDX_BUFFER_ONE_REG_WR		(1<<31)  /* Same as R300_PACKET3_3D_DRAW_VBUF but without VAP_VTX_FMT */  #define R300_PACKET3_3D_DRAW_VBUF_2         0x00003400 diff --git a/src/gallium/drivers/r300/r300_swtcl_emit.c b/src/gallium/drivers/r300/r300_swtcl_emit.c index 76ef48962b..fb009247a5 100644 --- a/src/gallium/drivers/r300/r300_swtcl_emit.c +++ b/src/gallium/drivers/r300/r300_swtcl_emit.c @@ -21,144 +21,295 @@   * USE OR OTHER DEALINGS IN THE SOFTWARE. */  #include "draw/draw_pipe.h" +#include "draw/draw_vbuf.h"  #include "util/u_memory.h"  #include "r300_cs.h"  #include "r300_context.h"  #include "r300_reg.h" -/* r300_swtcl_emit: Primitive vertex emission using an immediate - * vertex buffer and no HW TCL. */ +/* r300_swtcl_emit: Vertex and index buffer primitive emission. No HW TCL. */ -struct swtcl_stage { +struct r300_swtcl_render {      /* Parent class */ -    struct draw_stage draw; - +    struct vbuf_render base; +     +    /* Pipe context */      struct r300_context* r300; + +    /* Vertex information */ +    size_t vertex_size; +    unsigned prim; +    unsigned hwprim; + +    /* VBO */ +    struct pipe_buffer* vbo; +    size_t vbo_size; +    size_t vbo_offset; +    void* vbo_map; +    size_t vbo_alloc_size; +    size_t vbo_max_used;  }; -static INLINE struct swtcl_stage* swtcl_stage(struct draw_stage* draw) { -    return (struct swtcl_stage*)draw; +static INLINE struct r300_swtcl_render* +r300_swtcl_render(struct vbuf_render* render) +{ +    return (struct r300_swtcl_render*)render;  } -static INLINE void r300_emit_vertex(struct r300_context* r300, -                                    const struct vertex_header* vertex) +static const struct vertex_info* +r300_swtcl_render_get_vertex_info(struct vbuf_render* render)  { -    struct vertex_info* vinfo = &r300->vertex_info; -    CS_LOCALS(r300); -    uint i, j; +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    struct r300_context* r300 = r300render->r300; + +    r300_update_derived_state(r300); + +    return &r300->vertex_info; +} + +static boolean r300_swtcl_render_allocate_vertices(struct vbuf_render* render, +                                                   ushort vertex_size, +                                                   ushort count) +{ +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    struct r300_context* r300 = r300render->r300; +    struct pipe_screen* screen = r300->context.screen; +    size_t size = (size_t)vertex_size * (size_t)count; + +    if (r300render->vbo) { +        pipe_buffer_reference(screen, r300render->vbo, NULL); +    } + +    r300render->vbo_size = MAX2(size, r300render->vbo_alloc_size); +    r300render->vbo_offset = 0; +    r300render->vbo = pipe_buffer_create(screen, +                                         64, +                                         PIPE_BUFFER_USAGE_VERTEX, +                                         r300render->vbo_size); + +    r300render->vertex_size = vertex_size; + +    if (r300render->vbo) { +        return true; +    } else { +        return false; +    } +} + +static void* r300_swtcl_render_map_vertices(struct vbuf_render* render) +{ +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    struct pipe_screen* screen = r300render->r300->context.screen; + +    r300render->vbo_map = pipe_buffer_map(screen, r300render->vbo, +                                          PIPE_BUFFER_USAGE_CPU_WRITE); + +    return (unsigned char*)r300render->vbo_map + r300render->vbo_offset; +} + +static void* r300_swtcl_render_unmap_vertices(struct vbuf_render* render, +                                              ushort min, +                                              ushort max) +{ +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    struct pipe_screen* screen = r300render->r300->context.screen; + +    r300render->vbo_max_used = MAX2(r300render->vbo_max_used, +             r300render->vertex_size * (max + 1)); + +    pipe_buffer_unmap(screen, r300render->vbo); +} + +static void r300_swtcl_render_release_vertices(struct vbuf_render* render) +{ +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    struct pipe_screen* screen = r300render->r300->context.screen; + +    pipe_buffer_reference(screen, r300render->vbo, NULL); +} + +static boolean r300_swtcl_render_set_primitive(struct vbuf_render* render, +                                               unsigned prim) +{ +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    r300render->prim = prim; -    for (i = 0; i < vinfo->num_attribs; i++) { -        j = vinfo->attrib[i].src_index; -        switch (vinfo->attrib[i].emit) { -            case EMIT_1F: -                OUT_CS_32F(vertex->data[j][0]); -                break; -            case EMIT_2F: -                OUT_CS_32F(vertex->data[j][0]); -                OUT_CS_32F(vertex->data[j][1]); -                break; -            case EMIT_3F: -                OUT_CS_32F(vertex->data[j][0]); -                OUT_CS_32F(vertex->data[j][1]); -                OUT_CS_32F(vertex->data[j][2]); -                break; -            case EMIT_4F: -                OUT_CS_32F(vertex->data[j][0]); -                OUT_CS_32F(vertex->data[j][1]); -                OUT_CS_32F(vertex->data[j][2]); -                OUT_CS_32F(vertex->data[j][3]); -                break; -            default: -                debug_printf("r300: Unknown emit value %d\n", -                    vinfo->attrib[i].emit); -                break; -        } +    switch (prim) { +        case PIPE_PRIM_POINTS: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_POINTS; +            break; +        case PIPE_PRIM_LINES: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_LINES; +            break; +        case PIPE_PRIM_LINE_LOOP: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_LINE_LOOP; +            break; +        case PIPE_PRIM_LINE_STRIP: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_LINE_STRIP; +            break; +        case PIPE_PRIM_TRIANGLES: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_TRIANGLES; +            break; +        case PIPE_PRIM_TRIANGLE_STRIP: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP; +            break; +        case PIPE_PRIM_TRIANGLE_FAN: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN; +            break; +        case PIPE_PRIM_QUADS: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_QUADS; +            break; +        case PIPE_PRIM_QUAD_STRIP: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_QUAD_STRIP; +            break; +        case PIPE_PRIM_POLYGON: +            r300render->hwprim = R300_VAP_VF_CNTL__PRIM_POLYGON; +            break; +        default: +            return false; +            break;      } + +    return true;  } -static INLINE void r300_emit_prim(struct draw_stage* draw, -                                  struct prim_header* prim, -                                  unsigned hwprim, -                                  unsigned count) +static void r300_swtcl_render_draw_arrays(struct vbuf_render* render, +                                          unsigned start, +                                          unsigned count)  { -    struct r300_context* r300 = swtcl_stage(draw)->r300; +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    struct r300_context* r300 = r300render->r300; +    struct pipe_screen* screen = r300->context.screen; +      CS_LOCALS(r300); -    int i; +    /* Make sure that all possible state is emitted. */ +    r300_update_derived_state(r300);      r300_emit_dirty_state(r300); +    /* Take care of vertex formats and routes */      BEGIN_CS(3);      OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);      OUT_CS(r300->vertex_info.hwfmt[0]);      OUT_CS(r300->vertex_info.hwfmt[1]);      END_CS; -    BEGIN_CS(2 + (count * r300->vertex_info.size) + 2); -    OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, count)); -    OUT_CS(hwprim | R300_PRIM_WALK_RING | -        (count << R300_PRIM_NUM_VERTICES_SHIFT)); +    /* Draw stuff! */ +    BEGIN_CS(2); +    OUT_CS(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0)); +    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | +           r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); +} + +static void r300_swtcl_render_draw(struct vbuf_render* render, +                                   const ushort* indices, +                                   uint count) +{ +    struct r300_swtcl_render* r300render = r300_swtcl_render(render); +    struct r300_context* r300 = r300render->r300; +    struct pipe_screen* screen = r300->context.screen; +    struct pipe_buffer* index_buffer; +    void* index_map; + +    CS_LOCALS(r300); + +    /* Make sure that all possible state is emitted. */ +    r300_update_derived_state(r300); +    r300_emit_dirty_state(r300); -    for (i = 0; i < count; i++) { -        r300_emit_vertex(r300, prim->v[i]); +    /* Send our indices into an index buffer. */ +    index_buffer = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, +                                      count * 4); +    if (!index_buffer) { +        return;      } +    index_map = pipe_buffer_map(screen, index_buffer, +                                PIPE_BUFFER_USAGE_CPU_WRITE); +    memcpy(index_map, indices, count * 4); +    pipe_buffer_unmap(screen, index_buffer); + +    /* Take care of vertex formats and routes */ +    BEGIN_CS(3); +    OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); +    OUT_CS(r300->vertex_info.hwfmt[0]); +    OUT_CS(r300->vertex_info.hwfmt[1]);      END_CS; -} -/* Just as an aside... - * - * Radeons can do many more primitives: - * - Line strip - * - Triangle fan - * - Triangle strip - * - Line loop - * - Quads - * - Quad strip - * - Polygons - * - * The following were just the only ones in Draw. */ +    /* Draw stuff! */ +    BEGIN_CS(10); +    OUT_CS(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0)); +    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | +           r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); -static void r300_emit_point(struct draw_stage* draw, struct prim_header* prim) -{ -    r300_emit_prim(draw, prim, R300_PRIM_TYPE_POINT, 1); +    OUT_CS(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2)); +    OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2)); +    OUT_CS_RELOC(index_buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); +    END_CS;  } -static void r300_emit_line(struct draw_stage* draw, struct prim_header* prim) +static void r300_swtcl_render_destroy(struct vbuf_render* render)  { -    r300_emit_prim(draw, prim, R300_PRIM_TYPE_LINE, 2); +    FREE(render);  } -static void r300_emit_tri(struct draw_stage* draw, struct prim_header* prim) +static struct vbuf_render* r300_swtcl_render_create(struct r300_context* r300)  { -    r300_emit_prim(draw, prim, R300_PRIM_TYPE_TRI_LIST, 3); -} +    struct r300_swtcl_render* r300render = CALLOC_STRUCT(r300_swtcl_render); +    struct pipe_screen* screen = r300->context.screen; -static void r300_swtcl_flush(struct draw_stage* draw, unsigned flags) -{ -} +    r300render->r300 = r300; -static void r300_reset_stipple(struct draw_stage* draw) -{ -    /* XXX */ -} +    /* XXX find real numbers plz */ +    r300render->base.max_vertex_buffer_bytes = 128 * 1024; +    r300render->base.max_indices = 16 * 1024; -static void r300_swtcl_destroy(struct draw_stage* draw) -{ -    FREE(draw); +    r300render->base.get_vertex_info = r300_swtcl_render_get_vertex_info; +    r300render->base.allocate_vertices = r300_swtcl_render_allocate_vertices; +    r300render->base.map_vertices = r300_swtcl_render_map_vertices; +    r300render->base.unmap_vertices = r300_swtcl_render_unmap_vertices; +    r300render->base.set_primitive = r300_swtcl_render_set_primitive; +    r300render->base.draw = r300_swtcl_render_draw; +    r300render->base.draw_arrays = r300_swtcl_render_draw_arrays; +    r300render->base.release_vertices = r300_swtcl_render_release_vertices; +    r300render->base.destroy = r300_swtcl_render_destroy; + +    /* XXX bonghits ahead +    r300render->vbo_alloc_size = 128 * 4096; +    r300render->vbo_size = r300render->vbo_alloc_size; +    r300render->vbo_offset = 0; +    r300render->vbo = pipe_buffer_create(screen, +                                         64, +                                         PIPE_BUFFER_USAGE_VERTEX, +                                         r300render->vbo_size); +    r300render->vbo_map = pipe_buffer_map(screen, +                                          r300render->vbo, +                                          PIPE_BUFFER_USAGE_CPU_WRITE); +    pipe_buffer_unmap(screen, r300render->vbo); */ + +    return &r300render->base;  }  struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300)  { -    struct swtcl_stage* swtcl = CALLOC_STRUCT(swtcl_stage); +    struct vbuf_render* render; +    struct draw_stage* stage; + +    render = r300_swtcl_render_create(r300); + +    if (!render) { +        return NULL; +    } + +    stage = draw_vbuf_stage(r300->draw, render); + +    if (!stage) { +        render->destroy(render); +        return NULL; +    } -    swtcl->r300 = r300; -    swtcl->draw.point = r300_emit_point; -    swtcl->draw.line = r300_emit_line; -    swtcl->draw.tri = r300_emit_tri; -    swtcl->draw.flush = r300_swtcl_flush; -    swtcl->draw.reset_stipple_counter = r300_reset_stipple; -    swtcl->draw.destroy = r300_swtcl_destroy; +    draw_set_render(r300->draw, render); -    return &swtcl->draw; +    return stage;  } diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 9cd5784e5b..d56eed80a4 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -60,6 +60,7 @@ struct softpipe_vbuf_render     struct softpipe_context *softpipe;     uint prim;     uint vertex_size; +   uint vertex_buffer_size;     void *vertex_buffer;  }; @@ -80,26 +81,44 @@ sp_vbuf_get_vertex_info(struct vbuf_render *vbr)  } -static void * +static boolean  sp_vbuf_allocate_vertices(struct vbuf_render *vbr, -                            ushort vertex_size, ushort nr_vertices) +                          ushort vertex_size, ushort nr_vertices)  {     struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); -   assert(!cvbr->vertex_buffer); -   cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16); +   unsigned size = vertex_size * nr_vertices; + +   if (cvbr->vertex_buffer_size < size) { +      align_free(cvbr->vertex_buffer); +      cvbr->vertex_buffer = align_malloc(size, 16); +      cvbr->vertex_buffer_size = size; +   } +     cvbr->vertex_size = vertex_size; -   return cvbr->vertex_buffer; +   return cvbr->vertex_buffer != NULL;  } -  static void -sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, -                           unsigned vertex_size, unsigned vertices_used) +sp_vbuf_release_vertices(struct vbuf_render *vbr) +{ +   /* keep the old allocation for next time */ +} + +static void * +sp_vbuf_map_vertices(struct vbuf_render *vbr)  {     struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); -   align_free(vertices); -   assert(vertices == cvbr->vertex_buffer); -   cvbr->vertex_buffer = NULL; +   return cvbr->vertex_buffer; +} + +static void  +sp_vbuf_unmap_vertices(struct vbuf_render *vbr,  +                       ushort min_index, +                       ushort max_index ) +{ +   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); +   assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size ); +   /* do nothing */  } @@ -115,8 +134,6 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)     setup_prepare( setup_ctx ); - -     cvbr->prim = prim;     return TRUE; @@ -394,6 +411,8 @@ sp_init_vbuf(struct softpipe_context *sp)     sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info;     sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices; +   sp->vbuf_render->base.map_vertices = sp_vbuf_map_vertices; +   sp->vbuf_render->base.unmap_vertices = sp_vbuf_unmap_vertices;     sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive;     sp->vbuf_render->base.draw = sp_vbuf_draw;     sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays; | 
