mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
intermediate code generator (not finished);
generic back-end interpreter (interprets directly intermediate code)
This commit is contained in:
parent
e5ff2b94ff
commit
02168254a8
15 changed files with 4059 additions and 77 deletions
1385
src/mesa/shader/slang/slang_assemble.c
Normal file
1385
src/mesa/shader/slang/slang_assemble.c
Normal file
File diff suppressed because it is too large
Load diff
145
src/mesa/shader/slang/slang_assemble.h
Normal file
145
src/mesa/shader/slang/slang_assemble.h
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_ASSEMBLE_H
|
||||
#define SLANG_ASSEMBLE_H
|
||||
|
||||
#include "slang_compile.h"
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum slang_assembly_type_
|
||||
{
|
||||
/* core */
|
||||
slang_asm_none,
|
||||
slang_asm_float_copy,
|
||||
slang_asm_float_move,
|
||||
slang_asm_float_push,
|
||||
slang_asm_float_deref,
|
||||
slang_asm_float_add,
|
||||
slang_asm_float_multiply,
|
||||
slang_asm_float_divide,
|
||||
slang_asm_float_negate,
|
||||
slang_asm_float_less,
|
||||
slang_asm_float_equal,
|
||||
slang_asm_float_to_int,
|
||||
slang_asm_int_copy,
|
||||
slang_asm_int_move,
|
||||
slang_asm_int_push,
|
||||
slang_asm_int_deref,
|
||||
slang_asm_int_to_float,
|
||||
slang_asm_int_to_addr,
|
||||
slang_asm_bool_copy,
|
||||
slang_asm_bool_move,
|
||||
slang_asm_bool_push,
|
||||
slang_asm_bool_deref,
|
||||
slang_asm_addr_copy,
|
||||
slang_asm_addr_push,
|
||||
slang_asm_addr_deref,
|
||||
slang_asm_addr_add,
|
||||
slang_asm_addr_multiply,
|
||||
slang_asm_jump,
|
||||
slang_asm_jump_if_zero,
|
||||
slang_asm_enter,
|
||||
slang_asm_leave,
|
||||
slang_asm_local_alloc,
|
||||
slang_asm_local_free,
|
||||
slang_asm_local_addr,
|
||||
slang_asm_call,
|
||||
slang_asm_return,
|
||||
slang_asm_discard,
|
||||
slang_asm_exit,
|
||||
slang_asm__last
|
||||
} slang_assembly_type;
|
||||
|
||||
typedef struct slang_assembly_
|
||||
{
|
||||
slang_assembly_type type;
|
||||
GLfloat literal;
|
||||
GLuint param[2];
|
||||
} slang_assembly;
|
||||
|
||||
typedef struct slang_assembly_file_
|
||||
{
|
||||
slang_assembly *code;
|
||||
unsigned int count;
|
||||
} slang_assembly_file;
|
||||
|
||||
void 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_flow_control_
|
||||
{
|
||||
unsigned int loop_start; /* for "continue" statement */
|
||||
unsigned int loop_end; /* for "break" statement */
|
||||
unsigned int function_end; /* for "return" statement */
|
||||
} slang_assembly_flow_control;
|
||||
|
||||
typedef struct slang_assembly_name_space_
|
||||
{
|
||||
struct slang_function_scope_ *funcs;
|
||||
struct slang_struct_scope_ *structs;
|
||||
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);
|
||||
|
||||
int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,
|
||||
slang_assembly_name_space *);
|
||||
|
||||
typedef struct slang_assembly_stack_info_
|
||||
{
|
||||
unsigned int swizzle_mask;
|
||||
} slang_assembly_stack_info;
|
||||
|
||||
int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,
|
||||
slang_assembly_name_space *);
|
||||
|
||||
typedef struct slang_assembly_local_info_
|
||||
{
|
||||
unsigned int ret_size;
|
||||
unsigned int addr_tmp;
|
||||
unsigned int swizzle_tmp;
|
||||
} slang_assembly_local_info;
|
||||
|
||||
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 *);
|
||||
|
||||
void xxx_first (slang_assembly_file *);
|
||||
void xxx_prolog (slang_assembly_file *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
485
src/mesa/shader/slang/slang_assemble_conditional.c
Normal file
485
src/mesa/shader/slang/slang_assemble_conditional.c
Normal file
|
|
@ -0,0 +1,485 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_assemble_conditional.c
|
||||
* slang condtional expressions assembler
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "imports.h"
|
||||
#include "slang_utility.h"
|
||||
#include "slang_assemble_conditional.h"
|
||||
#include "slang_assemble.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)
|
||||
{
|
||||
/*
|
||||
and:
|
||||
<left-expression>
|
||||
jumpz zero
|
||||
<right-expression>
|
||||
jump end
|
||||
zero:
|
||||
push 0
|
||||
end:
|
||||
*/
|
||||
|
||||
unsigned int zero_jump, end_jump;
|
||||
slang_assembly_stack_info stk;
|
||||
|
||||
/* evaluate left expression */
|
||||
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* jump to pushing 0 if not true */
|
||||
zero_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
|
||||
return 0;
|
||||
|
||||
/* evaluate right expression */
|
||||
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* jump to the end of the expression */
|
||||
end_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* push 0 on stack */
|
||||
file->code[zero_jump].param[0] = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_bool_push))
|
||||
return 0;
|
||||
|
||||
/* the end of the expression */
|
||||
file->code[end_jump].param[0] = file->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_assemble_logicalor() */
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
or:
|
||||
<left-expression>
|
||||
jumpz right
|
||||
push 1
|
||||
jump end
|
||||
right:
|
||||
<right-expression>
|
||||
end:
|
||||
*/
|
||||
|
||||
unsigned int right_jump, end_jump;
|
||||
slang_assembly_stack_info stk;
|
||||
|
||||
/* evaluate left expression */
|
||||
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* jump to evaluation of right expression if not true */
|
||||
right_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
|
||||
return 0;
|
||||
|
||||
/* push 1 on stack */
|
||||
if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f))
|
||||
return 0;
|
||||
|
||||
/* jump to the end of the expression */
|
||||
end_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* evaluate right expression */
|
||||
file->code[right_jump].param[0] = file->count;
|
||||
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* the end of the expression */
|
||||
file->code[end_jump].param[0] = file->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_assemble_select() */
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
select:
|
||||
<condition-expression>
|
||||
jumpz false
|
||||
<true-expression>
|
||||
jump end
|
||||
false:
|
||||
<false-expression>
|
||||
end:
|
||||
*/
|
||||
|
||||
unsigned int cond_jump, end_jump;
|
||||
slang_assembly_stack_info stk;
|
||||
|
||||
/* execute condition expression */
|
||||
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* jump to false expression if not true */
|
||||
cond_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
|
||||
return 0;
|
||||
|
||||
/* execute true expression */
|
||||
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* jump to the end of the expression */
|
||||
end_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* resolve false point */
|
||||
file->code[cond_jump].param[0] = file->count;
|
||||
|
||||
/* execute false expression */
|
||||
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* resolve the end of the expression */
|
||||
file->code[end_jump].param[0] = file->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_assemble_for() */
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
for:
|
||||
<init-statement>
|
||||
jump start
|
||||
break:
|
||||
jump end
|
||||
continue:
|
||||
<loop-increment>
|
||||
start:
|
||||
<condition-statement>
|
||||
jumpz end
|
||||
<loop-body>
|
||||
jump continue
|
||||
end:
|
||||
*/
|
||||
|
||||
unsigned int start_jump, end_jump, cond_jump;
|
||||
unsigned int break_label, cont_label;
|
||||
slang_assembly_flow_control loop_flow = *flow;
|
||||
slang_assembly_stack_info stk;
|
||||
|
||||
/* execute initialization statement */
|
||||
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
if (!_slang_cleanup_stack (file, op->children, 0, space))
|
||||
return 0;
|
||||
|
||||
/* skip the "go to the end of the loop" and loop-increment statements */
|
||||
start_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* go to the end of the loop - break statements are directed here */
|
||||
break_label = file->count;
|
||||
end_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* resolve the beginning of the loop - continue statements are directed here */
|
||||
cont_label = file->count;
|
||||
|
||||
/* execute loop-increment statement */
|
||||
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
|
||||
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))
|
||||
return 0;
|
||||
/* TODO: inspect stk */
|
||||
|
||||
/* jump to the end of the loop if not true */
|
||||
cond_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
|
||||
return 0;
|
||||
|
||||
/* 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))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
if (!_slang_cleanup_stack (file, op->children + 3, 0, space))
|
||||
return 0;
|
||||
|
||||
/* go to the beginning of the loop */
|
||||
if (!slang_assembly_file_push_label (file, slang_asm_jump, cont_label))
|
||||
return 0;
|
||||
|
||||
/* resolve the end of the loop */
|
||||
file->code[end_jump].param[0] = file->count;
|
||||
file->code[cond_jump].param[0] = file->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_assemble_do() */
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
do:
|
||||
jump start
|
||||
break:
|
||||
jump end
|
||||
continue:
|
||||
jump condition
|
||||
start:
|
||||
<loop-body>
|
||||
condition:
|
||||
<condition-statement>
|
||||
jumpz end
|
||||
jump start
|
||||
end:
|
||||
*/
|
||||
|
||||
unsigned int skip_jump, end_jump, cont_jump, cond_jump;
|
||||
unsigned int break_label, cont_label;
|
||||
slang_assembly_flow_control loop_flow = *flow;
|
||||
slang_assembly_stack_info stk;
|
||||
|
||||
/* skip the "go to the end of the loop" and "go to condition" statements */
|
||||
skip_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* go to the end of the loop - break statements are directed here */
|
||||
break_label = file->count;
|
||||
end_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* go to condition - continue statements are directed here */
|
||||
cont_label = file->count;
|
||||
cont_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* resolve the beginning of the loop */
|
||||
file->code[skip_jump].param[0] = file->count;
|
||||
|
||||
/* 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))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
if (!_slang_cleanup_stack (file, op->children, 0, space))
|
||||
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))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
|
||||
/* jump to the end of the loop if not true */
|
||||
cond_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
|
||||
return 0;
|
||||
|
||||
/* jump to the beginning of the loop */
|
||||
if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))
|
||||
return 0;
|
||||
|
||||
/* resolve the end of the loop */
|
||||
file->code[end_jump].param[0] = file->count;
|
||||
file->code[cond_jump].param[0] = file->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_assemble_while() */
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
while:
|
||||
jump continue
|
||||
break:
|
||||
jump end
|
||||
continue:
|
||||
<condition-statement>
|
||||
jumpz end
|
||||
<loop-body>
|
||||
jump continue
|
||||
end:
|
||||
*/
|
||||
|
||||
unsigned int skip_jump, end_jump, cond_jump;
|
||||
unsigned int break_label;
|
||||
slang_assembly_flow_control loop_flow = *flow;
|
||||
slang_assembly_stack_info stk;
|
||||
|
||||
/* skip the "go to the end of the loop" statement */
|
||||
skip_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* go to the end of the loop - break statements are directed here */
|
||||
break_label = file->count;
|
||||
end_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* resolve the beginning of the loop - continue statements are directed here */
|
||||
file->code[skip_jump].param[0] = file->count;
|
||||
|
||||
/* execute condition statement */
|
||||
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
|
||||
/* jump to the end of the loop if not true */
|
||||
cond_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
|
||||
return 0;
|
||||
|
||||
/* 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))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
|
||||
return 0;
|
||||
|
||||
/* jump to the beginning of the loop */
|
||||
if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0]))
|
||||
return 0;
|
||||
|
||||
/* resolve the end of the loop */
|
||||
file->code[end_jump].param[0] = file->count;
|
||||
file->code[cond_jump].param[0] = file->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_assemble_if() */
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
if:
|
||||
<condition-statement>
|
||||
jumpz else
|
||||
<true-statement>
|
||||
jump end
|
||||
else:
|
||||
<false-statement>
|
||||
end:
|
||||
*/
|
||||
|
||||
unsigned int cond_jump, else_jump;
|
||||
slang_assembly_stack_info stk;
|
||||
|
||||
/* execute condition statement */
|
||||
if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
|
||||
/* jump to false-statement if not true */
|
||||
cond_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump_if_zero))
|
||||
return 0;
|
||||
|
||||
/* execute true-statement */
|
||||
if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
if (!_slang_cleanup_stack (file, op->children + 1, 0, space))
|
||||
return 0;
|
||||
|
||||
/* skip if-false statement */
|
||||
else_jump = file->count;
|
||||
if (!slang_assembly_file_push (file, slang_asm_jump))
|
||||
return 0;
|
||||
|
||||
/* resolve start of false-statement */
|
||||
file->code[cond_jump].param[0] = file->count;
|
||||
|
||||
/* execute false-statement */
|
||||
if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk))
|
||||
return 0;
|
||||
/* TODO: pass-in stk to cleanup */
|
||||
if (!_slang_cleanup_stack (file, op->children + 2, 0, space))
|
||||
return 0;
|
||||
|
||||
/* resolve end of if-false statement */
|
||||
file->code[else_jump].param[0] = file->count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
66
src/mesa/shader/slang/slang_assemble_conditional.h
Normal file
66
src/mesa/shader/slang/slang_assemble_conditional.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_ASSEMBLE_CONDITIONAL_H
|
||||
#define SLANG_ASSEMBLE_CONDITIONAL_H
|
||||
|
||||
#include "slang_assemble.h"
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
333
src/mesa/shader/slang/slang_assemble_constructor.c
Normal file
333
src/mesa/shader/slang/slang_assemble_constructor.c
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_assemble_constructor.c
|
||||
* slang constructor and vector swizzle assembler
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "imports.h"
|
||||
#include "slang_utility.h"
|
||||
#include "slang_assemble_constructor.h"
|
||||
#include "slang_assemble_typeinfo.h"
|
||||
#include "slang_storage.h"
|
||||
|
||||
/* _slang_is_swizzle() */
|
||||
|
||||
int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz)
|
||||
{
|
||||
unsigned int i;
|
||||
int xyzw = 0, rgba = 0, stpq = 0;
|
||||
|
||||
/* the swizzle can be at most 4-component long */
|
||||
swz->num_components = slang_string_length (field);
|
||||
if (swz->num_components > 4)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < swz->num_components; i++)
|
||||
{
|
||||
/* mark which swizzle group is used */
|
||||
switch (field[i])
|
||||
{
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'z':
|
||||
case 'w':
|
||||
xyzw = 1;
|
||||
break;
|
||||
case 'r':
|
||||
case 'g':
|
||||
case 'b':
|
||||
case 'a':
|
||||
rgba = 1;
|
||||
break;
|
||||
case 's':
|
||||
case 't':
|
||||
case 'p':
|
||||
case 'q':
|
||||
stpq = 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* collect swizzle component */
|
||||
switch (field[i])
|
||||
{
|
||||
case 'x':
|
||||
case 'r':
|
||||
case 's':
|
||||
swz->swizzle[i] = 0;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* only one swizzle group can be used */
|
||||
if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_is_swizzle_mask() */
|
||||
|
||||
int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows)
|
||||
{
|
||||
unsigned int c, i;
|
||||
|
||||
if (swz->num_components > rows)
|
||||
return 0;
|
||||
c = swz->swizzle[0];
|
||||
for (i = 1; i < swz->num_components; i++)
|
||||
{
|
||||
if (swz->swizzle[i] <= c)
|
||||
return 0;
|
||||
c = swz->swizzle[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _slang_multiply_swizzles() */
|
||||
|
||||
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)
|
||||
{
|
||||
slang_assembly_typeinfo ti;
|
||||
int result;
|
||||
slang_storage_aggregate agg, flat_agg;
|
||||
slang_assembly_stack_info stk;
|
||||
unsigned int i;
|
||||
|
||||
slang_assembly_typeinfo_construct (&ti);
|
||||
if (!(result = _slang_typeof_operation (op, space, &ti)))
|
||||
goto end1;
|
||||
|
||||
slang_storage_aggregate_construct (&agg);
|
||||
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
|
||||
goto end2;
|
||||
|
||||
slang_storage_aggregate_construct (&flat_agg);
|
||||
if (!(result = _slang_flatten_aggregate (&flat_agg, &agg)))
|
||||
goto end;
|
||||
|
||||
if (!(result = _slang_assemble_operation (file, op, 0, flow, space, info, &stk)))
|
||||
goto end;
|
||||
|
||||
for (i = 0; i < flat_agg.count; i++)
|
||||
{
|
||||
const slang_storage_array *arr1 = flat_agg.arrays + i;
|
||||
const slang_storage_array *arr2 = flat->arrays + *index;
|
||||
|
||||
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:
|
||||
slang_storage_aggregate_destruct (&flat_agg);
|
||||
end2:
|
||||
slang_storage_aggregate_destruct (&agg);
|
||||
end1:
|
||||
slang_assembly_typeinfo_destruct (&ti);
|
||||
return result;
|
||||
}
|
||||
/* XXX: general swizzle! */
|
||||
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_typeinfo ti;
|
||||
int result;
|
||||
slang_storage_aggregate agg, flat;
|
||||
unsigned int size, index, i;
|
||||
|
||||
slang_assembly_typeinfo_construct (&ti);
|
||||
if (!(result = _slang_typeof_operation (op, space, &ti)))
|
||||
goto end1;
|
||||
|
||||
slang_storage_aggregate_construct (&agg);
|
||||
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
|
||||
goto end2;
|
||||
|
||||
size = _slang_sizeof_aggregate (&agg);
|
||||
|
||||
slang_storage_aggregate_construct (&flat);
|
||||
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,
|
||||
space, info)))
|
||||
goto end;
|
||||
/* TODO: watch the index, if it reaches the size, raise an error */
|
||||
}
|
||||
|
||||
result = 1;
|
||||
end:
|
||||
slang_storage_aggregate_destruct (&flat);
|
||||
end2:
|
||||
slang_storage_aggregate_destruct (&agg);
|
||||
end1:
|
||||
slang_assembly_typeinfo_destruct (&ti);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* _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;
|
||||
}
|
||||
for (i = 0; i < master_rows; i++)
|
||||
{
|
||||
switch (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))
|
||||
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))
|
||||
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))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
|
||||
return 0;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
80
src/mesa/shader/slang/slang_assemble_constructor.h
Normal file
80
src/mesa/shader/slang/slang_assemble_constructor.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_ASSEMBLE_CONSTRUCTOR_H
|
||||
#define SLANG_ASSEMBLE_CONSTRUCTOR_H
|
||||
|
||||
#include "slang_assemble.h"
|
||||
#include "slang_compile.h"
|
||||
|
||||
#if defined __cplusplus
|
||||
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
|
||||
returns 0 otherwise
|
||||
*/
|
||||
int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz);
|
||||
|
||||
/*
|
||||
checks if a general swizzle is an l-value swizzle - these swizzles do not have
|
||||
duplicated fields and they are specified in order
|
||||
returns 1 if this is a swizzle mask
|
||||
returns 0 otherwise
|
||||
*/
|
||||
int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows);
|
||||
|
||||
/*
|
||||
combines two swizzles to form single swizzle
|
||||
example: "wzyx.yx" --> "zw"
|
||||
*/
|
||||
void _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const slang_swizzle *);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
428
src/mesa/shader/slang/slang_assemble_typeinfo.c
Normal file
428
src/mesa/shader/slang/slang_assemble_typeinfo.c
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_assemble_typeinfo.c
|
||||
* slang type info
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "imports.h"
|
||||
#include "slang_utility.h"
|
||||
#include "slang_assemble_typeinfo.h"
|
||||
|
||||
/* slang_assembly_typeinfo */
|
||||
|
||||
void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
|
||||
{
|
||||
slang_type_specifier_construct (&ti->spec);
|
||||
}
|
||||
|
||||
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)
|
||||
{
|
||||
slang_type_specifier_destruct (&ti->spec);
|
||||
}
|
||||
|
||||
/* _slang_typeof_operation() */
|
||||
|
||||
int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *space,
|
||||
slang_assembly_typeinfo *ti)
|
||||
{
|
||||
ti->can_be_referenced = 0;
|
||||
ti->is_swizzled = 0;
|
||||
|
||||
switch (op->type)
|
||||
{
|
||||
case slang_oper_block_no_new_scope:
|
||||
case slang_oper_block_new_scope:
|
||||
case slang_oper_variable_decl:
|
||||
case slang_oper_asm:
|
||||
case slang_oper_break:
|
||||
case slang_oper_continue:
|
||||
case slang_oper_discard:
|
||||
case slang_oper_return:
|
||||
case slang_oper_if:
|
||||
case slang_oper_while:
|
||||
case slang_oper_do:
|
||||
case slang_oper_for:
|
||||
case slang_oper_void:
|
||||
ti->spec.type = slang_spec_void;
|
||||
break;
|
||||
case slang_oper_expression:
|
||||
case slang_oper_assign:
|
||||
case slang_oper_addassign:
|
||||
case slang_oper_subassign:
|
||||
case slang_oper_mulassign:
|
||||
case slang_oper_divassign:
|
||||
case slang_oper_preincrement:
|
||||
case slang_oper_predecrement:
|
||||
if (!_slang_typeof_operation (op->children, space, ti))
|
||||
return 0;
|
||||
break;
|
||||
case slang_oper_literal_bool:
|
||||
case slang_oper_logicalor:
|
||||
case slang_oper_logicalxor:
|
||||
case slang_oper_logicaland:
|
||||
case slang_oper_equal:
|
||||
case slang_oper_notequal:
|
||||
case slang_oper_less:
|
||||
case slang_oper_greater:
|
||||
case slang_oper_lessequal:
|
||||
case slang_oper_greaterequal:
|
||||
case slang_oper_not:
|
||||
ti->spec.type = slang_spec_bool;
|
||||
break;
|
||||
case slang_oper_literal_int:
|
||||
ti->spec.type = slang_spec_int;
|
||||
break;
|
||||
case slang_oper_literal_float:
|
||||
ti->spec.type = slang_spec_float;
|
||||
break;
|
||||
case slang_oper_identifier:
|
||||
{
|
||||
slang_variable *var;
|
||||
|
||||
var = _slang_locate_variable (op->locals, op->identifier, 1);
|
||||
if (var == NULL)
|
||||
return 0;
|
||||
if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))
|
||||
return 0;
|
||||
ti->can_be_referenced = 1;
|
||||
}
|
||||
break;
|
||||
case slang_oper_sequence:
|
||||
/* TODO: check [0] and [1] if they match */
|
||||
if (!_slang_typeof_operation (op->children + 1, space, ti))
|
||||
return 0;
|
||||
ti->can_be_referenced = 0;
|
||||
ti->is_swizzled = 0;
|
||||
break;
|
||||
/*case slang_oper_modassign:*/
|
||||
/*case slang_oper_lshassign:*/
|
||||
/*case slang_oper_rshassign:*/
|
||||
/*case slang_oper_orassign:*/
|
||||
/*case slang_oper_xorassign:*/
|
||||
/*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))
|
||||
return 0;
|
||||
ti->can_be_referenced = 0;
|
||||
ti->is_swizzled = 0;
|
||||
break;
|
||||
/*case slang_oper_bitor:*/
|
||||
/*case slang_oper_bitxor:*/
|
||||
/*case slang_oper_bitand:*/
|
||||
/*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;
|
||||
}
|
||||
break;
|
||||
case slang_oper_subtract:
|
||||
{
|
||||
int exists;
|
||||
if (!_slang_typeof_function ("-", op->children, 2, space, &ti->spec, &exists))
|
||||
return 0;
|
||||
if (!exists)
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case slang_oper_divide:
|
||||
{
|
||||
int exists;
|
||||
if (!_slang_typeof_function ("/", op->children, 2, space, &ti->spec, &exists))
|
||||
return 0;
|
||||
if (!exists)
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case slang_oper_minus:
|
||||
{
|
||||
int exists;
|
||||
if (!_slang_typeof_function ("-", op->children, 1, space, &ti->spec, &exists))
|
||||
return 0;
|
||||
if (!exists)
|
||||
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))
|
||||
{
|
||||
slang_assembly_typeinfo_destruct (&_ti);
|
||||
return 0;
|
||||
}
|
||||
ti->can_be_referenced = _ti.can_be_referenced;
|
||||
switch (_ti.spec.type)
|
||||
{
|
||||
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;
|
||||
}
|
||||
slang_assembly_typeinfo_destruct (&_ti);
|
||||
}
|
||||
break;
|
||||
case slang_oper_call:
|
||||
{
|
||||
int exists;
|
||||
if (!_slang_typeof_function (op->identifier, op->children, op->num_children, space,
|
||||
&ti->spec, &exists))
|
||||
return 0;
|
||||
if (!exists)
|
||||
{
|
||||
slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1);
|
||||
if (s != NULL)
|
||||
{
|
||||
ti->spec.type = slang_spec_struct;
|
||||
ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
|
||||
if (ti->spec._struct == NULL)
|
||||
return 0;
|
||||
if (!slang_struct_construct_a (ti->spec._struct))
|
||||
{
|
||||
slang_alloc_free (ti->spec._struct);
|
||||
ti->spec._struct = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (!slang_struct_copy (ti->spec._struct, s))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
slang_type_specifier_type type = slang_type_specifier_type_from_string (
|
||||
op->identifier);
|
||||
if (type == slang_spec_void)
|
||||
return 0;
|
||||
ti->spec.type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case slang_oper_field:
|
||||
{
|
||||
slang_assembly_typeinfo _ti;
|
||||
slang_assembly_typeinfo_construct (&_ti);
|
||||
if (!_slang_typeof_operation (op->children, space, &_ti))
|
||||
{
|
||||
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);
|
||||
if (field == NULL)
|
||||
{
|
||||
slang_assembly_typeinfo_destruct (&_ti);
|
||||
return 0;
|
||||
}
|
||||
if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier))
|
||||
{
|
||||
slang_assembly_typeinfo_destruct (&_ti);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int rows;
|
||||
switch (_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))
|
||||
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;
|
||||
_slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);
|
||||
ti->swz = swz;
|
||||
}
|
||||
switch (_ti.spec.type)
|
||||
{
|
||||
case slang_spec_vec2:
|
||||
case slang_spec_vec3:
|
||||
case slang_spec_vec4:
|
||||
switch (ti->swz.num_components)
|
||||
{
|
||||
case 1:
|
||||
ti->spec.type = slang_spec_float;
|
||||
break;
|
||||
case 2:
|
||||
ti->spec.type = slang_spec_vec2;
|
||||
break;
|
||||
case 3:
|
||||
ti->spec.type = slang_spec_vec3;
|
||||
break;
|
||||
case 4:
|
||||
ti->spec.type = slang_spec_vec4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case slang_spec_ivec2:
|
||||
case slang_spec_ivec3:
|
||||
case slang_spec_ivec4:
|
||||
switch (ti->swz.num_components)
|
||||
{
|
||||
case 1:
|
||||
ti->spec.type = slang_spec_int;
|
||||
break;
|
||||
case 2:
|
||||
ti->spec.type = slang_spec_ivec2;
|
||||
break;
|
||||
case 3:
|
||||
ti->spec.type = slang_spec_ivec3;
|
||||
break;
|
||||
case 4:
|
||||
ti->spec.type = slang_spec_ivec4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case slang_spec_bvec2:
|
||||
case slang_spec_bvec3:
|
||||
case slang_spec_bvec4:
|
||||
switch (ti->swz.num_components)
|
||||
{
|
||||
case 1:
|
||||
ti->spec.type = slang_spec_bool;
|
||||
break;
|
||||
case 2:
|
||||
ti->spec.type = slang_spec_bvec2;
|
||||
break;
|
||||
case 3:
|
||||
ti->spec.type = slang_spec_bvec3;
|
||||
break;
|
||||
case 4:
|
||||
ti->spec.type = slang_spec_bvec4;
|
||||
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))
|
||||
return 0;
|
||||
ti->can_be_referenced = 0;
|
||||
ti->is_swizzled = 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* _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)
|
||||
{
|
||||
slang_function *fun = _slang_locate_function (name, params, num_params, space);
|
||||
*exists = fun != NULL;
|
||||
if (fun == NULL)
|
||||
return 1;
|
||||
return slang_type_specifier_copy (spec, &fun->header.type.specifier);
|
||||
}
|
||||
|
||||
67
src/mesa/shader/slang/slang_assemble_typeinfo.h
Normal file
67
src/mesa/shader/slang/slang_assemble_typeinfo.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_ASSEMBLE_TYPEINFO_H
|
||||
#define SLANG_ASSEMBLE_TYPEINFO_H
|
||||
|
||||
#include "slang_assemble_constructor.h"
|
||||
#include "slang_compile.h"
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct slang_assembly_typeinfo_
|
||||
{
|
||||
int can_be_referenced;
|
||||
int is_swizzled;
|
||||
slang_swizzle swz;
|
||||
slang_type_specifier spec;
|
||||
} slang_assembly_typeinfo;
|
||||
|
||||
void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *);
|
||||
void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *);
|
||||
|
||||
/*
|
||||
retrieves type information about an operation
|
||||
returns 1 on success
|
||||
returns 0 otherwise
|
||||
*/
|
||||
int _slang_typeof_operation (slang_operation *, slang_assembly_name_space *,
|
||||
slang_assembly_typeinfo *);
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -33,6 +33,9 @@
|
|||
#include "slang_utility.h"
|
||||
#include "slang_compile.h"
|
||||
#include "slang_preprocess.h"
|
||||
#include "slang_storage.h"
|
||||
#include "slang_assemble.h"
|
||||
#include "slang_execute.h"
|
||||
|
||||
/*
|
||||
This is a straightforward implementation of the slang front-end compiler.
|
||||
|
|
@ -43,22 +46,61 @@
|
|||
|
||||
static void slang_variable_construct (slang_variable *);
|
||||
static int slang_variable_copy (slang_variable *, const slang_variable *);
|
||||
static void slang_struct_construct (slang_struct *);
|
||||
static void slang_struct_destruct (slang_struct *);
|
||||
static int slang_struct_copy (slang_struct *, const slang_struct *);
|
||||
static int slang_struct_equal (const slang_struct *, const slang_struct *);
|
||||
static void slang_variable_destruct (slang_variable *);
|
||||
|
||||
/* slang_type_specifier_type */
|
||||
|
||||
/* these must match with slang_type_specifier_type enum */
|
||||
static const char *type_specifier_type_names[] = {
|
||||
"void",
|
||||
"bool",
|
||||
"bvec2",
|
||||
"bvec3",
|
||||
"bvec4",
|
||||
"int",
|
||||
"ivec2",
|
||||
"ivec3",
|
||||
"ivec4",
|
||||
"float",
|
||||
"vec2",
|
||||
"vec3",
|
||||
"vec4",
|
||||
"mat2",
|
||||
"mat3",
|
||||
"mat4",
|
||||
"sampler1D",
|
||||
"sampler2D",
|
||||
"sampler3D",
|
||||
"samplerCube",
|
||||
"sampler1DShadow",
|
||||
"sampler2DShadow",
|
||||
NULL
|
||||
};
|
||||
|
||||
slang_type_specifier_type slang_type_specifier_type_from_string (const char *name)
|
||||
{
|
||||
const char **p = type_specifier_type_names;
|
||||
while (*p != NULL)
|
||||
{
|
||||
if (slang_string_compare (*p, name) == 0)
|
||||
return (slang_type_specifier_type) (p - type_specifier_type_names);
|
||||
p++;
|
||||
}
|
||||
return slang_spec_void;
|
||||
}
|
||||
|
||||
/* slang_type_specifier */
|
||||
|
||||
static void slang_type_specifier_construct (slang_type_specifier *spec)
|
||||
void slang_type_specifier_construct (slang_type_specifier *spec)
|
||||
{
|
||||
spec->type = slang_spec_void;
|
||||
spec->_struct = NULL;
|
||||
spec->_array = NULL;
|
||||
}
|
||||
|
||||
static void slang_type_specifier_destruct (slang_type_specifier *spec)
|
||||
void slang_type_specifier_destruct (slang_type_specifier *spec)
|
||||
{
|
||||
if (spec->_struct != NULL)
|
||||
{
|
||||
|
|
@ -72,7 +114,7 @@ static void slang_type_specifier_destruct (slang_type_specifier *spec)
|
|||
}
|
||||
}
|
||||
|
||||
static int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
|
||||
int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
|
||||
{
|
||||
slang_type_specifier_destruct (x);
|
||||
slang_type_specifier_construct (x);
|
||||
|
|
@ -80,19 +122,28 @@ static int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_
|
|||
if (x->type == slang_spec_struct)
|
||||
{
|
||||
x->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
|
||||
slang_struct_construct (x->_struct);
|
||||
if (x->_struct == NULL)
|
||||
return 0;
|
||||
if (!slang_struct_construct_a (x->_struct))
|
||||
{
|
||||
slang_alloc_free (x->_struct);
|
||||
x->_struct = NULL;
|
||||
return 0;
|
||||
}
|
||||
return slang_struct_copy (x->_struct, y->_struct);
|
||||
}
|
||||
if (x->type == slang_spec_array)
|
||||
{
|
||||
x->_array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier));
|
||||
if (x->_array == NULL)
|
||||
return 0;
|
||||
slang_type_specifier_construct (x->_array);
|
||||
return slang_type_specifier_copy (x->_array, y->_array);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
|
||||
int slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
|
||||
{
|
||||
if (x->type != y->type)
|
||||
return 0;
|
||||
|
|
@ -162,8 +213,8 @@ static int slang_variable_scope_copy (slang_variable_scope *x, const slang_varia
|
|||
}
|
||||
|
||||
/* slang_operation */
|
||||
/* XXX mem! */
|
||||
static void slang_operation_construct (slang_operation *oper)
|
||||
|
||||
int slang_operation_construct_a (slang_operation *oper)
|
||||
{
|
||||
oper->type = slang_oper_none;
|
||||
oper->children = NULL;
|
||||
|
|
@ -171,10 +222,13 @@ static void slang_operation_construct (slang_operation *oper)
|
|||
oper->literal = (float) 0;
|
||||
oper->identifier = NULL;
|
||||
oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
|
||||
if (oper->locals == NULL)
|
||||
return 0;
|
||||
slang_variable_scope_construct (oper->locals);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void slang_operation_destruct (slang_operation *oper)
|
||||
void slang_operation_destruct (slang_operation *oper)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < oper->num_children; i++)
|
||||
|
|
@ -188,16 +242,31 @@ static void slang_operation_destruct (slang_operation *oper)
|
|||
static int slang_operation_copy (slang_operation *x, const slang_operation *y)
|
||||
{
|
||||
unsigned int i;
|
||||
slang_operation_destruct (x);
|
||||
slang_operation_construct (x);
|
||||
for (i = 0; i < x->num_children; i++)
|
||||
slang_operation_destruct (x->children + i);
|
||||
slang_alloc_free (x->children);
|
||||
x->num_children = 0;
|
||||
slang_alloc_free (x->identifier);
|
||||
x->identifier = NULL;
|
||||
slang_variable_scope_destruct (x->locals);
|
||||
slang_variable_scope_construct (x->locals);
|
||||
|
||||
x->type = y->type;
|
||||
x->children = (slang_operation *) slang_alloc_malloc (y->num_children * sizeof (
|
||||
slang_operation));
|
||||
if (x->children == NULL)
|
||||
return 0;
|
||||
for (i = 0; i < y->num_children; i++)
|
||||
if (!slang_operation_construct_a (x->children + i))
|
||||
{
|
||||
unsigned int j;
|
||||
for (j = 0; j < i; j++)
|
||||
slang_operation_destruct (x->children + j);
|
||||
slang_alloc_free (x->children);
|
||||
x->children = NULL;
|
||||
return 0;
|
||||
}
|
||||
x->num_children = y->num_children;
|
||||
for (i = 0; i < x->num_children; i++)
|
||||
slang_operation_construct (x->children + i);
|
||||
for (i = 0; i < x->num_children; i++)
|
||||
if (!slang_operation_copy (x->children + i, y->children + i))
|
||||
return 0;
|
||||
|
|
@ -221,6 +290,7 @@ static void slang_variable_construct (slang_variable *var)
|
|||
var->name = NULL;
|
||||
var->array_size = NULL;
|
||||
var->initializer = NULL;
|
||||
var->address = ~0;
|
||||
}
|
||||
|
||||
static void slang_variable_destruct (slang_variable *var)
|
||||
|
|
@ -256,7 +326,12 @@ static int slang_variable_copy (slang_variable *x, const slang_variable *y)
|
|||
x->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
|
||||
if (x->array_size == NULL)
|
||||
return 0;
|
||||
slang_operation_construct (x->array_size);
|
||||
if (!slang_operation_construct_a (x->array_size))
|
||||
{
|
||||
slang_alloc_free (x->array_size);
|
||||
x->array_size = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (!slang_operation_copy (x->array_size, y->array_size))
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -265,13 +340,29 @@ static int slang_variable_copy (slang_variable *x, const slang_variable *y)
|
|||
x->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
|
||||
if (x->initializer == NULL)
|
||||
return 0;
|
||||
slang_operation_construct (x->initializer);
|
||||
if (!slang_operation_construct_a (x->initializer))
|
||||
{
|
||||
slang_alloc_free (x->initializer);
|
||||
x->initializer = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (!slang_operation_copy (x->initializer, y->initializer))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *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 (all && scope->outer_scope != NULL)
|
||||
return _slang_locate_variable (scope->outer_scope, name, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* slang_struct_scope */
|
||||
|
||||
static void slang_struct_scope_construct (slang_struct_scope *scope)
|
||||
|
|
@ -299,7 +390,17 @@ static int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_sc
|
|||
return 0;
|
||||
x->num_structs = y->num_structs;
|
||||
for (i = 0; i < x->num_structs; i++)
|
||||
slang_struct_construct (x->structs + i);
|
||||
{
|
||||
unsigned int j;
|
||||
if (!slang_struct_construct_a (x->structs + i))
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
slang_struct_destruct (x->structs + j);
|
||||
slang_alloc_free (x->structs);
|
||||
x->structs = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < x->num_structs; i++)
|
||||
if (!slang_struct_copy (x->structs + i, y->structs + i))
|
||||
return 0;
|
||||
|
|
@ -307,8 +408,7 @@ static int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_sc
|
|||
return 1;
|
||||
}
|
||||
|
||||
static 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, const char *name, int all_scopes)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < stru->num_structs; i++)
|
||||
|
|
@ -320,14 +420,23 @@ static slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const ch
|
|||
}
|
||||
|
||||
/* slang_struct */
|
||||
/* XXX mem! */
|
||||
static void slang_struct_construct (slang_struct *stru)
|
||||
|
||||
int slang_struct_construct_a (slang_struct *stru)
|
||||
{
|
||||
stru->name = NULL;
|
||||
stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
|
||||
if (stru->fields == NULL)
|
||||
return 0;
|
||||
slang_variable_scope_construct (stru->fields);
|
||||
stru->structs = (slang_struct_scope *) slang_alloc_malloc (sizeof (slang_struct_scope));
|
||||
if (stru->structs == NULL)
|
||||
{
|
||||
slang_variable_scope_destruct (stru->fields);
|
||||
slang_alloc_free (stru->fields);
|
||||
return 0;
|
||||
}
|
||||
slang_struct_scope_construct (stru->structs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void slang_struct_destruct (slang_struct *stru)
|
||||
|
|
@ -339,10 +448,14 @@ static void slang_struct_destruct (slang_struct *stru)
|
|||
slang_alloc_free (stru->structs);
|
||||
}
|
||||
|
||||
static int slang_struct_copy (slang_struct *x, const slang_struct *y)
|
||||
int slang_struct_copy (slang_struct *x, const slang_struct *y)
|
||||
{
|
||||
slang_struct_destruct (x);
|
||||
slang_struct_construct (x);
|
||||
slang_alloc_free (x->name);
|
||||
x->name = NULL;
|
||||
slang_variable_scope_destruct (x->fields);
|
||||
slang_variable_scope_construct (x->fields);
|
||||
slang_struct_scope_destruct (x->structs);
|
||||
slang_struct_scope_construct (x->structs);
|
||||
if (y->name != NULL)
|
||||
{
|
||||
x->name = slang_string_duplicate (y->name);
|
||||
|
|
@ -386,6 +499,7 @@ static void slang_function_construct (slang_function *func)
|
|||
func->parameters = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
|
||||
slang_variable_scope_construct (func->parameters);
|
||||
func->body = NULL;
|
||||
func->address = ~0;
|
||||
}
|
||||
|
||||
static void slang_function_destruct (slang_function *func)
|
||||
|
|
@ -561,7 +675,7 @@ typedef struct slang_parse_ctx_
|
|||
int parsing_builtin;
|
||||
} slang_parse_ctx;
|
||||
|
||||
/* --- */
|
||||
/* _slang_compile() */
|
||||
|
||||
static int parse_identifier (slang_parse_ctx *C, char **id)
|
||||
{
|
||||
|
|
@ -826,7 +940,14 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_struct_construct (spec->_struct);
|
||||
if (!slang_struct_construct_a (spec->_struct))
|
||||
{
|
||||
slang_alloc_free (spec->_struct);
|
||||
spec->_struct = NULL;
|
||||
slang_alloc_free (name);
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
spec->_struct->name = name;
|
||||
spec->_struct->structs->outer_scope = structs;
|
||||
}
|
||||
|
|
@ -878,7 +999,14 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_operation_construct (var->array_size);
|
||||
if (!slang_operation_construct_a (var->array_size))
|
||||
{
|
||||
slang_alloc_free (var->array_size);
|
||||
var->array_size = NULL;
|
||||
slang_type_specifier_destruct (&sp);
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
if (!parse_expression (C, var->array_size, scope, structs, funcs))
|
||||
{
|
||||
slang_type_specifier_destruct (&sp);
|
||||
|
|
@ -904,8 +1032,9 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
|
|||
return 0;
|
||||
}
|
||||
s = structs->structs + structs->num_structs;
|
||||
if (!slang_struct_construct_a (s))
|
||||
return 0;
|
||||
structs->num_structs++;
|
||||
slang_struct_construct (s);
|
||||
if (!slang_struct_copy (s, spec->_struct))
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -931,7 +1060,12 @@ static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec,
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_struct_construct (spec->_struct);
|
||||
if (!slang_struct_construct_a (spec->_struct))
|
||||
{
|
||||
slang_alloc_free (spec->_struct);
|
||||
spec->_struct = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (!slang_struct_copy (spec->_struct, stru))
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1025,7 +1159,11 @@ static int parse_child_operation (slang_parse_ctx *C, slang_operation *oper, int
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_operation_construct (oper->children + oper->num_children);
|
||||
if (!slang_operation_construct_a (oper->children + oper->num_children))
|
||||
{
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
oper->num_children++;
|
||||
if (statement)
|
||||
return parse_statement (C, oper->children + oper->num_children - 1, scope, structs, funcs);
|
||||
|
|
@ -1073,7 +1211,16 @@ static int parse_statement (slang_parse_ctx *C, slang_operation *oper, slang_var
|
|||
return 0;
|
||||
}
|
||||
for (i = 0; i < num_vars; i++)
|
||||
slang_operation_construct (oper->children + i);
|
||||
if (!slang_operation_construct_a (oper->children + i))
|
||||
{
|
||||
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 < scope->num_variables; i++)
|
||||
{
|
||||
|
|
@ -1230,39 +1377,10 @@ static int handle_unary_expression (slang_parse_ctx *C, slang_operation *op,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* these must match with slang_type_specifier_type enum */
|
||||
static const char *builtin_constructor_names[] = {
|
||||
"void",
|
||||
"bool",
|
||||
"bvec2",
|
||||
"bvec3",
|
||||
"bvec4",
|
||||
"int",
|
||||
"ivec2",
|
||||
"ivec3",
|
||||
"ivec4",
|
||||
"float",
|
||||
"vec2",
|
||||
"vec3",
|
||||
"vec4",
|
||||
"mat2",
|
||||
"mat3",
|
||||
"mat4",
|
||||
"sampler1D",
|
||||
"sampler2D",
|
||||
"sampler3D",
|
||||
"samplerCube",
|
||||
"sampler1DShadow",
|
||||
"sampler2DShadow",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int is_constructor_name (const char *name, slang_struct_scope *structs)
|
||||
{
|
||||
const char **p = &builtin_constructor_names[1];
|
||||
while (*p != NULL)
|
||||
if (slang_string_compare (*p++, name) == 0)
|
||||
return 1;
|
||||
if (slang_type_specifier_type_from_string (name) != slang_spec_void)
|
||||
return 1;
|
||||
return slang_struct_scope_find (structs, name, 1) != NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1285,8 +1403,12 @@ static int parse_expression (slang_parse_ctx *C, slang_operation *oper, slang_va
|
|||
return 0;
|
||||
}
|
||||
op = ops + num_ops;
|
||||
if (!slang_operation_construct_a (op))
|
||||
{
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
num_ops++;
|
||||
slang_operation_construct (op);
|
||||
op->locals->outer_scope = scope;
|
||||
switch (op_code)
|
||||
{
|
||||
|
|
@ -1513,6 +1635,7 @@ static int parse_expression (slang_parse_ctx *C, slang_operation *oper, slang_va
|
|||
static int parse_parameter_declaration (slang_parse_ctx *C, slang_variable *param,
|
||||
slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
|
||||
{
|
||||
slang_storage_aggregate agg;
|
||||
if (!parse_type_qualifier (C, ¶m->type.qualifier))
|
||||
return 0;
|
||||
switch (*C->I++)
|
||||
|
|
@ -1557,10 +1680,24 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_variable *para
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_operation_construct (param->array_size);
|
||||
if (!slang_operation_construct_a (param->array_size))
|
||||
{
|
||||
slang_alloc_free (param->array_size);
|
||||
param->array_size = NULL;
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
if (!parse_expression (C, param->array_size, scope, structs, funcs))
|
||||
return 0;
|
||||
}
|
||||
slang_storage_aggregate_construct (&agg);
|
||||
if (!_slang_aggregate_variable (&agg, ¶m->type.specifier, param->array_size, funcs,
|
||||
structs))
|
||||
{
|
||||
slang_storage_aggregate_destruct (&agg);
|
||||
return 0;
|
||||
}
|
||||
slang_storage_aggregate_destruct (&agg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1680,7 +1817,7 @@ static int parse_function_prototype (slang_parse_ctx *C, slang_function *func,
|
|||
if (func->header.type.specifier.type == slang_spec_struct)
|
||||
return 0;
|
||||
func->header.name = slang_string_duplicate (
|
||||
builtin_constructor_names[func->header.type.specifier.type]);
|
||||
type_specifier_type_names[func->header.type.specifier.type]);
|
||||
if (func->header.name == NULL)
|
||||
{
|
||||
slang_info_log_memory (C->L);
|
||||
|
|
@ -1728,7 +1865,13 @@ static int parse_function_definition (slang_parse_ctx *C, slang_function *func,
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_operation_construct (func->body);
|
||||
if (!slang_operation_construct_a (func->body))
|
||||
{
|
||||
slang_alloc_free (func->body);
|
||||
func->body = NULL;
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
if (!parse_statement (C, func->body, func->parameters, structs, funcs))
|
||||
return 0;
|
||||
return 1;
|
||||
|
|
@ -1781,7 +1924,13 @@ static int parse_init_declarator (slang_parse_ctx *C, const slang_fully_specifie
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_operation_construct (var->initializer);
|
||||
if (!slang_operation_construct_a (var->initializer))
|
||||
{
|
||||
slang_alloc_free (var->initializer);
|
||||
var->initializer = NULL;
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
if (!parse_expression (C, var->initializer, vars, structs, funcs))
|
||||
return 0;
|
||||
break;
|
||||
|
|
@ -1816,13 +1965,32 @@ static int parse_init_declarator (slang_parse_ctx *C, const slang_fully_specifie
|
|||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
slang_operation_construct (var->array_size);
|
||||
if (!slang_operation_construct_a (var->array_size))
|
||||
{
|
||||
slang_alloc_free (var->array_size);
|
||||
var->array_size = NULL;
|
||||
slang_info_log_memory (C->L);
|
||||
return 0;
|
||||
}
|
||||
if (!parse_expression (C, var->array_size, vars, structs, funcs))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (!(var->type.specifier.type == slang_spec_array && var->array_size == NULL))
|
||||
{
|
||||
slang_storage_aggregate agg;
|
||||
|
||||
slang_storage_aggregate_construct (&agg);
|
||||
if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_size, funcs,
|
||||
structs))
|
||||
{
|
||||
slang_storage_aggregate_destruct (&agg);
|
||||
return 0;
|
||||
}
|
||||
slang_storage_aggregate_destruct (&agg);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1874,7 +2042,8 @@ static int parse_function (slang_parse_ctx *C, int definition, slang_struct_scop
|
|||
}
|
||||
}
|
||||
|
||||
/* find a function with a prototype matching the parsed one */
|
||||
/* find a function with a prototype matching the parsed one - only the current scope
|
||||
is being searched to allow built-in function overriding */
|
||||
found_func = slang_function_scope_find (funcs, &parsed_func, 0);
|
||||
if (found_func == NULL)
|
||||
{
|
||||
|
|
@ -1919,6 +2088,37 @@ static int parse_function (slang_parse_ctx *C, int definition, slang_struct_scop
|
|||
/* return the found function */
|
||||
*parsed_func_ret = found_func;
|
||||
}
|
||||
|
||||
/* assemble the parsed function */
|
||||
if (definition)
|
||||
{
|
||||
static int x = 0;
|
||||
const int y = 61; /* core 437 */
|
||||
static
|
||||
slang_assembly_file file;
|
||||
slang_assembly_name_space space;
|
||||
x++;
|
||||
if (x == 1)
|
||||
slang_assembly_file_construct (&file);
|
||||
space.funcs = funcs;
|
||||
space.structs = structs;
|
||||
space.vars = scope;
|
||||
if (x == 1)
|
||||
xxx_first (&file);
|
||||
if (x == y)
|
||||
xxx_prolog (&file);
|
||||
if (!_slang_assemble_function (&file, *parsed_func_ret, &space))
|
||||
{
|
||||
slang_assembly_file_destruct (&file);
|
||||
return 0;
|
||||
}
|
||||
if (x == y)
|
||||
{
|
||||
_slang_execute (&file);
|
||||
slang_assembly_file_destruct (&file);
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,14 +68,21 @@ typedef enum slang_type_specifier_type_
|
|||
slang_spec_sampler2DShadow,
|
||||
slang_spec_struct,
|
||||
slang_spec_array
|
||||
} slang_type_specifier_type;
|
||||
} slang_type_specifier_type;
|
||||
|
||||
slang_type_specifier_type slang_type_specifier_type_from_string (const char *);
|
||||
|
||||
typedef struct slang_type_specifier_
|
||||
{
|
||||
slang_type_specifier_type type;
|
||||
struct slang_struct_ *_struct; /* spec_struct */
|
||||
struct slang_type_specifier_ *_array; /* spec_array */
|
||||
} slang_type_specifier;
|
||||
} slang_type_specifier;
|
||||
|
||||
void slang_type_specifier_construct (slang_type_specifier *);
|
||||
void slang_type_specifier_destruct (slang_type_specifier *);
|
||||
int slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *);
|
||||
int slang_type_specifier_equal (const slang_type_specifier *, const slang_type_specifier *);
|
||||
|
||||
typedef struct slang_fully_specified_type_
|
||||
{
|
||||
|
|
@ -164,29 +171,40 @@ typedef struct slang_operation_
|
|||
float literal; /* bool, literal_int, literal_float */
|
||||
char *identifier; /* asm, identifier, call, field */
|
||||
slang_variable_scope *locals;
|
||||
} slang_operation;
|
||||
} slang_operation;
|
||||
|
||||
int slang_operation_construct_a (slang_operation *);
|
||||
void slang_operation_destruct (slang_operation *);
|
||||
|
||||
typedef struct slang_variable_
|
||||
{
|
||||
slang_fully_specified_type type;
|
||||
char *name;
|
||||
slang_operation *array_size; /* spec_array */
|
||||
slang_operation *initializer;
|
||||
} slang_variable;
|
||||
slang_operation *initializer;
|
||||
unsigned int address;
|
||||
} slang_variable;
|
||||
|
||||
slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all);
|
||||
|
||||
typedef struct slang_struct_scope_
|
||||
{
|
||||
struct slang_struct_ *structs;
|
||||
unsigned int num_structs;
|
||||
struct slang_struct_scope_ *outer_scope;
|
||||
} slang_struct_scope;
|
||||
} slang_struct_scope;
|
||||
|
||||
struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, const char *, int);
|
||||
|
||||
typedef struct slang_struct_
|
||||
{
|
||||
char *name;
|
||||
slang_variable_scope *fields;
|
||||
slang_struct_scope *structs;
|
||||
} slang_struct;
|
||||
} slang_struct;
|
||||
|
||||
int slang_struct_construct_a (slang_struct *);
|
||||
int slang_struct_copy (slang_struct *, const slang_struct *);
|
||||
|
||||
typedef enum slang_function_kind_
|
||||
{
|
||||
|
|
@ -201,7 +219,8 @@ typedef struct slang_function_
|
|||
slang_variable header;
|
||||
slang_variable_scope *parameters;
|
||||
unsigned int param_count;
|
||||
slang_operation *body;
|
||||
slang_operation *body;
|
||||
unsigned int address;
|
||||
} slang_function;
|
||||
|
||||
typedef struct slang_function_scope_
|
||||
|
|
|
|||
347
src/mesa/shader/slang/slang_execute.c
Normal file
347
src/mesa/shader/slang/slang_execute.c
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_execute.c
|
||||
* intermediate code interpreter
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "imports.h"
|
||||
#include "slang_utility.h"
|
||||
#include "slang_assemble.h"
|
||||
#include "slang_storage.h"
|
||||
#include "slang_execute.h"
|
||||
|
||||
static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
|
||||
{
|
||||
fprintf (f, "%.5u:\t", i);
|
||||
|
||||
switch (a->type)
|
||||
{
|
||||
case slang_asm_none:
|
||||
fprintf (f, "none");
|
||||
break;
|
||||
case slang_asm_float_copy:
|
||||
fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]);
|
||||
break;
|
||||
case slang_asm_float_move:
|
||||
fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]);
|
||||
break;
|
||||
case slang_asm_float_push:
|
||||
fprintf (f, "float_push\t%f", a->literal);
|
||||
break;
|
||||
case slang_asm_float_deref:
|
||||
fprintf (f, "float_deref");
|
||||
break;
|
||||
case slang_asm_float_add:
|
||||
fprintf (f, "float_add");
|
||||
break;
|
||||
case slang_asm_float_multiply:
|
||||
fprintf (f, "float_multiply");
|
||||
break;
|
||||
case slang_asm_float_divide:
|
||||
fprintf (f, "float_divide");
|
||||
break;
|
||||
case slang_asm_float_negate:
|
||||
fprintf (f, "float_negate");
|
||||
break;
|
||||
case slang_asm_float_less:
|
||||
fprintf (f, "float_less");
|
||||
break;
|
||||
case slang_asm_float_equal:
|
||||
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_int_copy:
|
||||
fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);
|
||||
break;
|
||||
case slang_asm_int_move:
|
||||
fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]);
|
||||
break;
|
||||
case slang_asm_int_push:
|
||||
fprintf (f, "int_push\t%d", (GLint) a->literal);
|
||||
break;
|
||||
case slang_asm_int_deref:
|
||||
fprintf (f, "int_deref");
|
||||
break;
|
||||
case slang_asm_int_to_float:
|
||||
fprintf (f, "int_to_float");
|
||||
break;
|
||||
case slang_asm_int_to_addr:
|
||||
fprintf (f, "int_to_addr");
|
||||
break;
|
||||
case slang_asm_bool_copy:
|
||||
fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
|
||||
break;
|
||||
case slang_asm_bool_move:
|
||||
fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]);
|
||||
break;
|
||||
case slang_asm_bool_push:
|
||||
fprintf (f, "bool_push\t%d", a->literal != 0.0f);
|
||||
break;
|
||||
case slang_asm_bool_deref:
|
||||
fprintf (f, "bool_deref");
|
||||
break;
|
||||
case slang_asm_addr_copy:
|
||||
fprintf (f, "addr_copy");
|
||||
break;
|
||||
case slang_asm_addr_push:
|
||||
fprintf (f, "addr_push\t%u", a->param[0]);
|
||||
break;
|
||||
case slang_asm_addr_deref:
|
||||
fprintf (f, "addr_deref");
|
||||
break;
|
||||
case slang_asm_addr_add:
|
||||
fprintf (f, "address_add");
|
||||
break;
|
||||
case slang_asm_addr_multiply:
|
||||
fprintf (f, "address_multiply");
|
||||
break;
|
||||
case slang_asm_jump:
|
||||
fprintf (f, "jump\t%u", a->param[0]);
|
||||
break;
|
||||
case slang_asm_jump_if_zero:
|
||||
fprintf (f, "jump_if_zero\t%u", a->param[0]);
|
||||
break;
|
||||
case slang_asm_enter:
|
||||
fprintf (f, "enter\t%u", a->param[0]);
|
||||
break;
|
||||
case slang_asm_leave:
|
||||
fprintf (f, "leave");
|
||||
break;
|
||||
case slang_asm_local_alloc:
|
||||
fprintf (f, "local_alloc\t%u", a->param[0]);
|
||||
break;
|
||||
case slang_asm_local_free:
|
||||
fprintf (f, "local_free\t%u", a->param[0]);
|
||||
break;
|
||||
case slang_asm_local_addr:
|
||||
fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]);
|
||||
break;
|
||||
case slang_asm_call:
|
||||
fprintf (f, "call\t%u", a->param[0]);
|
||||
break;
|
||||
case slang_asm_return:
|
||||
fprintf (f, "return");
|
||||
break;
|
||||
case slang_asm_discard:
|
||||
fprintf (f, "discard");
|
||||
break;
|
||||
case slang_asm_exit:
|
||||
fprintf (f, "exit");
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf (f, "\n");
|
||||
}
|
||||
|
||||
static void dump (const slang_assembly_file *file)
|
||||
{
|
||||
unsigned int i;
|
||||
static unsigned int counter = 0;
|
||||
FILE *f;
|
||||
char filename[256];
|
||||
|
||||
counter++;
|
||||
sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
|
||||
f = fopen (filename, "w");
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < file->count; i++)
|
||||
dump_instruction (f, file->code + i, i);
|
||||
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
int _slang_execute (const slang_assembly_file *file)
|
||||
{
|
||||
slang_machine mach;
|
||||
FILE *f;
|
||||
|
||||
mach.ip = 0;
|
||||
mach.sp = SLANG_MACHINE_STACK_SIZE;
|
||||
mach.bp = 0;
|
||||
mach.kill = 0;
|
||||
mach.exit = 0;
|
||||
|
||||
/* assume 32-bit machine */
|
||||
static_assert(sizeof (GLfloat) == 4);
|
||||
static_assert(sizeof (GLfloat *) == 4);
|
||||
static_assert(sizeof (GLuint) == 4);
|
||||
static_assert(sizeof (GLuint *) == 4);
|
||||
|
||||
dump (file);
|
||||
|
||||
f = fopen ("~mesa-slang-assembly-execution.txt", "w");
|
||||
|
||||
while (!mach.exit)
|
||||
{
|
||||
slang_assembly *a = file->code + mach.ip;
|
||||
if (f != NULL)
|
||||
{
|
||||
unsigned int i;
|
||||
dump_instruction (f, a, 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._float[i], mach.stack._addr[i]);
|
||||
fflush (f);
|
||||
}
|
||||
mach.ip++;
|
||||
|
||||
switch (a->type)
|
||||
{
|
||||
case slang_asm_none:
|
||||
break;
|
||||
case slang_asm_float_copy:
|
||||
case slang_asm_int_copy:
|
||||
case slang_asm_bool_copy:
|
||||
*(mach.stack._floatp[mach.sp + a->param[0] / 4] + a->param[1] / 4) =
|
||||
mach.stack._float[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_float_move:
|
||||
case slang_asm_int_move:
|
||||
case slang_asm_bool_move:
|
||||
mach.stack._float[mach.sp + a->param[0] / 4] =
|
||||
mach.stack._float[mach.sp + (mach.stack._addr[mach.sp] + a->param[1]) / 4];
|
||||
break;
|
||||
case slang_asm_float_push:
|
||||
case slang_asm_int_push:
|
||||
case slang_asm_bool_push:
|
||||
mach.sp--;
|
||||
mach.stack._float[mach.sp] = a->literal;
|
||||
break;
|
||||
case slang_asm_float_deref:
|
||||
case slang_asm_int_deref:
|
||||
case slang_asm_bool_deref:
|
||||
mach.stack._float[mach.sp] = *mach.stack._floatp[mach.sp];
|
||||
break;
|
||||
case slang_asm_float_add:
|
||||
mach.stack._float[mach.sp + 1] += mach.stack._float[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_float_multiply:
|
||||
mach.stack._float[mach.sp + 1] *= mach.stack._float[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_float_divide:
|
||||
mach.stack._float[mach.sp + 1] /= mach.stack._float[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_float_negate:
|
||||
mach.stack._float[mach.sp] = -mach.stack._float[mach.sp];
|
||||
break;
|
||||
case slang_asm_float_less:
|
||||
mach.stack._float[mach.sp + 1] =
|
||||
mach.stack._float[mach.sp + 1] < mach.stack._float[mach.sp] ? 1.0f : 0.0f;
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_float_equal:
|
||||
mach.sp--;
|
||||
mach.stack._float[mach.sp] = mach.stack._float[mach.sp + 1 + a->param[0] / 4] ==
|
||||
mach.stack._float[mach.sp + 1 + a->param[1] / 4] ? 1.0f : 0.0f;
|
||||
break;
|
||||
case slang_asm_float_to_int:
|
||||
mach.stack._float[mach.sp] = (GLfloat) (GLint) mach.stack._float[mach.sp];
|
||||
break;
|
||||
case slang_asm_int_to_float:
|
||||
break;
|
||||
case slang_asm_int_to_addr:
|
||||
mach.stack._addr[mach.sp] = (GLuint) (GLint) mach.stack._float[mach.sp];
|
||||
break;
|
||||
case slang_asm_addr_copy:
|
||||
*mach.stack._addrp[mach.sp + 1] = mach.stack._addr[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_addr_push:
|
||||
mach.sp--;
|
||||
mach.stack._addr[mach.sp] = a->param[0];
|
||||
break;
|
||||
case slang_asm_addr_deref:
|
||||
mach.stack._addr[mach.sp] = *mach.stack._addrp[mach.sp];
|
||||
break;
|
||||
case slang_asm_addr_add:
|
||||
mach.stack._addr[mach.sp + 1] += mach.stack._addr[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_addr_multiply:
|
||||
mach.stack._addr[mach.sp + 1] *= mach.stack._addr[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_jump:
|
||||
mach.ip = a->param[0];
|
||||
break;
|
||||
case slang_asm_jump_if_zero:
|
||||
if (mach.stack._float[mach.sp] == 0.0f)
|
||||
mach.ip = a->param[0];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_enter:
|
||||
mach.sp--;
|
||||
mach.stack._addr[mach.sp] = mach.bp;
|
||||
mach.bp = mach.sp + a->param[0] / 4 + 1;
|
||||
break;
|
||||
case slang_asm_leave:
|
||||
mach.bp = mach.stack._addr[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_local_alloc:
|
||||
mach.sp -= a->param[0] / 4;
|
||||
break;
|
||||
case slang_asm_local_free:
|
||||
mach.sp += a->param[0] / 4;
|
||||
break;
|
||||
case slang_asm_local_addr:
|
||||
mach.sp--;
|
||||
mach.stack._addr[mach.sp] = (GLuint) mach.stack._addr + mach.bp * 4 -
|
||||
(a->param[0] + a->param[1]);
|
||||
break;
|
||||
case slang_asm_call:
|
||||
mach.sp--;
|
||||
mach.stack._addr[mach.sp] = mach.ip;
|
||||
mach.ip = a->param[0];
|
||||
break;
|
||||
case slang_asm_return:
|
||||
mach.ip = mach.stack._addr[mach.sp];
|
||||
mach.sp++;
|
||||
break;
|
||||
case slang_asm_discard:
|
||||
mach.kill = 1;
|
||||
break;
|
||||
case slang_asm_exit:
|
||||
mach.exit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (f != NULL)
|
||||
fclose (f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
57
src/mesa/shader/slang/slang_execute.h
Normal file
57
src/mesa/shader/slang/slang_execute.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_EXECUTE_H
|
||||
#define SLANG_EXECUTE_H
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SLANG_MACHINE_STACK_SIZE 64
|
||||
|
||||
typedef struct slang_machine_
|
||||
{
|
||||
GLuint ip; /* instruction pointer, for flow control */
|
||||
GLuint sp; /* stack pointer, for stack access */
|
||||
GLuint bp; /* base pointer, for local variable access */
|
||||
GLuint kill; /* discard the fragment */
|
||||
GLuint exit; /* terminate the shader */
|
||||
union stack_
|
||||
{
|
||||
GLfloat _float[SLANG_MACHINE_STACK_SIZE];
|
||||
GLfloat *_floatp[SLANG_MACHINE_STACK_SIZE];
|
||||
GLuint _addr[SLANG_MACHINE_STACK_SIZE];
|
||||
GLuint *_addrp[SLANG_MACHINE_STACK_SIZE];
|
||||
} stack;
|
||||
} slang_machine;
|
||||
|
||||
int _slang_execute (const slang_assembly_file *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
255
src/mesa/shader/slang/slang_storage.c
Normal file
255
src/mesa/shader/slang/slang_storage.c
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file slang_storage.c
|
||||
* slang variable storage
|
||||
* \author Michal Krol
|
||||
*/
|
||||
|
||||
#include "imports.h"
|
||||
#include "slang_utility.h"
|
||||
#include "slang_storage.h"
|
||||
#include "slang_assemble.h"
|
||||
|
||||
/* slang_storage_array */
|
||||
|
||||
void slang_storage_array_construct (slang_storage_array *arr)
|
||||
{
|
||||
arr->type = slang_stor_aggregate;
|
||||
arr->aggregate = NULL;
|
||||
arr->length = 0;
|
||||
}
|
||||
|
||||
void slang_storage_array_destruct (slang_storage_array *arr)
|
||||
{
|
||||
if (arr->aggregate != NULL)
|
||||
{
|
||||
slang_storage_aggregate_destruct (arr->aggregate);
|
||||
slang_alloc_free (arr->aggregate);
|
||||
}
|
||||
}
|
||||
|
||||
/* slang_storage_aggregate */
|
||||
|
||||
void slang_storage_aggregate_construct (slang_storage_aggregate *agg)
|
||||
{
|
||||
agg->arrays = NULL;
|
||||
agg->count = 0;
|
||||
}
|
||||
|
||||
void slang_storage_aggregate_destruct (slang_storage_aggregate *agg)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < agg->count; i++)
|
||||
slang_storage_array_destruct (agg->arrays + i);
|
||||
slang_alloc_free (agg->arrays);
|
||||
}
|
||||
|
||||
static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggregate *agg)
|
||||
{
|
||||
slang_storage_array *arr = NULL;
|
||||
agg->arrays = (slang_storage_array *) slang_alloc_realloc (agg->arrays, agg->count * sizeof (
|
||||
slang_storage_array), (agg->count + 1) * sizeof (slang_storage_array));
|
||||
if (agg->arrays != NULL)
|
||||
{
|
||||
arr = agg->arrays + agg->count;
|
||||
slang_storage_array_construct (arr);
|
||||
agg->count++;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/* _slang_aggregate_variable() */
|
||||
|
||||
static int aggregate_vector (slang_storage_aggregate *agg, slang_storage_type basic_type,
|
||||
unsigned int row_count)
|
||||
{
|
||||
slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
|
||||
if (arr == NULL)
|
||||
return 0;
|
||||
arr->type = basic_type;
|
||||
arr->length = row_count;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type,
|
||||
unsigned int order)
|
||||
{
|
||||
slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
|
||||
if (arr == NULL)
|
||||
return 0;
|
||||
arr->type = slang_stor_aggregate;
|
||||
arr->length = order;
|
||||
arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (
|
||||
slang_storage_aggregate));
|
||||
if (arr->aggregate == NULL)
|
||||
return 0;
|
||||
slang_storage_aggregate_construct (arr->aggregate);
|
||||
if (!aggregate_vector (arr->aggregate, basic_type, order))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aggregate_variables (slang_storage_aggregate *agg, const slang_variable_scope *vars,
|
||||
slang_function_scope *funcs, slang_struct_scope *structs)
|
||||
{
|
||||
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))
|
||||
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)
|
||||
{
|
||||
switch (spec->type)
|
||||
{
|
||||
case slang_spec_bool:
|
||||
return aggregate_vector (agg, slang_stor_bool, 1);
|
||||
case slang_spec_bvec2:
|
||||
return aggregate_vector (agg, slang_stor_bool, 2);
|
||||
case slang_spec_bvec3:
|
||||
return aggregate_vector (agg, slang_stor_bool, 3);
|
||||
case slang_spec_bvec4:
|
||||
return aggregate_vector (agg, slang_stor_bool, 4);
|
||||
case slang_spec_int:
|
||||
return aggregate_vector (agg, slang_stor_int, 1);
|
||||
case slang_spec_ivec2:
|
||||
return aggregate_vector (agg, slang_stor_int, 2);
|
||||
case slang_spec_ivec3:
|
||||
return aggregate_vector (agg, slang_stor_int, 3);
|
||||
case slang_spec_ivec4:
|
||||
return aggregate_vector (agg, slang_stor_int, 4);
|
||||
case slang_spec_float:
|
||||
return aggregate_vector (agg, slang_stor_float, 1);
|
||||
case slang_spec_vec2:
|
||||
return aggregate_vector (agg, slang_stor_float, 2);
|
||||
case slang_spec_vec3:
|
||||
return aggregate_vector (agg, slang_stor_float, 3);
|
||||
case slang_spec_vec4:
|
||||
return aggregate_vector (agg, slang_stor_float, 4);
|
||||
case slang_spec_mat2:
|
||||
return aggregate_matrix (agg, slang_stor_float, 2);
|
||||
case slang_spec_mat3:
|
||||
return aggregate_matrix (agg, slang_stor_float, 3);
|
||||
case slang_spec_mat4:
|
||||
return aggregate_matrix (agg, slang_stor_float, 4);
|
||||
case slang_spec_sampler1D:
|
||||
case slang_spec_sampler2D:
|
||||
case slang_spec_sampler3D:
|
||||
case slang_spec_samplerCube:
|
||||
case slang_spec_sampler1DShadow:
|
||||
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);
|
||||
case slang_spec_array:
|
||||
{
|
||||
slang_storage_array *arr;
|
||||
slang_assembly_file file;
|
||||
slang_assembly_flow_control flow;
|
||||
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)
|
||||
return 0;
|
||||
arr->type = slang_stor_aggregate;
|
||||
arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (
|
||||
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))
|
||||
return 0;
|
||||
slang_assembly_file_construct (&file);
|
||||
space.funcs = funcs;
|
||||
space.structs = structs;
|
||||
/* XXX: vars! */
|
||||
space.vars = NULL;
|
||||
if (!_slang_assemble_operation (&file, array_size, 0, &flow, &space, &info, &stk))
|
||||
{
|
||||
slang_assembly_file_destruct (&file);
|
||||
return 0;
|
||||
}
|
||||
/* TODO: evaluate array size */
|
||||
slang_assembly_file_destruct (&file);
|
||||
arr->length = 256;
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* _slang_sizeof_aggregate() */
|
||||
|
||||
unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
|
||||
{
|
||||
unsigned int i, size = 0;
|
||||
for (i = 0; i < agg->count; i++)
|
||||
{
|
||||
unsigned int element_size;
|
||||
if (agg->arrays[i].type == slang_stor_aggregate)
|
||||
element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate);
|
||||
else
|
||||
element_size = sizeof (GLfloat);
|
||||
size += element_size * agg->arrays[i].length;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/* _slang_flatten_aggregate () */
|
||||
|
||||
int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < agg->count; i++)
|
||||
{
|
||||
unsigned int j;
|
||||
for (j = 0; j < agg->arrays[i].length; j++)
|
||||
{
|
||||
if (agg->arrays[i].type == slang_stor_aggregate)
|
||||
{
|
||||
if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
slang_storage_array *arr;
|
||||
arr = slang_storage_aggregate_push_new (flat);
|
||||
if (arr == NULL)
|
||||
return 0;
|
||||
arr->type = agg->arrays[i].type;
|
||||
arr->length = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
109
src/mesa/shader/slang/slang_storage.h
Normal file
109
src/mesa/shader/slang/slang_storage.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined SLANG_STORAGE_H
|
||||
#define SLANG_STORAGE_H
|
||||
|
||||
#include "slang_compile.h"
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Program variable data storage is kept completely transparent to the front-end compiler. It is
|
||||
up to the back-end how the data is actually allocated. The slang_storage_type enum
|
||||
provides the basic information about how the memory is interpreted. This abstract piece
|
||||
of memory is called a data slot. A data slot of a particular type has a fixed size.
|
||||
|
||||
For now, only the three basic types are supported, that is bool, int and float. Other built-in
|
||||
types like vector or matrix can easily be decomposed into a series of basic types.
|
||||
*/
|
||||
typedef enum slang_storage_type_
|
||||
{
|
||||
slang_stor_aggregate,
|
||||
slang_stor_bool,
|
||||
slang_stor_int,
|
||||
slang_stor_float
|
||||
} slang_storage_type;
|
||||
|
||||
/*
|
||||
The slang_storage_array structure groups data slots of the same type into an array. This
|
||||
array has a fixed length. Arrays are required to have a size equal to the sum of sizes of its
|
||||
elements. They are also required to support indirect addressing. That is, if B references
|
||||
first data slot in the array, S is the size of the data slot and I is the integral index that
|
||||
is not known at compile time, B+I*S references I-th data slot.
|
||||
|
||||
This structure is also used to break down built-in data types that are not supported directly.
|
||||
Vectors, like vec3, are constructed from arrays of their basic types. Matrices are formed of
|
||||
an array of column vectors, which are in turn processed as other vectors.
|
||||
*/
|
||||
typedef struct slang_storage_array_
|
||||
{
|
||||
slang_storage_type type;
|
||||
struct slang_storage_aggregate_ *aggregate; /* slang_stor_aggregate */
|
||||
unsigned int length;
|
||||
} slang_storage_array;
|
||||
|
||||
void slang_storage_array_construct (slang_storage_array *);
|
||||
void slang_storage_array_destruct (slang_storage_array *);
|
||||
|
||||
/*
|
||||
The slang_storage_aggregate structure relaxes the indirect addressing requirement for
|
||||
slang_storage_array structure. Aggregates are always accessed statically - its member
|
||||
addresses are well-known at compile time. For example, user-defined types are implemented as
|
||||
aggregates. Aggregates can collect data of a different type.
|
||||
*/
|
||||
typedef struct slang_storage_aggregate_
|
||||
{
|
||||
slang_storage_array *arrays;
|
||||
unsigned int count;
|
||||
} slang_storage_aggregate;
|
||||
|
||||
void 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 *);
|
||||
|
||||
/*
|
||||
returns total size (in machine units) of the given aggregate
|
||||
returns 0 on error
|
||||
*/
|
||||
unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *);
|
||||
|
||||
/*
|
||||
converts structured aggregate to a flat one, with arrays of generic type being
|
||||
one-element long
|
||||
returns 1 on success
|
||||
returns 0 otherwise
|
||||
*/
|
||||
int _slang_flatten_aggregate (slang_storage_aggregate *, const slang_storage_aggregate *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -187,8 +187,14 @@ SLANG_CPP_SOURCES = \
|
|||
shader/slang/OSDependent/Linux/ossource.cpp
|
||||
|
||||
SLANG_SOURCES = \
|
||||
shader/slang/slang_assemble.c \
|
||||
shader/slang/slang_assemble_conditional.c \
|
||||
shader/slang/slang_assemble_constructor.c \
|
||||
shader/slang/slang_assemble_typeinfo.c \
|
||||
shader/slang/slang_compile.c \
|
||||
shader/slang/slang_execute.c \
|
||||
shader/slang/slang_preprocess.c \
|
||||
shader/slang/slang_storage.c \
|
||||
shader/slang/slang_utility.c
|
||||
|
||||
ASM_C_SOURCES = \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue