diff options
author | Michal Krol <[email protected]> | 2006-02-13 11:38:37 +0000 |
---|---|---|
committer | Michal Krol <[email protected]> | 2006-02-13 11:38:37 +0000 |
commit | 02eb9acc5e4307db09662592951ef44319a0cda5 (patch) | |
tree | 585a539ed6d6775801dcc9e685759521680da9f9 | |
parent | 44e9ccc708bb0a92dfeaf038ded60295dfe2d3ae (diff) |
Get it running for ARB_vertex_shader.
Add experimental print functions to builtin library.
Some functionality missing:
- automatic arrays;
- general constructors;
- local variable initialization;
- texture sampling and noise;
- semantic error checking;
- function prototypes.
27 files changed, 2060 insertions, 1346 deletions
diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c index a97da6b2834..45b6b1961cc 100644 --- a/src/mesa/shader/slang/slang_assemble.c +++ b/src/mesa/shader/slang/slang_assemble.c @@ -31,18 +31,20 @@ #include "imports.h"
#include "slang_utility.h"
#include "slang_assemble.h"
-#include "slang_compile.h"
+/*#include "slang_compile.h"*/
#include "slang_storage.h"
-#include "slang_assemble_constructor.h"
+/*#include "slang_assemble_constructor.h"*/
#include "slang_assemble_typeinfo.h"
#include "slang_assemble_conditional.h"
#include "slang_assemble_assignment.h"
+#include "slang_execute.h"
/* slang_assembly */
-static void slang_assembly_construct (slang_assembly *assem)
+static int slang_assembly_construct (slang_assembly *assem)
{
assem->type = slang_asm_none;
+ return 1;
}
static void slang_assembly_destruct (slang_assembly *assem)
@@ -51,10 +53,12 @@ static void slang_assembly_destruct (slang_assembly *assem) /* slang_assembly_file */
-void slang_assembly_file_construct (slang_assembly_file *file)
+int slang_assembly_file_construct (slang_assembly_file *file)
{
file->code = NULL;
file->count = 0;
+ file->capacity = 0;
+ return 1;
}
void slang_assembly_file_destruct (slang_assembly_file *file)
@@ -62,30 +66,40 @@ void slang_assembly_file_destruct (slang_assembly_file *file) unsigned int i;
for (i = 0; i < file->count; i++)
- slang_assembly_destruct (file->code + i);
+ slang_assembly_destruct (&file->code[i]);
slang_alloc_free (file->code);
}
-static int slang_assembly_file_push_new (slang_assembly_file *file)
+static int push_new (slang_assembly_file *file)
{
- file->code = (slang_assembly *) slang_alloc_realloc (file->code, file->count * sizeof (
- slang_assembly), (file->count + 1) * sizeof (slang_assembly));
- if (file->code != NULL)
+ if (file->count == file->capacity)
{
- slang_assembly_construct (file->code + file->count);
- file->count++;
- return 1;
+ unsigned int n;
+
+ if (file->capacity == 0)
+ n = 256;
+ else
+ n = file->capacity * 2;
+ file->code = (slang_assembly *) slang_alloc_realloc (file->code,
+ file->capacity * sizeof (slang_assembly), n * sizeof (slang_assembly));
+ if (file->code == NULL)
+ return 0;
+ file->capacity = n;
}
- return 0;
+ if (!slang_assembly_construct (&file->code[file->count]))
+ return 0;
+ file->count++;
+ return 1;
}
-static int slang_assembly_file_push_general (slang_assembly_file *file, slang_assembly_type type,
- GLfloat literal, GLuint label, GLuint size)
+static int push_gen (slang_assembly_file *file, slang_assembly_type type, GLfloat literal,
+ GLuint label, GLuint size)
{
slang_assembly *assem;
- if (!slang_assembly_file_push_new (file))
+
+ if (!push_new (file))
return 0;
- assem = file->code + file->count - 1;
+ assem = &file->code[file->count - 1];
assem->type = type;
assem->literal = literal;
assem->param[0] = label;
@@ -95,102 +109,138 @@ static int slang_assembly_file_push_general (slang_assembly_file *file, slang_as int slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)
{
- return slang_assembly_file_push_general (file, type, (GLfloat) 0, 0, 0);
+ return push_gen (file, type, (GLfloat) 0, 0, 0);
}
int slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,
GLuint label)
{
- return slang_assembly_file_push_general (file, type, (GLfloat) 0, label, 0);
+ return push_gen (file, type, (GLfloat) 0, label, 0);
}
int slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,
GLuint label1, GLuint label2)
{
- return slang_assembly_file_push_general (file, type, (GLfloat) 0, label1, label2);
+ return push_gen (file, type, (GLfloat) 0, label1, label2);
}
int slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,
GLfloat literal)
{
- return slang_assembly_file_push_general (file, type, literal, 0, 0);
+ return push_gen (file, type, literal, 0, 0);
+}
+
+#define PUSH slang_assembly_file_push
+#define PLAB slang_assembly_file_push_label
+#define PLAB2 slang_assembly_file_push_label2
+#define PLIT slang_assembly_file_push_literal
+
+/* slang_assembly_file_restore_point */
+
+int slang_assembly_file_restore_point_save (slang_assembly_file *file,
+ slang_assembly_file_restore_point *point)
+{
+ point->count = file->count;
+ return 1;
+}
+
+int slang_assembly_file_restore_point_load (slang_assembly_file *file,
+ slang_assembly_file_restore_point *point)
+{
+ unsigned int i;
+
+ for (i = point->count; i < file->count; i++)
+ slang_assembly_destruct (&file->code[i]);
+ file->count = point->count;
+ return 1;
}
/* utility functions */
static int sizeof_variable (slang_type_specifier *spec, slang_type_qualifier qual,
- slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size)
+ slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size,
+ slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)
{
slang_storage_aggregate agg;
- slang_storage_aggregate_construct (&agg);
- if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs, space->vars))
+ /* calculate the size of the variable's aggregate */
+ if (!slang_storage_aggregate_construct (&agg))
+ return 0;
+ if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs,
+ space->vars, mach, pfile, atoms))
{
slang_storage_aggregate_destruct (&agg);
return 0;
}
*size += _slang_sizeof_aggregate (&agg);
+ slang_storage_aggregate_destruct (&agg);
+
+ /* for reference variables consider the additional address overhead */
if (qual == slang_qual_out || qual == slang_qual_inout)
*size += 4;
- slang_storage_aggregate_destruct (&agg);
return 1;
}
static int sizeof_variable2 (slang_variable *var, slang_assembly_name_space *space,
- unsigned int *size)
+ unsigned int *size, slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)
{
var->address = *size;
if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)
var->address += 4;
return sizeof_variable (&var->type.specifier, var->type.qualifier, var->array_size, space,
- size);
+ size, mach, pfile, atoms);
}
static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop,
- slang_assembly_name_space *space, unsigned int *size)
+ slang_assembly_name_space *space, unsigned int *size, slang_machine *mach,
+ slang_assembly_file *pfile, slang_atom_pool *atoms)
{
unsigned int i;
for (i = start; i < stop; i++)
- if (!sizeof_variable2 (vars->variables + i, space, size))
+ if (!sizeof_variable2 (&vars->variables[i], space, size, mach, pfile, atoms))
return 0;
return 1;
}
static int collect_locals (slang_operation *op, slang_assembly_name_space *space,
- unsigned int *size)
+ unsigned int *size, slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)
{
unsigned int i;
- if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size))
+ if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size, mach, pfile,
+ atoms))
return 0;
for (i = 0; i < op->num_children; i++)
- if (!collect_locals (op->children + i, space, size))
+ if (!collect_locals (&op->children[i], space, size, mach, pfile, atoms))
return 0;
return 1;
}
/* _slang_locate_function() */
-slang_function *_slang_locate_function (const char *name, slang_operation *params,
- unsigned int num_params, slang_assembly_name_space *space)
+slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,
+ slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,
+ slang_atom_pool *atoms)
{
unsigned int i;
- for (i = 0; i < space->funcs->num_functions; i++)
+ for (i = 0; i < funcs->num_functions; i++)
{
unsigned int j;
- slang_function *f = space->funcs->functions + i;
+ slang_function *f = &funcs->functions[i];
- if (slang_string_compare (name, f->header.name) != 0)
+ if (a_name != f->header.a_name)
continue;
if (f->param_count != num_params)
continue;
for (j = 0; j < num_params; j++)
{
slang_assembly_typeinfo ti;
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (params + j, space, &ti))
+
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
+ if (!_slang_typeof_operation (¶ms[j], space, &ti, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
@@ -201,28 +251,25 @@ slang_function *_slang_locate_function (const char *name, slang_operation *param break;
}
slang_assembly_typeinfo_destruct (&ti);
+
/* "out" and "inout" formal parameter requires the actual parameter to be l-value */
if (!ti.can_be_referenced &&
- (f->parameters->variables[j].type.qualifier == slang_qual_out ||
- f->parameters->variables[j].type.qualifier == slang_qual_inout))
+ (f->parameters->variables[j].type.qualifier == slang_qual_out ||
+ f->parameters->variables[j].type.qualifier == slang_qual_inout))
break;
}
if (j == num_params)
return f;
}
- if (space->funcs->outer_scope != NULL)
- {
- slang_assembly_name_space my_space = *space;
- my_space.funcs = space->funcs->outer_scope;
- return _slang_locate_function (name, params, num_params, &my_space);
- }
+ if (funcs->outer_scope != NULL)
+ return _slang_locate_function (funcs->outer_scope, a_name, params, num_params, space, atoms);
return NULL;
}
/* _slang_assemble_function() */
int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
- slang_assembly_name_space *space)
+ slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)
{
unsigned int param_size, local_size;
unsigned int skip, cleanup;
@@ -238,97 +285,106 @@ int _slang_assemble_function (slang_assembly_file *file, slang_function *fun, return 1;
}
- /* calculate return value and parameters size */
+ /* At this point traverse function formal parameters and code to calculate
+ * total memory size to be allocated on the stack.
+ * During this process the variables will be assigned local addresses to
+ * reference them in the code.
+ * No storage optimizations are performed so exclusive scopes are not detected and shared. */
+
+ /* calculate return value size */
param_size = 0;
if (fun->header.type.specifier.type != slang_spec_void)
if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
- ¶m_size))
+ ¶m_size, mach, file, atoms))
return 0;
info.ret_size = param_size;
- if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, ¶m_size))
+
+ /* calculate formal parameter list size */
+ if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, ¶m_size, mach, file,
+ atoms))
return 0;
- /* calculate local variables size, take into account the four-byte return address and
- temporaries for various tasks */
+ /* calculate local variables size - take into account the four-byte return address and
+ * temporaries for various tasks (4 for addr and 16 for swizzle temporaries).
+ * these include variables from the formal parameter scope and from the code */
info.addr_tmp = param_size + 4;
info.swizzle_tmp = param_size + 4 + 4;
local_size = param_size + 4 + 4 + 16;
if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,
- &local_size))
+ &local_size, mach, file, atoms))
return 0;
- if (!collect_locals (fun->body, space, &local_size))
+ if (!collect_locals (fun->body, space, &local_size, mach, file, atoms))
return 0;
/* allocate local variable storage */
- if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, local_size - param_size - 4))
+ if (!PLAB (file, slang_asm_local_alloc, local_size - param_size - 4))
return 0;
/* mark a new frame for function variable storage */
- if (!slang_assembly_file_push_label (file, slang_asm_enter, local_size))
+ if (!PLAB (file, slang_asm_enter, local_size))
return 0;
- /* skip the cleanup jump */
+ /* jump directly to the actual code */
skip = file->count;
- if (!slang_assembly_file_push_new (file))
+ if (!push_new (file))
return 0;
file->code[skip].type = slang_asm_jump;
/* all "return" statements will be directed here */
flow.function_end = file->count;
cleanup = file->count;
- if (!slang_assembly_file_push_new (file))
+ if (!push_new (file))
return 0;
file->code[cleanup].type = slang_asm_jump;
/* execute the function body */
file->code[skip].param[0] = file->count;
- if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk))
+ if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk, mach, atoms))
return 0;
/* this is the end of the function - restore the old function frame */
file->code[cleanup].param[0] = file->count;
- if (!slang_assembly_file_push (file, slang_asm_leave))
+ if (!PUSH (file, slang_asm_leave))
return 0;
/* free local variable storage */
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, local_size - param_size - 4))
+ if (!PLAB (file, slang_asm_local_free, local_size - param_size - 4))
return 0;
- /* jump out of the function */
- if (!slang_assembly_file_push (file, slang_asm_return))
+ /* return from the function */
+ if (!PUSH (file, slang_asm_return))
return 0;
return 1;
}
int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,
- slang_assembly_name_space *space)
+ slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)
{
slang_assembly_typeinfo ti;
- unsigned int size;
+ unsigned int size = 0;
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (op, space, &ti))
+ /* get type info of the operation and calculate its size */
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
+ if (!_slang_typeof_operation (op, space, &ti, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- if (ti.spec.type == slang_spec_void)
- size = 0;
- else if (ref)
+ if (ref)
size = 4;
- else
- {
- size = 0;
- if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size))
+ else if (ti.spec.type != slang_spec_void)
+ if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size, mach, file, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- }
slang_assembly_typeinfo_destruct (&ti);
+
+ /* if nonzero, free it from the stack */
if (size != 0)
{
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, size))
+ if (!PLAB (file, slang_asm_local_free, size))
return 0;
}
return 1;
@@ -336,103 +392,133 @@ int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int re /* _slang_assemble_operation() */
-/* XXX: general swizzle! */
static int dereference_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
- unsigned int index, unsigned int *size, slang_assembly_local_info *info)
+ unsigned int *size, slang_assembly_local_info *info, slang_swizzle *swz, int is_swizzled)
{
unsigned int i;
for (i = agg->count; i > 0; i--)
{
- const slang_storage_array *arr = agg->arrays + i - 1;
+ const slang_storage_array *arr = &agg->arrays[i - 1];
unsigned int j;
for (j = arr->length; j > 0; j--)
{
if (arr->type == slang_stor_aggregate)
{
- if (!dereference_aggregate (file, arr->aggregate, index, size, info))
+ if (!dereference_aggregate (file, arr->aggregate, size, info, swz, is_swizzled))
return 0;
}
else
{
+ unsigned int src_offset;
+ slang_assembly_type ty;
+
*size -= 4;
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
- 4))
+
+ /* calculate the offset within source variable to read */
+ if (is_swizzled)
+ {
+ /* swizzle the index to get the actual offset */
+ src_offset = swz->swizzle[*size / 4] * 4;
+ }
+ else
+ {
+ /* no swizzling - read sequentially */
+ src_offset = *size;
+ }
+
+ /* dereference data slot of a basic type */
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_deref))
+ if (!PUSH (file, slang_asm_addr_deref))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_addr_push, *size))
+ if (!PLAB (file, slang_asm_addr_push, src_offset))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_add))
+ if (!PUSH (file, slang_asm_addr_add))
return 0;
+
switch (arr->type)
{
case slang_stor_bool:
- if (!slang_assembly_file_push (file, slang_asm_bool_deref))
- return 0;
+ ty = slang_asm_bool_deref;
break;
case slang_stor_int:
- if (!slang_assembly_file_push (file, slang_asm_int_deref))
- return 0;
+ ty = slang_asm_int_deref;
break;
case slang_stor_float:
- if (!slang_assembly_file_push (file, slang_asm_float_deref))
- return 0;
+ ty = slang_asm_float_deref;
break;
}
- index += 4;
+ if (!PUSH (file, ty))
+ return 0;
}
}
}
return 1;
}
-/* XXX: general swizzle! */
-int dereference (slang_assembly_file *file, slang_operation *op,
- slang_assembly_name_space *space, slang_assembly_local_info *info)
+
+int _slang_dereference (slang_assembly_file *file, slang_operation *op,
+ slang_assembly_name_space *space, slang_assembly_local_info *info, slang_machine *mach,
+ slang_atom_pool *atoms)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int size;
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (op, space, &ti))
+ /* get type information of the given operation */
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
+ if (!_slang_typeof_operation (op, space, &ti, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- slang_storage_aggregate_construct (&agg);
- if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs, space->vars))
+ /* construct aggregate from the type info */
+ if (!slang_storage_aggregate_construct (&agg))
+ {
+ slang_assembly_typeinfo_destruct (&ti);
+ return 0;
+ }
+ if (!_slang_aggregate_variable (&agg, &ti.spec, ti.array_size, space->funcs, space->structs,
+ space->vars, mach, file, atoms))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
+ /* dereference the resulting aggregate */
size = _slang_sizeof_aggregate (&agg);
- result = dereference_aggregate (file, &agg, 0, &size, info);
+ result = dereference_aggregate (file, &agg, &size, info, &ti.swz, ti.is_swizzled);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
-static int call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,
+int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
unsigned int i;
- slang_assembly_stack_info stk;
+ slang_assembly_stack_info p_stk[64];
+
+ /* TODO: fix this, allocate dynamically */
+ if (param_count > 64)
+ return 0;
/* make room for the return value, if any */
if (fun->header.type.specifier.type != slang_spec_void)
{
unsigned int ret_size = 0;
- if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, &ret_size))
+
+ if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
+ &ret_size, mach, file, atoms))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size))
+ if (!PLAB (file, slang_asm_local_alloc, ret_size))
return 0;
}
@@ -444,56 +530,59 @@ static int call_function (slang_assembly_file *file, slang_function *fun, slang_ if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
fun->parameters->variables[i].type.qualifier == slang_qual_out)
{
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
/* TODO: optimize the "out" parameter case */
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, params + i, 1, &flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, ¶ms[i], 1, &flow, space, info, &p_stk[i],
+ mach, atoms))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_copy))
+ if (!PUSH (file, slang_asm_addr_copy))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_deref))
+ if (!PUSH (file, slang_asm_addr_deref))
return 0;
if (i == 0 && assignment)
{
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
- 4))
+ /* duplicate the resulting address */
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_deref))
+ if (!PUSH (file, slang_asm_addr_deref))
return 0;
}
- if (!dereference (file, params, space, info))
+ if (!_slang_dereference (file, ¶ms[i], space, info, mach, atoms))
return 0;
}
else
{
- /* TODO: for "out" and "inout" parameters also push the address (first) */
- /* TODO: optimize the "out" parameter case */
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, params + i, 0, &flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, ¶ms[i], 0, &flow, space, info, &p_stk[i],
+ mach, atoms))
return 0;
}
}
/* call the function */
- if (!slang_assembly_file_push_label (file, slang_asm_call, fun->address))
+ if (!PLAB (file, slang_asm_call, fun->address))
return 0;
/* pop the parameters from the stack */
for (i = param_count; i > 0; i--)
{
unsigned int j = i - 1;
+
if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
fun->parameters->variables[j].type.qualifier == slang_qual_out)
{
- if (!_slang_assemble_assignment (file, params + j, space, info))
+ /* for output parameter copy the contents of the formal parameter
+ * back to the original actual parameter */
+ if (!_slang_assemble_assignment (file, ¶ms[j], space, info, &p_stk[j], mach, atoms))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
+ /* pop the actual parameter's address */
+ if (!PLAB (file, slang_asm_local_free, 4))
return 0;
}
else
{
- if (!_slang_cleanup_stack (file, params + j, 0, space))
+ /* pop the value of the parameter */
+ if (!_slang_cleanup_stack (file, ¶ms[j], 0, space, mach, atoms))
return 0;
}
}
@@ -501,73 +590,94 @@ static int call_function (slang_assembly_file *file, slang_function *fun, slang_ return 1;
}
+/* TODO: migrate to full-atom version */
int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
- slang_function *fun = _slang_locate_function (name, params, param_count, space);
+ slang_atom atom;
+ slang_function *fun;
+
+ atom = slang_atom_pool_atom (atoms, name);
+ if (atom == SLANG_ATOM_NULL)
+ return 0;
+ fun = _slang_locate_function (space->funcs, atom, params, param_count, space, atoms);
if (fun == NULL)
return 0;
- return call_function (file, fun, params, param_count, assignment, space, info);
+ return _slang_call_function (file, fun, params, param_count, assignment, space, info, mach,
+ atoms);
}
static int call_function_name_dummyint (slang_assembly_file *file, const char *name,
- slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info)
+ slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info,
+ slang_machine *mach, slang_atom_pool *atoms)
{
- slang_operation p2[2];
+ slang_operation p[2];
int result;
- p2[0] = *params;
- if (!slang_operation_construct (p2 + 1))
+ p[0] = params[0];
+ if (!slang_operation_construct (&p[1]))
return 0;
- p2[1].type = slang_oper_literal_int;
- result = call_function_name (file, name, p2, 2, 0, space, info);
- slang_operation_destruct (p2 + 1);
+ p[1].type = slang_oper_literal_int;
+ result = call_function_name (file, name, p, 2, 0, space, info, mach, atoms);
+ slang_operation_destruct (&p[1]);
return result;
}
-static int call_asm_instruction (slang_assembly_file *file, const char *name)
+static const struct
{
- const struct
- {
- const char *name;
- slang_assembly_type code1, code2;
- } inst[] = {
- { "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
- { "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
- { "float_copy", slang_asm_float_copy, slang_asm_none },
- { "int_copy", slang_asm_int_copy, slang_asm_none },
- { "bool_copy", slang_asm_bool_copy, slang_asm_none },
- { "float_add", slang_asm_float_add, slang_asm_float_copy },
- { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
- { "float_divide", slang_asm_float_divide, slang_asm_float_copy },
- { "float_negate", slang_asm_float_negate, slang_asm_float_copy },
- { "float_less", slang_asm_float_less, slang_asm_bool_copy },
- { "float_equal", slang_asm_float_equal, slang_asm_bool_copy },
- { NULL, slang_asm_none, slang_asm_none }
- };
+ const char *name;
+ slang_assembly_type code1, code2;
+} inst[] = {
+ /* core */
+ { "float_add", slang_asm_float_add, slang_asm_float_copy },
+ { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
+ { "float_divide", slang_asm_float_divide, slang_asm_float_copy },
+ { "float_negate", slang_asm_float_negate, slang_asm_float_copy },
+ { "float_less", slang_asm_float_less, slang_asm_bool_copy },
+ { "float_equal", slang_asm_float_equal_exp,slang_asm_bool_copy },
+ { "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
+ { "float_sine", slang_asm_float_sine, slang_asm_float_copy },
+ { "float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy },
+ { "float_arctan", slang_asm_float_arctan, slang_asm_float_copy },
+ { "float_power", slang_asm_float_power, slang_asm_float_copy },
+ { "float_log2", slang_asm_float_log2, slang_asm_float_copy },
+ { "float_floor", slang_asm_float_floor, slang_asm_float_copy },
+ { "float_ceil", slang_asm_float_ceil, slang_asm_float_copy },
+ { "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
+ /* mesa-specific extensions */
+ { "float_print", slang_asm_float_deref, slang_asm_float_print },
+ { "int_print", slang_asm_int_deref, slang_asm_int_print },
+ { "bool_print", slang_asm_bool_deref, slang_asm_bool_print },
+ { NULL, slang_asm_none, slang_asm_none }
+};
+
+static int call_asm_instruction (slang_assembly_file *file, slang_atom a_name, slang_atom_pool *atoms)
+{
+ const char *id;
unsigned int i;
+ id = slang_atom_pool_id (atoms, a_name);
+
for (i = 0; inst[i].name != NULL; i++)
- if (slang_string_compare (name, inst[i].name) == 0)
+ if (slang_string_compare (id, inst[i].name) == 0)
break;
if (inst[i].name == NULL)
return 0;
- if (!slang_assembly_file_push_label2 (file, inst[i].code1, 4, 0))
+ if (!PLAB2 (file, inst[i].code1, 4, 0))
return 0;
if (inst[i].code2 != slang_asm_none)
- if (!slang_assembly_file_push_label2 (file, inst[i].code2, 4, 0))
+ if (!PLAB2 (file, inst[i].code2, 4, 0))
return 0;
/* clean-up the stack from the remaining dst address */
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
+ if (!PLAB (file, slang_asm_local_free, 4))
return 0;
return 1;
}
-/* XXX: general swizzle! */
static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label)
{
@@ -575,7 +685,7 @@ static int equality_aggregate (slang_assembly_file *file, const slang_storage_ag for (i = 0; i < agg->count; i++)
{
- const slang_storage_array *arr = agg->arrays + i;
+ const slang_storage_array *arr = &agg->arrays[i];
unsigned int j;
for (j = 0; j < arr->length; j++)
@@ -587,39 +697,38 @@ static int equality_aggregate (slang_assembly_file *file, const slang_storage_ag }
else
{
- if (!slang_assembly_file_push_label2 (file, slang_asm_float_equal, size + *index,
- *index))
+ if (!PLAB2 (file, slang_asm_float_equal_int, size + *index, *index))
return 0;
*index += 4;
- if (!slang_assembly_file_push_label (file, slang_asm_jump_if_zero, z_label))
+ if (!PLAB (file, slang_asm_jump_if_zero, z_label))
return 0;
}
}
}
return 1;
}
-/* XXX: general swizzle! */
+
static int equality (slang_assembly_file *file, slang_operation *op,
- slang_assembly_name_space *space, slang_assembly_local_info *info, int equal)
+ slang_assembly_name_space *space, slang_assembly_local_info *info, int equal,
+ slang_machine *mach, slang_atom_pool *atoms)
{
slang_assembly_typeinfo ti;
- int result;
+ int result = 0;
slang_storage_aggregate agg;
unsigned int index, size;
unsigned int skip_jump, true_label, true_jump, false_label, false_jump;
/* get type of operation */
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (op, space, &ti))
- {
- slang_assembly_typeinfo_destruct (&ti);
+ if (!slang_assembly_typeinfo_construct (&ti))
return 0;
- }
+ if (!_slang_typeof_operation (op, space, &ti, atoms))
+ goto end1;
/* convert it to an aggregate */
- slang_storage_aggregate_construct (&agg);
- if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
- space->vars)))
+ if (!slang_storage_aggregate_construct (&agg))
+ goto end1;
+ if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
+ space->vars, mach, file, atoms))
goto end;
/* compute the size of the agregate - there are two such aggregates on the stack */
@@ -627,37 +736,35 @@ static int equality (slang_assembly_file *file, slang_operation *op, /* jump to the actual data-comparison code */
skip_jump = file->count;
- if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
+ if (!PUSH (file, slang_asm_jump))
goto end;
/* pop off the stack the compared data and push 1 */
true_label = file->count;
- if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
+ if (!PLAB (file, slang_asm_local_free, size * 2))
goto end;
- if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f)))
+ if (!PLIT (file, slang_asm_bool_push, (GLfloat) 1))
goto end;
true_jump = file->count;
- if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
+ if (!PUSH (file, slang_asm_jump))
goto end;
false_label = file->count;
- if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
+ if (!PLAB (file, slang_asm_local_free, size * 2))
goto end;
- if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 0.0f)))
+ if (!PLIT (file, slang_asm_bool_push, (GLfloat) 0))
goto end;
false_jump = file->count;
- if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
+ if (!PUSH (file, slang_asm_jump))
goto end;
file->code[skip_jump].param[0] = file->count;
/* compare the data on stack, it will eventually jump either to true or false label */
index = 0;
- if (!(result = equality_aggregate (file, &agg, &index, size, info,
- equal ? false_label : true_label)))
+ if (!equality_aggregate (file, &agg, &index, size, info, equal ? false_label : true_label))
goto end;
- if (!(result = slang_assembly_file_push_label (file, slang_asm_jump,
- equal ? true_label : false_label)))
+ if (!PLAB (file, slang_asm_jump, equal ? true_label : false_label))
goto end;
file->code[true_jump].param[0] = file->count;
@@ -666,20 +773,245 @@ static int equality (slang_assembly_file *file, slang_operation *op, result = 1;
end:
slang_storage_aggregate_destruct (&agg);
+end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
+static int handle_subscript (slang_assembly_typeinfo *tie, slang_assembly_typeinfo *tia,
+ slang_assembly_file *file, slang_operation *op, int reference, slang_assembly_flow_control *flow,
+ slang_assembly_name_space *space, slang_assembly_local_info *info, slang_machine *mach,
+ slang_atom_pool *atoms)
+{
+ unsigned int asize = 0, esize = 0;
+ slang_assembly_stack_info _stk;
+
+ /* get type info of the master expression (matrix, vector or an array */
+ if (!_slang_typeof_operation (&op->children[0], space, tia, atoms))
+ return 0;
+ if (!sizeof_variable (&tia->spec, slang_qual_none, tia->array_size, space, &asize, mach, file,
+ atoms))
+ return 0;
+
+ /* get type info of the result (matrix column, vector row or array element) */
+ if (!_slang_typeof_operation (op, space, tie, atoms))
+ return 0;
+ if (!sizeof_variable (&tie->spec, slang_qual_none, NULL, space, &esize, mach, file, atoms))
+ return 0;
+
+ /* assemble the master expression */
+ if (!_slang_assemble_operation (file, &op->children[0], reference, flow, space, info, &_stk,
+ mach, atoms))
+ return 0;
+ /* ignre the _stk */
+
+ /* when indexing an l-value swizzle, push the swizzle_tmp */
+ if (reference && tia->is_swizzled)
+ {
+ if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
+ return 0;
+ }
+
+ /* assemble the subscript expression */
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &_stk, mach, atoms))
+ return 0;
+ /* ignore the _stk */
+
+ if (reference && tia->is_swizzled)
+ {
+ unsigned int i;
+
+ /* copy the swizzle indexes to the swizzle_tmp */
+ for (i = 0; i < tia->swz.num_components; i++)
+ {
+ if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
+ return 0;
+ if (!PLAB (file, slang_asm_addr_push, i * 4))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[i]))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_copy))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+ }
+
+ /* offset the pushed swizzle_tmp address and dereference it */
+ if (!PUSH (file, slang_asm_int_to_addr))
+ return 0;
+ if (!PLAB (file, slang_asm_addr_push, 4))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_multiply))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_deref))
+ return 0;
+ }
+ else
+ {
+ /* convert the integer subscript to a relative address */
+ if (!PUSH (file, slang_asm_int_to_addr))
+ return 0;
+ }
+
+ if (!PLAB (file, slang_asm_addr_push, esize))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_multiply))
+ return 0;
+
+ if (reference)
+ {
+ /* offset the base address with the relative address */
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ }
+ else
+ {
+ unsigned int i;
+
+ /* move the selected element to the beginning of the master expression */
+ for (i = 0; i < esize; i += 4)
+ if (!PLAB2 (file, slang_asm_float_move, asize - esize + i + 4, i + 4))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+
+ /* free the rest of the master expression */
+ if (!PLAB (file, slang_asm_local_free, asize - esize))
+ return 0;
+ }
+ return 1;
+}
+
+static int handle_field (slang_assembly_typeinfo *tia, slang_assembly_typeinfo *tib,
+ slang_assembly_file *file, slang_operation *op, int reference, slang_assembly_flow_control *flow,
+ slang_assembly_name_space *space, slang_assembly_local_info *info, slang_assembly_stack_info *stk,
+ slang_machine *mach, slang_atom_pool *atoms)
+{
+ slang_assembly_stack_info _stk;
+
+ /* get type info of the result (field or swizzle) */
+ if (!_slang_typeof_operation (op, space, tia, atoms))
+ return 0;
+
+ /* get type info of the master expression being accessed (struct or vector) */
+ if (!_slang_typeof_operation (&op->children[0], space, tib, atoms))
+ return 0;
+
+ /* if swizzling a vector in-place, the swizzle temporary is needed */
+ if (!reference && tia->is_swizzled)
+ if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
+ return 0;
+
+ /* assemble the master expression */
+ if (!_slang_assemble_operation (file, &op->children[0], reference, flow, space, info, &_stk,
+ mach, atoms))
+ return 0;
+ /* ignore _stk.swizzle - we'll have it in tia->swz */
+
+ /* assemble the field expression */
+ if (tia->is_swizzled)
+ {
+ if (reference)
+ {
+ /*if (tia->swz.num_components == 1)
+ {
+ /* simple case - adjust the vector's address to point to the selected component */
+ /* if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ }
+ else*/
+ {
+ /* two or more vector components are being referenced - the so-called write mask
+ * must be passed to the upper operations and applied when assigning value
+ * to this swizzle */
+ stk->swizzle = tia->swz;
+ }
+ }
+ else
+ {
+ /* swizzle the vector in-place using the swizzle temporary */
+ if (!_slang_assemble_constructor_from_swizzle (file, &tia->swz, &tia->spec, &tib->spec,
+ info))
+ return 0;
+ }
+ }
+ else
+ {
+ GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
+
+ for (i = 0; i < tib->spec._struct->fields->num_variables; i++)
+ {
+ slang_variable *field;
+ slang_storage_aggregate agg;
+ GLuint size;
+
+ field = &tib->spec._struct->fields->variables[i];
+ if (!slang_storage_aggregate_construct (&agg))
+ return 0;
+ if (!_slang_aggregate_variable (&agg, &field->type.specifier, field->array_size,
+ space->funcs, space->structs, space->vars, mach, file, atoms))
+ {
+ slang_storage_aggregate_destruct (&agg);
+ return 0;
+ }
+ size = _slang_sizeof_aggregate (&agg);
+ slang_storage_aggregate_destruct (&agg);
+
+ if (op->a_id == field->a_name)
+ {
+ field_size = size;
+ struct_size = field_offset + size;
+ }
+ else if (struct_size != 0)
+ struct_size += size;
+ else
+ field_offset += size;
+ }
+
+ if (!PLAB (file, slang_asm_addr_push, field_offset))
+ return 0;
+
+ if (reference)
+ {
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ }
+ else
+ {
+ unsigned int i;
+
+ /* move the selected element to the beginning of the master expression */
+ for (i = 0; i < field_size; i += 4)
+ if (!PLAB2 (file, slang_asm_float_move, struct_size - field_size + i + 4, i + 4))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+
+ /* free the rest of the master expression */
+ if (!PLAB (file, slang_asm_local_free, struct_size - field_size))
+ return 0;
+ }
+ }
+ return 1;
+}
+
int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info, slang_assembly_stack_info *stk)
+ slang_assembly_local_info *info, slang_assembly_stack_info *stk, slang_machine *mach,
+ slang_atom_pool *atoms)
{
unsigned int assem;
- stk->swizzle_mask = 0;
+ stk->swizzle.num_components = 0;
assem = file->count;
- if (!slang_assembly_file_push_new (file))
+ if (!push_new (file))
return 0;
switch (op->type)
@@ -688,13 +1020,16 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i case slang_oper_block_new_scope:
{
unsigned int i;
+
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children + i, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[i], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children + i, 0, space))
+ /* ignore the stk */
+ if (!_slang_cleanup_stack (file, &op->children[i], 0, space, mach, atoms))
return 0;
}
}
@@ -713,15 +1048,17 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i case slang_oper_asm:
{
unsigned int i;
+
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children + i, i == 0, flow, space, info,
- &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[i], i == 0, flow, space, info,
+ &stk, mach, atoms))
return 0;
- /* TODO: inspect stk */
+ /* __asm statement does not support any swizzles, so lets ignore stk for now */
}
- if (!call_asm_instruction (file, op->identifier))
+ if (!call_asm_instruction (file, op->a_id, atoms))
return 0;
}
break;
@@ -735,48 +1072,57 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i break;
case slang_oper_discard:
file->code[assem].type = slang_asm_discard;
- if (!slang_assembly_file_push (file, slang_asm_exit))
+ if (!PUSH (file, slang_asm_exit))
return 0;
break;
case slang_oper_return:
if (info->ret_size != 0)
{
slang_assembly_stack_info stk;
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, 0, info->ret_size))
+
+ /* push the result's address */
+ if (!PLAB2 (file, slang_asm_local_addr, 0, info->ret_size))
return 0;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!_slang_assemble_assignment (file, op->children, space, info))
+
+ /* ignore the stk from latest operation, reset swizzle to 0 for the assignment */
+ stk.swizzle.num_components = 0;
+ /* assign the operation to the function result (it was reserved on the stack) */
+ if (!_slang_assemble_assignment (file, op->children, space, info, &stk, mach, atoms))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
+
+ if (!PLAB (file, slang_asm_local_free, 4))
return 0;
}
- if (!slang_assembly_file_push_label (file, slang_asm_jump, flow->function_end))
+ if (!PLAB (file, slang_asm_jump, flow->function_end))
return 0;
break;
case slang_oper_expression:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, &stk))
+
+ assert (!reference);
+ if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk, mach, atoms))
return 0;
- /* TODO: inspect stk */
+ /* ignore the stk info */
}
break;
case slang_oper_if:
- if (!_slang_assemble_if (file, op, flow, space, info))
+ if (!_slang_assemble_if (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_while:
- if (!_slang_assemble_while (file, op, flow, space, info))
+ if (!_slang_assemble_while (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_do:
- if (!_slang_assemble_do (file, op, flow, space, info))
+ if (!_slang_assemble_do (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_for:
- if (!_slang_assemble_for (file, op, flow, space, info))
+ if (!_slang_assemble_for (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_void:
@@ -797,69 +1143,75 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i {
slang_variable *var;
unsigned int size;
- var = _slang_locate_variable (op->locals, op->identifier, 1);
+
+ /* find the variable and calculate its size */
+ var = _slang_locate_variable (op->locals, op->a_id, 1);
if (var == NULL)
return 0;
size = 0;
if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,
- &size))
+ &size, mach, file, atoms))
return 0;
- if (var->initializer != NULL)
+
+ /* prepare stack for dereferencing */
+ if (!reference)
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ return 0;
+
+ /* push the variable's address */
+ if (var->global)
{
- assert (!"var->initializer, oper_identifier");
+ if (!PLAB (file, slang_asm_addr_push, var->address))
+ return 0;
}
else
{
- if (!reference)
- {
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
- info->addr_tmp, 4))
- return 0;
- }
- /* XXX: globals! */
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,
- size))
+ if (!PLAB2 (file, slang_asm_local_addr, var->address, size))
+ return 0;
+ }
+
+ /* perform the dereference */
+ if (!reference)
+ {
+ if (!PUSH (file, slang_asm_addr_copy))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+ if (!_slang_dereference (file, op, space, info, mach, atoms))
return 0;
- if (!reference)
- {
- if (!slang_assembly_file_push (file, slang_asm_addr_copy))
- return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
- return 0;
- if (!dereference (file, op, space, info))
- return 0;
- }
}
}
break;
case slang_oper_sequence:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))
return 0;
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,
- &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info,
+ &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
}
break;
case slang_oper_assign:
- if (!_slang_assemble_assign (file, op, "=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_addassign:
- if (!_slang_assemble_assign (file, op, "+=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "+=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_subassign:
- if (!_slang_assemble_assign (file, op, "-=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "-=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_mulassign:
- if (!_slang_assemble_assign (file, op, "*=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "*=", reference, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_modassign:*/
@@ -869,214 +1221,149 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i /*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_divassign:
- if (!_slang_assemble_assign (file, op, "/=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "/=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_select:
- if (!_slang_assemble_select (file, op, flow, space, info))
+ if (!_slang_assemble_select (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_logicalor:
- if (!_slang_assemble_logicalor (file, op, flow, space, info))
+ if (!_slang_assemble_logicalor (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_logicaland:
- if (!_slang_assemble_logicaland (file, op, flow, space, info))
+ if (!_slang_assemble_logicaland (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_logicalxor:
- if (!call_function_name (file, "^^", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "^^", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
case slang_oper_less:
- if (!call_function_name (file, "<", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "<", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_greater:
- if (!call_function_name (file, ">", op->children, 2, 0, space, info))
+ if (!call_function_name (file, ">", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_lessequal:
- if (!call_function_name (file, "<=", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "<=", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_greaterequal:
- if (!call_function_name (file, ">=", op->children, 2, 0, space, info))
+ if (!call_function_name (file, ">=", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
- if (!call_function_name (file, "+", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "+", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_subtract:
- if (!call_function_name (file, "-", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "-", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_multiply:
- if (!call_function_name (file, "*", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "*", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_modulus:*/
case slang_oper_divide:
- if (!call_function_name (file, "/", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "/", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_equal:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!equality (file, op->children, space, info, 1))
+ if (!equality (file, op->children, space, info, 1, mach, atoms))
return 0;
}
break;
case slang_oper_notequal:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!equality (file, op->children, space, info, 0))
+ if (!equality (file, op->children, space, info, 0, mach, atoms))
return 0;
}
break;
case slang_oper_preincrement:
- if (!_slang_assemble_assign (file, op, "++", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "++", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_predecrement:
- if (!_slang_assemble_assign (file, op, "--", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "--", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_plus:
- if (!call_function_name (file, "+", op->children, 1, 0, space, info))
+ if (!_slang_dereference (file, op, space, info, mach, atoms))
return 0;
break;
case slang_oper_minus:
- if (!call_function_name (file, "-", op->children, 1, 0, space, info))
+ if (!call_function_name (file, "-", op->children, 1, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_complement:*/
case slang_oper_not:
- if (!call_function_name (file, "!", op->children, 1, 0, space, info))
+ if (!call_function_name (file, "!", op->children, 1, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_subscript:
{
- slang_assembly_stack_info _stk;
slang_assembly_typeinfo ti_arr, ti_elem;
- unsigned int arr_size = 0, elem_size = 0;
- if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
- &_stk))
- return 0;
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))
- return 0;
- slang_assembly_typeinfo_construct (&ti_arr);
- if (!_slang_typeof_operation (op->children, space, &ti_arr))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- return 0;
- }
- if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- return 0;
- }
- slang_assembly_typeinfo_construct (&ti_elem);
- if (!_slang_typeof_operation (op, space, &ti_elem))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- if (!slang_assembly_file_push (file, slang_asm_int_to_addr))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
+
+ if (!slang_assembly_typeinfo_construct (&ti_arr))
return 0;
- }
- if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))
+ if (!slang_assembly_typeinfo_construct (&ti_elem))
{
slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
- if (!slang_assembly_file_push (file, slang_asm_addr_multiply))
+ if (!handle_subscript (&ti_elem, &ti_arr, file, op, reference, flow, space, info,
+ mach, atoms))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
- if (reference)
- {
- if (!slang_assembly_file_push (file, slang_asm_addr_add))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- }
- else
- {
- unsigned int i;
- for (i = 0; i < elem_size; i += 4)
- {
- if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,
- arr_size - elem_size + i + 4, i + 4))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- }
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- if (!slang_assembly_file_push_label (file, slang_asm_local_free,
- arr_size - elem_size))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- }
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
}
break;
case slang_oper_call:
{
- slang_function *fun = _slang_locate_function (op->identifier, op->children,
- op->num_children, space);
+ slang_function *fun;
+
+ fun = _slang_locate_function (space->funcs, op->a_id, op->children, op->num_children,
+ space, atoms);
if (fun == NULL)
{
- if (!_slang_assemble_constructor (file, op, flow, space, info))
- return 0;
+/* if (!_slang_assemble_constructor (file, op, flow, space, info, mach))
+*/ return 0;
}
else
{
- if (!call_function (file, fun, op->children, op->num_children, 0, space, info))
+ if (!_slang_call_function (file, fun, op->children, op->num_children, 0, space,
+ info, mach, atoms))
return 0;
}
}
@@ -1084,101 +1371,31 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i case slang_oper_field:
{
slang_assembly_typeinfo ti_after, ti_before;
- slang_assembly_stack_info _stk;
- slang_assembly_typeinfo_construct (&ti_after);
- if (!_slang_typeof_operation (op, space, &ti_after))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
+
+ if (!slang_assembly_typeinfo_construct (&ti_after))
return 0;
- }
- slang_assembly_typeinfo_construct (&ti_before);
- if (!_slang_typeof_operation (op->children, space, &ti_before))
+ if (!slang_assembly_typeinfo_construct (&ti_before))
{
slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
- if (!reference && ti_after.is_swizzled)
- {
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
- info->swizzle_tmp, 16))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- }
- if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
- &_stk))
+ if (!handle_field (&ti_after, &ti_before, file, op, reference, flow, space, info, stk,
+ mach, atoms))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
- /* TODO: inspect stk */
- if (ti_after.is_swizzled)
- {
- if (reference)
- {
- if (ti_after.swz.num_components == 1)
- {
- if (!slang_assembly_file_push_label (file, slang_asm_addr_push,
- ti_after.swz.swizzle[0] * 4))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- if (!slang_assembly_file_push (file, slang_asm_addr_add))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- }
- else
- {
- unsigned int i;
- for (i = 0; i < ti_after.swz.num_components; i++)
- stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];
- }
- }
- else
- {
- if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,
- &ti_after.spec, &ti_before.spec, info))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- }
- }
- else
- {
- if (reference)
- {
- /* TODO: struct field address */
- }
- else
- {
- /* TODO: struct field value */
- }
- }
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
}
break;
case slang_oper_postincrement:
- if (!call_function_name_dummyint (file, "++", op->children, space, info))
- return 0;
- if (!dereference (file, op, space, info))
+ if (!call_function_name_dummyint (file, "++", op->children, space, info, mach, atoms))
return 0;
break;
case slang_oper_postdecrement:
- if (!call_function_name_dummyint (file, "--", op->children, space, info))
- return 0;
- if (!dereference (file, op, space, info))
+ if (!call_function_name_dummyint (file, "--", op->children, space, info, mach, atoms))
return 0;
break;
default:
diff --git a/src/mesa/shader/slang/slang_assemble.h b/src/mesa/shader/slang/slang_assemble.h index d93755c7e7b..c3af8d8fed8 100644 --- a/src/mesa/shader/slang/slang_assemble.h +++ b/src/mesa/shader/slang/slang_assemble.h @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -44,8 +44,16 @@ typedef enum slang_assembly_type_ slang_asm_float_divide,
slang_asm_float_negate,
slang_asm_float_less,
- slang_asm_float_equal,
+ slang_asm_float_equal_exp,
+ slang_asm_float_equal_int,
slang_asm_float_to_int,
+ slang_asm_float_sine,
+ slang_asm_float_arcsine,
+ slang_asm_float_arctan,
+ slang_asm_float_power,
+ slang_asm_float_log2,
+ slang_asm_float_floor,
+ slang_asm_float_ceil,
slang_asm_int_copy,
slang_asm_int_move,
slang_asm_int_push,
@@ -72,6 +80,10 @@ typedef enum slang_assembly_type_ slang_asm_return,
slang_asm_discard,
slang_asm_exit,
+ /* mesa-specific extensions */
+ slang_asm_float_print,
+ slang_asm_int_print,
+ slang_asm_bool_print,
slang_asm__last
} slang_assembly_type;
@@ -86,15 +98,26 @@ typedef struct slang_assembly_file_ {
slang_assembly *code;
unsigned int count;
+ unsigned int capacity;
} slang_assembly_file;
-void slang_assembly_file_construct (slang_assembly_file *);
+int slang_assembly_file_construct (slang_assembly_file *);
void slang_assembly_file_destruct (slang_assembly_file *);
int slang_assembly_file_push (slang_assembly_file *, slang_assembly_type);
int slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint);
int slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint);
int slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat);
+typedef struct slang_assembly_file_restore_point_
+{
+ unsigned int count;
+} slang_assembly_file_restore_point;
+
+int slang_assembly_file_restore_point_save (slang_assembly_file *,
+ slang_assembly_file_restore_point *);
+int slang_assembly_file_restore_point_load (slang_assembly_file *,
+ slang_assembly_file_restore_point *);
+
typedef struct slang_assembly_flow_control_
{
unsigned int loop_start; /* for "continue" statement */
@@ -109,19 +132,31 @@ typedef struct slang_assembly_name_space_ struct slang_variable_scope_ *vars;
} slang_assembly_name_space;
-slang_function *_slang_locate_function (const char *name, slang_operation *params,
- unsigned int num_params, slang_assembly_name_space *space);
+slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,
+ slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,
+ slang_atom_pool *);
int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,
- slang_assembly_name_space *);
+ slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);
+
+/*
+ holds a complete information about vector swizzle - the <swizzle> array contains
+ vector component sources indices, where 0 is "x", 1 is "y", ...
+ example: "xwz" --> { 3, { 0, 3, 2, n/u } }
+*/
+typedef struct slang_swizzle_
+{
+ unsigned int num_components;
+ unsigned int swizzle[4];
+} slang_swizzle;
typedef struct slang_assembly_stack_info_
{
- unsigned int swizzle_mask;
+ slang_swizzle swizzle;
} slang_assembly_stack_info;
int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,
- slang_assembly_name_space *);
+ slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);
typedef struct slang_assembly_local_info_
{
@@ -130,9 +165,12 @@ typedef struct slang_assembly_local_info_ unsigned int swizzle_tmp;
} slang_assembly_local_info;
+int _slang_dereference (slang_assembly_file *, slang_operation *, slang_assembly_name_space *,
+ slang_assembly_local_info *, struct slang_machine_ *, slang_atom_pool *);
+
int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference,
slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *,
- slang_assembly_stack_info *);
+ slang_assembly_stack_info *, struct slang_machine_ *, slang_atom_pool *);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_assemble_assignment.c b/src/mesa/shader/slang/slang_assemble_assignment.c index d8821f03bb9..3c35e862566 100644 --- a/src/mesa/shader/slang/slang_assemble_assignment.c +++ b/src/mesa/shader/slang/slang_assemble_assignment.c @@ -29,10 +29,11 @@ */
#include "imports.h"
+#include "slang_utility.h"
#include "slang_assemble_assignment.h"
#include "slang_assemble_typeinfo.h"
#include "slang_storage.h"
-#include "slang_utility.h"
+#include "slang_execute.h"
/*
_slang_assemble_assignment()
@@ -54,28 +55,45 @@ | addr of variable |
+------------------+
*/
-/* TODO: add support for swizzle mask */
+
static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
- unsigned int *index, unsigned int size, slang_assembly_local_info *info)
+ unsigned int *index, unsigned int size, slang_assembly_local_info *info,
+ slang_assembly_stack_info *stk)
{
unsigned int i;
for (i = 0; i < agg->count; i++)
{
- const slang_storage_array *arr = agg->arrays + i;
+ const slang_storage_array *arr = &agg->arrays[i];
unsigned int j;
for (j = 0; j < arr->length; j++)
{
if (arr->type == slang_stor_aggregate)
{
- if (!assign_aggregate (file, arr->aggregate, index, size, info))
+ if (!assign_aggregate (file, arr->aggregate, index, size, info, stk))
return 0;
}
else
{
+ unsigned int dst_addr_loc, dst_offset;
slang_assembly_type ty;
+ /* calculate the distance from top of the stack to the destination address */
+ dst_addr_loc = size - *index;
+
+ /* calculate the offset within destination variable to write */
+ if (stk->swizzle.num_components != 0)
+ {
+ /* swizzle the index to get the actual offset */
+ dst_offset = stk->swizzle.swizzle[*index / 4] * 4;
+ }
+ else
+ {
+ /* no swizzling - write sequentially */
+ dst_offset = *index;
+ }
+
switch (arr->type)
{
case slang_stor_bool:
@@ -90,7 +108,7 @@ static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggr default:
break;
}
- if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index))
+ if (!slang_assembly_file_push_label2 (file, ty, dst_addr_loc, dst_offset))
return 0;
*index += 4;
}
@@ -100,22 +118,29 @@ static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggr }
int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
- slang_assembly_name_space *space, slang_assembly_local_info *info)
+ slang_assembly_name_space *space, slang_assembly_local_info *info, slang_assembly_stack_info *stk,
+ struct slang_machine_ *mach, slang_atom_pool *atoms)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int index, size;
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (op, space, &ti))
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
+ if (!_slang_typeof_operation (op, space, &ti, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- slang_storage_aggregate_construct (&agg);
- if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs, space->vars))
+ if (!slang_storage_aggregate_construct (&agg))
+ {
+ slang_assembly_typeinfo_destruct (&ti);
+ return 0;
+ }
+ if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
+ space->vars, mach, file, atoms))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
@@ -124,7 +149,7 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op, index = 0;
size = _slang_sizeof_aggregate (&agg);
- result = assign_aggregate (file, &agg, &index, size, info);
+ result = assign_aggregate (file, &agg, &index, size, info, stk);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
@@ -138,17 +163,15 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op, children
*/
-int dereference (slang_assembly_file *file, slang_operation *op,
- slang_assembly_name_space *space, slang_assembly_local_info *info);
-
int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms);
int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,
- int ref, slang_assembly_name_space *space, slang_assembly_local_info *info)
+ int ref, slang_assembly_name_space *space, slang_assembly_local_info *info,
+ struct slang_machine_ *mach, slang_atom_pool *atoms)
{
- slang_assembly_stack_info stk;
+ slang_assembly_stack_info l_stk, r_stk;
slang_assembly_flow_control flow;
if (!ref)
@@ -159,16 +182,19 @@ int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, cons if (slang_string_compare ("=", oper) == 0)
{
- if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 1, &flow, space, info, &l_stk, mach,
+ atoms))
return 0;
- if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, &flow, space, info, &r_stk, mach,
+ atoms))
return 0;
- if (!_slang_assemble_assignment (file, op->children, space, info))
+ if (!_slang_assemble_assignment (file, op->children, space, info, &l_stk, mach, atoms))
return 0;
}
else
{
- if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info))
+ if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info, mach,
+ atoms))
return 0;
}
@@ -178,7 +204,7 @@ int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, cons return 0;
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
- if (!dereference (file, op->children, space, info))
+ if (!_slang_dereference (file, op->children, space, info, mach, atoms))
return 0;
}
diff --git a/src/mesa/shader/slang/slang_assemble_assignment.h b/src/mesa/shader/slang/slang_assemble_assignment.h index 06972ad176e..1dc48b16a77 100644 --- a/src/mesa/shader/slang/slang_assemble_assignment.h +++ b/src/mesa/shader/slang/slang_assemble_assignment.h @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -32,10 +32,12 @@ extern "C" { #endif
int _slang_assemble_assignment (slang_assembly_file *, slang_operation *,
- slang_assembly_name_space *, slang_assembly_local_info *);
+ slang_assembly_name_space *, slang_assembly_local_info *, slang_assembly_stack_info *,
+ struct slang_machine_ *, slang_atom_pool *);
int _slang_assemble_assign (slang_assembly_file *, slang_operation *, const char *, int ref,
- slang_assembly_name_space *, slang_assembly_local_info *);
+ slang_assembly_name_space *, slang_assembly_local_info *, struct slang_machine_ *,
+ slang_atom_pool *);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_assemble_conditional.c b/src/mesa/shader/slang/slang_assemble_conditional.c index 498938bdd55..74324cfe6c2 100644 --- a/src/mesa/shader/slang/slang_assemble_conditional.c +++ b/src/mesa/shader/slang/slang_assemble_conditional.c @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -32,12 +32,13 @@ #include "slang_utility.h"
#include "slang_assemble_conditional.h"
#include "slang_assemble.h"
+#include "slang_execute.h"
/* _slang_assemble_logicaland() */
int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
/*
and:
@@ -54,7 +55,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op, slang_assembly_stack_info stk;
/* evaluate left expression */
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -64,7 +65,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op, return 0;
/* evaluate right expression */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -75,7 +76,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op, /* push 0 on stack */
file->code[zero_jump].param[0] = file->count;
- if (!slang_assembly_file_push (file, slang_asm_bool_push))
+ if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, (GLfloat) 0))
return 0;
/* the end of the expression */
@@ -88,7 +89,7 @@ int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op, int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
/*
or:
@@ -105,7 +106,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op, slang_assembly_stack_info stk;
/* evaluate left expression */
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -115,7 +116,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op, return 0;
/* push 1 on stack */
- if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f))
+ if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, (GLfloat) 1))
return 0;
/* jump to the end of the expression */
@@ -125,7 +126,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op, /* evaluate right expression */
file->code[right_jump].param[0] = file->count;
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -139,7 +140,7 @@ int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op, int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
/*
select:
@@ -156,7 +157,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op, slang_assembly_stack_info stk;
/* execute condition expression */
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -166,7 +167,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op, return 0;
/* execute true expression */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -179,7 +180,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op, file->code[cond_jump].param[0] = file->count;
/* execute false expression */
- if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -193,7 +194,7 @@ int _slang_assemble_select (slang_assembly_file *file, slang_operation *op, int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
/*
for:
@@ -217,10 +218,10 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op, slang_assembly_stack_info stk;
/* execute initialization statement */
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))
return 0;
/* skip the "go to the end of the loop" and loop-increment statements */
@@ -238,17 +239,17 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op, cont_label = file->count;
/* execute loop-increment statement */
- if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[2], 0, space, mach, atoms))
return 0;
/* resolve the condition point */
file->code[start_jump].param[0] = file->count;
/* execute condition statement */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
@@ -260,10 +261,10 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op, /* execute loop body */
loop_flow.loop_start = cont_label;
loop_flow.loop_end = break_label;
- if (!_slang_assemble_operation (file, op->children + 3, 0, &loop_flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[3], 0, &loop_flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children + 3, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[3], 0, space, mach, atoms))
return 0;
/* go to the beginning of the loop */
@@ -281,7 +282,7 @@ int _slang_assemble_for (slang_assembly_file *file, slang_operation *op, int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
/*
do:
@@ -327,17 +328,17 @@ int _slang_assemble_do (slang_assembly_file *file, slang_operation *op, /* execute loop body */
loop_flow.loop_start = cont_label;
loop_flow.loop_end = break_label;
- if (!_slang_assemble_operation (file, op->children, 0, &loop_flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, &loop_flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))
return 0;
/* resolve condition point */
file->code[cont_jump].param[0] = file->count;
/* execute condition statement */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
@@ -361,7 +362,7 @@ int _slang_assemble_do (slang_assembly_file *file, slang_operation *op, int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
/*
while:
@@ -396,7 +397,7 @@ int _slang_assemble_while (slang_assembly_file *file, slang_operation *op, file->code[skip_jump].param[0] = file->count;
/* execute condition statement */
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
@@ -408,10 +409,10 @@ int _slang_assemble_while (slang_assembly_file *file, slang_operation *op, /* execute loop body */
loop_flow.loop_start = file->code[skip_jump].param[0];
loop_flow.loop_end = break_label;
- if (!_slang_assemble_operation (file, op->children + 1, 0, &loop_flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, &loop_flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[1], 0, space, mach, atoms))
return 0;
/* jump to the beginning of the loop */
@@ -429,7 +430,7 @@ int _slang_assemble_while (slang_assembly_file *file, slang_operation *op, int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
/*
if:
@@ -446,7 +447,7 @@ int _slang_assemble_if (slang_assembly_file *file, slang_operation *op, slang_assembly_stack_info stk;
/* execute condition statement */
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
@@ -456,10 +457,10 @@ int _slang_assemble_if (slang_assembly_file *file, slang_operation *op, return 0;
/* execute true-statement */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[1], 0, space, mach, atoms))
return 0;
/* skip if-false statement */
@@ -471,10 +472,10 @@ int _slang_assemble_if (slang_assembly_file *file, slang_operation *op, file->code[cond_jump].param[0] = file->count;
/* execute false-statement */
- if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[2], 0, flow, space, info, &stk, mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[2], 0, space, mach, atoms))
return 0;
/* resolve end of if-false statement */
diff --git a/src/mesa/shader/slang/slang_assemble_conditional.h b/src/mesa/shader/slang/slang_assemble_conditional.h index f52b4129d3a..f5aa0d48261 100644 --- a/src/mesa/shader/slang/slang_assemble_conditional.h +++ b/src/mesa/shader/slang/slang_assemble_conditional.h @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -33,31 +33,31 @@ extern "C" { int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);
int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);
int _slang_assemble_select (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);
int _slang_assemble_for (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);
int _slang_assemble_do (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);
int _slang_assemble_while (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);
int _slang_assemble_if (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *, slang_atom_pool *);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_assemble_constructor.c b/src/mesa/shader/slang/slang_assemble_constructor.c index e62f88b591e..aa2e0195388 100644 --- a/src/mesa/shader/slang/slang_assemble_constructor.c +++ b/src/mesa/shader/slang/slang_assemble_constructor.c @@ -84,25 +84,23 @@ int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz) case 'y':
case 'g':
case 't':
- if (rows < 2)
- return 0;
swz->swizzle[i] = 1;
break;
case 'z':
case 'b':
case 'p':
- if (rows < 3)
- return 0;
swz->swizzle[i] = 2;
break;
case 'w':
case 'a':
case 'q':
- if (rows < 4)
- return 0;
swz->swizzle[i] = 3;
break;
}
+
+ /* check if the component is valid for given vector's row count */
+ if (rows <= swz->swizzle[i])
+ return 0;
}
/* only one swizzle group can be used */
@@ -116,16 +114,18 @@ int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz) int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows)
{
- unsigned int c, i;
+ unsigned int i, c = 0;
+ /* the swizzle may not be longer than the vector dim */
if (swz->num_components > rows)
return 0;
- c = swz->swizzle[0];
- for (i = 1; i < swz->num_components; i++)
+
+ /* the swizzle components cannot be duplicated */
+ for (i = 0; i < swz->num_components; i++)
{
- if (swz->swizzle[i] <= c)
+ if ((c & (1 << swz->swizzle[i])) != 0)
return 0;
- c = swz->swizzle[i];
+ c |= 1 << swz->swizzle[i];
}
return 1;
}
@@ -136,13 +136,14 @@ void _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left, const slang_swizzle *right)
{
unsigned int i;
+
dst->num_components = right->num_components;
for (i = 0; i < right->num_components; i++)
dst->swizzle[i] = left->swizzle[right->swizzle[i]];
}
/* _slang_assemble_constructor() */
-
+/*
static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat,
unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow,
slang_assembly_name_space *space, slang_assembly_local_info *info)
@@ -177,10 +178,10 @@ static int constructor_aggregate (slang_assembly_file *file, const slang_storage if (arr1->type != arr2->type)
{
/* TODO: convert (generic) from arr1 to arr2 */
- }
+/* }
(*index)++;
/* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */
- }
+/* }
result = 1;
end:
@@ -192,38 +193,41 @@ end1: return result;
}
/* XXX: general swizzle! */
-int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
+/*int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, struct slang_machine_ *pmach)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg, flat;
unsigned int size, index, i;
- slang_assembly_typeinfo_construct (&ti);
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
if (!(result = _slang_typeof_operation (op, space, &ti)))
goto end1;
- slang_storage_aggregate_construct (&agg);
+ if (!(result = slang_storage_aggregate_construct (&agg)))
+ goto end1;
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
- space->vars)))
+ space->vars, pmach, file)))
goto end2;
size = _slang_sizeof_aggregate (&agg);
- slang_storage_aggregate_construct (&flat);
+ if (!(result = slang_storage_aggregate_construct (&flat)))
+ goto end2;
if (!(result = _slang_flatten_aggregate (&flat, &agg)))
goto end;
index = 0;
for (i = 0; i < op->num_children; i++)
{
- if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,
+/* if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,
space, info)))
goto end;
/* TODO: watch the index, if it reaches the size, raise an error */
- }
+/* }
result = 1;
end:
@@ -236,66 +240,34 @@ end1: }
/* _slang_assemble_constructor_from_swizzle() */
-/* XXX: wrong */
+
int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,
slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info)
{
unsigned int master_rows, i;
- switch (master_spec->type)
- {
- case slang_spec_bool:
- case slang_spec_int:
- case slang_spec_float:
- master_rows = 1;
- break;
- case slang_spec_bvec2:
- case slang_spec_ivec2:
- case slang_spec_vec2:
- master_rows = 2;
- break;
- case slang_spec_bvec3:
- case slang_spec_ivec3:
- case slang_spec_vec3:
- master_rows = 3;
- break;
- case slang_spec_bvec4:
- case slang_spec_ivec4:
- case slang_spec_vec4:
- master_rows = 4;
- break;
- default:
- break;
- }
+
+ master_rows = _slang_type_dim (master_spec->type);
for (i = 0; i < master_rows; i++)
{
- switch (master_spec->type)
+ switch (_slang_type_base (master_spec->type))
{
case slang_spec_bool:
- case slang_spec_bvec2:
- case slang_spec_bvec3:
- case slang_spec_bvec4:
- if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy, (master_rows - i) * 4,
- i * 4))
+ if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy,
+ (master_rows - i) * 4, i * 4))
return 0;
break;
case slang_spec_int:
- case slang_spec_ivec2:
- case slang_spec_ivec3:
- case slang_spec_ivec4:
- if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy, (master_rows - i) * 4,
- i * 4))
+ if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy,
+ (master_rows - i) * 4, i * 4))
return 0;
break;
case slang_spec_float:
- case slang_spec_vec2:
- case slang_spec_vec3:
- case slang_spec_vec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,
- (master_rows - i) * 4, i * 4))
+ (master_rows - i) * 4, i * 4))
return 0;
break;
default:
- break;
+ break;
}
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
@@ -303,37 +275,29 @@ int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const s for (i = swz->num_components; i > 0; i--)
{
unsigned int n = i - 1;
+
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, swz->swizzle[n] * 4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_add))
return 0;
- switch (master_spec->type)
+ switch (_slang_type_base (master_spec->type))
{
case slang_spec_bool:
- case slang_spec_bvec2:
- case slang_spec_bvec3:
- case slang_spec_bvec4:
if (!slang_assembly_file_push (file, slang_asm_bool_deref))
return 0;
break;
case slang_spec_int:
- case slang_spec_ivec2:
- case slang_spec_ivec3:
- case slang_spec_ivec4:
if (!slang_assembly_file_push (file, slang_asm_int_deref))
return 0;
break;
case slang_spec_float:
- case slang_spec_vec2:
- case slang_spec_vec3:
- case slang_spec_vec4:
if (!slang_assembly_file_push (file, slang_asm_float_deref))
return 0;
break;
default:
- break;
+ break;
}
}
return 1;
diff --git a/src/mesa/shader/slang/slang_assemble_constructor.h b/src/mesa/shader/slang/slang_assemble_constructor.h index f8a0fead3ca..b87e9cce7de 100644 --- a/src/mesa/shader/slang/slang_assemble_constructor.h +++ b/src/mesa/shader/slang/slang_assemble_constructor.h @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -33,17 +33,6 @@ extern "C" { #endif
/*
- holds a complete information about vector swizzle - the <swizzle> array contains
- vector component sources indices, where 0 is "x", 1 is "y", ...
- example: "xwz" --> { 3, { 0, 3, 2, n/u } }
-*/
-typedef struct slang_swizzle_
-{
- unsigned int num_components;
- unsigned int swizzle[4];
-} slang_swizzle;
-
-/*
checks if a field selector is a general swizzle (an r-value swizzle with replicated
components or an l-value swizzle mask) for a vector
returns 1 if this is the case, <swz> is filled with swizzle information
@@ -67,7 +56,7 @@ void _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const sla int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info);
+ slang_assembly_local_info *info, struct slang_machine_ *);
int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,
slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info);
diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.c b/src/mesa/shader/slang/slang_assemble_typeinfo.c index f5505567637..778ba04ced8 100644 --- a/src/mesa/shader/slang/slang_assemble_typeinfo.c +++ b/src/mesa/shader/slang/slang_assemble_typeinfo.c @@ -34,20 +34,37 @@ /* slang_assembly_typeinfo */
-void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
+int slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
{
- slang_type_specifier_construct (&ti->spec);
+ if (!slang_type_specifier_construct (&ti->spec))
+ return 0;
+ ti->array_size = NULL;
+ return 1;
}
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)
{
slang_type_specifier_destruct (&ti->spec);
+ /* do not free ti->array_size */
}
/* _slang_typeof_operation() */
+static int typeof_existing_function (const char *name, slang_operation *params,
+ unsigned int num_params, slang_assembly_name_space *space, slang_type_specifier *spec,
+ slang_atom_pool *atoms)
+{
+ slang_atom atom;
+ int exists;
+
+ atom = slang_atom_pool_atom (atoms, name);
+ if (!_slang_typeof_function (atom, params, num_params, space, spec, &exists, atoms))
+ return 0;
+ return exists;
+}
+
int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *space,
- slang_assembly_typeinfo *ti)
+ slang_assembly_typeinfo *ti, slang_atom_pool *atoms)
{
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
@@ -77,7 +94,7 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa case slang_oper_divassign:
case slang_oper_preincrement:
case slang_oper_predecrement:
- if (!_slang_typeof_operation (op->children, space, ti))
+ if (!_slang_typeof_operation (op->children, space, ti, atoms))
return 0;
break;
case slang_oper_literal_bool:
@@ -103,17 +120,18 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa {
slang_variable *var;
- var = _slang_locate_variable (op->locals, op->identifier, 1);
+ var = _slang_locate_variable (op->locals, op->a_id, 1);
if (var == NULL)
return 0;
if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))
return 0;
ti->can_be_referenced = 1;
+ ti->array_size = var->array_size;
}
break;
case slang_oper_sequence:
/* TODO: check [0] and [1] if they match */
- if (!_slang_typeof_operation (op->children + 1, space, ti))
+ if (!_slang_typeof_operation (&op->children[1], space, ti, atoms))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
@@ -126,7 +144,7 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa /*case slang_oper_andassign:*/
case slang_oper_select:
/* TODO: check [1] and [2] if they match */
- if (!_slang_typeof_operation (op->children + 1, space, ti))
+ if (!_slang_typeof_operation (&op->children[1], space, ti, atoms))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
@@ -137,107 +155,61 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa /*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
- {
- int exists;
- if (!_slang_typeof_function ("+", op->children, 2, space, &ti->spec, &exists))
- return 0;
- if (!exists)
- return 0;
- }
+ if (!typeof_existing_function ("+", op->children, 2, space, &ti->spec, atoms))
+ return 0;
break;
case slang_oper_subtract:
- {
- int exists;
- if (!_slang_typeof_function ("-", op->children, 2, space, &ti->spec, &exists))
- return 0;
- if (!exists)
- return 0;
- }
+ if (!typeof_existing_function ("-", op->children, 2, space, &ti->spec, atoms))
+ return 0;
break;
case slang_oper_multiply:
- {
- int exists;
- if (!_slang_typeof_function ("*", op->children, 2, space, &ti->spec, &exists))
- return 0;
- if (!exists)
- return 0;
- }
+ if (!typeof_existing_function ("*", op->children, 2, space, &ti->spec, atoms))
+ return 0;
break;
case slang_oper_divide:
- {
- int exists;
- if (!_slang_typeof_function ("/", op->children, 2, space, &ti->spec, &exists))
- return 0;
- if (!exists)
- return 0;
- }
+ if (!typeof_existing_function ("/", op->children, 2, space, &ti->spec, atoms))
+ return 0;
break;
/*case slang_oper_modulus:*/
case slang_oper_plus:
- {
- int exists;
- if (!_slang_typeof_function ("+", op->children, 1, space, &ti->spec, &exists))
- return 0;
- if (!exists)
- return 0;
- }
+ if (!_slang_typeof_operation (op->children, space, ti, atoms))
+ return 0;
+ ti->can_be_referenced = 0;
+ ti->is_swizzled = 0;
break;
case slang_oper_minus:
- {
- int exists;
- if (!_slang_typeof_function ("-", op->children, 1, space, &ti->spec, &exists))
- return 0;
- if (!exists)
- return 0;
- }
+ if (!typeof_existing_function ("-", op->children, 1, space, &ti->spec, atoms))
+ return 0;
break;
/*case slang_oper_complement:*/
case slang_oper_subscript:
{
slang_assembly_typeinfo _ti;
- slang_assembly_typeinfo_construct (&_ti);
- if (!_slang_typeof_operation (op->children, space, &_ti))
+
+ if (!slang_assembly_typeinfo_construct (&_ti))
+ return 0;
+ if (!_slang_typeof_operation (op->children, space, &_ti, atoms))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
ti->can_be_referenced = _ti.can_be_referenced;
- switch (_ti.spec.type)
+ if (_ti.spec.type == slang_spec_array)
{
- case slang_spec_bvec2:
- case slang_spec_bvec3:
- case slang_spec_bvec4:
- ti->spec.type = slang_spec_bool;
- break;
- case slang_spec_ivec2:
- case slang_spec_ivec3:
- case slang_spec_ivec4:
- ti->spec.type = slang_spec_int;
- break;
- case slang_spec_vec2:
- case slang_spec_vec3:
- case slang_spec_vec4:
- ti->spec.type = slang_spec_float;
- break;
- case slang_spec_mat2:
- ti->spec.type = slang_spec_vec2;
- break;
- case slang_spec_mat3:
- ti->spec.type = slang_spec_vec3;
- break;
- case slang_spec_mat4:
- ti->spec.type = slang_spec_vec4;
- break;
- case slang_spec_array:
if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
- break;
- default:
- slang_assembly_typeinfo_destruct (&_ti);
- return 0;
+ }
+ else
+ {
+ if (!_slang_type_is_vector (_ti.spec.type) && !_slang_type_is_matrix (_ti.spec.type))
+ {
+ slang_assembly_typeinfo_destruct (&_ti);
+ return 0;
+ }
+ ti->spec.type = _slang_type_base (_ti.spec.type);
}
slang_assembly_typeinfo_destruct (&_ti);
}
@@ -245,12 +217,13 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa case slang_oper_call:
{
int exists;
- if (!_slang_typeof_function (op->identifier, op->children, op->num_children, space,
- &ti->spec, &exists))
+
+ if (!_slang_typeof_function (op->a_id, op->children, op->num_children, space, &ti->spec,
+ &exists, atoms))
return 0;
if (!exists)
{
- slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);
+/* slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);
if (s != NULL)
{
ti->spec.type = slang_spec_struct;
@@ -267,9 +240,12 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa return 0;
}
else
- {
- slang_type_specifier_type type = slang_type_specifier_type_from_string (
- op->identifier);
+*/ {
+ const char *name;
+ slang_type_specifier_type type;
+
+ name = slang_atom_pool_id (atoms, op->a_id);
+ type = slang_type_specifier_type_from_string (name);
if (type == slang_spec_void)
return 0;
ti->spec.type = type;
@@ -280,16 +256,19 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa case slang_oper_field:
{
slang_assembly_typeinfo _ti;
- slang_assembly_typeinfo_construct (&_ti);
- if (!_slang_typeof_operation (op->children, space, &_ti))
+
+ if (!slang_assembly_typeinfo_construct (&_ti))
+ return 0;
+ if (!_slang_typeof_operation (op->children, space, &_ti, atoms))
{
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
if (_ti.spec.type == slang_spec_struct)
{
- slang_variable *field = _slang_locate_variable (_ti.spec._struct->fields,
- op->identifier, 0);
+ slang_variable *field;
+
+ field = _slang_locate_variable (_ti.spec._struct->fields, op->a_id, 0);
if (field == NULL)
{
slang_assembly_typeinfo_destruct (&_ti);
@@ -300,112 +279,96 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
+ ti->can_be_referenced = _ti.can_be_referenced;
}
else
{
unsigned int rows;
- switch (_ti.spec.type)
+ const char *swizzle;
+ slang_type_specifier_type base;
+
+ /* determine the swizzle of the field expression */
+ if (!_slang_type_is_vector (_ti.spec.type))
{
- case slang_spec_vec2:
- case slang_spec_ivec2:
- case slang_spec_bvec2:
- rows = 2;
- break;
- case slang_spec_vec3:
- case slang_spec_ivec3:
- case slang_spec_bvec3:
- rows = 3;
- break;
- case slang_spec_vec4:
- case slang_spec_ivec4:
- case slang_spec_bvec4:
- rows = 4;
- break;
- default:
slang_assembly_typeinfo_destruct (&_ti);
return 0;
}
- if (!_slang_is_swizzle (op->identifier, rows, &ti->swz))
+ rows = _slang_type_dim (_ti.spec.type);
+ swizzle = slang_atom_pool_id (atoms, op->a_id);
+ if (!_slang_is_swizzle (swizzle, rows, &ti->swz))
+ {
+ slang_assembly_typeinfo_destruct (&_ti);
return 0;
+ }
ti->is_swizzled = 1;
ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz,
rows);
if (_ti.is_swizzled)
{
slang_swizzle swz;
+
+ /* swizzle the swizzle */
_slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);
ti->swz = swz;
}
- switch (_ti.spec.type)
+ base = _slang_type_base (_ti.spec.type);
+ switch (ti->swz.num_components)
{
- case slang_spec_vec2:
- case slang_spec_vec3:
- case slang_spec_vec4:
- switch (ti->swz.num_components)
+ case 1:
+ ti->spec.type = base;
+ break;
+ case 2:
+ switch (base)
{
- case 1:
- ti->spec.type = slang_spec_float;
- break;
- case 2:
+ case slang_spec_float:
ti->spec.type = slang_spec_vec2;
break;
- case 3:
- ti->spec.type = slang_spec_vec3;
+ case slang_spec_int:
+ ti->spec.type = slang_spec_ivec2;
break;
- case 4:
- ti->spec.type = slang_spec_vec4;
+ case slang_spec_bool:
+ ti->spec.type = slang_spec_bvec2;
break;
}
break;
- case slang_spec_ivec2:
- case slang_spec_ivec3:
- case slang_spec_ivec4:
- switch (ti->swz.num_components)
+ case 3:
+ switch (base)
{
- case 1:
- ti->spec.type = slang_spec_int;
- break;
- case 2:
- ti->spec.type = slang_spec_ivec2;
+ case slang_spec_float:
+ ti->spec.type = slang_spec_vec3;
break;
- case 3:
+ case slang_spec_int:
ti->spec.type = slang_spec_ivec3;
break;
- case 4:
- ti->spec.type = slang_spec_ivec4;
+ case slang_spec_bool:
+ ti->spec.type = slang_spec_bvec3;
break;
}
break;
- case slang_spec_bvec2:
- case slang_spec_bvec3:
- case slang_spec_bvec4:
- switch (ti->swz.num_components)
+ case 4:
+ switch (base)
{
- case 1:
- ti->spec.type = slang_spec_bool;
- break;
- case 2:
- ti->spec.type = slang_spec_bvec2;
+ case slang_spec_float:
+ ti->spec.type = slang_spec_vec4;
break;
- case 3:
- ti->spec.type = slang_spec_bvec3;
+ case slang_spec_int:
+ ti->spec.type = slang_spec_ivec4;
break;
- case 4:
+ case slang_spec_bool:
ti->spec.type = slang_spec_bvec4;
break;
}
break;
default:
- break;
+ break;
}
}
slang_assembly_typeinfo_destruct (&_ti);
- return 1;
}
break;
case slang_oper_postincrement:
case slang_oper_postdecrement:
- if (!_slang_typeof_operation (op->children, space, ti))
+ if (!_slang_typeof_operation (op->children, space, ti, atoms))
return 0;
ti->can_be_referenced = 0;
ti->is_swizzled = 0;
@@ -418,13 +381,113 @@ int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *spa /* _slang_typeof_function() */
-int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,
- slang_assembly_name_space *space, slang_type_specifier *spec, int *exists)
+int _slang_typeof_function (slang_atom a_name, slang_operation *params, unsigned int num_params,
+ slang_assembly_name_space *space, slang_type_specifier *spec, int *exists, slang_atom_pool *atoms)
{
- slang_function *fun = _slang_locate_function (name, params, num_params, space);
+ slang_function *fun;
+
+ fun = _slang_locate_function (space->funcs, a_name, params, num_params, space, atoms);
*exists = fun != NULL;
if (fun == NULL)
return 1;
return slang_type_specifier_copy (spec, &fun->header.type.specifier);
}
+/* _slang_type_is_matrix() */
+
+int _slang_type_is_matrix (slang_type_specifier_type ty)
+{
+ switch (ty)
+ {
+ case slang_spec_mat2:
+ case slang_spec_mat3:
+ case slang_spec_mat4:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* _slang_type_is_vector() */
+
+int _slang_type_is_vector (slang_type_specifier_type ty)
+{
+ switch (ty)
+ {
+ case slang_spec_vec2:
+ case slang_spec_vec3:
+ case slang_spec_vec4:
+ case slang_spec_ivec2:
+ case slang_spec_ivec3:
+ case slang_spec_ivec4:
+ case slang_spec_bvec2:
+ case slang_spec_bvec3:
+ case slang_spec_bvec4:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* _slang_type_base_of_vector() */
+
+slang_type_specifier_type _slang_type_base (slang_type_specifier_type ty)
+{
+ switch (ty)
+ {
+ case slang_spec_float:
+ case slang_spec_vec2:
+ case slang_spec_vec3:
+ case slang_spec_vec4:
+ return slang_spec_float;
+ case slang_spec_int:
+ case slang_spec_ivec2:
+ case slang_spec_ivec3:
+ case slang_spec_ivec4:
+ return slang_spec_int;
+ case slang_spec_bool:
+ case slang_spec_bvec2:
+ case slang_spec_bvec3:
+ case slang_spec_bvec4:
+ return slang_spec_bool;
+ case slang_spec_mat2:
+ return slang_spec_vec2;
+ case slang_spec_mat3:
+ return slang_spec_vec3;
+ case slang_spec_mat4:
+ return slang_spec_vec4;
+ default:
+ return slang_spec_void;
+ }
+}
+
+/* _slang_type_dim */
+
+unsigned int _slang_type_dim (slang_type_specifier_type ty)
+{
+ switch (ty)
+ {
+ case slang_spec_float:
+ case slang_spec_int:
+ case slang_spec_bool:
+ return 1;
+ case slang_spec_vec2:
+ case slang_spec_ivec2:
+ case slang_spec_bvec2:
+ case slang_spec_mat2:
+ return 2;
+ case slang_spec_vec3:
+ case slang_spec_ivec3:
+ case slang_spec_bvec3:
+ case slang_spec_mat3:
+ return 3;
+ case slang_spec_vec4:
+ case slang_spec_ivec4:
+ case slang_spec_bvec4:
+ case slang_spec_mat4:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.h b/src/mesa/shader/slang/slang_assemble_typeinfo.h index 1c1839457eb..cd16440e1a7 100644 --- a/src/mesa/shader/slang/slang_assemble_typeinfo.h +++ b/src/mesa/shader/slang/slang_assemble_typeinfo.h @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -38,9 +38,10 @@ typedef struct slang_assembly_typeinfo_ int is_swizzled;
slang_swizzle swz;
slang_type_specifier spec;
+ slang_operation *array_size;
} slang_assembly_typeinfo;
-void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);
+int slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);
/*
@@ -49,15 +50,20 @@ void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *); returns 0 otherwise
*/
int _slang_typeof_operation (slang_operation *, slang_assembly_name_space *,
- slang_assembly_typeinfo *);
+ slang_assembly_typeinfo *, slang_atom_pool *);
/*
retrieves type of a function prototype, if one exists
returns 1 on success, even if the function was not found
returns 0 otherwise
*/
-int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params,
- slang_assembly_name_space *space, slang_type_specifier *spec, int *exists);
+int _slang_typeof_function (slang_atom a_name, slang_operation *params, unsigned int num_params,
+ slang_assembly_name_space *space, slang_type_specifier *spec, int *exists, slang_atom_pool *);
+
+int _slang_type_is_matrix (slang_type_specifier_type);
+int _slang_type_is_vector (slang_type_specifier_type);
+slang_type_specifier_type _slang_type_base (slang_type_specifier_type);
+unsigned int _slang_type_dim (slang_type_specifier_type);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index ce5653c6c54..11243202db6 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -59,30 +59,83 @@ static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size) int slang_translation_unit_construct (slang_translation_unit *unit) { - if (!slang_variable_scope_construct (&unit->globals))
+ unit->assembly = (slang_assembly_file *) slang_alloc_malloc (sizeof (slang_assembly_file));
+ if (unit->assembly == NULL)
return 0;
- if (!slang_function_scope_construct (&unit->functions))
+ if (!slang_assembly_file_construct (unit->assembly))
{
- slang_variable_scope_destruct (&unit->globals);
+ slang_alloc_free (unit->assembly);
return 0;
- } - if (!slang_struct_scope_construct (&unit->structs))
+ }
+ unit->global_pool = (slang_var_pool *) slang_alloc_malloc (sizeof (slang_var_pool));
+ if (unit->global_pool == NULL)
+ {
+ slang_assembly_file_destruct (unit->assembly);
+ slang_alloc_free (unit->assembly);
+ return 0;
+ }
+ unit->global_pool->next_addr = 0;
+ unit->machine = (slang_machine *) slang_alloc_malloc (sizeof (slang_machine));
+ if (unit->machine == NULL)
+ {
+ slang_alloc_free (unit->global_pool);
+ slang_assembly_file_destruct (unit->assembly);
+ slang_alloc_free (unit->assembly);
+ return 0;
+ }
+ slang_machine_init (unit->machine);
+ unit->atom_pool = (slang_atom_pool *) slang_alloc_malloc (sizeof (slang_atom_pool));
+ if (unit->atom_pool == NULL)
+ {
+ slang_alloc_free (unit->machine);
+ slang_alloc_free (unit->global_pool);
+ slang_assembly_file_destruct (unit->assembly);
+ slang_alloc_free (unit->assembly);
+ return 0;
+ }
+ slang_atom_pool_construct (unit->atom_pool);
+ if (!slang_translation_unit_construct2 (unit, unit->assembly, unit->global_pool, unit->machine,
+ unit->atom_pool))
+ {
+ slang_alloc_free (unit->atom_pool);
+ slang_alloc_free (unit->machine);
+ slang_alloc_free (unit->global_pool);
+ slang_assembly_file_destruct (unit->assembly);
+ slang_alloc_free (unit->assembly);
+ return 0;
+ }
+ unit->free_assembly = 1;
+ unit->free_global_pool = 1;
+ unit->free_machine = 1;
+ unit->free_atom_pool = 1;
+ return 1; +}
+
+int slang_translation_unit_construct2 (slang_translation_unit *unit, slang_assembly_file *file,
+ slang_var_pool *pool, struct slang_machine_ *mach, slang_atom_pool *atoms)
+{
+ if (!slang_variable_scope_construct (&unit->globals))
+ return 0;
+ if (!slang_function_scope_construct (&unit->functions))
{
slang_variable_scope_destruct (&unit->globals);
- slang_function_scope_destruct (&unit->functions);
return 0;
}
- unit->assembly = (slang_assembly_file *) slang_alloc_malloc (sizeof (slang_assembly_file));
- if (unit->assembly == NULL)
+ if (!slang_struct_scope_construct (&unit->structs))
{
slang_variable_scope_destruct (&unit->globals);
slang_function_scope_destruct (&unit->functions);
- slang_struct_scope_destruct (&unit->structs);
return 0;
}
- slang_assembly_file_construct (unit->assembly);
- unit->global_pool.next_addr = 0;
- return 1; + unit->assembly = file;
+ unit->free_assembly = 0;
+ unit->global_pool = pool;
+ unit->free_global_pool = 0;
+ unit->machine = mach;
+ unit->free_machine = 0;
+ unit->atom_pool = atoms;
+ unit->free_atom_pool = 0;
+ return 1;
} void slang_translation_unit_destruct (slang_translation_unit *unit) @@ -90,8 +143,20 @@ void slang_translation_unit_destruct (slang_translation_unit *unit) slang_variable_scope_destruct (&unit->globals); slang_function_scope_destruct (&unit->functions); slang_struct_scope_destruct (&unit->structs);
- slang_assembly_file_destruct (unit->assembly);
- slang_alloc_free (unit->assembly); + if (unit->free_assembly)
+ {
+ slang_assembly_file_destruct (unit->assembly);
+ slang_alloc_free (unit->assembly);
+ }
+ if (unit->free_global_pool)
+ slang_alloc_free (unit->global_pool);
+ if (unit->free_machine)
+ slang_alloc_free (unit->machine);
+ if (unit->free_atom_pool)
+ {
+ slang_atom_pool_destruct (unit->atom_pool);
+ slang_alloc_free (unit->atom_pool);
+ } } /* slang_info_log */ @@ -182,7 +247,8 @@ typedef struct slang_parse_ctx_ const byte *I; slang_info_log *L; int parsing_builtin;
- int global_scope; + int global_scope;
+ slang_atom_pool *atoms; } slang_parse_ctx;
/* slang_output_ctx */
@@ -194,20 +260,24 @@ typedef struct slang_output_ctx_ slang_struct_scope *structs;
slang_assembly_file *assembly;
slang_var_pool *global_pool;
+ slang_machine *machine;
} slang_output_ctx; /* _slang_compile() */ -static int parse_identifier (slang_parse_ctx *C, char **id) +static void parse_identifier_str (slang_parse_ctx *C, char **id) { - *id = slang_string_duplicate ((const char *) C->I); - if (*id == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - C->I += _mesa_strlen ((const char *) C->I) + 1; - return 1; + *id = (char *) C->I;
+ C->I += _mesa_strlen (*id) + 1; +}
+
+static slang_atom parse_identifier (slang_parse_ctx *C)
+{
+ const char *id;
+
+ id = (const char *) C->I;
+ C->I += _mesa_strlen (id) + 1;
+ return slang_atom_pool_atom (C->atoms, id);
} static int parse_number (slang_parse_ctx *C, int *number) @@ -239,30 +309,14 @@ static int parse_float (slang_parse_ctx *C, float *number) char *exponent = NULL; char *whole = NULL; - if (!parse_identifier (C, &integral)) - return 0; - - if (!parse_identifier (C, &fractional)) - { - slang_alloc_free (integral); - return 0; - } - - if (!parse_identifier (C, &exponent)) - { - slang_alloc_free (fractional); - slang_alloc_free (integral); - return 0; - } + parse_identifier_str (C, &integral); + parse_identifier_str (C, &fractional); + parse_identifier_str (C, &exponent);
- whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + - _mesa_strlen (fractional) + _mesa_strlen (exponent) + 3) * - sizeof (char))); + whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) +
+ _mesa_strlen (exponent) + 3) * sizeof (char))); if (whole == NULL) { - slang_alloc_free (exponent); - slang_alloc_free (fractional); - slang_alloc_free (integral); slang_info_log_memory (C->L); return 0; } @@ -276,14 +330,11 @@ static int parse_float (slang_parse_ctx *C, float *number) *number = (float) (_mesa_strtod(whole, (char **)NULL)); slang_alloc_free (whole); - slang_alloc_free (exponent); - slang_alloc_free (fractional); - slang_alloc_free (integral); return 1; } /* revision number - increment after each change affecting emitted output */ -#define REVISION 2 +#define REVISION 3 static int check_revision (slang_parse_ctx *C) { @@ -307,8 +358,10 @@ static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_ty static int parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var)
{
- if (!parse_identifier (C, &var->name))
+ var->a_name = parse_identifier (C);
+ if (var->a_name == SLANG_ATOM_NULL)
return 0;
+
switch (*C->I++)
{
case FIELD_NONE:
@@ -332,6 +385,7 @@ static int parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slan default:
return 0;
}
+
return 1;
}
@@ -355,7 +409,7 @@ static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_st slang_info_log_memory (C->L);
return 0;
}
- var = st->fields->variables + st->fields->num_variables;
+ var = &st->fields->variables[st->fields->num_variables];
if (!slang_variable_construct (var))
return 0;
st->fields->num_variables++;
@@ -365,25 +419,30 @@ static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_st return 0;
}
while (*C->I++ != FIELD_NONE);
+
return 1;
}
static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st)
{
- char *name;
+ slang_atom a_name;
+ const char *name;
- if (!parse_identifier (C, &name))
+ /* parse struct name (if any) and make sure it is unique in current scope */
+ a_name = parse_identifier (C);
+ if (a_name == SLANG_ATOM_NULL)
return 0;
- if (name[0] != '\0' && slang_struct_scope_find (O->structs, name, 0) != NULL)
+ name = slang_atom_pool_id (C->atoms, a_name);
+ if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL)
{
slang_info_log_error (C->L, "%s: duplicate type name", name);
- slang_alloc_free (name);
return 0;
}
+
+ /* set-up a new struct */
*st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
if (*st == NULL)
{
- slang_alloc_free (name);
slang_info_log_memory (C->L);
return 0;
}
@@ -391,13 +450,13 @@ static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct * {
slang_alloc_free (*st);
*st = NULL;
- slang_alloc_free (name);
slang_info_log_memory (C->L);
return 0;
}
- (**st).name = name;
+ (**st).a_name = a_name;
(**st).structs->outer_scope = O->structs;
+ /* parse individual struct fields */
do
{
slang_type_specifier sp;
@@ -412,13 +471,14 @@ static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct * }
while (*C->I++ != FIELD_NONE);
- if ((**st).name != '\0')
+ /* if named struct, copy it to current scope */
+ if (name[0] != '\0')
{
slang_struct *s;
O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs,
- O->structs->num_structs * sizeof (slang_struct),
- (O->structs->num_structs + 1) * sizeof (slang_struct));
+ O->structs->num_structs * sizeof (slang_struct),
+ (O->structs->num_structs + 1) * sizeof (slang_struct));
if (O->structs->structs == NULL)
{
slang_info_log_memory (C->L);
@@ -576,21 +636,24 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_output_ctx *O, slang_ if (!parse_struct (C, O, &spec->_struct)) return 0; break; - case TYPE_SPECIFIER_TYPENAME: + case TYPE_SPECIFIER_TYPENAME:
spec->type = slang_spec_struct; { - char *name; - slang_struct *stru; - if (!parse_identifier (C, &name)) - return 0; - stru = slang_struct_scope_find (O->structs, name, 1); + slang_atom a_name; + slang_struct *stru;
+ + a_name = parse_identifier (C);
+ if (a_name == NULL) + return 0;
+ + stru = slang_struct_scope_find (O->structs, a_name, 1); if (stru == NULL) { - slang_info_log_error (C->L, "%s: undeclared type name", name); - slang_alloc_free (name); + slang_info_log_error (C->L, "%s: undeclared type name",
+ slang_atom_pool_id (C->atoms, a_name)); return 0; } - slang_alloc_free (name); + spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); if (spec->_struct == NULL) { @@ -687,7 +750,9 @@ static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O, static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper,
int statement) -{ +{
+ slang_operation *ch;
+ oper->children = (slang_operation *) slang_alloc_realloc (oper->children, oper->num_children * sizeof (slang_operation), (oper->num_children + 1) * sizeof (slang_operation)); @@ -695,16 +760,17 @@ static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang { slang_info_log_memory (C->L); return 0; - } - if (!slang_operation_construct (oper->children + oper->num_children)) + }
+ ch = &oper->children[oper->num_children]; + if (!slang_operation_construct (ch)) { slang_info_log_memory (C->L); return 0; } oper->num_children++; if (statement) - return parse_statement (C, O, &oper->children[oper->num_children - 1]); - return parse_expression (C, O, &oper->children[oper->num_children - 1]); + return parse_statement (C, O, ch); + return parse_expression (C, O, ch); } static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O); @@ -714,29 +780,34 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera oper->locals->outer_scope = O->vars; switch (*C->I++) { - case OP_BLOCK_BEGIN_NO_NEW_SCOPE: + case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
+ /* parse child statements, do not create new variable scope */ oper->type = slang_oper_block_no_new_scope; while (*C->I != OP_END) if (!parse_child_operation (C, O, oper, 1)) return 0; C->I++; break; - case OP_BLOCK_BEGIN_NEW_SCOPE: - oper->type = slang_oper_block_new_scope; - while (*C->I != OP_END)
+ case OP_BLOCK_BEGIN_NEW_SCOPE:
+ /* parse child statements, create new variable scope */ {
slang_output_ctx o = *O;
+
+ oper->type = slang_oper_block_new_scope;
o.vars = oper->locals; - if (!parse_child_operation (C, &o, oper, 1)) - return 0;
+ while (*C->I != OP_END)
+ if (!parse_child_operation (C, &o, oper, 1)) + return 0;
+ C->I++;
} - C->I++; break; - case OP_DECLARE: + case OP_DECLARE:
+ /* local variable declaration, individual declarators are stored as children identifiers */ oper->type = slang_oper_variable_decl; { const unsigned int first_var = O->vars->num_variables;
- +
+ /* parse the declaration, note that there can be zero or more than one declarators */ if (!parse_declaration (C, O)) return 0; if (first_var < O->vars->num_variables) @@ -751,36 +822,28 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera slang_info_log_memory (C->L); return 0; } - for (i = 0; i < num_vars; i++) - if (!slang_operation_construct (oper->children + i)) + for (oper->num_children = 0; oper->num_children < num_vars; oper->num_children++) + if (!slang_operation_construct (&oper->children[oper->num_children])) { - unsigned int j; - for (j = 0; j < i; j++) - slang_operation_destruct (oper->children + j); - slang_alloc_free (oper->children); - oper->children = NULL; slang_info_log_memory (C->L); return 0; } - oper->num_children = num_vars; for (i = first_var; i < O->vars->num_variables; i++) { - slang_operation *o = oper->children + i - first_var; + slang_operation *o = &oper->children[i - first_var];
+ o->type = slang_oper_identifier; o->locals->outer_scope = O->vars; - o->identifier = slang_string_duplicate (O->vars->variables[i].name); - if (o->identifier == NULL) - { - slang_info_log_memory (C->L); - return 0; - } + o->a_id = O->vars->variables[i].a_name; } } } break; - case OP_ASM: - oper->type = slang_oper_asm; - if (!parse_identifier (C, &oper->identifier)) + case OP_ASM:
+ /* the __asm statement, parse the mnemonic and all its arguments as expressions */ + oper->type = slang_oper_asm;
+ oper->a_id = parse_identifier (C);
+ if (oper->a_id == SLANG_ATOM_NULL) return 0; while (*C->I != OP_END) if (!parse_child_operation (C, O, oper, 0)) @@ -816,9 +879,10 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera return 0; break; case OP_WHILE: - oper->type = slang_oper_while;
{
slang_output_ctx o = *O;
+
+ oper->type = slang_oper_while;
o.vars = oper->locals; if (!parse_child_operation (C, &o, oper, 1)) return 0; @@ -834,9 +898,10 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera return 0; break; case OP_FOR: - oper->type = slang_oper_for;
{
slang_output_ctx o = *O;
+
+ oper->type = slang_oper_for;
o.vars = oper->locals; if (!parse_child_operation (C, &o, oper, 1)) return 0; @@ -852,85 +917,41 @@ static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_opera return 0; } return 1; +}
+
+static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops,
+ unsigned int *total_ops, unsigned int n)
+{
+ unsigned int i;
+
+ op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation));
+ if (op->children == NULL)
+ {
+ slang_info_log_memory (C->L);
+ return 0;
+ }
+ op->num_children = n;
+
+ for (i = 0; i < n; i++)
+ op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
+ (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
+ *total_ops -= n;
+
+ *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation),
+ *total_ops * sizeof (slang_operation));
+ if (*ops == NULL)
+ {
+ slang_info_log_memory (C->L);
+ return 0;
+ }
+ return 1;
} -static int handle_trinary_expression (slang_parse_ctx *C, slang_operation *op, - slang_operation **ops, unsigned int *num_ops) -{ - op->num_children = 3; - op->children = (slang_operation *) slang_alloc_malloc (3 * sizeof (slang_operation)); - if (op->children == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - op->children[0] = (*ops)[*num_ops - 4]; - op->children[1] = (*ops)[*num_ops - 3]; - op->children[2] = (*ops)[*num_ops - 2]; - (*ops)[*num_ops - 4] = (*ops)[*num_ops - 1]; - *num_ops -= 3; - *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 3) * sizeof (slang_operation), - *num_ops * sizeof (slang_operation)); - if (*ops == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - return 1; -} - -static int handle_binary_expression (slang_parse_ctx *C, slang_operation *op, - slang_operation **ops, unsigned int *num_ops) -{ - op->num_children = 2; - op->children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation)); - if (op->children == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - op->children[0] = (*ops)[*num_ops - 3]; - op->children[1] = (*ops)[*num_ops - 2]; - (*ops)[*num_ops - 3] = (*ops)[*num_ops - 1]; - *num_ops -= 2; - *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 2) * sizeof (slang_operation), - *num_ops * sizeof (slang_operation)); - if (*ops == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - return 1; -} - -static int handle_unary_expression (slang_parse_ctx *C, slang_operation *op, - slang_operation **ops, unsigned int *num_ops) -{ - op->num_children = 1; - op->children = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); - if (op->children == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - op->children[0] = (*ops)[*num_ops - 2]; - (*ops)[*num_ops - 2] = (*ops)[*num_ops - 1]; - (*num_ops)--; - *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 1) * sizeof (slang_operation), - *num_ops * sizeof (slang_operation)); - if (*ops == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - return 1; -} - -static int is_constructor_name (const char *name, slang_struct_scope *structs) +static int is_constructor_name (const char *name, slang_atom a_name, slang_struct_scope *structs) { if (slang_type_specifier_type_from_string (name) != slang_spec_void) return 1; - return slang_struct_scope_find (structs, name, 1) != NULL; + return slang_struct_scope_find (structs, a_name, 1) != NULL; } static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper) @@ -942,7 +963,9 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper while (*C->I != OP_END) { slang_operation *op; - const unsigned int op_code = *C->I++; + const unsigned int op_code = *C->I++;
+
+ /* allocate default operation, becomes a no-op if not used */ ops = (slang_operation *) slang_alloc_realloc (ops, num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation)); if (ops == NULL) @@ -950,14 +973,15 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper slang_info_log_memory (C->L); return 0; } - op = ops + num_ops; + op = &ops[num_ops]; if (!slang_operation_construct (op)) { slang_info_log_memory (C->L); return 0; } num_ops++; - op->locals->outer_scope = O->vars; + op->locals->outer_scope = O->vars;
+ switch (op_code) { case OP_PUSH_VOID: @@ -967,13 +991,13 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper op->type = slang_oper_literal_bool; if (!parse_number (C, &number)) return 0; - op->literal = (float) number; + op->literal = (GLfloat) number; break; case OP_PUSH_INT: op->type = slang_oper_literal_int; if (!parse_number (C, &number)) return 0; - op->literal = (float) number; + op->literal = (GLfloat) number; break; case OP_PUSH_FLOAT: op->type = slang_oper_literal_float; @@ -982,37 +1006,38 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper break; case OP_PUSH_IDENTIFIER: op->type = slang_oper_identifier; - if (!parse_identifier (C, &op->identifier)) + op->a_id = parse_identifier (C);
+ if (op->a_id == SLANG_ATOM_NULL) return 0; break; case OP_SEQUENCE: op->type = slang_oper_sequence; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_ASSIGN: op->type = slang_oper_assign; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_ADDASSIGN: op->type = slang_oper_addassign; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_SUBASSIGN: op->type = slang_oper_subassign; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_MULASSIGN: op->type = slang_oper_mulassign; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_DIVASSIGN: op->type = slang_oper_divassign; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_MODASSIGN:*/ @@ -1023,22 +1048,22 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper /*case OP_ANDASSIGN:*/ case OP_SELECT: op->type = slang_oper_select; - if (!handle_trinary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 3)) return 0; break; case OP_LOGICALOR: op->type = slang_oper_logicalor; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_LOGICALXOR: op->type = slang_oper_logicalxor; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_LOGICALAND: op->type = slang_oper_logicaland; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_BITOR:*/ @@ -1046,126 +1071,133 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper /*case OP_BITAND:*/ case OP_EQUAL: op->type = slang_oper_equal; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_NOTEQUAL: op->type = slang_oper_notequal; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_LESS: op->type = slang_oper_less; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_GREATER: op->type = slang_oper_greater; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_LESSEQUAL: op->type = slang_oper_lessequal; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_GREATEREQUAL: op->type = slang_oper_greaterequal; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_LSHIFT:*/ /*case OP_RSHIFT:*/ case OP_ADD: op->type = slang_oper_add; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_SUBTRACT: op->type = slang_oper_subtract; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_MULTIPLY: op->type = slang_oper_multiply; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_DIVIDE: op->type = slang_oper_divide; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_MODULUS:*/ case OP_PREINCREMENT: op->type = slang_oper_preincrement; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; case OP_PREDECREMENT: op->type = slang_oper_predecrement; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; case OP_PLUS: op->type = slang_oper_plus; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; case OP_MINUS: op->type = slang_oper_minus; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; case OP_NOT: op->type = slang_oper_not; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; /*case OP_COMPLEMENT:*/ case OP_SUBSCRIPT: op->type = slang_oper_subscript; - if (!handle_binary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) return 0; break; case OP_CALL: op->type = slang_oper_call; - if (!parse_identifier (C, &op->identifier)) + op->a_id = parse_identifier (C);
+ if (op->a_id == SLANG_ATOM_NULL) return 0; while (*C->I != OP_END) if (!parse_child_operation (C, O, op, 0)) return 0; C->I++; - if (!C->parsing_builtin && - !slang_function_scope_find_by_name (O->funs, op->identifier, 1) && - !is_constructor_name (op->identifier, O->structs)) - { - slang_info_log_error (C->L, "%s: undeclared function name", op->identifier); - return 0; + if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1))
+ {
+ const char *id;
+
+ id = slang_atom_pool_id (C->atoms, op->a_id); + if (!is_constructor_name (id, op->a_id, O->structs)) + { + slang_info_log_error (C->L, "%s: undeclared function name", id); + return 0; + }
} break; case OP_FIELD: op->type = slang_oper_field; - if (!parse_identifier (C, &op->identifier)) + op->a_id = parse_identifier (C);
+ if (op->a_id == SLANG_ATOM_NULL) return 0; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; case OP_POSTINCREMENT: op->type = slang_oper_postincrement; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; case OP_POSTDECREMENT: op->type = slang_oper_postdecrement; - if (!handle_unary_expression (C, op, &ops, &num_ops)) + if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) return 0; break; default: return 0; } } - C->I++; + C->I++;
+ *oper = *ops; slang_alloc_free (ops); return 1; @@ -1183,7 +1215,10 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
slang_variable *param) { - slang_storage_aggregate agg; + slang_storage_aggregate agg;
+
+ /* parse and validate the parameter's type qualifiers (there can be two at most) because
+ * not all combinations are valid */ if (!parse_type_qualifier (C, ¶m->type.qualifier)) return 0; switch (*C->I++) @@ -1215,11 +1250,16 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, break; default: return 0; - } + }
+
+ /* parse parameter's type specifier and name */ if (!parse_type_specifier (C, O, ¶m->type.specifier)) - return 0; - if (!parse_identifier (C, ¶m->name)) - return 0; + return 0;
+ param->a_name = parse_identifier (C); + if (param->a_name == SLANG_ATOM_NULL)
+ return 0;
+
+ /* if the parameter is an array, parse its size (the size must be explicitly defined */ if (*C->I++ == PARAMETER_ARRAY_PRESENT) { param->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); @@ -1236,16 +1276,22 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, return 0; } if (!parse_expression (C, O, param->array_size)) - return 0; - } - slang_storage_aggregate_construct (&agg); - if (!_slang_aggregate_variable (&agg, ¶m->type.specifier, param->array_size, O->funs, - O->structs, O->vars)) - { - slang_storage_aggregate_destruct (&agg); - return 0; - } - slang_storage_aggregate_destruct (&agg); + return 0;
+ /* TODO: execute the array_size */ + }
+
+ /* calculate the parameter size */
+ if (!slang_storage_aggregate_construct (&agg))
+ return 0;
+ if (!_slang_aggregate_variable (&agg, ¶m->type.specifier, param->array_size, O->funs,
+ O->structs, O->vars, O->machine, O->assembly, C->atoms))
+ {
+ slang_storage_aggregate_destruct (&agg);
+ return 0;
+ }
+ param->size = _slang_sizeof_aggregate (&agg);
+ slang_storage_aggregate_destruct (&agg);
+ /* TODO: allocate the local address here? */
return 1; } @@ -1259,38 +1305,35 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, #define PARAMETER_NEXT 1 /* operator type */ -#define OPERATOR_ASSIGN 1 -#define OPERATOR_ADDASSIGN 2 -#define OPERATOR_SUBASSIGN 3 -#define OPERATOR_MULASSIGN 4 -#define OPERATOR_DIVASSIGN 5 -/*#define OPERATOR_MODASSIGN 6*/ -/*#define OPERATOR_LSHASSIGN 7*/ -/*#define OPERATOR_RSHASSIGN 8*/ -/*#define OPERATOR_ANDASSIGN 9*/ -/*#define OPERATOR_XORASSIGN 10*/ -/*#define OPERATOR_ORASSIGN 11*/ -#define OPERATOR_LOGICALXOR 12 -/*#define OPERATOR_BITOR 13*/ -/*#define OPERATOR_BITXOR 14*/ -/*#define OPERATOR_BITAND 15*/ -#define OPERATOR_EQUAL 16 -#define OPERATOR_NOTEQUAL 17 -#define OPERATOR_LESS 18 -#define OPERATOR_GREATER 19 -#define OPERATOR_LESSEQUAL 20 -#define OPERATOR_GREATEREQUAL 21 -/*#define OPERATOR_LSHIFT 22*/ -/*#define OPERATOR_RSHIFT 23*/ -#define OPERATOR_MULTIPLY 24 -#define OPERATOR_DIVIDE 25 -/*#define OPERATOR_MODULUS 26*/ -#define OPERATOR_INCREMENT 27 -#define OPERATOR_DECREMENT 28 -#define OPERATOR_PLUS 29 -#define OPERATOR_MINUS 30 -/*#define OPERATOR_COMPLEMENT 31*/ -#define OPERATOR_NOT 32 +#define OPERATOR_ADDASSIGN 1 +#define OPERATOR_SUBASSIGN 2 +#define OPERATOR_MULASSIGN 3 +#define OPERATOR_DIVASSIGN 4 +/*#define OPERATOR_MODASSIGN 5*/ +/*#define OPERATOR_LSHASSIGN 6*/ +/*#define OPERATOR_RSHASSIGN 7*/ +/*#define OPERATOR_ANDASSIGN 8*/ +/*#define OPERATOR_XORASSIGN 9*/ +/*#define OPERATOR_ORASSIGN 10*/ +#define OPERATOR_LOGICALXOR 11 +/*#define OPERATOR_BITOR 12*/ +/*#define OPERATOR_BITXOR 13*/ +/*#define OPERATOR_BITAND 14*/ +#define OPERATOR_LESS 15 +#define OPERATOR_GREATER 16 +#define OPERATOR_LESSEQUAL 17 +#define OPERATOR_GREATEREQUAL 18 +/*#define OPERATOR_LSHIFT 19*/ +/*#define OPERATOR_RSHIFT 20*/ +#define OPERATOR_MULTIPLY 21 +#define OPERATOR_DIVIDE 22 +/*#define OPERATOR_MODULUS 23*/ +#define OPERATOR_INCREMENT 24 +#define OPERATOR_DECREMENT 25 +#define OPERATOR_PLUS 26 +#define OPERATOR_MINUS 27 +/*#define OPERATOR_COMPLEMENT 28*/ +#define OPERATOR_NOT 29 static const struct { unsigned int o_code; @@ -1302,7 +1345,6 @@ static const struct { { OPERATOR_DECREMENT, "--" }, { OPERATOR_SUBASSIGN, "-=" }, { OPERATOR_MINUS, "-" }, - { OPERATOR_NOTEQUAL, "!=" }, { OPERATOR_NOT, "!" }, { OPERATOR_MULASSIGN, "*=" }, { OPERATOR_MULTIPLY, "*" }, @@ -1316,8 +1358,6 @@ static const struct { /*{ OPERATOR_RSHASSIGN, ">>=" },*/ /*{ OPERATOR_RSHIFT, ">>" },*/ { OPERATOR_GREATER, ">" }, - { OPERATOR_EQUAL, "==" }, - { OPERATOR_ASSIGN, "=" }, /*{ OPERATOR_MODASSIGN, "%=" },*/ /*{ OPERATOR_MODULUS, "%" },*/ /*{ OPERATOR_ANDASSIGN, "&=" },*/ @@ -1326,46 +1366,51 @@ static const struct { /*{ OPERATOR_BITOR, "|" },*/ /*{ OPERATOR_COMPLEMENT, "~" },*/ /*{ OPERATOR_XORASSIGN, "^=" },*/ - { OPERATOR_LOGICALXOR, "^^" }/*,*/ + { OPERATOR_LOGICALXOR, "^^" }, /*{ OPERATOR_BITXOR, "^" }*/ }; -static int parse_operator_name (slang_parse_ctx *C, char **pname) +static slang_atom parse_operator_name (slang_parse_ctx *C) { - unsigned int i; - for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++) + unsigned int i;
+ + for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)
+ { if (operator_names[i].o_code == (unsigned int) (*C->I)) { - *pname = slang_string_duplicate (operator_names[i].o_name); - if (*pname == NULL) + slang_atom atom = slang_atom_pool_atom (C->atoms, operator_names[i].o_name); + if (atom == SLANG_ATOM_NULL) { slang_info_log_memory (C->L); return 0; } C->I++; - return 1; - } + return atom; + }
+ } return 0; } static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func) -{ +{
+ /* parse function type and name */ if (!parse_fully_specified_type (C, O, &func->header.type)) return 0; switch (*C->I++) { - case FUNCTION_ORDINARY: + case FUNCTION_ORDINARY:
func->kind = slang_func_ordinary; - if (!parse_identifier (C, &func->header.name)) - return 0; + func->header.a_name = parse_identifier (C); + if (func->header.a_name == SLANG_ATOM_NULL)
+ return 0;
break; case FUNCTION_CONSTRUCTOR: func->kind = slang_func_constructor; if (func->header.type.specifier.type == slang_spec_struct) return 0; - func->header.name = slang_string_duplicate ( + func->header.a_name = slang_atom_pool_atom (C->atoms, slang_type_specifier_type_to_string (func->header.type.specifier.type)); - if (func->header.name == NULL) + if (func->header.a_name == SLANG_ATOM_NULL) { slang_info_log_memory (C->L); return 0; @@ -1373,15 +1418,19 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, sl break; case FUNCTION_OPERATOR: func->kind = slang_func_operator; - if (!parse_operator_name (C, &func->header.name)) + func->header.a_name = parse_operator_name (C);
+ if (func->header.a_name == SLANG_ATOM_NULL) return 0; break; default: return 0; }
- func->parameters->outer_scope = O->vars; +
+ /* parse function parameters */ while (*C->I++ == PARAMETER_NEXT) - { + {
+ slang_variable *p;
+ func->parameters->variables = (slang_variable *) slang_alloc_realloc ( func->parameters->variables, func->parameters->num_variables * sizeof (slang_variable), @@ -1390,14 +1439,21 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, sl { slang_info_log_memory (C->L); return 0; - } - slang_variable_construct (func->parameters->variables + func->parameters->num_variables); + }
+ p = &func->parameters->variables[func->parameters->num_variables]; + if (!slang_variable_construct (p))
+ return 0;
func->parameters->num_variables++; - if (!parse_parameter_declaration (C, O,
- &func->parameters->variables[func->parameters->num_variables - 1])) + if (!parse_parameter_declaration (C, O, p)) return 0; - } - func->param_count = func->parameters->num_variables; + }
+
+ /* function formal parameters and local variables share the same scope, so save
+ * the information about param count in a seperate place
+ * also link the scope to the global variable scope so when a given identifier is not
+ * found here, the search process continues in the global space */ + func->param_count = func->parameters->num_variables;
+ func->parameters->outer_scope = O->vars; return 1; } @@ -1406,7 +1462,9 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s slang_output_ctx o = *O;
if (!parse_function_prototype (C, O, func)) - return 0; + return 0;
+
+ /* create function's body operation */ func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); if (func->body == NULL) { @@ -1420,12 +1478,110 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s slang_info_log_memory (C->L); return 0; }
+
+ /* to parse the body the parse context is modified in order to capture parsed variables
+ * into function's local variable scope */
C->global_scope = 0;
o.vars = func->parameters; if (!parse_statement (C, &o, func->body)) return 0;
C->global_scope = 1; return 1; +}
+
+static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
+ slang_assembly_name_space *space, slang_variable *var, slang_atom_pool *atoms)
+{
+ slang_assembly_file_restore_point point;
+ slang_machine mach;
+ slang_assembly_local_info info;
+ slang_operation op_id, op_assign;
+ int result;
+ slang_assembly_flow_control flow;
+ slang_assembly_stack_info stk;
+
+ /* save the current assembly */
+ if (!slang_assembly_file_restore_point_save (file, &point))
+ return 0;
+
+ /* setup the machine */
+ mach = *pmach;
+ mach.ip = file->count;
+
+ /* allocate local storage for expression */
+ info.ret_size = 0;
+ info.addr_tmp = 0;
+ info.swizzle_tmp = 4;
+ if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20))
+ return 0;
+ if (!slang_assembly_file_push_label (file, slang_asm_enter, 20))
+ return 0;
+
+ /* construct the left side of assignment */
+ if (!slang_operation_construct (&op_id))
+ return 0;
+ op_id.type = slang_oper_identifier;
+ op_id.a_id = var->a_name;
+
+ /* put the variable into operation's scope */
+ op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable));
+ if (op_id.locals->variables == NULL)
+ {
+ slang_operation_destruct (&op_id);
+ return 0;
+ }
+ op_id.locals->num_variables = 1;
+ op_id.locals->variables[0] = *var;
+
+ /* construct the assignment expression */
+ if (!slang_operation_construct (&op_assign))
+ {
+ op_id.locals->num_variables = 0;
+ slang_operation_destruct (&op_id);
+ return 0;
+ }
+ op_assign.type = slang_oper_assign;
+ op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
+ if (op_assign.children == NULL)
+ {
+ slang_operation_destruct (&op_assign);
+ op_id.locals->num_variables = 0;
+ slang_operation_destruct (&op_id);
+ return 0;
+ }
+ op_assign.num_children = 2;
+ op_assign.children[0] = op_id;
+ op_assign.children[1] = *var->initializer;
+
+ /* insert the actual expression */
+ result = _slang_assemble_operation (file, &op_assign, 0, &flow, space, &info, &stk, pmach, atoms);
+
+ /* carefully destroy the operations */
+ op_assign.num_children = 0;
+ slang_alloc_free (op_assign.children);
+ op_assign.children = NULL;
+ slang_operation_destruct (&op_assign);
+ op_id.locals->num_variables = 0;
+ slang_operation_destruct (&op_id);
+
+ if (!result)
+ return 0;
+ if (!slang_assembly_file_push (file, slang_asm_exit))
+ return 0;
+
+ /* execute the expression */
+ if (!_slang_execute2 (file, &mach))
+ return 0;
+
+ /* restore the old assembly */
+ if (!slang_assembly_file_restore_point_load (file, &point))
+ return 0;
+
+ /* now we copy the contents of the initialized variable back to the original machine */
+ _mesa_memcpy ((GLubyte *) pmach->mem + var->address, (GLubyte *) mach.mem + var->address,
+ var->size);
+
+ return 1;
} /* init declarator list */ @@ -1442,9 +1598,9 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
const slang_fully_specified_type *type) { - slang_variable *var; + slang_variable *var;
- /* empty init declatator, e.g. "float ;" */
+ /* empty init declatator (without name, e.g. "float ;") */
if (*C->I++ == VARIABLE_NONE) return 1;
@@ -1458,12 +1614,15 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, return 0; } var = &O->vars->variables[O->vars->num_variables]; - slang_variable_construct (var);
+ if (!slang_variable_construct (var))
+ return 0;
O->vars->num_variables++;
- /* copy the declarator qualifier type, parse the identifier */ + /* copy the declarator qualifier type, parse the identifier */
+ var->global = C->global_scope; var->type.qualifier = type->qualifier; - if (!parse_identifier (C, &var->name)) + var->a_name = parse_identifier (C); + if (var->a_name == SLANG_ATOM_NULL)
return 0;
switch (*C->I++) @@ -1491,11 +1650,12 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, return 0; } if (!parse_expression (C, O, var->initializer)) - return 0; + return 0;
+ /* TODO: execute the initializer */ break; - case VARIABLE_ARRAY_UNKNOWN:
+/* case VARIABLE_ARRAY_UNKNOWN:
/* unsized array - mark it as array and copy the specifier to the array element */ - var->type.specifier.type = slang_spec_array; +/* var->type.specifier.type = slang_spec_array; var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof ( slang_type_specifier)); if (var->type.specifier._array == NULL) @@ -1506,9 +1666,9 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, slang_type_specifier_construct (var->type.specifier._array); if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier)) return 0; - break; + break;*/ case VARIABLE_ARRAY_EXPLICIT:
- /* an array - mark it as array, copy the specifier to the array element and
+ /* sized array - mark it as array, copy the specifier to the array element and
* parse the expression */ var->type.specifier.type = slang_spec_array; var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof ( @@ -1518,7 +1678,13 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, slang_info_log_memory (C->L); return 0; } - slang_type_specifier_construct (var->type.specifier._array); + if (!slang_type_specifier_construct (var->type.specifier._array))
+ {
+ slang_alloc_free (var->type.specifier._array);
+ var->type.specifier._array = NULL;
+ slang_info_log_memory (C->L);
+ return 0;
+ } if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier)) return 0; var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); @@ -1546,15 +1712,29 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, { slang_storage_aggregate agg; - slang_storage_aggregate_construct (&agg); + if (!slang_storage_aggregate_construct (&agg))
+ return 0; if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_size, O->funs, - O->structs, O->vars)) + O->structs, O->vars, O->machine, O->assembly, C->atoms)) { slang_storage_aggregate_destruct (&agg); return 0; }
- var->address = slang_var_pool_alloc (O->global_pool, _slang_sizeof_aggregate (&agg)); - slang_storage_aggregate_destruct (&agg); + var->size = _slang_sizeof_aggregate (&agg);
+ slang_storage_aggregate_destruct (&agg);
+ var->address = slang_var_pool_alloc (O->global_pool, var->size); + }
+
+ /* initialize global variable */
+ if (C->global_scope && var->initializer != NULL)
+ {
+ slang_assembly_name_space space;
+
+ space.funcs = O->funs;
+ space.structs = O->structs;
+ space.vars = O->vars;
+ if (!initialize_global (O->assembly, O->machine, &space, var, C->atoms))
+ return 0;
} return 1; } @@ -1562,13 +1742,17 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O) { slang_fully_specified_type type; - - slang_fully_specified_type_construct (&type); +
+ /* parse the fully specified type, common to all declarators */ + if (!slang_fully_specified_type_construct (&type))
+ return 0; if (!parse_fully_specified_type (C, O, &type)) { slang_fully_specified_type_destruct (&type); return 0; - } + }
+
+ /* parse declarators, pass-in the parsed type */ do { if (!parse_init_declarator (C, O, &type)) @@ -1577,7 +1761,8 @@ static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O) return 0; } } - while (*C->I++ == DECLARATOR_NEXT); + while (*C->I++ == DECLARATOR_NEXT);
+ slang_fully_specified_type_destruct (&type); return 1; } @@ -1598,7 +1783,7 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti return 0; } } - else +/* else { if (!parse_function_prototype (C, O, &parsed_func)) { @@ -1608,7 +1793,7 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti } /* find a function with a prototype matching the parsed one - only the current scope - is being searched to allow built-in function overriding */ + * is being searched to allow built-in function overriding */ found_func = slang_function_scope_find (O->funs, &parsed_func, 0); if (found_func == NULL) { @@ -1628,13 +1813,13 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti /* return the newly parsed function */ *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1]; } - else +/* else { /* TODO: check function return type qualifiers and specifiers */ - if (definition) +/* if (definition) { /* destroy the existing function declaration and replace it with the new one */ - if (found_func->body != NULL) +/* if (found_func->body != NULL) { slang_info_log_error (C->L, "%s: function already has a body", parsed_func.header.name); @@ -1647,11 +1832,11 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti else { /* another declaration of the same function prototype - ignore it */ - slang_function_destruct (&parsed_func); +/* slang_function_destruct (&parsed_func); } /* return the found function */ - *parsed_func_ret = found_func; +/* *parsed_func_ret = found_func; } /* assemble the parsed function */ @@ -1661,11 +1846,12 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti space.funcs = O->funs; space.structs = O->structs; - space.vars = O->vars; - - (**parsed_func_ret).address = O->assembly->count; - /*if (!_slang_assemble_function (O->assembly, *parsed_func_ret, &space)) - return 0;*/ + space.vars = O->vars;
+ if (!_slang_assemble_function (O->assembly, *parsed_func_ret, &space, O->machine, C->atoms))
+ {
+ const char *name = slang_atom_pool_id (C->atoms, (**parsed_func_ret).header.a_name); + return 0;
+ } } return 1; } @@ -1676,17 +1862,19 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O) { - slang_function *dummy_func; - switch (*C->I++) { case DECLARATION_INIT_DECLARATOR_LIST: if (!parse_init_declarator_list (C, O)) return 0; break; - case DECLARATION_FUNCTION_PROTOTYPE: - if (!parse_function (C, O, 0, &dummy_func)) - return 0; + case DECLARATION_FUNCTION_PROTOTYPE:
+ {
+ slang_function *dummy_func;
+ + if (!parse_function (C, O, 0, &dummy_func)) + return 0;
+ } break; default: return 0; @@ -1703,21 +1891,26 @@ static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *u {
slang_output_ctx o;
+ /* setup output context */
o.funs = &unit->functions;
o.structs = &unit->structs;
o.vars = &unit->globals;
o.assembly = unit->assembly;
- o.global_pool = &unit->global_pool;
- + o.global_pool = unit->global_pool;
+ o.machine = unit->machine;
+
+ /* parse individual functions and declarations */ while (*C->I != EXTERNAL_NULL) - {
- slang_function *func;
- + { switch (*C->I++) { - case EXTERNAL_FUNCTION_DEFINITION: - if (!parse_function (C, &o, 1, &func)) - return 0; + case EXTERNAL_FUNCTION_DEFINITION:
+ {
+ slang_function *func;
+ + if (!parse_function (C, &o, 1, &func)) + return 0;
+ } break; case EXTERNAL_DECLARATION: if (!parse_declaration (C, &o)) @@ -1737,36 +1930,38 @@ static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *u #define BUILTIN_TOTAL 3 static int compile_binary (const byte *prod, slang_translation_unit *unit, slang_unit_type type, - slang_info_log *log, slang_translation_unit *builtins) + slang_info_log *log, slang_translation_unit *builtins, slang_assembly_file *file,
+ slang_var_pool *pool, slang_machine *mach, slang_translation_unit *downlink,
+ slang_atom_pool *atoms) { - slang_parse_ctx C; + slang_parse_ctx C;
+
+ /* create translation unit object */
+ if (file != NULL)
+ {
+ if (!slang_translation_unit_construct2 (unit, file, pool, mach, atoms))
+ return 0;
+ unit->type = type;
+ } /* set-up parse context */ C.I = prod; C.L = log; C.parsing_builtin = builtins == NULL;
- C.global_scope = 1; + C.global_scope = 1;
+ C.atoms = unit->atom_pool;
if (!check_revision (&C)) - return 0; - - /* create translation unit object */ - slang_translation_unit_construct (unit); - unit->type = type; + {
+ slang_translation_unit_destruct (unit);
+ return 0;
+ } - if (builtins != NULL) + if (downlink != NULL) { - /* link to built-in functions */ - builtins[BUILTIN_COMMON].functions.outer_scope = &builtins[BUILTIN_CORE].functions; - builtins[BUILTIN_TARGET].functions.outer_scope = &builtins[BUILTIN_COMMON].functions; - unit->functions.outer_scope = &builtins[BUILTIN_TARGET].functions; - - /* link to built-in variables - core unit does not define any */ - builtins[BUILTIN_TARGET].globals.outer_scope = &builtins[BUILTIN_COMMON].globals; - unit->globals.outer_scope = &builtins[BUILTIN_TARGET].globals; - - /* link to built-in structure typedefs - only in common unit */ - unit->structs.outer_scope = &builtins[BUILTIN_COMMON].structs; + unit->functions.outer_scope = &downlink->functions; + unit->globals.outer_scope = &downlink->globals; + unit->structs.outer_scope = &downlink->structs; } /* parse translation unit */ @@ -1789,7 +1984,7 @@ static int compile_with_grammar (grammar id, const char *source, slang_translati if (!_slang_preprocess_version (source, &version, &start, log)) return 0; - /* check the syntax */ + /* check the syntax and generate its binary representation */ if (!grammar_fast_check (id, (const byte *) source + start, &prod, &size, 65536)) { char buf[1024]; @@ -1798,8 +1993,10 @@ static int compile_with_grammar (grammar id, const char *source, slang_translati slang_info_log_error (log, buf); return 0; } - - if (!compile_binary (prod, unit, type, log, builtins)) +
+ /* syntax is okay - translate it to internal representation */ + if (!compile_binary (prod, unit, type, log, builtins, NULL, NULL, NULL,
+ &builtins[BUILTIN_TARGET], NULL)) { grammar_alloc_free (prod); return 0; @@ -1858,26 +2055,33 @@ static int compile (grammar *id, slang_translation_unit *builtin_units, int *com /* if parsing user-specified shader, load built-in library */
if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
{
+ /* compile core functionality first */
if (!compile_binary (slang_core_gc, &builtin_units[BUILTIN_CORE],
- slang_unit_fragment_builtin, log, NULL))
+ slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,
+ unit->machine, NULL, unit->atom_pool))
return 0;
compiled[BUILTIN_CORE] = 1;
+ /* compile common functions and variables, link to core */
if (!compile_binary (slang_common_builtin_gc, &builtin_units[BUILTIN_COMMON],
- slang_unit_fragment_builtin, log, NULL))
+ slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,
+ unit->machine, &builtin_units[BUILTIN_CORE], unit->atom_pool))
return 0;
compiled[BUILTIN_COMMON] = 1;
+ /* compile target-specific functions and variables, link to common */
if (type == slang_unit_fragment_shader)
{
if (!compile_binary (slang_fragment_builtin_gc, &builtin_units[BUILTIN_TARGET],
- slang_unit_fragment_builtin, log, NULL))
+ slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,
+ unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))
return 0;
}
else if (type == slang_unit_vertex_shader)
{
if (!compile_binary (slang_vertex_builtin_gc, &builtin_units[BUILTIN_TARGET],
- slang_unit_vertex_builtin, log, NULL))
+ slang_unit_vertex_builtin, log, NULL, unit->assembly, unit->global_pool,
+ unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))
return 0;
}
compiled[BUILTIN_TARGET] = 1;
@@ -1899,20 +2103,28 @@ int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit {
int success; grammar id = 0; - slang_translation_unit builtin_units[BUILTIN_TOTAL];
- int compiled[BUILTIN_TOTAL] = { 0 }; - +// slang_translation_unit builtin_units[BUILTIN_TOTAL];
+ slang_translation_unit *builtin_units;
+ int compiled[BUILTIN_TOTAL] = { 0 };
+
+ /* create the main unit first */
+ if (!slang_translation_unit_construct (unit))
+ return 0;
+ unit->type = type; +
+ builtin_units = (slang_translation_unit *) slang_alloc_malloc (BUILTIN_TOTAL * sizeof (slang_translation_unit)); success = compile (&id, builtin_units, compiled, source, unit, type, log); - /* destroy built-in library */ - if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) + /* destroy built-in library */
+ /* XXX: free with the unit */ + /*if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) {
int i;
for (i = 0; i < BUILTIN_TOTAL; i++)
if (compiled[i] != 0) slang_translation_unit_destruct (&builtin_units[i]); - }
+ }*/
if (id != 0) grammar_destroy (id);
diff --git a/src/mesa/shader/slang/slang_compile.h b/src/mesa/shader/slang/slang_compile.h index dd774dd35ee..8c7b96c9702 100644 --- a/src/mesa/shader/slang/slang_compile.h +++ b/src/mesa/shader/slang/slang_compile.h @@ -54,10 +54,18 @@ typedef struct slang_translation_unit_ slang_struct_scope structs; slang_unit_type type;
struct slang_assembly_file_ *assembly;
- slang_var_pool global_pool; + int free_assembly;
+ slang_var_pool *global_pool;
+ int free_global_pool;
+ struct slang_machine_ *machine;
+ int free_machine;
+ slang_atom_pool *atom_pool;
+ int free_atom_pool; } slang_translation_unit; -int slang_translation_unit_construct (slang_translation_unit *); +int slang_translation_unit_construct (slang_translation_unit *);
+int slang_translation_unit_construct2 (slang_translation_unit *, struct slang_assembly_file_ *,
+ slang_var_pool *, struct slang_machine_ *, slang_atom_pool *); void slang_translation_unit_destruct (slang_translation_unit *); typedef struct slang_info_log_ diff --git a/src/mesa/shader/slang/slang_compile_function.c b/src/mesa/shader/slang/slang_compile_function.c index 970c6faef04..d62b009e662 100644 --- a/src/mesa/shader/slang/slang_compile_function.c +++ b/src/mesa/shader/slang/slang_compile_function.c @@ -31,7 +31,6 @@ #include "imports.h"
#include "slang_utility.h"
#include "slang_compile_variable.h"
-#include "slang_compile_struct.h"
#include "slang_compile_operation.h"
#include "slang_compile_function.h"
@@ -91,15 +90,15 @@ void slang_function_scope_destruct (slang_function_scope *scope) slang_alloc_free (scope->functions);
}
-int slang_function_scope_find_by_name (slang_function_scope *funcs, const char *name, int all_scopes)
+int slang_function_scope_find_by_name (slang_function_scope *funcs, slang_atom a_name, int all_scopes)
{
unsigned int i;
for (i = 0; i < funcs->num_functions; i++)
- if (slang_string_compare (name, funcs->functions[i].header.name) == 0)
+ if (a_name == funcs->functions[i].header.a_name)
return 1;
if (all_scopes && funcs->outer_scope != NULL)
- return slang_function_scope_find_by_name (funcs->outer_scope, name, 1);
+ return slang_function_scope_find_by_name (funcs->outer_scope, a_name, 1);
return 0;
}
@@ -110,10 +109,10 @@ slang_function *slang_function_scope_find (slang_function_scope *funcs, slang_fu for (i = 0; i < funcs->num_functions; i++)
{
- slang_function *f = funcs->functions + i;
+ slang_function *f = &funcs->functions[i];
unsigned int j;
- if (slang_string_compare (fun->header.name, f->header.name) != 0)
+ if (fun->header.a_name != f->header.a_name)
continue;
if (fun->param_count != f->param_count)
continue;
diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h index 7f13bffa92f..59743dfc29e 100644 --- a/src/mesa/shader/slang/slang_compile_function.h +++ b/src/mesa/shader/slang/slang_compile_function.h @@ -58,7 +58,7 @@ typedef struct slang_function_scope_ int slang_function_scope_construct (slang_function_scope *);
void slang_function_scope_destruct (slang_function_scope *);
-int slang_function_scope_find_by_name (slang_function_scope *, const char *, int);
+int slang_function_scope_find_by_name (slang_function_scope *, slang_atom, int);
slang_function *slang_function_scope_find (slang_function_scope *, slang_function *, int);
#ifdef __cplusplus
diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c index f6d371a44ba..6783f1dc78d 100644 --- a/src/mesa/shader/slang/slang_compile_operation.c +++ b/src/mesa/shader/slang/slang_compile_operation.c @@ -31,9 +31,7 @@ #include "imports.h"
#include "slang_utility.h"
#include "slang_compile_variable.h"
-#include "slang_compile_struct.h"
#include "slang_compile_operation.h"
-#include "slang_compile_function.h"
/* slang_operation */
@@ -43,7 +41,7 @@ int slang_operation_construct (slang_operation *oper) oper->children = NULL;
oper->num_children = 0;
oper->literal = (float) 0;
- oper->identifier = NULL;
+ oper->a_id = SLANG_ATOM_NULL;
oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
if (oper->locals == NULL)
return 0;
@@ -62,7 +60,6 @@ void slang_operation_destruct (slang_operation *oper) for (i = 0; i < oper->num_children; i++)
slang_operation_destruct (oper->children + i);
slang_alloc_free (oper->children);
- slang_alloc_free (oper->identifier);
slang_variable_scope_destruct (oper->locals);
slang_alloc_free (oper->locals);
}
@@ -94,15 +91,7 @@ int slang_operation_copy (slang_operation *x, const slang_operation *y) return 0;
}
z.literal = y->literal;
- if (y->identifier != NULL)
- {
- z.identifier = slang_string_duplicate (y->identifier);
- if (z.identifier == NULL)
- {
- slang_operation_destruct (&z);
- return 0;
- }
- }
+ z.a_id = y->a_id;
if (!slang_variable_scope_copy (z.locals, y->locals))
{
slang_operation_destruct (&z);
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h index 54b2d17df6c..9e64848a0a1 100644 --- a/src/mesa/shader/slang/slang_compile_operation.h +++ b/src/mesa/shader/slang/slang_compile_operation.h @@ -101,7 +101,7 @@ typedef struct slang_operation_ struct slang_operation_ *children;
unsigned int num_children;
float literal; /* type: bool, literal_int, literal_float */
- char *identifier; /* type: asm, identifier, call, field */
+ slang_atom a_id; /* type: asm, identifier, call, field */
slang_variable_scope *locals;
} slang_operation;
diff --git a/src/mesa/shader/slang/slang_compile_struct.c b/src/mesa/shader/slang/slang_compile_struct.c index bad58f4e5be..0828d235989 100644 --- a/src/mesa/shader/slang/slang_compile_struct.c +++ b/src/mesa/shader/slang/slang_compile_struct.c @@ -32,8 +32,6 @@ #include "slang_utility.h"
#include "slang_compile_variable.h"
#include "slang_compile_struct.h"
-#include "slang_compile_operation.h"
-#include "slang_compile_function.h"
/* slang_struct_scope */
@@ -86,15 +84,15 @@ int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_scope *y) return 1;
}
-slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *name, int all_scopes)
+slang_struct *slang_struct_scope_find (slang_struct_scope *stru, slang_atom a_name, int all_scopes)
{
unsigned int i;
for (i = 0; i < stru->num_structs; i++)
- if (slang_string_compare (name, stru->structs[i].name) == 0)
- return stru->structs + i;
+ if (a_name == stru->structs[i].a_name)
+ return &stru->structs[i];
if (all_scopes && stru->outer_scope != NULL)
- return slang_struct_scope_find (stru->outer_scope, name, 1);
+ return slang_struct_scope_find (stru->outer_scope, a_name, 1);
return NULL;
}
@@ -102,7 +100,7 @@ slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *nam int slang_struct_construct (slang_struct *stru)
{
- stru->name = NULL;
+ stru->a_name = SLANG_ATOM_NULL;
stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
if (stru->fields == NULL)
return 0;
@@ -130,7 +128,6 @@ int slang_struct_construct (slang_struct *stru) void slang_struct_destruct (slang_struct *stru)
{
- slang_alloc_free (stru->name);
slang_variable_scope_destruct (stru->fields);
slang_alloc_free (stru->fields);
slang_struct_scope_destruct (stru->structs);
@@ -143,15 +140,7 @@ int slang_struct_copy (slang_struct *x, const slang_struct *y) if (!slang_struct_construct (&z))
return 0;
- if (y->name != NULL)
- {
- z.name = slang_string_duplicate (y->name);
- if (z.name == NULL)
- {
- slang_struct_destruct (&z);
- return 0;
- }
- }
+ z.a_name = y->a_name;
if (!slang_variable_scope_copy (z.fields, y->fields))
{
slang_struct_destruct (&z);
@@ -175,15 +164,16 @@ int slang_struct_equal (const slang_struct *x, const slang_struct *y) return 0;
for (i = 0; i < x->fields->num_variables; i++)
{
- slang_variable *varx = x->fields->variables + i;
- slang_variable *vary = y->fields->variables + i;
- if (slang_string_compare (varx->name, vary->name) != 0)
+ slang_variable *varx = &x->fields->variables[i];
+ slang_variable *vary = &y->fields->variables[i];
+
+ if (varx->a_name != vary->a_name)
return 0;
if (!slang_type_specifier_equal (&varx->type.specifier, &vary->type.specifier))
return 0;
if (varx->type.specifier.type == slang_spec_array)
{
- /* TODO compare array sizes */
+ /* TODO: compare array sizes */
}
}
return 1;
diff --git a/src/mesa/shader/slang/slang_compile_struct.h b/src/mesa/shader/slang/slang_compile_struct.h index 10af980216f..4798b6042fc 100644 --- a/src/mesa/shader/slang/slang_compile_struct.h +++ b/src/mesa/shader/slang/slang_compile_struct.h @@ -39,11 +39,11 @@ typedef struct slang_struct_scope_ int slang_struct_scope_construct (slang_struct_scope *);
void slang_struct_scope_destruct (slang_struct_scope *);
int slang_struct_scope_copy (slang_struct_scope *, const slang_struct_scope *);
-struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, const char *, int);
+struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, slang_atom, int);
typedef struct slang_struct_
{
- char *name;
+ slang_atom a_name;
struct slang_variable_scope_ *fields;
slang_struct_scope *structs;
} slang_struct;
diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c index 39aabd8312d..da3b24fb7ef 100644 --- a/src/mesa/shader/slang/slang_compile_variable.c +++ b/src/mesa/shader/slang/slang_compile_variable.c @@ -33,7 +33,6 @@ #include "slang_compile_variable.h"
#include "slang_compile_struct.h"
#include "slang_compile_operation.h"
-#include "slang_compile_function.h"
/* slang_type_specifier_type */
@@ -269,17 +268,18 @@ int slang_variable_construct (slang_variable *var) {
if (!slang_fully_specified_type_construct (&var->type))
return 0;
- var->name = NULL;
+ var->a_name = SLANG_ATOM_NULL;
var->array_size = NULL;
var->initializer = NULL;
var->address = ~0;
+ var->size = 0;
+ var->global = 0;
return 1;
}
void slang_variable_destruct (slang_variable *var)
{
slang_fully_specified_type_destruct (&var->type);
- slang_alloc_free (var->name);
if (var->array_size != NULL)
{
slang_operation_destruct (var->array_size);
@@ -303,15 +303,7 @@ int slang_variable_copy (slang_variable *x, const slang_variable *y) slang_variable_destruct (&z);
return 0;
}
- if (y->name != NULL)
- {
- z.name = slang_string_duplicate (y->name);
- if (z.name == NULL)
- {
- slang_variable_destruct (&z);
- return 0;
- }
- }
+ z.a_name = y->a_name;
if (y->array_size != NULL)
{
z.array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
@@ -352,20 +344,23 @@ int slang_variable_copy (slang_variable *x, const slang_variable *y) return 0;
}
}
+ z.address = y->address;
+ z.size = y->size;
+ z.global = y->global;
slang_variable_destruct (x);
*x = z;
return 1;
}
-slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all)
+slang_variable *_slang_locate_variable (slang_variable_scope *scope, slang_atom a_name, int all)
{
unsigned int i;
for (i = 0; i < scope->num_variables; i++)
- if (slang_string_compare (name, scope->variables[i].name) == 0)
- return scope->variables + i;
+ if (a_name == scope->variables[i].a_name)
+ return &scope->variables[i];
if (all && scope->outer_scope != NULL)
- return _slang_locate_variable (scope->outer_scope, name, 1);
+ return _slang_locate_variable (scope->outer_scope, a_name, 1);
return NULL;
}
diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h index d82a661edaf..fc42280ae56 100644 --- a/src/mesa/shader/slang/slang_compile_variable.h +++ b/src/mesa/shader/slang/slang_compile_variable.h @@ -109,17 +109,19 @@ int slang_variable_scope_copy (slang_variable_scope *, const slang_variable_scop typedef struct slang_variable_
{
slang_fully_specified_type type;
- char *name;
+ slang_atom a_name;
struct slang_operation_ *array_size; /* type: spec_array */
struct slang_operation_ *initializer;
unsigned int address;
+ unsigned int size;
+ int global;
} slang_variable;
int slang_variable_construct (slang_variable *);
void slang_variable_destruct (slang_variable *);
int slang_variable_copy (slang_variable *, const slang_variable *);
-slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all);
+slang_variable *_slang_locate_variable (slang_variable_scope *scope, slang_atom a_name, int all);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_execute.c b/src/mesa/shader/slang/slang_execute.c index e4df8325776..a40a35cd578 100644 --- a/src/mesa/shader/slang/slang_execute.c +++ b/src/mesa/shader/slang/slang_execute.c @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -34,7 +34,24 @@ #include "slang_storage.h"
#include "slang_execute.h"
-#define DEBUG_SLANG 1
+#define DEBUG_SLANG 0
+
+void slang_machine_init (slang_machine *mach)
+{
+ mach->ip = 0;
+ mach->sp = SLANG_MACHINE_STACK_SIZE;
+ mach->bp = 0;
+ mach->kill = 0;
+ mach->exit = 0;
+}
+
+int _slang_execute (const slang_assembly_file *file)
+{
+ slang_machine mach;
+
+ slang_machine_init (&mach);
+ return _slang_execute2 (file, &mach);
+}
#if DEBUG_SLANG
@@ -44,6 +61,7 @@ static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i) switch (a->type)
{
+ /* core */
case slang_asm_none:
fprintf (f, "none");
break;
@@ -74,12 +92,36 @@ static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i) case slang_asm_float_less:
fprintf (f, "float_less");
break;
- case slang_asm_float_equal:
+ case slang_asm_float_equal_exp:
+ fprintf (f, "float_equal");
+ break;
+ case slang_asm_float_equal_int:
fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_to_int:
fprintf (f, "float_to_int");
break;
+ case slang_asm_float_sine:
+ fprintf (f, "float_sine");
+ break;
+ case slang_asm_float_arcsine:
+ fprintf (f, "float_arcsine");
+ break;
+ case slang_asm_float_arctan:
+ fprintf (f, "float_arctan");
+ break;
+ case slang_asm_float_power:
+ fprintf (f, "float_power");
+ break;
+ case slang_asm_float_log2:
+ fprintf (f, "float_log2");
+ break;
+ case slang_asm_float_floor:
+ fprintf (f, "float_floor");
+ break;
+ case slang_asm_float_ceil:
+ fprintf (f, "float_ceil");
+ break;
case slang_asm_int_copy:
fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);
break;
@@ -158,6 +200,16 @@ static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i) case slang_asm_exit:
fprintf (f, "exit");
break;
+ /* mesa-specific extensions */
+ case slang_asm_float_print:
+ fprintf (f, "float_print");
+ break;
+ case slang_asm_int_print:
+ fprintf (f, "int_print");
+ break;
+ case slang_asm_bool_print:
+ fprintf (f, "bool_print");
+ break;
default:
break;
}
@@ -186,11 +238,13 @@ static void dump (const slang_assembly_file *file) #endif
-int _slang_execute (const slang_assembly_file *file)
+int _slang_execute2 (const slang_assembly_file *file, slang_machine *mach)
{
- slang_machine mach;
+ slang_machine_slot *stack;
-#ifdef DEBUG_SLANG
+#if DEBUG_SLANG
+ static unsigned int counter = 0;
+ char filename[256];
FILE *f;
#endif
@@ -198,161 +252,195 @@ int _slang_execute (const slang_assembly_file *file) static_assert(sizeof (GLfloat) == 4);
static_assert(sizeof (GLuint) == 4);
- mach.ip = 0;
- mach.sp = SLANG_MACHINE_STACK_SIZE;
- mach.bp = 0;
- mach.kill = 0;
- mach.exit = 0;
- mach.global = mach.mem;
- mach.stack = mach.global + SLANG_MACHINE_GLOBAL_SIZE;
-
#if DEBUG_SLANG
dump (file);
- f = fopen ("~mesa-slang-assembly-execution.txt", "w");
+ counter++;
+ _mesa_sprintf (filename, "~mesa-slang-assembly-exec-(%u).txt", counter);
+ f = fopen (filename, "w");
#endif
- while (!mach.exit)
+ stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE;
+
+ while (!mach->exit)
{
- slang_assembly *a;
+ slang_assembly *a = &file->code[mach->ip];
#if DEBUG_SLANG
- if (f != NULL)
+ if (f != NULL && a->type != slang_asm_none)
{
unsigned int i;
- dump_instruction (f, file->code + mach.ip, mach.ip);
- fprintf (f, "\t\tsp=%u bp=%u\n", mach.sp, mach.bp);
- for (i = mach.sp; i < SLANG_MACHINE_STACK_SIZE; i++)
- fprintf (f, "\t%.5u\t%6f\t%u\n", i, mach.stack[i]._float, mach.stack[i]._addr);
+ dump_instruction (f, file->code + mach->ip, mach->ip);
+ fprintf (f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp);
+ for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++)
+ fprintf (f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, stack[i]._addr);
fflush (f);
}
#endif
- a = file->code + mach.ip;
- mach.ip++;
+ mach->ip++;
switch (a->type)
{
+ /* core */
case slang_asm_none:
break;
case slang_asm_float_copy:
case slang_asm_int_copy:
case slang_asm_bool_copy:
- mach.mem[mach.stack[mach.sp + a->param[0] / 4]._addr + a->param[1] / 4]._float =
- mach.stack[mach.sp]._float;
- mach.sp++;
+ mach->mem[(stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4]._float =
+ stack[mach->sp]._float;
+ mach->sp++;
break;
case slang_asm_float_move:
case slang_asm_int_move:
case slang_asm_bool_move:
- mach.stack[mach.sp + a->param[0] / 4]._float =
- mach.stack[mach.sp + (mach.stack[mach.sp]._addr + a->param[1]) / 4]._float;
+ stack[mach->sp + a->param[0] / 4]._float =
+ stack[mach->sp + (stack[mach->sp]._addr + a->param[1]) / 4]._float;
break;
case slang_asm_float_push:
case slang_asm_int_push:
case slang_asm_bool_push:
- mach.sp--;
- mach.stack[mach.sp]._float = a->literal;
+ mach->sp--;
+ stack[mach->sp]._float = a->literal;
break;
case slang_asm_float_deref:
case slang_asm_int_deref:
case slang_asm_bool_deref:
- mach.stack[mach.sp]._float = mach.mem[mach.stack[mach.sp]._addr]._float;
+ stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float;
break;
case slang_asm_float_add:
- mach.stack[mach.sp + 1]._float += mach.stack[mach.sp]._float;
- mach.sp++;
+ stack[mach->sp + 1]._float += stack[mach->sp]._float;
+ mach->sp++;
break;
case slang_asm_float_multiply:
- mach.stack[mach.sp + 1]._float *= mach.stack[mach.sp]._float;
- mach.sp++;
+ stack[mach->sp + 1]._float *= stack[mach->sp]._float;
+ mach->sp++;
break;
case slang_asm_float_divide:
- mach.stack[mach.sp + 1]._float /= mach.stack[mach.sp]._float;
- mach.sp++;
+ stack[mach->sp + 1]._float /= stack[mach->sp]._float;
+ mach->sp++;
break;
case slang_asm_float_negate:
- mach.stack[mach.sp]._float = -mach.stack[mach.sp]._float;
+ stack[mach->sp]._float = -stack[mach->sp]._float;
break;
case slang_asm_float_less:
- mach.stack[mach.sp + 1]._float =
- mach.stack[mach.sp + 1]._float < mach.stack[mach.sp]._float ? 1.0f : 0.0f;
- mach.sp++;
+ stack[mach->sp + 1]._float =
+ stack[mach->sp + 1]._float < stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;
+ mach->sp++;
+ break;
+ case slang_asm_float_equal_exp:
+ stack[mach->sp + 1]._float =
+ stack[mach->sp + 1]._float == stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0;
+ mach->sp++;
break;
- case slang_asm_float_equal:
- mach.sp--;
- mach.stack[mach.sp]._float = mach.stack[mach.sp + 1 + a->param[0] / 4]._float ==
- mach.stack[mach.sp + 1 + a->param[1] / 4]._float ? 1.0f : 0.0f;
+ case slang_asm_float_equal_int:
+ mach->sp--;
+ stack[mach->sp]._float = stack[mach->sp + 1 + a->param[0] / 4]._float ==
+ stack[mach->sp + 1 + a->param[1] / 4]._float ? (GLfloat) 1 : (GLfloat) 0;
break;
case slang_asm_float_to_int:
- mach.stack[mach.sp]._float = (GLfloat) (GLint) mach.stack[mach.sp]._float;
+ stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float;
+ break;
+ case slang_asm_float_sine:
+ stack[mach->sp]._float = (GLfloat) _mesa_sin (stack[mach->sp]._float);
+ break;
+ case slang_asm_float_arcsine:
+ stack[mach->sp]._float = _mesa_asinf (stack[mach->sp]._float);
+ break;
+ case slang_asm_float_arctan:
+ stack[mach->sp]._float = _mesa_atanf (stack[mach->sp]._float);
+ break;
+ case slang_asm_float_power:
+ stack[mach->sp + 1]._float =
+ (GLfloat) _mesa_pow (stack[mach->sp + 1]._float, stack[mach->sp]._float);
+ mach->sp++;
+ break;
+ case slang_asm_float_log2:
+ stack[mach->sp]._float = LOG2 (stack[mach->sp]._float);
+ break;
+ case slang_asm_float_floor:
+ stack[mach->sp]._float = FLOORF (stack[mach->sp]._float);
+ break;
+ case slang_asm_float_ceil:
+ stack[mach->sp]._float = CEILF (stack[mach->sp]._float);
break;
case slang_asm_int_to_float:
break;
case slang_asm_int_to_addr:
- mach.stack[mach.sp]._addr = (GLuint) (GLint) mach.stack[mach.sp]._float;
+ stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float;
break;
case slang_asm_addr_copy:
- mach.mem[mach.stack[mach.sp + 1]._addr]._addr = mach.stack[mach.sp]._addr;
- mach.sp++;
+ mach->mem[stack[mach->sp + 1]._addr / 4]._addr = stack[mach->sp]._addr;
+ mach->sp++;
break;
case slang_asm_addr_push:
- mach.sp--;
- mach.stack[mach.sp]._addr = a->param[0];
+ mach->sp--;
+ stack[mach->sp]._addr = a->param[0];
break;
case slang_asm_addr_deref:
- mach.stack[mach.sp]._addr = mach.mem[mach.stack[mach.sp]._addr]._addr;
+ stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr;
break;
case slang_asm_addr_add:
- mach.stack[mach.sp + 1]._addr += mach.stack[mach.sp]._addr;
- mach.sp++;
+ stack[mach->sp + 1]._addr += stack[mach->sp]._addr;
+ mach->sp++;
break;
case slang_asm_addr_multiply:
- mach.stack[mach.sp + 1]._addr *= mach.stack[mach.sp]._addr;
- mach.sp++;
+ stack[mach->sp + 1]._addr *= stack[mach->sp]._addr;
+ mach->sp++;
break;
case slang_asm_jump:
- mach.ip = a->param[0];
+ mach->ip = a->param[0];
break;
case slang_asm_jump_if_zero:
- if (mach.stack[mach.sp]._float == 0.0f)
- mach.ip = a->param[0];
- mach.sp++;
+ if (stack[mach->sp]._float == 0.0f)
+ mach->ip = a->param[0];
+ mach->sp++;
break;
case slang_asm_enter:
- mach.sp--;
- mach.stack[mach.sp]._addr = mach.bp;
- mach.bp = mach.sp + a->param[0] / 4;
+ mach->sp--;
+ stack[mach->sp]._addr = mach->bp;
+ mach->bp = mach->sp + a->param[0] / 4;
break;
case slang_asm_leave:
- mach.bp = mach.stack[mach.sp]._addr;
- mach.sp++;
+ mach->bp = stack[mach->sp]._addr;
+ mach->sp++;
break;
case slang_asm_local_alloc:
- mach.sp -= a->param[0] / 4;
+ mach->sp -= a->param[0] / 4;
break;
case slang_asm_local_free:
- mach.sp += a->param[0] / 4;
+ mach->sp += a->param[0] / 4;
break;
case slang_asm_local_addr:
- mach.sp--;
- mach.stack[mach.sp]._addr = SLANG_MACHINE_GLOBAL_SIZE * 4 + mach.bp * 4 -
+ mach->sp--;
+ stack[mach->sp]._addr = SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 -
(a->param[0] + a->param[1]) + 4;
break;
case slang_asm_call:
- mach.sp--;
- mach.stack[mach.sp]._addr = mach.ip;
- mach.ip = a->param[0];
+ mach->sp--;
+ stack[mach->sp]._addr = mach->ip;
+ mach->ip = a->param[0];
break;
case slang_asm_return:
- mach.ip = mach.stack[mach.sp]._addr;
- mach.sp++;
+ mach->ip = stack[mach->sp]._addr;
+ mach->sp++;
break;
case slang_asm_discard:
- mach.kill = 1;
+ mach->kill = 1;
break;
case slang_asm_exit:
- mach.exit = 1;
+ mach->exit = 1;
+ break;
+ /* mesa-specific extensions */
+ case slang_asm_float_print:
+ _mesa_printf ("slang print: %f\n", stack[mach->sp]._float);
+ break;
+ case slang_asm_int_print:
+ _mesa_printf ("slang print: %d\n", (GLint) stack[mach->sp]._float);
+ break;
+ case slang_asm_bool_print:
+ _mesa_printf ("slang print: %s\n", (GLint) stack[mach->sp]._float ? "true" : "false");
break;
}
}
@@ -362,6 +450,6 @@ int _slang_execute (const slang_assembly_file *file) fclose (f);
#endif
- return 0;
+ return 1;
}
diff --git a/src/mesa/shader/slang/slang_execute.h b/src/mesa/shader/slang/slang_execute.h index f911574b159..a3b326f3155 100644 --- a/src/mesa/shader/slang/slang_execute.h +++ b/src/mesa/shader/slang/slang_execute.h @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -47,11 +47,12 @@ typedef struct slang_machine_ GLuint kill; /* discard the fragment */
GLuint exit; /* terminate the shader */
slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE];
- slang_machine_slot *global;
- slang_machine_slot *stack;
} slang_machine;
+void slang_machine_init (slang_machine *);
+
int _slang_execute (const slang_assembly_file *);
+int _slang_execute2 (const slang_assembly_file *, slang_machine *);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_preprocess.c b/src/mesa/shader/slang/slang_preprocess.c index b1f62ded3da..3601a384f7a 100644 --- a/src/mesa/shader/slang/slang_preprocess.c +++ b/src/mesa/shader/slang/slang_preprocess.c @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -30,6 +30,7 @@ #include "imports.h"
#include "grammar_mesa.h"
+#include "slang_utility.h"
#include "slang_compile.h"
#include "slang_preprocess.h"
diff --git a/src/mesa/shader/slang/slang_storage.c b/src/mesa/shader/slang/slang_storage.c index 8a608c49023..a2d1ab9314b 100644 --- a/src/mesa/shader/slang/slang_storage.c +++ b/src/mesa/shader/slang/slang_storage.c @@ -31,15 +31,17 @@ #include "imports.h" #include "slang_utility.h" #include "slang_storage.h" -#include "slang_assemble.h" +#include "slang_assemble.h"
+#include "slang_execute.h" /* slang_storage_array */ -void slang_storage_array_construct (slang_storage_array *arr) +int slang_storage_array_construct (slang_storage_array *arr) { arr->type = slang_stor_aggregate; arr->aggregate = NULL; - arr->length = 0; + arr->length = 0;
+ return 1; } void slang_storage_array_destruct (slang_storage_array *arr) @@ -53,15 +55,17 @@ void slang_storage_array_destruct (slang_storage_array *arr) /* slang_storage_aggregate */ -void slang_storage_aggregate_construct (slang_storage_aggregate *agg) +int slang_storage_aggregate_construct (slang_storage_aggregate *agg) { agg->arrays = NULL; - agg->count = 0; + agg->count = 0;
+ return 1; } void slang_storage_aggregate_destruct (slang_storage_aggregate *agg) { - unsigned int i; + unsigned int i;
+ for (i = 0; i < agg->count; i++) slang_storage_array_destruct (agg->arrays + i); slang_alloc_free (agg->arrays); @@ -75,7 +79,8 @@ static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggr if (agg->arrays != NULL) { arr = agg->arrays + agg->count; - slang_storage_array_construct (arr); + if (!slang_storage_array_construct (arr))
+ return NULL; agg->count++; } return arr; @@ -97,7 +102,7 @@ static int aggregate_vector (slang_storage_aggregate *agg, slang_storage_type ba static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type, unsigned int dimension) { - slang_storage_array *arr = slang_storage_aggregate_push_new (agg); + slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
if (arr == NULL) return 0; arr->type = slang_stor_aggregate; @@ -106,26 +111,80 @@ static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type ba slang_storage_aggregate)); if (arr->aggregate == NULL) return 0; - slang_storage_aggregate_construct (arr->aggregate); + if (!slang_storage_aggregate_construct (arr->aggregate))
+ {
+ slang_alloc_free (arr->aggregate);
+ arr->aggregate = NULL;
+ return 0;
+ } if (!aggregate_vector (arr->aggregate, basic_type, dimension)) return 0; return 1; } static int aggregate_variables (slang_storage_aggregate *agg, slang_variable_scope *vars, - slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *globals) + slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *globals,
+ slang_machine *mach, slang_assembly_file *file, slang_atom_pool *atoms) { unsigned int i; for (i = 0; i < vars->num_variables; i++) if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier, - vars->variables[i].array_size, funcs, structs, globals)) + vars->variables[i].array_size, funcs, structs, globals, mach, file, atoms)) return 0; return 1; } +
+static int eval_array_size (slang_assembly_file *file, slang_machine *pmach,
+ slang_assembly_name_space *space, slang_operation *array_size, GLuint *plength,
+ slang_atom_pool *atoms)
+{
+ slang_assembly_file_restore_point point;
+ slang_assembly_local_info info;
+ slang_assembly_flow_control flow;
+ slang_assembly_stack_info stk;
+ slang_machine mach;
+
+ /* save the current assembly */
+ if (!slang_assembly_file_restore_point_save (file, &point))
+ return 0;
+
+ /* setup the machine */
+ mach = *pmach;
+ mach.ip = file->count;
+
+ /* allocate local storage for expression */
+ info.ret_size = 0;
+ info.addr_tmp = 0;
+ info.swizzle_tmp = 4;
+ if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20))
+ return 0;
+ if (!slang_assembly_file_push_label (file, slang_asm_enter, 20))
+ return 0;
+
+ /* insert the actual expression */
+ if (!_slang_assemble_operation (file, array_size, 0, &flow, space, &info, &stk, pmach, atoms))
+ return 0;
+ if (!slang_assembly_file_push (file, slang_asm_exit))
+ return 0;
+
+ /* execute the expression */
+ if (!_slang_execute2 (file, &mach))
+ return 0;
+
+ /* the evaluated expression is on top of the stack */
+ *plength = (GLuint) mach.mem[mach.sp + SLANG_MACHINE_GLOBAL_SIZE]._float;
+ /* TODO: check if 0 < arr->length <= 65535 */
+
+ /* restore the old assembly */
+ if (!slang_assembly_file_restore_point_load (file, &point))
+ return 0;
+ return 1;
+}
int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec, slang_operation *array_size, slang_function_scope *funcs, slang_struct_scope *structs, - slang_variable_scope *vars) + slang_variable_scope *vars, slang_machine *mach, slang_assembly_file *file,
+ slang_atom_pool *atoms) { switch (spec->type) { @@ -167,15 +226,12 @@ int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifie case slang_spec_sampler2DShadow: return aggregate_vector (agg, slang_stor_int, 1); case slang_spec_struct: - return aggregate_variables (agg, spec->_struct->fields, funcs, structs, vars); + return aggregate_variables (agg, spec->_struct->fields, funcs, structs, vars, mach,
+ file, atoms); case slang_spec_array: { - slang_storage_array *arr; - slang_assembly_file file; - slang_assembly_flow_control flow; + slang_storage_array *arr;
slang_assembly_name_space space; - slang_assembly_local_info info; - slang_assembly_stack_info stk; arr = slang_storage_aggregate_push_new (agg); if (arr == NULL) @@ -185,21 +241,20 @@ int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifie slang_storage_aggregate)); if (arr->aggregate == NULL) return 0; - slang_storage_aggregate_construct (arr->aggregate); - if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs, vars)) - return 0; - slang_assembly_file_construct (&file); - space.funcs = funcs; - space.structs = structs; - space.vars = vars; - if (!_slang_assemble_operation (&file, array_size, 0, &flow, &space, &info, &stk)) - { - slang_assembly_file_destruct (&file); - return 0; + if (!slang_storage_aggregate_construct (arr->aggregate))
+ {
+ slang_alloc_free (arr->aggregate);
+ arr->aggregate = NULL;
+ return 0;
} - /* TODO: evaluate array size */ - slang_assembly_file_destruct (&file); - arr->length = 256; + if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs,
+ vars, mach, file, atoms)) + return 0;
+ space.funcs = funcs;
+ space.structs = structs;
+ space.vars = vars;
+ if (!eval_array_size (file, mach, &space, array_size, &arr->length, atoms))
+ return 0; } return 1; default: @@ -211,10 +266,12 @@ int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifie unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg) { - unsigned int i, size = 0; + unsigned int i, size = 0;
+ for (i = 0; i < agg->count; i++) { - unsigned int element_size; + unsigned int element_size;
+ if (agg->arrays[i].type == slang_stor_aggregate) element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate); else @@ -228,10 +285,12 @@ unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg) int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg) { - unsigned int i; + unsigned int i;
+ for (i = 0; i < agg->count; i++) { - unsigned int j; + unsigned int j;
+ for (j = 0; j < agg->arrays[i].length; j++) { if (agg->arrays[i].type == slang_stor_aggregate) @@ -241,7 +300,8 @@ int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage } else { - slang_storage_array *arr; + slang_storage_array *arr;
+ arr = slang_storage_aggregate_push_new (flat); if (arr == NULL) return 0; diff --git a/src/mesa/shader/slang/slang_storage.h b/src/mesa/shader/slang/slang_storage.h index b875ce6745a..a99f38f65c8 100644 --- a/src/mesa/shader/slang/slang_storage.h +++ b/src/mesa/shader/slang/slang_storage.h @@ -66,7 +66,7 @@ typedef struct slang_storage_array_ unsigned int length; } slang_storage_array; -void slang_storage_array_construct (slang_storage_array *); +int slang_storage_array_construct (slang_storage_array *); void slang_storage_array_destruct (slang_storage_array *); /* @@ -81,12 +81,13 @@ typedef struct slang_storage_aggregate_ unsigned int count; } slang_storage_aggregate; -void slang_storage_aggregate_construct (slang_storage_aggregate *); +int slang_storage_aggregate_construct (slang_storage_aggregate *); void slang_storage_aggregate_destruct (slang_storage_aggregate *); int _slang_aggregate_variable (slang_storage_aggregate *, struct slang_type_specifier_ *, struct slang_operation_ *, struct slang_function_scope_ *, slang_struct_scope *, - slang_variable_scope *); + slang_variable_scope *, struct slang_machine_ *, struct slang_assembly_file_ *,
+ slang_atom_pool *); /* returns total size (in machine units) of the given aggregate diff --git a/src/mesa/shader/slang/slang_utility.c b/src/mesa/shader/slang/slang_utility.c index c07e161c8d9..5075832a924 100644 --- a/src/mesa/shader/slang/slang_utility.c +++ b/src/mesa/shader/slang/slang_utility.c @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -31,43 +31,82 @@ #include "imports.h"
#include "slang_utility.h"
-void slang_alloc_free (void *ptr)
+char *slang_string_concat (char *dst, const char *src)
{
- _mesa_free (ptr);
+ return _mesa_strcpy (dst + _mesa_strlen (dst), src);
}
-void *slang_alloc_malloc (unsigned int size)
-{
- return _mesa_malloc (size);
-}
+/* slang_atom_pool */
-void *slang_alloc_realloc (void *ptr, unsigned int old_size, unsigned int size)
+void slang_atom_pool_construct (slang_atom_pool *pool)
{
- return _mesa_realloc (ptr, old_size, size);
-}
+ GLuint i;
-int slang_string_compare (const char *str1, const char *str2)
-{
- return _mesa_strcmp (str1, str2);
+ for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
+ pool->entries[i] = NULL;
}
-char *slang_string_copy (char *dst, const char *src)
+void slang_atom_pool_destruct (slang_atom_pool *pool)
{
- return _mesa_strcpy (dst, src);
-}
+ GLuint i;
-char *slang_string_concat (char *dst, const char *src)
-{
- return _mesa_strcpy (dst + _mesa_strlen (dst), src);
+ for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
+ {
+ slang_atom_entry *entry;
+
+ entry = pool->entries[i];
+ while (entry != NULL)
+ {
+ slang_atom_entry *next;
+
+ next = entry->next;
+ slang_alloc_free (entry->id);
+ slang_alloc_free (entry);
+ entry = next;
+ }
+ }
}
-char *slang_string_duplicate (const char *src)
+slang_atom slang_atom_pool_atom (slang_atom_pool *pool, const char *id)
{
- return _mesa_strdup (src);
+ GLuint hash;
+ const char *p = id;
+ slang_atom_entry **entry;
+
+ hash = 0;
+ while (*p != '\0')
+ {
+ GLuint g;
+
+ hash = (hash << 4) + (GLuint) *p++;
+ g = hash & 0xf0000000;
+ if (g != 0)
+ hash ^= g >> 24;
+ hash &= ~g;
+ }
+ hash %= SLANG_ATOM_POOL_SIZE;
+
+ entry = &pool->entries[hash];
+ while (*entry != NULL)
+ {
+ if (slang_string_compare ((**entry).id, id) == 0)
+ return (slang_atom) (**entry).id;
+ entry = &(**entry).next;
+ }
+
+ *entry = (slang_atom_entry *) slang_alloc_malloc (sizeof (slang_atom_entry));
+ if (*entry == NULL)
+ return SLANG_ATOM_NULL;
+
+ (**entry).next = NULL;
+ (**entry).id = slang_string_duplicate (id);
+ if ((**entry).id == NULL)
+ return SLANG_ATOM_NULL;
+ return (slang_atom) (**entry).id;
}
-unsigned int slang_string_length (const char *str)
+const char *slang_atom_pool_id (slang_atom_pool *pool, slang_atom atom)
{
- return _mesa_strlen (str);
+ return (const char *) atom;
}
diff --git a/src/mesa/shader/slang/slang_utility.h b/src/mesa/shader/slang/slang_utility.h index 2b040a44466..2d2ac8e42e4 100644 --- a/src/mesa/shader/slang/slang_utility.h +++ b/src/mesa/shader/slang/slang_utility.h @@ -1,8 +1,8 @@ /*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
- * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 2005-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"),
@@ -34,14 +34,37 @@ extern "C" { */
#define static_assert(expr) do { int _array[(expr) ? 1 : -1]; _array[0]; } while (0)
-void slang_alloc_free (void *);
-void *slang_alloc_malloc (unsigned int);
-void *slang_alloc_realloc (void *, unsigned int, unsigned int);
-int slang_string_compare (const char *, const char *);
-char *slang_string_copy (char *, const char *);
+#define slang_alloc_free(ptr) _mesa_free (ptr)
+#define slang_alloc_malloc(size) _mesa_malloc (size)
+#define slang_alloc_realloc(ptr, old_size, size) _mesa_realloc (ptr, old_size, size)
+#define slang_string_compare(str1, str2) _mesa_strcmp (str1, str2)
+#define slang_string_copy(dst, src) _mesa_strcpy (dst, src)
+#define slang_string_duplicate(src) _mesa_strdup (src)
+#define slang_string_length(str) _mesa_strlen (str)
+
char *slang_string_concat (char *, const char *);
-char *slang_string_duplicate (const char *);
-unsigned int slang_string_length (const char *);
+
+typedef GLvoid *slang_atom;
+
+#define SLANG_ATOM_NULL ((slang_atom) 0)
+
+typedef struct slang_atom_entry_
+{
+ char *id;
+ struct slang_atom_entry_ *next;
+} slang_atom_entry;
+
+#define SLANG_ATOM_POOL_SIZE 1023
+
+typedef struct slang_atom_pool_
+{
+ slang_atom_entry *entries[SLANG_ATOM_POOL_SIZE];
+} slang_atom_pool;
+
+void slang_atom_pool_construct (slang_atom_pool *);
+void slang_atom_pool_destruct (slang_atom_pool *);
+slang_atom slang_atom_pool_atom (slang_atom_pool *, const char *);
+const char *slang_atom_pool_id (slang_atom_pool *, slang_atom);
#ifdef __cplusplus
}
|