1 /************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29 #include "draw/draw_pipe.h" 30 #include "util/u_math.h" 31 #include "util/u_memory.h" 32 #include "util/u_pack_color.h" 33 34 #include "i915_context.h" 35 #include "i915_reg.h" 36 #include "i915_state.h" 37 #include "i915_batch.h" 38 39 40 41 /** 42 * Primitive emit to hardware. No support for vertex buffers or any 43 * nice fast paths. 44 */ 45 struct setup_stage { 46 struct draw_stage stage; /**< This must be first (base class) */ 47 48 struct i915_context *i915; 49 }; 50 51 52 53 /** 54 * Basically a cast wrapper. 55 */ 56 static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) 57 { 58 return (struct setup_stage *)stage; 59 } 60 61 62 /** 63 * Extract the needed fields from vertex_header and emit i915 dwords. 64 * Recall that the vertices are constructed by the 'draw' module and 65 * have a couple of slots at the beginning (1-dword header, 4-dword 66 * clip pos) that we ignore here. 67 */ 68 static INLINE void 69 emit_hw_vertex( struct i915_context *i915, 70 const struct vertex_header *vertex) 71 { 72 const struct vertex_info *vinfo = &i915->current.vertex_info; 73 uint i; 74 uint count = 0; /* for debug/sanity */ 75 76 assert(!i915->dirty); 77 78 for (i = 0; i < vinfo->num_attribs; i++) { 79 const uint j = vinfo->attrib[i].src_index; 80 const float *attrib = vertex->data[j]; 81 switch (vinfo->attrib[i].emit) { 82 case EMIT_1F: 83 OUT_BATCH( fui(attrib[0]) ); 84 count++; 85 break; 86 case EMIT_2F: 87 OUT_BATCH( fui(attrib[0]) ); 88 OUT_BATCH( fui(attrib[1]) ); 89 count += 2; 90 break; 91 case EMIT_3F: 92 OUT_BATCH( fui(attrib[0]) ); 93 OUT_BATCH( fui(attrib[1]) ); 94 OUT_BATCH( fui(attrib[2]) ); 95 count += 3; 96 break; 97 case EMIT_4F: 98 OUT_BATCH( fui(attrib[0]) ); 99 OUT_BATCH( fui(attrib[1]) ); 100 OUT_BATCH( fui(attrib[2]) ); 101 OUT_BATCH( fui(attrib[3]) ); 102 count += 4; 103 break; 104 case EMIT_4UB: 105 OUT_BATCH( pack_ub4(float_to_ubyte( attrib[0] ), 106 float_to_ubyte( attrib[1] ), 107 float_to_ubyte( attrib[2] ), 108 float_to_ubyte( attrib[3] )) ); 109 count += 1; 110 break; 111 case EMIT_4UB_BGRA: 112 OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ), 113 float_to_ubyte( attrib[1] ), 114 float_to_ubyte( attrib[0] ), 115 float_to_ubyte( attrib[3] )) ); 116 count += 1; 117 break; 118 default: 119 assert(0); 120 } 121 } 122 assert(count == vinfo->size); 123 } 124 125 126 127 static INLINE void 128 emit_prim( struct draw_stage *stage, 129 struct prim_header *prim, 130 unsigned hwprim, 131 unsigned nr ) 132 { 133 struct i915_context *i915 = setup_stage(stage)->i915; 134 unsigned vertex_size; 135 unsigned i; 136 137 if (i915->dirty) 138 i915_update_derived( i915 ); 139 140 if (i915->hardware_dirty) 141 i915_emit_hardware_state( i915 ); 142 143 /* need to do this after validation! */ 144 vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ 145 assert(vertex_size >= 12); /* never smaller than 12 bytes */ 146 147 if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) { 148 FLUSH_BATCH(NULL); 149 150 /* Make sure state is re-emitted after a flush: 151 */ 152 i915_emit_hardware_state( i915 ); 153 154 if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) { 155 assert(0); 156 return; 157 } 158 } 159 160 /* Emit each triangle as a single primitive. I told you this was 161 * simple. 162 */ 163 OUT_BATCH(_3DPRIMITIVE | 164 hwprim | 165 ((4 + vertex_size * nr)/4 - 2)); 166 167 for (i = 0; i < nr; i++) 168 emit_hw_vertex(i915, prim->v[i]); 169 } 170 171 172 static void 173 setup_tri( struct draw_stage *stage, struct prim_header *prim ) 174 { 175 emit_prim( stage, prim, PRIM3D_TRILIST, 3 ); 176 } 177 178 179 static void 180 setup_line(struct draw_stage *stage, struct prim_header *prim) 181 { 182 emit_prim( stage, prim, PRIM3D_LINELIST, 2 ); 183 } 184 185 186 static void 187 setup_point(struct draw_stage *stage, struct prim_header *prim) 188 { 189 emit_prim( stage, prim, PRIM3D_POINTLIST, 1 ); 190 } 191 192 193 static void setup_flush( struct draw_stage *stage, unsigned flags ) 194 { 195 } 196 197 static void reset_stipple_counter( struct draw_stage *stage ) 198 { 199 } 200 201 static void render_destroy( struct draw_stage *stage ) 202 { 203 FREE( stage ); 204 } 205 206 207 /** 208 * Create a new primitive setup/render stage. This gets plugged into 209 * the 'draw' module's pipeline. 210 */ 211 struct draw_stage *i915_draw_render_stage( struct i915_context *i915 ) 212 { 213 struct setup_stage *setup = CALLOC_STRUCT(setup_stage); 214 215 setup->i915 = i915; 216 setup->stage.draw = i915->draw; 217 setup->stage.point = setup_point; 218 setup->stage.line = setup_line; 219 setup->stage.tri = setup_tri; 220 setup->stage.flush = setup_flush; 221 setup->stage.reset_stipple_counter = reset_stipple_counter; 222 setup->stage.destroy = render_destroy; 223 224 return &setup->stage; 225 } 226