i915_state_derived.c revision d64561472b8a7fa20512a6586d724c7c7b2867b3
1/************************************************************************** 2 * 3 * Copyright 2003 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 29#include "util/u_memory.h" 30#include "pipe/p_shader_tokens.h" 31#include "draw/draw_context.h" 32#include "draw/draw_vertex.h" 33#include "i915_context.h" 34#include "i915_state.h" 35#include "i915_debug.h" 36#include "i915_reg.h" 37 38 39 40/*********************************************************************** 41 * Determine the hardware vertex layout. 42 * Depends on vertex/fragment shader state. 43 */ 44static void calculate_vertex_layout(struct i915_context *i915) 45{ 46 const struct i915_fragment_shader *fs = i915->fs; 47 const enum interp_mode colorInterp = i915->rasterizer->color_interp; 48 struct vertex_info vinfo; 49 boolean texCoords[8], colors[2], fog, needW; 50 uint i; 51 int src; 52 53 memset(texCoords, 0, sizeof(texCoords)); 54 colors[0] = colors[1] = fog = needW = FALSE; 55 memset(&vinfo, 0, sizeof(vinfo)); 56 57 /* Determine which fragment program inputs are needed. Setup HW vertex 58 * layout below, in the HW-specific attribute order. 59 */ 60 for (i = 0; i < fs->info.num_inputs; i++) { 61 switch (fs->info.input_semantic_name[i]) { 62 case TGSI_SEMANTIC_POSITION: 63 break; 64 case TGSI_SEMANTIC_COLOR: 65 assert(fs->info.input_semantic_index[i] < 2); 66 colors[fs->info.input_semantic_index[i]] = TRUE; 67 break; 68 case TGSI_SEMANTIC_GENERIC: 69 /* usually a texcoord */ 70 { 71 const uint unit = fs->info.input_semantic_index[i]; 72 assert(unit < 8); 73 texCoords[unit] = TRUE; 74 needW = TRUE; 75 } 76 break; 77 case TGSI_SEMANTIC_FOG: 78 fog = TRUE; 79 break; 80 default: 81 assert(0); 82 } 83 } 84 85 86 /* pos */ 87 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0); 88 if (needW) { 89 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src); 90 vinfo.hwfmt[0] |= S4_VFMT_XYZW; 91 vinfo.attrib[0].emit = EMIT_4F; 92 } 93 else { 94 draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src); 95 vinfo.hwfmt[0] |= S4_VFMT_XYZ; 96 vinfo.attrib[0].emit = EMIT_3F; 97 } 98 99 /* hardware point size */ 100 /* XXX todo */ 101 102 /* primary color */ 103 if (colors[0]) { 104 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0); 105 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src); 106 vinfo.hwfmt[0] |= S4_VFMT_COLOR; 107 } 108 109 /* secondary color */ 110 if (colors[1]) { 111 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1); 112 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src); 113 vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; 114 } 115 116 /* fog coord, not fog blend factor */ 117 if (fog) { 118 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0); 119 draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); 120 vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM; 121 } 122 123 /* texcoords */ 124 for (i = 0; i < 8; i++) { 125 uint hwtc; 126 if (texCoords[i]) { 127 hwtc = TEXCOORDFMT_4D; 128 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, i); 129 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); 130 } 131 else { 132 hwtc = TEXCOORDFMT_NOT_PRESENT; 133 } 134 vinfo.hwfmt[1] |= hwtc << (i * 4); 135 } 136 137 draw_compute_vertex_size(&vinfo); 138 139 if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { 140 /* Need to set this flag so that the LIS2/4 registers get set. 141 * It also means the i915_update_immediate() function must be called 142 * after this one, in i915_update_derived(). 143 */ 144 i915->dirty |= I915_NEW_VERTEX_FORMAT; 145 146 memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo)); 147 } 148} 149 150struct i915_tracked_state i915_update_vertex_layout = { 151 "vertex_layout", 152 calculate_vertex_layout, 153 I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS 154}; 155 156 157 158/*********************************************************************** 159 * Update fragment state 160 */ 161static void update_fs(struct i915_context *i915) 162{ 163 i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ 164} 165 166struct i915_tracked_state i915_hw_fs = { 167 "fs", 168 update_fs, 169 I915_NEW_FS 170}; 171 172 173 174/*********************************************************************** 175 */ 176static struct i915_tracked_state *atoms[] = { 177 &i915_update_vertex_layout, 178 &i915_hw_samplers, 179 &i915_hw_sampler_views, 180 &i915_hw_immediate, 181 &i915_hw_dynamic, 182 &i915_hw_fs, 183 &i915_hw_framebuffer, 184 NULL, 185}; 186 187void i915_update_derived(struct i915_context *i915) 188{ 189 int i; 190 191 if (I915_DBG_ON(DBG_ATOMS)) 192 i915_dump_dirty(i915, __FUNCTION__); 193 194 for (i = 0; atoms[i]; i++) 195 if (atoms[i]->dirty & i915->dirty) 196 atoms[i]->update(i915); 197 198 i915->dirty = 0; 199} 200