i915g: Move fragment state to its own file
[mesa.git] / src / gallium / drivers / i915 / i915_state_derived.c
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 */
44 static 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
150 struct 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 */
160 static struct i915_tracked_state *atoms[] = {
161 &i915_update_vertex_layout,
162 &i915_hw_samplers,
163 &i915_hw_sampler_views,
164 &i915_hw_immediate,
165 &i915_hw_dynamic,
166 &i915_hw_fs,
167 &i915_hw_framebuffer,
168 &i915_hw_constants,
169 NULL,
170 };
171
172 void i915_update_derived(struct i915_context *i915)
173 {
174 int i;
175
176 if (I915_DBG_ON(DBG_ATOMS))
177 i915_dump_dirty(i915, __FUNCTION__);
178
179 for (i = 0; atoms[i]; i++)
180 if (atoms[i]->dirty & i915->dirty)
181 atoms[i]->update(i915);
182
183 i915->dirty = 0;
184 }