summaryrefslogtreecommitdiff
path: root/src/mesa/shader
diff options
context:
space:
mode:
authorMichal Krol <mjkrol@gmail.org>2006-04-04 10:18:07 +0000
committerMichal Krol <mjkrol@gmail.org>2006-04-04 10:18:07 +0000
commitb4e9750bf4996ca5bb622bbbe28be4f071811bc6 (patch)
treee0c595b22aeee885b4910267c8dc0995e3d362d5 /src/mesa/shader
parent607b61a994d8dca150d5611b18db9b55755f73b4 (diff)
More GLSL code:
- add support for varyings; GLSL fixes: - pow was wrongly computed in x86 back-end;
Diffstat (limited to 'src/mesa/shader')
-rw-r--r--src/mesa/shader/shaderobjects.h17
-rwxr-xr-xsrc/mesa/shader/shaderobjects_3dlabs.c56
-rw-r--r--src/mesa/shader/slang/slang_analyse.c8
-rw-r--r--src/mesa/shader/slang/slang_execute_x86.c27
-rw-r--r--src/mesa/shader/slang/slang_export.c52
-rw-r--r--src/mesa/shader/slang/slang_export.h39
-rw-r--r--src/mesa/shader/slang/slang_link.c133
-rw-r--r--src/mesa/shader/slang/slang_link.h22
8 files changed, 295 insertions, 59 deletions
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 <size> 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 <array_len> is not 0, the data quantity is an array of <array_len> size.
+ * If the <array_len> is not 0, the data quantity is an array of <array_len> size.
* If the <structure> is not NULL, the data quantity is a struct. The <basic_type> is
* invalid and the <field_count> holds the size of the <structure> array.
* The <basic_type> values match those of <type> parameter for glGetActiveUniformARB.
@@ -59,6 +59,43 @@ 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;
@@ -224,6 +221,97 @@ static GLboolean gather_active_uniforms (slang_active_uniforms *u, slang_export_
}
/*
+ * 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
@@ -65,6 +65,27 @@ typedef struct
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;
GLuint frag_address;
} slang_texture_usage;
@@ -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];