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
00039 #include "main/imports.h"
00040 #include "main/macros.h"
00041 #include "main/feedback.h"
00042
00043 #include "st_context.h"
00044 #include "st_atom.h"
00045 #include "st_draw.h"
00046 #include "st_cb_rasterpos.h"
00047 #include "st_draw.h"
00048 #include "draw/draw_context.h"
00049 #include "draw/draw_pipe.h"
00050 #include "shader/prog_instruction.h"
00051 #include "vbo/vbo.h"
00052
00053
00054
00058 struct rastpos_stage
00059 {
00060 struct draw_stage stage;
00061 GLcontext *ctx;
00063
00064 struct gl_client_array array[VERT_ATTRIB_MAX];
00065 const struct gl_client_array *arrays[VERT_ATTRIB_MAX];
00066 struct _mesa_prim prim;
00067 };
00068
00069
00070 static INLINE struct rastpos_stage *
00071 rastpos_stage( struct draw_stage *stage )
00072 {
00073 return (struct rastpos_stage *) stage;
00074 }
00075
00076 static void
00077 rastpos_flush( struct draw_stage *stage, unsigned flags )
00078 {
00079
00080 }
00081
00082 static void
00083 rastpos_reset_stipple_counter( struct draw_stage *stage )
00084 {
00085
00086 }
00087
00088 static void
00089 rastpos_tri( struct draw_stage *stage, struct prim_header *prim )
00090 {
00091
00092 assert(0);
00093 }
00094
00095 static void
00096 rastpos_line( struct draw_stage *stage, struct prim_header *prim )
00097 {
00098
00099 assert(0);
00100 }
00101
00102 static void
00103 rastpos_destroy(struct draw_stage *stage)
00104 {
00105 free(stage);
00106 }
00107
00108
00113 static void
00114 update_attrib(GLcontext *ctx, const GLuint *outputMapping,
00115 const struct vertex_header *vert,
00116 GLfloat *dest,
00117 GLuint result, GLuint defaultAttrib)
00118 {
00119 const GLfloat *src;
00120 const GLuint k = outputMapping[result];
00121 if (k != ~0U)
00122 src = vert->data[k];
00123 else
00124 src = ctx->Current.Attrib[defaultAttrib];
00125 COPY_4V(dest, src);
00126 }
00127
00128
00132 static void
00133 rastpos_point(struct draw_stage *stage, struct prim_header *prim)
00134 {
00135 struct rastpos_stage *rs = rastpos_stage(stage);
00136 GLcontext *ctx = rs->ctx;
00137 struct st_context *st = ctx->st;
00138 const GLfloat height = (GLfloat) ctx->DrawBuffer->Height;
00139 const GLuint *outputMapping = st->vertex_result_to_slot;
00140 const GLfloat *pos;
00141 GLuint i;
00142
00143
00144 ctx->Current.RasterPosValid = GL_TRUE;
00145
00146
00147 pos = prim->v[0]->data[0];
00148 ctx->Current.RasterPos[0] = pos[0];
00149 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
00150 ctx->Current.RasterPos[1] = height - pos[1];
00151 else
00152 ctx->Current.RasterPos[1] = pos[1];
00153 ctx->Current.RasterPos[2] = pos[2];
00154 ctx->Current.RasterPos[3] = pos[3];
00155
00156
00157 update_attrib(ctx, outputMapping, prim->v[0],
00158 ctx->Current.RasterColor,
00159 VERT_RESULT_COL0, VERT_ATTRIB_COLOR0);
00160
00161 update_attrib(ctx, outputMapping, prim->v[0],
00162 ctx->Current.RasterSecondaryColor,
00163 VERT_RESULT_COL1, VERT_ATTRIB_COLOR1);
00164
00165 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
00166 update_attrib(ctx, outputMapping, prim->v[0],
00167 ctx->Current.RasterTexCoords[i],
00168 VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);
00169 }
00170
00171 if (ctx->RenderMode == GL_SELECT) {
00172 _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
00173 }
00174 }
00175
00176
00180 static struct rastpos_stage *
00181 new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw)
00182 {
00183 struct rastpos_stage *rs = CALLOC_STRUCT(rastpos_stage);
00184 GLuint i;
00185
00186 rs->stage.draw = draw;
00187 rs->stage.next = NULL;
00188 rs->stage.point = rastpos_point;
00189 rs->stage.line = rastpos_line;
00190 rs->stage.tri = rastpos_tri;
00191 rs->stage.flush = rastpos_flush;
00192 rs->stage.destroy = rastpos_destroy;
00193 rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
00194 rs->stage.destroy = rastpos_destroy;
00195 rs->ctx = ctx;
00196
00197 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
00198 rs->array[i].Size = 4;
00199 rs->array[i].Type = GL_FLOAT;
00200 rs->array[i].Stride = 0;
00201 rs->array[i].StrideB = 0;
00202 rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
00203 rs->array[i].Enabled = GL_TRUE;
00204 rs->array[i].Normalized = GL_TRUE;
00205 rs->array[i].BufferObj = NULL;
00206 rs->arrays[i] = &rs->array[i];
00207 }
00208
00209 rs->prim.mode = GL_POINTS;
00210 rs->prim.indexed = 0;
00211 rs->prim.begin = 1;
00212 rs->prim.end = 1;
00213 rs->prim.weak = 0;
00214 rs->prim.start = 0;
00215 rs->prim.count = 1;
00216
00217 return rs;
00218 }
00219
00220
00221 static void
00222 st_RasterPos(GLcontext *ctx, const GLfloat v[4])
00223 {
00224 struct st_context *st = ctx->st;
00225 struct draw_context *draw = st->draw;
00226 struct rastpos_stage *rs;
00227
00228 if (st->rastpos_stage) {
00229
00230 rs = rastpos_stage(st->rastpos_stage);
00231 }
00232 else {
00233
00234 rs = new_draw_rastpos_stage(ctx, draw);
00235 st->rastpos_stage = &rs->stage;
00236 }
00237
00238
00239 draw_set_rasterize_stage(st->draw, st->rastpos_stage);
00240
00241
00242 st_validate_state(ctx->st);
00243
00244
00245 ctx->Current.RasterPosValid = GL_FALSE;
00246
00247
00248
00249
00250 rs->array[0].Ptr = (GLubyte *) v;
00251
00252
00253 st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, 0, 1);
00254 }
00255
00256
00257
00258 void st_init_rasterpos_functions(struct dd_function_table *functions)
00259 {
00260 functions->RasterPos = st_RasterPos;
00261 }