diff options
author | Brian Paul <[email protected]> | 2008-11-07 15:51:10 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-11-07 15:51:10 -0700 |
commit | 448156f769ebf271a6a8c03c61588c3e6c6363f0 (patch) | |
tree | 360ac5045c88500d122a8d41586338037c308ce9 /src/mesa/shader/slang/slang_compile.c | |
parent | b632e5aa7f948ed5bbf7104682ec3ee463af4c0a (diff) |
mesa: add support for 'invariant' keyword for GLSL 1.20
Diffstat (limited to 'src/mesa/shader/slang/slang_compile.c')
-rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 141 |
1 files changed, 107 insertions, 34 deletions
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 294e46235c2..b826888120d 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -160,6 +160,8 @@ typedef struct slang_output_ctx_ struct gl_program *program; slang_var_table *vartable; GLuint default_precision[TYPE_SPECIFIER_COUNT]; + GLboolean allow_precision; + GLboolean allow_invariant; } slang_output_ctx; /* _slang_compile() */ @@ -479,6 +481,27 @@ parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st) } +/* invariant qualifer */ +#define TYPE_VARIANT 90 +#define TYPE_INVARIANT 91 + +static int +parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant) +{ + GLuint invariant = *C->I++; + switch (invariant) { + case TYPE_VARIANT: + *variant = SLANG_VARIANT; + return 1; + case TYPE_INVARIANT: + *variant = SLANG_INVARIANT; + return 1; + default: + return 0; + } +} + + /* type qualifier */ #define TYPE_QUALIFIER_NONE 0 #define TYPE_QUALIFIER_CONST 1 @@ -491,7 +514,8 @@ parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st) static int parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual) { - switch (*C->I++) { + GLuint qualifier = *C->I++; + switch (qualifier) { case TYPE_QUALIFIER_NONE: *qual = SLANG_QUAL_NONE; break; @@ -691,48 +715,80 @@ parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, return 1; } + #define PRECISION_DEFAULT 0 #define PRECISION_LOW 1 #define PRECISION_MEDIUM 2 #define PRECISION_HIGH 3 static int +parse_type_precision(slang_parse_ctx *C, + slang_type_precision *precision) +{ + GLint prec = *C->I++; + switch (prec) { + case PRECISION_DEFAULT: + *precision = SLANG_PREC_DEFAULT; + return 1; + case PRECISION_LOW: + *precision = SLANG_PREC_LOW; + return 1; + case PRECISION_MEDIUM: + *precision = SLANG_PREC_MEDIUM; + return 1; + case PRECISION_HIGH: + *precision = SLANG_PREC_HIGH; + return 1; + default: + return 0; + } +} + +static int parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, slang_fully_specified_type * type) { - GLuint precision; - + if (!parse_type_variant(C, &type->variant)) + return 0; + if (!parse_type_qualifier(C, &type->qualifier)) return 0; - precision = *C->I++; + + if (!parse_type_precision(C, &type->precision)) + return 0; + if (!parse_type_specifier(C, O, &type->specifier)) return 0; - switch (precision) { - case PRECISION_DEFAULT: - assert(type->specifier.type < TYPE_SPECIFIER_COUNT); - if (type->specifier.type < TYPE_SPECIFIER_COUNT) - type->precision = O->default_precision[type->specifier.type]; - break; - case PRECISION_LOW: - type->precision = SLANG_PREC_LOW; - break; - case PRECISION_MEDIUM: - type->precision = SLANG_PREC_MEDIUM; - break; - case PRECISION_HIGH: - type->precision = SLANG_PREC_HIGH; - break; - default: + if (!O->allow_invariant && type->variant == SLANG_INVARIANT) { + slang_info_log_error(C->L, + "'invariant' keyword not allowed (perhaps set #version 120)"); return 0; } -#if !FEATURE_es2_glsl - if (precision != PRECISION_DEFAULT) { - slang_info_log_error(C->L, "precision qualifiers not allowed"); + /* need this? + if (type->qualifier != SLANG_QUAL_VARYING && + type->variant == SLANG_INVARIANT) { + slang_info_log_error(C->L, + "invariant qualifer only allowed for varying vars"); return 0; } -#endif + */ + + if (O->allow_precision) { + if (type->precision == SLANG_PREC_DEFAULT) { + assert(type->specifier.type < TYPE_SPECIFIER_COUNT); + /* use the default precision for this datatype */ + type->precision = O->default_precision[type->specifier.type]; + } + } + else { + /* only default is allowed */ + if (type->precision != SLANG_PREC_DEFAULT) { + slang_info_log_error(C->L, "precision qualifiers not allowed"); + return 0; + } + } return 1; } @@ -1484,10 +1540,13 @@ static int parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, slang_function * func) { + GLuint functype; /* parse function type and name */ if (!parse_fully_specified_type(C, O, &func->header.type)) return 0; - switch (*C->I++) { + + functype = *C->I++; + switch (functype) { case FUNCTION_ORDINARY: func->kind = SLANG_FUNC_ORDINARY; func->header.a_name = parse_identifier(C); @@ -1927,9 +1986,13 @@ parse_declaration(slang_parse_ctx * C, slang_output_ctx * O) static int parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O) { -#if FEATURE_es2_glsl int precision, type; + if (!O->allow_precision) { + slang_info_log_error(C->L, "syntax error at \"precision\""); + return 0; + } + precision = *C->I++; switch (precision) { case PRECISION_LOW: @@ -1967,10 +2030,6 @@ parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O) O->default_precision[type] = precision; return 1; -#else - slang_info_log_error(C->L, "syntax error at \"precision\""); - return 0; -#endif } @@ -1989,7 +2048,7 @@ init_default_precision(slang_output_ctx *O, slang_unit_type type) 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; @@ -1997,14 +2056,13 @@ init_default_precision(slang_output_ctx *O, slang_unit_type type) else { O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM; } -#endif } static int parse_invariant(slang_parse_ctx * C, slang_output_ctx * O) { - if (C->version >= 120 || FEATURE_es2_glsl) { + if (O->allow_invariant) { slang_atom *a = parse_identifier(C); /* XXX not doing anything with this var yet */ /*printf("ID: %s\n", (char*) a);*/ @@ -2046,7 +2104,6 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, } /* setup output context */ - init_default_precision(&o, unit->type); o.funs = &unit->funs; o.structs = &unit->structs; o.vars = &unit->vars; @@ -2055,6 +2112,22 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, o.vartable = _slang_new_var_table(maxRegs); _slang_push_var_table(o.vartable); + /* allow 'invariant' keyword? */ +#if FEATURE_es2_glsl + o.allow_invariant = GL_TRUE; +#else + o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE; +#endif + + /* allow 'lowp/mediump/highp' keywords? */ +#if FEATURE_es2_glsl + o.allow_precision = GL_TRUE; +#else + o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE; +#endif + init_default_precision(&o, unit->type); + + /* parse individual functions and declarations */ while (*C->I != EXTERNAL_NULL) { switch (*C->I++) { |