1/************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 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 VMWARE 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#include "draw/draw_context.h" 29#include "draw/draw_vertex.h" 30#include "pipe/p_shader_tokens.h" 31#include "util/log.h" 32#include "util/u_memory.h" 33#include "i915_context.h" 34#include "i915_debug.h" 35#include "i915_fpc.h" 36#include "i915_reg.h" 37#include "i915_state.h" 38 39 40/*********************************************************************** 41 * Determine the hardware vertex layout. 42 * Depends on vertex/fragment shader state. 43 */ 44static void 45calculate_vertex_layout(struct i915_context *i915) 46{ 47 const struct i915_fragment_shader *fs = i915->fs; 48 struct vertex_info vinfo; 49 bool colors[2], fog, needW, face; 50 uint32_t i; 51 int src; 52 53 colors[0] = colors[1] = fog = needW = face = 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 case TGSI_SEMANTIC_PCOORD: 63 case TGSI_SEMANTIC_FACE: 64 /* Handled as texcoord inputs below */ 65 break; 66 case TGSI_SEMANTIC_COLOR: 67 assert(fs->info.input_semantic_index[i] < 2); 68 colors[fs->info.input_semantic_index[i]] = true; 69 break; 70 case TGSI_SEMANTIC_TEXCOORD: 71 case TGSI_SEMANTIC_GENERIC: 72 needW = true; 73 break; 74 case TGSI_SEMANTIC_FOG: 75 fog = true; 76 break; 77 default: 78 debug_printf("Unknown input type %d\n", 79 fs->info.input_semantic_name[i]); 80 assert(0); 81 } 82 } 83 84 /* pos */ 85 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0); 86 if (needW) { 87 draw_emit_vertex_attr(&vinfo, EMIT_4F, src); 88 vinfo.hwfmt[0] |= S4_VFMT_XYZW; 89 vinfo.attrib[0].emit = EMIT_4F; 90 } else { 91 draw_emit_vertex_attr(&vinfo, EMIT_3F, src); 92 vinfo.hwfmt[0] |= S4_VFMT_XYZ; 93 vinfo.attrib[0].emit = EMIT_3F; 94 } 95 96 /* point size. if not emitted here, then point size comes from LIS4. */ 97 if (i915->rasterizer->templ.point_size_per_vertex) { 98 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_PSIZE, 0); 99 if (src != -1) { 100 draw_emit_vertex_attr(&vinfo, EMIT_1F, src); 101 vinfo.hwfmt[0] |= S4_VFMT_POINT_WIDTH; 102 } 103 } 104 105 /* primary color */ 106 if (colors[0]) { 107 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0); 108 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src); 109 vinfo.hwfmt[0] |= S4_VFMT_COLOR; 110 } 111 112 /* secondary color */ 113 if (colors[1]) { 114 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1); 115 draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src); 116 vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; 117 } 118 119 /* fog coord, not fog blend factor */ 120 if (fog) { 121 src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0); 122 draw_emit_vertex_attr(&vinfo, EMIT_1F, src); 123 vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM; 124 } 125 126 /* texcoords/varyings */ 127 for (i = 0; i < I915_TEX_UNITS; i++) { 128 uint32_t hwtc; 129 if (fs->texcoords[i].semantic != -1) { 130 src = draw_find_shader_output(i915->draw, fs->texcoords[i].semantic, 131 fs->texcoords[i].index); 132 if (fs->texcoords[i].semantic == TGSI_SEMANTIC_FACE) { 133 /* XXX Because of limitations in the draw module, currently src will 134 * be 0 for SEMANTIC_FACE, so this aliases to POS. We need to fix in 135 * the draw module by adding an extra shader output. 136 */ 137 mesa_loge("Front/back face is broken\n"); 138 draw_emit_vertex_attr(&vinfo, EMIT_1F, src); 139 hwtc = TEXCOORDFMT_1D; 140 } else { 141 hwtc = TEXCOORDFMT_4D; 142 draw_emit_vertex_attr(&vinfo, EMIT_4F, src); 143 } 144 } else { 145 hwtc = TEXCOORDFMT_NOT_PRESENT; 146 } 147 vinfo.hwfmt[1] |= hwtc << (i * 4); 148 } 149 150 draw_compute_vertex_size(&vinfo); 151 152 if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { 153 /* Need to set this flag so that the LIS2/4 registers get set. 154 * It also means the i915_update_immediate() function must be called 155 * after this one, in i915_update_derived(). 156 */ 157 i915->dirty |= I915_NEW_VERTEX_FORMAT; 158 159 memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo)); 160 } 161} 162 163struct i915_tracked_state i915_update_vertex_layout = { 164 "vertex_layout", calculate_vertex_layout, 165 I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS}; 166 167/*********************************************************************** 168 */ 169static struct i915_tracked_state *atoms[] = { 170 &i915_update_vertex_layout, &i915_hw_samplers, &i915_hw_immediate, 171 &i915_hw_dynamic, &i915_hw_fs, &i915_hw_framebuffer, 172 &i915_hw_dst_buf_vars, &i915_hw_constants, NULL, 173}; 174 175void 176i915_update_derived(struct i915_context *i915) 177{ 178 int i; 179 180 if (I915_DBG_ON(DBG_ATOMS)) 181 i915_dump_dirty(i915, __FUNCTION__); 182 183 if (!i915->fs) { 184 i915->dirty &= ~(I915_NEW_FS_CONSTANTS | I915_NEW_FS); 185 i915->hardware_dirty &= ~(I915_HW_PROGRAM | I915_HW_CONSTANTS); 186 } 187 188 if (!i915->vs) 189 i915->dirty &= ~I915_NEW_VS; 190 191 if (!i915->blend) 192 i915->dirty &= ~I915_NEW_BLEND; 193 194 if (!i915->rasterizer) 195 i915->dirty &= ~I915_NEW_RASTERIZER; 196 197 if (!i915->depth_stencil) 198 i915->dirty &= ~I915_NEW_DEPTH_STENCIL; 199 200 for (i = 0; atoms[i]; i++) 201 if (atoms[i]->dirty & i915->dirty) 202 atoms[i]->update(i915); 203 204 i915->dirty = 0; 205} 206