i915_state_derived.c revision fe306e7ea5e789adc955653d9be8cd7f8af47264
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_reg.h" 36 37 38 39/** 40 * Determine the hardware vertex layout. 41 * Depends on vertex/fragment shader state. 42 */ 43static void calculate_vertex_layout( struct i915_context *i915 ) 44{ 45 const struct i915_fragment_shader *fs = i915->fs; 46 const enum interp_mode colorInterp = i915->rasterizer->color_interp; 47 struct vertex_info vinfo; 48 boolean texCoords[8], colors[2], fog, needW; 49 uint i; 50 int src; 51 52 memset(texCoords, 0, sizeof(texCoords)); 53 colors[0] = colors[1] = fog = needW = FALSE; 54 memset(&vinfo, 0, sizeof(vinfo)); 55 56 /* Determine which fragment program inputs are needed. Setup HW vertex 57 * layout below, in the HW-specific attribute order. 58 */ 59 for (i = 0; i < fs->info.num_inputs; i++) { 60 switch (fs->info.input_semantic_name[i]) { 61 case TGSI_SEMANTIC_POSITION: 62 break; 63 case TGSI_SEMANTIC_COLOR: 64 assert(fs->info.input_semantic_index[i] < 2); 65 colors[fs->info.input_semantic_index[i]] = TRUE; 66 break; 67 case TGSI_SEMANTIC_GENERIC: 68 /* usually a texcoord */ 69 { 70 const uint unit = fs->info.input_semantic_index[i]; 71 assert(unit < 8); 72 texCoords[unit] = TRUE; 73 needW = TRUE; 74 } 75 break; 76 case TGSI_SEMANTIC_FOG: 77 fog = TRUE; 78 break; 79 default: 80 assert(0); 81 } 82 } 83 84 85 /* pos */ 86 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0); 87 if (needW) { 88 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src); 89 vinfo.hwfmt[0] |= S4_VFMT_XYZW; 90 vinfo.attrib[0].emit = EMIT_4F; 91 } 92 else { 93 draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src); 94 vinfo.hwfmt[0] |= S4_VFMT_XYZ; 95 vinfo.attrib[0].emit = EMIT_3F; 96 } 97 98 /* hardware point size */ 99 /* XXX todo */ 100 101 /* primary color */ 102 if (colors[0]) { 103 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0); 104 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src); 105 vinfo.hwfmt[0] |= S4_VFMT_COLOR; 106 } 107 108 /* secondary color */ 109 if (colors[1]) { 110 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1); 111 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src); 112 vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; 113 } 114 115 /* fog coord, not fog blend factor */ 116 if (fog) { 117 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0); 118 draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); 119 vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM; 120 } 121 122 /* texcoords */ 123 for (i = 0; i < 8; i++) { 124 uint hwtc; 125 if (texCoords[i]) { 126 hwtc = TEXCOORDFMT_4D; 127 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, i); 128 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); 129 } 130 else { 131 hwtc = TEXCOORDFMT_NOT_PRESENT; 132 } 133 vinfo.hwfmt[1] |= hwtc << (i * 4); 134 } 135 136 draw_compute_vertex_size(&vinfo); 137 138 if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { 139 /* Need to set this flag so that the LIS2/4 registers get set. 140 * It also means the i915_update_immediate() function must be called 141 * after this one, in i915_update_derived(). 142 */ 143 i915->dirty |= I915_NEW_VERTEX_FORMAT; 144 145 memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo)); 146 } 147} 148 149 150 151 152/* Hopefully this will remain quite simple, otherwise need to pull in 153 * something like the state tracker mechanism. 154 */ 155void i915_update_derived( struct i915_context *i915 ) 156{ 157 if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS)) 158 calculate_vertex_layout( i915 ); 159 160 if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW)) 161 i915_update_samplers(i915); 162 163 if (i915->dirty & I915_NEW_SAMPLER_VIEW) 164 i915_update_textures(i915); 165 166 if (i915->dirty) 167 i915_update_immediate( i915 ); 168 169 if (i915->dirty) 170 i915_update_dynamic( i915 ); 171 172 if (i915->dirty & I915_NEW_FS) { 173 i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ 174 } 175 176 /* HW emit currently references framebuffer state directly: 177 */ 178 if (i915->dirty & I915_NEW_FRAMEBUFFER) 179 i915->hardware_dirty |= I915_HW_STATIC; 180 181 i915->dirty = 0; 182} 183