fo_state.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 /* Authors:  Keith Whitwell <keith@tungstengraphics.com>
00029  */
00030 
00031 #include "pipe/p_inlines.h"
00032 
00033 #include "fo_context.h"
00034 
00035 
00036 /* This looks like a lot of work at the moment - we're keeping a
00037  * duplicate copy of the state up-to-date.  
00038  *
00039  * This can change in two ways:
00040  * - With constant state objects we would only need to save a pointer,
00041  *     not the whole object.
00042  * - By adding a callback in the state tracker to re-emit state.  The
00043  *     state tracker knows the current state already and can re-emit it 
00044  *     without additional complexity.
00045  *
00046  * This works as a proof-of-concept, but a final version will have
00047  * lower overheads.
00048  */
00049 
00050 
00051 
00052 static void *
00053 failover_create_blend_state( struct pipe_context *pipe,
00054                              const struct pipe_blend_state *blend )
00055 {
00056    struct fo_state *state = malloc(sizeof(struct fo_state));
00057    struct failover_context *failover = failover_context(pipe);
00058 
00059    state->sw_state = failover->sw->create_blend_state(failover->sw, blend);
00060    state->hw_state = failover->hw->create_blend_state(failover->hw, blend);
00061 
00062    return state;
00063 }
00064 
00065 static void
00066 failover_bind_blend_state( struct pipe_context *pipe,
00067                            void *blend )
00068 {
00069    struct failover_context *failover = failover_context(pipe);
00070    struct fo_state *state = (struct fo_state *)blend;
00071    failover->blend = state;
00072    failover->dirty |= FO_NEW_BLEND;
00073    failover->sw->bind_blend_state( failover->sw, state->sw_state );
00074    failover->hw->bind_blend_state( failover->hw, state->hw_state );
00075 }
00076 
00077 static void
00078 failover_delete_blend_state( struct pipe_context *pipe,
00079                              void *blend )
00080 {
00081    struct fo_state *state = (struct fo_state*)blend;
00082    struct failover_context *failover = failover_context(pipe);
00083 
00084    failover->sw->delete_blend_state(failover->sw, state->sw_state);
00085    failover->hw->delete_blend_state(failover->hw, state->hw_state);
00086    state->sw_state = 0;
00087    state->hw_state = 0;
00088    free(state);
00089 }
00090 
00091 static void
00092 failover_set_blend_color( struct pipe_context *pipe,
00093                           const struct pipe_blend_color *blend_color )
00094 {
00095    struct failover_context *failover = failover_context(pipe);
00096 
00097    failover->blend_color = *blend_color;
00098    failover->dirty |= FO_NEW_BLEND_COLOR;
00099    failover->sw->set_blend_color( failover->sw, blend_color );
00100    failover->hw->set_blend_color( failover->hw, blend_color );
00101 }
00102 
00103 static void 
00104 failover_set_clip_state( struct pipe_context *pipe,
00105                          const struct pipe_clip_state *clip )
00106 {
00107    struct failover_context *failover = failover_context(pipe);
00108 
00109    failover->clip = *clip;
00110    failover->dirty |= FO_NEW_CLIP;
00111    failover->sw->set_clip_state( failover->sw, clip );
00112    failover->hw->set_clip_state( failover->hw, clip );
00113 }
00114 
00115 
00116 static void *
00117 failover_create_depth_stencil_state(struct pipe_context *pipe,
00118                               const struct pipe_depth_stencil_alpha_state *templ)
00119 {
00120    struct fo_state *state = malloc(sizeof(struct fo_state));
00121    struct failover_context *failover = failover_context(pipe);
00122 
00123    state->sw_state = failover->sw->create_depth_stencil_alpha_state(failover->sw, templ);
00124    state->hw_state = failover->hw->create_depth_stencil_alpha_state(failover->hw, templ);
00125 
00126    return state;
00127 }
00128 
00129 static void
00130 failover_bind_depth_stencil_state(struct pipe_context *pipe,
00131                                   void *depth_stencil)
00132 {
00133    struct failover_context *failover = failover_context(pipe);
00134    struct fo_state *state = (struct fo_state *)depth_stencil;
00135    failover->depth_stencil = state;
00136    failover->dirty |= FO_NEW_DEPTH_STENCIL;
00137    failover->sw->bind_depth_stencil_alpha_state(failover->sw, state->sw_state);
00138    failover->hw->bind_depth_stencil_alpha_state(failover->hw, state->hw_state);
00139 }
00140 
00141 static void
00142 failover_delete_depth_stencil_state(struct pipe_context *pipe,
00143                                     void *ds)
00144 {
00145    struct fo_state *state = (struct fo_state*)ds;
00146    struct failover_context *failover = failover_context(pipe);
00147 
00148    failover->sw->delete_depth_stencil_alpha_state(failover->sw, state->sw_state);
00149    failover->hw->delete_depth_stencil_alpha_state(failover->hw, state->hw_state);
00150    state->sw_state = 0;
00151    state->hw_state = 0;
00152    free(state);
00153 }
00154 
00155 static void
00156 failover_set_framebuffer_state(struct pipe_context *pipe,
00157                                const struct pipe_framebuffer_state *framebuffer)
00158 {
00159    struct failover_context *failover = failover_context(pipe);
00160 
00161    failover->framebuffer = *framebuffer;
00162    failover->dirty |= FO_NEW_FRAMEBUFFER;
00163    failover->sw->set_framebuffer_state( failover->sw, framebuffer );
00164    failover->hw->set_framebuffer_state( failover->hw, framebuffer );
00165 }
00166 
00167 
00168 static void *
00169 failover_create_fs_state(struct pipe_context *pipe,
00170                          const struct pipe_shader_state *templ)
00171 {
00172    struct fo_state *state = malloc(sizeof(struct fo_state));
00173    struct failover_context *failover = failover_context(pipe);
00174 
00175    state->sw_state = failover->sw->create_fs_state(failover->sw, templ);
00176    state->hw_state = failover->hw->create_fs_state(failover->hw, templ);
00177 
00178    return state;
00179 }
00180 
00181 static void
00182 failover_bind_fs_state(struct pipe_context *pipe, void *fs)
00183 {
00184    struct failover_context *failover = failover_context(pipe);
00185    struct fo_state *state = (struct fo_state*)fs;
00186    failover->fragment_shader = state;
00187    failover->dirty |= FO_NEW_FRAGMENT_SHADER;
00188    failover->sw->bind_fs_state(failover->sw, state->sw_state);
00189    failover->hw->bind_fs_state(failover->hw, state->hw_state);
00190 }
00191 
00192 static void
00193 failover_delete_fs_state(struct pipe_context *pipe,
00194                          void *fs)
00195 {
00196    struct fo_state *state = (struct fo_state*)fs;
00197    struct failover_context *failover = failover_context(pipe);
00198 
00199    failover->sw->delete_fs_state(failover->sw, state->sw_state);
00200    failover->hw->delete_fs_state(failover->hw, state->hw_state);
00201    state->sw_state = 0;
00202    state->hw_state = 0;
00203    free(state);
00204 }
00205 
00206 static void *
00207 failover_create_vs_state(struct pipe_context *pipe,
00208                          const struct pipe_shader_state *templ)
00209 {
00210    struct fo_state *state = malloc(sizeof(struct fo_state));
00211    struct failover_context *failover = failover_context(pipe);
00212 
00213    state->sw_state = failover->sw->create_vs_state(failover->sw, templ);
00214    state->hw_state = failover->hw->create_vs_state(failover->hw, templ);
00215 
00216    return state;
00217 }
00218 
00219 static void
00220 failover_bind_vs_state(struct pipe_context *pipe,
00221                        void *vs)
00222 {
00223    struct failover_context *failover = failover_context(pipe);
00224 
00225    struct fo_state *state = (struct fo_state*)vs;
00226    failover->vertex_shader = state;
00227    failover->dirty |= FO_NEW_VERTEX_SHADER;
00228    failover->sw->bind_vs_state(failover->sw, state->sw_state);
00229    failover->hw->bind_vs_state(failover->hw, state->hw_state);
00230 }
00231 
00232 static void
00233 failover_delete_vs_state(struct pipe_context *pipe,
00234                          void *vs)
00235 {
00236    struct fo_state *state = (struct fo_state*)vs;
00237    struct failover_context *failover = failover_context(pipe);
00238 
00239    failover->sw->delete_vs_state(failover->sw, state->sw_state);
00240    failover->hw->delete_vs_state(failover->hw, state->hw_state);
00241    state->sw_state = 0;
00242    state->hw_state = 0;
00243    free(state);
00244 }
00245 
00246 static void 
00247 failover_set_polygon_stipple( struct pipe_context *pipe,
00248                               const struct pipe_poly_stipple *stipple )
00249 {
00250    struct failover_context *failover = failover_context(pipe);
00251 
00252    failover->poly_stipple = *stipple;
00253    failover->dirty |= FO_NEW_STIPPLE;
00254    failover->sw->set_polygon_stipple( failover->sw, stipple );
00255    failover->hw->set_polygon_stipple( failover->hw, stipple );
00256 }
00257 
00258 
00259 static void *
00260 failover_create_rasterizer_state(struct pipe_context *pipe,
00261                                  const struct pipe_rasterizer_state *templ)
00262 {
00263    struct fo_state *state = malloc(sizeof(struct fo_state));
00264    struct failover_context *failover = failover_context(pipe);
00265 
00266    state->sw_state = failover->sw->create_rasterizer_state(failover->sw, templ);
00267    state->hw_state = failover->hw->create_rasterizer_state(failover->hw, templ);
00268 
00269    return state;
00270 }
00271 
00272 static void
00273 failover_bind_rasterizer_state(struct pipe_context *pipe,
00274                                void *raster)
00275 {
00276    struct failover_context *failover = failover_context(pipe);
00277 
00278    struct fo_state *state = (struct fo_state*)raster;
00279    failover->rasterizer = state;
00280    failover->dirty |= FO_NEW_RASTERIZER;
00281    failover->sw->bind_rasterizer_state(failover->sw, state->sw_state);
00282    failover->hw->bind_rasterizer_state(failover->hw, state->hw_state);
00283 }
00284 
00285 static void
00286 failover_delete_rasterizer_state(struct pipe_context *pipe,
00287                                  void *raster)
00288 {
00289    struct fo_state *state = (struct fo_state*)raster;
00290    struct failover_context *failover = failover_context(pipe);
00291 
00292    failover->sw->delete_rasterizer_state(failover->sw, state->sw_state);
00293    failover->hw->delete_rasterizer_state(failover->hw, state->hw_state);
00294    state->sw_state = 0;
00295    state->hw_state = 0;
00296    free(state);
00297 }
00298 
00299 
00300 static void 
00301 failover_set_scissor_state( struct pipe_context *pipe,
00302                                  const struct pipe_scissor_state *scissor )
00303 {
00304    struct failover_context *failover = failover_context(pipe);
00305 
00306    failover->scissor = *scissor;
00307    failover->dirty |= FO_NEW_SCISSOR;
00308    failover->sw->set_scissor_state( failover->sw, scissor );
00309    failover->hw->set_scissor_state( failover->hw, scissor );
00310 }
00311 
00312 
00313 static void *
00314 failover_create_sampler_state(struct pipe_context *pipe,
00315                               const struct pipe_sampler_state *templ)
00316 {
00317    struct fo_state *state = malloc(sizeof(struct fo_state));
00318    struct failover_context *failover = failover_context(pipe);
00319 
00320    state->sw_state = failover->sw->create_sampler_state(failover->sw, templ);
00321    state->hw_state = failover->hw->create_sampler_state(failover->hw, templ);
00322 
00323    return state;
00324 }
00325 
00326 static void
00327 failover_bind_sampler_states(struct pipe_context *pipe,
00328                              unsigned num, void **sampler)
00329 {
00330    struct failover_context *failover = failover_context(pipe);
00331    struct fo_state *state = (struct fo_state*)sampler;
00332    uint i;
00333    assert(num <= PIPE_MAX_SAMPLERS);
00334    /* Check for no-op */
00335    if (num == failover->num_samplers &&
00336        !memcmp(failover->sampler, sampler, num * sizeof(void *)))
00337       return;
00338    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
00339       failover->sw_sampler_state[i] = i < num ? state[i].sw_state : NULL;
00340       failover->hw_sampler_state[i] = i < num ? state[i].hw_state : NULL;
00341    }
00342    failover->dirty |= FO_NEW_SAMPLER;
00343    failover->num_samplers = num;
00344    failover->sw->bind_sampler_states(failover->sw, num,
00345                                      failover->sw_sampler_state);
00346    failover->hw->bind_sampler_states(failover->hw, num,
00347                                      failover->hw_sampler_state);
00348 }
00349 
00350 static void
00351 failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)
00352 {
00353    struct fo_state *state = (struct fo_state*)sampler;
00354    struct failover_context *failover = failover_context(pipe);
00355 
00356    failover->sw->delete_sampler_state(failover->sw, state->sw_state);
00357    failover->hw->delete_sampler_state(failover->hw, state->hw_state);
00358    state->sw_state = 0;
00359    state->hw_state = 0;
00360    free(state);
00361 }
00362 
00363 
00364 static void
00365 failover_set_sampler_textures(struct pipe_context *pipe,
00366                               unsigned num,
00367                               struct pipe_texture **texture)
00368 {
00369    struct failover_context *failover = failover_context(pipe);
00370    uint i;
00371 
00372    assert(num <= PIPE_MAX_SAMPLERS);
00373 
00374    /* Check for no-op */
00375    if (num == failover->num_textures &&
00376        !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *)))
00377       return;
00378    for (i = 0; i < num; i++)
00379       pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
00380                              texture[i]);
00381    for (i = num; i < failover->num_textures; i++)
00382       pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
00383                              NULL);
00384    failover->dirty |= FO_NEW_TEXTURE;
00385    failover->num_textures = num;
00386    failover->sw->set_sampler_textures( failover->sw, num, texture );
00387    failover->hw->set_sampler_textures( failover->hw, num, texture );
00388 }
00389 
00390 
00391 static void 
00392 failover_set_viewport_state( struct pipe_context *pipe,
00393                              const struct pipe_viewport_state *viewport )
00394 {
00395    struct failover_context *failover = failover_context(pipe);
00396 
00397    failover->viewport = *viewport; 
00398    failover->dirty |= FO_NEW_VIEWPORT;
00399    failover->sw->set_viewport_state( failover->sw, viewport );
00400    failover->hw->set_viewport_state( failover->hw, viewport );
00401 }
00402 
00403 
00404 static void
00405 failover_set_vertex_buffers(struct pipe_context *pipe,
00406                             unsigned count,
00407                             const struct pipe_vertex_buffer *vertex_buffers)
00408 {
00409    struct failover_context *failover = failover_context(pipe);
00410 
00411    memcpy(failover->vertex_buffers, vertex_buffers,
00412           count * sizeof(vertex_buffers[0]));
00413    failover->dirty |= FO_NEW_VERTEX_BUFFER;
00414    failover->num_vertex_buffers = count;
00415    failover->sw->set_vertex_buffers( failover->sw, count, vertex_buffers );
00416    failover->hw->set_vertex_buffers( failover->hw, count, vertex_buffers );
00417 }
00418 
00419 
00420 static void
00421 failover_set_vertex_elements(struct pipe_context *pipe,
00422                              unsigned count,
00423                              const struct pipe_vertex_element *vertex_elements)
00424 {
00425    struct failover_context *failover = failover_context(pipe);
00426 
00427    memcpy(failover->vertex_elements, vertex_elements,
00428           count * sizeof(vertex_elements[0]));
00429 
00430    failover->dirty |= FO_NEW_VERTEX_ELEMENT;
00431    failover->num_vertex_elements = count;
00432    failover->sw->set_vertex_elements( failover->sw, count, vertex_elements );
00433    failover->hw->set_vertex_elements( failover->hw, count, vertex_elements );
00434 }
00435 
00436 void
00437 failover_set_constant_buffer(struct pipe_context *pipe,
00438                              uint shader, uint index,
00439                              const struct pipe_constant_buffer *buf)
00440 {
00441    struct failover_context *failover = failover_context(pipe);
00442 
00443    assert(shader < PIPE_SHADER_TYPES);
00444    assert(index == 0);
00445 
00446    failover->sw->set_constant_buffer(failover->sw, shader, index, buf);
00447    failover->hw->set_constant_buffer(failover->hw, shader, index, buf);
00448 }
00449 
00450 
00451 void
00452 failover_init_state_functions( struct failover_context *failover )
00453 {
00454    failover->pipe.create_blend_state = failover_create_blend_state;
00455    failover->pipe.bind_blend_state   = failover_bind_blend_state;
00456    failover->pipe.delete_blend_state = failover_delete_blend_state;
00457    failover->pipe.create_sampler_state = failover_create_sampler_state;
00458    failover->pipe.bind_sampler_states  = failover_bind_sampler_states;
00459    failover->pipe.delete_sampler_state = failover_delete_sampler_state;
00460    failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state;
00461    failover->pipe.bind_depth_stencil_alpha_state   = failover_bind_depth_stencil_state;
00462    failover->pipe.delete_depth_stencil_alpha_state = failover_delete_depth_stencil_state;
00463    failover->pipe.create_rasterizer_state = failover_create_rasterizer_state;
00464    failover->pipe.bind_rasterizer_state = failover_bind_rasterizer_state;
00465    failover->pipe.delete_rasterizer_state = failover_delete_rasterizer_state;
00466    failover->pipe.create_fs_state = failover_create_fs_state;
00467    failover->pipe.bind_fs_state   = failover_bind_fs_state;
00468    failover->pipe.delete_fs_state = failover_delete_fs_state;
00469    failover->pipe.create_vs_state = failover_create_vs_state;
00470    failover->pipe.bind_vs_state   = failover_bind_vs_state;
00471    failover->pipe.delete_vs_state = failover_delete_vs_state;
00472 
00473    failover->pipe.set_blend_color = failover_set_blend_color;
00474    failover->pipe.set_clip_state = failover_set_clip_state;
00475    failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
00476    failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
00477    failover->pipe.set_scissor_state = failover_set_scissor_state;
00478    failover->pipe.set_sampler_textures = failover_set_sampler_textures;
00479    failover->pipe.set_viewport_state = failover_set_viewport_state;
00480    failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
00481    failover->pipe.set_vertex_elements = failover_set_vertex_elements;
00482    failover->pipe.set_constant_buffer = failover_set_constant_buffer;
00483 }

Generated on Tue Sep 29 06:25:16 2009 for Gallium3D by  doxygen 1.5.4