home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / pipeline.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  18KB  |  639 lines

  1. /* $Id: pipeline.c,v 1.11.2.3 1999/12/12 18:47:35 keithw Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. /* Dynamic pipelines, support for CVA.
  28.  * Copyright (C) 1999 Keith Whitwell.
  29.  */
  30.  
  31. #ifndef XFree86Server
  32. #include <stdio.h>
  33. #else
  34. #include "GL/xf86glx.h"
  35. #endif
  36. #include "bbox.h"
  37. #include "clip.h"
  38. #include "context.h"
  39. #include "cva.h"
  40. #include "pipeline.h"
  41. #include "vbcull.h"
  42. #include "vbindirect.h"
  43. #include "vbrender.h"
  44. #include "vbxform.h"
  45. #include "fog.h"
  46. #include "light.h"
  47. #include "mmath.h"
  48. #include "shade.h"
  49. #include "stages.h"
  50. #include "types.h"
  51. #include "translate.h"
  52. #include "xform.h"
  53.  
  54. #ifndef MESA_VERBOSE
  55. int MESA_VERBOSE = 0 
  56. /*                 | VERBOSE_PIPELINE */
  57. /*                 | VERBOSE_IMMEDIATE */
  58. /*                 | VERBOSE_VARRAY */
  59. /*                 | VERBOSE_TEXTURE */
  60. /*                 | VERBOSE_API */
  61. /*                 | VERBOSE_DRIVER */
  62. /*                 | VERBOSE_STATE */
  63. /*                 | VERBOSE_CULL */
  64. /*                 | VERBOSE_DISPLAY_LIST */
  65. /*                 | VERBOSE_LIGHTING */
  66. ;
  67. #endif
  68.  
  69. #ifndef MESA_DEBUG_FLAGS
  70. int MESA_DEBUG_FLAGS = 0 
  71. /*                 | DEBUG_ALWAYS_FLUSH */
  72. ;
  73. #endif
  74.  
  75.  
  76.  
  77. void gl_print_pipe_ops( const char *msg, GLuint flags )
  78. {
  79.    fprintf(stderr, 
  80.        "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s\n",
  81.        msg,
  82.        flags,
  83.        (flags & PIPE_OP_CVA_PREPARE)   ? "cva-prepare, " : "",
  84.        (flags & PIPE_OP_VERT_XFORM)    ? "vert-xform, " : "",
  85.        (flags & PIPE_OP_NORM_XFORM)    ? "norm-xform, " : "",
  86.        (flags & PIPE_OP_LIGHT)         ? "light, " : "",
  87.        (flags & PIPE_OP_FOG)           ? "fog, " : "",
  88.        (flags & PIPE_OP_TEX0)          ? "tex-0, " : "",
  89.        (flags & PIPE_OP_TEX1)          ? "tex-1, " : "",
  90.        (flags & PIPE_OP_RAST_SETUP_0)  ? "rast-0, " : "",
  91.        (flags & PIPE_OP_RAST_SETUP_1)  ? "rast-1, " : "",
  92.        (flags & PIPE_OP_RENDER)        ? "render, " : "");
  93.  
  94. }
  95.  
  96.  
  97.  
  98. /* Have to reset only those parts of the vb which are being recalculated.
  99.  */
  100. void gl_reset_cva_vb( struct vertex_buffer *VB, GLuint stages )
  101. {
  102.    GLcontext *ctx = VB->ctx;
  103.  
  104.    if (MESA_VERBOSE&VERBOSE_PIPELINE)
  105.       gl_print_pipe_ops( "reset cva vb", stages ); 
  106.  
  107.    if (ctx->Driver.ResetCvaVB)
  108.       ctx->Driver.ResetCvaVB( VB, stages );
  109.  
  110.    if (stages & PIPE_OP_VERT_XFORM) 
  111.    {
  112.       if (VB->ClipOrMask & CLIP_USER_BIT)
  113.      MEMSET(VB->UserClipMask, 0, VB->Count);
  114.  
  115.       VB->ClipOrMask = 0;
  116.       VB->ClipAndMask = CLIP_ALL_BITS;
  117.       VB->CullMode = 0;
  118.       VB->CullFlag[0] = VB->CullFlag[1] = 0;
  119.       VB->Culled = 0;
  120.    }
  121.  
  122.    if (stages & PIPE_OP_NORM_XFORM) {
  123.       VB->NormalPtr = &ctx->CVA.v.Normal;
  124.    }
  125.  
  126.    if (stages & PIPE_OP_LIGHT) 
  127.    {
  128.       VB->ColorPtr = VB->Color[0] = VB->Color[1] = &ctx->CVA.v.Color;
  129.       VB->IndexPtr = VB->Index[0] = VB->Index[1] = &ctx->CVA.v.Index;
  130.    }
  131.    else if (stages & PIPE_OP_FOG) 
  132.    {
  133.       if (ctx->Light.Enabled) {
  134.      VB->Color[0] = VB->LitColor[0];
  135.      VB->Color[1] = VB->LitColor[1];      
  136.      VB->Index[0] = VB->LitIndex[0];
  137.      VB->Index[1] = VB->LitIndex[1];      
  138.       } else {
  139.      VB->Color[0] = VB->Color[1] = &ctx->CVA.v.Color;
  140.      VB->Index[0] = VB->Index[1] = &ctx->CVA.v.Index;
  141.       }
  142.       VB->ColorPtr = VB->Color[0];
  143.       VB->IndexPtr = VB->Index[0];
  144.    }
  145. }
  146.  
  147.  
  148.  
  149.  
  150. static const char *pipeline_name[3] = {
  151.    0,
  152.    "Immediate",
  153.    "CVA Precalc",
  154. };
  155.  
  156.  
  157.  
  158. static void pipeline_ctr( struct gl_pipeline *p, GLcontext *ctx, GLuint type )
  159. {
  160.    GLuint i;
  161.    (void) ctx;
  162.  
  163.    p->state_change = 0;
  164.    p->cva_state_change = 0;
  165.    p->inputs = 0;
  166.    p->outputs = 0;
  167.    p->type = type;
  168.    p->ops = 0;
  169.  
  170.    for (i = 0 ; i < gl_default_nr_stages ; i++) 
  171.       p->state_change |= gl_default_pipeline[i].state_change;
  172. }
  173.  
  174.  
  175. void gl_pipeline_init( GLcontext *ctx )
  176. {
  177.    if (ctx->Driver.RegisterPipelineStages)
  178.       ctx->NrPipelineStages = 
  179.      ctx->Driver.RegisterPipelineStages( ctx->PipelineStage,
  180.                          gl_default_pipeline,
  181.                          gl_default_nr_stages );
  182.    else 
  183.    {
  184.       MEMCPY( ctx->PipelineStage, 
  185.           gl_default_pipeline, 
  186.           sizeof(*gl_default_pipeline) * gl_default_nr_stages );
  187.  
  188.       ctx->NrPipelineStages = gl_default_nr_stages;
  189.    }
  190.  
  191.    pipeline_ctr( &ctx->CVA.elt, ctx, PIPE_IMMEDIATE);
  192.    pipeline_ctr( &ctx->CVA.pre, ctx, PIPE_PRECALC );
  193. }
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. #define MINIMAL_VERT_DATA (VERT_DATA&~(VERT_TEX0_4|VERT_TEX1_4|VERT_EVAL_ANY))
  201.  
  202. #define VERT_CURRENT_DATA (VERT_TEX0_1234|VERT_TEX1_1234|VERT_RGBA| \
  203.                VERT_INDEX|VERT_EDGE|VERT_NORM| \
  204.                        VERT_MATERIAL)
  205.  
  206. /* Called prior to every recomputation of the CVA precalc data, except where
  207.  * the driver is able to calculate the pipeline unassisted.
  208.  */
  209. void gl_build_full_precalc_pipeline( GLcontext *ctx )
  210. {
  211.    struct gl_pipeline_stage *pipeline = ctx->PipelineStage;
  212.    struct gl_cva *cva = &ctx->CVA;
  213.    struct gl_pipeline *pre = &cva->pre;   
  214.    struct gl_pipeline_stage **stages = pre->stages;
  215.    GLuint i;
  216.    GLuint newstate = pre->new_state;
  217.    GLuint changed_ops = 0;
  218.    GLuint oldoutputs = pre->outputs;
  219.    GLuint oldinputs = pre->inputs;
  220.    GLuint fallback = (VERT_CURRENT_DATA & ctx->Current.Flag & 
  221.               ~ctx->Array.Summary);
  222.    GLuint changed_outputs = (ctx->Array.NewArrayState | 
  223.                  (fallback & cva->orflag));
  224.    GLuint available = fallback | ctx->Array.Flags;
  225.  
  226.    pre->cva_state_change = 0;
  227.    pre->ops = 0;
  228.    pre->outputs = 0;
  229.    pre->inputs = 0;
  230.    pre->forbidden_inputs = 0;
  231.    pre->fallback = 0;
  232.    
  233.    if (ctx->Array.Summary & VERT_ELT) 
  234.       cva->orflag &= VERT_MATERIAL;
  235.   
  236.    cva->orflag &= ~(ctx->Array.Summary & ~VERT_OBJ_ANY);
  237.    available &= ~cva->orflag;
  238.    
  239.    pre->outputs = available;
  240.    pre->inputs = available;
  241.  
  242.    if (MESA_VERBOSE & VERBOSE_PIPELINE) {
  243.       fprintf(stderr, ": Rebuild pipeline\n");
  244.       gl_print_vert_flags("orflag", cva->orflag);
  245.    }
  246.       
  247.    
  248.  
  249.    /* If something changes in the pipeline, tag all subsequent stages
  250.     * using this value for recalcuation.  Also used to build the full
  251.     * pipeline by setting newstate and newinputs to ~0.
  252.     *
  253.     * Because all intermediate values are buffered, the new inputs
  254.     * are enough to fully specify what needs to be calculated, and a
  255.     * single pass identifies all stages requiring recalculation.
  256.     */
  257.    for (i = 0 ; i < ctx->NrPipelineStages ; i++) 
  258.    {
  259.       pipeline[i].check(ctx, &pipeline[i]);
  260.  
  261.       if (pipeline[i].type & PIPE_PRECALC) 
  262.       {
  263.      if ((newstate & pipeline[i].cva_state_change) ||
  264.          (changed_outputs & pipeline[i].inputs) ||
  265.          !pipeline[i].inputs)
  266.      {        
  267.         changed_ops |= pipeline[i].ops;
  268.         changed_outputs |= pipeline[i].outputs;
  269.         pipeline[i].active &= ~PIPE_PRECALC;
  270.  
  271.         if ((pipeline[i].inputs & ~available) == 0 &&
  272.         (pipeline[i].ops & pre->ops) == 0)
  273.         {
  274.            pipeline[i].active |= PIPE_PRECALC;
  275.            *stages++ = &pipeline[i];
  276.         } 
  277.      }
  278.       
  279.      /* Incompatible with multiple stages structs implementing
  280.       * the same stage.
  281.       */
  282.      available &= ~pipeline[i].outputs;
  283.      pre->outputs &= ~pipeline[i].outputs;
  284.  
  285.      if (pipeline[i].active & PIPE_PRECALC) {
  286.         pre->ops |= pipeline[i].ops;
  287.         pre->outputs |= pipeline[i].outputs;
  288.         available |= pipeline[i].outputs;
  289.         pre->forbidden_inputs |= pipeline[i].pre_forbidden_inputs;
  290.      }
  291.       } 
  292.       else if (pipeline[i].active & PIPE_PRECALC) 
  293.       {
  294.      pipeline[i].active &= ~PIPE_PRECALC;
  295.      changed_outputs |= pipeline[i].outputs;
  296.      changed_ops |= pipeline[i].ops;
  297.       }
  298.    }
  299.  
  300.    *stages = 0;
  301.  
  302.    pre->new_outputs = pre->outputs & (changed_outputs | ~oldoutputs);
  303.    pre->new_inputs = pre->inputs & ~oldinputs;
  304.    pre->fallback = pre->inputs & fallback;
  305.    pre->forbidden_inputs |= pre->inputs & fallback;
  306.  
  307.    pre->changed_ops = changed_ops;
  308.  
  309.    if (ctx->Driver.OptimizePrecalcPipeline)
  310.       ctx->Driver.OptimizePrecalcPipeline( ctx, pre );
  311. }
  312.  
  313. void gl_build_precalc_pipeline( GLcontext *ctx )
  314. {
  315.    struct gl_pipeline *pre = &ctx->CVA.pre;   
  316.    struct gl_pipeline *elt = &ctx->CVA.elt;   
  317.  
  318.    if (!ctx->Driver.BuildPrecalcPipeline ||
  319.        !ctx->Driver.BuildPrecalcPipeline( ctx ))
  320.       gl_build_full_precalc_pipeline( ctx );
  321.  
  322.    pre->data_valid = 0;
  323.    pre->pipeline_valid = 1;
  324.    elt->pipeline_valid = 0;
  325.    
  326.    ctx->CVA.orflag = 0;
  327.    
  328.    if (MESA_VERBOSE&VERBOSE_PIPELINE)
  329.       gl_print_pipeline( ctx, pre ); 
  330. }
  331.  
  332.  
  333. static void gl_build_full_immediate_pipeline( GLcontext *ctx )
  334. {
  335.    struct gl_pipeline_stage *pipeline = ctx->PipelineStage;
  336.    struct gl_cva *cva = &ctx->CVA;
  337.    struct gl_pipeline *pre = &cva->pre;   
  338.    struct gl_pipeline *elt = &cva->elt;
  339.    struct gl_pipeline_stage **stages = elt->stages;
  340.    GLuint i;
  341.    GLuint newstate = elt->new_state;
  342.    GLuint active_ops = 0;
  343.    GLuint available = cva->orflag | MINIMAL_VERT_DATA;
  344.    GLuint generated = 0;
  345.    GLuint is_elt = 0;
  346.  
  347.    if (pre->data_valid && ctx->CompileCVAFlag) {
  348.       is_elt = 1;
  349.       active_ops = cva->pre.ops;
  350.       available |= pre->outputs | VERT_PRECALC_DATA;
  351.    }
  352.  
  353.  
  354.    elt->outputs = 0;        /* not used */
  355.    elt->inputs = 0;
  356.  
  357.    for (i = 0 ; i < ctx->NrPipelineStages ; i++) {
  358.       pipeline[i].active &= ~PIPE_IMMEDIATE;
  359.  
  360.       if ((pipeline[i].state_change & newstate) ||
  361.         (pipeline[i].elt_forbidden_inputs & available)) 
  362.       {
  363.      pipeline[i].check(ctx, &pipeline[i]);
  364.       }
  365.  
  366.       if ((pipeline[i].type & PIPE_IMMEDIATE) &&
  367.       (pipeline[i].ops & active_ops) == 0 && 
  368.       (pipeline[i].elt_forbidden_inputs & available) == 0
  369.      )
  370.       {
  371.      if (pipeline[i].inputs & ~available) 
  372.         elt->forbidden_inputs |= pipeline[i].inputs & ~available;
  373.      else
  374.      {
  375.         elt->inputs |= pipeline[i].inputs & ~generated;
  376.         elt->forbidden_inputs |= pipeline[i].elt_forbidden_inputs;
  377.         pipeline[i].active |= PIPE_IMMEDIATE;
  378.         *stages++ = &pipeline[i];
  379.         generated |= pipeline[i].outputs;
  380.         available |= pipeline[i].outputs;
  381.         active_ops |= pipeline[i].ops;
  382.      }
  383.       }
  384.    }
  385.  
  386.    *stages = 0;
  387.    
  388.    elt->copy_transformed_data = 1;
  389.    elt->replay_copied_vertices = 0;
  390.  
  391.    if (is_elt) {
  392.       cva->merge = elt->inputs & pre->outputs;
  393.       elt->ops = active_ops & ~pre->ops;
  394.    }
  395. }
  396.  
  397.  
  398.  
  399. void gl_build_immediate_pipeline( GLcontext *ctx )
  400. {
  401.    struct gl_pipeline *elt = &ctx->CVA.elt;   
  402.  
  403.    if (!ctx->Driver.BuildEltPipeline ||
  404.        !ctx->Driver.BuildEltPipeline( ctx )) {
  405.       gl_build_full_immediate_pipeline( ctx );
  406.    }
  407.  
  408.    elt->pipeline_valid = 1;
  409.    ctx->CVA.orflag = 0;
  410.    
  411.    if (MESA_VERBOSE&VERBOSE_PIPELINE)
  412.       gl_print_pipeline( ctx, elt ); 
  413. }
  414.    
  415. #define INTERESTED ~(NEW_DRIVER_STATE|NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE)
  416.  
  417. void gl_update_pipelines( GLcontext *ctx )
  418. {
  419.    GLuint newstate = ctx->NewState;
  420.    struct gl_cva *cva = &ctx->CVA;
  421.  
  422.    newstate &= INTERESTED;
  423.  
  424.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_STATE))
  425.       gl_print_enable_flags("enabled", ctx->Enabled);
  426.  
  427.    if (newstate ||
  428.        cva->lock_changed ||
  429.        cva->orflag != cva->last_orflag ||
  430.        ctx->Array.Flags != cva->last_array_flags)
  431.    {   
  432.       GLuint flags = VERT_WIN;
  433.  
  434.       if (ctx->Visual->RGBAflag) 
  435.      flags |= VERT_RGBA;
  436.       else 
  437.      flags |= VERT_INDEX;
  438.  
  439.       if (ctx->Texture.Enabled & 0xf) {
  440.      if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
  441.         flags &= ~VERT_RGBA;
  442.  
  443.      flags |= VERT_TEX0_ANY;
  444.       }
  445.  
  446.       if (ctx->Texture.Enabled & 0xf0)
  447.      flags |= VERT_TEX1_ANY;
  448.    
  449.       if (ctx->Polygon.Unfilled) 
  450.      flags |= VERT_EDGE;
  451.  
  452.       if (ctx->RenderMode==GL_FEEDBACK) 
  453.       {
  454.      flags = (VERT_WIN|VERT_RGBA|VERT_INDEX|
  455.           VERT_NORM|VERT_EDGE|
  456.           VERT_TEX0_ANY|VERT_TEX1_ANY);
  457.       }
  458.  
  459.       ctx->RenderFlags = flags;
  460.  
  461.       cva->elt.new_state |= newstate;
  462.       cva->elt.pipeline_valid = 0;
  463.  
  464.       cva->pre.new_state |= newstate;
  465.       cva->pre.forbidden_inputs = 0;
  466.       cva->pre.pipeline_valid = 0;
  467.       cva->lock_changed = 0;
  468.    }
  469.  
  470.    if (ctx->Array.NewArrayState != cva->last_array_new_state)
  471.       cva->pre.pipeline_valid = 0;
  472.  
  473.    cva->pre.data_valid = 0;
  474.    cva->last_array_new_state = ctx->Array.NewArrayState;
  475.    cva->last_orflag = cva->orflag;
  476.    cva->last_array_flags = ctx->Array.Flags;
  477. }
  478.  
  479. void gl_run_pipeline( struct vertex_buffer *VB )
  480. {
  481.    struct gl_pipeline *pipe = VB->pipeline;
  482.    struct gl_pipeline_stage **stages = pipe->stages;
  483.    short x;
  484.    
  485.    pipe->data_valid = 1;    /* optimized stages might want to reset this. */
  486.  
  487.    START_FAST_MATH(x);
  488.    
  489.    for ( VB->Culled = 0; *stages && !VB->Culled ; stages++ ) 
  490.       (*stages)->run( VB );
  491.       
  492.    END_FAST_MATH(x);
  493.  
  494.    pipe->new_state = 0;
  495. }
  496.  
  497. void gl_print_vert_flags( const char *name, GLuint flags ) 
  498. {
  499.    fprintf(stderr, 
  500.        "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
  501.        name,
  502.        flags,
  503.        (flags & VERT_OBJ_ANY)    ? "vertices (obj), " : "",
  504.        (flags & VERT_ELT)        ? "array-elt, " : "",
  505.        (flags & VERT_RGBA)       ? "colors, " : "",
  506.        (flags & VERT_NORM)       ? "normals, " : "",
  507.        (flags & VERT_INDEX)      ? "index, " : "",
  508.        (flags & VERT_EDGE)       ? "edgeflag, " : "",
  509.        (flags & VERT_MATERIAL)   ? "material, " : "",
  510.        (flags & VERT_TEX0_ANY)   ? "texcoord0, " : "",
  511.        (flags & VERT_TEX1_ANY)   ? "texcoord1, " : "",
  512.        (flags & VERT_EVAL_ANY)   ? "eval-coord, " : "",
  513.        (flags & VERT_EYE)        ? "eye, " : "",
  514.        (flags & VERT_WIN)        ? "win, " : "",
  515.        (flags & VERT_PRECALC_DATA) ? "precalc data, " : "",
  516.        (flags & VERT_SETUP_FULL) ? "driver-data, " : "", 
  517.        (flags & VERT_SETUP_PART) ? "partial-driver-data, " : ""
  518.       );
  519. }
  520.  
  521. void gl_print_tri_caps( const char *name, GLuint flags ) 
  522. {
  523.    fprintf(stderr, 
  524.        "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
  525.        name,
  526.        flags,
  527.        (flags & DD_FEEDBACK)            ? "feedback, " : "",
  528.        (flags & DD_SELECT)              ? "select, " : "",
  529.        (flags & DD_FLATSHADE)           ? "flat-shade, " : "",
  530.        (flags & DD_MULTIDRAW)           ? "multidraw, " : "",
  531.        (flags & DD_SEPERATE_SPECULAR)   ? "seperate-specular, " : "",
  532.        (flags & DD_TRI_LIGHT_TWOSIDE)   ? "tri-light-twoside, " : "",
  533.        (flags & DD_TRI_UNFILLED)        ? "tri-unfilled, " : "",
  534.        (flags & DD_TRI_STIPPLE)         ? "tri-stipple, " : "",
  535.        (flags & DD_TRI_OFFSET)          ? "tri-offset, " : "",
  536.        (flags & DD_TRI_CULL)            ? "tri-bf-cull, " : "",
  537.        (flags & DD_LINE_SMOOTH)         ? "line-smooth, " : "",
  538.        (flags & DD_LINE_STIPPLE)        ? "line-stipple, " : "",
  539.        (flags & DD_LINE_WIDTH)          ? "line-wide, " : "",
  540.        (flags & DD_POINT_SMOOTH)        ? "point-smooth, " : "", 
  541.        (flags & DD_POINT_SIZE)          ? "point-size, " : "", 
  542.        (flags & DD_POINT_ATTEN)         ? "point-atten, " : "", 
  543.        (flags & DD_LIGHTING_CULL)       ? "lighting-cull, " : "", 
  544.        (flags & DD_POINT_SW_RASTERIZE)  ? "sw-points, " : "", 
  545.        (flags & DD_LINE_SW_RASTERIZE)   ? "sw-lines, " : "", 
  546.        (flags & DD_TRI_SW_RASTERIZE)    ? "sw-tris, " : "", 
  547.        (flags & DD_QUAD_SW_RASTERIZE)   ? "sw-quads, " : "",
  548.        (flags & DD_TRI_CULL_FRONT_BACK) ? "cull-all, " : ""
  549.       );
  550. }
  551.  
  552.  
  553. void gl_print_pipeline( GLcontext *ctx, struct gl_pipeline *p )
  554. {
  555.    struct gl_pipeline_stage *pipeline = ctx->PipelineStage;
  556.    GLuint i;
  557.  
  558.    fprintf(stderr,"Type: %s\n", pipeline_name[p->type]);
  559.  
  560.    if (!p->pipeline_valid) {
  561.       printf("--> Not up to date!!!\n");
  562.       return;
  563.    }
  564.  
  565.    gl_print_vert_flags("Inputs", p->inputs);
  566.    gl_print_vert_flags("Forbidden", p->forbidden_inputs);
  567.    gl_print_vert_flags("Outputs", p->outputs);
  568.  
  569.    if (0) 
  570.       for (i = 0 ; i < ctx->NrPipelineStages ; i++) 
  571.      if (pipeline[i].active & p->type) {
  572.         fprintf(stderr,"%u: %s\n", i, pipeline[i].name);
  573.         
  574.         gl_print_vert_flags("\tinputs", pipeline[i].inputs);
  575.         gl_print_vert_flags("\toutputs", pipeline[i].outputs);
  576.         
  577.         if (p->type == PIPE_PRECALC && pipeline[i].pre_forbidden_inputs)
  578.            gl_print_vert_flags("\tforbidden", 
  579.                    pipeline[i].pre_forbidden_inputs);
  580.  
  581.         if (p->type == PIPE_IMMEDIATE && pipeline[i].elt_forbidden_inputs)
  582.            gl_print_vert_flags("\tforbidden", 
  583.                    pipeline[i].elt_forbidden_inputs);
  584.  
  585.      }
  586.  
  587.  
  588.    if (1) {
  589.       struct gl_pipeline_stage **stages = p->stages;
  590.       fprintf(stderr,"\nStages requiring precalculation:\n");
  591.       for ( i=0 ; stages[i] ; i++) {
  592.      fprintf(stderr, "%u: %s\n", i, stages[i]->name);
  593.      gl_print_vert_flags("\tinputs", stages[i]->inputs);
  594.      gl_print_vert_flags("\toutputs", stages[i]->outputs);
  595.      if (p->type == PIPE_PRECALC && pipeline[i].pre_forbidden_inputs)
  596.         gl_print_vert_flags("\tforbidden", 
  597.                 pipeline[i].pre_forbidden_inputs);
  598.  
  599.      if (p->type == PIPE_IMMEDIATE && pipeline[i].elt_forbidden_inputs)
  600.         gl_print_vert_flags("\tforbidden", 
  601.                 pipeline[i].elt_forbidden_inputs);
  602.       }
  603.    }
  604. }
  605.  
  606.  
  607.  
  608. void gl_print_active_pipeline( GLcontext *ctx, struct gl_pipeline *p )
  609. {
  610.    struct gl_pipeline_stage **stages = p->stages;
  611.    GLuint i;
  612.  
  613.    (void) ctx;
  614.  
  615.    fprintf(stderr,"Type: %s\n", pipeline_name[p->type]);
  616.  
  617.    if (!p->pipeline_valid) {
  618.       printf("--> Not up to date!!!\n");
  619.       return;
  620.    }
  621.  
  622.    gl_print_vert_flags("Inputs", p->inputs);
  623.    gl_print_vert_flags("Forbidden", p->forbidden_inputs);
  624.    gl_print_vert_flags("Outputs", p->outputs);
  625.  
  626.    for ( i=0 ; stages[i] ; i++) {
  627.       fprintf(stderr, "%u: %s\n", i, stages[i]->name);
  628.  
  629.       gl_print_vert_flags("\tinputs", stages[i]->inputs);
  630.       gl_print_vert_flags("\toutputs", stages[i]->outputs);
  631.  
  632.       if (p->type == PIPE_PRECALC && stages[i]->pre_forbidden_inputs)
  633.         gl_print_vert_flags("\tforbidden", 
  634.                 stages[i]->pre_forbidden_inputs);
  635.       }
  636. }
  637.  
  638.  
  639.