diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/ast.h | 34 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 11 | ||||
-rw-r--r-- | mesalib/src/glsl/glcpp/glcpp-parse.y | 3 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_lexer.ll | 5 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.yy | 165 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.cpp | 3 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.h | 2 |
7 files changed, 188 insertions, 35 deletions
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h index b800c1108..6d81afc99 100644 --- a/mesalib/src/glsl/ast.h +++ b/mesalib/src/glsl/ast.h @@ -380,6 +380,15 @@ struct ast_type_qualifier { unsigned depth_less:1; unsigned depth_unchanged:1; /** \} */ + + /** \name Layout qualifiers for GL_ARB_uniform_buffer_object */ + /** \{ */ + unsigned std140:1; + unsigned shared:1; + unsigned packed:1; + unsigned column_major:1; + unsigned row_major:1; + /** \} */ } /** \brief Set of flags, accessed by name. */ q; @@ -421,15 +430,19 @@ struct ast_type_qualifier { const char *interpolation_string() const; }; +class ast_declarator_list; + class ast_struct_specifier : public ast_node { public: - ast_struct_specifier(const char *identifier, ast_node *declarator_list); + ast_struct_specifier(const char *identifier, + ast_declarator_list *declarator_list); virtual void print(void) const; virtual ir_rvalue *hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); const char *name; + /* List of ast_declarator_list * */ exec_list declarations; }; @@ -762,6 +775,25 @@ public: ast_function *prototype; ast_compound_statement *body; }; + +class ast_uniform_block : public ast_node { +public: + ast_uniform_block(ast_type_qualifier layout, + const char *block_name, + ast_declarator_list *member_list) + : layout(layout), block_name(block_name) + { + declarations.push_degenerate_list_at_head(&member_list->link); + } + + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + + ast_type_qualifier layout; + const char *block_name; + /** List of ast_declarator_list * */ + exec_list declarations; +}; /*@}*/ extern void diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 15aa88ea9..bbe8f0596 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -3989,6 +3989,17 @@ ast_struct_specifier::hir(exec_list *instructions, return NULL; } +ir_rvalue * +ast_uniform_block::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + /* The ast_uniform_block has a list of ast_declarator_lists. We + * need to turn those into ir_variables with an association + * with this uniform block. + */ + return NULL; +} + static void detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, exec_list *instructions) diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index cc4af1689..c0c1ca197 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1186,6 +1186,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_shader_bit_encoding) add_builtin_define(parser, "GL_ARB_shader_bit_encoding", 1); + + if (extensions->ARB_uniform_buffer_object) + add_builtin_define(parser, "GL_ARB_uniform_buffer_object", 1); } language_version = 110; diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll index 2028d7f47..24cda0c45 100644 --- a/mesalib/src/glsl/glsl_lexer.ll +++ b/mesalib/src/glsl/glsl_lexer.ll @@ -312,6 +312,7 @@ layout { || yyextra->AMD_conservative_depth_enable || yyextra->ARB_conservative_depth_enable || yyextra->ARB_explicit_attrib_location_enable + || yyextra->ARB_uniform_buffer_object_enable || yyextra->ARB_fragment_coord_conventions_enable) { return LAYOUT_TOK; } else { @@ -392,7 +393,7 @@ enum KEYWORD(110 || ES, 999, ENUM); typedef KEYWORD(110 || ES, 999, TYPEDEF); template KEYWORD(110 || ES, 999, TEMPLATE); this KEYWORD(110 || ES, 999, THIS); -packed KEYWORD(110 || ES, 999, PACKED_TOK); +packed KEYWORD(110 || ES, 140 || yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK); goto KEYWORD(110 || ES, 999, GOTO); switch KEYWORD(110 || ES, 130, SWITCH); default KEYWORD(110 || ES, 130, DEFAULT); @@ -468,7 +469,7 @@ image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW); imageBuffer KEYWORD(130, 999, IMAGEBUFFER); iimageBuffer KEYWORD(130, 999, IIMAGEBUFFER); uimageBuffer KEYWORD(130, 999, UIMAGEBUFFER); -row_major KEYWORD(130, 999, ROW_MAJOR); +row_major KEYWORD(130, 140 || yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR); /* Additional reserved words in GLSL 1.40 */ isampler2DRect KEYWORD(140, 140, ISAMPLER2DRECT); diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 5ca8740c4..337337591 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -155,6 +155,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %type <type_qualifier> interpolation_qualifier %type <type_qualifier> layout_qualifier %type <type_qualifier> layout_qualifier_id_list layout_qualifier_id +%type <type_qualifier> uniform_block_layout_qualifier %type <type_specifier> type_specifier %type <type_specifier> type_specifier_no_prec %type <type_specifier> type_specifier_nonarray @@ -213,11 +214,14 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %type <node> declaration %type <node> declaration_statement %type <node> jump_statement +%type <node> uniform_block %type <struct_specifier> struct_specifier -%type <node> struct_declaration_list +%type <declarator_list> struct_declaration_list %type <declarator_list> struct_declaration %type <declaration> struct_declarator %type <declaration> struct_declarator_list +%type <declarator_list> member_list +%type <declarator_list> member_declaration %type <node> selection_statement %type <selection_rest_statement> selection_rest_statement %type <node> switch_statement @@ -800,6 +804,10 @@ declaration: $3->is_precision_statement = true; $$ = $3; } + | uniform_block + { + $$ = $1; + } ; function_prototype: @@ -1100,13 +1108,8 @@ layout_qualifier_id_list: YYERROR; } - $$.flags.i = $1.flags.i | $3.flags.i; - - if ($1.flags.q.explicit_location) - $$.location = $1.location; - - if ($1.flags.q.explicit_index) - $$.index = $1.index; + $$ = $1; + $$.flags.i |= $3.flags.i; if ($3.flags.q.explicit_location) $$.location = $3.location; @@ -1119,21 +1122,17 @@ layout_qualifier_id_list: layout_qualifier_id: any_identifier { - bool got_one = false; - memset(& $$, 0, sizeof($$)); /* Layout qualifiers for ARB_fragment_coord_conventions. */ - if (!got_one && state->ARB_fragment_coord_conventions_enable) { + if (!$$.flags.i && state->ARB_fragment_coord_conventions_enable) { if (strcmp($1, "origin_upper_left") == 0) { - got_one = true; $$.flags.q.origin_upper_left = 1; } else if (strcmp($1, "pixel_center_integer") == 0) { - got_one = true; $$.flags.q.pixel_center_integer = 1; } - if (got_one && state->ARB_fragment_coord_conventions_warn) { + if ($$.flags.i && state->ARB_fragment_coord_conventions_warn) { _mesa_glsl_warning(& @1, state, "GL_ARB_fragment_coord_conventions layout " "identifier `%s' used\n", $1); @@ -1141,36 +1140,49 @@ layout_qualifier_id: } /* Layout qualifiers for AMD/ARB_conservative_depth. */ - if (!got_one && + if (!$$.flags.i && (state->AMD_conservative_depth_enable || state->ARB_conservative_depth_enable)) { if (strcmp($1, "depth_any") == 0) { - got_one = true; $$.flags.q.depth_any = 1; } else if (strcmp($1, "depth_greater") == 0) { - got_one = true; $$.flags.q.depth_greater = 1; } else if (strcmp($1, "depth_less") == 0) { - got_one = true; $$.flags.q.depth_less = 1; } else if (strcmp($1, "depth_unchanged") == 0) { - got_one = true; $$.flags.q.depth_unchanged = 1; } - if (got_one && state->AMD_conservative_depth_warn) { + if ($$.flags.i && state->AMD_conservative_depth_warn) { _mesa_glsl_warning(& @1, state, "GL_AMD_conservative_depth " "layout qualifier `%s' is used\n", $1); } - if (got_one && state->ARB_conservative_depth_warn) { + if ($$.flags.i && state->ARB_conservative_depth_warn) { _mesa_glsl_warning(& @1, state, "GL_ARB_conservative_depth " "layout qualifier `%s' is used\n", $1); } } - if (!got_one) { + /* See also uniform_block_layout_qualifier. */ + if (!$$.flags.i && state->ARB_uniform_buffer_object_enable) { + if (strcmp($1, "std140") == 0) { + $$.flags.q.std140 = 1; + } else if (strcmp($1, "shared") == 0) { + $$.flags.q.shared = 1; + } else if (strcmp($1, "column_major") == 0) { + $$.flags.q.column_major = 1; + } + + if ($$.flags.i && state->ARB_uniform_buffer_object_warn) { + _mesa_glsl_warning(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "layout qualifier `%s' is used\n", $1); + } + } + + if (!$$.flags.i) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'\n", $1); YYERROR; @@ -1178,8 +1190,6 @@ layout_qualifier_id: } | any_identifier '=' INTCONSTANT { - bool got_one = false; - memset(& $$, 0, sizeof($$)); if (state->ARB_explicit_attrib_location_enable) { @@ -1187,8 +1197,6 @@ layout_qualifier_id: * FINISHME: GLSL 1.30 (or later) are supported. */ if (strcmp("location", $1) == 0) { - got_one = true; - $$.flags.q.explicit_location = 1; if ($3 >= 0) { @@ -1201,8 +1209,6 @@ layout_qualifier_id: } if (strcmp("index", $1) == 0) { - got_one = true; - $$.flags.q.explicit_index = 1; if ($3 >= 0) { @@ -1218,7 +1224,7 @@ layout_qualifier_id: /* If the identifier didn't match any known layout identifiers, * emit an error. */ - if (!got_one) { + if (!$$.flags.i) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'\n", $1); YYERROR; @@ -1228,6 +1234,38 @@ layout_qualifier_id: "identifier `%s' used\n", $1); } } + | uniform_block_layout_qualifier + { + $$ = $1; + /* Layout qualifiers for ARB_uniform_buffer_object. */ + if (!state->ARB_uniform_buffer_object_enable) { + _mesa_glsl_error(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "layout qualifier `%s' is used\n", $1); + } else if (state->ARB_uniform_buffer_object_warn) { + _mesa_glsl_warning(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "layout qualifier `%s' is used\n", $1); + } + } + ; + +/* This is a separate language rule because we parse these as tokens + * (due to them being reserved keywords) instead of identifiers like + * most qualifiers. See the any_identifier path of + * layout_qualifier_id for the others. + */ +uniform_block_layout_qualifier: + ROW_MAJOR + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.row_major = 1; + } + | PACKED_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.packed = 1; + } ; interpolation_qualifier: @@ -1498,12 +1536,12 @@ struct_specifier: struct_declaration_list: struct_declaration { - $$ = (ast_node *) $1; + $$ = $1; $1->link.self_link(); } | struct_declaration_list struct_declaration { - $$ = (ast_node *) $1; + $$ = $1; $$->link.insert_before(& $2->link); } ; @@ -1881,3 +1919,68 @@ function_definition: state->symbols->pop_scope(); } ; + +/* layout_qualifieropt is packed into this rule */ +uniform_block: + UNIFORM NEW_IDENTIFIER '{' member_list '}' ';' + { + void *ctx = state; + ast_type_qualifier no_qual; + memset(&no_qual, 0, sizeof(no_qual)); + $$ = new(ctx) ast_uniform_block(no_qual, $2, $4); + } + | layout_qualifier UNIFORM NEW_IDENTIFIER '{' member_list '}' ';' + { + void *ctx = state; + $$ = new(ctx) ast_uniform_block($1, $3, $5); + } + ; + +member_list: + member_declaration + { + $$ = $1; + $1->link.self_link(); + } + | member_declaration member_list + { + $$ = $1; + $2->link.insert_before(& $$->link); + } + ; + +/* Specifying "uniform" inside of a uniform block is redundant. */ +uniformopt: + /* nothing */ + | UNIFORM + ; + +member_declaration: + layout_qualifier uniformopt type_specifier struct_declarator_list ';' + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->qualifier = $1; + type->qualifier.flags.q.uniform = true; + type->specifier = $3; + $$ = new(ctx) ast_declarator_list(type); + $$->set_location(yylloc); + + $$->declarations.push_degenerate_list_at_head(& $4->link); + } + | uniformopt type_specifier struct_declarator_list ';' + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->qualifier.flags.q.uniform = true; + type->specifier = $2; + $$ = new(ctx) ast_declarator_list(type); + $$->set_location(yylloc); + + $$->declarations.push_degenerate_list_at_head(& $3->link); + } + ; diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 02c398616..d9ee406cf 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -296,6 +296,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D), EXT(OES_EGL_image_external, true, false, true, false, true, OES_EGL_image_external), EXT(ARB_shader_bit_encoding, true, true, true, true, false, ARB_shader_bit_encoding), + EXT(ARB_uniform_buffer_object, true, false, true, true, false, ARB_uniform_buffer_object), }; #undef EXT @@ -1002,7 +1003,7 @@ ast_struct_specifier::print(void) const ast_struct_specifier::ast_struct_specifier(const char *identifier, - ast_node *declarator_list) + ast_declarator_list *declarator_list) { if (identifier == NULL) { static unsigned anon_count = 1; diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index b6dfbd07b..2564e5856 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -211,6 +211,8 @@ struct _mesa_glsl_parse_state { bool OES_EGL_image_external_warn; bool ARB_shader_bit_encoding_enable; bool ARB_shader_bit_encoding_warn; + bool ARB_uniform_buffer_object_enable; + bool ARB_uniform_buffer_object_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ |