Merge branch 'master' of git+ssh://michal@git.freedesktop.org/git/mesa/mesa into...
[mesa.git] / src / mesa / pipe / softpipe / sp_quad_fs.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /* Vertices are just an array of floats, with all the attributes
26 * packed. We currently assume a layout like:
27 *
28 * attr[0][0..3] - window position
29 * attr[1..n][0..3] - remaining attributes.
30 *
31 * Attributes are assumed to be 4 floats wide but are packed so that
32 * all the enabled attributes run contiguously.
33 */
34
35 #include "glheader.h"
36 #include "imports.h"
37 #include "sp_context.h"
38 #include "sp_headers.h"
39 #include "sp_quad.h"
40
41 struct exec_machine {
42 const struct setup_coefficient *coef;
43
44 GLfloat attr[FRAG_ATTRIB_MAX][4][QUAD_SIZE];
45 };
46
47
48 /**
49 * Compute quad's attributes values, as constants (GL_FLAT shading).
50 */
51 static INLINE void cinterp( struct exec_machine *exec,
52 GLuint attrib,
53 GLuint i )
54 {
55 GLuint j;
56
57 for (j = 0; j < QUAD_SIZE; j++) {
58 exec->attr[attrib][i][j] = exec->coef[attrib].a0[i];
59 }
60 }
61
62
63 /**
64 * Compute quad's attribute values by linear interpolation.
65 *
66 * Push into the fp:
67 *
68 * INPUT[attr] = MAD COEF_A0[attr], COEF_DADX[attr], INPUT_WPOS.xxxx
69 * INPUT[attr] = MAD INPUT[attr], COEF_DADY[attr], INPUT_WPOS.yyyy
70 */
71 static INLINE void linterp( struct exec_machine *exec,
72 GLuint attrib,
73 GLuint i )
74 {
75 GLuint j;
76
77 for (j = 0; j < QUAD_SIZE; j++) {
78 const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j];
79 const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j];
80 exec->attr[attrib][i][j] = (exec->coef[attrib].a0[i] +
81 exec->coef[attrib].dadx[i] * x +
82 exec->coef[attrib].dady[i] * y);
83 }
84 }
85
86
87 /**
88 * Compute quad's attribute values by linear interpolation with
89 * perspective correction.
90 *
91 * Push into the fp:
92 *
93 * INPUT[attr] = MAD COEF_A0[attr], COEF_DADX[attr], INPUT_WPOS.xxxx
94 * INPUT[attr] = MAD INPUT[attr], COEF_DADY[attr], INPUT_WPOS.yyyy
95 * INPUT[attr] = MUL INPUT[attr], INPUT_WPOS.wwww
96 *
97 * (Or should that be 1/w ???)
98 */
99 static INLINE void pinterp( struct exec_machine *exec,
100 GLuint attrib,
101 GLuint i )
102 {
103 GLuint j;
104
105 for (j = 0; j < QUAD_SIZE; j++) {
106 const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j];
107 const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j];
108 const GLfloat invW = exec->attr[FRAG_ATTRIB_WPOS][3][j];
109 exec->attr[attrib][i][j] = ((exec->coef[attrib].a0[i] +
110 exec->coef[attrib].dadx[i] * x +
111 exec->coef[attrib].dady[i] * y) * invW);
112 }
113 }
114
115
116
117 /* This should be done by the fragment shader execution unit (code
118 * generated from the decl instructions). Do it here for now.
119 */
120 static void
121 shade_quad( struct quad_stage *qs, struct quad_header *quad )
122 {
123 struct softpipe_context *softpipe = qs->softpipe;
124 struct exec_machine exec;
125 GLfloat fx = quad->x0;
126 GLfloat fy = quad->y0;
127 GLuint i, j;
128 GLboolean need_z = softpipe->depth_test.enabled; /* XXX hack */
129
130 exec.coef = quad->coef;
131
132 /* Position:
133 */
134 exec.attr[FRAG_ATTRIB_WPOS][0][0] = fx;
135 exec.attr[FRAG_ATTRIB_WPOS][0][1] = fx + 1.0;
136 exec.attr[FRAG_ATTRIB_WPOS][0][2] = fx;
137 exec.attr[FRAG_ATTRIB_WPOS][0][3] = fx + 1.0;
138
139 exec.attr[FRAG_ATTRIB_WPOS][1][0] = fy;
140 exec.attr[FRAG_ATTRIB_WPOS][1][1] = fy;
141 exec.attr[FRAG_ATTRIB_WPOS][1][2] = fy + 1.0;
142 exec.attr[FRAG_ATTRIB_WPOS][1][3] = fy + 1.0;
143
144 /* Z and W are done by linear interpolation:
145 * XXX we'll probably have to use integers for Z
146 */
147 if (/*softpipe->*/need_z) {
148 linterp(&exec, 0, 2); /* attr[0].z */
149 }
150
151 if (softpipe->need_w) {
152 linterp(&exec, 0, 3); /* attr[0].w */
153 // invert(&exec, 0, 3);
154 }
155
156 /* Interpolate all the remaining attributes. This will get pushed
157 * into the fragment program's responsibilities at some point.
158 */
159 for (i = 1; i < quad->nr_attrs; i++) {
160 #if 1
161 for (j = 0; j < NUM_CHANNELS; j++)
162 linterp(&exec, i, j);
163 #else
164 switch (quad->interp[i]) {
165 case INTERP_CONSTANT:
166 for (j = 0; j < NUM_CHANNELS; j++)
167 cinterp(&exec, i, j);
168 break;
169
170 case INTERP_LINEAR:
171 for (j = 0; j < NUM_CHANNELS; j++)
172 linterp(&exec, i, j);
173 break;
174
175 case INTERP_PERSPECTIVE:
176 for (j = 0; j < NUM_CHANNELS; j++)
177 pinterp(&exec, i, j);
178 break;
179 }
180 #endif
181 }
182
183 #if 0
184 softpipe->run_fs( tri->fp, quad, &tri->outputs );
185 #else
186 {
187 GLuint attr = softpipe->fp_attr_to_slot[FRAG_ATTRIB_COL0];
188 assert(attr);
189
190 memcpy(quad->outputs.color,
191 exec.attr[attr],
192 sizeof(quad->outputs.color));
193
194 if (need_z) {
195 quad->outputs.depth[0] = exec.attr[0][2][0];
196 quad->outputs.depth[1] = exec.attr[0][2][1];
197 quad->outputs.depth[2] = exec.attr[0][2][2];
198 quad->outputs.depth[3] = exec.attr[0][2][3];
199 }
200 }
201 #endif
202
203 qs->next->run(qs->next, quad);
204 }
205
206
207
208 struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
209 {
210 struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
211
212 stage->softpipe = softpipe;
213 stage->run = shade_quad;
214
215 return stage;
216 }