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: 29 * Keith Whitwell <keith (at) tungstengraphics.com> 30 */ 31 32 #include "i915_state_inlines.h" 33 #include "i915_context.h" 34 #include "i915_state.h" 35 #include "i915_reg.h" 36 #include "util/u_memory.h" 37 38 39 /* Convinience function to check immediate state. 40 */ 41 42 static INLINE void set_immediate(struct i915_context *i915, 43 unsigned offset, 44 const unsigned state) 45 { 46 if (i915->current.immediate[offset] == state) 47 return; 48 49 i915->current.immediate[offset] = state; 50 i915->immediate_dirty |= 1 << offset; 51 i915->hardware_dirty |= I915_HW_IMMEDIATE; 52 } 53 54 55 56 /*********************************************************************** 57 * S0,S1: Vertex buffer state. 58 */ 59 static void upload_S0S1(struct i915_context *i915) 60 { 61 unsigned LIS0, LIS1; 62 63 /* I915_NEW_VBO 64 */ 65 LIS0 = i915->vbo_offset; 66 67 /* Need to force this */ 68 if (i915->dirty & I915_NEW_VBO) { 69 i915->immediate_dirty |= 1 << I915_IMMEDIATE_S0; 70 i915->hardware_dirty |= I915_HW_IMMEDIATE; 71 } 72 73 /* I915_NEW_VERTEX_SIZE 74 */ 75 { 76 unsigned vertex_size = i915->current.vertex_info.size; 77 78 LIS1 = ((vertex_size << 24) | 79 (vertex_size << 16)); 80 } 81 82 set_immediate(i915, I915_IMMEDIATE_S0, LIS0); 83 set_immediate(i915, I915_IMMEDIATE_S1, LIS1); 84 } 85 86 const struct i915_tracked_state i915_upload_S0S1 = { 87 "imm S0 S1", 88 upload_S0S1, 89 I915_NEW_VBO | I915_NEW_VERTEX_FORMAT 90 }; 91 92 93 94 /*********************************************************************** 95 * S4: Vertex format, rasterization state 96 */ 97 static void upload_S2S4(struct i915_context *i915) 98 { 99 unsigned LIS2, LIS4; 100 101 /* I915_NEW_VERTEX_FORMAT 102 */ 103 { 104 LIS2 = i915->current.vertex_info.hwfmt[1]; 105 LIS4 = i915->current.vertex_info.hwfmt[0]; 106 assert(LIS4); /* should never be zero? */ 107 } 108 109 LIS4 |= i915->rasterizer->LIS4; 110 111 set_immediate(i915, I915_IMMEDIATE_S2, LIS2); 112 set_immediate(i915, I915_IMMEDIATE_S4, LIS4); 113 } 114 115 const struct i915_tracked_state i915_upload_S2S4 = { 116 "imm S2 S4", 117 upload_S2S4, 118 I915_NEW_RASTERIZER | I915_NEW_VERTEX_FORMAT 119 }; 120 121 122 123 /*********************************************************************** 124 */ 125 static void upload_S5(struct i915_context *i915) 126 { 127 unsigned LIS5 = 0; 128 129 /* I915_NEW_DEPTH_STENCIL 130 */ 131 LIS5 |= i915->depth_stencil->stencil_LIS5; 132 /* hope it's safe to set stencil ref value even if stencil test is disabled? */ 133 LIS5 |= i915->stencil_ref.ref_value[0] << S5_STENCIL_REF_SHIFT; 134 135 /* I915_NEW_BLEND 136 */ 137 LIS5 |= i915->blend->LIS5; 138 139 #if 0 140 /* I915_NEW_RASTERIZER 141 */ 142 if (i915->rasterizer->LIS7) { 143 LIS5 |= S5_GLOBAL_DEPTH_OFFSET_ENABLE; 144 } 145 #endif 146 147 set_immediate(i915, I915_IMMEDIATE_S5, LIS5); 148 } 149 150 const struct i915_tracked_state i915_upload_S5 = { 151 "imm S5", 152 upload_S5, 153 I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_RASTERIZER 154 }; 155 156 157 158 /*********************************************************************** 159 */ 160 static void upload_S6(struct i915_context *i915) 161 { 162 unsigned LIS6 = (2 << S6_TRISTRIP_PV_SHIFT); 163 164 /* I915_NEW_FRAMEBUFFER 165 */ 166 if (i915->framebuffer.cbufs[0]) 167 LIS6 |= S6_COLOR_WRITE_ENABLE; 168 169 /* I915_NEW_BLEND 170 */ 171 LIS6 |= i915->blend->LIS6; 172 173 /* I915_NEW_DEPTH 174 */ 175 LIS6 |= i915->depth_stencil->depth_LIS6; 176 177 set_immediate(i915, I915_IMMEDIATE_S6, LIS6); 178 } 179 180 const struct i915_tracked_state i915_upload_S6 = { 181 "imm S6", 182 upload_S6, 183 I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL | I915_NEW_FRAMEBUFFER 184 }; 185 186 187 188 /*********************************************************************** 189 */ 190 static void upload_S7(struct i915_context *i915) 191 { 192 #if 0 193 unsigned LIS7; 194 195 /* I915_NEW_RASTERIZER 196 */ 197 LIS7 = i915->rasterizer->LIS7; 198 199 set_immediate(i915, I915_IMMEDIATE_S7, LIS7); 200 #endif 201 } 202 203 const struct i915_tracked_state i915_upload_S7 = { 204 "imm S7", 205 upload_S7, 206 I915_NEW_RASTERIZER 207 }; 208 209 210 211 /*********************************************************************** 212 */ 213 static const struct i915_tracked_state *atoms[] = { 214 &i915_upload_S0S1, 215 &i915_upload_S2S4, 216 &i915_upload_S5, 217 &i915_upload_S6, 218 &i915_upload_S7 219 }; 220 221 static void update_immediate(struct i915_context *i915) 222 { 223 int i; 224 225 for (i = 0; i < Elements(atoms); i++) 226 if (i915->dirty & atoms[i]->dirty) 227 atoms[i]->update(i915); 228 } 229 230 struct i915_tracked_state i915_hw_immediate = { 231 "immediate", 232 update_immediate, 233 ~0 /* all state atoms, becuase we do internal checking */ 234 }; 235