Creates a new pipe driver that feeds commands to either a hardware or software pipe depending on fallback state. Untested concept checkpoint. At this point it compiles.tags/mesa_20090313
@@ -1,6 +1,7 @@ | |||
default: | |||
cd softpipe ; make | |||
cd i915simple ; make | |||
cd failover ; make | |||
clean: | |||
rm -f `find . -name \*.[oa]` |
@@ -0,0 +1,21 @@ | |||
TOP = ../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = failover | |||
DRIVER_SOURCES = \ | |||
fo_state.c \ | |||
fo_state_emit.c \ | |||
fo_context.c | |||
C_SOURCES = \ | |||
$(COMMON_SOURCES) \ | |||
$(DRIVER_SOURCES) | |||
ASM_SOURCES = | |||
include ../Makefile.template | |||
symlinks: | |||
@@ -0,0 +1,155 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_winsys.h" | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_context.h" | |||
#include "fo_context.h" | |||
#include "fo_winsys.h" | |||
static void failover_destroy( struct pipe_context *pipe ) | |||
{ | |||
struct failover_context *failover = failover_context( pipe ); | |||
free( failover ); | |||
} | |||
static boolean failover_draw_elements( struct pipe_context *pipe, | |||
struct pipe_buffer_handle *indexBuffer, | |||
unsigned indexSize, | |||
unsigned prim, unsigned start, unsigned count) | |||
{ | |||
struct failover_context *failover = failover_context( pipe ); | |||
/* If there has been any statechange since last time, try hardware | |||
* rendering again: | |||
*/ | |||
if (failover->dirty) { | |||
failover->mode = FO_HW; | |||
} | |||
/* Try hardware: | |||
*/ | |||
if (failover->mode == FO_HW) { | |||
if (!failover->hw->draw_elements( failover->hw, | |||
indexBuffer, | |||
indexSize, | |||
prim, | |||
start, | |||
count )) { | |||
failover->hw->flush( failover->hw, ~0 ); | |||
failover->mode = FO_SW; | |||
} | |||
} | |||
/* Possibly try software: | |||
*/ | |||
if (failover->mode == FO_SW) { | |||
if (failover->dirty) | |||
failover_state_emit( failover ); | |||
failover->sw->draw_elements( failover->sw, | |||
indexBuffer, | |||
indexSize, | |||
prim, | |||
start, | |||
count ); | |||
/* Be ready to switch back to hardware rendering without an | |||
* intervening flush. Unlikely to be much performance impact to | |||
* this: | |||
*/ | |||
failover->sw->flush( failover->sw, ~0 ); | |||
} | |||
return TRUE; | |||
} | |||
static boolean failover_draw_arrays( struct pipe_context *pipe, | |||
unsigned prim, unsigned start, unsigned count) | |||
{ | |||
return failover_draw_elements(pipe, NULL, 0, prim, start, count); | |||
} | |||
struct pipe_context *failover_create( struct pipe_context *hw, | |||
struct pipe_context *sw ) | |||
{ | |||
struct failover_context *failover = CALLOC_STRUCT(failover_context); | |||
if (failover == NULL) | |||
return NULL; | |||
failover->pipe.winsys = hw->winsys; | |||
failover->pipe.destroy = failover_destroy; | |||
failover->pipe.supported_formats = hw->supported_formats; | |||
failover->pipe.max_texture_size = hw->max_texture_size; | |||
failover->pipe.get_name = hw->get_name; | |||
failover->pipe.get_vendor = hw->get_vendor; | |||
failover->pipe.draw_arrays = failover_draw_arrays; | |||
failover->pipe.draw_elements = failover_draw_elements; | |||
failover->pipe.clear = hw->clear; | |||
/* No software occlusion fallback (or other optional functionality) | |||
* at this point - if the hardware doesn't support it, don't | |||
* advertise it to the application. | |||
*/ | |||
failover->pipe.reset_occlusion_counter = hw->reset_occlusion_counter; | |||
failover->pipe.get_occlusion_counter = hw->get_occlusion_counter; | |||
failover_init_state_functions( failover ); | |||
failover->pipe.surface_alloc = hw->surface_alloc; | |||
failover->pipe.get_tex_surface = hw->get_tex_surface; | |||
failover->pipe.region_alloc = hw->region_alloc; | |||
failover->pipe.region_release = hw->region_release; | |||
failover->pipe.region_idle = hw->region_idle; | |||
failover->pipe.region_map = hw->region_map; | |||
failover->pipe.region_unmap = hw->region_unmap; | |||
failover->pipe.region_data = hw->region_data; | |||
failover->pipe.region_copy = hw->region_copy; | |||
failover->pipe.region_fill = hw->region_fill; | |||
failover->pipe.mipmap_tree_layout = hw->mipmap_tree_layout; | |||
failover->pipe.flush = hw->flush; | |||
failover->dirty = 0; | |||
return &failover->pipe; | |||
} | |||
@@ -0,0 +1,113 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
/* Authors: Keith Whitwell <keith@tungstengraphics.com> | |||
*/ | |||
#ifndef FO_CONTEXT_H | |||
#define FO_CONTEXT_H | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_context.h" | |||
#define FO_NEW_VIEWPORT 0x1 | |||
#define FO_NEW_SETUP 0x2 | |||
#define FO_NEW_FRAGMENT_SHADER 0x4 | |||
#define FO_NEW_BLEND 0x8 | |||
#define FO_NEW_CLIP 0x10 | |||
#define FO_NEW_SCISSOR 0x20 | |||
#define FO_NEW_STIPPLE 0x40 | |||
#define FO_NEW_FRAMEBUFFER 0x80 | |||
#define FO_NEW_ALPHA_TEST 0x100 | |||
#define FO_NEW_DEPTH_TEST 0x200 | |||
#define FO_NEW_SAMPLER 0x400 | |||
#define FO_NEW_TEXTURE 0x800 | |||
#define FO_NEW_STENCIL 0x1000 | |||
#define FO_NEW_VERTEX 0x2000 | |||
#define FO_NEW_VERTEX_SHADER 0x4000 | |||
#define FO_NEW_BLEND_COLOR 0x8000 | |||
#define FO_NEW_CLEAR_COLOR 0x10000 | |||
#define FO_NEW_VERTEX_BUFFER 0x20000 | |||
#define FO_NEW_VERTEX_ELEMENT 0x40000 | |||
#define FO_HW 0 | |||
#define FO_SW 1 | |||
struct failover_context { | |||
struct pipe_context pipe; /**< base class */ | |||
/* The most recent drawing state as set by the driver: | |||
*/ | |||
struct pipe_alpha_test_state alpha_test; | |||
struct pipe_blend_state blend; | |||
struct pipe_blend_color blend_color; | |||
struct pipe_clear_color_state clear_color; | |||
struct pipe_clip_state clip; | |||
struct pipe_depth_state depth_test; | |||
struct pipe_framebuffer_state framebuffer; | |||
struct pipe_shader_state fragment_shader; | |||
struct pipe_shader_state vertex_shader; | |||
struct pipe_poly_stipple poly_stipple; | |||
struct pipe_scissor_state scissor; | |||
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; | |||
struct pipe_setup_state setup; | |||
struct pipe_stencil_state stencil; | |||
struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; | |||
struct pipe_viewport_state viewport; | |||
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; | |||
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; | |||
unsigned dirty; | |||
unsigned dirty_sampler; | |||
unsigned dirty_texture; | |||
unsigned dirty_vertex_buffer; | |||
unsigned dirty_vertex_element; | |||
unsigned mode; | |||
struct pipe_context *hw; | |||
struct pipe_context *sw; | |||
}; | |||
void failover_init_state_functions( struct failover_context *failover ); | |||
void failover_state_emit( struct failover_context *failover ); | |||
static INLINE struct failover_context * | |||
failover_context( struct pipe_context *pipe ) | |||
{ | |||
return (struct failover_context *)pipe; | |||
} | |||
#endif /* FO_CONTEXT_H */ |
@@ -0,0 +1,287 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
/* Authors: Keith Whitwell <keith@tungstengraphics.com> | |||
*/ | |||
#include "fo_context.h" | |||
/* This looks like a lot of work at the moment - we're keeping a | |||
* duplicate copy of the state up-to-date. | |||
* | |||
* This can change in two ways: | |||
* - With constant state objects we would only need to save a pointer, | |||
* not the whole object. | |||
* - By adding a callback in the state tracker to re-emit state. The | |||
* state tracker knows the current state already and can re-emit it | |||
* without additional complexity. | |||
* | |||
* This works as a proof-of-concept, but a final version will have | |||
* lower overheads. | |||
*/ | |||
static void | |||
failover_set_alpha_test_state(struct pipe_context *pipe, | |||
const struct pipe_alpha_test_state *alpha) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->alpha_test = *alpha; | |||
failover->dirty |= FO_NEW_ALPHA_TEST; | |||
failover->hw->set_alpha_test_state( failover->hw, alpha ); | |||
} | |||
static void | |||
failover_set_blend_state( struct pipe_context *pipe, | |||
const struct pipe_blend_state *blend ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->blend = *blend; | |||
failover->dirty |= FO_NEW_BLEND; | |||
failover->hw->set_blend_state( failover->hw, blend ); | |||
} | |||
static void | |||
failover_set_blend_color( struct pipe_context *pipe, | |||
const struct pipe_blend_color *blend_color ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->blend_color = *blend_color; | |||
failover->dirty |= FO_NEW_BLEND_COLOR; | |||
failover->hw->set_blend_color( failover->hw, blend_color ); | |||
} | |||
static void | |||
failover_set_clip_state( struct pipe_context *pipe, | |||
const struct pipe_clip_state *clip ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->clip = *clip; | |||
failover->dirty |= FO_NEW_CLIP; | |||
failover->hw->set_clip_state( failover->hw, clip ); | |||
} | |||
static void | |||
failover_set_clear_color_state( struct pipe_context *pipe, | |||
const struct pipe_clear_color_state *clear_color ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->clear_color = *clear_color; | |||
failover->dirty |= FO_NEW_CLEAR_COLOR; | |||
failover->hw->set_clear_color_state( failover->hw, clear_color ); | |||
} | |||
static void | |||
failover_set_depth_test_state(struct pipe_context *pipe, | |||
const struct pipe_depth_state *depth) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->depth_test = *depth; | |||
failover->dirty |= FO_NEW_DEPTH_TEST; | |||
failover->hw->set_depth_state( failover->hw, depth ); | |||
} | |||
static void | |||
failover_set_framebuffer_state(struct pipe_context *pipe, | |||
const struct pipe_framebuffer_state *framebuffer) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->framebuffer = *framebuffer; | |||
failover->dirty |= FO_NEW_FRAMEBUFFER; | |||
failover->hw->set_framebuffer_state( failover->hw, framebuffer ); | |||
} | |||
static void | |||
failover_set_fs_state(struct pipe_context *pipe, | |||
const struct pipe_shader_state *fs) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->fragment_shader = *fs; | |||
failover->dirty |= FO_NEW_FRAGMENT_SHADER; | |||
failover->hw->set_fs_state( failover->hw, fs ); | |||
} | |||
static void | |||
failover_set_vs_state(struct pipe_context *pipe, | |||
const struct pipe_shader_state *vs) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->vertex_shader = *vs; | |||
failover->dirty |= FO_NEW_VERTEX_SHADER; | |||
failover->hw->set_vs_state( failover->hw, vs ); | |||
} | |||
static void | |||
failover_set_polygon_stipple( struct pipe_context *pipe, | |||
const struct pipe_poly_stipple *stipple ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->poly_stipple = *stipple; | |||
failover->dirty |= FO_NEW_STIPPLE; | |||
failover->hw->set_polygon_stipple( failover->hw, stipple ); | |||
} | |||
static void | |||
failover_set_setup_state( struct pipe_context *pipe, | |||
const struct pipe_setup_state *setup ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->setup = *setup; | |||
failover->dirty |= FO_NEW_SETUP; | |||
failover->hw->set_setup_state( failover->hw, setup ); | |||
} | |||
static void | |||
failover_set_scissor_state( struct pipe_context *pipe, | |||
const struct pipe_scissor_state *scissor ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->scissor = *scissor; | |||
failover->dirty |= FO_NEW_SCISSOR; | |||
failover->hw->set_scissor_state( failover->hw, scissor ); | |||
} | |||
static void | |||
failover_set_stencil_state(struct pipe_context *pipe, | |||
const struct pipe_stencil_state *stencil) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->stencil = *stencil; | |||
failover->dirty |= FO_NEW_STENCIL; | |||
failover->hw->set_stencil_state( failover->hw, stencil ); | |||
} | |||
static void | |||
failover_set_sampler_state(struct pipe_context *pipe, | |||
unsigned unit, | |||
const struct pipe_sampler_state *sampler) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->sampler[unit] = *sampler; | |||
failover->dirty |= FO_NEW_SAMPLER; | |||
failover->dirty_sampler |= (1<<unit); | |||
failover->hw->set_sampler_state( failover->hw, unit, sampler ); | |||
} | |||
static void | |||
failover_set_texture_state(struct pipe_context *pipe, | |||
unsigned unit, | |||
struct pipe_mipmap_tree *texture) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->texture[unit] = texture; | |||
failover->dirty |= FO_NEW_TEXTURE; | |||
failover->dirty_texture |= (1<<unit); | |||
failover->hw->set_texture_state( failover->hw, unit, texture ); | |||
} | |||
static void | |||
failover_set_viewport_state( struct pipe_context *pipe, | |||
const struct pipe_viewport_state *viewport ) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->viewport = *viewport; | |||
failover->dirty |= FO_NEW_VIEWPORT; | |||
failover->hw->set_viewport_state( failover->hw, viewport ); | |||
} | |||
static void | |||
failover_set_vertex_buffer(struct pipe_context *pipe, | |||
unsigned unit, | |||
const struct pipe_vertex_buffer *vertex_buffer) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->vertex_buffer[unit] = *vertex_buffer; | |||
failover->dirty |= FO_NEW_VERTEX_BUFFER; | |||
failover->dirty_vertex_buffer |= (1<<unit); | |||
failover->hw->set_vertex_buffer( failover->hw, unit, vertex_buffer ); | |||
} | |||
static void | |||
failover_set_vertex_element(struct pipe_context *pipe, | |||
unsigned unit, | |||
const struct pipe_vertex_element *vertex_element) | |||
{ | |||
struct failover_context *failover = failover_context(pipe); | |||
failover->vertex_element[unit] = *vertex_element; | |||
failover->dirty |= FO_NEW_VERTEX_ELEMENT; | |||
failover->dirty_vertex_element |= (1<<unit); | |||
failover->hw->set_vertex_element( failover->hw, unit, vertex_element ); | |||
} | |||
void | |||
failover_init_state_functions( struct failover_context *failover ) | |||
{ | |||
failover->pipe.set_alpha_test_state = failover_set_alpha_test_state; | |||
failover->pipe.set_blend_color = failover_set_blend_color; | |||
failover->pipe.set_blend_state = failover_set_blend_state; | |||
failover->pipe.set_clip_state = failover_set_clip_state; | |||
failover->pipe.set_clear_color_state = failover_set_clear_color_state; | |||
failover->pipe.set_depth_state = failover_set_depth_test_state; | |||
failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; | |||
failover->pipe.set_fs_state = failover_set_fs_state; | |||
failover->pipe.set_vs_state = failover_set_vs_state; | |||
failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; | |||
failover->pipe.set_sampler_state = failover_set_sampler_state; | |||
failover->pipe.set_scissor_state = failover_set_scissor_state; | |||
failover->pipe.set_setup_state = failover_set_setup_state; | |||
failover->pipe.set_stencil_state = failover_set_stencil_state; | |||
failover->pipe.set_texture_state = failover_set_texture_state; | |||
failover->pipe.set_viewport_state = failover_set_viewport_state; | |||
failover->pipe.set_vertex_buffer = failover_set_vertex_buffer; | |||
failover->pipe.set_vertex_element = failover_set_vertex_element; | |||
} |
@@ -0,0 +1,131 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
/* Authors: Keith Whitwell <keith@tungstengraphics.com> | |||
*/ | |||
#include "fo_context.h" | |||
/* This looks like a lot of work at the moment - we're keeping a | |||
* duplicate copy of the state up-to-date. | |||
* | |||
* This can change in two ways: | |||
* - With constant state objects we would only need to save a pointer, | |||
* not the whole object. | |||
* - By adding a callback in the state tracker to re-emit state. The | |||
* state tracker knows the current state already and can re-emit it | |||
* without additional complexity. | |||
* | |||
* This works as a proof-of-concept, but a final version will have | |||
* lower overheads. | |||
*/ | |||
void | |||
failover_state_emit( struct failover_context *failover ) | |||
{ | |||
unsigned i; | |||
if (failover->dirty & FO_NEW_ALPHA_TEST) | |||
failover->hw->set_alpha_test_state( failover->hw, &failover->alpha_test ); | |||
if (failover->dirty & FO_NEW_BLEND) | |||
failover->hw->set_blend_state( failover->hw, &failover->blend ); | |||
if (failover->dirty & FO_NEW_BLEND_COLOR) | |||
failover->hw->set_blend_color( failover->hw, &failover->blend_color ); | |||
if (failover->dirty & FO_NEW_CLIP) | |||
failover->hw->set_clip_state( failover->hw, &failover->clip ); | |||
if (failover->dirty & FO_NEW_CLEAR_COLOR) | |||
failover->hw->set_clear_color_state( failover->hw, &failover->clear_color ); | |||
if (failover->dirty & FO_NEW_DEPTH_TEST) | |||
failover->hw->set_depth_state( failover->hw, &failover->depth_test ); | |||
if (failover->dirty & FO_NEW_FRAMEBUFFER) | |||
failover->hw->set_framebuffer_state( failover->hw, &failover->framebuffer ); | |||
if (failover->dirty & FO_NEW_FRAGMENT_SHADER) | |||
failover->hw->set_fs_state( failover->hw, &failover->fragment_shader ); | |||
if (failover->dirty & FO_NEW_VERTEX_SHADER) | |||
failover->hw->set_vs_state( failover->hw, &failover->vertex_shader ); | |||
if (failover->dirty & FO_NEW_STIPPLE) | |||
failover->hw->set_polygon_stipple( failover->hw, &failover->poly_stipple ); | |||
if (failover->dirty & FO_NEW_SETUP) | |||
failover->hw->set_setup_state( failover->hw, &failover->setup ); | |||
if (failover->dirty & FO_NEW_SCISSOR) | |||
failover->hw->set_scissor_state( failover->hw, &failover->scissor ); | |||
if (failover->dirty & FO_NEW_STENCIL) | |||
failover->hw->set_stencil_state( failover->hw, &failover->stencil ); | |||
if (failover->dirty & FO_NEW_VIEWPORT) | |||
failover->hw->set_viewport_state( failover->hw, &failover->viewport ); | |||
if (failover->dirty & FO_NEW_SAMPLER) { | |||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { | |||
if (failover->dirty_sampler & (1<<i)) { | |||
failover->hw->set_sampler_state( failover->hw, i, | |||
&failover->sampler[i] ); | |||
} | |||
} | |||
} | |||
if (failover->dirty & FO_NEW_TEXTURE) { | |||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { | |||
if (failover->dirty_texture & (1<<i)) { | |||
failover->hw->set_texture_state( failover->hw, i, | |||
failover->texture[i] ); | |||
} | |||
} | |||
} | |||
if (failover->dirty & FO_NEW_VERTEX_BUFFER) { | |||
for (i = 0; i < PIPE_ATTRIB_MAX; i++) { | |||
if (failover->dirty_vertex_buffer & (1<<i)) { | |||
failover->hw->set_vertex_buffer( failover->hw, i, | |||
&failover->vertex_buffer[i] ); | |||
} | |||
} | |||
} | |||
if (failover->dirty & FO_NEW_VERTEX_ELEMENT) { | |||
for (i = 0; i < PIPE_ATTRIB_MAX; i++) { | |||
if (failover->dirty_vertex_element & (1<<i)) { | |||
failover->hw->set_vertex_element( failover->hw, i, | |||
&failover->vertex_element[i] ); | |||
} | |||
} | |||
} | |||
failover->dirty = 0; | |||
} |
@@ -0,0 +1,45 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
#ifndef FO_WINSYS_H | |||
#define FO_WINSYS_H | |||
/* This is the interface that failover requires any window system | |||
* hosting it to implement. This is the only include file in failover | |||
* which is public. | |||
*/ | |||
struct pipe_context; | |||
struct pipe_context *failover_create( struct pipe_context *hw, | |||
struct pipe_context *sw ); | |||
#endif /* FO_WINSYS_H */ |
@@ -149,7 +149,7 @@ static void i915_destroy( struct pipe_context *pipe ) | |||
static void i915_draw_elements( struct pipe_context *pipe, | |||
static boolean i915_draw_elements( struct pipe_context *pipe, | |||
struct pipe_buffer_handle *indexBuffer, | |||
unsigned indexSize, | |||
unsigned prim, unsigned start, unsigned count) | |||
@@ -202,13 +202,15 @@ static void i915_draw_elements( struct pipe_context *pipe, | |||
pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); | |||
draw_set_mapped_element_buffer(draw, 0, NULL); | |||
} | |||
return TRUE; | |||
} | |||
static void i915_draw_arrays( struct pipe_context *pipe, | |||
unsigned prim, unsigned start, unsigned count) | |||
static boolean i915_draw_arrays( struct pipe_context *pipe, | |||
unsigned prim, unsigned start, unsigned count) | |||
{ | |||
i915_draw_elements(pipe, NULL, 0, prim, start, count); | |||
return i915_draw_elements(pipe, NULL, 0, prim, start, count); | |||
} | |||
@@ -29,6 +29,7 @@ | |||
#include "i915_context.h" | |||
#include "i915_fpc.h" | |||
#include "pipe/tgsi/core/tgsi_token.h" | |||
#include "pipe/tgsi/core/tgsi_parse.h" | |||
@@ -60,15 +60,16 @@ struct pipe_context { | |||
/* | |||
* Drawing | |||
* Drawing. | |||
* Return false on fallbacks (temporary??) | |||
*/ | |||
void (*draw_arrays)( struct pipe_context *pipe, | |||
unsigned mode, unsigned start, unsigned count); | |||
boolean (*draw_arrays)( struct pipe_context *pipe, | |||
unsigned mode, unsigned start, unsigned count); | |||
void (*draw_elements)( struct pipe_context *pipe, | |||
struct pipe_buffer_handle *indexBuffer, | |||
unsigned indexSize, | |||
unsigned mode, unsigned start, unsigned count); | |||
boolean (*draw_elements)( struct pipe_context *pipe, | |||
struct pipe_buffer_handle *indexBuffer, | |||
unsigned indexSize, | |||
unsigned mode, unsigned start, unsigned count); | |||
/** Clear a surface to given value (no scissor; clear whole surface) */ | |||
void (*clear)(struct pipe_context *pipe, struct pipe_surface *ps, |
@@ -43,11 +43,11 @@ | |||
void | |||
boolean | |||
softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, | |||
unsigned start, unsigned count) | |||
{ | |||
softpipe_draw_elements(pipe, NULL, 0, mode, start, count); | |||
return softpipe_draw_elements(pipe, NULL, 0, mode, start, count); | |||
} | |||
@@ -59,7 +59,7 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, | |||
* | |||
* XXX should the element buffer be specified/bound with a separate function? | |||
*/ | |||
void | |||
boolean | |||
softpipe_draw_elements(struct pipe_context *pipe, | |||
struct pipe_buffer_handle *indexBuffer, | |||
unsigned indexSize, | |||
@@ -73,7 +73,7 @@ softpipe_draw_elements(struct pipe_context *pipe, | |||
draw_prim_info( mode, &first, &incr ); | |||
length = draw_trim( count, first, incr ); | |||
if (!length) | |||
return; | |||
return TRUE; | |||
if (sp->dirty) | |||
@@ -123,4 +123,6 @@ softpipe_draw_elements(struct pipe_context *pipe, | |||
} | |||
softpipe_unmap_surfaces(sp); | |||
return TRUE; | |||
} |
@@ -95,13 +95,13 @@ void softpipe_set_vertex_buffer(struct pipe_context *, | |||
void softpipe_update_derived( struct softpipe_context *softpipe ); | |||
void softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, | |||
unsigned start, unsigned count); | |||
boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, | |||
unsigned start, unsigned count); | |||
void softpipe_draw_elements(struct pipe_context *pipe, | |||
struct pipe_buffer_handle *indexBuffer, | |||
unsigned indexSize, | |||
unsigned mode, unsigned start, unsigned count); | |||
boolean softpipe_draw_elements(struct pipe_context *pipe, | |||
struct pipe_buffer_handle *indexBuffer, | |||
unsigned indexSize, | |||
unsigned mode, unsigned start, unsigned count); | |||
void |