Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 "main/glheader.h"
30
#include "main/context.h"
31
 
32
#include "pipe/p_defines.h"
33
#include "st_context.h"
34
#include "st_atom.h"
35
#include "st_cb_bitmap.h"
36
#include "st_program.h"
37
#include "st_manager.h"
38
 
39
 
40
/**
41
 * This is used to initialize st->atoms[].
42
 */
43
static const struct st_tracked_state *atoms[] =
44
{
45
   &st_update_depth_stencil_alpha,
46
   &st_update_clip,
47
 
48
   &st_finalize_textures,
49
   &st_update_fp,
50
   &st_update_gp,
51
   &st_update_vp,
52
 
53
   &st_update_rasterizer,
54
   &st_update_polygon_stipple,
55
   &st_update_viewport,
56
   &st_update_scissor,
57
   &st_update_blend,
58
   &st_update_vertex_texture,
59
   &st_update_fragment_texture,
60
   &st_update_geometry_texture,
61
   &st_update_sampler, /* depends on update_*_texture for swizzle */
62
   &st_update_framebuffer,
63
   &st_update_msaa,
64
   &st_update_vs_constants,
65
   &st_update_gs_constants,
66
   &st_update_fs_constants,
67
   &st_bind_vs_ubos,
68
   &st_bind_fs_ubos,
69
   &st_update_pixel_transfer,
70
 
71
   /* this must be done after the vertex program update */
72
   &st_update_array
73
};
74
 
75
 
76
void st_init_atoms( struct st_context *st )
77
{
78
   /* no-op */
79
}
80
 
81
 
82
void st_destroy_atoms( struct st_context *st )
83
{
84
   /* no-op */
85
}
86
 
87
 
88
/***********************************************************************
89
 */
90
 
91
static 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
 
98
static 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
 
106
static 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
/* Too complex to figure out, just check every time:
116
 */
117
static void check_program_state( struct st_context *st )
118
{
119
   struct gl_context *ctx = st->ctx;
120
 
121
   if (ctx->VertexProgram._Current != &st->vp->Base)
122
      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
123
 
124
   if (ctx->FragmentProgram._Current != &st->fp->Base)
125
      st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
126
 
127
   if (ctx->GeometryProgram._Current != &st->gp->Base)
128
      st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
129
}
130
 
131
static void check_attrib_edgeflag(struct st_context *st)
132
{
133
   const struct gl_client_array **arrays = st->ctx->Array._DrawArrays;
134
   GLboolean vertDataEdgeFlags;
135
 
136
   if (!arrays)
137
      return;
138
 
139
   vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj &&
140
                       arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name;
141
   if (vertDataEdgeFlags != st->vertdata_edgeflags) {
142
      st->vertdata_edgeflags = vertDataEdgeFlags;
143
      st->dirty.st |= ST_NEW_EDGEFLAGS_DATA;
144
   }
145
}
146
 
147
 
148
/***********************************************************************
149
 * Update all derived state:
150
 */
151
 
152
void st_validate_state( struct st_context *st )
153
{
154
   struct st_state_flags *state = &st->dirty;
155
   GLuint i;
156
 
157
   /* Get Mesa driver state. */
158
   st->dirty.st |= st->ctx->NewDriverState;
159
   st->ctx->NewDriverState = 0;
160
 
161
   check_attrib_edgeflag(st);
162
 
163
   if (state->mesa)
164
      st_flush_bitmap_cache(st);
165
 
166
   check_program_state( st );
167
 
168
   st_manager_validate_framebuffers(st);
169
 
170
   if (state->st == 0)
171
      return;
172
 
173
   /*printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/
174
 
175
#ifdef DEBUG
176
   if (1) {
177
#else
178
   if (0) {
179
#endif
180
      /* Debug version which enforces various sanity checks on the
181
       * state flags which are generated and checked to help ensure
182
       * state atoms are ordered correctly in the list.
183
       */
184
      struct st_state_flags examined, prev;
185
      memset(&examined, 0, sizeof(examined));
186
      prev = *state;
187
 
188
      for (i = 0; i < Elements(atoms); i++) {
189
	 const struct st_tracked_state *atom = atoms[i];
190
	 struct st_state_flags generated;
191
 
192
	 /*printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/
193
 
194
	 if (!(atom->dirty.mesa || atom->dirty.st) ||
195
	     !atom->update) {
196
	    printf("malformed atom %s\n", atom->name);
197
	    assert(0);
198
	 }
199
 
200
	 if (check_state(state, &atom->dirty)) {
201
	    atoms[i]->update( st );
202
	    /*printf("after: %x\n", atom->dirty.mesa);*/
203
	 }
204
 
205
	 accumulate_state(&examined, &atom->dirty);
206
 
207
	 /* generated = (prev ^ state)
208
	  * if (examined & generated)
209
	  *     fail;
210
	  */
211
	 xor_states(&generated, &prev, state);
212
	 assert(!check_state(&examined, &generated));
213
	 prev = *state;
214
      }
215
      /*printf("\n");*/
216
 
217
   }
218
   else {
219
      for (i = 0; i < Elements(atoms); i++) {
220
	 if (check_state(state, &atoms[i]->dirty))
221
	    atoms[i]->update( st );
222
      }
223
   }
224
 
225
   memset(state, 0, sizeof(*state));
226
}
227