1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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 **************************************************************************/
29 #include "main/glheader.h"
30 #include "main/context.h"
32 #include "pipe/p_defines.h"
33 #include "st_context.h"
35 #include "st_cb_bitmap.h"
36 #include "st_program.h"
40 /* This is used to initialize st->atoms[]. We could use this list
41 * directly except for a single atom, st_update_constants, which has a
42 * .dirty value which changes according to the parameters of the
43 * current fragment and vertex programs, and so cannot be a static
46 static const struct st_tracked_state
*atoms
[] =
48 &st_update_depth_stencil_alpha
,
51 &st_finalize_textures
,
54 &st_update_rasterizer
,
55 &st_update_polygon_stipple
,
61 &st_update_framebuffer
,
62 &st_update_vs_constants
,
63 &st_update_fs_constants
,
64 &st_update_pixel_transfer
68 void st_init_atoms( struct st_context
*st
)
72 st
->atoms
= malloc(sizeof(atoms
));
73 st
->nr_atoms
= sizeof(atoms
)/sizeof(*atoms
);
74 memcpy(st
->atoms
, atoms
, sizeof(atoms
));
76 /* Patch in a pointer to the dynamic state atom:
78 for (i
= 0; i
< st
->nr_atoms
; i
++) {
79 if (st
->atoms
[i
] == &st_update_vs_constants
) {
80 st
->atoms
[i
] = &st
->constants
.tracked_state
[PIPE_SHADER_VERTEX
];
81 st
->atoms
[i
][0] = st_update_vs_constants
;
84 if (st
->atoms
[i
] == &st_update_fs_constants
) {
85 st
->atoms
[i
] = &st
->constants
.tracked_state
[PIPE_SHADER_FRAGMENT
];
86 st
->atoms
[i
][0] = st_update_fs_constants
;
92 void st_destroy_atoms( struct st_context
*st
)
101 /***********************************************************************
104 static GLboolean
check_state( const struct st_state_flags
*a
,
105 const struct st_state_flags
*b
)
107 return ((a
->mesa
& b
->mesa
) ||
111 static void accumulate_state( struct st_state_flags
*a
,
112 const struct st_state_flags
*b
)
119 static void xor_states( struct st_state_flags
*result
,
120 const struct st_state_flags
*a
,
121 const struct st_state_flags
*b
)
123 result
->mesa
= a
->mesa
^ b
->mesa
;
124 result
->st
= a
->st
^ b
->st
;
128 /* Too complex to figure out, just check every time:
130 static void check_program_state( struct st_context
*st
)
132 GLcontext
*ctx
= st
->ctx
;
134 if (ctx
->VertexProgram
._Current
!= &st
->vp
->Base
)
135 st
->dirty
.st
|= ST_NEW_VERTEX_PROGRAM
;
137 if (ctx
->FragmentProgram
._Current
!= &st
->fp
->Base
)
138 st
->dirty
.st
|= ST_NEW_FRAGMENT_PROGRAM
;
143 /***********************************************************************
144 * Update all derived state:
147 void st_validate_state( struct st_context
*st
)
149 struct st_state_flags
*state
= &st
->dirty
;
152 /* The bitmap cache is immune to pixel unpack changes.
153 * Note that GLUT makes several calls to glPixelStore for each
154 * bitmap char it draws so this is an important check.
156 if (state
->mesa
& ~_NEW_PACKUNPACK
)
157 st_flush_bitmap_cache(st
);
159 check_program_state( st
);
164 // _mesa_printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);
167 /* Debug version which enforces various sanity checks on the
168 * state flags which are generated and checked to help ensure
169 * state atoms are ordered correctly in the list.
171 struct st_state_flags examined
, prev
;
172 memset(&examined
, 0, sizeof(examined
));
175 for (i
= 0; i
< st
->nr_atoms
; i
++) {
176 const struct st_tracked_state
*atom
= st
->atoms
[i
];
177 struct st_state_flags generated
;
179 // _mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);
181 if (!(atom
->dirty
.mesa
|| atom
->dirty
.st
) ||
183 _mesa_printf("malformed atom %s\n", atom
->name
);
187 if (check_state(state
, &atom
->dirty
)) {
188 st
->atoms
[i
]->update( st
);
189 // _mesa_printf("after: %x\n", atom->dirty.mesa);
192 accumulate_state(&examined
, &atom
->dirty
);
194 /* generated = (prev ^ state)
195 * if (examined & generated)
198 xor_states(&generated
, &prev
, state
);
199 assert(!check_state(&examined
, &generated
));
202 // _mesa_printf("\n");
206 const GLuint nr
= st
->nr_atoms
;
208 for (i
= 0; i
< nr
; i
++) {
209 if (check_state(state
, &st
->atoms
[i
]->dirty
))
210 st
->atoms
[i
]->update( st
);
214 memset(state
, 0, sizeof(*state
));