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.
26 * \file slang_export.c
27 * interface between assembly code and the application
32 #include "slang_utility.h"
33 #include "slang_export.h"
36 * slang_export_data_quant
39 GLvoid
slang_export_data_quant_ctr (slang_export_data_quant
*self
)
41 self
->name
= SLANG_ATOM_NULL
;
44 self
->structure
= NULL
;
45 self
->u
.basic_type
= GL_FLOAT
;
48 GLvoid
slang_export_data_quant_dtr (slang_export_data_quant
*self
)
50 if (self
->structure
!= NULL
)
54 for (i
= 0; i
< self
->u
.field_count
; i
++)
55 slang_export_data_quant_dtr (&self
->structure
[i
]);
56 slang_alloc_free (self
->structure
);
60 slang_export_data_quant
*slang_export_data_quant_add_field (slang_export_data_quant
*self
)
62 const GLuint n
= self
->u
.field_count
;
64 self
->structure
= (slang_export_data_quant
*) slang_alloc_realloc (self
->structure
,
65 n
* sizeof (slang_export_data_quant
), (n
+ 1) * sizeof (slang_export_data_quant
));
66 if (self
->structure
== NULL
)
68 slang_export_data_quant_ctr (&self
->structure
[n
]);
69 self
->u
.field_count
++;
70 return &self
->structure
[n
];
74 * slang_export_data_entry
77 GLvoid
slang_export_data_entry_ctr (slang_export_data_entry
*self
)
79 slang_export_data_quant_ctr (&self
->quant
);
80 self
->access
= slang_exp_uniform
;
84 GLvoid
slang_export_data_entry_dtr (slang_export_data_entry
*self
)
86 slang_export_data_quant_dtr (&self
->quant
);
90 * slang_export_data_table
93 GLvoid
slang_export_data_table_ctr (slang_export_data_table
*self
)
100 GLvoid
slang_export_data_table_dtr (slang_export_data_table
*self
)
102 if (self
->entries
!= NULL
)
106 for (i
= 0; i
< self
->count
; i
++)
107 slang_export_data_entry_dtr (&self
->entries
[i
]);
108 slang_alloc_free (self
->entries
);
112 slang_export_data_entry
*slang_export_data_table_add (slang_export_data_table
*self
)
114 const GLuint n
= self
->count
;
116 self
->entries
= (slang_export_data_entry
*) slang_alloc_realloc (self
->entries
,
117 n
* sizeof (slang_export_data_entry
), (n
+ 1) * sizeof (slang_export_data_entry
));
118 if (self
->entries
== NULL
)
120 slang_export_data_entry_ctr (&self
->entries
[n
]);
122 return &self
->entries
[n
];
126 * _slang_find_exported_data()
129 #define EXTRACT_ERROR 0
130 #define EXTRACT_BASIC 1
131 #define EXTRACT_ARRAY 2
132 #define EXTRACT_STRUCT 3
133 #define EXTRACT_STRUCT_ARRAY 4
135 #define EXTRACT_MAXLEN 255
137 static GLuint
extract_name (const char *name
, char *parsed
, GLuint
*element
, const char **end
)
141 if ((name
[0] >= 'a' && name
[0] <= 'z') || (name
[0] >= 'A' && name
[0] <= 'Z') || name
[0] == '_')
145 for (i
= 1; i
< EXTRACT_MAXLEN
; i
++)
147 if ((name
[i
] >= 'a' && name
[i
] <= 'z') || (name
[i
] >= 'A' && name
[i
] <= 'Z') ||
148 (name
[i
] >= '0' && name
[i
] <= '9') || name
[0] == '_')
157 return EXTRACT_BASIC
;
163 return EXTRACT_STRUCT
;
169 if (name
[i
] >= '0' && name
[i
] <= '9')
171 *element
= name
[i
] - '0';
174 if (name
[i
] >= '0' && name
[i
] <= '9')
175 *element
= *element
* 10 + (name
[i
] - '0');
184 return EXTRACT_STRUCT_ARRAY
;
187 return EXTRACT_ARRAY
;
198 return EXTRACT_ERROR
;
201 static GLboolean
validate_extracted (slang_export_data_quant
*q
, GLuint element
, GLuint extr
)
208 return element
< q
->array_len
;
210 return q
->structure
!= NULL
;
211 case EXTRACT_STRUCT_ARRAY
:
212 return q
->structure
!= NULL
&& element
< q
->array_len
;
217 static GLuint
calculate_offset (slang_export_data_quant
*q
, GLuint element
)
219 if (q
->array_len
!= 0)
220 return element
* q
->size
;
224 static GLboolean
find_exported_data (slang_export_data_quant
*q
, const char *name
,
225 slang_export_data_quant
**quant
, GLuint
*offset
, slang_atom_pool
*atoms
)
227 char parsed
[EXTRACT_MAXLEN
];
228 GLuint result
, element
, i
;
232 result
= extract_name (name
, parsed
, &element
, &end
);
233 if (result
== EXTRACT_ERROR
)
236 atom
= slang_atom_pool_atom (atoms
, parsed
);
237 if (atom
== SLANG_ATOM_NULL
)
240 for (i
= 0; i
< q
->u
.field_count
; i
++)
241 if (q
->structure
[i
].name
== atom
)
243 if (!validate_extracted (&q
->structure
[i
], element
, result
))
245 *offset
+= calculate_offset (&q
->structure
[i
], element
);
246 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
250 *quant
= &q
->structure
[i
];
253 return find_exported_data (&q
->structure
[i
], end
, quant
, offset
, atoms
);
258 GLboolean
_slang_find_exported_data (slang_export_data_table
*table
, const char *name
,
259 slang_export_data_entry
**entry
, slang_export_data_quant
**quant
, GLuint
*offset
)
261 char parsed
[EXTRACT_MAXLEN
];
262 GLuint result
, element
, i
;
266 result
= extract_name (name
, parsed
, &element
, &end
);
267 if (result
== EXTRACT_ERROR
)
270 atom
= slang_atom_pool_atom (table
->atoms
, parsed
);
271 if (atom
== SLANG_ATOM_NULL
)
274 for (i
= 0; i
< table
->count
; i
++)
275 if (table
->entries
[i
].quant
.name
== atom
)
277 if (!validate_extracted (&table
->entries
[i
].quant
, element
, result
))
279 *entry
= &table
->entries
[i
];
280 *offset
= calculate_offset (&table
->entries
[i
].quant
, element
);
281 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
285 *quant
= &table
->entries
[i
].quant
;
288 return find_exported_data (&table
->entries
[i
].quant
, end
, quant
, offset
, table
->atoms
);