Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /**
  27.  * \file state.c
  28.  * State management.
  29.  *
  30.  * This file manages recalculation of derived values in struct gl_context.
  31.  */
  32.  
  33.  
  34. #include "glheader.h"
  35. #include "mtypes.h"
  36. #include "arrayobj.h"
  37. #include "context.h"
  38. #include "debug.h"
  39. #include "macros.h"
  40. #include "ffvertex_prog.h"
  41. #include "framebuffer.h"
  42. #include "light.h"
  43. #include "matrix.h"
  44. #include "pixel.h"
  45. #include "program/program.h"
  46. #include "program/prog_parameter.h"
  47. #include "shaderobj.h"
  48. #include "state.h"
  49. #include "stencil.h"
  50. #include "texenvprogram.h"
  51. #include "texobj.h"
  52. #include "texstate.h"
  53. #include "varray.h"
  54. #include "blend.h"
  55.  
  56.  
  57. /**
  58.  * Update the following fields:
  59.  *   ctx->VertexProgram._Enabled
  60.  *   ctx->FragmentProgram._Enabled
  61.  *   ctx->ATIFragmentShader._Enabled
  62.  * This needs to be done before texture state validation.
  63.  */
  64. static void
  65. update_program_enables(struct gl_context *ctx)
  66. {
  67.    /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment
  68.     * program is enabled AND valid.  Similarly for ATI fragment shaders.
  69.     * GLSL shaders not relevant here.
  70.     */
  71.    ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
  72.       && ctx->VertexProgram.Current->Base.Instructions;
  73.    ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
  74.       && ctx->FragmentProgram.Current->Base.Instructions;
  75.    ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
  76.       && ctx->ATIFragmentShader.Current->Instructions[0];
  77. }
  78.  
  79.  
  80. /**
  81.  * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point
  82.  * to the current/active programs.  Then call ctx->Driver.BindProgram() to
  83.  * tell the driver which programs to use.
  84.  *
  85.  * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
  86.  * programs or programs derived from fixed-function state.
  87.  *
  88.  * This function needs to be called after texture state validation in case
  89.  * we're generating a fragment program from fixed-function texture state.
  90.  *
  91.  * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
  92.  * or fragment program is being used.
  93.  */
  94. static GLbitfield
  95. update_program(struct gl_context *ctx)
  96. {
  97.    const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram;
  98.    const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram;
  99.    struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram;
  100.    const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
  101.    const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
  102.    const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
  103.    GLbitfield new_state = 0x0;
  104.  
  105.    /*
  106.     * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
  107.     * pointers to the programs that should be used for rendering.  If either
  108.     * is NULL, use fixed-function code paths.
  109.     *
  110.     * These programs may come from several sources.  The priority is as
  111.     * follows:
  112.     *   1. OpenGL 2.0/ARB vertex/fragment shaders
  113.     *   2. ARB/NV vertex/fragment programs
  114.     *   3. Programs derived from fixed-function state.
  115.     *
  116.     * Note: it's possible for a vertex shader to get used with a fragment
  117.     * program (and vice versa) here, but in practice that shouldn't ever
  118.     * come up, or matter.
  119.     */
  120.  
  121.    if (fsProg && fsProg->LinkStatus
  122.        && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
  123.       /* Use GLSL fragment shader */
  124.       _mesa_reference_shader_program(ctx,
  125.                                      &ctx->Shader._CurrentFragmentProgram,
  126.                                      fsProg);
  127.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
  128.                                gl_fragment_program(fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
  129.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
  130.                                NULL);
  131.    }
  132.    else if (ctx->FragmentProgram._Enabled) {
  133.       /* Use user-defined fragment program */
  134.       _mesa_reference_shader_program(ctx,
  135.                                      &ctx->Shader._CurrentFragmentProgram,
  136.                                      NULL);
  137.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
  138.                                ctx->FragmentProgram.Current);
  139.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
  140.                                NULL);
  141.    }
  142.    else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
  143.       /* Use fragment program generated from fixed-function state */
  144.       struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx);
  145.  
  146.       _mesa_reference_shader_program(ctx,
  147.                                      &ctx->Shader._CurrentFragmentProgram,
  148.                                      f);
  149.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
  150.                                gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
  151.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
  152.                                gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
  153.    }
  154.    else {
  155.       /* No fragment program */
  156.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
  157.       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
  158.                                NULL);
  159.    }
  160.  
  161.    if (gsProg && gsProg->LinkStatus
  162.        && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) {
  163.       /* Use GLSL geometry shader */
  164.       _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
  165.                                gl_geometry_program(gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program));
  166.    } else {
  167.       /* No geometry program */
  168.       _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
  169.    }
  170.  
  171.    /* Examine vertex program after fragment program as
  172.     * _mesa_get_fixed_func_vertex_program() needs to know active
  173.     * fragprog inputs.
  174.     */
  175.    if (vsProg && vsProg->LinkStatus
  176.        && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) {
  177.       /* Use GLSL vertex shader */
  178.       _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
  179.                                gl_vertex_program(vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program));
  180.    }
  181.    else if (ctx->VertexProgram._Enabled) {
  182.       /* Use user-defined vertex program */
  183.       _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
  184.                                ctx->VertexProgram.Current);
  185.    }
  186.    else if (ctx->VertexProgram._MaintainTnlProgram) {
  187.       /* Use vertex program generated from fixed-function state */
  188.       _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
  189.                                _mesa_get_fixed_func_vertex_program(ctx));
  190.       _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
  191.                                ctx->VertexProgram._Current);
  192.    }
  193.    else {
  194.       /* no vertex program */
  195.       _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
  196.    }
  197.  
  198.    /* Let the driver know what's happening:
  199.     */
  200.    if (ctx->FragmentProgram._Current != prevFP) {
  201.       new_state |= _NEW_PROGRAM;
  202.       if (ctx->Driver.BindProgram) {
  203.          ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
  204.                           (struct gl_program *) ctx->FragmentProgram._Current);
  205.       }
  206.    }
  207.  
  208.    if (ctx->GeometryProgram._Current != prevGP) {
  209.       new_state |= _NEW_PROGRAM;
  210.       if (ctx->Driver.BindProgram) {
  211.          ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM,
  212.                             (struct gl_program *) ctx->GeometryProgram._Current);
  213.       }
  214.    }
  215.  
  216.    if (ctx->VertexProgram._Current != prevVP) {
  217.       new_state |= _NEW_PROGRAM;
  218.       if (ctx->Driver.BindProgram) {
  219.          ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
  220.                             (struct gl_program *) ctx->VertexProgram._Current);
  221.       }
  222.    }
  223.  
  224.    return new_state;
  225. }
  226.  
  227.  
  228. /**
  229.  * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0.
  230.  */
  231. static GLbitfield
  232. update_program_constants(struct gl_context *ctx)
  233. {
  234.    GLbitfield new_state = 0x0;
  235.  
  236.    if (ctx->FragmentProgram._Current) {
  237.       const struct gl_program_parameter_list *params =
  238.          ctx->FragmentProgram._Current->Base.Parameters;
  239.       if (params && params->StateFlags & ctx->NewState) {
  240.          new_state |= _NEW_PROGRAM_CONSTANTS;
  241.       }
  242.    }
  243.  
  244.    if (ctx->GeometryProgram._Current) {
  245.       const struct gl_program_parameter_list *params =
  246.          ctx->GeometryProgram._Current->Base.Parameters;
  247.       /*FIXME: StateFlags is always 0 because we have unnamed constant
  248.        *       not state changes */
  249.       if (params /*&& params->StateFlags & ctx->NewState*/) {
  250.          new_state |= _NEW_PROGRAM_CONSTANTS;
  251.       }
  252.    }
  253.  
  254.    if (ctx->VertexProgram._Current) {
  255.       const struct gl_program_parameter_list *params =
  256.          ctx->VertexProgram._Current->Base.Parameters;
  257.       if (params && params->StateFlags & ctx->NewState) {
  258.          new_state |= _NEW_PROGRAM_CONSTANTS;
  259.       }
  260.    }
  261.  
  262.    return new_state;
  263. }
  264.  
  265.  
  266.  
  267.  
  268. static void
  269. update_viewport_matrix(struct gl_context *ctx)
  270. {
  271.    const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
  272.  
  273.    ASSERT(depthMax > 0);
  274.  
  275.    /* Compute scale and bias values. This is really driver-specific
  276.     * and should be maintained elsewhere if at all.
  277.     * NOTE: RasterPos uses this.
  278.     */
  279.    _math_matrix_viewport(&ctx->Viewport._WindowMap,
  280.                          ctx->Viewport.X, ctx->Viewport.Y,
  281.                          ctx->Viewport.Width, ctx->Viewport.Height,
  282.                          ctx->Viewport.Near, ctx->Viewport.Far,
  283.                          depthMax);
  284. }
  285.  
  286.  
  287. /**
  288.  * Update derived multisample state.
  289.  */
  290. static void
  291. update_multisample(struct gl_context *ctx)
  292. {
  293.    ctx->Multisample._Enabled = GL_FALSE;
  294.    if (ctx->Multisample.Enabled &&
  295.        ctx->DrawBuffer &&
  296.        ctx->DrawBuffer->Visual.sampleBuffers)
  297.       ctx->Multisample._Enabled = GL_TRUE;
  298. }
  299.  
  300.  
  301. /**
  302.  * Update the ctx->VertexProgram._TwoSideEnabled flag.
  303.  */
  304. static void
  305. update_twoside(struct gl_context *ctx)
  306. {
  307.    if (ctx->Shader.CurrentVertexProgram ||
  308.        ctx->VertexProgram._Enabled) {
  309.       ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled;
  310.    } else {
  311.       ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled &&
  312.                                             ctx->Light.Model.TwoSide);
  313.    }
  314. }
  315.  
  316.  
  317. /**
  318.  * Compute derived GL state.
  319.  * If __struct gl_contextRec::NewState is non-zero then this function \b must
  320.  * be called before rendering anything.
  321.  *
  322.  * Calls dd_function_table::UpdateState to perform any internal state
  323.  * management necessary.
  324.  *
  325.  * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
  326.  * _mesa_update_buffer_bounds(),
  327.  * _mesa_update_lighting() and _mesa_update_tnl_spaces().
  328.  */
  329. void
  330. _mesa_update_state_locked( struct gl_context *ctx )
  331. {
  332.    GLbitfield new_state = ctx->NewState;
  333.    GLbitfield prog_flags = _NEW_PROGRAM;
  334.    GLbitfield new_prog_state = 0x0;
  335.  
  336.    if (new_state == _NEW_CURRENT_ATTRIB)
  337.       goto out;
  338.  
  339.    if (MESA_VERBOSE & VERBOSE_STATE)
  340.       _mesa_print_state("_mesa_update_state", new_state);
  341.  
  342.    /* Determine which state flags effect vertex/fragment program state */
  343.    if (ctx->FragmentProgram._MaintainTexEnvProgram) {
  344.       prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG |
  345.                      _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT |
  346.                      _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP |
  347.                      _NEW_COLOR);
  348.    }
  349.    if (ctx->VertexProgram._MaintainTnlProgram) {
  350.       prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE |
  351.                      _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT |
  352.                      _NEW_FOG | _NEW_LIGHT |
  353.                      _MESA_NEW_NEED_EYE_COORDS);
  354.    }
  355.  
  356.    /*
  357.     * Now update derived state info
  358.     */
  359.  
  360.    if (new_state & prog_flags)
  361.       update_program_enables( ctx );
  362.  
  363.    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
  364.       _mesa_update_modelview_project( ctx, new_state );
  365.  
  366.    if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
  367.       _mesa_update_texture( ctx, new_state );
  368.  
  369.    if (new_state & _NEW_BUFFERS)
  370.       _mesa_update_framebuffer(ctx);
  371.  
  372.    if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
  373.       _mesa_update_draw_buffer_bounds( ctx );
  374.  
  375.    if (new_state & _NEW_LIGHT)
  376.       _mesa_update_lighting( ctx );
  377.  
  378.    if (new_state & (_NEW_LIGHT | _NEW_PROGRAM))
  379.       update_twoside( ctx );
  380.  
  381.    if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
  382.       _mesa_update_stencil( ctx );
  383.  
  384.    if (new_state & _NEW_PIXEL)
  385.       _mesa_update_pixel( ctx, new_state );
  386.  
  387.    if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
  388.       update_viewport_matrix(ctx);
  389.  
  390.    if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS))
  391.       update_multisample( ctx );
  392.  
  393.    /* ctx->_NeedEyeCoords is now up to date.
  394.     *
  395.     * If the truth value of this variable has changed, update for the
  396.     * new lighting space and recompute the positions of lights and the
  397.     * normal transform.
  398.     *
  399.     * If the lighting space hasn't changed, may still need to recompute
  400.     * light positions & normal transforms for other reasons.
  401.     */
  402.    if (new_state & _MESA_NEW_NEED_EYE_COORDS)
  403.       _mesa_update_tnl_spaces( ctx, new_state );
  404.  
  405.    if (new_state & prog_flags) {
  406.       /* When we generate programs from fixed-function vertex/fragment state
  407.        * this call may generate/bind a new program.  If so, we need to
  408.        * propogate the _NEW_PROGRAM flag to the driver.
  409.        */
  410.       new_prog_state |= update_program( ctx );
  411.    }
  412.  
  413.    if (ctx->Const.CheckArrayBounds &&
  414.        new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) {
  415.       _mesa_update_array_object_max_element(ctx, ctx->Array.ArrayObj);
  416.    }
  417.  
  418.  out:
  419.    new_prog_state |= update_program_constants(ctx);
  420.  
  421.    /*
  422.     * Give the driver a chance to act upon the new_state flags.
  423.     * The driver might plug in different span functions, for example.
  424.     * Also, this is where the driver can invalidate the state of any
  425.     * active modules (such as swrast_setup, swrast, tnl, etc).
  426.     *
  427.     * Set ctx->NewState to zero to avoid recursion if
  428.     * Driver.UpdateState() has to call FLUSH_VERTICES().  (fixed?)
  429.     */
  430.    new_state = ctx->NewState | new_prog_state;
  431.    ctx->NewState = 0;
  432.  
  433.     printf("call update state\n");
  434.  
  435.    ctx->Driver.UpdateState(ctx, new_state);
  436. }
  437.  
  438.  
  439. /* This is the usual entrypoint for state updates:
  440.  */
  441. void
  442. _mesa_update_state( struct gl_context *ctx )
  443. {
  444.    _mesa_lock_context_textures(ctx);
  445.    _mesa_update_state_locked(ctx);
  446.    _mesa_unlock_context_textures(ctx);
  447. }
  448.  
  449.  
  450.  
  451.  
  452. /**
  453.  * Want to figure out which fragment program inputs are actually
  454.  * constant/current values from ctx->Current.  These should be
  455.  * referenced as a tracked state variable rather than a fragment
  456.  * program input, to save the overhead of putting a constant value in
  457.  * every submitted vertex, transferring it to hardware, interpolating
  458.  * it across the triangle, etc...
  459.  *
  460.  * When there is a VP bound, just use vp->outputs.  But when we're
  461.  * generating vp from fixed function state, basically want to
  462.  * calculate:
  463.  *
  464.  * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) |
  465.  *                 potential_vp_outputs )
  466.  *
  467.  * Where potential_vp_outputs is calculated by looking at enabled
  468.  * texgen, etc.
  469.  *
  470.  * The generated fragment program should then only declare inputs that
  471.  * may vary or otherwise differ from the ctx->Current values.
  472.  * Otherwise, the fp should track them as state values instead.
  473.  */
  474. void
  475. _mesa_set_varying_vp_inputs( struct gl_context *ctx,
  476.                              GLbitfield64 varying_inputs )
  477. {
  478.    if (ctx->varying_vp_inputs != varying_inputs) {
  479.       ctx->varying_vp_inputs = varying_inputs;
  480.  
  481.       /* Only the fixed-func generated programs need to use the flag
  482.        * and the fixed-func fragment program uses it only if there is also
  483.        * a fixed-func vertex program, so this only depends on the latter.
  484.        *
  485.        * It's okay to check the VP pointer here, because this is called after
  486.        * _mesa_update_state in the vbo module. */
  487.       if (ctx->VertexProgram._TnlProgram ||
  488.           ctx->FragmentProgram._TexEnvProgram) {
  489.          ctx->NewState |= _NEW_VARYING_VP_INPUTS;
  490.       }
  491.       /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/
  492.    }
  493. }
  494.  
  495.  
  496. /**
  497.  * Used by drivers to tell core Mesa that the driver is going to
  498.  * install/ use its own vertex program.  In particular, this will
  499.  * prevent generated fragment programs from using state vars instead
  500.  * of ordinary varyings/inputs.
  501.  */
  502. void
  503. _mesa_set_vp_override(struct gl_context *ctx, GLboolean flag)
  504. {
  505.    if (ctx->VertexProgram._Overriden != flag) {
  506.       ctx->VertexProgram._Overriden = flag;
  507.  
  508.       /* Set one of the bits which will trigger fragment program
  509.        * regeneration:
  510.        */
  511.       ctx->NewState |= _NEW_PROGRAM;
  512.    }
  513. }
  514.