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 GLenum
slang_export_data_quant_type (slang_export_data_quant
*self
)
84 assert (self
->structure
== NULL
);
85 return self
->u
.basic_type
;
88 GLuint
slang_export_data_quant_fields (slang_export_data_quant
*self
)
90 assert (self
->structure
!= NULL
);
91 return self
->u
.field_count
;
94 GLuint
slang_export_data_quant_elements (slang_export_data_quant
*self
)
96 if (self
->array_len
== 0)
98 return self
->array_len
;
101 GLuint
slang_export_data_quant_components (slang_export_data_quant
*self
)
103 return self
->size
/ 4;
106 GLuint
slang_export_data_quant_size (slang_export_data_quant
*self
)
112 * slang_export_data_entry
115 GLvoid
slang_export_data_entry_ctr (slang_export_data_entry
*self
)
117 slang_export_data_quant_ctr (&self
->quant
);
118 self
->access
= slang_exp_uniform
;
122 GLvoid
slang_export_data_entry_dtr (slang_export_data_entry
*self
)
124 slang_export_data_quant_dtr (&self
->quant
);
128 * slang_export_data_table
131 GLvoid
slang_export_data_table_ctr (slang_export_data_table
*self
)
133 self
->entries
= NULL
;
138 GLvoid
slang_export_data_table_dtr (slang_export_data_table
*self
)
140 if (self
->entries
!= NULL
)
144 for (i
= 0; i
< self
->count
; i
++)
145 slang_export_data_entry_dtr (&self
->entries
[i
]);
146 slang_alloc_free (self
->entries
);
150 slang_export_data_entry
*slang_export_data_table_add (slang_export_data_table
*self
)
152 const GLuint n
= self
->count
;
154 self
->entries
= (slang_export_data_entry
*) slang_alloc_realloc (self
->entries
,
155 n
* sizeof (slang_export_data_entry
), (n
+ 1) * sizeof (slang_export_data_entry
));
156 if (self
->entries
== NULL
)
158 slang_export_data_entry_ctr (&self
->entries
[n
]);
160 return &self
->entries
[n
];
164 * slang_export_code_entry
167 static GLvoid
slang_export_code_entry_ctr (slang_export_code_entry
*self
)
169 self
->name
= SLANG_ATOM_NULL
;
173 static GLvoid
slang_export_code_entry_dtr (slang_export_code_entry
*self
)
178 * slang_export_code_table
181 GLvoid
slang_export_code_table_ctr (slang_export_code_table
*self
)
183 self
->entries
= NULL
;
188 GLvoid
slang_export_code_table_dtr (slang_export_code_table
*self
)
190 if (self
->entries
!= NULL
)
194 for (i
= 0; i
< self
->count
; i
++)
195 slang_export_code_entry_dtr (&self
->entries
[i
]);
196 slang_alloc_free (self
->entries
);
200 slang_export_code_entry
*slang_export_code_table_add (slang_export_code_table
*self
)
202 const GLuint n
= self
->count
;
204 self
->entries
= (slang_export_code_entry
*) slang_alloc_realloc (self
->entries
,
205 n
* sizeof (slang_export_code_entry
), (n
+ 1) * sizeof (slang_export_code_entry
));
206 if (self
->entries
== NULL
)
208 slang_export_code_entry_ctr (&self
->entries
[n
]);
210 return &self
->entries
[n
];
214 * _slang_find_exported_data()
217 #define EXTRACT_ERROR 0
218 #define EXTRACT_BASIC 1
219 #define EXTRACT_ARRAY 2
220 #define EXTRACT_STRUCT 3
221 #define EXTRACT_STRUCT_ARRAY 4
223 #define EXTRACT_MAXLEN 255
225 static GLuint
extract_name (const char *name
, char *parsed
, GLuint
*element
, const char **end
)
229 if ((name
[0] >= 'a' && name
[0] <= 'z') || (name
[0] >= 'A' && name
[0] <= 'Z') || name
[0] == '_')
233 for (i
= 1; i
< EXTRACT_MAXLEN
; i
++)
235 if ((name
[i
] >= 'a' && name
[i
] <= 'z') || (name
[i
] >= 'A' && name
[i
] <= 'Z') ||
236 (name
[i
] >= '0' && name
[i
] <= '9') || name
[0] == '_')
245 return EXTRACT_BASIC
;
251 return EXTRACT_STRUCT
;
257 if (name
[i
] >= '0' && name
[i
] <= '9')
259 *element
= name
[i
] - '0';
262 if (name
[i
] >= '0' && name
[i
] <= '9')
263 *element
= *element
* 10 + (name
[i
] - '0');
272 return EXTRACT_STRUCT_ARRAY
;
275 return EXTRACT_ARRAY
;
286 return EXTRACT_ERROR
;
289 static GLboolean
validate_extracted (slang_export_data_quant
*q
, GLuint element
, GLuint extr
)
296 return element
< slang_export_data_quant_elements (q
);
298 return slang_export_data_quant_struct (q
);
299 case EXTRACT_STRUCT_ARRAY
:
300 return slang_export_data_quant_struct (q
) && element
< slang_export_data_quant_elements (q
);
305 static GLuint
calculate_offset (slang_export_data_quant
*q
, GLuint element
)
307 if (slang_export_data_quant_array (q
))
308 return element
* slang_export_data_quant_size (q
);
312 static GLboolean
find_exported_data (slang_export_data_quant
*q
, const char *name
,
313 slang_export_data_quant
**quant
, GLuint
*offset
, slang_atom_pool
*atoms
)
315 char parsed
[EXTRACT_MAXLEN
];
316 GLuint result
, element
, i
;
319 const GLuint fields
= slang_export_data_quant_fields (q
);
321 result
= extract_name (name
, parsed
, &element
, &end
);
322 if (result
== EXTRACT_ERROR
)
325 atom
= slang_atom_pool_atom (atoms
, parsed
);
326 if (atom
== SLANG_ATOM_NULL
)
329 for (i
= 0; i
< fields
; i
++)
330 if (q
->structure
[i
].name
== atom
)
332 if (!validate_extracted (&q
->structure
[i
], element
, result
))
334 *offset
+= calculate_offset (&q
->structure
[i
], element
);
335 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
339 *quant
= &q
->structure
[i
];
342 return find_exported_data (&q
->structure
[i
], end
, quant
, offset
, atoms
);
347 GLboolean
_slang_find_exported_data (slang_export_data_table
*table
, const char *name
,
348 slang_export_data_entry
**entry
, slang_export_data_quant
**quant
, GLuint
*offset
)
350 char parsed
[EXTRACT_MAXLEN
];
351 GLuint result
, element
, i
;
355 result
= extract_name (name
, parsed
, &element
, &end
);
356 if (result
== EXTRACT_ERROR
)
359 atom
= slang_atom_pool_atom (table
->atoms
, parsed
);
360 if (atom
== SLANG_ATOM_NULL
)
363 for (i
= 0; i
< table
->count
; i
++)
364 if (table
->entries
[i
].quant
.name
== atom
)
366 if (!validate_extracted (&table
->entries
[i
].quant
, element
, result
))
368 *entry
= &table
->entries
[i
];
369 *offset
= calculate_offset (&table
->entries
[i
].quant
, element
);
370 if (result
== EXTRACT_BASIC
|| result
== EXTRACT_ARRAY
)
374 *quant
= &table
->entries
[i
].quant
;
377 return find_exported_data (&table
->entries
[i
].quant
, end
, quant
, offset
, table
->atoms
);