25725625e009798493b682bd031f599067c2fe40
[mesa.git] / src / mesa / pipe / failover / fo_state.c
1 /**************************************************************************
2 *
3 * Copyright 2007 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 /* Authors: Keith Whitwell <keith@tungstengraphics.com>
29 */
30
31 #include "fo_context.h"
32
33
34 /* This looks like a lot of work at the moment - we're keeping a
35 * duplicate copy of the state up-to-date.
36 *
37 * This can change in two ways:
38 * - With constant state objects we would only need to save a pointer,
39 * not the whole object.
40 * - By adding a callback in the state tracker to re-emit state. The
41 * state tracker knows the current state already and can re-emit it
42 * without additional complexity.
43 *
44 * This works as a proof-of-concept, but a final version will have
45 * lower overheads.
46 */
47
48 static void
49 failover_set_alpha_test_state(struct pipe_context *pipe,
50 const struct pipe_alpha_test_state *alpha)
51 {
52 struct failover_context *failover = failover_context(pipe);
53
54 failover->alpha_test = *alpha;
55 failover->dirty |= FO_NEW_ALPHA_TEST;
56 failover->hw->set_alpha_test_state( failover->hw, alpha );
57 }
58
59
60 static void *
61 failover_create_blend_state( struct pipe_context *pipe,
62 const struct pipe_blend_state *blend )
63 {
64 struct fo_state *state = malloc(sizeof(struct fo_state));
65 struct failover_context *failover = failover_context(pipe);
66
67 state->sw_state = failover->sw->create_blend_state(pipe, blend);
68 state->hw_state = failover->hw->create_blend_state(pipe, blend);
69
70 return state;
71 }
72
73 static void
74 failover_bind_blend_state( struct pipe_context *pipe,
75 void *blend )
76 {
77 struct failover_context *failover = failover_context(pipe);
78
79 failover->blend = (struct fo_state *)blend;
80 failover->dirty |= FO_NEW_BLEND;
81 failover->hw->bind_blend_state( failover->hw, blend );
82 }
83
84 static void
85 failover_delete_blend_state( struct pipe_context *pipe,
86 void *blend )
87 {
88 struct fo_state *state = (struct fo_state*)blend;
89 struct failover_context *failover = failover_context(pipe);
90
91 failover->sw->delete_blend_state(pipe, state->sw_state);
92 failover->hw->delete_blend_state(pipe, state->hw_state);
93 state->sw_state = 0;
94 state->hw_state = 0;
95 free(state);
96 }
97
98 static void
99 failover_set_blend_color( struct pipe_context *pipe,
100 const struct pipe_blend_color *blend_color )
101 {
102 struct failover_context *failover = failover_context(pipe);
103
104 failover->blend_color = *blend_color;
105 failover->dirty |= FO_NEW_BLEND_COLOR;
106 failover->hw->set_blend_color( failover->hw, blend_color );
107 }
108
109 static void
110 failover_set_clip_state( struct pipe_context *pipe,
111 const struct pipe_clip_state *clip )
112 {
113 struct failover_context *failover = failover_context(pipe);
114
115 failover->clip = *clip;
116 failover->dirty |= FO_NEW_CLIP;
117 failover->hw->set_clip_state( failover->hw, clip );
118 }
119
120 static void
121 failover_set_clear_color_state( struct pipe_context *pipe,
122 const struct pipe_clear_color_state *clear_color )
123 {
124 struct failover_context *failover = failover_context(pipe);
125
126 failover->clear_color = *clear_color;
127 failover->dirty |= FO_NEW_CLEAR_COLOR;
128 failover->hw->set_clear_color_state( failover->hw, clear_color );
129 }
130
131 static void
132 failover_bind_depth_stencil_state(struct pipe_context *pipe,
133 const struct pipe_depth_stencil_state *depth_stencil)
134 {
135 struct failover_context *failover = failover_context(pipe);
136
137 failover->depth_stencil = depth_stencil;
138 failover->dirty |= FO_NEW_DEPTH_STENCIL;
139 failover->hw->bind_depth_stencil_state( failover->hw, depth_stencil );
140 }
141
142 static void
143 failover_set_framebuffer_state(struct pipe_context *pipe,
144 const struct pipe_framebuffer_state *framebuffer)
145 {
146 struct failover_context *failover = failover_context(pipe);
147
148 failover->framebuffer = *framebuffer;
149 failover->dirty |= FO_NEW_FRAMEBUFFER;
150 failover->hw->set_framebuffer_state( failover->hw, framebuffer );
151 }
152
153 static void
154 failover_bind_fs_state(struct pipe_context *pipe,
155 const struct pipe_shader_state *fs)
156 {
157 struct failover_context *failover = failover_context(pipe);
158
159 failover->fragment_shader = fs;
160 failover->dirty |= FO_NEW_FRAGMENT_SHADER;
161 failover->hw->bind_fs_state( failover->hw, fs );
162 }
163
164 static void
165 failover_bind_vs_state(struct pipe_context *pipe,
166 const struct pipe_shader_state *vs)
167 {
168 struct failover_context *failover = failover_context(pipe);
169
170 failover->vertex_shader = vs;
171 failover->dirty |= FO_NEW_VERTEX_SHADER;
172 failover->hw->bind_vs_state( failover->hw, vs );
173 }
174
175 static void
176 failover_set_polygon_stipple( struct pipe_context *pipe,
177 const struct pipe_poly_stipple *stipple )
178 {
179 struct failover_context *failover = failover_context(pipe);
180
181 failover->poly_stipple = *stipple;
182 failover->dirty |= FO_NEW_STIPPLE;
183 failover->hw->set_polygon_stipple( failover->hw, stipple );
184 }
185
186 static void *
187 failover_create_rasterizer_state(struct pipe_context *pipe,
188 const struct pipe_rasterizer_state *templ)
189 {
190 struct fo_state *state = malloc(sizeof(struct fo_state));
191 struct failover_context *failover = failover_context(pipe);
192
193 state->sw_state = failover->sw->create_rasterizer_state(pipe, templ);
194 state->hw_state = failover->hw->create_rasterizer_state(pipe, templ);
195
196 return state;
197 }
198
199 static void
200 failover_bind_rasterizer_state(struct pipe_context *pipe,
201 void *raster)
202 {
203 struct failover_context *failover = failover_context(pipe);
204
205 failover->rasterizer = (struct fo_state *)raster;
206 failover->dirty |= FO_NEW_RASTERIZER;
207 failover->hw->bind_rasterizer_state( failover->hw, raster );
208 }
209
210 static void
211 failover_delete_rasterizer_state(struct pipe_context *pipe,
212 void *raster)
213 {
214 struct fo_state *state = (struct fo_state*)raster;
215 struct failover_context *failover = failover_context(pipe);
216
217 failover->sw->delete_rasterizer_state(pipe, state->sw_state);
218 failover->hw->delete_rasterizer_state(pipe, state->hw_state);
219 state->sw_state = 0;
220 state->hw_state = 0;
221 free(state);
222 }
223
224
225 static void
226 failover_set_scissor_state( struct pipe_context *pipe,
227 const struct pipe_scissor_state *scissor )
228 {
229 struct failover_context *failover = failover_context(pipe);
230
231 failover->scissor = *scissor;
232 failover->dirty |= FO_NEW_SCISSOR;
233 failover->hw->set_scissor_state( failover->hw, scissor );
234 }
235
236 static void
237 failover_bind_sampler_state(struct pipe_context *pipe,
238 unsigned unit,
239 const struct pipe_sampler_state *sampler)
240 {
241 struct failover_context *failover = failover_context(pipe);
242
243 failover->sampler[unit] = sampler;
244 failover->dirty |= FO_NEW_SAMPLER;
245 failover->dirty_sampler |= (1<<unit);
246 failover->hw->bind_sampler_state( failover->hw, unit, sampler );
247 }
248
249
250 static void
251 failover_set_texture_state(struct pipe_context *pipe,
252 unsigned unit,
253 struct pipe_mipmap_tree *texture)
254 {
255 struct failover_context *failover = failover_context(pipe);
256
257 failover->texture[unit] = texture;
258 failover->dirty |= FO_NEW_TEXTURE;
259 failover->dirty_texture |= (1<<unit);
260 failover->hw->set_texture_state( failover->hw, unit, texture );
261 }
262
263
264 static void
265 failover_set_viewport_state( struct pipe_context *pipe,
266 const struct pipe_viewport_state *viewport )
267 {
268 struct failover_context *failover = failover_context(pipe);
269
270 failover->viewport = *viewport;
271 failover->dirty |= FO_NEW_VIEWPORT;
272 failover->hw->set_viewport_state( failover->hw, viewport );
273 }
274
275
276 static void
277 failover_set_vertex_buffer(struct pipe_context *pipe,
278 unsigned unit,
279 const struct pipe_vertex_buffer *vertex_buffer)
280 {
281 struct failover_context *failover = failover_context(pipe);
282
283 failover->vertex_buffer[unit] = *vertex_buffer;
284 failover->dirty |= FO_NEW_VERTEX_BUFFER;
285 failover->dirty_vertex_buffer |= (1<<unit);
286 failover->hw->set_vertex_buffer( failover->hw, unit, vertex_buffer );
287 }
288
289
290 static void
291 failover_set_vertex_element(struct pipe_context *pipe,
292 unsigned unit,
293 const struct pipe_vertex_element *vertex_element)
294 {
295 struct failover_context *failover = failover_context(pipe);
296
297 failover->vertex_element[unit] = *vertex_element;
298 failover->dirty |= FO_NEW_VERTEX_ELEMENT;
299 failover->dirty_vertex_element |= (1<<unit);
300 failover->hw->set_vertex_element( failover->hw, unit, vertex_element );
301 }
302
303
304 void
305 failover_init_state_functions( struct failover_context *failover )
306 {
307 failover->pipe.create_blend_state = failover_create_blend_state;
308 failover->pipe.bind_blend_state = failover_bind_blend_state;
309 failover->pipe.delete_blend_state = failover_delete_blend_state;
310 failover->pipe.bind_sampler_state = failover_bind_sampler_state;
311 failover->pipe.bind_depth_stencil_state = failover_bind_depth_stencil_state;
312 failover->pipe.create_rasterizer_state = failover_create_rasterizer_state;
313 failover->pipe.bind_rasterizer_state = failover_bind_rasterizer_state;
314 failover->pipe.delete_rasterizer_state = failover_delete_rasterizer_state;
315 failover->pipe.bind_fs_state = failover_bind_fs_state;
316 failover->pipe.bind_vs_state = failover_bind_vs_state;
317
318 failover->pipe.set_alpha_test_state = failover_set_alpha_test_state;
319 failover->pipe.set_blend_color = failover_set_blend_color;
320 failover->pipe.set_clip_state = failover_set_clip_state;
321 failover->pipe.set_clear_color_state = failover_set_clear_color_state;
322 failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
323 failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
324 failover->pipe.set_scissor_state = failover_set_scissor_state;
325 failover->pipe.set_texture_state = failover_set_texture_state;
326 failover->pipe.set_viewport_state = failover_set_viewport_state;
327 failover->pipe.set_vertex_buffer = failover_set_vertex_buffer;
328 failover->pipe.set_vertex_element = failover_set_vertex_element;
329 }