1 /************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. 4 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29 /** 30 * @author Jose Fonseca <jfonseca (at) vmware.com> 31 * @author Keith Whitwell <keith (at) tungstengraphics.com> 32 */ 33 34 #include "util/u_memory.h" 35 #include "util/u_math.h" 36 #include "util/u_dump.h" 37 #include "draw/draw_context.h" 38 #include "lp_screen.h" 39 #include "lp_context.h" 40 #include "lp_state.h" 41 #include "lp_debug.h" 42 43 44 static void * 45 llvmpipe_create_blend_state(struct pipe_context *pipe, 46 const struct pipe_blend_state *blend) 47 { 48 struct pipe_blend_state *state = mem_dup(blend, sizeof *blend); 49 int i; 50 51 if (LP_PERF & PERF_NO_BLEND) { 52 state->independent_blend_enable = 0; 53 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) 54 state->rt[i].blend_enable = 0; 55 } 56 57 return state; 58 } 59 60 61 static void 62 llvmpipe_bind_blend_state(struct pipe_context *pipe, void *blend) 63 { 64 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 65 66 if (llvmpipe->blend == blend) 67 return; 68 69 draw_flush(llvmpipe->draw); 70 71 llvmpipe->blend = blend; 72 73 llvmpipe->dirty |= LP_NEW_BLEND; 74 } 75 76 77 static void 78 llvmpipe_delete_blend_state(struct pipe_context *pipe, void *blend) 79 { 80 FREE( blend ); 81 } 82 83 84 static void 85 llvmpipe_set_blend_color(struct pipe_context *pipe, 86 const struct pipe_blend_color *blend_color) 87 { 88 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 89 90 if(!blend_color) 91 return; 92 93 if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0) 94 return; 95 96 draw_flush(llvmpipe->draw); 97 98 memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color); 99 100 llvmpipe->dirty |= LP_NEW_BLEND_COLOR; 101 } 102 103 104 /** XXX move someday? Or consolidate all these simple state setters 105 * into one file. 106 */ 107 108 109 static void * 110 llvmpipe_create_depth_stencil_state(struct pipe_context *pipe, 111 const struct pipe_depth_stencil_alpha_state *depth_stencil) 112 { 113 struct pipe_depth_stencil_alpha_state *state; 114 115 state = mem_dup(depth_stencil, sizeof *depth_stencil); 116 117 if (LP_PERF & PERF_NO_DEPTH) { 118 state->depth.enabled = 0; 119 state->depth.writemask = 0; 120 state->stencil[0].enabled = 0; 121 state->stencil[1].enabled = 0; 122 } 123 124 if (LP_PERF & PERF_NO_ALPHATEST) { 125 state->alpha.enabled = 0; 126 } 127 128 return state; 129 } 130 131 132 static void 133 llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe, 134 void *depth_stencil) 135 { 136 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 137 138 if (llvmpipe->depth_stencil == depth_stencil) 139 return; 140 141 draw_flush(llvmpipe->draw); 142 143 llvmpipe->depth_stencil = depth_stencil; 144 145 llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA; 146 } 147 148 149 static void 150 llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) 151 { 152 FREE( depth ); 153 } 154 155 156 static void 157 llvmpipe_set_stencil_ref(struct pipe_context *pipe, 158 const struct pipe_stencil_ref *stencil_ref) 159 { 160 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 161 162 if(!stencil_ref) 163 return; 164 165 if(memcmp(&llvmpipe->stencil_ref, stencil_ref, sizeof *stencil_ref) == 0) 166 return; 167 168 draw_flush(llvmpipe->draw); 169 170 memcpy(&llvmpipe->stencil_ref, stencil_ref, sizeof *stencil_ref); 171 172 /* not sure. want new flag? */ 173 llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA; 174 } 175 176 static void 177 llvmpipe_set_sample_mask(struct pipe_context *pipe, 178 unsigned sample_mask) 179 { 180 } 181 182 void 183 llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe) 184 { 185 llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state; 186 llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state; 187 llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state; 188 189 llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state; 190 llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state; 191 llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state; 192 193 llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color; 194 195 llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref; 196 llvmpipe->pipe.set_sample_mask = llvmpipe_set_sample_mask; 197 } 198