X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fstate.c;h=fb8b71cfe22932ae577935462b0161db6414e2cd;hb=c6ed42a89ede459e72b18cd8890cc3aba39905f5;hp=7ad50bcaddcfeb78b6a8c287056858f2734bf35d;hpb=636d01bd61cac83e13c3c64874e7e34e828ca93a;p=mesa.git diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 7ad50bcaddc..fb8b71cfe22 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -33,6 +33,7 @@ #include "glheader.h" #include "mtypes.h" +#include "arrayobj.h" #include "context.h" #include "debug.h" #include "macros.h" @@ -43,6 +44,7 @@ #include "pixel.h" #include "program/program.h" #include "program/prog_parameter.h" +#include "shaderobj.h" #include "state.h" #include "stencil.h" #include "texenvprogram.h" @@ -61,127 +63,6 @@ update_separate_specular(struct gl_context *ctx) } -/** - * Helper for update_arrays(). - * \return min(current min, array->_MaxElement). - */ -static GLuint -update_min(GLuint min, struct gl_client_array *array) -{ - _mesa_update_array_max_element(array); - return MIN2(min, array->_MaxElement); -} - - -/** - * Update ctx->Array._MaxElement (the max legal index into all enabled arrays). - * Need to do this upon new array state or new buffer object state. - */ -static void -update_arrays( struct gl_context *ctx ) -{ - struct gl_array_object *arrayObj = ctx->Array.ArrayObj; - GLuint i, min = ~0; - - /* find min of _MaxElement values for all enabled arrays */ - - /* 0 */ - if (ctx->VertexProgram._Current - && arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); - } - else if (arrayObj->Vertex.Enabled) { - min = update_min(min, &arrayObj->Vertex); - } - - /* 1 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]); - } - /* no conventional vertex weight array */ - - /* 2 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); - } - else if (arrayObj->Normal.Enabled) { - min = update_min(min, &arrayObj->Normal); - } - - /* 3 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); - } - else if (arrayObj->Color.Enabled) { - min = update_min(min, &arrayObj->Color); - } - - /* 4 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]); - } - else if (arrayObj->SecondaryColor.Enabled) { - min = update_min(min, &arrayObj->SecondaryColor); - } - - /* 5 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]); - } - else if (arrayObj->FogCoord.Enabled) { - min = update_min(min, &arrayObj->FogCoord); - } - - /* 6 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]); - } - else if (arrayObj->Index.Enabled) { - min = update_min(min, &arrayObj->Index); - } - - /* 7 */ - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]); - } - - /* 8..15 */ - for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { - if (ctx->VertexProgram._Enabled - && arrayObj->VertexAttrib[i].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[i]); - } - else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits - && arrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { - min = update_min(min, &arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]); - } - } - - /* 16..31 */ - if (ctx->VertexProgram._Current) { - for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) { - if (arrayObj->VertexAttrib[i].Enabled) { - min = update_min(min, &arrayObj->VertexAttrib[i]); - } - } - } - - if (arrayObj->EdgeFlag.Enabled) { - min = update_min(min, &arrayObj->EdgeFlag); - } - - /* _MaxElement is one past the last legal array element */ - arrayObj->_MaxElement = min; -} - - /** * Update the following fields: * ctx->VertexProgram._Enabled @@ -224,7 +105,7 @@ update_program(struct gl_context *ctx) { const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram; const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram; - const struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram; + struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram; const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current; @@ -246,32 +127,51 @@ update_program(struct gl_context *ctx) * come up, or matter. */ - if (fsProg && fsProg->LinkStatus && fsProg->FragmentProgram) { + if (fsProg && fsProg->LinkStatus + && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { /* Use GLSL fragment shader */ + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + fsProg); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, - fsProg->FragmentProgram); + gl_fragment_program(fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, + NULL); } else if (ctx->FragmentProgram._Enabled) { /* Use user-defined fragment program */ + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + NULL); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, ctx->FragmentProgram.Current); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, + NULL); } else if (ctx->FragmentProgram._MaintainTexEnvProgram) { /* Use fragment program generated from fixed-function state */ + struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); + + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + f); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, - _mesa_get_fixed_func_fragment_program(ctx)); + gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, - ctx->FragmentProgram._Current); + gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); } else { /* No fragment program */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, + NULL); } - if (gsProg && gsProg->LinkStatus && gsProg->GeometryProgram) { + if (gsProg && gsProg->LinkStatus + && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) { /* Use GLSL geometry shader */ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, - gsProg->GeometryProgram); + gl_geometry_program(gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program)); } else { /* No geometry program */ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); @@ -281,10 +181,11 @@ update_program(struct gl_context *ctx) * _mesa_get_fixed_func_vertex_program() needs to know active * fragprog inputs. */ - if (vsProg && vsProg->LinkStatus && vsProg->VertexProgram) { + if (vsProg && vsProg->LinkStatus + && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) { /* Use GLSL vertex shader */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, - vsProg->VertexProgram); + gl_vertex_program(vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program)); } else if (ctx->VertexProgram._Enabled) { /* Use user-defined vertex program */ @@ -406,19 +307,6 @@ update_multisample(struct gl_context *ctx) } -/** - * Update derived color/blend/logicop state. - */ -static void -update_color(struct gl_context *ctx) -{ - /* This is needed to support 1.1's RGB logic ops AND - * 1.0's blending logicops. - */ - ctx->Color._LogicOpEnabled = _mesa_rgba_logicop_enabled(ctx); -} - - /** * Update the ctx->Color._ClampFragmentColor field */ @@ -460,20 +348,30 @@ update_clamp_read_color(struct gl_context *ctx) ctx->Color._ClampReadColor = ctx->Color.ClampReadColor; } - +/** + * Update the ctx->VertexProgram._TwoSideEnabled flag. + */ +static void +update_twoside(struct gl_context *ctx) +{ + if (ctx->Shader.CurrentVertexProgram || + ctx->VertexProgram._Enabled) { + ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled; + } else { + ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled && + ctx->Light.Model.TwoSide); + } +} /* - * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET + * Check polygon state and set DD_TRI_OFFSET * in ctx->_TriangleCaps if needed. */ static void update_polygon(struct gl_context *ctx) { - ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); - - if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) - ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; + ctx->_TriangleCaps &= ~DD_TRI_OFFSET; if ( ctx->Polygon.OffsetPoint || ctx->Polygon.OffsetLine @@ -525,9 +423,6 @@ update_tricaps(struct gl_context *ctx, GLbitfield new_state) if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) ctx->_TriangleCaps |= DD_TRI_UNFILLED; - if (ctx->Polygon.CullFlag - && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) - ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; if (ctx->Polygon.OffsetPoint || ctx->Polygon.OffsetLine || ctx->Polygon.OffsetFill) @@ -539,16 +434,8 @@ update_tricaps(struct gl_context *ctx, GLbitfield new_state) */ if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; - if (ctx->Light.ShadeModel == GL_FLAT) - ctx->_TriangleCaps |= DD_FLATSHADE; if (_mesa_need_secondary_color(ctx)) ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; - - /* - * Stencil - */ - if (ctx->Stencil._TestTwoSide) - ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; } #endif @@ -581,12 +468,13 @@ _mesa_update_state_locked( struct gl_context *ctx ) /* Determine which state flags effect vertex/fragment program state */ if (ctx->FragmentProgram._MaintainTexEnvProgram) { prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG | - _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE | - _NEW_PROGRAM | _NEW_FRAG_CLAMP); + _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT | + _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP | + _NEW_COLOR); } if (ctx->VertexProgram._MaintainTnlProgram) { - prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | - _NEW_TRANSFORM | _NEW_POINT | + prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE | + _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT | _NEW_FOG | _NEW_LIGHT | _MESA_NEW_NEED_EYE_COORDS); } @@ -616,6 +504,9 @@ _mesa_update_state_locked( struct gl_context *ctx ) if (new_state & _NEW_LIGHT) _mesa_update_lighting( ctx ); + if (new_state & (_NEW_LIGHT | _NEW_PROGRAM)) + update_twoside( ctx ); + if (new_state & (_NEW_LIGHT | _NEW_BUFFERS)) update_clamp_vertex_color(ctx); @@ -625,18 +516,15 @@ _mesa_update_state_locked( struct gl_context *ctx ) if (new_state & _NEW_PIXEL) _mesa_update_pixel( ctx, new_state ); - if (new_state & _DD_NEW_SEPARATE_SPECULAR) + if (new_state & _MESA_NEW_SEPARATE_SPECULAR) update_separate_specular( ctx ); if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) update_viewport_matrix(ctx); - if (new_state & _NEW_MULTISAMPLE) + if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS)) update_multisample( ctx ); - if (new_state & _NEW_COLOR) - update_color( ctx ); - if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) update_clamp_read_color(ctx); @@ -645,7 +533,7 @@ _mesa_update_state_locked( struct gl_context *ctx ) #if 0 if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT - | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) + | _NEW_STENCIL | _MESA_NEW_SEPARATE_SPECULAR)) update_tricaps( ctx, new_state ); #endif @@ -670,7 +558,7 @@ _mesa_update_state_locked( struct gl_context *ctx ) } if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) - update_arrays( ctx ); + _mesa_update_array_object_max_element(ctx, ctx->Array.ArrayObj); out: new_prog_state |= update_program_constants(ctx); @@ -687,9 +575,7 @@ _mesa_update_state_locked( struct gl_context *ctx ) new_state = ctx->NewState | new_prog_state; ctx->NewState = 0; ctx->Driver.UpdateState(ctx, new_state); - ctx->Array.NewState = 0; - if (!ctx->Array.RebindArrays) - ctx->Array.RebindArrays = (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) != 0; + ctx->Array.ArrayObj->NewArrays = 0x0; } @@ -730,11 +616,21 @@ _mesa_update_state( struct gl_context *ctx ) */ void _mesa_set_varying_vp_inputs( struct gl_context *ctx, - GLbitfield varying_inputs ) + GLbitfield64 varying_inputs ) { if (ctx->varying_vp_inputs != varying_inputs) { ctx->varying_vp_inputs = varying_inputs; - ctx->NewState |= _NEW_ARRAY; + + /* Only the fixed-func generated programs need to use the flag + * and the fixed-func fragment program uses it only if there is also + * a fixed-func vertex program, so this only depends on the latter. + * + * It's okay to check the VP pointer here, because this is called after + * _mesa_update_state in the vbo module. */ + if (ctx->VertexProgram._TnlProgram || + ctx->FragmentProgram._TexEnvProgram) { + ctx->NewState |= _NEW_VARYING_VP_INPUTS; + } /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/ } }