2 * Mesa 3-D graphics library
5 * Copyright (C) 2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
31 #include "shaderobjects.h"
32 #include "shaderobjects_3dlabs.h"
33 #include "t_pipeline.h"
34 #include "slang_utility.h"
38 GLvector4f outputs
[VERT_RESULT_MAX
];
39 GLvector4f ndc_coords
;
45 #define ARBVS_STAGE_DATA(stage) ((arbvs_stage_data *) stage->privatePtr)
47 static GLboolean
construct_arb_vertex_shader (GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
49 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
50 struct vertex_buffer
*vb
= &tnl
->vb
;
51 arbvs_stage_data
*store
;
52 GLuint size
= vb
->Size
;
55 stage
->privatePtr
= _mesa_malloc (sizeof (arbvs_stage_data
));
56 store
= ARBVS_STAGE_DATA(stage
);
60 for (i
= 0; i
< VERT_RESULT_MAX
; i
++)
62 _mesa_vector4f_alloc (&store
->outputs
[i
], 0, size
, 32);
63 store
->outputs
[i
].size
= 4;
65 _mesa_vector4f_alloc (&store
->ndc_coords
, 0, size
, 32);
66 store
->clipmask
= (GLubyte
*) ALIGN_MALLOC (size
, 32);
71 static void destruct_arb_vertex_shader (struct tnl_pipeline_stage
*stage
)
73 arbvs_stage_data
*store
= ARBVS_STAGE_DATA(stage
);
79 for (i
= 0; i
< VERT_RESULT_MAX
; i
++)
80 _mesa_vector4f_free (&store
->outputs
[i
]);
81 _mesa_vector4f_free (&store
->ndc_coords
);
82 ALIGN_FREE (store
->clipmask
);
85 stage
->privatePtr
= NULL
;
89 static void validate_arb_vertex_shader (GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
93 static void fetch_input_float (const char *name
, GLuint attr
, GLuint i
, struct vertex_buffer
*vb
,
94 struct gl2_vertex_shader_intf
**vs
)
96 const GLubyte
*ptr
= (const GLubyte
*) vb
->AttribPtr
[attr
]->data
;
97 /*const GLuint size = vb->AttribPtr[attr]->size;*/
98 const GLuint stride
= vb
->AttribPtr
[attr
]->stride
;
99 const GLfloat
*data
= (const GLfloat
*) (ptr
+ stride
* i
);
103 _slang_fetch_float (vs
, name
, vec
, 1);
106 static void fetch_input_vec3 (const char *name
, GLuint attr
, GLuint i
, struct vertex_buffer
*vb
,
107 struct gl2_vertex_shader_intf
**vs
)
109 const GLubyte
*ptr
= (const GLubyte
*) vb
->AttribPtr
[attr
]->data
;
110 /*const GLuint size = vb->AttribPtr[attr]->size;*/
111 const GLuint stride
= vb
->AttribPtr
[attr
]->stride
;
112 const GLfloat
*data
= (const GLfloat
*) (ptr
+ stride
* i
);
118 _slang_fetch_vec3 (vs
, name
, vec
, 1);
121 static void fetch_input_vec4 (const char *name
, GLuint attr
, GLuint i
, struct vertex_buffer
*vb
,
122 struct gl2_vertex_shader_intf
**vs
)
124 const GLubyte
*ptr
= (const GLubyte
*) vb
->AttribPtr
[attr
]->data
;
125 const GLuint size
= vb
->AttribPtr
[attr
]->size
;
126 const GLuint stride
= vb
->AttribPtr
[attr
]->stride
;
127 const GLfloat
*data
= (const GLfloat
*) (ptr
+ stride
* i
);
151 _slang_fetch_vec4 (vs
, name
, vec
, 0, 1);
154 static void fetch_output_float (const char *name
, GLuint attr
, GLuint i
, arbvs_stage_data
*store
,
155 struct gl2_vertex_shader_intf
**vs
)
159 _slang_fetch_float (vs
, name
, vec
, 0);
160 _mesa_memcpy (&store
->outputs
[attr
].data
[i
], vec
, 4);
163 static void fetch_output_vec4 (const char *name
, GLuint attr
, GLuint i
, GLuint index
,
164 arbvs_stage_data
*store
, struct gl2_vertex_shader_intf
**vs
)
168 _slang_fetch_vec4 (vs
, name
, vec
, index
, 0);
169 _mesa_memcpy (&store
->outputs
[attr
].data
[i
], vec
, 16);
172 static void fetch_uniform_mat4 (const char *name
, GLmatrix
*matrix
, GLuint index
,
173 struct gl2_vertex_shader_intf
**vs
)
179 _mesa_strcpy (buffer
, name
);
180 len
= _mesa_strlen (name
);
182 /* we want inverse matrix */
185 /* allocate inverse matrix and make it dirty */
186 _math_matrix_alloc_inv (matrix
);
187 _math_matrix_loadf (matrix
, matrix
->m
);
189 _math_matrix_analyse (matrix
);
192 _slang_fetch_mat4 (vs
, name
, matrix
->m
, index
, 1);
195 _mesa_strcpy (buffer
+ len
, "Transpose");
196 _math_transposef (mat
, matrix
->m
);
197 _slang_fetch_mat4 (vs
, buffer
, mat
, index
, 1);
200 _mesa_strcpy (buffer
+ len
, "Inverse");
201 _slang_fetch_mat4 (vs
, buffer
, matrix
->inv
, index
, 1);
203 /* inverse transpose */
204 _mesa_strcpy (buffer
+ len
, "InverseTranspose");
205 _math_transposef (mat
, matrix
->inv
);
206 _slang_fetch_mat4 (vs
, buffer
, mat
, index
, 1);
209 static void fetch_normal_matrix (const char *name
, GLmatrix
*matrix
,
210 struct gl2_vertex_shader_intf
**vs
)
214 _math_matrix_analyse (matrix
);
216 /* inverse transpose */
217 mat
[0] = matrix
->inv
[0];
218 mat
[1] = matrix
->inv
[4];
219 mat
[2] = matrix
->inv
[8];
220 mat
[3] = matrix
->inv
[1];
221 mat
[4] = matrix
->inv
[5];
222 mat
[5] = matrix
->inv
[9];
223 mat
[6] = matrix
->inv
[2];
224 mat
[7] = matrix
->inv
[6];
225 mat
[8] = matrix
->inv
[10];
226 _slang_fetch_mat3 (vs
, name
, mat
, 0, 1);
229 static GLboolean
run_arb_vertex_shader (GLcontext
*ctx
, struct tnl_pipeline_stage
*stage
)
231 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
232 struct vertex_buffer
*vb
= &tnl
->vb
;
233 arbvs_stage_data
*store
= ARBVS_STAGE_DATA(stage
);
234 struct gl2_program_intf
**prog
;
235 struct gl2_vertex_shader_intf
**vs
= NULL
;
238 prog
= ctx
->ShaderObjects
.CurrentProgram
;
242 count
= (**prog
)._container
.GetAttachedCount ((struct gl2_container_intf
**) prog
);
243 for (i
= 0; i
< count
; i
++)
245 struct gl2_generic_intf
**obj
;
246 struct gl2_unknown_intf
**unk
;
248 obj
= (**prog
)._container
.GetAttached ((struct gl2_container_intf
**) prog
, i
);
249 unk
= (**obj
)._unknown
.QueryInterface ((struct gl2_unknown_intf
**) obj
, UIID_VERTEX_SHADER
);
250 (**obj
)._unknown
.Release ((struct gl2_unknown_intf
**) obj
);
253 vs
= (struct gl2_vertex_shader_intf
**) unk
;
260 fetch_uniform_mat4 ("gl_ModelViewMatrix", ctx
->ModelviewMatrixStack
.Top
, 0, vs
);
261 fetch_uniform_mat4 ("gl_ProjectionMatrix", ctx
->ProjectionMatrixStack
.Top
, 0, vs
);
262 fetch_uniform_mat4 ("gl_ModelViewProjectionMatrix", &ctx
->_ModelProjectMatrix
, 0, vs
);
263 for (j
= 0; j
< 8; j
++)
264 fetch_uniform_mat4 ("gl_TextureMatrix", ctx
->TextureMatrixStack
[j
].Top
, j
, vs
);
265 fetch_normal_matrix ("gl_NormalMatrix", ctx
->ModelviewMatrixStack
.Top
, vs
);
266 /* XXX: fetch uniform float gl_NormalScale */
267 /* XXX: fetch uniform mat4 gl_ClipPlane */
268 /* XXX: fetch uniform mat4 gl_TextureEnvColor */
269 /* XXX: fetch uniform mat4 gl_EyePlaneS */
270 /* XXX: fetch uniform mat4 gl_EyePlaneT */
271 /* XXX: fetch uniform mat4 gl_EyePlaneR */
272 /* XXX: fetch uniform mat4 gl_EyePlaneQ */
273 /* XXX: fetch uniform mat4 gl_ObjectPlaneS */
274 /* XXX: fetch uniform mat4 gl_ObjectPlaneT */
275 /* XXX: fetch uniform mat4 gl_ObjectPlaneR */
276 /* XXX: fetch uniform mat4 gl_ObjectPlaneQ */
278 for (i
= 0; i
< vb
->Count
; i
++)
280 fetch_input_vec4 ("gl_Vertex", _TNL_ATTRIB_POS
, i
, vb
, vs
);
281 fetch_input_vec3 ("gl_Normal", _TNL_ATTRIB_NORMAL
, i
, vb
, vs
);
282 fetch_input_vec4 ("gl_Color", _TNL_ATTRIB_COLOR0
, i
, vb
, vs
);
283 fetch_input_vec4 ("gl_SecondaryColor", _TNL_ATTRIB_COLOR1
, i
, vb
, vs
);
284 fetch_input_float ("gl_FogCoord", _TNL_ATTRIB_FOG
, i
, vb
, vs
);
285 fetch_input_vec4 ("gl_MultiTexCoord0", _TNL_ATTRIB_TEX0
, i
, vb
, vs
);
286 fetch_input_vec4 ("gl_MultiTexCoord1", _TNL_ATTRIB_TEX1
, i
, vb
, vs
);
287 fetch_input_vec4 ("gl_MultiTexCoord2", _TNL_ATTRIB_TEX2
, i
, vb
, vs
);
288 fetch_input_vec4 ("gl_MultiTexCoord3", _TNL_ATTRIB_TEX3
, i
, vb
, vs
);
289 fetch_input_vec4 ("gl_MultiTexCoord4", _TNL_ATTRIB_TEX4
, i
, vb
, vs
);
290 fetch_input_vec4 ("gl_MultiTexCoord5", _TNL_ATTRIB_TEX5
, i
, vb
, vs
);
291 fetch_input_vec4 ("gl_MultiTexCoord6", _TNL_ATTRIB_TEX6
, i
, vb
, vs
);
292 fetch_input_vec4 ("gl_MultiTexCoord7", _TNL_ATTRIB_TEX7
, i
, vb
, vs
);
294 _slang_exec_vertex_shader (vs
);
296 fetch_output_vec4 ("gl_Position", VERT_RESULT_HPOS
, i
, 0, store
, vs
);
297 fetch_output_vec4 ("gl_FrontColor", VERT_RESULT_COL0
, i
, 0, store
, vs
);
298 fetch_output_vec4 ("gl_FrontSecondaryColor", VERT_RESULT_COL1
, i
, 0, store
, vs
);
299 fetch_output_float ("gl_FogFragCoord", VERT_RESULT_FOGC
, i
, store
, vs
);
300 for (j
= 0; j
< 8; j
++)
301 fetch_output_vec4 ("gl_TexCoord", VERT_RESULT_TEX0
+ j
, i
, j
, store
, vs
);
302 fetch_output_float ("gl_PointSize", VERT_RESULT_PSIZ
, i
, store
, vs
);
303 fetch_output_vec4 ("gl_BackColor", VERT_RESULT_BFC0
, i
, 0, store
, vs
);
304 fetch_output_vec4 ("gl_BackSecondaryColor", VERT_RESULT_BFC1
, i
, 0, store
, vs
);
305 /* XXX: fetch output gl_ClipVertex */
308 (**vs
)._shader
._generic
._unknown
.Release ((struct gl2_unknown_intf
**) vs
);
310 vb
->ClipPtr
= &store
->outputs
[VERT_RESULT_HPOS
];
311 vb
->ClipPtr
->count
= vb
->Count
;
312 vb
->ColorPtr
[0] = &store
->outputs
[VERT_RESULT_COL0
];
313 vb
->SecondaryColorPtr
[0] = &store
->outputs
[VERT_RESULT_COL1
];
314 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
315 vb
->TexCoordPtr
[i
] = &store
->outputs
[VERT_RESULT_TEX0
+ i
];
316 vb
->ColorPtr
[1] = &store
->outputs
[VERT_RESULT_BFC0
];
317 vb
->SecondaryColorPtr
[1] = &store
->outputs
[VERT_RESULT_BFC1
];
318 vb
->FogCoordPtr
= &store
->outputs
[VERT_RESULT_FOGC
];
319 vb
->PointSizePtr
= &store
->outputs
[VERT_RESULT_PSIZ
];
321 vb
->AttribPtr
[VERT_ATTRIB_COLOR0
] = vb
->ColorPtr
[0];
322 vb
->AttribPtr
[VERT_ATTRIB_COLOR1
] = vb
->SecondaryColorPtr
[0];
323 vb
->AttribPtr
[VERT_ATTRIB_FOG
] = vb
->FogCoordPtr
;
324 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
325 vb
->AttribPtr
[VERT_ATTRIB_TEX0
+ i
] = vb
->TexCoordPtr
[i
];
326 vb
->AttribPtr
[_TNL_ATTRIB_POINTSIZE
] = &store
->outputs
[VERT_RESULT_PSIZ
];
329 store
->andmask
= CLIP_ALL_BITS
;
331 if (tnl
->NeedNdcCoords
)
333 vb
->NdcPtr
= _mesa_clip_tab
[vb
->ClipPtr
->size
] (vb
->ClipPtr
, &store
->ndc_coords
,
334 store
->clipmask
, &store
->ormask
, &store
->andmask
);
339 _mesa_clip_np_tab
[vb
->ClipPtr
->size
] (vb
->ClipPtr
, NULL
, store
->clipmask
, &store
->ormask
,
346 vb
->ClipAndMask
= store
->andmask
;
347 vb
->ClipOrMask
= store
->ormask
;
348 vb
->ClipMask
= store
->clipmask
;
353 const struct tnl_pipeline_stage _tnl_arb_vertex_shader_stage
= {
356 construct_arb_vertex_shader
,
357 destruct_arb_vertex_shader
,
358 validate_arb_vertex_shader
,
359 run_arb_vertex_shader