From 6acf1e93a291511cfb20b0e2aeda6e71ceb62a62 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 25 Apr 2006 10:11:59 +0000 Subject: Remove carriage returns. --- src/mesa/shader/slang/slang_export.c | 772 ++++++++--------- src/mesa/shader/slang/slang_export.h | 366 ++++---- src/mesa/shader/slang/slang_link.c | 1572 +++++++++++++++++----------------- src/mesa/shader/slang/slang_link.h | 626 +++++++------- 4 files changed, 1668 insertions(+), 1668 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/slang/slang_export.c b/src/mesa/shader/slang/slang_export.c index dcf64244b74..9620ef07901 100644 --- a/src/mesa/shader/slang/slang_export.c +++ b/src/mesa/shader/slang/slang_export.c @@ -1,386 +1,386 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file slang_export.c - * interface between assembly code and the application - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_export.h" - -/* - * slang_export_data_quant - */ - -GLvoid slang_export_data_quant_ctr (slang_export_data_quant *self) -{ - self->name = SLANG_ATOM_NULL; - self->size = 0; - self->array_len = 0; - self->structure = NULL; - self->u.basic_type = GL_FLOAT; -} - -GLvoid slang_export_data_quant_dtr (slang_export_data_quant *self) -{ - if (self->structure != NULL) - { - GLuint i; - - for (i = 0; i < self->u.field_count; i++) - slang_export_data_quant_dtr (&self->structure[i]); - slang_alloc_free (self->structure); - } -} - -slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *self) -{ - const GLuint n = self->u.field_count; - - self->structure = (slang_export_data_quant *) slang_alloc_realloc (self->structure, - n * sizeof (slang_export_data_quant), (n + 1) * sizeof (slang_export_data_quant)); - if (self->structure == NULL) - return NULL; - slang_export_data_quant_ctr (&self->structure[n]); - self->u.field_count++; - return &self->structure[n]; -} - -GLboolean slang_export_data_quant_array (slang_export_data_quant *self) -{ - return self->array_len != 0; -} - -GLboolean slang_export_data_quant_struct (slang_export_data_quant *self) -{ - return self->structure != NULL; -} - -GLboolean slang_export_data_quant_simple (slang_export_data_quant *self) -{ - return self->array_len == 0 && self->structure == NULL; -} - -GLenum slang_export_data_quant_type (slang_export_data_quant *self) -{ - assert (self->structure == NULL); - return self->u.basic_type; -} - -GLuint slang_export_data_quant_fields (slang_export_data_quant *self) -{ - assert (self->structure != NULL); - return self->u.field_count; -} - -GLuint slang_export_data_quant_elements (slang_export_data_quant *self) -{ - if (self->array_len == 0) - return 1; - return self->array_len; -} - -GLuint slang_export_data_quant_components (slang_export_data_quant *self) -{ - return self->size / 4; -} - -GLuint slang_export_data_quant_size (slang_export_data_quant *self) -{ - return self->size; -} - -/* - * slang_export_data_entry - */ - -GLvoid slang_export_data_entry_ctr (slang_export_data_entry *self) -{ - slang_export_data_quant_ctr (&self->quant); - self->access = slang_exp_uniform; - self->address = ~0; -} - -GLvoid slang_export_data_entry_dtr (slang_export_data_entry *self) -{ - slang_export_data_quant_dtr (&self->quant); -} - -/* - * slang_export_data_table - */ - -GLvoid slang_export_data_table_ctr (slang_export_data_table *self) -{ - self->entries = NULL; - self->count = 0; - self->atoms = NULL; -} - -GLvoid slang_export_data_table_dtr (slang_export_data_table *self) -{ - if (self->entries != NULL) - { - GLuint i; - - for (i = 0; i < self->count; i++) - slang_export_data_entry_dtr (&self->entries[i]); - slang_alloc_free (self->entries); - } -} - -slang_export_data_entry *slang_export_data_table_add (slang_export_data_table *self) -{ - const GLuint n = self->count; - - self->entries = (slang_export_data_entry *) slang_alloc_realloc (self->entries, - n * sizeof (slang_export_data_entry), (n + 1) * sizeof (slang_export_data_entry)); - if (self->entries == NULL) - return NULL; - slang_export_data_entry_ctr (&self->entries[n]); - self->count++; - return &self->entries[n]; -} - -/* - * slang_export_code_entry - */ - -static GLvoid slang_export_code_entry_ctr (slang_export_code_entry *self) -{ - self->name = SLANG_ATOM_NULL; - self->address = ~0; -} - -static GLvoid slang_export_code_entry_dtr (slang_export_code_entry *self) -{ -} - -/* - * slang_export_code_table - */ - -GLvoid slang_export_code_table_ctr (slang_export_code_table *self) -{ - self->entries = NULL; - self->count = 0; - self->atoms = NULL; -} - -GLvoid slang_export_code_table_dtr (slang_export_code_table *self) -{ - if (self->entries != NULL) - { - GLuint i; - - for (i = 0; i < self->count; i++) - slang_export_code_entry_dtr (&self->entries[i]); - slang_alloc_free (self->entries); - } -} - -slang_export_code_entry *slang_export_code_table_add (slang_export_code_table *self) -{ - const GLuint n = self->count; - - self->entries = (slang_export_code_entry *) slang_alloc_realloc (self->entries, - n * sizeof (slang_export_code_entry), (n + 1) * sizeof (slang_export_code_entry)); - if (self->entries == NULL) - return NULL; - slang_export_code_entry_ctr (&self->entries[n]); - self->count++; - return &self->entries[n]; -} - -/* - * _slang_find_exported_data() - */ - -#define EXTRACT_ERROR 0 -#define EXTRACT_BASIC 1 -#define EXTRACT_ARRAY 2 -#define EXTRACT_STRUCT 3 -#define EXTRACT_STRUCT_ARRAY 4 - -#define EXTRACT_MAXLEN 255 - -static GLuint extract_name (const char *name, char *parsed, GLuint *element, const char **end) -{ - GLuint i; - - if ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z') || name[0] == '_') - { - parsed[0] = name[0]; - - for (i = 1; i < EXTRACT_MAXLEN; i++) - { - if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') || - (name[i] >= '0' && name[i] <= '9') || name[0] == '_') - { - parsed[i] = name[i]; - } - else - { - if (name[i] == '\0') - { - parsed[i] = '\0'; - return EXTRACT_BASIC; - } - if (name[i] == '.') - { - parsed[i] = '\0'; - *end = &name[i + 1]; - return EXTRACT_STRUCT; - } - if (name[i] == '[') - { - parsed[i] = '\0'; - i++; - if (name[i] >= '0' && name[i] <= '9') - { - *element = name[i] - '0'; - for (i++; ; i++) - { - if (name[i] >= '0' && name[i] <= '9') - *element = *element * 10 + (name[i] - '0'); - else - { - if (name[i] == ']') - { - i++; - if (name[i] == '.') - { - *end = &name[i + 1]; - return EXTRACT_STRUCT_ARRAY; - } - *end = &name[i]; - return EXTRACT_ARRAY; - } - break; - } - } - } - } - break; - } - } - } - return EXTRACT_ERROR; -} - -static GLboolean validate_extracted (slang_export_data_quant *q, GLuint element, GLuint extr) -{ - switch (extr) - { - case EXTRACT_BASIC: - return GL_TRUE; - case EXTRACT_ARRAY: - return element < slang_export_data_quant_elements (q); - case EXTRACT_STRUCT: - return slang_export_data_quant_struct (q); - case EXTRACT_STRUCT_ARRAY: - return slang_export_data_quant_struct (q) && element < slang_export_data_quant_elements (q); - } - return GL_FALSE; -} - -static GLuint calculate_offset (slang_export_data_quant *q, GLuint element) -{ - if (slang_export_data_quant_array (q)) - return element * slang_export_data_quant_size (q); - return 0; -} - -static GLboolean find_exported_data (slang_export_data_quant *q, const char *name, - slang_export_data_quant **quant, GLuint *offset, slang_atom_pool *atoms) -{ - char parsed[EXTRACT_MAXLEN]; - GLuint result, element, i; - const char *end; - slang_atom atom; - const GLuint fields = slang_export_data_quant_fields (q); - - result = extract_name (name, parsed, &element, &end); - if (result == EXTRACT_ERROR) - return GL_FALSE; - - atom = slang_atom_pool_atom (atoms, parsed); - if (atom == SLANG_ATOM_NULL) - return GL_FALSE; - - for (i = 0; i < fields; i++) - if (q->structure[i].name == atom) - { - if (!validate_extracted (&q->structure[i], element, result)) - return GL_FALSE; - *offset += calculate_offset (&q->structure[i], element); - if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY) - { - if (*end != '\0') - return GL_FALSE; - *quant = &q->structure[i]; - return GL_TRUE; - } - return find_exported_data (&q->structure[i], end, quant, offset, atoms); - } - return GL_FALSE; -} - -GLboolean _slang_find_exported_data (slang_export_data_table *table, const char *name, - slang_export_data_entry **entry, slang_export_data_quant **quant, GLuint *offset) -{ - char parsed[EXTRACT_MAXLEN]; - GLuint result, element, i; - const char *end; - slang_atom atom; - - result = extract_name (name, parsed, &element, &end); - if (result == EXTRACT_ERROR) - return GL_FALSE; - - atom = slang_atom_pool_atom (table->atoms, parsed); - if (atom == SLANG_ATOM_NULL) - return GL_FALSE; - - for (i = 0; i < table->count; i++) - if (table->entries[i].quant.name == atom) - { - if (!validate_extracted (&table->entries[i].quant, element, result)) - return GL_FALSE; - *entry = &table->entries[i]; - *offset = calculate_offset (&table->entries[i].quant, element); - if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY) - { - if (*end != '\0') - return GL_FALSE; - *quant = &table->entries[i].quant; - return GL_TRUE; - } - return find_exported_data (&table->entries[i].quant, end, quant, offset, table->atoms); - } - return GL_FALSE; -} - +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_export.c + * interface between assembly code and the application + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_export.h" + +/* + * slang_export_data_quant + */ + +GLvoid slang_export_data_quant_ctr (slang_export_data_quant *self) +{ + self->name = SLANG_ATOM_NULL; + self->size = 0; + self->array_len = 0; + self->structure = NULL; + self->u.basic_type = GL_FLOAT; +} + +GLvoid slang_export_data_quant_dtr (slang_export_data_quant *self) +{ + if (self->structure != NULL) + { + GLuint i; + + for (i = 0; i < self->u.field_count; i++) + slang_export_data_quant_dtr (&self->structure[i]); + slang_alloc_free (self->structure); + } +} + +slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *self) +{ + const GLuint n = self->u.field_count; + + self->structure = (slang_export_data_quant *) slang_alloc_realloc (self->structure, + n * sizeof (slang_export_data_quant), (n + 1) * sizeof (slang_export_data_quant)); + if (self->structure == NULL) + return NULL; + slang_export_data_quant_ctr (&self->structure[n]); + self->u.field_count++; + return &self->structure[n]; +} + +GLboolean slang_export_data_quant_array (slang_export_data_quant *self) +{ + return self->array_len != 0; +} + +GLboolean slang_export_data_quant_struct (slang_export_data_quant *self) +{ + return self->structure != NULL; +} + +GLboolean slang_export_data_quant_simple (slang_export_data_quant *self) +{ + return self->array_len == 0 && self->structure == NULL; +} + +GLenum slang_export_data_quant_type (slang_export_data_quant *self) +{ + assert (self->structure == NULL); + return self->u.basic_type; +} + +GLuint slang_export_data_quant_fields (slang_export_data_quant *self) +{ + assert (self->structure != NULL); + return self->u.field_count; +} + +GLuint slang_export_data_quant_elements (slang_export_data_quant *self) +{ + if (self->array_len == 0) + return 1; + return self->array_len; +} + +GLuint slang_export_data_quant_components (slang_export_data_quant *self) +{ + return self->size / 4; +} + +GLuint slang_export_data_quant_size (slang_export_data_quant *self) +{ + return self->size; +} + +/* + * slang_export_data_entry + */ + +GLvoid slang_export_data_entry_ctr (slang_export_data_entry *self) +{ + slang_export_data_quant_ctr (&self->quant); + self->access = slang_exp_uniform; + self->address = ~0; +} + +GLvoid slang_export_data_entry_dtr (slang_export_data_entry *self) +{ + slang_export_data_quant_dtr (&self->quant); +} + +/* + * slang_export_data_table + */ + +GLvoid slang_export_data_table_ctr (slang_export_data_table *self) +{ + self->entries = NULL; + self->count = 0; + self->atoms = NULL; +} + +GLvoid slang_export_data_table_dtr (slang_export_data_table *self) +{ + if (self->entries != NULL) + { + GLuint i; + + for (i = 0; i < self->count; i++) + slang_export_data_entry_dtr (&self->entries[i]); + slang_alloc_free (self->entries); + } +} + +slang_export_data_entry *slang_export_data_table_add (slang_export_data_table *self) +{ + const GLuint n = self->count; + + self->entries = (slang_export_data_entry *) slang_alloc_realloc (self->entries, + n * sizeof (slang_export_data_entry), (n + 1) * sizeof (slang_export_data_entry)); + if (self->entries == NULL) + return NULL; + slang_export_data_entry_ctr (&self->entries[n]); + self->count++; + return &self->entries[n]; +} + +/* + * slang_export_code_entry + */ + +static GLvoid slang_export_code_entry_ctr (slang_export_code_entry *self) +{ + self->name = SLANG_ATOM_NULL; + self->address = ~0; +} + +static GLvoid slang_export_code_entry_dtr (slang_export_code_entry *self) +{ +} + +/* + * slang_export_code_table + */ + +GLvoid slang_export_code_table_ctr (slang_export_code_table *self) +{ + self->entries = NULL; + self->count = 0; + self->atoms = NULL; +} + +GLvoid slang_export_code_table_dtr (slang_export_code_table *self) +{ + if (self->entries != NULL) + { + GLuint i; + + for (i = 0; i < self->count; i++) + slang_export_code_entry_dtr (&self->entries[i]); + slang_alloc_free (self->entries); + } +} + +slang_export_code_entry *slang_export_code_table_add (slang_export_code_table *self) +{ + const GLuint n = self->count; + + self->entries = (slang_export_code_entry *) slang_alloc_realloc (self->entries, + n * sizeof (slang_export_code_entry), (n + 1) * sizeof (slang_export_code_entry)); + if (self->entries == NULL) + return NULL; + slang_export_code_entry_ctr (&self->entries[n]); + self->count++; + return &self->entries[n]; +} + +/* + * _slang_find_exported_data() + */ + +#define EXTRACT_ERROR 0 +#define EXTRACT_BASIC 1 +#define EXTRACT_ARRAY 2 +#define EXTRACT_STRUCT 3 +#define EXTRACT_STRUCT_ARRAY 4 + +#define EXTRACT_MAXLEN 255 + +static GLuint extract_name (const char *name, char *parsed, GLuint *element, const char **end) +{ + GLuint i; + + if ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z') || name[0] == '_') + { + parsed[0] = name[0]; + + for (i = 1; i < EXTRACT_MAXLEN; i++) + { + if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') || + (name[i] >= '0' && name[i] <= '9') || name[0] == '_') + { + parsed[i] = name[i]; + } + else + { + if (name[i] == '\0') + { + parsed[i] = '\0'; + return EXTRACT_BASIC; + } + if (name[i] == '.') + { + parsed[i] = '\0'; + *end = &name[i + 1]; + return EXTRACT_STRUCT; + } + if (name[i] == '[') + { + parsed[i] = '\0'; + i++; + if (name[i] >= '0' && name[i] <= '9') + { + *element = name[i] - '0'; + for (i++; ; i++) + { + if (name[i] >= '0' && name[i] <= '9') + *element = *element * 10 + (name[i] - '0'); + else + { + if (name[i] == ']') + { + i++; + if (name[i] == '.') + { + *end = &name[i + 1]; + return EXTRACT_STRUCT_ARRAY; + } + *end = &name[i]; + return EXTRACT_ARRAY; + } + break; + } + } + } + } + break; + } + } + } + return EXTRACT_ERROR; +} + +static GLboolean validate_extracted (slang_export_data_quant *q, GLuint element, GLuint extr) +{ + switch (extr) + { + case EXTRACT_BASIC: + return GL_TRUE; + case EXTRACT_ARRAY: + return element < slang_export_data_quant_elements (q); + case EXTRACT_STRUCT: + return slang_export_data_quant_struct (q); + case EXTRACT_STRUCT_ARRAY: + return slang_export_data_quant_struct (q) && element < slang_export_data_quant_elements (q); + } + return GL_FALSE; +} + +static GLuint calculate_offset (slang_export_data_quant *q, GLuint element) +{ + if (slang_export_data_quant_array (q)) + return element * slang_export_data_quant_size (q); + return 0; +} + +static GLboolean find_exported_data (slang_export_data_quant *q, const char *name, + slang_export_data_quant **quant, GLuint *offset, slang_atom_pool *atoms) +{ + char parsed[EXTRACT_MAXLEN]; + GLuint result, element, i; + const char *end; + slang_atom atom; + const GLuint fields = slang_export_data_quant_fields (q); + + result = extract_name (name, parsed, &element, &end); + if (result == EXTRACT_ERROR) + return GL_FALSE; + + atom = slang_atom_pool_atom (atoms, parsed); + if (atom == SLANG_ATOM_NULL) + return GL_FALSE; + + for (i = 0; i < fields; i++) + if (q->structure[i].name == atom) + { + if (!validate_extracted (&q->structure[i], element, result)) + return GL_FALSE; + *offset += calculate_offset (&q->structure[i], element); + if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY) + { + if (*end != '\0') + return GL_FALSE; + *quant = &q->structure[i]; + return GL_TRUE; + } + return find_exported_data (&q->structure[i], end, quant, offset, atoms); + } + return GL_FALSE; +} + +GLboolean _slang_find_exported_data (slang_export_data_table *table, const char *name, + slang_export_data_entry **entry, slang_export_data_quant **quant, GLuint *offset) +{ + char parsed[EXTRACT_MAXLEN]; + GLuint result, element, i; + const char *end; + slang_atom atom; + + result = extract_name (name, parsed, &element, &end); + if (result == EXTRACT_ERROR) + return GL_FALSE; + + atom = slang_atom_pool_atom (table->atoms, parsed); + if (atom == SLANG_ATOM_NULL) + return GL_FALSE; + + for (i = 0; i < table->count; i++) + if (table->entries[i].quant.name == atom) + { + if (!validate_extracted (&table->entries[i].quant, element, result)) + return GL_FALSE; + *entry = &table->entries[i]; + *offset = calculate_offset (&table->entries[i].quant, element); + if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY) + { + if (*end != '\0') + return GL_FALSE; + *quant = &table->entries[i].quant; + return GL_TRUE; + } + return find_exported_data (&table->entries[i].quant, end, quant, offset, table->atoms); + } + return GL_FALSE; +} + diff --git a/src/mesa/shader/slang/slang_export.h b/src/mesa/shader/slang/slang_export.h index aaf00773c1e..40ceac19e10 100644 --- a/src/mesa/shader/slang/slang_export.h +++ b/src/mesa/shader/slang/slang_export.h @@ -1,183 +1,183 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#if !defined SLANG_EXPORT_H -#define SLANG_EXPORT_H - -#include "slang_utility.h" - -#if defined __cplusplus -extern "C" { -#endif - -/* - * Basic data quantity to transfer between application and assembly. - * The is the actual size of the data quantity including padding, if any. It is - * used to calculate offsets from the beginning of the data. - * If the is not 0, the data quantity is an array of size. - * If the is not NULL, the data quantity is a struct. The is - * invalid and the holds the size of the array. - * The values match those of parameter for glGetActiveUniformARB. - */ - -typedef struct slang_export_data_quant_ -{ - slang_atom name; - GLuint size; - GLuint array_len; - struct slang_export_data_quant_ *structure; - union - { - GLenum basic_type; - GLuint field_count; - } u; -} slang_export_data_quant; - -GLvoid slang_export_data_quant_ctr (slang_export_data_quant *); -GLvoid slang_export_data_quant_dtr (slang_export_data_quant *); -slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *); - -/* - * Returns GL_FALSE if the quant is not an array. - */ -GLboolean slang_export_data_quant_array (slang_export_data_quant *); - -/* - * Returns GL_FALSE if the quant is not a structure. - */ -GLboolean slang_export_data_quant_struct (slang_export_data_quant *); - -/* - * Returns GL_TRUE if the quant is neither an array nor a structure. - */ -GLboolean slang_export_data_quant_simple (slang_export_data_quant *); - -/* - * Returns basic type of the quant. It must not be a structure. - */ -GLenum slang_export_data_quant_type (slang_export_data_quant *); - -/* - * Returns number of fields in the quant that is a structure. - */ -GLuint slang_export_data_quant_fields (slang_export_data_quant *); - -/* - * Return number of elements in the quant. - * For arrays, return the size of the array. - * Otherwise, return 1. - */ -GLuint slang_export_data_quant_elements (slang_export_data_quant *); - -/* - * Returns total number of components withing the quant element. - */ -GLuint slang_export_data_quant_components (slang_export_data_quant *); - -/* - * Returns size of the quant element. - */ -GLuint slang_export_data_quant_size (slang_export_data_quant *); - -/* - * Data access pattern. Specifies how data is accessed at what frequency. - */ - -typedef enum -{ - slang_exp_uniform, - slang_exp_varying, - slang_exp_attribute -} slang_export_data_access; - -/* - * Data export entry. Holds the data type information, access pattern and base address. - */ - -typedef struct -{ - slang_export_data_quant quant; - slang_export_data_access access; - GLuint address; -} slang_export_data_entry; - -GLvoid slang_export_data_entry_ctr (slang_export_data_entry *); -GLvoid slang_export_data_entry_dtr (slang_export_data_entry *); - -/* - * Data export table. - */ - -typedef struct -{ - slang_export_data_entry *entries; - GLuint count; - slang_atom_pool *atoms; -} slang_export_data_table; - -GLvoid slang_export_data_table_ctr (slang_export_data_table *); -GLvoid slang_export_data_table_dtr (slang_export_data_table *); -slang_export_data_entry *slang_export_data_table_add (slang_export_data_table *); - -/* - * Code export entry. Contains label name and its entry point (label, address). - */ - -typedef struct -{ - slang_atom name; - GLuint address; -} slang_export_code_entry; - -/* - * Code export table. - */ - -typedef struct -{ - slang_export_code_entry *entries; - GLuint count; - slang_atom_pool *atoms; -} slang_export_code_table; - -GLvoid slang_export_code_table_ctr (slang_export_code_table *); -GLvoid slang_export_code_table_dtr (slang_export_code_table *); -slang_export_code_entry *slang_export_code_table_add (slang_export_code_table *); - -/* - * _slang_find_exported_data() - * - * Parses the name string and returns corresponding data entry, data quantity and offset. - * Returns GL_TRUE if the data is found, returns GL_FALSE otherwise. - */ - -GLboolean _slang_find_exported_data (slang_export_data_table *, const char *, - slang_export_data_entry **, slang_export_data_quant **, GLuint *); - -#ifdef __cplusplus -} -#endif - -#endif - +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_EXPORT_H +#define SLANG_EXPORT_H + +#include "slang_utility.h" + +#if defined __cplusplus +extern "C" { +#endif + +/* + * Basic data quantity to transfer between application and assembly. + * The is the actual size of the data quantity including padding, if any. It is + * used to calculate offsets from the beginning of the data. + * If the is not 0, the data quantity is an array of size. + * If the is not NULL, the data quantity is a struct. The is + * invalid and the holds the size of the array. + * The values match those of parameter for glGetActiveUniformARB. + */ + +typedef struct slang_export_data_quant_ +{ + slang_atom name; + GLuint size; + GLuint array_len; + struct slang_export_data_quant_ *structure; + union + { + GLenum basic_type; + GLuint field_count; + } u; +} slang_export_data_quant; + +GLvoid slang_export_data_quant_ctr (slang_export_data_quant *); +GLvoid slang_export_data_quant_dtr (slang_export_data_quant *); +slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *); + +/* + * Returns GL_FALSE if the quant is not an array. + */ +GLboolean slang_export_data_quant_array (slang_export_data_quant *); + +/* + * Returns GL_FALSE if the quant is not a structure. + */ +GLboolean slang_export_data_quant_struct (slang_export_data_quant *); + +/* + * Returns GL_TRUE if the quant is neither an array nor a structure. + */ +GLboolean slang_export_data_quant_simple (slang_export_data_quant *); + +/* + * Returns basic type of the quant. It must not be a structure. + */ +GLenum slang_export_data_quant_type (slang_export_data_quant *); + +/* + * Returns number of fields in the quant that is a structure. + */ +GLuint slang_export_data_quant_fields (slang_export_data_quant *); + +/* + * Return number of elements in the quant. + * For arrays, return the size of the array. + * Otherwise, return 1. + */ +GLuint slang_export_data_quant_elements (slang_export_data_quant *); + +/* + * Returns total number of components withing the quant element. + */ +GLuint slang_export_data_quant_components (slang_export_data_quant *); + +/* + * Returns size of the quant element. + */ +GLuint slang_export_data_quant_size (slang_export_data_quant *); + +/* + * Data access pattern. Specifies how data is accessed at what frequency. + */ + +typedef enum +{ + slang_exp_uniform, + slang_exp_varying, + slang_exp_attribute +} slang_export_data_access; + +/* + * Data export entry. Holds the data type information, access pattern and base address. + */ + +typedef struct +{ + slang_export_data_quant quant; + slang_export_data_access access; + GLuint address; +} slang_export_data_entry; + +GLvoid slang_export_data_entry_ctr (slang_export_data_entry *); +GLvoid slang_export_data_entry_dtr (slang_export_data_entry *); + +/* + * Data export table. + */ + +typedef struct +{ + slang_export_data_entry *entries; + GLuint count; + slang_atom_pool *atoms; +} slang_export_data_table; + +GLvoid slang_export_data_table_ctr (slang_export_data_table *); +GLvoid slang_export_data_table_dtr (slang_export_data_table *); +slang_export_data_entry *slang_export_data_table_add (slang_export_data_table *); + +/* + * Code export entry. Contains label name and its entry point (label, address). + */ + +typedef struct +{ + slang_atom name; + GLuint address; +} slang_export_code_entry; + +/* + * Code export table. + */ + +typedef struct +{ + slang_export_code_entry *entries; + GLuint count; + slang_atom_pool *atoms; +} slang_export_code_table; + +GLvoid slang_export_code_table_ctr (slang_export_code_table *); +GLvoid slang_export_code_table_dtr (slang_export_code_table *); +slang_export_code_entry *slang_export_code_table_add (slang_export_code_table *); + +/* + * _slang_find_exported_data() + * + * Parses the name string and returns corresponding data entry, data quantity and offset. + * Returns GL_TRUE if the data is found, returns GL_FALSE otherwise. + */ + +GLboolean _slang_find_exported_data (slang_export_data_table *, const char *, + slang_export_data_entry **, slang_export_data_quant **, GLuint *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 9d61a29e912..95e390020e4 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -1,786 +1,786 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file slang_link.c - * slang linker - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_link.h" -#include "slang_analyse.h" - -static GLboolean entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms) -{ - const char *str = slang_atom_pool_id (atoms, name); - return str[0] == 'g' && str[1] == 'l' && str[2] == '_'; -} - -/* - * slang_active_variables - */ - -static GLvoid slang_active_variables_ctr (slang_active_variables *self) -{ - self->table = NULL; - self->count = 0; -} - -static GLvoid slang_active_variables_dtr (slang_active_variables *self) -{ - GLuint i; - - for (i = 0; i < self->count; i++) - slang_alloc_free (self->table[i].name); - slang_alloc_free (self->table); -} - -static GLboolean add_simple_variable (slang_active_variables *self, slang_export_data_quant *q, - const char *name) -{ - const GLuint n = self->count; - - self->table = (slang_active_variable *) slang_alloc_realloc (self->table, - n * sizeof (slang_active_variable), (n + 1) * sizeof (slang_active_variable)); - if (self->table == NULL) - return GL_FALSE; - - self->table[n].quant = q; - self->table[n].name = slang_string_duplicate (name); - if (self->table[n].name == NULL) - return GL_FALSE; - self->count++; - - return GL_TRUE; -} - -static GLboolean add_complex_variable (slang_active_variables *self, slang_export_data_quant *q, - char *name, slang_atom_pool *atoms) -{ - slang_string_concat (name, slang_atom_pool_id (atoms, q->name)); - if (slang_export_data_quant_array (q)) - slang_string_concat (name, "[0]"); - - if (slang_export_data_quant_struct (q)) - { - GLuint dot_pos, i; - const GLuint fields = slang_export_data_quant_fields (q); - - slang_string_concat (name, "."); - dot_pos = slang_string_length (name); - - for (i = 0; i < fields; i++) - { - if (!add_complex_variable (self, &q->structure[i], name, atoms)) - return GL_FALSE; - - name[dot_pos] = '\0'; - } - - return GL_TRUE; - } - - return add_simple_variable (self, q, name); -} - -static GLboolean gather_active_variables (slang_active_variables *self, - slang_export_data_table *tbl, slang_export_data_access access) -{ - GLuint i; - - for (i = 0; i < tbl->count; i++) - if (tbl->entries[i].access == access) - { - char name[1024] = ""; - - if (!add_complex_variable (self, &tbl->entries[i].quant, name, tbl->atoms)) - return GL_FALSE; - } - - return GL_TRUE; -} - -/* - * slang_attrib_overrides - */ - -static GLvoid slang_attrib_overrides_ctr (slang_attrib_overrides *self) -{ - self->table = NULL; - self->count = 0; -} - -static GLvoid slang_attrib_overrides_dtr (slang_attrib_overrides *self) -{ - GLuint i; - - for (i = 0; i < self->count; i++) - slang_alloc_free (self->table[i].name); - slang_alloc_free (self->table); -} - -GLboolean slang_attrib_overrides_add (slang_attrib_overrides *self, GLuint index, const GLchar *name) -{ - const GLuint n = self->count; - GLuint i; - - for (i = 0; i < n; i++) - if (slang_string_compare (name, self->table[i].name) == 0) - { - self->table[i].index = index; - return GL_TRUE; - } - - self->table = (slang_attrib_override *) slang_alloc_realloc (self->table, - n * sizeof (slang_attrib_override), (n + 1) * sizeof (slang_attrib_override)); - if (self->table == NULL) - return GL_FALSE; - - self->table[n].index = index; - self->table[n].name = slang_string_duplicate (name); - if (self->table[n].name == NULL) - return GL_FALSE; - self->count++; - - return GL_TRUE; -} - -static GLuint lookup_attrib_override (slang_attrib_overrides *self, const GLchar *name) -{ - GLuint i; - - for (i = 0; self->count; i++) - if (slang_string_compare (name, self->table[i].name) == 0) - return self->table[i].index; - return MAX_VERTEX_ATTRIBS; -} - -/* - * slang_uniform_bindings - */ - -static GLvoid slang_uniform_bindings_ctr (slang_uniform_bindings *self) -{ - self->table = NULL; - self->count = 0; -} - -static GLvoid slang_uniform_bindings_dtr (slang_uniform_bindings *self) -{ - GLuint i; - - for (i = 0; i < self->count; i++) - slang_alloc_free (self->table[i].name); - slang_alloc_free (self->table); -} - -static GLboolean add_simple_uniform_binding (slang_uniform_bindings *self, - slang_export_data_quant *q, const char *name, GLuint index, GLuint addr) -{ - const GLuint n = self->count; - GLuint i; - - for (i = 0; i < n; i++) - if (slang_string_compare (self->table[i].name, name) == 0) - { - self->table[i].address[index] = addr; - return GL_TRUE; - } - - self->table = (slang_uniform_binding *) slang_alloc_realloc (self->table, - n * sizeof (slang_uniform_binding), (n + 1) * sizeof (slang_uniform_binding)); - if (self->table == NULL) - return GL_FALSE; - - self->table[n].quant = q; - self->table[n].name = slang_string_duplicate (name); - if (self->table[n].name == NULL) - return GL_FALSE; - for (i = 0; i < SLANG_SHADER_MAX; i++) - self->table[n].address[i] = ~0; - self->table[n].address[index] = addr; - self->count++; - - return GL_TRUE; -} - -static GLboolean add_complex_uniform_binding (slang_uniform_bindings *self, - slang_export_data_quant *q, char *name, slang_atom_pool *atoms, GLuint index, GLuint addr) -{ - GLuint count, i; - - slang_string_concat (name, slang_atom_pool_id (atoms, q->name)); - count = slang_export_data_quant_elements (q); - for (i = 0; i < count; i++) - { - GLuint bracket_pos; - - bracket_pos = slang_string_length (name); - if (slang_export_data_quant_array (q)) - _mesa_sprintf (name + slang_string_length (name), "[%d]", i); - - if (slang_export_data_quant_struct (q)) - { - GLuint dot_pos, i; - const GLuint fields = slang_export_data_quant_fields (q); - - slang_string_concat (name, "."); - dot_pos = slang_string_length (name); - - for (i = 0; i < fields; i++) - { - if (!add_complex_uniform_binding (self, &q->structure[i], name, atoms, index, addr)) - return GL_FALSE; - - name[dot_pos] = '\0'; - addr += slang_export_data_quant_size (&q->structure[i]); - } - } - else - { - if (!add_simple_uniform_binding (self, q, name, index, addr)) - return GL_FALSE; - - addr += slang_export_data_quant_size (q); - } - - name[bracket_pos] = '\0'; - } - - return GL_TRUE; -} - -static GLboolean gather_uniform_bindings (slang_uniform_bindings *self, - slang_export_data_table *tbl, GLuint index) -{ - GLuint i; - - for (i = 0; i < tbl->count; i++) - if (tbl->entries[i].access == slang_exp_uniform) - { - char name[1024] = ""; - - if (!add_complex_uniform_binding (self, &tbl->entries[i].quant, name, tbl->atoms, index, - tbl->entries[i].address)) - return GL_FALSE; - } - - return GL_TRUE; -} - -/* - * slang_attrib_bindings - */ - -static GLvoid slang_attrib_bindings_ctr (slang_attrib_bindings *self) -{ - GLuint i; - - self->binding_count = 0; - for (i = 0; i < MAX_VERTEX_ATTRIBS; i++) - self->slots[i].addr = ~0; -} - -static GLvoid slang_attrib_bindings_dtr (slang_attrib_bindings *self) -{ - GLuint i; - - for (i = 0; i < self->binding_count; i++) - slang_alloc_free (self->bindings[i].name); -} - -static GLuint can_allocate_attrib_slots (slang_attrib_bindings *self, GLuint index, GLuint count) -{ - GLuint i; - - for (i = 0; i < count; i++) - if (self->slots[index + i].addr != ~0) - break; - return i; -} - -static GLuint allocate_attrib_slots (slang_attrib_bindings *self, GLuint count) -{ - GLuint i; - - for (i = 0; i <= MAX_VERTEX_ATTRIBS - count; i++) - { - GLuint size; - - size = can_allocate_attrib_slots (self, i, count); - if (size == count) - return i; - - /* speed-up the search a bit */ - i += count; - } - return MAX_VERTEX_ATTRIBS; -} - -static GLboolean add_attrib_binding (slang_attrib_bindings *self, slang_export_data_quant *q, - const char *name, GLuint addr, GLuint index_override) -{ - const GLuint n = self->binding_count; - GLuint slot_span, slot_index; - GLuint i; - - assert (slang_export_data_quant_simple (q)); - - switch (slang_export_data_quant_type (q)) - { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - slot_span = 1; - break; - case GL_FLOAT_MAT2: - slot_span = 2; - break; - case GL_FLOAT_MAT3: - slot_span = 3; - break; - case GL_FLOAT_MAT4: - slot_span = 4; - break; - default: - assert (0); - } - - if (index_override == MAX_VERTEX_ATTRIBS) - slot_index = allocate_attrib_slots (self, slot_span); - else if (can_allocate_attrib_slots (self, index_override, slot_span) == slot_span) - slot_index = index_override; - else - slot_index = MAX_VERTEX_ATTRIBS; - - if (slot_index == MAX_VERTEX_ATTRIBS) - { - /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */ - return GL_FALSE; - } - - self->bindings[n].quant = q; - self->bindings[n].name = slang_string_duplicate (name); - if (self->bindings[n].name == NULL) - return GL_FALSE; - self->bindings[n].first_slot_index = slot_index; - self->binding_count++; - - for (i = 0; i < slot_span; i++) - self->slots[self->bindings[n].first_slot_index + i].addr = addr + i * 4; - - return GL_TRUE; -} - -static GLboolean gather_attrib_bindings (slang_attrib_bindings *self, slang_export_data_table *tbl, - slang_attrib_overrides *ovr) -{ - GLuint i; - - /* First pass. Gather attribs that have overriden index slots. */ - for (i = 0; i < tbl->count; i++) - if (tbl->entries[i].access == slang_exp_attribute && - !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) - { - slang_export_data_quant *quant = &tbl->entries[i].quant; - const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name); - GLuint index = lookup_attrib_override (ovr, id); - - if (index != MAX_VERTEX_ATTRIBS) - { - if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index)) - return GL_FALSE; - } - } - - /* Second pass. Gather attribs that have *NOT* overriden index slots. */ - for (i = 0; i < tbl->count; i++) - if (tbl->entries[i].access == slang_exp_attribute && - !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) - { - slang_export_data_quant *quant = &tbl->entries[i].quant; - const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name); - GLuint index = lookup_attrib_override (ovr, id); - - if (index == MAX_VERTEX_ATTRIBS) - { - if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index)) - return GL_FALSE; - } - } - - return GL_TRUE; -} - -/* - * slang_varying_bindings - */ - -static GLvoid slang_varying_bindings_ctr (slang_varying_bindings *self) -{ - self->binding_count = 0; - self->slot_count = 0; -} - -static GLvoid slang_varying_bindings_dtr (slang_varying_bindings *self) -{ - GLuint i; - - for (i = 0; i < self->binding_count; i++) - slang_alloc_free (self->bindings[i].name); -} - -static GLvoid update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean is_vert, - GLuint addr, GLuint do_offset) -{ - GLuint i; - - for (i = 0; i < count; i++) - *(is_vert ? &slots[i].vert_addr : &slots[i].frag_addr) = addr + i * 4 * do_offset; -} - -static GLboolean add_varying_binding (slang_varying_bindings *self, - slang_export_data_quant *q, const char *name, GLboolean is_vert, GLuint addr) -{ - const GLuint n = self->binding_count; - const GLuint slot_span = - slang_export_data_quant_components (q) * slang_export_data_quant_elements (q); - GLuint i; - - for (i = 0; i < n; i++) - if (slang_string_compare (self->bindings[i].name, name) == 0) - { - /* TODO: data quantities must match, or else link fails */ - update_varying_slots (&self->slots[self->bindings[i].first_slot_index], slot_span, - is_vert, addr, 1); - return GL_TRUE; - } - - if (self->slot_count + slot_span > MAX_VARYING_FLOATS) - { - /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */ - return GL_FALSE; - } - - self->bindings[n].quant = q; - self->bindings[n].name = slang_string_duplicate (name); - if (self->bindings[n].name == NULL) - return GL_FALSE; - self->bindings[n].first_slot_index = self->slot_count; - self->binding_count++; - - update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, is_vert, - addr, 1); - update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, !is_vert, - ~0, 0); - self->slot_count += slot_span; - - return GL_TRUE; -} - -static GLboolean gather_varying_bindings (slang_varying_bindings *self, - slang_export_data_table *tbl, GLboolean is_vert) -{ - GLuint i; - - for (i = 0; i < tbl->count; i++) - if (tbl->entries[i].access == slang_exp_varying && - !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) - { - if (!add_varying_binding (self, &tbl->entries[i].quant, slang_atom_pool_id (tbl->atoms, - tbl->entries[i].quant.name), is_vert, tbl->entries[i].address)) - return GL_FALSE; - } - - return GL_TRUE; -} - -/* - * slang_texture_bindings - */ - -GLvoid slang_texture_usages_ctr (slang_texture_usages *self) -{ - self->table = NULL; - self->count = 0; -} - -GLvoid slang_texture_usages_dtr (slang_texture_usages *self) -{ - slang_alloc_free (self->table); -} - -/* - * slang_program - */ - -GLvoid slang_program_ctr (slang_program *self) -{ - GLuint i; - - slang_active_variables_ctr (&self->active_uniforms); - slang_active_variables_ctr (&self->active_attribs); - slang_attrib_overrides_ctr (&self->attrib_overrides); - slang_uniform_bindings_ctr (&self->uniforms); - slang_attrib_bindings_ctr (&self->attribs); - slang_varying_bindings_ctr (&self->varyings); - slang_texture_usages_ctr (&self->texture_usage); - for (i = 0; i < SLANG_SHADER_MAX; i++) - { - GLuint j; - - for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++) - self->common_fixed_entries[i][j] = ~0; - for (j = 0; j < SLANG_COMMON_CODE_MAX; j++) - self->code[i][j] = ~0; - self->machines[i] = NULL; - self->assemblies[i] = NULL; - } - for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++) - self->vertex_fixed_entries[i] = ~0; - for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++) - self->fragment_fixed_entries[i] = ~0; -} - -GLvoid slang_program_dtr (slang_program *self) -{ - slang_active_variables_dtr (&self->active_uniforms); - slang_active_variables_dtr (&self->active_attribs); - slang_attrib_overrides_dtr (&self->attrib_overrides); - slang_uniform_bindings_dtr (&self->uniforms); - slang_attrib_bindings_dtr (&self->attribs); - slang_varying_bindings_dtr (&self->varyings); - slang_texture_usages_dtr (&self->texture_usage); -} - -static GLvoid slang_program_rst (slang_program *self) -{ - GLuint i; - - slang_active_variables_dtr (&self->active_uniforms); - slang_active_variables_dtr (&self->active_attribs); - slang_uniform_bindings_dtr (&self->uniforms); - slang_attrib_bindings_dtr (&self->attribs); - slang_varying_bindings_dtr (&self->varyings); - slang_texture_usages_dtr (&self->texture_usage); - - slang_active_variables_ctr (&self->active_uniforms); - slang_active_variables_ctr (&self->active_attribs); - slang_uniform_bindings_ctr (&self->uniforms); - slang_attrib_bindings_ctr (&self->attribs); - slang_varying_bindings_ctr (&self->varyings); - slang_texture_usages_ctr (&self->texture_usage); - for (i = 0; i < SLANG_SHADER_MAX; i++) - { - GLuint j; - - for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++) - self->common_fixed_entries[i][j] = ~0; - for (j = 0; j < SLANG_COMMON_CODE_MAX; j++) - self->code[i][j] = ~0; - } - for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++) - self->vertex_fixed_entries[i] = ~0; - for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++) - self->fragment_fixed_entries[i] = ~0; -} - -/* - * _slang_link() - */ - -static GLuint gd (slang_export_data_table *tbl, const char *name) -{ - slang_atom atom; - GLuint i; - - atom = slang_atom_pool_atom (tbl->atoms, name); - if (atom == SLANG_ATOM_NULL) - return ~0; - - for (i = 0; i < tbl->count; i++) - if (atom == tbl->entries[i].quant.name) - return tbl->entries[i].address; - return ~0; -} - -static GLvoid resolve_common_fixed (GLuint e[], slang_export_data_table *tbl) -{ - e[SLANG_COMMON_FIXED_MODELVIEWMATRIX] = gd (tbl, "gl_ModelViewMatrix"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIX] = gd (tbl, "gl_ProjectionMatrix"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX] = gd (tbl, "gl_ModelViewProjectionMatrix"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIX] = gd (tbl, "gl_TextureMatrix"); - e[SLANG_COMMON_FIXED_NORMALMATRIX] = gd (tbl, "gl_NormalMatrix"); - e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE] = gd (tbl, "gl_ModelViewMatrixInverse"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE] = gd (tbl, "gl_ProjectionMatrixInverse"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE] = - gd (tbl, "gl_ModelViewProjectionMatrixInverse"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE] = gd (tbl, "gl_TextureMatrixInverse"); - e[SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE] = gd (tbl, "gl_ModelViewMatrixTranspose"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE] = gd (tbl, "gl_ProjectionMatrixTranspose"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE] = - gd (tbl, "gl_ModelViewProjectionMatrixTranspose"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE] = gd (tbl, "gl_TextureMatrixTranspose"); - e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE] = - gd (tbl, "gl_ModelViewMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE] = - gd (tbl, "gl_ProjectionMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE] = - gd (tbl, "gl_ModelViewProjectionMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE] = - gd (tbl, "gl_TextureMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_NORMALSCALE] = gd (tbl, "gl_NormalScale"); - e[SLANG_COMMON_FIXED_DEPTHRANGE] = gd (tbl, "gl_DepthRange"); - e[SLANG_COMMON_FIXED_CLIPPLANE] = gd (tbl, "gl_ClipPlane"); - e[SLANG_COMMON_FIXED_POINT] = gd (tbl, "gl_Point"); - e[SLANG_COMMON_FIXED_FRONTMATERIAL] = gd (tbl, "gl_FrontMaterial"); - e[SLANG_COMMON_FIXED_BACKMATERIAL] = gd (tbl, "gl_BackMaterial"); - e[SLANG_COMMON_FIXED_LIGHTSOURCE] = gd (tbl, "gl_LightSource"); - e[SLANG_COMMON_FIXED_LIGHTMODEL] = gd (tbl, "gl_LightModel"); - e[SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT] = gd (tbl, "gl_FrontLightModelProduct"); - e[SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT] = gd (tbl, "gl_BackLightModelProduct"); - e[SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT] = gd (tbl, "gl_FrontLightProduct"); - e[SLANG_COMMON_FIXED_BACKLIGHTPRODUCT] = gd (tbl, "gl_BackLightProduct"); - e[SLANG_COMMON_FIXED_TEXTUREENVCOLOR] = gd (tbl, "gl_TextureEnvColor"); - e[SLANG_COMMON_FIXED_EYEPLANES] = gd (tbl, "gl_EyePlaneS"); - e[SLANG_COMMON_FIXED_EYEPLANET] = gd (tbl, "gl_EyePlaneT"); - e[SLANG_COMMON_FIXED_EYEPLANER] = gd (tbl, "gl_EyePlaneR"); - e[SLANG_COMMON_FIXED_EYEPLANEQ] = gd (tbl, "gl_EyePlaneQ"); - e[SLANG_COMMON_FIXED_OBJECTPLANES] = gd (tbl, "gl_ObjectPlaneS"); - e[SLANG_COMMON_FIXED_OBJECTPLANET] = gd (tbl, "gl_ObjectPlaneT"); - e[SLANG_COMMON_FIXED_OBJECTPLANER] = gd (tbl, "gl_ObjectPlaneR"); - e[SLANG_COMMON_FIXED_OBJECTPLANEQ] = gd (tbl, "gl_ObjectPlaneQ"); - e[SLANG_COMMON_FIXED_FOG] = gd (tbl, "gl_Fog"); -} - -static GLvoid resolve_vertex_fixed (GLuint e[], slang_export_data_table *tbl) -{ - e[SLANG_VERTEX_FIXED_POSITION] = gd (tbl, "gl_Position"); - e[SLANG_VERTEX_FIXED_POINTSIZE] = gd (tbl, "gl_PointSize"); - e[SLANG_VERTEX_FIXED_CLIPVERTEX] = gd (tbl, "gl_ClipVertex"); - e[SLANG_VERTEX_FIXED_COLOR] = gd (tbl, "gl_Color"); - e[SLANG_VERTEX_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor"); - e[SLANG_VERTEX_FIXED_NORMAL] = gd (tbl, "gl_Normal"); - e[SLANG_VERTEX_FIXED_VERTEX] = gd (tbl, "gl_Vertex"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD0] = gd (tbl, "gl_MultiTexCoord0"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD1] = gd (tbl, "gl_MultiTexCoord1"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD2] = gd (tbl, "gl_MultiTexCoord2"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD3] = gd (tbl, "gl_MultiTexCoord3"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD4] = gd (tbl, "gl_MultiTexCoord4"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD5] = gd (tbl, "gl_MultiTexCoord5"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD6] = gd (tbl, "gl_MultiTexCoord6"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD7] = gd (tbl, "gl_MultiTexCoord7"); - e[SLANG_VERTEX_FIXED_FOGCOORD] = gd (tbl, "gl_FogCoord"); - e[SLANG_VERTEX_FIXED_FRONTCOLOR] = gd (tbl, "gl_FrontColor"); - e[SLANG_VERTEX_FIXED_BACKCOLOR] = gd (tbl, "gl_BackColor"); - e[SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR] = gd (tbl, "gl_FrontSecondaryColor"); - e[SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR] = gd (tbl, "gl_BackSecondaryColor"); - e[SLANG_VERTEX_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord"); - e[SLANG_VERTEX_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord"); -} - -static GLvoid resolve_fragment_fixed (GLuint e[], slang_export_data_table *tbl) -{ - e[SLANG_FRAGMENT_FIXED_FRAGCOORD] = gd (tbl, "gl_FragCoord"); - e[SLANG_FRAGMENT_FIXED_FRONTFACING] = gd (tbl, "gl_FrontFacing"); - e[SLANG_FRAGMENT_FIXED_FRAGCOLOR] = gd (tbl, "gl_FragColor"); - e[SLANG_FRAGMENT_FIXED_FRAGDATA] = gd (tbl, "gl_FragData"); - e[SLANG_FRAGMENT_FIXED_FRAGDEPTH] = gd (tbl, "gl_FragDepth"); - e[SLANG_FRAGMENT_FIXED_COLOR] = gd (tbl, "gl_Color"); - e[SLANG_FRAGMENT_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor"); - e[SLANG_FRAGMENT_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord"); - e[SLANG_FRAGMENT_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord"); -} - -static GLuint gc (slang_export_code_table *tbl, const char *name) -{ - slang_atom atom; - GLuint i; - - atom = slang_atom_pool_atom (tbl->atoms, name); - if (atom == SLANG_ATOM_NULL) - return ~0; - - for (i = 0; i < tbl->count; i++) - if (atom == tbl->entries[i].name) - return tbl->entries[i].address; - return ~0; -} - -static GLvoid resolve_common_code (GLuint code[], slang_export_code_table *tbl) -{ - code[SLANG_COMMON_CODE_MAIN] = gc (tbl, "@main"); -} - -GLboolean _slang_link (slang_program *prog, slang_translation_unit **units, GLuint count) -{ - GLuint i; - - slang_program_rst (prog); - - for (i = 0; i < count; i++) - { - GLuint index; - - if (units[i]->type == slang_unit_fragment_shader) - { - index = SLANG_SHADER_FRAGMENT; - resolve_fragment_fixed (prog->fragment_fixed_entries, &units[i]->exp_data); - } - else - { - index = SLANG_SHADER_VERTEX; - resolve_vertex_fixed (prog->vertex_fixed_entries, &units[i]->exp_data); - if (!gather_attrib_bindings (&prog->attribs, &units[i]->exp_data, - &prog->attrib_overrides)) - return GL_FALSE; - } - - if (!gather_active_variables (&prog->active_uniforms, &units[i]->exp_data, - slang_exp_uniform)) - return GL_FALSE; - if (!gather_active_variables (&prog->active_attribs, &units[i]->exp_data, - slang_exp_attribute)) - return GL_FALSE; - if (!gather_uniform_bindings (&prog->uniforms, &units[i]->exp_data, index)) - return GL_FALSE; - if (!gather_varying_bindings (&prog->varyings, &units[i]->exp_data, - index == SLANG_SHADER_VERTEX)) - return GL_FALSE; - resolve_common_fixed (prog->common_fixed_entries[index], &units[i]->exp_data); - resolve_common_code (prog->code[index], &units[i]->exp_code); - prog->machines[index] = units[i]->machine; - prog->assemblies[index] = units[i]->assembly; - } - - /* TODO: all varyings read by fragment shader must be written by vertex shader */ - - if (!_slang_analyse_texture_usage (prog)) - return GL_FALSE; - - return GL_TRUE; -} - +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_link.c + * slang linker + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_link.h" +#include "slang_analyse.h" + +static GLboolean entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms) +{ + const char *str = slang_atom_pool_id (atoms, name); + return str[0] == 'g' && str[1] == 'l' && str[2] == '_'; +} + +/* + * slang_active_variables + */ + +static GLvoid slang_active_variables_ctr (slang_active_variables *self) +{ + self->table = NULL; + self->count = 0; +} + +static GLvoid slang_active_variables_dtr (slang_active_variables *self) +{ + GLuint i; + + for (i = 0; i < self->count; i++) + slang_alloc_free (self->table[i].name); + slang_alloc_free (self->table); +} + +static GLboolean add_simple_variable (slang_active_variables *self, slang_export_data_quant *q, + const char *name) +{ + const GLuint n = self->count; + + self->table = (slang_active_variable *) slang_alloc_realloc (self->table, + n * sizeof (slang_active_variable), (n + 1) * sizeof (slang_active_variable)); + if (self->table == NULL) + return GL_FALSE; + + self->table[n].quant = q; + self->table[n].name = slang_string_duplicate (name); + if (self->table[n].name == NULL) + return GL_FALSE; + self->count++; + + return GL_TRUE; +} + +static GLboolean add_complex_variable (slang_active_variables *self, slang_export_data_quant *q, + char *name, slang_atom_pool *atoms) +{ + slang_string_concat (name, slang_atom_pool_id (atoms, q->name)); + if (slang_export_data_quant_array (q)) + slang_string_concat (name, "[0]"); + + if (slang_export_data_quant_struct (q)) + { + GLuint dot_pos, i; + const GLuint fields = slang_export_data_quant_fields (q); + + slang_string_concat (name, "."); + dot_pos = slang_string_length (name); + + for (i = 0; i < fields; i++) + { + if (!add_complex_variable (self, &q->structure[i], name, atoms)) + return GL_FALSE; + + name[dot_pos] = '\0'; + } + + return GL_TRUE; + } + + return add_simple_variable (self, q, name); +} + +static GLboolean gather_active_variables (slang_active_variables *self, + slang_export_data_table *tbl, slang_export_data_access access) +{ + GLuint i; + + for (i = 0; i < tbl->count; i++) + if (tbl->entries[i].access == access) + { + char name[1024] = ""; + + if (!add_complex_variable (self, &tbl->entries[i].quant, name, tbl->atoms)) + return GL_FALSE; + } + + return GL_TRUE; +} + +/* + * slang_attrib_overrides + */ + +static GLvoid slang_attrib_overrides_ctr (slang_attrib_overrides *self) +{ + self->table = NULL; + self->count = 0; +} + +static GLvoid slang_attrib_overrides_dtr (slang_attrib_overrides *self) +{ + GLuint i; + + for (i = 0; i < self->count; i++) + slang_alloc_free (self->table[i].name); + slang_alloc_free (self->table); +} + +GLboolean slang_attrib_overrides_add (slang_attrib_overrides *self, GLuint index, const GLchar *name) +{ + const GLuint n = self->count; + GLuint i; + + for (i = 0; i < n; i++) + if (slang_string_compare (name, self->table[i].name) == 0) + { + self->table[i].index = index; + return GL_TRUE; + } + + self->table = (slang_attrib_override *) slang_alloc_realloc (self->table, + n * sizeof (slang_attrib_override), (n + 1) * sizeof (slang_attrib_override)); + if (self->table == NULL) + return GL_FALSE; + + self->table[n].index = index; + self->table[n].name = slang_string_duplicate (name); + if (self->table[n].name == NULL) + return GL_FALSE; + self->count++; + + return GL_TRUE; +} + +static GLuint lookup_attrib_override (slang_attrib_overrides *self, const GLchar *name) +{ + GLuint i; + + for (i = 0; self->count; i++) + if (slang_string_compare (name, self->table[i].name) == 0) + return self->table[i].index; + return MAX_VERTEX_ATTRIBS; +} + +/* + * slang_uniform_bindings + */ + +static GLvoid slang_uniform_bindings_ctr (slang_uniform_bindings *self) +{ + self->table = NULL; + self->count = 0; +} + +static GLvoid slang_uniform_bindings_dtr (slang_uniform_bindings *self) +{ + GLuint i; + + for (i = 0; i < self->count; i++) + slang_alloc_free (self->table[i].name); + slang_alloc_free (self->table); +} + +static GLboolean add_simple_uniform_binding (slang_uniform_bindings *self, + slang_export_data_quant *q, const char *name, GLuint index, GLuint addr) +{ + const GLuint n = self->count; + GLuint i; + + for (i = 0; i < n; i++) + if (slang_string_compare (self->table[i].name, name) == 0) + { + self->table[i].address[index] = addr; + return GL_TRUE; + } + + self->table = (slang_uniform_binding *) slang_alloc_realloc (self->table, + n * sizeof (slang_uniform_binding), (n + 1) * sizeof (slang_uniform_binding)); + if (self->table == NULL) + return GL_FALSE; + + self->table[n].quant = q; + self->table[n].name = slang_string_duplicate (name); + if (self->table[n].name == NULL) + return GL_FALSE; + for (i = 0; i < SLANG_SHADER_MAX; i++) + self->table[n].address[i] = ~0; + self->table[n].address[index] = addr; + self->count++; + + return GL_TRUE; +} + +static GLboolean add_complex_uniform_binding (slang_uniform_bindings *self, + slang_export_data_quant *q, char *name, slang_atom_pool *atoms, GLuint index, GLuint addr) +{ + GLuint count, i; + + slang_string_concat (name, slang_atom_pool_id (atoms, q->name)); + count = slang_export_data_quant_elements (q); + for (i = 0; i < count; i++) + { + GLuint bracket_pos; + + bracket_pos = slang_string_length (name); + if (slang_export_data_quant_array (q)) + _mesa_sprintf (name + slang_string_length (name), "[%d]", i); + + if (slang_export_data_quant_struct (q)) + { + GLuint dot_pos, i; + const GLuint fields = slang_export_data_quant_fields (q); + + slang_string_concat (name, "."); + dot_pos = slang_string_length (name); + + for (i = 0; i < fields; i++) + { + if (!add_complex_uniform_binding (self, &q->structure[i], name, atoms, index, addr)) + return GL_FALSE; + + name[dot_pos] = '\0'; + addr += slang_export_data_quant_size (&q->structure[i]); + } + } + else + { + if (!add_simple_uniform_binding (self, q, name, index, addr)) + return GL_FALSE; + + addr += slang_export_data_quant_size (q); + } + + name[bracket_pos] = '\0'; + } + + return GL_TRUE; +} + +static GLboolean gather_uniform_bindings (slang_uniform_bindings *self, + slang_export_data_table *tbl, GLuint index) +{ + GLuint i; + + for (i = 0; i < tbl->count; i++) + if (tbl->entries[i].access == slang_exp_uniform) + { + char name[1024] = ""; + + if (!add_complex_uniform_binding (self, &tbl->entries[i].quant, name, tbl->atoms, index, + tbl->entries[i].address)) + return GL_FALSE; + } + + return GL_TRUE; +} + +/* + * slang_attrib_bindings + */ + +static GLvoid slang_attrib_bindings_ctr (slang_attrib_bindings *self) +{ + GLuint i; + + self->binding_count = 0; + for (i = 0; i < MAX_VERTEX_ATTRIBS; i++) + self->slots[i].addr = ~0; +} + +static GLvoid slang_attrib_bindings_dtr (slang_attrib_bindings *self) +{ + GLuint i; + + for (i = 0; i < self->binding_count; i++) + slang_alloc_free (self->bindings[i].name); +} + +static GLuint can_allocate_attrib_slots (slang_attrib_bindings *self, GLuint index, GLuint count) +{ + GLuint i; + + for (i = 0; i < count; i++) + if (self->slots[index + i].addr != ~0) + break; + return i; +} + +static GLuint allocate_attrib_slots (slang_attrib_bindings *self, GLuint count) +{ + GLuint i; + + for (i = 0; i <= MAX_VERTEX_ATTRIBS - count; i++) + { + GLuint size; + + size = can_allocate_attrib_slots (self, i, count); + if (size == count) + return i; + + /* speed-up the search a bit */ + i += count; + } + return MAX_VERTEX_ATTRIBS; +} + +static GLboolean add_attrib_binding (slang_attrib_bindings *self, slang_export_data_quant *q, + const char *name, GLuint addr, GLuint index_override) +{ + const GLuint n = self->binding_count; + GLuint slot_span, slot_index; + GLuint i; + + assert (slang_export_data_quant_simple (q)); + + switch (slang_export_data_quant_type (q)) + { + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + slot_span = 1; + break; + case GL_FLOAT_MAT2: + slot_span = 2; + break; + case GL_FLOAT_MAT3: + slot_span = 3; + break; + case GL_FLOAT_MAT4: + slot_span = 4; + break; + default: + assert (0); + } + + if (index_override == MAX_VERTEX_ATTRIBS) + slot_index = allocate_attrib_slots (self, slot_span); + else if (can_allocate_attrib_slots (self, index_override, slot_span) == slot_span) + slot_index = index_override; + else + slot_index = MAX_VERTEX_ATTRIBS; + + if (slot_index == MAX_VERTEX_ATTRIBS) + { + /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */ + return GL_FALSE; + } + + self->bindings[n].quant = q; + self->bindings[n].name = slang_string_duplicate (name); + if (self->bindings[n].name == NULL) + return GL_FALSE; + self->bindings[n].first_slot_index = slot_index; + self->binding_count++; + + for (i = 0; i < slot_span; i++) + self->slots[self->bindings[n].first_slot_index + i].addr = addr + i * 4; + + return GL_TRUE; +} + +static GLboolean gather_attrib_bindings (slang_attrib_bindings *self, slang_export_data_table *tbl, + slang_attrib_overrides *ovr) +{ + GLuint i; + + /* First pass. Gather attribs that have overriden index slots. */ + for (i = 0; i < tbl->count; i++) + if (tbl->entries[i].access == slang_exp_attribute && + !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) + { + slang_export_data_quant *quant = &tbl->entries[i].quant; + const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name); + GLuint index = lookup_attrib_override (ovr, id); + + if (index != MAX_VERTEX_ATTRIBS) + { + if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index)) + return GL_FALSE; + } + } + + /* Second pass. Gather attribs that have *NOT* overriden index slots. */ + for (i = 0; i < tbl->count; i++) + if (tbl->entries[i].access == slang_exp_attribute && + !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) + { + slang_export_data_quant *quant = &tbl->entries[i].quant; + const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name); + GLuint index = lookup_attrib_override (ovr, id); + + if (index == MAX_VERTEX_ATTRIBS) + { + if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +/* + * slang_varying_bindings + */ + +static GLvoid slang_varying_bindings_ctr (slang_varying_bindings *self) +{ + self->binding_count = 0; + self->slot_count = 0; +} + +static GLvoid slang_varying_bindings_dtr (slang_varying_bindings *self) +{ + GLuint i; + + for (i = 0; i < self->binding_count; i++) + slang_alloc_free (self->bindings[i].name); +} + +static GLvoid update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean is_vert, + GLuint addr, GLuint do_offset) +{ + GLuint i; + + for (i = 0; i < count; i++) + *(is_vert ? &slots[i].vert_addr : &slots[i].frag_addr) = addr + i * 4 * do_offset; +} + +static GLboolean add_varying_binding (slang_varying_bindings *self, + slang_export_data_quant *q, const char *name, GLboolean is_vert, GLuint addr) +{ + const GLuint n = self->binding_count; + const GLuint slot_span = + slang_export_data_quant_components (q) * slang_export_data_quant_elements (q); + GLuint i; + + for (i = 0; i < n; i++) + if (slang_string_compare (self->bindings[i].name, name) == 0) + { + /* TODO: data quantities must match, or else link fails */ + update_varying_slots (&self->slots[self->bindings[i].first_slot_index], slot_span, + is_vert, addr, 1); + return GL_TRUE; + } + + if (self->slot_count + slot_span > MAX_VARYING_FLOATS) + { + /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */ + return GL_FALSE; + } + + self->bindings[n].quant = q; + self->bindings[n].name = slang_string_duplicate (name); + if (self->bindings[n].name == NULL) + return GL_FALSE; + self->bindings[n].first_slot_index = self->slot_count; + self->binding_count++; + + update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, is_vert, + addr, 1); + update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, !is_vert, + ~0, 0); + self->slot_count += slot_span; + + return GL_TRUE; +} + +static GLboolean gather_varying_bindings (slang_varying_bindings *self, + slang_export_data_table *tbl, GLboolean is_vert) +{ + GLuint i; + + for (i = 0; i < tbl->count; i++) + if (tbl->entries[i].access == slang_exp_varying && + !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) + { + if (!add_varying_binding (self, &tbl->entries[i].quant, slang_atom_pool_id (tbl->atoms, + tbl->entries[i].quant.name), is_vert, tbl->entries[i].address)) + return GL_FALSE; + } + + return GL_TRUE; +} + +/* + * slang_texture_bindings + */ + +GLvoid slang_texture_usages_ctr (slang_texture_usages *self) +{ + self->table = NULL; + self->count = 0; +} + +GLvoid slang_texture_usages_dtr (slang_texture_usages *self) +{ + slang_alloc_free (self->table); +} + +/* + * slang_program + */ + +GLvoid slang_program_ctr (slang_program *self) +{ + GLuint i; + + slang_active_variables_ctr (&self->active_uniforms); + slang_active_variables_ctr (&self->active_attribs); + slang_attrib_overrides_ctr (&self->attrib_overrides); + slang_uniform_bindings_ctr (&self->uniforms); + slang_attrib_bindings_ctr (&self->attribs); + slang_varying_bindings_ctr (&self->varyings); + slang_texture_usages_ctr (&self->texture_usage); + for (i = 0; i < SLANG_SHADER_MAX; i++) + { + GLuint j; + + for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++) + self->common_fixed_entries[i][j] = ~0; + for (j = 0; j < SLANG_COMMON_CODE_MAX; j++) + self->code[i][j] = ~0; + self->machines[i] = NULL; + self->assemblies[i] = NULL; + } + for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++) + self->vertex_fixed_entries[i] = ~0; + for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++) + self->fragment_fixed_entries[i] = ~0; +} + +GLvoid slang_program_dtr (slang_program *self) +{ + slang_active_variables_dtr (&self->active_uniforms); + slang_active_variables_dtr (&self->active_attribs); + slang_attrib_overrides_dtr (&self->attrib_overrides); + slang_uniform_bindings_dtr (&self->uniforms); + slang_attrib_bindings_dtr (&self->attribs); + slang_varying_bindings_dtr (&self->varyings); + slang_texture_usages_dtr (&self->texture_usage); +} + +static GLvoid slang_program_rst (slang_program *self) +{ + GLuint i; + + slang_active_variables_dtr (&self->active_uniforms); + slang_active_variables_dtr (&self->active_attribs); + slang_uniform_bindings_dtr (&self->uniforms); + slang_attrib_bindings_dtr (&self->attribs); + slang_varying_bindings_dtr (&self->varyings); + slang_texture_usages_dtr (&self->texture_usage); + + slang_active_variables_ctr (&self->active_uniforms); + slang_active_variables_ctr (&self->active_attribs); + slang_uniform_bindings_ctr (&self->uniforms); + slang_attrib_bindings_ctr (&self->attribs); + slang_varying_bindings_ctr (&self->varyings); + slang_texture_usages_ctr (&self->texture_usage); + for (i = 0; i < SLANG_SHADER_MAX; i++) + { + GLuint j; + + for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++) + self->common_fixed_entries[i][j] = ~0; + for (j = 0; j < SLANG_COMMON_CODE_MAX; j++) + self->code[i][j] = ~0; + } + for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++) + self->vertex_fixed_entries[i] = ~0; + for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++) + self->fragment_fixed_entries[i] = ~0; +} + +/* + * _slang_link() + */ + +static GLuint gd (slang_export_data_table *tbl, const char *name) +{ + slang_atom atom; + GLuint i; + + atom = slang_atom_pool_atom (tbl->atoms, name); + if (atom == SLANG_ATOM_NULL) + return ~0; + + for (i = 0; i < tbl->count; i++) + if (atom == tbl->entries[i].quant.name) + return tbl->entries[i].address; + return ~0; +} + +static GLvoid resolve_common_fixed (GLuint e[], slang_export_data_table *tbl) +{ + e[SLANG_COMMON_FIXED_MODELVIEWMATRIX] = gd (tbl, "gl_ModelViewMatrix"); + e[SLANG_COMMON_FIXED_PROJECTIONMATRIX] = gd (tbl, "gl_ProjectionMatrix"); + e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX] = gd (tbl, "gl_ModelViewProjectionMatrix"); + e[SLANG_COMMON_FIXED_TEXTUREMATRIX] = gd (tbl, "gl_TextureMatrix"); + e[SLANG_COMMON_FIXED_NORMALMATRIX] = gd (tbl, "gl_NormalMatrix"); + e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE] = gd (tbl, "gl_ModelViewMatrixInverse"); + e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE] = gd (tbl, "gl_ProjectionMatrixInverse"); + e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE] = + gd (tbl, "gl_ModelViewProjectionMatrixInverse"); + e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE] = gd (tbl, "gl_TextureMatrixInverse"); + e[SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE] = gd (tbl, "gl_ModelViewMatrixTranspose"); + e[SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE] = gd (tbl, "gl_ProjectionMatrixTranspose"); + e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE] = + gd (tbl, "gl_ModelViewProjectionMatrixTranspose"); + e[SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE] = gd (tbl, "gl_TextureMatrixTranspose"); + e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE] = + gd (tbl, "gl_ModelViewMatrixInverseTranspose"); + e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE] = + gd (tbl, "gl_ProjectionMatrixInverseTranspose"); + e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE] = + gd (tbl, "gl_ModelViewProjectionMatrixInverseTranspose"); + e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE] = + gd (tbl, "gl_TextureMatrixInverseTranspose"); + e[SLANG_COMMON_FIXED_NORMALSCALE] = gd (tbl, "gl_NormalScale"); + e[SLANG_COMMON_FIXED_DEPTHRANGE] = gd (tbl, "gl_DepthRange"); + e[SLANG_COMMON_FIXED_CLIPPLANE] = gd (tbl, "gl_ClipPlane"); + e[SLANG_COMMON_FIXED_POINT] = gd (tbl, "gl_Point"); + e[SLANG_COMMON_FIXED_FRONTMATERIAL] = gd (tbl, "gl_FrontMaterial"); + e[SLANG_COMMON_FIXED_BACKMATERIAL] = gd (tbl, "gl_BackMaterial"); + e[SLANG_COMMON_FIXED_LIGHTSOURCE] = gd (tbl, "gl_LightSource"); + e[SLANG_COMMON_FIXED_LIGHTMODEL] = gd (tbl, "gl_LightModel"); + e[SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT] = gd (tbl, "gl_FrontLightModelProduct"); + e[SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT] = gd (tbl, "gl_BackLightModelProduct"); + e[SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT] = gd (tbl, "gl_FrontLightProduct"); + e[SLANG_COMMON_FIXED_BACKLIGHTPRODUCT] = gd (tbl, "gl_BackLightProduct"); + e[SLANG_COMMON_FIXED_TEXTUREENVCOLOR] = gd (tbl, "gl_TextureEnvColor"); + e[SLANG_COMMON_FIXED_EYEPLANES] = gd (tbl, "gl_EyePlaneS"); + e[SLANG_COMMON_FIXED_EYEPLANET] = gd (tbl, "gl_EyePlaneT"); + e[SLANG_COMMON_FIXED_EYEPLANER] = gd (tbl, "gl_EyePlaneR"); + e[SLANG_COMMON_FIXED_EYEPLANEQ] = gd (tbl, "gl_EyePlaneQ"); + e[SLANG_COMMON_FIXED_OBJECTPLANES] = gd (tbl, "gl_ObjectPlaneS"); + e[SLANG_COMMON_FIXED_OBJECTPLANET] = gd (tbl, "gl_ObjectPlaneT"); + e[SLANG_COMMON_FIXED_OBJECTPLANER] = gd (tbl, "gl_ObjectPlaneR"); + e[SLANG_COMMON_FIXED_OBJECTPLANEQ] = gd (tbl, "gl_ObjectPlaneQ"); + e[SLANG_COMMON_FIXED_FOG] = gd (tbl, "gl_Fog"); +} + +static GLvoid resolve_vertex_fixed (GLuint e[], slang_export_data_table *tbl) +{ + e[SLANG_VERTEX_FIXED_POSITION] = gd (tbl, "gl_Position"); + e[SLANG_VERTEX_FIXED_POINTSIZE] = gd (tbl, "gl_PointSize"); + e[SLANG_VERTEX_FIXED_CLIPVERTEX] = gd (tbl, "gl_ClipVertex"); + e[SLANG_VERTEX_FIXED_COLOR] = gd (tbl, "gl_Color"); + e[SLANG_VERTEX_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor"); + e[SLANG_VERTEX_FIXED_NORMAL] = gd (tbl, "gl_Normal"); + e[SLANG_VERTEX_FIXED_VERTEX] = gd (tbl, "gl_Vertex"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD0] = gd (tbl, "gl_MultiTexCoord0"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD1] = gd (tbl, "gl_MultiTexCoord1"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD2] = gd (tbl, "gl_MultiTexCoord2"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD3] = gd (tbl, "gl_MultiTexCoord3"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD4] = gd (tbl, "gl_MultiTexCoord4"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD5] = gd (tbl, "gl_MultiTexCoord5"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD6] = gd (tbl, "gl_MultiTexCoord6"); + e[SLANG_VERTEX_FIXED_MULTITEXCOORD7] = gd (tbl, "gl_MultiTexCoord7"); + e[SLANG_VERTEX_FIXED_FOGCOORD] = gd (tbl, "gl_FogCoord"); + e[SLANG_VERTEX_FIXED_FRONTCOLOR] = gd (tbl, "gl_FrontColor"); + e[SLANG_VERTEX_FIXED_BACKCOLOR] = gd (tbl, "gl_BackColor"); + e[SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR] = gd (tbl, "gl_FrontSecondaryColor"); + e[SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR] = gd (tbl, "gl_BackSecondaryColor"); + e[SLANG_VERTEX_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord"); + e[SLANG_VERTEX_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord"); +} + +static GLvoid resolve_fragment_fixed (GLuint e[], slang_export_data_table *tbl) +{ + e[SLANG_FRAGMENT_FIXED_FRAGCOORD] = gd (tbl, "gl_FragCoord"); + e[SLANG_FRAGMENT_FIXED_FRONTFACING] = gd (tbl, "gl_FrontFacing"); + e[SLANG_FRAGMENT_FIXED_FRAGCOLOR] = gd (tbl, "gl_FragColor"); + e[SLANG_FRAGMENT_FIXED_FRAGDATA] = gd (tbl, "gl_FragData"); + e[SLANG_FRAGMENT_FIXED_FRAGDEPTH] = gd (tbl, "gl_FragDepth"); + e[SLANG_FRAGMENT_FIXED_COLOR] = gd (tbl, "gl_Color"); + e[SLANG_FRAGMENT_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor"); + e[SLANG_FRAGMENT_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord"); + e[SLANG_FRAGMENT_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord"); +} + +static GLuint gc (slang_export_code_table *tbl, const char *name) +{ + slang_atom atom; + GLuint i; + + atom = slang_atom_pool_atom (tbl->atoms, name); + if (atom == SLANG_ATOM_NULL) + return ~0; + + for (i = 0; i < tbl->count; i++) + if (atom == tbl->entries[i].name) + return tbl->entries[i].address; + return ~0; +} + +static GLvoid resolve_common_code (GLuint code[], slang_export_code_table *tbl) +{ + code[SLANG_COMMON_CODE_MAIN] = gc (tbl, "@main"); +} + +GLboolean _slang_link (slang_program *prog, slang_translation_unit **units, GLuint count) +{ + GLuint i; + + slang_program_rst (prog); + + for (i = 0; i < count; i++) + { + GLuint index; + + if (units[i]->type == slang_unit_fragment_shader) + { + index = SLANG_SHADER_FRAGMENT; + resolve_fragment_fixed (prog->fragment_fixed_entries, &units[i]->exp_data); + } + else + { + index = SLANG_SHADER_VERTEX; + resolve_vertex_fixed (prog->vertex_fixed_entries, &units[i]->exp_data); + if (!gather_attrib_bindings (&prog->attribs, &units[i]->exp_data, + &prog->attrib_overrides)) + return GL_FALSE; + } + + if (!gather_active_variables (&prog->active_uniforms, &units[i]->exp_data, + slang_exp_uniform)) + return GL_FALSE; + if (!gather_active_variables (&prog->active_attribs, &units[i]->exp_data, + slang_exp_attribute)) + return GL_FALSE; + if (!gather_uniform_bindings (&prog->uniforms, &units[i]->exp_data, index)) + return GL_FALSE; + if (!gather_varying_bindings (&prog->varyings, &units[i]->exp_data, + index == SLANG_SHADER_VERTEX)) + return GL_FALSE; + resolve_common_fixed (prog->common_fixed_entries[index], &units[i]->exp_data); + resolve_common_code (prog->code[index], &units[i]->exp_code); + prog->machines[index] = units[i]->machine; + prog->assemblies[index] = units[i]->assembly; + } + + /* TODO: all varyings read by fragment shader must be written by vertex shader */ + + if (!_slang_analyse_texture_usage (prog)) + return GL_FALSE; + + return GL_TRUE; +} + diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 6f63a9d31dd..c5691300866 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -1,313 +1,313 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#if !defined SLANG_LINK_H -#define SLANG_LINK_H - -#include "slang_compile.h" - -#if defined __cplusplus -extern "C" { -#endif - -enum -{ - SLANG_SHADER_VERTEX, - SLANG_SHADER_FRAGMENT, - SLANG_SHADER_MAX -}; - -/* Active variables. - * - * Active uniforms or attribs can be queried by the application to get a list of uniforms - * or attribs actually used by shaders (uniforms) or vertex shader (attribs). - */ - -typedef struct -{ - slang_export_data_quant *quant; - char *name; -} slang_active_variable; - -typedef struct -{ - slang_active_variable *table; - GLuint count; -} slang_active_variables; - -/* - * Attrib binding override. - * - * The application can override GL attrib binding by specifying its preferred index assignment - * for a given attrib name. Those overrides are taken into account while linking the program. - */ - -typedef struct -{ - GLuint index; - GLchar *name; -} slang_attrib_override; - -typedef struct -{ - slang_attrib_override *table; - GLuint count; -} slang_attrib_overrides; - -GLboolean slang_attrib_overrides_add (slang_attrib_overrides *, GLuint, const GLchar *); - -/* - * Uniform bindings. - * - * Each slang_uniform_binding holds an array of addresses to actual memory locations in those - * shader types that use that uniform. Uniform bindings are held in an array and accessed - * by array index which is seen to the application as a uniform location. - * - * When the application writes to a particular uniform, it specifies its location. - * This location is treated as an array index to slang_uniform_bindings::table and tested - * against slang_uniform_bindings::count limit. The result is a pointer to slang_uniform_binding. - * The type of data being written to uniform is tested against slang_uniform_binding::quant. - * If the types are compatible, the array slang_uniform_binding::address is iterated for - * each shader type and if the address is valid (i.e. the uniform is used by this shader type), - * the new uniform value is written at that address. - */ - -typedef struct -{ - slang_export_data_quant *quant; - char *name; - GLuint address[SLANG_SHADER_MAX]; -} slang_uniform_binding; - -typedef struct -{ - slang_uniform_binding *table; - GLuint count; -} slang_uniform_bindings; - -/* - * Attrib bindings. - * - * There is a fixed number of vertex attrib vectors (attrib slots). The slang_attrib_slot::addr - * maps vertex attrib index to the actual memory location of the attrib in vertex shader. - * One vertex attrib can span over many attrib slots (this is the case for matrices). The - * slang_attrib_binding::first_slot_index holds the first slot index that the attrib is bound to. - */ - -typedef struct -{ - slang_export_data_quant *quant; - char *name; - GLuint first_slot_index; -} slang_attrib_binding; - -typedef struct -{ - GLuint addr; -} slang_attrib_slot; - -typedef struct -{ - slang_attrib_binding bindings[MAX_VERTEX_ATTRIBS]; - GLuint binding_count; - slang_attrib_slot slots[MAX_VERTEX_ATTRIBS]; -} slang_attrib_bindings; - -/* - * Varying bindings. - * - * There is a fixed number of varying floats (varying slots). The slang_varying_slot::vert_addr - * maps varying float index to the actual memory location of the output variable in vertex shader. - * The slang_varying_slot::frag_addr maps varying float index to the actual memory location of - * the input variable in fragment shader. - */ - -typedef struct -{ - GLuint vert_addr; - GLuint frag_addr; -} slang_varying_slot; - -typedef struct -{ - slang_export_data_quant *quant; - char *name; - GLuint first_slot_index; -} slang_varying_binding; - -typedef struct -{ - slang_varying_binding bindings[MAX_VARYING_FLOATS]; - GLuint binding_count; - slang_varying_slot slots[MAX_VARYING_FLOATS]; - GLuint slot_count; -} slang_varying_bindings; - -/* - * Texture usage. - * - * A slang_texture_usage struct holds indirect information about texture image unit usage. The - * slang_texture_usages::table is derived from active uniform table by extracting only uniforms - * that are samplers. - * - * To collect current texture usage one must iterate the slang_texture_usages::table and read - * uniform at address slang_texture_usage::frag_address to get texture unit index. This - * index, coupled with texture access type (target) taken from slang_texture_usage::quant - * forms texture usage for that texture unit. - */ - -typedef struct -{ - slang_export_data_quant *quant; - GLuint frag_address; -} slang_texture_usage; - -typedef struct -{ - slang_texture_usage *table; - GLuint count; -} slang_texture_usages; - -GLvoid slang_texture_usages_ctr (slang_texture_usages *); -GLvoid slang_texture_usages_dtr (slang_texture_usages *); - -enum -{ - SLANG_COMMON_FIXED_MODELVIEWMATRIX, - SLANG_COMMON_FIXED_PROJECTIONMATRIX, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX, - SLANG_COMMON_FIXED_TEXTUREMATRIX, - SLANG_COMMON_FIXED_NORMALMATRIX, - SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE, - SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_NORMALSCALE, - SLANG_COMMON_FIXED_DEPTHRANGE, - SLANG_COMMON_FIXED_CLIPPLANE, - SLANG_COMMON_FIXED_POINT, - SLANG_COMMON_FIXED_FRONTMATERIAL, - SLANG_COMMON_FIXED_BACKMATERIAL, - SLANG_COMMON_FIXED_LIGHTSOURCE, - SLANG_COMMON_FIXED_LIGHTMODEL, - SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT, - SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT, - SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT, - SLANG_COMMON_FIXED_BACKLIGHTPRODUCT, - SLANG_COMMON_FIXED_TEXTUREENVCOLOR, - SLANG_COMMON_FIXED_EYEPLANES, - SLANG_COMMON_FIXED_EYEPLANET, - SLANG_COMMON_FIXED_EYEPLANER, - SLANG_COMMON_FIXED_EYEPLANEQ, - SLANG_COMMON_FIXED_OBJECTPLANES, - SLANG_COMMON_FIXED_OBJECTPLANET, - SLANG_COMMON_FIXED_OBJECTPLANER, - SLANG_COMMON_FIXED_OBJECTPLANEQ, - SLANG_COMMON_FIXED_FOG, - SLANG_COMMON_FIXED_MAX -}; - -enum -{ - SLANG_VERTEX_FIXED_POSITION, - SLANG_VERTEX_FIXED_POINTSIZE, - SLANG_VERTEX_FIXED_CLIPVERTEX, - SLANG_VERTEX_FIXED_COLOR, - SLANG_VERTEX_FIXED_SECONDARYCOLOR, - SLANG_VERTEX_FIXED_NORMAL, - SLANG_VERTEX_FIXED_VERTEX, - SLANG_VERTEX_FIXED_MULTITEXCOORD0, - SLANG_VERTEX_FIXED_MULTITEXCOORD1, - SLANG_VERTEX_FIXED_MULTITEXCOORD2, - SLANG_VERTEX_FIXED_MULTITEXCOORD3, - SLANG_VERTEX_FIXED_MULTITEXCOORD4, - SLANG_VERTEX_FIXED_MULTITEXCOORD5, - SLANG_VERTEX_FIXED_MULTITEXCOORD6, - SLANG_VERTEX_FIXED_MULTITEXCOORD7, - SLANG_VERTEX_FIXED_FOGCOORD, - SLANG_VERTEX_FIXED_FRONTCOLOR, - SLANG_VERTEX_FIXED_BACKCOLOR, - SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR, - SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR, - SLANG_VERTEX_FIXED_TEXCOORD, - SLANG_VERTEX_FIXED_FOGFRAGCOORD, - SLANG_VERTEX_FIXED_MAX -}; - -enum -{ - SLANG_FRAGMENT_FIXED_FRAGCOORD, - SLANG_FRAGMENT_FIXED_FRONTFACING, - SLANG_FRAGMENT_FIXED_FRAGCOLOR, - SLANG_FRAGMENT_FIXED_FRAGDATA, - SLANG_FRAGMENT_FIXED_FRAGDEPTH, - SLANG_FRAGMENT_FIXED_COLOR, - SLANG_FRAGMENT_FIXED_SECONDARYCOLOR, - SLANG_FRAGMENT_FIXED_TEXCOORD, - SLANG_FRAGMENT_FIXED_FOGFRAGCOORD, - SLANG_FRAGMENT_FIXED_MAX -}; - -enum -{ - SLANG_COMMON_CODE_MAIN, - SLANG_COMMON_CODE_MAX -}; - -typedef struct -{ - slang_active_variables active_uniforms; - slang_active_variables active_attribs; - slang_attrib_overrides attrib_overrides; - slang_uniform_bindings uniforms; - slang_attrib_bindings attribs; - slang_varying_bindings varyings; - slang_texture_usages texture_usage; - GLuint common_fixed_entries[SLANG_SHADER_MAX][SLANG_COMMON_FIXED_MAX]; - GLuint vertex_fixed_entries[SLANG_VERTEX_FIXED_MAX]; - GLuint fragment_fixed_entries[SLANG_FRAGMENT_FIXED_MAX]; - GLuint code[SLANG_SHADER_MAX][SLANG_COMMON_CODE_MAX]; - slang_machine *machines[SLANG_SHADER_MAX]; - slang_assembly_file *assemblies[SLANG_SHADER_MAX]; -} slang_program; - -GLvoid slang_program_ctr (slang_program *); -GLvoid slang_program_dtr (slang_program *); - -GLboolean _slang_link (slang_program *, slang_translation_unit **, GLuint); - -#ifdef __cplusplus -} -#endif - -#endif - +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_LINK_H +#define SLANG_LINK_H + +#include "slang_compile.h" + +#if defined __cplusplus +extern "C" { +#endif + +enum +{ + SLANG_SHADER_VERTEX, + SLANG_SHADER_FRAGMENT, + SLANG_SHADER_MAX +}; + +/* Active variables. + * + * Active uniforms or attribs can be queried by the application to get a list of uniforms + * or attribs actually used by shaders (uniforms) or vertex shader (attribs). + */ + +typedef struct +{ + slang_export_data_quant *quant; + char *name; +} slang_active_variable; + +typedef struct +{ + slang_active_variable *table; + GLuint count; +} slang_active_variables; + +/* + * Attrib binding override. + * + * The application can override GL attrib binding by specifying its preferred index assignment + * for a given attrib name. Those overrides are taken into account while linking the program. + */ + +typedef struct +{ + GLuint index; + GLchar *name; +} slang_attrib_override; + +typedef struct +{ + slang_attrib_override *table; + GLuint count; +} slang_attrib_overrides; + +GLboolean slang_attrib_overrides_add (slang_attrib_overrides *, GLuint, const GLchar *); + +/* + * Uniform bindings. + * + * Each slang_uniform_binding holds an array of addresses to actual memory locations in those + * shader types that use that uniform. Uniform bindings are held in an array and accessed + * by array index which is seen to the application as a uniform location. + * + * When the application writes to a particular uniform, it specifies its location. + * This location is treated as an array index to slang_uniform_bindings::table and tested + * against slang_uniform_bindings::count limit. The result is a pointer to slang_uniform_binding. + * The type of data being written to uniform is tested against slang_uniform_binding::quant. + * If the types are compatible, the array slang_uniform_binding::address is iterated for + * each shader type and if the address is valid (i.e. the uniform is used by this shader type), + * the new uniform value is written at that address. + */ + +typedef struct +{ + slang_export_data_quant *quant; + char *name; + GLuint address[SLANG_SHADER_MAX]; +} slang_uniform_binding; + +typedef struct +{ + slang_uniform_binding *table; + GLuint count; +} slang_uniform_bindings; + +/* + * Attrib bindings. + * + * There is a fixed number of vertex attrib vectors (attrib slots). The slang_attrib_slot::addr + * maps vertex attrib index to the actual memory location of the attrib in vertex shader. + * One vertex attrib can span over many attrib slots (this is the case for matrices). The + * slang_attrib_binding::first_slot_index holds the first slot index that the attrib is bound to. + */ + +typedef struct +{ + slang_export_data_quant *quant; + char *name; + GLuint first_slot_index; +} slang_attrib_binding; + +typedef struct +{ + GLuint addr; +} slang_attrib_slot; + +typedef struct +{ + slang_attrib_binding bindings[MAX_VERTEX_ATTRIBS]; + GLuint binding_count; + slang_attrib_slot slots[MAX_VERTEX_ATTRIBS]; +} slang_attrib_bindings; + +/* + * Varying bindings. + * + * There is a fixed number of varying floats (varying slots). The slang_varying_slot::vert_addr + * maps varying float index to the actual memory location of the output variable in vertex shader. + * The slang_varying_slot::frag_addr maps varying float index to the actual memory location of + * the input variable in fragment shader. + */ + +typedef struct +{ + GLuint vert_addr; + GLuint frag_addr; +} slang_varying_slot; + +typedef struct +{ + slang_export_data_quant *quant; + char *name; + GLuint first_slot_index; +} slang_varying_binding; + +typedef struct +{ + slang_varying_binding bindings[MAX_VARYING_FLOATS]; + GLuint binding_count; + slang_varying_slot slots[MAX_VARYING_FLOATS]; + GLuint slot_count; +} slang_varying_bindings; + +/* + * Texture usage. + * + * A slang_texture_usage struct holds indirect information about texture image unit usage. The + * slang_texture_usages::table is derived from active uniform table by extracting only uniforms + * that are samplers. + * + * To collect current texture usage one must iterate the slang_texture_usages::table and read + * uniform at address slang_texture_usage::frag_address to get texture unit index. This + * index, coupled with texture access type (target) taken from slang_texture_usage::quant + * forms texture usage for that texture unit. + */ + +typedef struct +{ + slang_export_data_quant *quant; + GLuint frag_address; +} slang_texture_usage; + +typedef struct +{ + slang_texture_usage *table; + GLuint count; +} slang_texture_usages; + +GLvoid slang_texture_usages_ctr (slang_texture_usages *); +GLvoid slang_texture_usages_dtr (slang_texture_usages *); + +enum +{ + SLANG_COMMON_FIXED_MODELVIEWMATRIX, + SLANG_COMMON_FIXED_PROJECTIONMATRIX, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX, + SLANG_COMMON_FIXED_TEXTUREMATRIX, + SLANG_COMMON_FIXED_NORMALMATRIX, + SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE, + SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE, + SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE, + SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE, + SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE, + SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE, + SLANG_COMMON_FIXED_NORMALSCALE, + SLANG_COMMON_FIXED_DEPTHRANGE, + SLANG_COMMON_FIXED_CLIPPLANE, + SLANG_COMMON_FIXED_POINT, + SLANG_COMMON_FIXED_FRONTMATERIAL, + SLANG_COMMON_FIXED_BACKMATERIAL, + SLANG_COMMON_FIXED_LIGHTSOURCE, + SLANG_COMMON_FIXED_LIGHTMODEL, + SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT, + SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT, + SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT, + SLANG_COMMON_FIXED_BACKLIGHTPRODUCT, + SLANG_COMMON_FIXED_TEXTUREENVCOLOR, + SLANG_COMMON_FIXED_EYEPLANES, + SLANG_COMMON_FIXED_EYEPLANET, + SLANG_COMMON_FIXED_EYEPLANER, + SLANG_COMMON_FIXED_EYEPLANEQ, + SLANG_COMMON_FIXED_OBJECTPLANES, + SLANG_COMMON_FIXED_OBJECTPLANET, + SLANG_COMMON_FIXED_OBJECTPLANER, + SLANG_COMMON_FIXED_OBJECTPLANEQ, + SLANG_COMMON_FIXED_FOG, + SLANG_COMMON_FIXED_MAX +}; + +enum +{ + SLANG_VERTEX_FIXED_POSITION, + SLANG_VERTEX_FIXED_POINTSIZE, + SLANG_VERTEX_FIXED_CLIPVERTEX, + SLANG_VERTEX_FIXED_COLOR, + SLANG_VERTEX_FIXED_SECONDARYCOLOR, + SLANG_VERTEX_FIXED_NORMAL, + SLANG_VERTEX_FIXED_VERTEX, + SLANG_VERTEX_FIXED_MULTITEXCOORD0, + SLANG_VERTEX_FIXED_MULTITEXCOORD1, + SLANG_VERTEX_FIXED_MULTITEXCOORD2, + SLANG_VERTEX_FIXED_MULTITEXCOORD3, + SLANG_VERTEX_FIXED_MULTITEXCOORD4, + SLANG_VERTEX_FIXED_MULTITEXCOORD5, + SLANG_VERTEX_FIXED_MULTITEXCOORD6, + SLANG_VERTEX_FIXED_MULTITEXCOORD7, + SLANG_VERTEX_FIXED_FOGCOORD, + SLANG_VERTEX_FIXED_FRONTCOLOR, + SLANG_VERTEX_FIXED_BACKCOLOR, + SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR, + SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR, + SLANG_VERTEX_FIXED_TEXCOORD, + SLANG_VERTEX_FIXED_FOGFRAGCOORD, + SLANG_VERTEX_FIXED_MAX +}; + +enum +{ + SLANG_FRAGMENT_FIXED_FRAGCOORD, + SLANG_FRAGMENT_FIXED_FRONTFACING, + SLANG_FRAGMENT_FIXED_FRAGCOLOR, + SLANG_FRAGMENT_FIXED_FRAGDATA, + SLANG_FRAGMENT_FIXED_FRAGDEPTH, + SLANG_FRAGMENT_FIXED_COLOR, + SLANG_FRAGMENT_FIXED_SECONDARYCOLOR, + SLANG_FRAGMENT_FIXED_TEXCOORD, + SLANG_FRAGMENT_FIXED_FOGFRAGCOORD, + SLANG_FRAGMENT_FIXED_MAX +}; + +enum +{ + SLANG_COMMON_CODE_MAIN, + SLANG_COMMON_CODE_MAX +}; + +typedef struct +{ + slang_active_variables active_uniforms; + slang_active_variables active_attribs; + slang_attrib_overrides attrib_overrides; + slang_uniform_bindings uniforms; + slang_attrib_bindings attribs; + slang_varying_bindings varyings; + slang_texture_usages texture_usage; + GLuint common_fixed_entries[SLANG_SHADER_MAX][SLANG_COMMON_FIXED_MAX]; + GLuint vertex_fixed_entries[SLANG_VERTEX_FIXED_MAX]; + GLuint fragment_fixed_entries[SLANG_FRAGMENT_FIXED_MAX]; + GLuint code[SLANG_SHADER_MAX][SLANG_COMMON_CODE_MAX]; + slang_machine *machines[SLANG_SHADER_MAX]; + slang_assembly_file *assemblies[SLANG_SHADER_MAX]; +} slang_program; + +GLvoid slang_program_ctr (slang_program *); +GLvoid slang_program_dtr (slang_program *); + +GLboolean _slang_link (slang_program *, slang_translation_unit **, GLuint); + +#ifdef __cplusplus +} +#endif + +#endif + -- cgit v1.2.3