1 /**************************************************************************
3 * Copyright 2003 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 #include "main/glheader.h"
31 #include "main/context.h"
33 #include "pipe/p_defines.h"
34 #include "st_context.h"
36 #include "st_program.h"
37 #include "st_manager.h"
40 /* The list state update functions. */
41 static const struct st_tracked_state
*atoms
[] =
43 #define ST_STATE(FLAG, st_update) &st_update,
44 #include "st_atom_list.h"
49 void st_init_atoms( struct st_context
*st
)
51 STATIC_ASSERT(ARRAY_SIZE(atoms
) <= 64);
55 void st_destroy_atoms( struct st_context
*st
)
61 /* Too complex to figure out, just check every time:
63 static void check_program_state( struct st_context
*st
)
65 struct gl_context
*ctx
= st
->ctx
;
67 if (ctx
->VertexProgram
._Current
!= &st
->vp
->Base
)
68 st
->dirty
|= ST_NEW_VERTEX_PROGRAM(st
);
70 if (ctx
->FragmentProgram
._Current
!= &st
->fp
->Base
)
71 st
->dirty
|= ST_NEW_FRAGMENT_PROGRAM
;
73 if (ctx
->GeometryProgram
._Current
!= &st
->gp
->Base
)
74 st
->dirty
|= ST_NEW_GEOMETRY_PROGRAM
;
76 if (ctx
->TessCtrlProgram
._Current
!= &st
->tcp
->Base
)
77 st
->dirty
|= ST_NEW_TESSCTRL_PROGRAM
;
79 if (ctx
->TessEvalProgram
._Current
!= &st
->tep
->Base
)
80 st
->dirty
|= ST_NEW_TESSEVAL_PROGRAM
;
82 st
->gfx_shaders_may_be_dirty
= false;
85 static void check_attrib_edgeflag(struct st_context
*st
)
87 const struct gl_client_array
**arrays
= st
->ctx
->Array
._DrawArrays
;
88 GLboolean vertdata_edgeflags
, edgeflag_culls_prims
, edgeflags_enabled
;
93 edgeflags_enabled
= st
->ctx
->Polygon
.FrontMode
!= GL_FILL
||
94 st
->ctx
->Polygon
.BackMode
!= GL_FILL
;
96 vertdata_edgeflags
= edgeflags_enabled
&&
97 arrays
[VERT_ATTRIB_EDGEFLAG
]->StrideB
!= 0;
98 if (vertdata_edgeflags
!= st
->vertdata_edgeflags
) {
99 st
->vertdata_edgeflags
= vertdata_edgeflags
;
100 st
->dirty
|= ST_NEW_VERTEX_PROGRAM(st
);
103 edgeflag_culls_prims
= edgeflags_enabled
&& !vertdata_edgeflags
&&
104 !st
->ctx
->Current
.Attrib
[VERT_ATTRIB_EDGEFLAG
][0];
105 if (edgeflag_culls_prims
!= st
->edgeflag_culls_prims
) {
106 st
->edgeflag_culls_prims
= edgeflag_culls_prims
;
107 st
->dirty
|= ST_NEW_RASTERIZER
;
112 /***********************************************************************
113 * Update all derived state:
116 void st_validate_state( struct st_context
*st
, enum st_pipeline pipeline
)
118 struct gl_context
*ctx
= st
->ctx
;
119 uint64_t dirty
, pipeline_mask
;
120 uint32_t dirty_lo
, dirty_hi
;
122 /* Get Mesa driver state. */
123 st
->dirty
|= st
->ctx
->NewDriverState
& ST_ALL_STATES_MASK
;
124 st
->ctx
->NewDriverState
= 0;
126 /* Get pipeline state. */
128 case ST_PIPELINE_RENDER
:
129 if (st
->ctx
->API
== API_OPENGL_COMPAT
)
130 check_attrib_edgeflag(st
);
132 check_program_state(st
);
133 st_manager_validate_framebuffers(st
);
135 pipeline_mask
= ST_PIPELINE_RENDER_STATE_MASK
;
137 case ST_PIPELINE_COMPUTE
:
138 if (ctx
->ComputeProgram
._Current
!= &st
->cp
->Base
)
139 st
->dirty
|= ST_NEW_COMPUTE_PROGRAM
;
141 st
->compute_shader_may_be_dirty
= false;
142 pipeline_mask
= ST_PIPELINE_COMPUTE_STATE_MASK
;
145 unreachable("Invalid pipeline specified");
148 dirty
= st
->dirty
& pipeline_mask
;
153 dirty_hi
= dirty
>> 32;
157 * Don't use u_bit_scan64, it may be slower on 32-bit.
160 atoms
[u_bit_scan(&dirty_lo
)]->update(st
);
162 atoms
[32 + u_bit_scan(&dirty_hi
)]->update(st
);
164 /* Clear the render or compute state bits. */
165 st
->dirty
&= ~pipeline_mask
;