ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

t_vb_program.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00033 #include "main/glheader.h"
00034 #include "main/colormac.h"
00035 #include "main/context.h"
00036 #include "main/macros.h"
00037 #include "main/imports.h"
00038 #include "shader/prog_instruction.h"
00039 #include "shader/prog_statevars.h"
00040 #include "shader/prog_execute.h"
00041 #include "swrast/s_context.h"
00042 #include "swrast/s_texfilter.h"
00043 
00044 #include "tnl/tnl.h"
00045 #include "tnl/t_context.h"
00046 #include "tnl/t_pipeline.h"
00047 
00048 
00049 
00053 struct vp_stage_data {
00055    GLvector4f results[VERT_RESULT_MAX];
00056 
00057    GLvector4f ndcCoords;              
00058    GLubyte *clipmask;                 
00059    GLubyte ormask, andmask;           
00060 };
00061 
00062 
00063 #define VP_STAGE_DATA(stage) ((struct vp_stage_data *)(stage->privatePtr))
00064 
00065 
00066 static void
00067 userclip( GLcontext *ctx,
00068           GLvector4f *clip,
00069           GLubyte *clipmask,
00070           GLubyte *clipormask,
00071           GLubyte *clipandmask )
00072 {
00073    GLuint p;
00074 
00075    for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
00076       if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
00077      GLuint nr, i;
00078      const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
00079      const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
00080      const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
00081      const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
00082          GLfloat *coord = (GLfloat *)clip->data;
00083          GLuint stride = clip->stride;
00084          GLuint count = clip->count;
00085 
00086      for (nr = 0, i = 0 ; i < count ; i++) {
00087         GLfloat dp = (coord[0] * a + 
00088               coord[1] * b +
00089               coord[2] * c +
00090               coord[3] * d);
00091 
00092         if (dp < 0) {
00093            nr++;
00094            clipmask[i] |= CLIP_USER_BIT;
00095         }
00096 
00097         STRIDE_F(coord, stride);
00098      }
00099 
00100      if (nr > 0) {
00101         *clipormask |= CLIP_USER_BIT;
00102         if (nr == count) {
00103            *clipandmask |= CLIP_USER_BIT;
00104            return;
00105         }
00106      }
00107       }
00108    }
00109 }
00110 
00111 
00112 static GLboolean
00113 do_ndc_cliptest(GLcontext *ctx, struct vp_stage_data *store)
00114 {
00115    TNLcontext *tnl = TNL_CONTEXT(ctx);
00116    struct vertex_buffer *VB = &tnl->vb;
00117    /* Cliptest and perspective divide.  Clip functions must clear
00118     * the clipmask.
00119     */
00120    store->ormask = 0;
00121    store->andmask = CLIP_FRUSTUM_BITS;
00122 
00123    if (tnl->NeedNdcCoords) {
00124       VB->NdcPtr =
00125          _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
00126                                             &store->ndcCoords,
00127                                             store->clipmask,
00128                                             &store->ormask,
00129                                             &store->andmask );
00130    }
00131    else {
00132       VB->NdcPtr = NULL;
00133       _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
00134                                             NULL,
00135                                             store->clipmask,
00136                                             &store->ormask,
00137                                             &store->andmask );
00138    }
00139 
00140    if (store->andmask) {
00141       /* All vertices are outside the frustum */
00142       return GL_FALSE;
00143    }
00144 
00145    /* Test userclip planes.  This contributes to VB->ClipMask.
00146     */
00148    if (ctx->Transform.ClipPlanesEnabled && (!ctx->VertexProgram._Enabled ||
00149       ctx->VertexProgram.Current->IsPositionInvariant)) {
00150       userclip( ctx,
00151         VB->ClipPtr,
00152         store->clipmask,
00153         &store->ormask,
00154         &store->andmask );
00155 
00156       if (store->andmask) {
00157      return GL_FALSE;
00158       }
00159    }
00160 
00161    VB->ClipAndMask = store->andmask;
00162    VB->ClipOrMask = store->ormask;
00163    VB->ClipMask = store->clipmask;
00164 
00165    return GL_TRUE;
00166 }
00167 
00168 
00175 static void
00176 vp_fetch_texel(GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
00177                GLuint unit, GLfloat color[4])
00178 {
00179    GLchan rgba[4];
00180    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00181 
00182    /* XXX use a float-valued TextureSample routine here!!! */
00183    swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,
00184                                1, (const GLfloat (*)[4]) texcoord,
00185                                &lambda, &rgba);
00186    color[0] = CHAN_TO_FLOAT(rgba[0]);
00187    color[1] = CHAN_TO_FLOAT(rgba[1]);
00188    color[2] = CHAN_TO_FLOAT(rgba[2]);
00189    color[3] = CHAN_TO_FLOAT(rgba[3]);
00190 }
00191 
00192 
00197 void
00198 _tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program)
00199 {
00200    /* No-op.
00201     * If we had derived anything from the program that was private to this
00202     * stage we'd recompute/validate it here.
00203     */
00204 }
00205 
00206 
00210 static void
00211 init_machine(GLcontext *ctx, struct gl_program_machine *machine)
00212 {
00213    /* Input registers get initialized from the current vertex attribs */
00214    MEMCPY(machine->VertAttribs, ctx->Current.Attrib,
00215           MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat));
00216 
00217    if (ctx->VertexProgram._Current->IsNVProgram) {
00218       GLuint i;
00219       /* Output/result regs are initialized to [0,0,0,1] */
00220       for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
00221          ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F);
00222       }
00223       /* Temp regs are initialized to [0,0,0,0] */
00224       for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
00225          ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F);
00226       }
00227       for (i = 0; i < MAX_VERTEX_PROGRAM_ADDRESS_REGS; i++) {
00228          ASSIGN_4V(machine->AddressReg[i], 0, 0, 0, 0);
00229       }
00230    }
00231 
00232    machine->NumDeriv = 0;
00233 
00234    /* init condition codes */
00235    machine->CondCodes[0] = COND_EQ;
00236    machine->CondCodes[1] = COND_EQ;
00237    machine->CondCodes[2] = COND_EQ;
00238    machine->CondCodes[3] = COND_EQ;
00239 
00240    /* init call stack */
00241    machine->StackDepth = 0;
00242 
00243    machine->FetchTexelLod = vp_fetch_texel;
00244    machine->FetchTexelDeriv = NULL; /* not used by vertex programs */
00245 
00246    machine->Samplers = ctx->VertexProgram._Current->Base.SamplerUnits;
00247 }
00248 
00249 
00253 static void
00254 map_textures(GLcontext *ctx, const struct gl_vertex_program *vp)
00255 {
00256    GLuint u;
00257 
00258    if (!ctx->Driver.MapTexture)
00259       return;
00260 
00261    for (u = 0; u < ctx->Const.MaxVertexTextureImageUnits; u++) {
00262       if (vp->Base.TexturesUsed[u]) {
00263          /* Note: _Current *should* correspond to the target indicated
00264           * in TexturesUsed[u].
00265           */
00266          ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[u]._Current);
00267       }
00268    }
00269 }
00270 
00271 
00275 static void
00276 unmap_textures(GLcontext *ctx, const struct gl_vertex_program *vp)
00277 {
00278    GLuint u;
00279 
00280    if (!ctx->Driver.MapTexture)
00281       return;
00282 
00283    for (u = 0; u < ctx->Const.MaxVertexTextureImageUnits; u++) {
00284       if (vp->Base.TexturesUsed[u]) {
00285          /* Note: _Current *should* correspond to the target indicated
00286           * in TexturesUsed[u].
00287           */
00288          ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[u]._Current);
00289       }
00290    }
00291 }
00292 
00293 
00297 static GLboolean
00298 run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
00299 {
00300    TNLcontext *tnl = TNL_CONTEXT(ctx);
00301    struct vp_stage_data *store = VP_STAGE_DATA(stage);
00302    struct vertex_buffer *VB = &tnl->vb;
00303    struct gl_vertex_program *program = ctx->VertexProgram._Current;
00304    struct gl_program_machine machine;
00305    GLuint outputs[VERT_RESULT_MAX], numOutputs;
00306    GLuint i, j;
00307 
00308    if (!program)
00309       return GL_TRUE;
00310 
00311    if (program->IsNVProgram) {
00312       _mesa_load_tracked_matrices(ctx);
00313    }
00314    else {
00315       /* ARB program or vertex shader */
00316       _mesa_load_state_parameters(ctx, program->Base.Parameters);
00317    }
00318 
00319    /* make list of outputs to save some time below */
00320    numOutputs = 0;
00321    for (i = 0; i < VERT_RESULT_MAX; i++) {
00322       if (program->Base.OutputsWritten & (1 << i)) {
00323          outputs[numOutputs++] = i;
00324       }
00325    }
00326 
00327    map_textures(ctx, program);
00328 
00329    for (i = 0; i < VB->Count; i++) {
00330       GLuint attr;
00331 
00332       init_machine(ctx, &machine);
00333 
00334 #if 0
00335       printf("Input  %d: %f, %f, %f, %f\n", i,
00336              VB->AttribPtr[0]->data[i][0],
00337              VB->AttribPtr[0]->data[i][1],
00338              VB->AttribPtr[0]->data[i][2],
00339              VB->AttribPtr[0]->data[i][3]);
00340       printf("   color: %f, %f, %f, %f\n",
00341              VB->AttribPtr[3]->data[i][0],
00342              VB->AttribPtr[3]->data[i][1],
00343              VB->AttribPtr[3]->data[i][2],
00344              VB->AttribPtr[3]->data[i][3]);
00345       printf("  normal: %f, %f, %f, %f\n",
00346              VB->AttribPtr[2]->data[i][0],
00347              VB->AttribPtr[2]->data[i][1],
00348              VB->AttribPtr[2]->data[i][2],
00349              VB->AttribPtr[2]->data[i][3]);
00350 #endif
00351 
00352       /* the vertex array case */
00353       for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
00354      if (program->Base.InputsRead & (1 << attr)) {
00355         const GLubyte *ptr = (const GLubyte*) VB->AttribPtr[attr]->data;
00356         const GLuint size = VB->AttribPtr[attr]->size;
00357         const GLuint stride = VB->AttribPtr[attr]->stride;
00358         const GLfloat *data = (GLfloat *) (ptr + stride * i);
00359         COPY_CLEAN_4V(machine.VertAttribs[attr], size, data);
00360      }
00361       }
00362 
00363       /* execute the program */
00364       _mesa_execute_program(ctx, &program->Base, &machine);
00365 
00366       /* copy the output registers into the VB->attribs arrays */
00367       for (j = 0; j < numOutputs; j++) {
00368          const GLuint attr = outputs[j];
00369          COPY_4V(store->results[attr].data[i], machine.Outputs[attr]);
00370       }
00371 #if 0
00372       printf("HPOS: %f %f %f %f\n",
00373              machine.Outputs[0][0], 
00374              machine.Outputs[0][1], 
00375              machine.Outputs[0][2], 
00376              machine.Outputs[0][3]);
00377 #endif
00378    }
00379 
00380    unmap_textures(ctx, program);
00381 
00382    /* Fixup fog and point size results if needed */
00383    if (program->IsNVProgram) {
00384       if (ctx->Fog.Enabled &&
00385           (program->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) {
00386          for (i = 0; i < VB->Count; i++) {
00387             store->results[VERT_RESULT_FOGC].data[i][0] = 1.0;
00388          }
00389       }
00390 
00391       if (ctx->VertexProgram.PointSizeEnabled &&
00392           (program->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) {
00393          for (i = 0; i < VB->Count; i++) {
00394             store->results[VERT_RESULT_PSIZ].data[i][0] = ctx->Point.Size;
00395          }
00396       }
00397    }
00398 
00399    if (program->IsPositionInvariant) {
00400       /* We need the exact same transform as in the fixed function path here
00401        * to guarantee invariance, depending on compiler optimization flags
00402        * results could be different otherwise.
00403        */
00404       VB->ClipPtr = TransformRaw( &store->results[0],
00405                   &ctx->_ModelProjectMatrix,
00406                   VB->AttribPtr[0] );
00407 
00408       /* Drivers expect this to be clean to element 4...
00409        */
00410       switch (VB->ClipPtr->size) {
00411       case 1:
00412      /* impossible */
00413       case 2:
00414      _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
00415      /* fall-through */
00416       case 3:
00417      _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
00418      /* fall-through */
00419       case 4:
00420      break;
00421       }
00422    }
00423    else {
00424       /* Setup the VB pointers so that the next pipeline stages get
00425        * their data from the right place (the program output arrays).
00426        */
00427       VB->ClipPtr = &store->results[VERT_RESULT_HPOS];
00428       VB->ClipPtr->size = 4;
00429       VB->ClipPtr->count = VB->Count;
00430    }
00431 
00432    VB->ColorPtr[0] = &store->results[VERT_RESULT_COL0];
00433    VB->ColorPtr[1] = &store->results[VERT_RESULT_BFC0];
00434    VB->SecondaryColorPtr[0] = &store->results[VERT_RESULT_COL1];
00435    VB->SecondaryColorPtr[1] = &store->results[VERT_RESULT_BFC1];
00436    VB->FogCoordPtr = &store->results[VERT_RESULT_FOGC];
00437 
00438    VB->AttribPtr[VERT_ATTRIB_COLOR0] = &store->results[VERT_RESULT_COL0];
00439    VB->AttribPtr[VERT_ATTRIB_COLOR1] = &store->results[VERT_RESULT_COL1];
00440    VB->AttribPtr[VERT_ATTRIB_FOG] = &store->results[VERT_RESULT_FOGC];
00441    VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->results[VERT_RESULT_PSIZ];
00442 
00443    for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
00444       VB->TexCoordPtr[i] = 
00445       VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]
00446          = &store->results[VERT_RESULT_TEX0 + i];
00447    }
00448 
00449    for (i = 0; i < ctx->Const.MaxVarying; i++) {
00450       if (program->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) {
00451          /* Note: varying results get put into the generic attributes */
00452      VB->AttribPtr[VERT_ATTRIB_GENERIC0+i]
00453             = &store->results[VERT_RESULT_VAR0 + i];
00454       }
00455    }
00456 
00457 
00458    /* Perform NDC and cliptest operations:
00459     */
00460    return do_ndc_cliptest(ctx, store);
00461 }
00462 
00463 
00468 static GLboolean
00469 init_vp(GLcontext *ctx, struct tnl_pipeline_stage *stage)
00470 {
00471    TNLcontext *tnl = TNL_CONTEXT(ctx);
00472    struct vertex_buffer *VB = &(tnl->vb);
00473    struct vp_stage_data *store;
00474    const GLuint size = VB->Size;
00475    GLuint i;
00476 
00477    stage->privatePtr = MALLOC(sizeof(*store));
00478    store = VP_STAGE_DATA(stage);
00479    if (!store)
00480       return GL_FALSE;
00481 
00482    /* Allocate arrays of vertex output values */
00483    for (i = 0; i < VERT_RESULT_MAX; i++) {
00484       _mesa_vector4f_alloc( &store->results[i], 0, size, 32 );
00485       store->results[i].size = 4;
00486    }
00487 
00488    /* a few other misc allocations */
00489    _mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 );
00490    store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
00491 
00492    return GL_TRUE;
00493 }
00494 
00495 
00499 static void
00500 dtr(struct tnl_pipeline_stage *stage)
00501 {
00502    struct vp_stage_data *store = VP_STAGE_DATA(stage);
00503 
00504    if (store) {
00505       GLuint i;
00506 
00507       /* free the vertex program result arrays */
00508       for (i = 0; i < VERT_RESULT_MAX; i++)
00509          _mesa_vector4f_free( &store->results[i] );
00510 
00511       /* free misc arrays */
00512       _mesa_vector4f_free( &store->ndcCoords );
00513       ALIGN_FREE( store->clipmask );
00514 
00515       FREE( store );
00516       stage->privatePtr = NULL;
00517    }
00518 }
00519 
00520 
00521 static void
00522 validate_vp_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
00523 {
00524    if (ctx->VertexProgram._Current) {
00525       _swrast_update_texture_samplers(ctx);
00526    }
00527 }
00528 
00529 
00530 
00534 const struct tnl_pipeline_stage _tnl_vertex_program_stage =
00535 {
00536    "vertex-program",
00537    NULL,            /* private_data */
00538    init_vp,         /* create */
00539    dtr,             /* destroy */
00540    validate_vp_stage,       /* validate */
00541    run_vp           /* run -- initially set to ctr */
00542 };

Generated on Sun May 27 2012 04:20:46 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.