diff options
author | Keith Whitwell <[email protected]> | 2009-02-18 12:54:26 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 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 | 333 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_prim_vbuf.c | 45 |
20 files changed, 790 insertions, 371 deletions
diff --git a/configs/default b/configs/default index a90d46f18e1..2566a860a27 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 393741cc9d6..e280d8f507c 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 d77f120b96b..f58345ce3b1 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 dce96f6bc8c..2800f3ef823 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 76826d9be08..d699e2b46b5 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 00000000000..90444aecdfd --- /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 0c4e9412e27..12325d30d61 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 c02f229110a..aecaeee5b9e 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 232dfdaed2d..064e16c295c 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 dcb7744b177..6b7d02a19bc 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 84ffe3296af..cd9cd4b53fd 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 ec3b41c320a..38f9b604d37 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 a1c4c14445b..cccd3bf4358 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 2dc2e073291..58c41840e1f 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 221bee4777a..f6458232ae5 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 5e5436be537..491a8818068 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 187136ce7b7..319e1f65572 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 468e0a2e44b..be26b13b0b0 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 76ef48962b9..fb009247a50 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; - - 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; - } + 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 INLINE void r300_emit_prim(struct draw_stage* draw, - struct prim_header* prim, - unsigned hwprim, - unsigned count) +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_context* r300 = swtcl_stage(draw)->r300; + 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; + + 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 void r300_swtcl_render_draw_arrays(struct vbuf_render* render, + unsigned start, + unsigned count) +{ + 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 9cd5784e5bc..d56eed80a4f 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; |