draw_pt_post_vs.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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, /*const*/ 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    /* Do the hardwired planes first:
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); /* match mesa clipplane numbering - for now */
00077    if (-clip[2] + clip[3] < 0) mask |= (1<<5); /* match mesa clipplane numbering - for now */
00078 
00079    /* Followed by any remaining ones:
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 /* The normal case - cliptest, rhw divide, viewport transform.
00091  *
00092  * Also handle identity viewport here at the expense of a few wasted
00093  * instructions
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          /* divide by w */
00126          float w = 1.0f / position[3];
00127 
00128          /* Viewport mapping */
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 /* If bypass_clipping is set, skip cliptest and rhw divide.
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       /* Viewport mapping only, no cliptest/rhw divide
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 /* If bypass_clipping is set and we have an identity viewport, nothing
00181  * to do.
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       //if (opengl) 
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 }

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4