diff options
Diffstat (limited to 'src/mesa/pipe/i915simple/i915_prim_emit.c')
-rw-r--r-- | src/mesa/pipe/i915simple/i915_prim_emit.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/src/mesa/pipe/i915simple/i915_prim_emit.c b/src/mesa/pipe/i915simple/i915_prim_emit.c new file mode 100644 index 0000000000..97e337451e --- /dev/null +++ b/src/mesa/pipe/i915simple/i915_prim_emit.c @@ -0,0 +1,201 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "imports.h" +#include "macros.h" + +#include "pipe/draw/draw_private.h" + +#include "i915_context.h" +#include "i915_winsys.h" +#include "i915_reg.h" +#include "i915_state.h" + + + +/** + * Primitive emit to hardware. No support for vertex buffers or any + * nice fast paths. + */ +struct setup_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct i915_context *i915; +}; + + + +/** + * Basically a cast wrapper. + */ +static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) +{ + return (struct setup_stage *)stage; +} + +static inline unsigned pack_ub4( unsigned char b0, + unsigned char b1, + unsigned char b2, + unsigned char b3 ) +{ + return ((((unsigned int)b0) << 0) | + (((unsigned int)b1) << 8) | + (((unsigned int)b2) << 16) | + (((unsigned int)b3) << 24)); +} + +static inline unsigned fui( float f ) +{ + union { + float f; + unsigned ui; + } fi; + + fi.f = f; + return fi.ui; +} + +static inline unsigned char float_to_ubyte( float f ) +{ + unsigned char ub; + UNCLAMPED_FLOAT_TO_UBYTE(ub, f); + return ub; +} + + +/* Hardcoded vertex format: xyz/rgba + */ +static inline void +emit_hw_vertex( unsigned *ptr, + struct vertex_header *vertex ) +{ + ptr[0] = fui( vertex->data[0][0] ); + ptr[1] = fui( vertex->data[0][1] ); + ptr[2] = fui( vertex->data[0][2] ); + + ptr[3] = pack_ub4( float_to_ubyte( vertex->data[1][0] ), + float_to_ubyte( vertex->data[1][1] ), + float_to_ubyte( vertex->data[1][2] ), + float_to_ubyte( vertex->data[1][3] ) ); +} + + + + +static inline void +emit_prim( struct draw_stage *stage, + struct prim_header *prim, + unsigned hwprim, + unsigned nr ) +{ + struct i915_context *i915 = setup_stage(stage)->i915; + struct i915_winsys *winsys = i915->winsys; + unsigned vertex_size = 4 * sizeof(int); + unsigned *ptr; + unsigned i; + + i915_emit_hardware_state( i915 ); + + ptr = winsys->batch_start( winsys, nr * vertex_size, 0 ); + if (ptr == 0) { + winsys->batch_flush( winsys ); + ptr = winsys->batch_start( winsys, nr * vertex_size, 0 ); + if (ptr == 0) { + assert(0); + return; + } + } + + /* Emit each triangle as a single primitive. I told you this was + * simple. + */ + *ptr++ = (_3DPRIMITIVE | + hwprim | + ((4 + vertex_size * nr)/4 - 2)); + + for (i = 0; i < nr; i++) { + emit_hw_vertex(ptr, prim->v[i]); + ptr += vertex_size / sizeof(int); + } +} + + +static void +setup_tri( struct draw_stage *stage, struct prim_header *prim ) +{ + emit_prim( stage, prim, PRIM3D_TRILIST, 3 ); +} + + +static void +setup_line(struct draw_stage *stage, struct prim_header *prim) +{ + emit_prim( stage, prim, PRIM3D_LINELIST, 2 ); +} + + +static void +setup_point(struct draw_stage *stage, struct prim_header *prim) +{ + emit_prim( stage, prim, PRIM3D_POINTLIST, 1 ); +} + + + +static void setup_begin( struct draw_stage *stage ) +{ +} + + +static void setup_end( struct draw_stage *stage ) +{ +} + +static void reset_stipple_counter( struct draw_stage *stage ) +{ +} + + +/** + * Create a new primitive setup/render stage. + */ +struct draw_stage *i915_draw_render_stage( struct i915_context *i915 ) +{ + struct setup_stage *setup = CALLOC_STRUCT(setup_stage); + + setup->i915 = i915; + setup->stage.draw = i915->draw; + setup->stage.begin = setup_begin; + setup->stage.point = setup_point; + setup->stage.line = setup_line; + setup->stage.tri = setup_tri; + setup->stage.end = setup_end; + setup->stage.reset_stipple_counter = reset_stipple_counter; + + return &setup->stage; +} |