summaryrefslogtreecommitdiff
path: root/src/mesa/shader/slang/slang_compile.c
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2006-12-13 14:48:36 -0700
committerBrian <brian@yutani.localnet.net>2006-12-13 14:48:36 -0700
commitaff8e204d205b5d424d2c39a5d9e004caaa1eab1 (patch)
tree91d06d422f8900af461233186bcc79351c3025f6 /src/mesa/shader/slang/slang_compile.c
parent5b35132b41427798e02a66a8e39583fffbe9d232 (diff)
Checkpoint new GLSL compiler back-end to produce fp/vp-style assembly instructions.
Diffstat (limited to 'src/mesa/shader/slang/slang_compile.c')
-rw-r--r--src/mesa/shader/slang/slang_compile.c248
1 files changed, 192 insertions, 56 deletions
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index c49ab4a68d..a9c84abdce 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -29,10 +29,16 @@
*/
#include "imports.h"
+#include "context.h"
+#include "program.h"
#include "grammar_mesa.h"
+#include "slang_codegen.h"
#include "slang_compile.h"
#include "slang_preprocess.h"
#include "slang_storage.h"
+#include "slang_error.h"
+
+#include "slang_print.h"
/*
* This is a straightforward implementation of the slang front-end
@@ -214,6 +220,7 @@ slang_info_log_memory(slang_info_log * log)
log->dont_free_text = 1;
log->text = out_of_memory;
}
+ abort();
}
/* slang_parse_ctx */
@@ -237,6 +244,7 @@ typedef struct slang_output_ctx_
slang_assembly_file *assembly;
slang_var_pool *global_pool;
slang_machine *machine;
+ struct gl_program *program;
} slang_output_ctx;
/* _slang_compile() */
@@ -782,16 +790,17 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
* \param C the parsing context
* \param O the output context
* \param oper the operation we're parsing
- * \param statment which child of the operation is being parsed
+ * \param statement indicates whether parsing a statement, or expression
* \return 1 if success, 0 if error
*/
static int
parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
- slang_operation * oper, unsigned int statement)
+ slang_operation * oper, GLboolean statement)
{
slang_operation *ch;
/* grow child array */
+#if 000
oper->children = (slang_operation *)
slang_alloc_realloc(oper->children,
oper->num_children * sizeof(slang_operation),
@@ -807,7 +816,9 @@ parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
return 0;
}
oper->num_children++;
- /* XXX I guess the 0th "statement" is not really a statement? */
+#else
+ ch = slang_operation_grow(&oper->num_children, &oper->children);
+#endif
if (statement)
return parse_statement(C, O, ch);
return parse_expression(C, O, ch);
@@ -846,6 +857,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
/* local variable declaration, individual declarators are stored as
* children identifiers
*/
+#if 000
oper->type = slang_oper_variable_decl;
{
const unsigned int first_var = O->vars->num_variables;
@@ -881,6 +893,38 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
}
}
}
+#else
+
+ oper->type = slang_oper_block_no_new_scope;
+ {
+ const unsigned int first_var = O->vars->num_variables;
+
+ /* parse the declaration, note that there can be zero or more
+ * than one declarators
+ */
+ if (!parse_declaration(C, O))
+ return 0;
+ if (first_var < O->vars->num_variables) {
+ const unsigned int num_vars = O->vars->num_variables - first_var;
+ unsigned int i;
+
+ oper->num_children = num_vars;
+ oper->children = slang_operation_new(num_vars);
+ if (oper->children == NULL) {
+ slang_info_log_memory(C->L);
+ return 0;
+ }
+ for (i = first_var; i < O->vars->num_variables; i++) {
+ slang_operation *o = &oper->children[i - first_var];
+ o->type = slang_oper_variable_decl;
+ o->locals->outer_scope = O->vars;
+ o->a_id = O->vars->variables[i].a_name;
+ }
+ }
+ }
+
+
+#endif
break;
case OP_ASM:
/* the __asm statement, parse the mnemonic and all its arguments
@@ -888,6 +932,9 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
*/
oper->type = slang_oper_asm;
oper->a_id = parse_identifier(C);
+ if (strcmp((char*)oper->a_id, "dot") == 0) {
+ printf("Assemble dot! **************************\n");
+ }
if (oper->a_id == SLANG_ATOM_NULL)
return 0;
while (*C->I != OP_END) {
@@ -1042,18 +1089,27 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
op->type = slang_oper_literal_bool;
if (!parse_number(C, &number))
return 0;
- op->literal = (GLfloat) number;
+ op->literal[0] =
+ op->literal[1] =
+ op->literal[2] =
+ op->literal[3] = (GLfloat) number;
break;
case OP_PUSH_INT:
op->type = slang_oper_literal_int;
if (!parse_number(C, &number))
return 0;
- op->literal = (GLfloat) number;
+ op->literal[0] =
+ op->literal[1] =
+ op->literal[2] =
+ op->literal[3] = (GLfloat) number;
break;
case OP_PUSH_FLOAT:
op->type = slang_oper_literal_float;
- if (!parse_float(C, &op->literal))
+ if (!parse_float(C, &op->literal[0]))
return 0;
+ op->literal[1] =
+ op->literal[2] =
+ op->literal[3] = op->literal[0];
break;
case OP_PUSH_IDENTIFIER:
op->type = slang_oper_identifier;
@@ -1480,6 +1536,20 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
return 0;
}
+#if 111
+ /* if the function returns a value, append a hidden __retVal 'out'
+ * parameter that corresponds to the return value.
+ */
+ if (_slang_function_has_return_value(func)) {
+ slang_variable *p = slang_variable_scope_grow(func->parameters);
+ slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");
+ assert(a_retVal);
+ p->a_name = a_retVal;
+ p->type = func->header.type;
+ p->type.qualifier = slang_qual_out;
+ }
+#endif
+
/* function formal parameters and local variables share the same
* scope, so save the information about param count in a seperate
* place also link the scope to the global variable scope so when a
@@ -1488,6 +1558,7 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
*/
func->param_count = func->parameters->num_variables;
func->parameters->outer_scope = O->vars;
+
return 1;
}
@@ -1770,9 +1841,9 @@ parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
* \param O output context
* \param definition if non-zero expect a definition, else a declaration
* \param parsed_func_ret returns the parsed function
- * \return 1 if success, 0 if failure
+ * \return GL_TRUE if success, GL_FALSE if failure
*/
-static int
+static GLboolean
parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
slang_function ** parsed_func_ret)
{
@@ -1780,17 +1851,17 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
/* parse function definition/declaration */
if (!slang_function_construct(&parsed_func))
- return 0;
+ return GL_FALSE;
if (definition) {
if (!parse_function_definition(C, O, &parsed_func)) {
slang_function_destruct(&parsed_func);
- return 0;
+ return GL_FALSE;
}
}
else {
if (!parse_function_prototype(C, O, &parsed_func)) {
slang_function_destruct(&parsed_func);
- return 0;
+ return GL_FALSE;
}
}
@@ -1800,7 +1871,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
*/
found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
if (found_func == NULL) {
- /* add the parsed function to the function list */
+ /* New function, add it to the function list */
O->funs->functions =
(slang_function *) slang_alloc_realloc(O->funs->functions,
O->funs->num_functions *
@@ -1810,7 +1881,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
if (O->funs->functions == NULL) {
slang_info_log_memory(C->L);
slang_function_destruct(&parsed_func);
- return 0;
+ return GL_FALSE;
}
O->funs->functions[O->funs->num_functions] = parsed_func;
O->funs->num_functions++;
@@ -1819,6 +1890,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
*parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
}
else {
+ /* previously defined or declared */
/* TODO: check function return type qualifiers and specifiers */
if (definition) {
if (found_func->body != NULL) {
@@ -1827,7 +1899,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
parsed_func.header.
a_name));
slang_function_destruct(&parsed_func);
- return 0;
+ return GL_FALSE;
}
/* destroy the existing function declaration and replace it
@@ -1857,10 +1929,33 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
A.space.funcs = O->funs;
A.space.structs = O->structs;
A.space.vars = O->vars;
- if (!_slang_assemble_function(&A, *parsed_func_ret))
- return 0;
+ A.program = O->program;
+
+ _slang_reset_error();
+
+#if 0
+ printf("*************** Assemble function %s ****\n", (char *) (*parsed_func_ret)->header.a_name);
+ slang_print_var_scope((*parsed_func_ret)->parameters,
+ (*parsed_func_ret)->param_count);
+#endif
+
+
+ if (!_slang_assemble_function(&A, *parsed_func_ret)) {
+ /* propogate the error message back through the info log */
+ C->L->text = _mesa_strdup(_slang_error_text());
+ C->L->dont_free_text = GL_FALSE;
+ return GL_FALSE;
+ }
+
+
+#if 0
+ printf("**************************************\n");
+#endif
+#if 1
+ _slang_codegen_function(&A, *parsed_func_ret);
+#endif
}
- return 1;
+ return GL_TRUE;
}
/* declaration */
@@ -1895,7 +1990,8 @@ parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
#define EXTERNAL_DECLARATION 2
static GLboolean
-parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
+parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
+ struct gl_program *program)
{
slang_output_ctx o;
@@ -1906,6 +2002,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
o.assembly = &unit->object->assembly;
o.global_pool = &unit->object->varpool;
o.machine = &unit->object->machine;
+ o.program = program;
/* parse individual functions and declarations */
while (*C->I != EXTERNAL_NULL) {
@@ -1915,25 +2012,26 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
slang_function *func;
if (!parse_function(C, &o, 1, &func))
- return 0;
+ return GL_FALSE;
}
break;
case EXTERNAL_DECLARATION:
if (!parse_declaration(C, &o))
- return 0;
+ return GL_FALSE;
break;
default:
- return 0;
+ return GL_FALSE;
}
}
C->I++;
- return 1;
+ return GL_TRUE;
}
static GLboolean
compile_binary(const byte * prod, slang_code_unit * unit,
slang_unit_type type, slang_info_log * infolog,
- slang_code_unit * builtin, slang_code_unit * downlink)
+ slang_code_unit * builtin, slang_code_unit * downlink,
+ struct gl_program *program)
{
slang_parse_ctx C;
@@ -1956,13 +2054,14 @@ compile_binary(const byte * prod, slang_code_unit * unit,
}
/* parse translation unit */
- return parse_code_unit(&C, unit);
+ return parse_code_unit(&C, unit, program);
}
static GLboolean
compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
slang_unit_type type, slang_info_log * infolog,
- slang_code_unit * builtin)
+ slang_code_unit * builtin,
+ struct gl_program *program)
{
byte *prod;
GLuint size, start, version;
@@ -1987,8 +2086,9 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
}
/* Finally check the syntax and generate its binary representation. */
- if (!grammar_fast_check
- (id, (const byte *) (slang_string_cstr(&preprocessed)), &prod, &size,
+ if (!grammar_fast_check(id,
+ (const byte *) (slang_string_cstr(&preprocessed)),
+ &prod, &size,
65536)) {
char buf[1024];
GLint pos;
@@ -1996,14 +2096,14 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
slang_string_free(&preprocessed);
grammar_get_last_error((byte *) (buf), sizeof(buf), &pos);
slang_info_log_error(infolog, buf);
- return GL_FALSE;
+ RETURN_ERROR("syntax error", 0);
}
slang_string_free(&preprocessed);
/* Syntax is okay - translate it to internal representation. */
- if (!compile_binary
- (prod, unit, type, infolog, builtin,
- &builtin[SLANG_BUILTIN_TOTAL - 1])) {
+ if (!compile_binary(prod, unit, type, infolog, builtin,
+ &builtin[SLANG_BUILTIN_TOTAL - 1],
+ program)) {
grammar_alloc_free(prod);
return GL_FALSE;
}
@@ -2032,6 +2132,7 @@ static const byte slang_vertex_builtin_gc[] = {
};
#if defined(USE_X86_ASM) || defined(SLANG_X86)
+foo
static const byte slang_builtin_vec4_gc[] = {
#include "library/slang_builtin_vec4_gc.h"
};
@@ -2039,7 +2140,8 @@ static const byte slang_builtin_vec4_gc[] = {
static GLboolean
compile_object(grammar * id, const char *source, slang_code_object * object,
- slang_unit_type type, slang_info_log * infolog)
+ slang_unit_type type, slang_info_log * infolog,
+ struct gl_program *program)
{
slang_code_unit *builtins = NULL;
@@ -2067,56 +2169,79 @@ compile_object(grammar * id, const char *source, slang_code_object * object,
/* if parsing user-specified shader, load built-in library */
if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) {
/* compile core functionality first */
- if (!compile_binary(slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE],
- slang_unit_fragment_builtin, infolog, NULL, NULL))
+ if (!compile_binary(slang_core_gc,
+ &object->builtin[SLANG_BUILTIN_CORE],
+ slang_unit_fragment_builtin, infolog,
+ NULL, NULL, NULL))
return GL_FALSE;
/* compile common functions and variables, link to core */
- if (!compile_binary
- (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON],
- slang_unit_fragment_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_CORE]))
+ if (!compile_binary(slang_common_builtin_gc,
+ &object->builtin[SLANG_BUILTIN_COMMON],
+ slang_unit_fragment_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_CORE], NULL))
return GL_FALSE;
/* compile target-specific functions and variables, link to common */
if (type == slang_unit_fragment_shader) {
- if (!compile_binary
- (slang_fragment_builtin_gc,
- &object->builtin[SLANG_BUILTIN_TARGET],
- slang_unit_fragment_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON]))
+ if (!compile_binary(slang_fragment_builtin_gc,
+ &object->builtin[SLANG_BUILTIN_TARGET],
+ slang_unit_fragment_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_COMMON], NULL))
return GL_FALSE;
}
else if (type == slang_unit_vertex_shader) {
- if (!compile_binary
- (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
- slang_unit_vertex_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON]))
+ if (!compile_binary(slang_vertex_builtin_gc,
+ &object->builtin[SLANG_BUILTIN_TARGET],
+ slang_unit_vertex_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_COMMON], NULL))
return GL_FALSE;
}
#if defined(USE_X86_ASM) || defined(SLANG_X86)
/* compile x86 4-component vector overrides, link to target */
- if (!compile_binary
- (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4],
- slang_unit_fragment_builtin, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_TARGET]))
+ if (!compile_binary(slang_builtin_vec4_gc,
+ &object->builtin[SLANG_BUILTIN_VEC4],
+ slang_unit_fragment_builtin, infolog, NULL,
+ &object->builtin[SLANG_BUILTIN_TARGET]))
return GL_FALSE;
#endif
/* disable language extensions */
+#if NEW_SLANG /* allow-built-ins */
+ grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
+#else
grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0);
+#endif
builtins = object->builtin;
}
/* compile the actual shader - pass-in built-in library for external shader */
return compile_with_grammar(*id, source, &object->unit, type, infolog,
- builtins);
+ builtins, program);
+}
+
+
+static void
+slang_create_uniforms(const slang_export_data_table *exports,
+ struct gl_program *program)
+{
+ /* XXX only add uniforms that are actually going to get used */
+ GLuint i;
+ for (i = 0; i < exports->count; i++) {
+ if (exports->entries[i].access == slang_exp_uniform) {
+ const char *name = (char *) exports->entries[i].quant.name;
+ GLint j = _mesa_add_uniform(program->Parameters, name, 4);
+ assert(j >= 0);
+ }
+ }
}
+
GLboolean
_slang_compile(const char *source, slang_code_object * object,
- slang_unit_type type, slang_info_log * infolog)
+ slang_unit_type type, slang_info_log * infolog,
+ struct gl_program *program)
{
GLboolean success;
grammar id = 0;
@@ -2124,7 +2249,7 @@ _slang_compile(const char *source, slang_code_object * object,
_slang_code_object_dtr(object);
_slang_code_object_ctr(object);
- success = compile_object(&id, source, object, type, infolog);
+ success = compile_object(&id, source, object, type, infolog, program);
if (id != 0)
grammar_destroy(id);
if (!success)
@@ -2132,10 +2257,20 @@ _slang_compile(const char *source, slang_code_object * object,
if (!_slang_build_export_data_table(&object->expdata, &object->unit.vars))
return GL_FALSE;
- if (!_slang_build_export_code_table
- (&object->expcode, &object->unit.funs, &object->unit))
+ if (!_slang_build_export_code_table(&object->expcode, &object->unit.funs,
+ &object->unit))
return GL_FALSE;
+#if NEW_SLANG
+ {
+ GET_CURRENT_CONTEXT(ctx);
+ slang_create_uniforms(&object->expdata, program);
+ _mesa_print_program(program);
+ _mesa_print_program_parameters(ctx, program);
+ }
+#endif
+
+
#if defined(USE_X86_ASM) || defined(SLANG_X86)
/* XXX: lookup the @main label */
if (!_slang_x86_codegen
@@ -2146,3 +2281,4 @@ _slang_compile(const char *source, slang_code_object * object,
return GL_TRUE;
}
+