llvmpipe: move rasterizer to screen instead of setup context
[profile/ivi/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 }