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_export.h"
35 * slang_export_data_quant
38 GLvoid
slang_export_data_quant_ctr (slang_export_data_quant
*self
)
40 self
->name
= SLANG_ATOM_NULL
;
43 self
->structure
= NULL
;
44 self
->u
.basic_type
= GL_FLOAT
;
47 GLvoid
slang_export_data_quant_dtr (slang_export_data_quant
*self
)
49 if (self
->structure
!= NULL
)
53 for (i
= 0; i
< self
->u
.field_count
; i
++)
54 slang_export_data_quant_dtr (&self
->structure
[i
]);
55 slang_alloc_free (self
->structure
);
59 slang_export_data_quant
*slang_export_data_quant_add_field (slang_export_data_quant
*self
)
61 const GLuint n
= self
->u
.field_count
;
63 self
->structure
= (slang_export_data_quant
*) slang_alloc_realloc (self
->structure
,
64 n
* sizeof (slang_export_data_quant
), (n
+ 1) * sizeof (slang_export_data_quant
));
65 if (self
->structure
== NULL
)
67 slang_export_data_quant_ctr (&self
->structure
[n
]);
68 self
->u
.field_count
++;
69 return &self
->structure
[n
];
73 * slang_export_data_entry
76 GLvoid
slang_export_data_entry_ctr (slang_export_data_entry
*self
)
78 slang_export_data_quant_ctr (&self
->quant
);
79 self
->access
= slang_exp_uniform
;
83 GLvoid
slang_export_data_entry_dtr (slang_export_data_entry
*self
)
85 slang_export_data_quant_dtr (&self
->quant
);
89 * slang_export_data_table
92 GLvoid
slang_export_data_table_ctr (slang_export_data_table
*self
)
99 GLvoid
slang_export_data_table_dtr (slang_export_data_table
*self
)
101 if (self
->entries
!= NULL
)
105 for (i
= 0; i
< self
->count
; i
++)
106 slang_export_data_entry_dtr (&self
->entries
[i
]);
107 slang_alloc_free (self
->entries
);
111 slang_export_data_entry
*slang_export_data_table_add (slang_export_data_table
*self
)
113 const GLuint n
= self
->count
;
115 self
->entries
= (slang_export_data_entry
*) slang_alloc_realloc (self
->entries
,
116 n
* sizeof (slang_export_data_entry
), (n
+ 1) * sizeof (slang_export_data_entry
));
117 if (self
->entries
== NULL
)
119 slang_export_data_entry_ctr (&self
->entries
[n
]);
121 return &self
->entries
[n
];
125 * slang_export_code_entry
128 static GLvoid
slang_export_code_entry_ctr (slang_export_code_entry
*self
)
130 self
->name
= SLANG_ATOM_NULL
;
134 static GLvoid
slang_export_code_entry_dtr (slang_export_code_entry
*self
)
139 * slang_export_code_table
142 GLvoid
slang_export_code_table_ctr (slang_export_code_table
*self
)
144 self
->entries
= NULL
;
149 GLvoid
slang_export_code_table_dtr (slang_export_code_table
*self
)
151 if (self
->entries
!= NULL
)
155 for (i
= 0; i
< self
->count
; i
++)
156 slang_export_code_entry_dtr (&self
->entries
[i
]);
157 slang_alloc_free (self
->entries
);
161 slang_export_code_entry
*slang_export_code_table_add (slang_export_code_table
*self
)
163 const GLuint n
= self
->count
;
165 self
->entries
= (slang_export_code_entry
*) slang_alloc_realloc (self
->entries
,
166 n
* sizeof (slang_export_code_entry
), (n
+ 1) * sizeof (slang_export_code_entry
));
167 if (self
->entries
== NULL
)
169 slang_export_code_entry_ctr (&self
->entries
[n
]);
171 return &self
->entries
[n
];
175 * _slang_find_exported_data()
178 #define EXTRACT_ERROR 0
179 #define EXTRACT_BASIC 1
180 #define EXTRACT_ARRAY 2
181 #define EXTRACT_STRUCT 3
182 #define EXTRACT_STRUCT_ARRAY 4
184 #define EXTRACT_MAXLEN 255
186 static GLuint
extract_name (const char *name
, char *parsed
, GLuint
*element
, const char **end
)
190 if ((name
[0] >= 'a' && name
[0] <= 'z') || (name
[0] >= 'A' && name
[0] <= 'Z') || name
[0] == '_')
194 for (i
= 1; i
< EXTRACT_MAXLEN
; i
++)
196 if ((name
[i
] >= 'a' && name
[i
] <= 'z') || (name
[i
] >= 'A' && name
[i
] <= 'Z') ||
197 (name
[i
] >= '0' && name
[i
] <= '9') || name
[0] == '_')
206 return EXTRACT_BASIC
;
212 return EXTRACT_STRUCT
;
218 if (name
[i
] >= '0' && name
[i
] <= '9')
220 *element
= name
[i
] - '0';
223 if (name
[i
] >= '0' && name
[i
] <= '9')
224 *element
= *element
* 10 + (name
[i
] - '0');
233 return EXTRACT_STRUCT_ARRAY
;
236 return EXTRACT_ARRAY
;
247 return EXTRACT_ERROR
;
250 static GLboolean
validate_extracted (slang_export_data_quant
*q
, GLuint element
, GLuint extr
)
257 return element
< q
->array_len
;
259 return q
->structure
!= NULL
;
260 case EXTRACT_STRUCT_ARRAY
:
261 return q
->structure
!= NULL
&& element
< q
->array_len
;
266 static GLuint
calculate_offset (slang_export_data_quant
*q
, GLuint element
)
268 if (q
->array_len
!= 0)
269 return element
* q
->size
;
273 static GLboolean
find_exported_data (slang_export_data_quant
*q
, const char *name
,
274 slang_export_data_quant
**quant
, GLuint
*offset
, slang_atom_pool
*atoms
)
276 char parsed
[EXTRACT_MAXLEN
];
277 GLuint result
, element
, i
;
281 result
= extract_name (name
, parsed
, &element
, &end
);
282 if (result
== EXTRACT_ERROR
)
285 atom
= slang_atom_pool_atom (atoms
, parsed
);
286 if (atom
== SLANG_ATOM_NULL
)
289 for (i
= 0; i
< q
->u
.field_count
; i
++)
290 if (q
->structure
[i
].name
== atom
)
292 if (!validate_extracted (&q
->structure
[i
], element
, result
))
294 *offset
+= calculate_offset (&q
->structure
[i
], element
);
295 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
299 *quant
= &q
->structure
[i
];
302 return find_exported_data (&q
->structure
[i
], end
, quant
, offset
, atoms
);
307 GLboolean
_slang_find_exported_data (slang_export_data_table
*table
, const char *name
,
308 slang_export_data_entry
**entry
, slang_export_data_quant
**quant
, GLuint
*offset
)
310 char parsed
[EXTRACT_MAXLEN
];
311 GLuint result
, element
, i
;
315 result
= extract_name (name
, parsed
, &element
, &end
);
316 if (result
== EXTRACT_ERROR
)
319 atom
= slang_atom_pool_atom (table
->atoms
, parsed
);
320 if (atom
== SLANG_ATOM_NULL
)
323 for (i
= 0; i
< table
->count
; i
++)
324 if (table
->entries
[i
].quant
.name
== atom
)
326 if (!validate_extracted (&table
->entries
[i
].quant
, element
, result
))
328 *entry
= &table
->entries
[i
];
329 *offset
= calculate_offset (&table
->entries
[i
].quant
, element
);
330 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
334 *quant
= &table
->entries
[i
].quant
;
337 return find_exported_data (&table
->entries
[i
].quant
, end
, quant
, offset
, table
->atoms
);