📄 slang_compile.c
字号:
if (found_func == NULL) { /* New function, add it to the function list */ O->funs->functions = (slang_function *) _slang_realloc(O->funs->functions, O->funs->num_functions * sizeof(slang_function), (O->funs->num_functions + 1) * sizeof(slang_function)); if (O->funs->functions == NULL) { slang_info_log_memory(C->L); slang_function_destruct(&parsed_func); return GL_FALSE; } O->funs->functions[O->funs->num_functions] = parsed_func; O->funs->num_functions++; /* return the newly parsed function */ *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) { slang_info_log_error(C->L, "%s: function already has a body.", slang_atom_pool_id(C->atoms, parsed_func.header. a_name)); slang_function_destruct(&parsed_func); return GL_FALSE; } /* destroy the existing function declaration and replace it * with the new one, remember to save the fixup table */ parsed_func.fixups = found_func->fixups; slang_fixup_table_init(&found_func->fixups); slang_function_destruct(found_func); *found_func = parsed_func; } else { /* another declaration of the same function prototype - ignore it */ slang_function_destruct(&parsed_func); } /* return the found function */ *parsed_func_ret = found_func; } return GL_TRUE;}/* declaration */#define DECLARATION_FUNCTION_PROTOTYPE 1#define DECLARATION_INIT_DECLARATOR_LIST 2static intparse_declaration(slang_parse_ctx * C, slang_output_ctx * O){ switch (*C->I++) { case DECLARATION_INIT_DECLARATOR_LIST: if (!parse_init_declarator_list(C, O)) return 0; break; case DECLARATION_FUNCTION_PROTOTYPE: { slang_function *dummy_func; if (!parse_function(C, O, 0, &dummy_func)) return 0; } break; default: return 0; } return 1;}static intparse_default_precision(slang_parse_ctx * C, slang_output_ctx * O){#if FEATURE_es2_glsl int precision, type; precision = *C->I++; switch (precision) { case PRECISION_LOW: case PRECISION_MEDIUM: case PRECISION_HIGH: /* OK */ break; default: _mesa_problem(NULL, "unexpected precision %d at %s:%d\n", precision, __FILE__, __LINE__); return 0; } type = *C->I++; switch (type) { case TYPE_SPECIFIER_FLOAT: case TYPE_SPECIFIER_INT: case TYPE_SPECIFIER_SAMPLER1D: case TYPE_SPECIFIER_SAMPLER2D: case TYPE_SPECIFIER_SAMPLER3D: case TYPE_SPECIFIER_SAMPLERCUBE: case TYPE_SPECIFIER_SAMPLER1DSHADOW: case TYPE_SPECIFIER_SAMPLER2DSHADOW: case TYPE_SPECIFIER_SAMPLER2DRECT: case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW: /* OK */ break; default: _mesa_problem(NULL, "unexpected type %d at %s:%d\n", type, __FILE__, __LINE__); return 0; } assert(type < TYPE_SPECIFIER_COUNT); O->default_precision[type] = precision; return 1;#else slang_info_log_error(C->L, "syntax error at \"precision\""); return 0;#endif}/** * Initialize the default precision for all types. * XXX this info isn't used yet. */static voidinit_default_precision(slang_output_ctx *O, slang_unit_type type){ GLuint i; for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) {#if FEATURE_es2_glsl O->default_precision[i] = PRECISION_LOW;#else O->default_precision[i] = PRECISION_HIGH;#endif }#if FEATURE_es2_glsl if (type == SLANG_UNIT_VERTEX_SHADER) { O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH; O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH; } else { O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM; }#endif}static intparse_invariant(slang_parse_ctx * C, slang_output_ctx * O){ if (C->version >= 120 || FEATURE_es2_glsl) { slang_atom *a = parse_identifier(C); /* XXX not doing anything with this var yet */ /*printf("ID: %s\n", (char*) a);*/ return a ? 1 : 0; } else { slang_info_log_error(C->L, "syntax error at \"invariant\""); return 0; }} /* external declaration or default precision specifier */#define EXTERNAL_NULL 0#define EXTERNAL_FUNCTION_DEFINITION 1#define EXTERNAL_DECLARATION 2#define DEFAULT_PRECISION 3#define INVARIANT_STMT 4static GLbooleanparse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, struct gl_shader *shader){ GET_CURRENT_CONTEXT(ctx); slang_output_ctx o; GLboolean success; GLuint maxRegs; slang_function *mainFunc = NULL; if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN || unit->type == SLANG_UNIT_FRAGMENT_SHADER) { maxRegs = ctx->Const.FragmentProgram.MaxTemps; } else { assert(unit->type == SLANG_UNIT_VERTEX_BUILTIN || unit->type == SLANG_UNIT_VERTEX_SHADER); maxRegs = ctx->Const.VertexProgram.MaxTemps; } /* setup output context */ init_default_precision(&o, unit->type); o.funs = &unit->funs; o.structs = &unit->structs; o.vars = &unit->vars; o.global_pool = &unit->object->varpool; o.program = shader ? shader->Program : NULL; o.vartable = _slang_new_var_table(maxRegs); _slang_push_var_table(o.vartable); /* parse individual functions and declarations */ while (*C->I != EXTERNAL_NULL) { switch (*C->I++) { case EXTERNAL_FUNCTION_DEFINITION: { slang_function *func; success = parse_function(C, &o, 1, &func); if (success && _mesa_strcmp((char *) func->header.a_name, "main") == 0) { /* found main() */ mainFunc = func; } } break; case EXTERNAL_DECLARATION: success = parse_declaration(C, &o); break; case DEFAULT_PRECISION: success = parse_default_precision(C, &o); break; case INVARIANT_STMT: success = parse_invariant(C, &o); break; default: success = GL_FALSE; } if (!success) { /* xxx free codegen */ _slang_pop_var_table(o.vartable); return GL_FALSE; } } C->I++; if (mainFunc) { /* assemble (generate code) for main() */ slang_assemble_ctx A; A.atoms = C->atoms; A.space.funcs = o.funs; A.space.structs = o.structs; A.space.vars = o.vars; A.program = o.program; A.vartable = o.vartable; A.log = C->L; /* main() takes no parameters */ if (mainFunc->param_count > 0) { slang_info_log_error(A.log, "main() takes no arguments"); return GL_FALSE; } _slang_codegen_function(&A, mainFunc); shader->Main = GL_TRUE; /* this shader defines main() */ } _slang_pop_var_table(o.vartable); _slang_delete_var_table(o.vartable); return GL_TRUE;}static GLbooleancompile_binary(const byte * prod, slang_code_unit * unit, GLuint version, slang_unit_type type, slang_info_log * infolog, slang_code_unit * builtin, slang_code_unit * downlink, struct gl_shader *shader){ slang_parse_ctx C; unit->type = type; /* setup parse context */ C.I = prod; C.L = infolog; C.parsing_builtin = (builtin == NULL); C.global_scope = GL_TRUE; C.atoms = &unit->object->atompool; C.type = type; C.version = version; if (!check_revision(&C)) return GL_FALSE; if (downlink != NULL) { unit->vars.outer_scope = &downlink->vars; unit->funs.outer_scope = &downlink->funs; unit->structs.outer_scope = &downlink->structs; } /* parse translation unit */ return parse_code_unit(&C, unit, shader);}static GLbooleancompile_with_grammar(grammar id, const char *source, slang_code_unit * unit, slang_unit_type type, slang_info_log * infolog, slang_code_unit * builtin, struct gl_shader *shader){ byte *prod; GLuint size, start, version; slang_string preprocessed; GLuint maxVersion;#if FEATURE_ARB_shading_language_120 maxVersion = 120;#elif FEATURE_es2_glsl maxVersion = 100;#else maxVersion = 110;#endif /* First retrieve the version number. */ if (!_slang_preprocess_version(source, &version, &start, infolog)) return GL_FALSE; if (version > maxVersion) { slang_info_log_error(infolog, "language version %.2f is not supported.", version * 0.01); return GL_FALSE; } /* Now preprocess the source string. */ slang_string_init(&preprocessed); if (!_slang_preprocess_directives(&preprocessed, &source[start], infolog)) { slang_string_free(&preprocessed); slang_info_log_error(infolog, "failed to preprocess the source."); return GL_FALSE; } /* Finally check the syntax and generate its binary representation. */ if (!grammar_fast_check(id, (const byte *) (slang_string_cstr(&preprocessed)), &prod, &size, 65536)) { char buf[1024]; GLint pos; slang_string_free(&preprocessed); grammar_get_last_error((byte *) (buf), sizeof(buf), &pos); slang_info_log_error(infolog, buf); /* syntax error (possibly in library code) */#if 0 { int line, col; char *s; s = (char *) _mesa_find_line_column((const GLubyte *) source, (const GLubyte *) source + pos, &line, &col); printf("Error on line %d, col %d: %s\n", line, col, s); }#endif return GL_FALSE; } slang_string_free(&preprocessed); /* Syntax is okay - translate it to internal representation. */ if (!compile_binary(prod, unit, version, type, infolog, builtin, &builtin[SLANG_BUILTIN_TOTAL - 1], shader)) { grammar_alloc_free(prod); return GL_FALSE; } grammar_alloc_free(prod); return GL_TRUE;}LONGSTRING static const char *slang_shader_syn =#include "library/slang_shader_syn.h" ;static const byte slang_core_gc[] = {#include "library/slang_core_gc.h"};static const byte slang_120_core_gc[] = {#include "library/slang_120_core_gc.h"};static const byte slang_120_fragment_gc[] = {#include "library/slang_builtin_120_fragment_gc.h"};static const byte slang_common_builtin_gc[] = {#include "library/slang_common_builtin_gc.h"};static const byte slang_fragment_builtin_gc[] = {#include "library/slang_fragment_builtin_gc.h"};static const byte slang_vertex_builtin_gc[] = {#include "library/slang_vertex_builtin_gc.h"};static GLbooleancompile_object(grammar * id, const char *source, slang_code_object * object, slang_unit_type type, slang_info_log * infolog, struct gl_shader *shader){ slang_code_unit *builtins = NULL; GLuint base_version = 110; /* load GLSL grammar */ *id = grammar_load_from_text((const byte *) (slang_shader_syn)); if (*id == 0) { byte buf[1024]; int pos; grammar_get_last_error(buf, 1024, &pos); slang_info_log_error(infolog, (const char *) (buf)); return GL_FALSE; } /* set shader type - the syntax is slightly different for different shaders */ if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) grammar_set_reg8(*id, (const byte *) "shader_type", 1); else grammar_set_reg8(*id, (const byte *) "shader_type", 2); /* enable language extensions */ grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1); /* 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], base_version, SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, NULL, NULL)) return GL_FALSE;#if FEATURE_ARB_shading_language_120 if (!compile_binary(slang_120_core_gc, &object->builtin[SLANG_BUILTIN_120_CORE], 120, SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL)) return GL_FALSE;#endif /* compile common fu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -