00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "draw/draw_pipe.h"
00030 #include "util/u_math.h"
00031 #include "util/u_memory.h"
00032 #include "util/u_pack_color.h"
00033
00034 #include "i915_context.h"
00035 #include "i915_winsys.h"
00036 #include "i915_reg.h"
00037 #include "i915_state.h"
00038 #include "i915_batch.h"
00039
00040
00041
00046 struct setup_stage {
00047 struct draw_stage stage;
00049 struct i915_context *i915;
00050 };
00051
00052
00053
00057 static INLINE struct setup_stage *setup_stage( struct draw_stage *stage )
00058 {
00059 return (struct setup_stage *)stage;
00060 }
00061
00062
00069 static INLINE void
00070 emit_hw_vertex( struct i915_context *i915,
00071 const struct vertex_header *vertex)
00072 {
00073 const struct vertex_info *vinfo = &i915->current.vertex_info;
00074 uint i;
00075 uint count = 0;
00076
00077 assert(!i915->dirty);
00078
00079 for (i = 0; i < vinfo->num_attribs; i++) {
00080 const uint j = vinfo->attrib[i].src_index;
00081 const float *attrib = vertex->data[j];
00082 switch (vinfo->attrib[i].emit) {
00083 case EMIT_1F:
00084 OUT_BATCH( fui(attrib[0]) );
00085 count++;
00086 break;
00087 case EMIT_2F:
00088 OUT_BATCH( fui(attrib[0]) );
00089 OUT_BATCH( fui(attrib[1]) );
00090 count += 2;
00091 break;
00092 case EMIT_3F:
00093 OUT_BATCH( fui(attrib[0]) );
00094 OUT_BATCH( fui(attrib[1]) );
00095 OUT_BATCH( fui(attrib[2]) );
00096 count += 3;
00097 break;
00098 case EMIT_4F:
00099 OUT_BATCH( fui(attrib[0]) );
00100 OUT_BATCH( fui(attrib[1]) );
00101 OUT_BATCH( fui(attrib[2]) );
00102 OUT_BATCH( fui(attrib[3]) );
00103 count += 4;
00104 break;
00105 case EMIT_4UB:
00106 OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ),
00107 float_to_ubyte( attrib[1] ),
00108 float_to_ubyte( attrib[0] ),
00109 float_to_ubyte( attrib[3] )) );
00110 count += 1;
00111 break;
00112 default:
00113 assert(0);
00114 }
00115 }
00116 assert(count == vinfo->size);
00117 }
00118
00119
00120
00121 static INLINE void
00122 emit_prim( struct draw_stage *stage,
00123 struct prim_header *prim,
00124 unsigned hwprim,
00125 unsigned nr )
00126 {
00127 struct i915_context *i915 = setup_stage(stage)->i915;
00128 unsigned vertex_size;
00129 unsigned i;
00130
00131 if (i915->dirty)
00132 i915_update_derived( i915 );
00133
00134 if (i915->hardware_dirty)
00135 i915_emit_hardware_state( i915 );
00136
00137
00138 vertex_size = i915->current.vertex_info.size * 4;
00139 assert(vertex_size >= 12);
00140
00141 if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) {
00142 FLUSH_BATCH(NULL);
00143
00144
00145
00146 i915_update_derived( i915 );
00147 i915_emit_hardware_state( i915 );
00148
00149 if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) {
00150 assert(0);
00151 return;
00152 }
00153 }
00154
00155
00156
00157
00158 OUT_BATCH(_3DPRIMITIVE |
00159 hwprim |
00160 ((4 + vertex_size * nr)/4 - 2));
00161
00162 for (i = 0; i < nr; i++)
00163 emit_hw_vertex(i915, prim->v[i]);
00164 }
00165
00166
00167 static void
00168 setup_tri( struct draw_stage *stage, struct prim_header *prim )
00169 {
00170 emit_prim( stage, prim, PRIM3D_TRILIST, 3 );
00171 }
00172
00173
00174 static void
00175 setup_line(struct draw_stage *stage, struct prim_header *prim)
00176 {
00177 emit_prim( stage, prim, PRIM3D_LINELIST, 2 );
00178 }
00179
00180
00181 static void
00182 setup_point(struct draw_stage *stage, struct prim_header *prim)
00183 {
00184 emit_prim( stage, prim, PRIM3D_POINTLIST, 1 );
00185 }
00186
00187
00188 static void setup_flush( struct draw_stage *stage, unsigned flags )
00189 {
00190 }
00191
00192 static void reset_stipple_counter( struct draw_stage *stage )
00193 {
00194 }
00195
00196 static void render_destroy( struct draw_stage *stage )
00197 {
00198 FREE( stage );
00199 }
00200
00201
00206 struct draw_stage *i915_draw_render_stage( struct i915_context *i915 )
00207 {
00208 struct setup_stage *setup = CALLOC_STRUCT(setup_stage);
00209
00210 setup->i915 = i915;
00211 setup->stage.draw = i915->draw;
00212 setup->stage.point = setup_point;
00213 setup->stage.line = setup_line;
00214 setup->stage.tri = setup_tri;
00215 setup->stage.flush = setup_flush;
00216 setup->stage.reset_stipple_counter = reset_stipple_counter;
00217 setup->stage.destroy = render_destroy;
00218
00219 return &setup->stage;
00220 }