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"
41 * This is used to initialize st->atoms[].
43 static const struct st_tracked_state
*atoms
[] =
45 &st_update_depth_stencil_alpha
,
54 &st_update_rasterizer
,
55 &st_update_polygon_stipple
,
59 &st_update_vertex_texture
,
60 &st_update_fragment_texture
,
61 &st_update_geometry_texture
,
62 &st_update_tessctrl_texture
,
63 &st_update_tesseval_texture
,
64 &st_update_sampler
, /* depends on update_*_texture for swizzle */
65 &st_update_framebuffer
,
67 &st_update_sample_shading
,
68 &st_update_vs_constants
,
69 &st_update_tcs_constants
,
70 &st_update_tes_constants
,
71 &st_update_gs_constants
,
72 &st_update_fs_constants
,
78 &st_update_pixel_transfer
,
81 /* this must be done after the vertex program update */
86 void st_init_atoms( struct st_context
*st
)
92 void st_destroy_atoms( struct st_context
*st
)
98 /***********************************************************************
101 static GLboolean
check_state( const struct st_state_flags
*a
,
102 const struct st_state_flags
*b
)
104 return ((a
->mesa
& b
->mesa
) ||
108 static void accumulate_state( struct st_state_flags
*a
,
109 const struct st_state_flags
*b
)
116 static void xor_states( struct st_state_flags
*result
,
117 const struct st_state_flags
*a
,
118 const struct st_state_flags
*b
)
120 result
->mesa
= a
->mesa
^ b
->mesa
;
121 result
->st
= a
->st
^ b
->st
;
125 /* Too complex to figure out, just check every time:
127 static void check_program_state( struct st_context
*st
)
129 struct gl_context
*ctx
= st
->ctx
;
131 if (ctx
->VertexProgram
._Current
!= &st
->vp
->Base
)
132 st
->dirty
.st
|= ST_NEW_VERTEX_PROGRAM
;
134 if (ctx
->FragmentProgram
._Current
!= &st
->fp
->Base
)
135 st
->dirty
.st
|= ST_NEW_FRAGMENT_PROGRAM
;
137 if (ctx
->GeometryProgram
._Current
!= &st
->gp
->Base
)
138 st
->dirty
.st
|= ST_NEW_GEOMETRY_PROGRAM
;
141 static void check_attrib_edgeflag(struct st_context
*st
)
143 const struct gl_client_array
**arrays
= st
->ctx
->Array
._DrawArrays
;
144 GLboolean vertdata_edgeflags
, edgeflag_culls_prims
, edgeflags_enabled
;
149 edgeflags_enabled
= st
->ctx
->Polygon
.FrontMode
!= GL_FILL
||
150 st
->ctx
->Polygon
.BackMode
!= GL_FILL
;
152 vertdata_edgeflags
= edgeflags_enabled
&&
153 arrays
[VERT_ATTRIB_EDGEFLAG
]->StrideB
!= 0;
154 if (vertdata_edgeflags
!= st
->vertdata_edgeflags
) {
155 st
->vertdata_edgeflags
= vertdata_edgeflags
;
156 st
->dirty
.st
|= ST_NEW_VERTEX_PROGRAM
;
159 edgeflag_culls_prims
= edgeflags_enabled
&& !vertdata_edgeflags
&&
160 !st
->ctx
->Current
.Attrib
[VERT_ATTRIB_EDGEFLAG
][0];
161 if (edgeflag_culls_prims
!= st
->edgeflag_culls_prims
) {
162 st
->edgeflag_culls_prims
= edgeflag_culls_prims
;
163 st
->dirty
.st
|= ST_NEW_RASTERIZER
;
168 /***********************************************************************
169 * Update all derived state:
172 void st_validate_state( struct st_context
*st
)
174 struct st_state_flags
*state
= &st
->dirty
;
177 /* Get Mesa driver state. */
178 st
->dirty
.st
|= st
->ctx
->NewDriverState
;
179 st
->ctx
->NewDriverState
= 0;
181 check_attrib_edgeflag(st
);
183 check_program_state( st
);
185 st_manager_validate_framebuffers(st
);
187 if (state
->st
== 0 && state
->mesa
== 0)
190 /*printf("%s %x/%x\n", __func__, state->mesa, state->st);*/
197 /* Debug version which enforces various sanity checks on the
198 * state flags which are generated and checked to help ensure
199 * state atoms are ordered correctly in the list.
201 struct st_state_flags examined
, prev
;
202 memset(&examined
, 0, sizeof(examined
));
205 for (i
= 0; i
< ARRAY_SIZE(atoms
); i
++) {
206 const struct st_tracked_state
*atom
= atoms
[i
];
207 struct st_state_flags generated
;
209 /*printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/
211 if (!(atom
->dirty
.mesa
|| atom
->dirty
.st
) ||
213 printf("malformed atom %s\n", atom
->name
);
217 if (check_state(state
, &atom
->dirty
)) {
218 atoms
[i
]->update( st
);
219 /*printf("after: %x\n", atom->dirty.mesa);*/
222 accumulate_state(&examined
, &atom
->dirty
);
224 /* generated = (prev ^ state)
225 * if (examined & generated)
228 xor_states(&generated
, &prev
, state
);
229 assert(!check_state(&examined
, &generated
));
236 for (i
= 0; i
< ARRAY_SIZE(atoms
); i
++) {
237 if (check_state(state
, &atoms
[i
]->dirty
))
238 atoms
[i
]->update( st
);
242 memset(state
, 0, sizeof(*state
));