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 #include "util/u_math.h"
00029 #include "util/u_memory.h"
00030
00031 #include "draw/draw_context.h"
00032 #include "draw/draw_private.h"
00033 #include "draw/draw_pt.h"
00034
00035 #define FETCH_MAX 256
00036 #define DRAW_MAX (FETCH_MAX+8)
00037
00038 struct varray_frontend {
00039 struct draw_pt_front_end base;
00040 struct draw_context *draw;
00041
00042 ushort draw_elts[DRAW_MAX];
00043 unsigned fetch_elts[FETCH_MAX];
00044
00045 unsigned driver_fetch_max;
00046 unsigned fetch_max;
00047
00048 struct draw_pt_middle_end *middle;
00049
00050 unsigned input_prim;
00051 unsigned output_prim;
00052 };
00053
00054
00055 static void varray_flush_linear(struct varray_frontend *varray,
00056 unsigned start, unsigned count)
00057 {
00058 if (count) {
00059 assert(varray->middle->run_linear);
00060 varray->middle->run_linear(varray->middle, start, count);
00061 }
00062 }
00063
00064 static void varray_line_loop_segment(struct varray_frontend *varray,
00065 unsigned start,
00066 unsigned segment_start,
00067 unsigned segment_count,
00068 boolean end )
00069 {
00070 assert(segment_count+1 < varray->fetch_max);
00071 if (segment_count >= 1) {
00072 unsigned nr = 0, i;
00073
00074 for (i = 0; i < segment_count; i++)
00075 varray->fetch_elts[nr++] = start + segment_start + i;
00076
00077 if (end)
00078 varray->fetch_elts[nr++] = start;
00079
00080 assert(nr < FETCH_MAX);
00081
00082 varray->middle->run(varray->middle,
00083 varray->fetch_elts,
00084 nr,
00085 varray->draw_elts,
00086 nr);
00087 }
00088 }
00089
00090
00091
00092 static void varray_fan_segment(struct varray_frontend *varray,
00093 unsigned start,
00094 unsigned segment_start,
00095 unsigned segment_count )
00096 {
00097 assert(segment_count+1 < varray->fetch_max);
00098 if (segment_count >= 2) {
00099 unsigned nr = 0, i;
00100
00101 if (segment_start != 0)
00102 varray->fetch_elts[nr++] = start;
00103
00104 for (i = 0 ; i < segment_count; i++)
00105 varray->fetch_elts[nr++] = start + segment_start + i;
00106
00107 assert(nr < FETCH_MAX);
00108
00109 varray->middle->run(varray->middle,
00110 varray->fetch_elts,
00111 nr,
00112 varray->draw_elts,
00113 nr);
00114 }
00115 }
00116
00117
00118
00119
00120 #define FUNC varray_run
00121 #include "draw_pt_varray_tmp_linear.h"
00122
00123 static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
00124 PIPE_PRIM_POINTS,
00125 PIPE_PRIM_LINES,
00126 PIPE_PRIM_LINE_STRIP,
00127 PIPE_PRIM_LINE_STRIP,
00128 PIPE_PRIM_TRIANGLES,
00129 PIPE_PRIM_TRIANGLE_STRIP,
00130 PIPE_PRIM_TRIANGLE_FAN,
00131 PIPE_PRIM_QUADS,
00132 PIPE_PRIM_QUAD_STRIP,
00133 PIPE_PRIM_POLYGON
00134 };
00135
00136
00137
00138 static void varray_prepare(struct draw_pt_front_end *frontend,
00139 unsigned prim,
00140 struct draw_pt_middle_end *middle,
00141 unsigned opt)
00142 {
00143 struct varray_frontend *varray = (struct varray_frontend *)frontend;
00144
00145 varray->base.run = varray_run;
00146
00147 varray->input_prim = prim;
00148 varray->output_prim = decompose_prim[prim];
00149
00150 varray->middle = middle;
00151 middle->prepare(middle, varray->output_prim, opt, &varray->driver_fetch_max );
00152
00153
00154 assert((varray->driver_fetch_max & 1) == 0);
00155
00156 varray->fetch_max = MIN2(FETCH_MAX, varray->driver_fetch_max);
00157 }
00158
00159
00160
00161
00162 static void varray_finish(struct draw_pt_front_end *frontend)
00163 {
00164 struct varray_frontend *varray = (struct varray_frontend *)frontend;
00165 varray->middle->finish(varray->middle);
00166 varray->middle = NULL;
00167 }
00168
00169 static void varray_destroy(struct draw_pt_front_end *frontend)
00170 {
00171 FREE(frontend);
00172 }
00173
00174
00175 struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw)
00176 {
00177 ushort i;
00178 struct varray_frontend *varray = CALLOC_STRUCT(varray_frontend);
00179 if (varray == NULL)
00180 return NULL;
00181
00182 varray->base.prepare = varray_prepare;
00183 varray->base.run = NULL;
00184 varray->base.finish = varray_finish;
00185 varray->base.destroy = varray_destroy;
00186 varray->draw = draw;
00187
00188 for (i = 0; i < DRAW_MAX; i++) {
00189 varray->draw_elts[i] = i;
00190 }
00191
00192 return &varray->base;
00193 }