st_atom.c revision 3cdd8bfe8e5afa57001c605b42bfac1f3fbc4eb8
1/************************************************************************** 2 * 3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * 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 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: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 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. 25 * 26 **************************************************************************/ 27 28 29#include "glheader.h" 30#include "context.h" 31 32#include "st_context.h" 33#include "st_atom.h" 34 35 36 37/* This is used to initialize st->atoms[]. We could use this list 38 * directly except for a single atom, st_update_constants, which has a 39 * .dirty value which changes according to the parameters of the 40 * current fragment and vertex programs, and so cannot be a static 41 * value. 42 */ 43static const struct st_tracked_state *atoms[] = 44{ 45 &st_update_framebuffer, 46 &st_update_cbuf, 47 &st_update_clip, 48 &st_update_fs, 49 &st_update_setup, 50 &st_update_viewport, 51 &st_update_scissor, 52 &st_update_blend, 53 &st_update_stencil, 54 /* will be patched out at runtime */ 55/* &st_update_constants */ 56}; 57 58 59void st_init_atoms( struct st_context *st ) 60{ 61 GLuint i; 62 63 st->atoms = _mesa_malloc(sizeof(atoms)); 64 st->nr_atoms = sizeof(atoms)/sizeof(*atoms); 65 memcpy(st->atoms, atoms, sizeof(atoms)); 66 67 /* Patch in a pointer to the dynamic state atom: 68 */ 69 for (i = 0; i < st->nr_atoms; i++) 70 if (st->atoms[i] == &st_update_constants) 71 st->atoms[i] = &st->constants.tracked_state; 72 73 memcpy(&st->constants.tracked_state, 74 &st_update_constants, 75 sizeof(st_update_constants)); 76} 77 78 79void st_destroy_atoms( struct st_context *st ) 80{ 81 if (st->atoms) { 82 _mesa_free(st->atoms); 83 st->atoms = NULL; 84 } 85} 86 87 88/*********************************************************************** 89 */ 90 91static GLboolean check_state( const struct st_state_flags *a, 92 const struct st_state_flags *b ) 93{ 94 return ((a->mesa & b->mesa) || 95 (a->st & b->st)); 96} 97 98static void accumulate_state( struct st_state_flags *a, 99 const struct st_state_flags *b ) 100{ 101 a->mesa |= b->mesa; 102 a->st |= b->st; 103} 104 105 106static void xor_states( struct st_state_flags *result, 107 const struct st_state_flags *a, 108 const struct st_state_flags *b ) 109{ 110 result->mesa = a->mesa ^ b->mesa; 111 result->st = a->st ^ b->st; 112} 113 114 115/*********************************************************************** 116 * Update all derived state: 117 */ 118 119void st_validate_state( struct st_context *st ) 120{ 121 struct st_state_flags *state = &st->dirty; 122 GLuint i; 123 124 if (state->st == 0) 125 return; 126 127 if (1) { 128 /* Debug version which enforces various sanity checks on the 129 * state flags which are generated and checked to help ensure 130 * state atoms are ordered correctly in the list. 131 */ 132 struct st_state_flags examined, prev; 133 _mesa_memset(&examined, 0, sizeof(examined)); 134 prev = *state; 135 136 for (i = 0; i < st->nr_atoms; i++) { 137 const struct st_tracked_state *atom = st->atoms[i]; 138 struct st_state_flags generated; 139 140 assert(atom->dirty.mesa || 141 atom->dirty.st); 142 assert(atom->update); 143 144 if (check_state(state, &atom->dirty)) { 145 st->atoms[i]->update( st ); 146 } 147 148 accumulate_state(&examined, &atom->dirty); 149 150 /* generated = (prev ^ state) 151 * if (examined & generated) 152 * fail; 153 */ 154 xor_states(&generated, &prev, state); 155 assert(!check_state(&examined, &generated)); 156 prev = *state; 157 } 158 } 159 else { 160 const GLuint nr = st->nr_atoms; 161 162 for (i = 0; i < nr; i++) { 163 if (check_state(state, &st->atoms[i]->dirty)) 164 st->atoms[i]->update( st ); 165 } 166 } 167 168 memset(state, 0, sizeof(*state)); 169} 170 171 172 173