Use write posting in the kickoff function too.
[mesa.git] / src / mesa / pipe / i915simple / 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 "pipe/p_util.h"
30 #include "pipe/draw/draw_context.h"
31 #include "pipe/draw/draw_vertex.h"
32 #include "i915_context.h"
33 #include "i915_state.h"
34 #include "i915_reg.h"
35 #include "i915_fpc.h"
36 #include "pipe/tgsi/exec/tgsi_token.h"
37
38
39 /**
40 * Determine which post-transform / pre-rasterization vertex attributes
41 * we need.
42 * Derived from: fs, setup states.
43 */
44 static void calculate_vertex_layout( struct i915_context *i915 )
45 {
46 const struct pipe_shader_state *fs = i915->fs;
47 const enum interp_mode colorInterp = i915->rasterizer->color_interp;
48 struct vertex_info vinfo;
49 uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
50 boolean needW = 0;
51 uint i;
52 boolean texCoords[8];
53
54 memset(texCoords, 0, sizeof(texCoords));
55 memset(&vinfo, 0, sizeof(vinfo));
56
57 /* pos */
58 draw_emit_vertex_attr(&vinfo, FORMAT_3F, INTERP_LINEAR);
59 /* Note: we'll set the S4_VFMT_XYZ[W] bits below */
60
61 for (i = 0; i < fs->num_inputs; i++) {
62 switch (fs->input_semantic_name[i]) {
63 case TGSI_SEMANTIC_POSITION:
64 break;
65 case TGSI_SEMANTIC_COLOR:
66 if (fs->input_semantic_index[i] == 0) {
67 front0 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp);
68 vinfo.hwfmt[0] |= S4_VFMT_COLOR;
69 }
70 else {
71 assert(fs->input_semantic_index[i] == 1);
72 front1 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp);
73 vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
74 }
75 break;
76 case TGSI_SEMANTIC_GENERIC:
77 /* usually a texcoord */
78 {
79 const uint unit = fs->input_semantic_index[i];
80 uint hwtc;
81 texCoords[unit] = TRUE;
82 draw_emit_vertex_attr(&vinfo, FORMAT_4F, INTERP_PERSPECTIVE);
83 hwtc = TEXCOORDFMT_4D;
84 needW = TRUE;
85 vinfo.hwfmt[1] |= hwtc << (unit * 4);
86 }
87 break;
88 case TGSI_SEMANTIC_FOG:
89 fprintf(stderr, "i915 fogcoord not implemented yet\n");
90 draw_emit_vertex_attr(&vinfo, FORMAT_1F, INTERP_PERSPECTIVE);
91 break;
92 default:
93 assert(0);
94 }
95
96 }
97
98 /* finish up texcoord fields */
99 for (i = 0; i < 8; i++) {
100 if (!texCoords[i]) {
101 const uint hwtc = TEXCOORDFMT_NOT_PRESENT;
102 vinfo.hwfmt[1] |= hwtc << (i* 4);
103 }
104 }
105
106 /* go back and fill in the vertex position info now that we have needW */
107 if (needW) {
108 vinfo.hwfmt[0] |= S4_VFMT_XYZW;
109 vinfo.format[0] = FORMAT_4F;
110 }
111 else {
112 vinfo.hwfmt[0] |= S4_VFMT_XYZ;
113 vinfo.format[0] = FORMAT_3F;
114 }
115
116 /* Additional attributes required for setup: Just twosided
117 * lighting. Edgeflag is dealt with specially by setting bits in
118 * the vertex header.
119 */
120 if (i915->rasterizer->light_twoside) {
121 if (front0) {
122 back0 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp);
123 }
124 if (back0) {
125 back1 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp);
126 }
127 }
128
129 draw_compute_vertex_size(&vinfo);
130
131 if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
132 /* If the attributes have changed, tell the draw module about the new
133 * vertex layout. We'll also update the hardware vertex format info.
134 */
135 draw_set_vertex_attributes( i915->draw,
136 NULL,/*vinfo.slot_to_attrib,*/
137 vinfo.interp_mode,
138 vinfo.num_attribs);
139
140 draw_set_twoside_attributes(i915->draw,
141 front0, back0, front1, back1);
142
143 /* Need to set this flag so that the LIS2/4 registers get set.
144 * It also means the i915_update_immediate() function must be called
145 * after this one, in i915_update_derived().
146 */
147 i915->dirty |= I915_NEW_VERTEX_FORMAT;
148
149 memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo));
150 }
151 }
152
153
154
155
156 /* Hopefully this will remain quite simple, otherwise need to pull in
157 * something like the state tracker mechanism.
158 */
159 void i915_update_derived( struct i915_context *i915 )
160 {
161 if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS))
162 calculate_vertex_layout( i915 );
163
164 if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE))
165 i915_update_samplers(i915);
166
167 if (i915->dirty & I915_NEW_TEXTURE)
168 i915_update_textures(i915);
169
170 if (i915->dirty)
171 i915_update_immediate( i915 );
172
173 if (i915->dirty)
174 i915_update_dynamic( i915 );
175
176 if (i915->dirty & I915_NEW_FS) {
177 i915_translate_fragment_program(i915);
178 i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */
179 }
180
181 /* HW emit currently references framebuffer state directly:
182 */
183 if (i915->dirty & I915_NEW_FRAMEBUFFER)
184 i915->hardware_dirty |= I915_HW_STATIC;
185
186 i915->dirty = 0;
187 }