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
];
72 GLboolean
slang_export_data_quant_array (slang_export_data_quant
*self
)
74 return self
->array_len
!= 0;
77 GLboolean
slang_export_data_quant_struct (slang_export_data_quant
*self
)
79 return self
->structure
!= NULL
;
82 GLboolean
slang_export_data_quant_simple (slang_export_data_quant
*self
)
84 return self
->array_len
== 0 && self
->structure
== NULL
;
87 GLenum
slang_export_data_quant_type (slang_export_data_quant
*self
)
89 assert (self
->structure
== NULL
);
90 return self
->u
.basic_type
;
93 GLuint
slang_export_data_quant_fields (slang_export_data_quant
*self
)
95 assert (self
->structure
!= NULL
);
96 return self
->u
.field_count
;
99 GLuint
slang_export_data_quant_elements (slang_export_data_quant
*self
)
101 if (self
->array_len
== 0)
103 return self
->array_len
;
106 GLuint
slang_export_data_quant_components (slang_export_data_quant
*self
)
108 return self
->size
/ 4;
111 GLuint
slang_export_data_quant_size (slang_export_data_quant
*self
)
117 * slang_export_data_entry
120 GLvoid
slang_export_data_entry_ctr (slang_export_data_entry
*self
)
122 slang_export_data_quant_ctr (&self
->quant
);
123 self
->access
= slang_exp_uniform
;
127 GLvoid
slang_export_data_entry_dtr (slang_export_data_entry
*self
)
129 slang_export_data_quant_dtr (&self
->quant
);
133 * slang_export_data_table
136 GLvoid
slang_export_data_table_ctr (slang_export_data_table
*self
)
138 self
->entries
= NULL
;
143 GLvoid
slang_export_data_table_dtr (slang_export_data_table
*self
)
145 if (self
->entries
!= NULL
)
149 for (i
= 0; i
< self
->count
; i
++)
150 slang_export_data_entry_dtr (&self
->entries
[i
]);
151 slang_alloc_free (self
->entries
);
155 slang_export_data_entry
*slang_export_data_table_add (slang_export_data_table
*self
)
157 const GLuint n
= self
->count
;
159 self
->entries
= (slang_export_data_entry
*) slang_alloc_realloc (self
->entries
,
160 n
* sizeof (slang_export_data_entry
), (n
+ 1) * sizeof (slang_export_data_entry
));
161 if (self
->entries
== NULL
)
163 slang_export_data_entry_ctr (&self
->entries
[n
]);
165 return &self
->entries
[n
];
169 * slang_export_code_entry
172 static GLvoid
slang_export_code_entry_ctr (slang_export_code_entry
*self
)
174 self
->name
= SLANG_ATOM_NULL
;
178 static GLvoid
slang_export_code_entry_dtr (slang_export_code_entry
*self
)
183 * slang_export_code_table
186 GLvoid
slang_export_code_table_ctr (slang_export_code_table
*self
)
188 self
->entries
= NULL
;
193 GLvoid
slang_export_code_table_dtr (slang_export_code_table
*self
)
195 if (self
->entries
!= NULL
)
199 for (i
= 0; i
< self
->count
; i
++)
200 slang_export_code_entry_dtr (&self
->entries
[i
]);
201 slang_alloc_free (self
->entries
);
205 slang_export_code_entry
*slang_export_code_table_add (slang_export_code_table
*self
)
207 const GLuint n
= self
->count
;
209 self
->entries
= (slang_export_code_entry
*) slang_alloc_realloc (self
->entries
,
210 n
* sizeof (slang_export_code_entry
), (n
+ 1) * sizeof (slang_export_code_entry
));
211 if (self
->entries
== NULL
)
213 slang_export_code_entry_ctr (&self
->entries
[n
]);
215 return &self
->entries
[n
];
219 * _slang_find_exported_data()
222 #define EXTRACT_ERROR 0
223 #define EXTRACT_BASIC 1
224 #define EXTRACT_ARRAY 2
225 #define EXTRACT_STRUCT 3
226 #define EXTRACT_STRUCT_ARRAY 4
228 #define EXTRACT_MAXLEN 255
230 static GLuint
extract_name (const char *name
, char *parsed
, GLuint
*element
, const char **end
)
234 if ((name
[0] >= 'a' && name
[0] <= 'z') || (name
[0] >= 'A' && name
[0] <= 'Z') || name
[0] == '_')
238 for (i
= 1; i
< EXTRACT_MAXLEN
; i
++)
240 if ((name
[i
] >= 'a' && name
[i
] <= 'z') || (name
[i
] >= 'A' && name
[i
] <= 'Z') ||
241 (name
[i
] >= '0' && name
[i
] <= '9') || name
[0] == '_')
250 return EXTRACT_BASIC
;
256 return EXTRACT_STRUCT
;
262 if (name
[i
] >= '0' && name
[i
] <= '9')
264 *element
= name
[i
] - '0';
267 if (name
[i
] >= '0' && name
[i
] <= '9')
268 *element
= *element
* 10 + (name
[i
] - '0');
277 return EXTRACT_STRUCT_ARRAY
;
280 return EXTRACT_ARRAY
;
291 return EXTRACT_ERROR
;
294 static GLboolean
validate_extracted (slang_export_data_quant
*q
, GLuint element
, GLuint extr
)
301 return element
< slang_export_data_quant_elements (q
);
303 return slang_export_data_quant_struct (q
);
304 case EXTRACT_STRUCT_ARRAY
:
305 return slang_export_data_quant_struct (q
) && element
< slang_export_data_quant_elements (q
);
310 static GLuint
calculate_offset (slang_export_data_quant
*q
, GLuint element
)
312 if (slang_export_data_quant_array (q
))
313 return element
* slang_export_data_quant_size (q
);
317 static GLboolean
find_exported_data (slang_export_data_quant
*q
, const char *name
,
318 slang_export_data_quant
**quant
, GLuint
*offset
, slang_atom_pool
*atoms
)
320 char parsed
[EXTRACT_MAXLEN
];
321 GLuint result
, element
, i
;
324 const GLuint fields
= slang_export_data_quant_fields (q
);
326 result
= extract_name (name
, parsed
, &element
, &end
);
327 if (result
== EXTRACT_ERROR
)
330 atom
= slang_atom_pool_atom (atoms
, parsed
);
331 if (atom
== SLANG_ATOM_NULL
)
334 for (i
= 0; i
< fields
; i
++)
335 if (q
->structure
[i
].name
== atom
)
337 if (!validate_extracted (&q
->structure
[i
], element
, result
))
339 *offset
+= calculate_offset (&q
->structure
[i
], element
);
340 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
344 *quant
= &q
->structure
[i
];
347 return find_exported_data (&q
->structure
[i
], end
, quant
, offset
, atoms
);
352 GLboolean
_slang_find_exported_data (slang_export_data_table
*table
, const char *name
,
353 slang_export_data_entry
**entry
, slang_export_data_quant
**quant
, GLuint
*offset
)
355 char parsed
[EXTRACT_MAXLEN
];
356 GLuint result
, element
, i
;
360 result
= extract_name (name
, parsed
, &element
, &end
);
361 if (result
== EXTRACT_ERROR
)
364 atom
= slang_atom_pool_atom (table
->atoms
, parsed
);
365 if (atom
== SLANG_ATOM_NULL
)
368 for (i
= 0; i
< table
->count
; i
++)
369 if (table
->entries
[i
].quant
.name
== atom
)
371 if (!validate_extracted (&table
->entries
[i
].quant
, element
, result
))
373 *entry
= &table
->entries
[i
];
374 *offset
= calculate_offset (&table
->entries
[i
].quant
, element
);
375 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
379 *quant
= &table
->entries
[i
].quant
;
382 return find_exported_data (&table
->entries
[i
].quant
, end
, quant
, offset
, table
->atoms
);