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_memory.h"
00029 #include "pipe/p_context.h"
00030 #include "draw/draw_context.h"
00031 #include "draw/draw_private.h"
00032 #include "draw/draw_vbuf.h"
00033 #include "draw/draw_vertex.h"
00034 #include "draw/draw_pt.h"
00035
00036 struct pt_post_vs {
00037 struct draw_context *draw;
00038
00039 boolean (*run)( struct pt_post_vs *pvs,
00040 struct vertex_header *vertices,
00041 unsigned count,
00042 unsigned stride );
00043 };
00044
00045
00046
00047 static INLINE float
00048 dot4(const float *a, const float *b)
00049 {
00050 return (a[0]*b[0] +
00051 a[1]*b[1] +
00052 a[2]*b[2] +
00053 a[3]*b[3]);
00054 }
00055
00056
00057
00058 static INLINE unsigned
00059 compute_clipmask_gl(const float *clip, float plane[][4], unsigned nr)
00060 {
00061 unsigned mask = 0x0;
00062 unsigned i;
00063
00064 #if 0
00065 debug_printf("compute clipmask %f %f %f %f\n",
00066 clip[0], clip[1], clip[2], clip[3]);
00067 assert(clip[3] != 0.0);
00068 #endif
00069
00070
00071
00072 if (-clip[0] + clip[3] < 0) mask |= (1<<0);
00073 if ( clip[0] + clip[3] < 0) mask |= (1<<1);
00074 if (-clip[1] + clip[3] < 0) mask |= (1<<2);
00075 if ( clip[1] + clip[3] < 0) mask |= (1<<3);
00076 if ( clip[2] + clip[3] < 0) mask |= (1<<4);
00077 if (-clip[2] + clip[3] < 0) mask |= (1<<5);
00078
00079
00080
00081 for (i = 6; i < nr; i++) {
00082 if (dot4(clip, plane[i]) < 0)
00083 mask |= (1<<i);
00084 }
00085
00086 return mask;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
00096 struct vertex_header *vertices,
00097 unsigned count,
00098 unsigned stride )
00099 {
00100 struct vertex_header *out = vertices;
00101 const float *scale = pvs->draw->viewport.scale;
00102 const float *trans = pvs->draw->viewport.translate;
00103 const unsigned pos = pvs->draw->vs.position_output;
00104 unsigned clipped = 0;
00105 unsigned j;
00106
00107 if (0) debug_printf("%s\n");
00108
00109 for (j = 0; j < count; j++) {
00110 float *position = out->data[pos];
00111
00112 out->clip[0] = position[0];
00113 out->clip[1] = position[1];
00114 out->clip[2] = position[2];
00115 out->clip[3] = position[3];
00116
00117 out->vertex_id = 0xffff;
00118 out->clipmask = compute_clipmask_gl(out->clip,
00119 pvs->draw->plane,
00120 pvs->draw->nr_planes);
00121 clipped += out->clipmask;
00122
00123 if (out->clipmask == 0)
00124 {
00125
00126 float w = 1.0f / position[3];
00127
00128
00129 position[0] = position[0] * w * scale[0] + trans[0];
00130 position[1] = position[1] * w * scale[1] + trans[1];
00131 position[2] = position[2] * w * scale[2] + trans[2];
00132 position[3] = w;
00133 #if 0
00134 debug_printf("post viewport: %f %f %f %f\n",
00135 position[0],
00136 position[1],
00137 position[2],
00138 position[3]);
00139 #endif
00140 }
00141
00142 out = (struct vertex_header *)( (char *)out + stride );
00143 }
00144
00145 return clipped != 0;
00146 }
00147
00148
00149
00150
00151
00152 static boolean post_vs_viewport( struct pt_post_vs *pvs,
00153 struct vertex_header *vertices,
00154 unsigned count,
00155 unsigned stride )
00156 {
00157 struct vertex_header *out = vertices;
00158 const float *scale = pvs->draw->viewport.scale;
00159 const float *trans = pvs->draw->viewport.translate;
00160 const unsigned pos = pvs->draw->vs.position_output;
00161 unsigned j;
00162
00163 if (0) debug_printf("%s\n", __FUNCTION__);
00164 for (j = 0; j < count; j++) {
00165 float *position = out->data[pos];
00166
00167
00168
00169 position[0] = position[0] * scale[0] + trans[0];
00170 position[1] = position[1] * scale[1] + trans[1];
00171 position[2] = position[2] * scale[2] + trans[2];
00172
00173 out = (struct vertex_header *)((char *)out + stride);
00174 }
00175
00176 return FALSE;
00177 }
00178
00179
00180
00181
00182
00183 static boolean post_vs_none( struct pt_post_vs *pvs,
00184 struct vertex_header *vertices,
00185 unsigned count,
00186 unsigned stride )
00187 {
00188 if (0) debug_printf("%s\n", __FUNCTION__);
00189 return FALSE;
00190 }
00191
00192 boolean draw_pt_post_vs_run( struct pt_post_vs *pvs,
00193 struct vertex_header *pipeline_verts,
00194 unsigned count,
00195 unsigned stride )
00196 {
00197 return pvs->run( pvs, pipeline_verts, count, stride );
00198 }
00199
00200
00201 void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
00202 boolean bypass_clipping,
00203 boolean identity_viewport,
00204 boolean opengl )
00205 {
00206 if (bypass_clipping) {
00207 if (identity_viewport)
00208 pvs->run = post_vs_none;
00209 else
00210 pvs->run = post_vs_viewport;
00211 }
00212 else {
00213
00214 pvs->run = post_vs_cliptest_viewport_gl;
00215 }
00216 }
00217
00218
00219 struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw )
00220 {
00221 struct pt_post_vs *pvs = CALLOC_STRUCT( pt_post_vs );
00222 if (!pvs)
00223 return NULL;
00224
00225 pvs->draw = draw;
00226
00227 return pvs;
00228 }
00229
00230 void draw_pt_post_vs_destroy( struct pt_post_vs *pvs )
00231 {
00232 FREE(pvs);
00233 }