From b4e9750bf4996ca5bb622bbbe28be4f071811bc6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 4 Apr 2006 10:18:07 +0000 Subject: More GLSL code: - add support for varyings; GLSL fixes: - pow was wrongly computed in x86 back-end; --- src/mesa/shader/shaderobjects.h | 17 ++-- src/mesa/shader/shaderobjects_3dlabs.c | 56 +++++++++---- src/mesa/shader/slang/slang_analyse.c | 8 +- src/mesa/shader/slang/slang_execute_x86.c | 27 +++++- src/mesa/shader/slang/slang_export.c | 52 ++++++++++-- src/mesa/shader/slang/slang_export.h | 39 ++++++++- src/mesa/shader/slang/slang_link.c | 133 +++++++++++++++++++++++++----- src/mesa/shader/slang/slang_link.h | 22 +++++ 8 files changed, 295 insertions(+), 59 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/shaderobjects.h b/src/mesa/shader/shaderobjects.h index 060328163b..19c4e8d3f8 100644 --- a/src/mesa/shader/shaderobjects.h +++ b/src/mesa/shader/shaderobjects.h @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.5 * - * Copyright (C) 2004-2005 Brian Paul All Rights Reserved. + * Copyright (C) 2004-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"), @@ -85,14 +85,15 @@ struct gl2_program_intf GLboolean (* GetLinkStatus) (struct gl2_program_intf **); GLboolean (* GetValidateStatus) (struct gl2_program_intf **); GLvoid (* Link) (struct gl2_program_intf **); - GLvoid (* Validate) (struct gl2_program_intf **); - GLvoid (* UpdateFixedUniforms) (struct gl2_program_intf **); - GLvoid (* UpdateFixedAttribute) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, - GLboolean); - GLvoid (* UpdateFixedVarying) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, - GLboolean); - GLvoid (* GetTextureImageUsage) (struct gl2_program_intf **, GLbitfield *); + GLvoid (* Validate) (struct gl2_program_intf **); + GLvoid (* UpdateFixedUniforms) (struct gl2_program_intf **); + GLvoid (* UpdateFixedAttribute) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, + GLboolean); + GLvoid (* UpdateFixedVarying) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, + GLboolean); + GLvoid (* GetTextureImageUsage) (struct gl2_program_intf **, GLbitfield *); GLboolean (* IsShaderPresent) (struct gl2_program_intf **, GLenum); + GLvoid (* UpdateVarying) (struct gl2_program_intf **, GLuint, GLfloat *, GLboolean); }; struct gl2_fragment_shader_intf diff --git a/src/mesa/shader/shaderobjects_3dlabs.c b/src/mesa/shader/shaderobjects_3dlabs.c index 0b0ae414fd..fa38a1c9af 100755 --- a/src/mesa/shader/shaderobjects_3dlabs.c +++ b/src/mesa/shader/shaderobjects_3dlabs.c @@ -1150,9 +1150,7 @@ _program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *texim { GLuint n, addr, j; - n = pro->texture_usage.table[i].quant->array_len; - if (n == 0) - n = 1; + n = slang_export_data_quant_elements (pro->texture_usage.table[i].quant); addr = pro->texture_usage.table[i].frag_address; for (j = 0; j < n; j++) { @@ -1163,7 +1161,7 @@ _program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *texim image = (GLuint) *((GLfloat *) mem); if (image >= 0 && image < ctx->Const.MaxTextureImageUnits) { - switch (pro->texture_usage.table[i].quant->u.basic_type) + switch (slang_export_data_quant_type (pro->texture_usage.table[i].quant)) { case GL_SAMPLER_1D_ARB: case GL_SAMPLER_1D_SHADOW_ARB: @@ -1204,6 +1202,29 @@ _program_IsShaderPresent (struct gl2_program_intf **intf, GLenum subtype) } } +static GLvoid +_program_UpdateVarying (struct gl2_program_intf **intf, GLuint index, GLfloat *value, + GLboolean vert) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + slang_program *pro = &impl->_obj.prog; + GLuint addr; + + if (index >= pro->varyings.total) + return; + if (vert) + addr = pro->varyings.slots[index].vert_addr / 4; + else + addr = pro->varyings.slots[index].frag_addr / 4; + if (addr != ~0) + { + if (vert) + *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float; + else + pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value; + } +} + static struct gl2_program_intf _program_vftbl = { { { @@ -1231,7 +1252,8 @@ static struct gl2_program_intf _program_vftbl = { _program_UpdateFixedAttribute, _program_UpdateFixedVarying, _program_GetTextureImageUsage, - _program_IsShaderPresent + _program_IsShaderPresent, + _program_UpdateVarying }; static void @@ -1514,10 +1536,10 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize b = &bind->table[loc]; /* TODO: check sizes */ - if (b->quant->structure != NULL) + if (slang_export_data_quant_struct (b->quant)) return GL_FALSE; - switch (b->quant->u.basic_type) + switch (slang_export_data_quant_type (b->quant)) { case GL_BOOL_ARB: types_match = (type == GL_FLOAT) || (type == GL_INT); @@ -1556,7 +1578,7 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize types_match = (type == GL_INT); break; default: - types_match = (type == b->quant->u.basic_type); + types_match = (type == slang_export_data_quant_type (b->quant)); break; } @@ -1581,8 +1603,9 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize const GLfloat *src = (GLfloat *) (data); GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]); GLuint j; + GLuint total = count * slang_export_data_quant_components (b->quant); - for (j = 0; j < count * b->quant->size / 4; j++) + for (j = 0; j < total; j++) dst[j] = src[j] != 0.0f ? 1.0f : 0.0f; } } @@ -1594,8 +1617,9 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize const GLuint *src = (GLuint *) (data); GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]); GLuint j; + GLuint total = count * slang_export_data_quant_components (b->quant); - for (j = 0; j < count * b->quant->size / 4; j++) + for (j = 0; j < total; j++) dst[j] = src[j] ? 1.0f : 0.0f; } } @@ -1607,8 +1631,9 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize const GLuint *src = (GLuint *) (data); GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]); GLuint j; + GLuint total = count * slang_export_data_quant_components (b->quant); - for (j = 0; j < count * b->quant->size / 4; j++) + for (j = 0; j < total; j++) dst[j] = (GLfloat) src[j]; } } @@ -1618,7 +1643,7 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize if (b->address[i] != ~0) { _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4], data, - count * b->quant->size); + count * slang_export_data_quant_size (b->quant)); } } return GL_TRUE; @@ -1664,11 +1689,8 @@ GLvoid _slang_get_active_uniform (struct gl2_program_intf **pro, GLuint index, G name[len] = '\0'; if (length != NULL) *length = len; - *type = u->quant->u.basic_type; - if (u->quant->array_len == 0) - *size = 1; - else - *size = u->quant->array_len; + *type = slang_export_data_quant_type (u->quant); + *size = slang_export_data_quant_elements (u->quant); } void diff --git a/src/mesa/shader/slang/slang_analyse.c b/src/mesa/shader/slang/slang_analyse.c index 164dbec350..76320848b5 100644 --- a/src/mesa/shader/slang/slang_analyse.c +++ b/src/mesa/shader/slang/slang_analyse.c @@ -49,9 +49,9 @@ GLboolean _slang_analyse_texture_usage (slang_program *prog) { slang_uniform_binding *b = &prog->uniforms.table[i]; - if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && b->quant->structure == NULL) + if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && !slang_export_data_quant_struct (b->quant)) { - switch (b->quant->u.basic_type) + switch (slang_export_data_quant_type (b->quant)) { case GL_SAMPLER_1D_ARB: case GL_SAMPLER_2D_ARB: @@ -77,9 +77,9 @@ GLboolean _slang_analyse_texture_usage (slang_program *prog) { slang_uniform_binding *b = &prog->uniforms.table[i]; - if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && b->quant->structure == NULL) + if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && !slang_export_data_quant_struct (b->quant)) { - switch (b->quant->u.basic_type) + switch (slang_export_data_quant_type (b->quant)) { case GL_SAMPLER_1D_ARB: case GL_SAMPLER_2D_ARB: diff --git a/src/mesa/shader/slang/slang_execute_x86.c b/src/mesa/shader/slang/slang_execute_x86.c index eabe368596..b578838e82 100644 --- a/src/mesa/shader/slang/slang_execute_x86.c +++ b/src/mesa/shader/slang/slang_execute_x86.c @@ -81,6 +81,12 @@ static GLvoid add_fixup (codegen_ctx *G, GLuint index, GLubyte *csr) #define RND_NEG_FPU (FAST_X86_FPU | 0x400) #endif +#if 0 + +/* + * XXX + * These should produce a valid code that computes powers. Unfortunately, it does not. + */ static void set_fpu_round_neg_inf (codegen_ctx *G) { if (G->fpucntl != RND_NEG_FPU) @@ -107,6 +113,16 @@ static void emit_x87_ex2 (codegen_ctx *G) x87_fscale (&G->f); /* 2^a */ } +static void emit_pow (codegen_ctx *G) +{ + x87_fld (&G->f, x86_deref (G->r_esp)); + x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); + x87_fyl2x (&G->f); + emit_x87_ex2 (G); +} + +#endif + static GLfloat do_ceilf (GLfloat x) { return CEILF (x); @@ -117,6 +133,11 @@ static GLfloat do_floorf (GLfloat x) return FLOORF (x); } +static GLfloat do_powf (GLfloat y, GLfloat x) +{ + return (GLfloat) _mesa_pow ((GLdouble) x, (GLdouble) y); +} + static GLvoid do_print_float (GLfloat x) { _mesa_printf ("slang print: %f\n", x); @@ -285,10 +306,8 @@ static GLvoid codegen_assem (codegen_ctx *G, slang_assembly *a) x87_fstp (&G->f, x86_deref (G->r_esp)); break; case slang_asm_float_power: - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); - x87_fyl2x (&G->f); - emit_x87_ex2 (G); + /* TODO: use emit_pow() */ + x86_call (&G->f, (GLubyte *) do_powf); x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); x87_fstp (&G->f, x86_deref (G->r_esp)); break; diff --git a/src/mesa/shader/slang/slang_export.c b/src/mesa/shader/slang/slang_export.c index 43ce35de49..515c03fb64 100644 --- a/src/mesa/shader/slang/slang_export.c +++ b/src/mesa/shader/slang/slang_export.c @@ -69,6 +69,45 @@ slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_qu 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; +} + +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 */ @@ -254,19 +293,19 @@ static GLboolean validate_extracted (slang_export_data_quant *q, GLuint element, case EXTRACT_BASIC: return GL_TRUE; case EXTRACT_ARRAY: - return element < q->array_len; + return element < slang_export_data_quant_elements (q); case EXTRACT_STRUCT: - return q->structure != NULL; + return slang_export_data_quant_struct (q); case EXTRACT_STRUCT_ARRAY: - return q->structure != NULL && element < q->array_len; + 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 (q->array_len != 0) - return element * q->size; + if (slang_export_data_quant_array (q)) + return element * slang_export_data_quant_size (q); return 0; } @@ -277,6 +316,7 @@ static GLboolean find_exported_data (slang_export_data_quant *q, const char *nam 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) @@ -286,7 +326,7 @@ static GLboolean find_exported_data (slang_export_data_quant *q, const char *nam if (atom == SLANG_ATOM_NULL) return GL_FALSE; - for (i = 0; i < q->u.field_count; i++) + for (i = 0; i < fields; i++) if (q->structure[i].name == atom) { if (!validate_extracted (&q->structure[i], element, result)) diff --git a/src/mesa/shader/slang/slang_export.h b/src/mesa/shader/slang/slang_export.h index 88a74fe26b..c158eb4443 100644 --- a/src/mesa/shader/slang/slang_export.h +++ b/src/mesa/shader/slang/slang_export.h @@ -35,7 +35,7 @@ extern "C" { * 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. - * The is not 0, the data quantity is an array of size. + * 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. @@ -58,6 +58,43 @@ 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 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. + * For scalars, 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. */ diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 58d17c1558..a72ec2eaa0 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -79,46 +79,42 @@ static GLboolean slang_uniform_bindings_add (slang_uniform_bindings *self, slang return GL_TRUE; } -static GLboolean insert_binding (slang_uniform_bindings *bind, slang_export_data_quant *q, +static GLboolean insert_uniform_binding (slang_uniform_bindings *bind, 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)); - - if (q->array_len == 0) - count = 1; - else - count = q->array_len; - + count = slang_export_data_quant_elements (q); for (i = 0; i < count; i++) { GLuint save; save = slang_string_length (name); - if (q->array_len != 0) + if (slang_export_data_quant_array (q)) _mesa_sprintf (name + slang_string_length (name), "[%d]", i); - if (q->structure != NULL) + if (slang_export_data_quant_struct (q)) { GLuint save, i; + const GLuint fields = slang_export_data_quant_fields (q); slang_string_concat (name, "."); save = slang_string_length (name); - for (i = 0; i < q->u.field_count; i++) + for (i = 0; i < fields; i++) { - if (!insert_binding (bind, &q->structure[i], name, atoms, index, addr)) + if (!insert_uniform_binding (bind, &q->structure[i], name, atoms, index, addr)) return GL_FALSE; name[save] = '\0'; - addr += q->structure[i].size; + addr += slang_export_data_quant_size (&q->structure[i]); } } else { if (!slang_uniform_bindings_add (bind, q, name, index, addr)) return GL_FALSE; - addr += q->size; + addr += slang_export_data_quant_size (q); } name[save] = '\0'; } @@ -126,8 +122,8 @@ static GLboolean insert_binding (slang_uniform_bindings *bind, slang_export_data return GL_TRUE; } -static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind, slang_export_data_table *tbl, - GLuint index) +static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind, + slang_export_data_table *tbl, GLuint index) { GLuint i; @@ -136,7 +132,7 @@ static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind, slang_ex { char name[1024] = ""; - if (!insert_binding (bind, &tbl->entries[i].quant, name, tbl->atoms, index, + if (!insert_uniform_binding (bind, &tbl->entries[i].quant, name, tbl->atoms, index, tbl->entries[i].address)) return GL_FALSE; } @@ -184,17 +180,18 @@ static GLboolean insert_uniform (slang_active_uniforms *u, slang_export_data_qua slang_atom_pool *atoms) { slang_string_concat (name, slang_atom_pool_id (atoms, q->name)); - if (q->array_len != 0) + if (slang_export_data_quant_array (q)) slang_string_concat (name, "[0]"); - if (q->structure != NULL) + if (slang_export_data_quant_struct (q)) { GLuint save, i; + const GLuint fields = slang_export_data_quant_fields (q); slang_string_concat (name, "."); save = slang_string_length (name); - for (i = 0; i < q->u.field_count; i++) + for (i = 0; i < fields; i++) { if (!insert_uniform (u, &q->structure[i], name, atoms)) return GL_FALSE; @@ -223,6 +220,97 @@ static GLboolean gather_active_uniforms (slang_active_uniforms *u, slang_export_ return GL_TRUE; } +/* + * slang_varying_bindings + */ + +static GLvoid slang_varying_bindings_ctr (slang_varying_bindings *self) +{ + self->count = 0; + self->total = 0; +} + +static GLvoid slang_varying_bindings_dtr (slang_varying_bindings *self) +{ + GLuint i; + + for (i = 0; i < self->count; i++) + slang_alloc_free (self->table[i].name); +} + +static GLvoid update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean vert, + GLuint address, GLuint do_offset) +{ + GLuint i; + + for (i = 0; i < count; i++) + if (vert) + slots[i].vert_addr = address + i * 4 * do_offset; + else + slots[i].frag_addr = address + i * 4 * do_offset; +} + +static GLboolean slang_varying_bindings_add (slang_varying_bindings *self, + slang_export_data_quant *q, const char *name, GLboolean vert, GLuint address) +{ + const GLuint n = self->count; + const GLuint total_components = + 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->table[i].name, name) == 0) + { + /* TODO: data quantities must match, or else link fails */ + update_varying_slots (&self->slots[self->table[i].slot], total_components, vert, + address, 1); + return GL_TRUE; + } + + if (self->total + total_components > MAX_VARYING_FLOATS) + { + /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */ + return GL_FALSE; + } + + self->table[n].quant = q; + self->table[n].slot = self->total; + self->table[n].name = slang_string_duplicate (name); + if (self->table[n].name == NULL) + return GL_FALSE; + self->count++; + + update_varying_slots (&self->slots[self->table[n].slot], total_components, vert, address, 1); + update_varying_slots (&self->slots[self->table[n].slot], total_components, !vert, ~0, 0); + self->total += total_components; + + return GL_TRUE; +} + +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] == '_'; +} + +static GLboolean gather_varying_bindings (slang_varying_bindings *bind, + slang_export_data_table *tbl, GLboolean 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 (!slang_varying_bindings_add (bind, &tbl->entries[i].quant, + slang_atom_pool_id (tbl->atoms, tbl->entries[i].quant.name), vert, + tbl->entries[i].address)) + return GL_FALSE; + } + + return GL_TRUE; +} + /* * slang_texture_bindings */ @@ -248,6 +336,7 @@ GLvoid slang_program_ctr (slang_program *self) slang_uniform_bindings_ctr (&self->uniforms); slang_active_uniforms_ctr (&self->active_uniforms); + slang_varying_bindings_ctr (&self->varyings); slang_texture_usages_ctr (&self->texture_usage); for (i = 0; i < SLANG_SHADER_MAX; i++) { @@ -270,6 +359,7 @@ GLvoid slang_program_dtr (slang_program *self) { slang_uniform_bindings_dtr (&self->uniforms); slang_active_uniforms_dtr (&self->active_uniforms); + slang_varying_bindings_dtr (&self->varyings); slang_texture_usages_dtr (&self->texture_usage); } @@ -423,12 +513,17 @@ GLboolean _slang_link (slang_program *prog, slang_translation_unit **units, GLui return GL_FALSE; if (!gather_active_uniforms (&prog->active_uniforms, &units[i]->exp_data)) 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; diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 1592aefe2e..e74c256562 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -63,6 +63,27 @@ typedef struct GLuint count; } slang_active_uniforms; +typedef struct +{ + GLuint vert_addr; + GLuint frag_addr; +} slang_varying_slot; + +typedef struct +{ + slang_export_data_quant *quant; + char *name; + GLuint slot; +} slang_varying_binding; + +typedef struct +{ + slang_varying_binding table[MAX_VARYING_FLOATS]; + GLuint count; + slang_varying_slot slots[MAX_VARYING_FLOATS]; + GLuint total; +} slang_varying_bindings; + typedef struct { slang_export_data_quant *quant; @@ -173,6 +194,7 @@ typedef struct { slang_uniform_bindings uniforms; slang_active_uniforms active_uniforms; + 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]; -- cgit v1.2.3