fixed problems with parse_float() (fd.o bug 2520)
[mesa.git] / src / mesa / shader / shaderobjects_3dlabs.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 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 /**
26 * \file shaderobjects_3dlabs.c
27 * shader objects definitions for 3dlabs compiler
28 * \author Michal Krol
29 */
30
31
32 #include "glheader.h"
33 #include "shaderobjects.h"
34 #include "shaderobjects_3dlabs.h"
35 #include "context.h"
36 #include "macros.h"
37 #include "hash.h"
38
39
40 struct gl2_unknown_obj
41 {
42 GLuint reference_count;
43 void (* _destructor) (struct gl2_unknown_intf **);
44 };
45
46 struct gl2_unknown_impl
47 {
48 struct gl2_unknown_intf *_vftbl;
49 struct gl2_unknown_obj _obj;
50 };
51
52 static void
53 _unknown_destructor (struct gl2_unknown_intf **intf)
54 {
55 }
56
57 static void
58 _unknown_AddRef (struct gl2_unknown_intf **intf)
59 {
60 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
61
62 impl->_obj.reference_count++;
63 }
64
65 static void
66 _unknown_Release (struct gl2_unknown_intf **intf)
67 {
68 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
69
70 impl->_obj.reference_count--;
71 if (impl->_obj.reference_count == 0)
72 {
73 impl->_obj._destructor (intf);
74 _mesa_free ((void *) intf);
75 }
76 }
77
78 static struct gl2_unknown_intf **
79 _unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
80 {
81 if (uiid == UIID_UNKNOWN)
82 {
83 (**intf).AddRef (intf);
84 return intf;
85 }
86 return NULL;
87 }
88
89 static struct gl2_unknown_intf _unknown_vftbl = {
90 _unknown_AddRef,
91 _unknown_Release,
92 _unknown_QueryInterface
93 };
94
95 static void
96 _unknown_constructor (struct gl2_unknown_impl *impl)
97 {
98 impl->_vftbl = &_unknown_vftbl;
99 impl->_obj.reference_count = 1;
100 impl->_obj._destructor = _unknown_destructor;
101 }
102
103 struct gl2_generic_obj
104 {
105 struct gl2_unknown_obj _unknown;
106 GLhandleARB name;
107 GLboolean delete_status;
108 GLcharARB *info_log;
109 };
110
111 struct gl2_generic_impl
112 {
113 struct gl2_generic_intf *_vftbl;
114 struct gl2_generic_obj _obj;
115 };
116
117 static void
118 _generic_destructor (struct gl2_unknown_intf **intf)
119 {
120 GET_CURRENT_CONTEXT(ctx);
121 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
122
123 _mesa_free ((void *) impl->_obj.info_log);
124
125 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
126 _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name);
127 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
128
129 _unknown_destructor (intf);
130 }
131
132 static struct gl2_unknown_intf **
133 _generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
134 {
135 if (uiid == UIID_GENERIC)
136 {
137 (**intf).AddRef (intf);
138 return intf;
139 }
140 return _unknown_QueryInterface (intf, uiid);
141 }
142
143 static void
144 _generic_Delete (struct gl2_generic_intf **intf)
145 {
146 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
147
148 if (impl->_obj.delete_status == GL_FALSE)
149 {
150 impl->_obj.delete_status = GL_TRUE;
151 (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf);
152 }
153 }
154
155 static GLhandleARB
156 _generic_GetName (struct gl2_generic_intf **intf)
157 {
158 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
159
160 return impl->_obj.name;
161 }
162
163 static GLboolean
164 _generic_GetDeleteStatus (struct gl2_generic_intf **intf)
165 {
166 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
167
168 return impl->_obj.delete_status;
169 }
170
171 static const GLcharARB *
172 _generic_GetInfoLog (struct gl2_generic_intf **intf)
173 {
174 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
175
176 return impl->_obj.info_log;
177 }
178
179 static struct gl2_generic_intf _generic_vftbl = {
180 {
181 _unknown_AddRef,
182 _unknown_Release,
183 _generic_QueryInterface
184 },
185 _generic_Delete,
186 NULL,
187 _generic_GetName,
188 _generic_GetDeleteStatus,
189 _generic_GetInfoLog
190 };
191
192 static void
193 _generic_constructor (struct gl2_generic_impl *impl)
194 {
195 GET_CURRENT_CONTEXT(ctx);
196
197 _unknown_constructor ((struct gl2_unknown_impl *) impl);
198 impl->_vftbl = &_generic_vftbl;
199 impl->_obj._unknown._destructor = _generic_destructor;
200 impl->_obj.delete_status = GL_FALSE;
201 impl->_obj.info_log = NULL;
202
203 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
204 impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
205 _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
206 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
207 }
208
209 struct gl2_container_obj
210 {
211 struct gl2_generic_obj _generic;
212 struct gl2_generic_intf ***attached;
213 GLuint attached_count;
214 };
215
216 struct gl2_container_impl
217 {
218 struct gl2_container_intf *_vftbl;
219 struct gl2_container_obj _obj;
220 };
221
222 static void
223 _container_destructor (struct gl2_unknown_intf **intf)
224 {
225 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
226 GLuint i;
227
228 for (i = 0; i < impl->_obj.attached_count; i++)
229 {
230 struct gl2_generic_intf **x = impl->_obj.attached[i];
231 (**x)._unknown.Release ((struct gl2_unknown_intf **) x);
232 }
233
234 _generic_destructor (intf);
235 }
236
237 static struct gl2_unknown_intf **
238 _container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
239 {
240 if (uiid == UIID_CONTAINER)
241 {
242 (**intf).AddRef (intf);
243 return intf;
244 }
245 return _generic_QueryInterface (intf, uiid);
246 }
247
248 static GLboolean
249 _container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
250 {
251 GET_CURRENT_CONTEXT(ctx);
252 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
253 GLuint i;
254
255 for (i = 0; i < impl->_obj.attached_count; i++)
256 if (impl->_obj.attached[i] == att)
257 {
258 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
259 return GL_FALSE;
260 }
261
262 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
263 impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
264 sizeof (*impl->_obj.attached));
265 if (impl->_obj.attached == NULL)
266 return GL_FALSE;
267
268 impl->_obj.attached[impl->_obj.attached_count] = att;
269 impl->_obj.attached_count++;
270 (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
271 return GL_TRUE;
272 }
273
274 static GLboolean
275 _container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
276 {
277 GET_CURRENT_CONTEXT(ctx);
278 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
279 GLuint i, j;
280
281 for (i = 0; i < impl->_obj.attached_count; i++)
282 if (impl->_obj.attached[i] == att)
283 {
284 for (j = i; j < impl->_obj.attached_count - 1; j++)
285 impl->_obj.attached[j] = impl->_obj.attached[j + 1];
286 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
287 impl->_obj.attached_count * sizeof (*impl->_obj.attached),
288 (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
289 impl->_obj.attached_count--;
290 (**att)._unknown.Release ((struct gl2_unknown_intf **) att);
291 return GL_TRUE;
292 }
293
294 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
295 return GL_FALSE;
296 }
297
298 static GLsizei
299 _container_GetAttachedCount (struct gl2_container_intf **intf)
300 {
301 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
302
303 return impl->_obj.attached_count;
304 }
305
306 static struct gl2_generic_intf **
307 _container_GetAttached (struct gl2_container_intf **intf, GLuint index)
308 {
309 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
310
311 (**impl->_obj.attached[index])._unknown.AddRef (
312 (struct gl2_unknown_intf **)impl->_obj.attached[index]);
313 return impl->_obj.attached[index];
314 }
315
316 static struct gl2_container_intf _container_vftbl = {
317 {
318 {
319 _unknown_AddRef,
320 _unknown_Release,
321 _container_QueryInterface,
322 },
323 _generic_Delete,
324 NULL,
325 _generic_GetName,
326 _generic_GetDeleteStatus,
327 _generic_GetInfoLog,
328 },
329 _container_Attach,
330 _container_Detach,
331 _container_GetAttachedCount,
332 _container_GetAttached
333 };
334
335 static void
336 _container_constructor (struct gl2_container_impl *impl)
337 {
338 _generic_constructor ((struct gl2_generic_impl *) impl);
339 impl->_vftbl = &_container_vftbl;
340 impl->_obj._generic._unknown._destructor = _container_destructor;
341 impl->_obj.attached = NULL;
342 impl->_obj.attached_count = 0;
343 }
344
345 struct gl2_shader_obj
346 {
347 struct gl2_generic_obj _generic;
348 GLboolean compile_status;
349 GLcharARB *source;
350 GLint *offsets;
351 GLsizei offset_count;
352 };
353
354 struct gl2_shader_impl
355 {
356 struct gl2_shader_intf *_vftbl;
357 struct gl2_shader_obj _obj;
358 };
359
360 static void
361 _shader_destructor (struct gl2_unknown_intf **intf)
362 {
363 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
364
365 _mesa_free ((void *) impl->_obj.source);
366 _mesa_free ((void *) impl->_obj.offsets);
367 _generic_destructor (intf);
368 }
369
370 static struct gl2_unknown_intf **
371 _shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
372 {
373 if (uiid == UIID_SHADER)
374 {
375 (**intf).AddRef (intf);
376 return intf;
377 }
378 return _generic_QueryInterface (intf, uiid);
379 }
380
381 static GLenum
382 _shader_GetType (struct gl2_generic_intf **intf)
383 {
384 return GL_SHADER_OBJECT_ARB;
385 }
386
387 static GLboolean
388 _shader_GetCompileStatus (struct gl2_shader_intf **intf)
389 {
390 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
391
392 return impl->_obj.compile_status;
393 }
394
395 static GLvoid
396 _shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
397 {
398 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
399
400 _mesa_free ((void *) impl->_obj.source);
401 impl->_obj.source = src;
402 _mesa_free ((void *) impl->_obj.offsets);
403 impl->_obj.offsets = off;
404 impl->_obj.offset_count = cnt;
405 }
406
407 static const GLcharARB *
408 _shader_GetSource (struct gl2_shader_intf **intf)
409 {
410 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
411
412 return impl->_obj.source;
413 }
414
415 static GLvoid
416 _shader_Compile (struct gl2_shader_intf **intf)
417 {
418 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
419
420 impl->_obj.compile_status = GL_FALSE;
421 _mesa_free ((void *) impl->_obj._generic.info_log);
422 impl->_obj._generic.info_log = NULL;
423
424 /* TODO compile */
425 }
426
427 static struct gl2_shader_intf _shader_vftbl = {
428 {
429 {
430 _unknown_AddRef,
431 _unknown_Release,
432 _shader_QueryInterface,
433 },
434 _generic_Delete,
435 _shader_GetType,
436 _generic_GetName,
437 _generic_GetDeleteStatus,
438 _generic_GetInfoLog,
439 },
440 NULL,
441 _shader_GetCompileStatus,
442 _shader_SetSource,
443 _shader_GetSource,
444 _shader_Compile
445 };
446
447 static void
448 _shader_constructor (struct gl2_shader_impl *impl)
449 {
450 _generic_constructor ((struct gl2_generic_impl *) impl);
451 impl->_vftbl = &_shader_vftbl;
452 impl->_obj._generic._unknown._destructor = _shader_destructor;
453 impl->_obj.compile_status = GL_FALSE;
454 impl->_obj.source = NULL;
455 impl->_obj.offsets = NULL;
456 impl->_obj.offset_count = 0;
457 }
458
459 struct gl2_program_obj
460 {
461 struct gl2_container_obj _container;
462 GLboolean link_status;
463 GLboolean validate_status;
464 };
465
466 struct gl2_program_impl
467 {
468 struct gl2_program_intf *_vftbl;
469 struct gl2_program_obj _obj;
470 };
471
472 static void
473 _program_destructor (struct gl2_unknown_intf **intf)
474 {
475 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
476 (void) impl;
477 _container_destructor (intf);
478 }
479
480 static struct gl2_unknown_intf **
481 _program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
482 {
483 if (uiid == UIID_PROGRAM)
484 {
485 (**intf).AddRef (intf);
486 return intf;
487 }
488 return _container_QueryInterface (intf, uiid);
489 }
490
491 static GLenum
492 _program_GetType (struct gl2_generic_intf **intf)
493 {
494 return GL_PROGRAM_OBJECT_ARB;
495 }
496
497 static GLboolean
498 _program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
499 {
500 GET_CURRENT_CONTEXT(ctx);
501 struct gl2_unknown_intf **sha;
502
503 sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
504 if (sha == NULL)
505 {
506 _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
507 return GL_FALSE;
508 }
509
510 (**sha).Release (sha);
511 return _container_Attach (intf, att);
512 }
513
514 static GLboolean
515 _program_GetLinkStatus (struct gl2_program_intf **intf)
516 {
517 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
518
519 return impl->_obj.link_status;
520 }
521
522 static GLboolean
523 _program_GetValidateStatus (struct gl2_program_intf **intf)
524 {
525 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
526
527 return impl->_obj.validate_status;
528 }
529
530 static GLvoid
531 _program_Link (struct gl2_program_intf **intf)
532 {
533 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
534
535 impl->_obj.link_status = GL_FALSE;
536 _mesa_free ((void *) impl->_obj._container._generic.info_log);
537 impl->_obj._container._generic.info_log = NULL;
538
539 /* TODO link */
540 }
541
542 static GLvoid
543 _program_Validate (struct gl2_program_intf **intf)
544 {
545 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
546
547 impl->_obj.validate_status = GL_FALSE;
548
549 /* TODO validate */
550 }
551
552 static struct gl2_program_intf _program_vftbl = {
553 {
554 {
555 {
556 _unknown_AddRef,
557 _unknown_Release,
558 _program_QueryInterface,
559 },
560 _generic_Delete,
561 _program_GetType,
562 _generic_GetName,
563 _generic_GetDeleteStatus,
564 _generic_GetInfoLog,
565 },
566 _program_Attach,
567 _container_Detach,
568 _container_GetAttachedCount,
569 _container_GetAttached,
570 },
571 _program_GetLinkStatus,
572 _program_GetValidateStatus,
573 _program_Link,
574 _program_Validate
575 };
576
577 static void
578 _program_constructor (struct gl2_program_impl *impl)
579 {
580 _container_constructor ((struct gl2_container_impl *) impl);
581 impl->_vftbl = &_program_vftbl;
582 impl->_obj._container._generic._unknown._destructor = _program_destructor;
583 impl->_obj.link_status = GL_FALSE;
584 impl->_obj.validate_status = GL_FALSE;
585 }
586
587 struct gl2_fragment_shader_obj
588 {
589 struct gl2_shader_obj _shader;
590 };
591
592 struct gl2_fragment_shader_impl
593 {
594 struct gl2_fragment_shader_intf *_vftbl;
595 struct gl2_fragment_shader_obj _obj;
596 };
597
598 static void
599 _fragment_shader_destructor (struct gl2_unknown_intf **intf)
600 {
601 struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
602 (void) impl;
603 /* TODO free fragment shader data */
604
605 _shader_destructor (intf);
606 }
607
608 static struct gl2_unknown_intf **
609 _fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
610 {
611 if (uiid == UIID_FRAGMENT_SHADER)
612 {
613 (**intf).AddRef (intf);
614 return intf;
615 }
616 return _shader_QueryInterface (intf, uiid);
617 }
618
619 static GLenum
620 _fragment_shader_GetSubType (struct gl2_shader_intf **intf)
621 {
622 return GL_FRAGMENT_SHADER_ARB;
623 }
624
625 static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
626 {
627 {
628 {
629 _unknown_AddRef,
630 _unknown_Release,
631 _fragment_shader_QueryInterface,
632 },
633 _generic_Delete,
634 _shader_GetType,
635 _generic_GetName,
636 _generic_GetDeleteStatus,
637 _generic_GetInfoLog,
638 },
639 _fragment_shader_GetSubType,
640 _shader_GetCompileStatus,
641 _shader_SetSource,
642 _shader_GetSource,
643 _shader_Compile
644 }
645 };
646
647 static void
648 _fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
649 {
650 _shader_constructor ((struct gl2_shader_impl *) impl);
651 impl->_vftbl = &_fragment_shader_vftbl;
652 impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
653 }
654
655 struct gl2_vertex_shader_obj
656 {
657 struct gl2_shader_obj _shader;
658 };
659
660 struct gl2_vertex_shader_impl
661 {
662 struct gl2_vertex_shader_intf *_vftbl;
663 struct gl2_vertex_shader_obj _obj;
664 };
665
666 static void
667 _vertex_shader_destructor (struct gl2_unknown_intf **intf)
668 {
669 struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
670 (void) impl;
671 /* TODO free vertex shader data */
672
673 _shader_destructor (intf);
674 }
675
676 static struct gl2_unknown_intf **
677 _vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
678 {
679 if (uiid == UIID_VERTEX_SHADER)
680 {
681 (**intf).AddRef (intf);
682 return intf;
683 }
684 return _shader_QueryInterface (intf, uiid);
685 }
686
687 static GLenum
688 _vertex_shader_GetSubType (struct gl2_shader_intf **intf)
689 {
690 return GL_VERTEX_SHADER_ARB;
691 }
692
693 static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
694 {
695 {
696 {
697 _unknown_AddRef,
698 _unknown_Release,
699 _vertex_shader_QueryInterface,
700 },
701 _generic_Delete,
702 _shader_GetType,
703 _generic_GetName,
704 _generic_GetDeleteStatus,
705 _generic_GetInfoLog,
706 },
707 _vertex_shader_GetSubType,
708 _shader_GetCompileStatus,
709 _shader_SetSource,
710 _shader_GetSource,
711 _shader_Compile
712 }
713 };
714
715 static void
716 _vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
717 {
718 _shader_constructor ((struct gl2_shader_impl *) impl);
719 impl->_vftbl = &_vertex_shader_vftbl;
720 impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
721 }
722
723 GLhandleARB
724 _mesa_3dlabs_create_shader_object (GLenum shaderType)
725 {
726 GET_CURRENT_CONTEXT(ctx);
727 (void) ctx;
728 switch (shaderType)
729 {
730 case GL_FRAGMENT_SHADER_ARB:
731 {
732 struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *) _mesa_malloc (
733 sizeof (struct gl2_fragment_shader_impl));
734
735 if (x != NULL)
736 {
737 _fragment_shader_constructor (x);
738 return x->_obj._shader._generic.name;
739 }
740 }
741 break;
742 case GL_VERTEX_SHADER_ARB:
743 {
744 struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *) _mesa_malloc (
745 sizeof (struct gl2_vertex_shader_impl));
746
747 if (x != NULL)
748 {
749 _vertex_shader_constructor (x);
750 return x->_obj._shader._generic.name;
751 }
752 }
753 break;
754 }
755
756 return 0;
757 }
758
759 GLhandleARB
760 _mesa_3dlabs_create_program_object (void)
761 {
762 GET_CURRENT_CONTEXT(ctx);
763 struct gl2_program_impl *x = (struct gl2_program_impl *)
764 _mesa_malloc (sizeof (struct gl2_program_impl));
765
766 (void) ctx;
767 if (x != NULL)
768 {
769 _program_constructor (x);
770 return x->_obj._container._generic.name;
771 }
772
773 return 0;
774 }
775