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
00040 #include "main/imports.h"
00041 #include "main/context.h"
00042 #include "main/feedback.h"
00043 #include "main/macros.h"
00044
00045 #include "vbo/vbo.h"
00046
00047 #include "st_context.h"
00048 #include "st_atom.h"
00049 #include "st_draw.h"
00050 #include "st_cb_feedback.h"
00051 #include "st_cb_bufferobjects.h"
00052
00053 #include "pipe/p_context.h"
00054 #include "pipe/p_defines.h"
00055 #include "pipe/p_winsys.h"
00056 #include "cso_cache/cso_cache.h"
00057
00058 #include "draw/draw_context.h"
00059 #include "draw/draw_pipe.h"
00060
00061
00065 struct feedback_stage
00066 {
00067 struct draw_stage stage;
00068 GLcontext *ctx;
00069 GLboolean reset_stipple_counter;
00070 };
00071
00072
00073
00074
00075
00076
00077 static INLINE struct feedback_stage *
00078 feedback_stage( struct draw_stage *stage )
00079 {
00080 return (struct feedback_stage *)stage;
00081 }
00082
00083
00084 static void
00085 feedback_vertex(GLcontext *ctx, const struct draw_context *draw,
00086 const struct vertex_header *v)
00087 {
00088 const struct st_context *st = ctx->st;
00089 GLfloat win[4];
00090 const GLfloat *color, *texcoord;
00091 const GLfloat ci = 0;
00092 GLuint slot;
00093
00094
00095 win[0] = v->data[0][0];
00096 win[1] = ctx->DrawBuffer->Height - v->data[0][1];
00097 win[2] = v->data[0][2];
00098 win[3] = 1.0F / v->data[0][3];
00099
00100
00101
00102
00103
00104
00105 slot = st->vertex_result_to_slot[VERT_RESULT_COL0];
00106 if (slot != ~0U)
00107 color = v->data[slot];
00108 else
00109 color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
00110
00111 slot = st->vertex_result_to_slot[VERT_RESULT_TEX0];
00112 if (slot != ~0U)
00113 texcoord = v->data[slot];
00114 else
00115 texcoord = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
00116
00117 _mesa_feedback_vertex(ctx, win, color, ci, texcoord);
00118 }
00119
00120
00121 static void
00122 feedback_tri( struct draw_stage *stage, struct prim_header *prim )
00123 {
00124 struct feedback_stage *fs = feedback_stage(stage);
00125 struct draw_context *draw = stage->draw;
00126 FEEDBACK_TOKEN(fs->ctx, (GLfloat) GL_POLYGON_TOKEN);
00127 FEEDBACK_TOKEN(fs->ctx, (GLfloat) 3);
00128 feedback_vertex(fs->ctx, draw, prim->v[0]);
00129 feedback_vertex(fs->ctx, draw, prim->v[1]);
00130 feedback_vertex(fs->ctx, draw, prim->v[2]);
00131 }
00132
00133
00134 static void
00135 feedback_line( struct draw_stage *stage, struct prim_header *prim )
00136 {
00137 struct feedback_stage *fs = feedback_stage(stage);
00138 struct draw_context *draw = stage->draw;
00139 if (fs->reset_stipple_counter) {
00140 FEEDBACK_TOKEN(fs->ctx, (GLfloat) GL_LINE_RESET_TOKEN);
00141 fs->reset_stipple_counter = GL_FALSE;
00142 }
00143 else {
00144 FEEDBACK_TOKEN(fs->ctx, (GLfloat) GL_LINE_TOKEN);
00145 }
00146 feedback_vertex(fs->ctx, draw, prim->v[0]);
00147 feedback_vertex(fs->ctx, draw, prim->v[1]);
00148 }
00149
00150
00151 static void
00152 feedback_point( struct draw_stage *stage, struct prim_header *prim )
00153 {
00154 struct feedback_stage *fs = feedback_stage(stage);
00155 struct draw_context *draw = stage->draw;
00156 FEEDBACK_TOKEN(fs->ctx, (GLfloat) GL_POINT_TOKEN);
00157 feedback_vertex(fs->ctx, draw, prim->v[0]);
00158 }
00159
00160
00161 static void
00162 feedback_flush( struct draw_stage *stage, unsigned flags )
00163 {
00164
00165 }
00166
00167
00168 static void
00169 feedback_reset_stipple_counter( struct draw_stage *stage )
00170 {
00171 struct feedback_stage *fs = feedback_stage(stage);
00172 fs->reset_stipple_counter = GL_TRUE;
00173 }
00174
00175
00176 static void
00177 feedback_destroy( struct draw_stage *stage )
00178 {
00179
00180 }
00181
00185 static struct draw_stage *
00186 draw_glfeedback_stage(GLcontext *ctx, struct draw_context *draw)
00187 {
00188 struct feedback_stage *fs = CALLOC_STRUCT(feedback_stage);
00189
00190 fs->stage.draw = draw;
00191 fs->stage.next = NULL;
00192 fs->stage.point = feedback_point;
00193 fs->stage.line = feedback_line;
00194 fs->stage.tri = feedback_tri;
00195 fs->stage.flush = feedback_flush;
00196 fs->stage.reset_stipple_counter = feedback_reset_stipple_counter;
00197 fs->stage.destroy = feedback_destroy;
00198 fs->ctx = ctx;
00199
00200 return &fs->stage;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209 static void
00210 select_tri( struct draw_stage *stage, struct prim_header *prim )
00211 {
00212 struct feedback_stage *fs = feedback_stage(stage);
00213 _mesa_update_hitflag( fs->ctx, prim->v[0]->data[0][2] );
00214 _mesa_update_hitflag( fs->ctx, prim->v[1]->data[0][2] );
00215 _mesa_update_hitflag( fs->ctx, prim->v[2]->data[0][2] );
00216 }
00217
00218 static void
00219 select_line( struct draw_stage *stage, struct prim_header *prim )
00220 {
00221 struct feedback_stage *fs = feedback_stage(stage);
00222 _mesa_update_hitflag( fs->ctx, prim->v[0]->data[0][2] );
00223 _mesa_update_hitflag( fs->ctx, prim->v[1]->data[0][2] );
00224 }
00225
00226
00227 static void
00228 select_point( struct draw_stage *stage, struct prim_header *prim )
00229 {
00230 struct feedback_stage *fs = feedback_stage(stage);
00231 _mesa_update_hitflag( fs->ctx, prim->v[0]->data[0][2] );
00232 }
00233
00234
00235 static void
00236 select_flush( struct draw_stage *stage, unsigned flags )
00237 {
00238
00239 }
00240
00241
00242 static void
00243 select_reset_stipple_counter( struct draw_stage *stage )
00244 {
00245
00246 }
00247
00248 static void
00249 select_destroy( struct draw_stage *stage )
00250 {
00251
00252 }
00253
00254
00258 static struct draw_stage *
00259 draw_glselect_stage(GLcontext *ctx, struct draw_context *draw)
00260 {
00261 struct feedback_stage *fs = CALLOC_STRUCT(feedback_stage);
00262
00263 fs->stage.draw = draw;
00264 fs->stage.next = NULL;
00265 fs->stage.point = select_point;
00266 fs->stage.line = select_line;
00267 fs->stage.tri = select_tri;
00268 fs->stage.flush = select_flush;
00269 fs->stage.reset_stipple_counter = select_reset_stipple_counter;
00270 fs->stage.destroy = select_destroy;
00271 fs->ctx = ctx;
00272
00273 return &fs->stage;
00274 }
00275
00276
00277 static void
00278 st_RenderMode(GLcontext *ctx, GLenum newMode )
00279 {
00280 struct st_context *st = ctx->st;
00281 struct draw_context *draw = st->draw;
00282
00283 if (newMode == GL_RENDER) {
00284
00285 vbo_set_draw_func(ctx, st_draw_vbo);
00286 }
00287 else if (newMode == GL_SELECT) {
00288 if (!st->selection_stage)
00289 st->selection_stage = draw_glselect_stage(ctx, draw);
00290 draw_set_rasterize_stage(draw, st->selection_stage);
00291
00292 vbo_set_draw_func(ctx, st_feedback_draw_vbo);
00293 }
00294 else {
00295 if (!st->feedback_stage)
00296 st->feedback_stage = draw_glfeedback_stage(ctx, draw);
00297 draw_set_rasterize_stage(draw, st->feedback_stage);
00298
00299 vbo_set_draw_func(ctx, st_feedback_draw_vbo);
00300
00301 st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
00302 }
00303 }
00304
00305
00306
00307 void st_init_feedback_functions(struct dd_function_table *functions)
00308 {
00309 functions->RenderMode = st_RenderMode;
00310 }