1/************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. 4 * Copyright 2007 VMware, Inc. 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 VMWARE 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@vmware.com> 31 * @author Keith Whitwell <keithw@vmware.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 44static void * 45llvmpipe_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 61static void 62llvmpipe_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 77static void 78llvmpipe_delete_blend_state(struct pipe_context *pipe, void *blend) 79{ 80 FREE( blend ); 81} 82 83 84static void 85llvmpipe_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 109static void * 110llvmpipe_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 132static void 133llvmpipe_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 149static void 150llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) 151{ 152 FREE( depth ); 153} 154 155 156static void 157llvmpipe_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 176static void 177llvmpipe_set_sample_mask(struct pipe_context *pipe, 178 unsigned sample_mask) 179{ 180 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 181 182 if (sample_mask != llvmpipe->sample_mask) { 183 llvmpipe->sample_mask = sample_mask; 184 185 llvmpipe->dirty |= LP_NEW_RASTERIZER; 186 } 187} 188 189void 190llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe) 191{ 192 llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state; 193 llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state; 194 llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state; 195 196 llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state; 197 llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state; 198 llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state; 199 200 llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color; 201 202 llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref; 203 llvmpipe->pipe.set_sample_mask = llvmpipe_set_sample_mask; 204 205 llvmpipe->sample_mask = ~0; 206} 207