glsl: Parse `demote` statement
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Fri, 20 Sep 2019 16:34:19 +0000 (09:34 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 30 Sep 2019 19:44:30 +0000 (12:44 -0700)
When the EXT_demote_to_helper_invocation extension is enabled,
`demote` is treated as a keyword, and produces an ir_demote.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/compiler/glsl/ast.h
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/glsl_lexer.ll
src/compiler/glsl/glsl_parser.yy
src/compiler/glsl/glsl_parser_extras.cpp

index 90a35654aeb158a810456ce8f02b38f27f2f6945..f07a14bce8f07789e2346b0c122331d2c92a5d98 100644 (file)
@@ -1213,6 +1213,16 @@ public:
 };
 
 
+class ast_demote_statement : public ast_node {
+public:
+   ast_demote_statement(void) {}
+   virtual void print(void) const;
+
+   virtual ir_rvalue *hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state);
+};
+
+
 class ast_function_definition : public ast_node {
 public:
    ast_function_definition() : prototype(NULL), body(NULL)
index 194d3099060d4e79b0d80b8b6c3ae239af29f6e9..214412bc30a73954d2f20b40f40b9a9010510b81 100644 (file)
@@ -6464,6 +6464,25 @@ ast_jump_statement::hir(exec_list *instructions,
 }
 
 
+ir_rvalue *
+ast_demote_statement::hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state)
+{
+   void *ctx = state;
+
+   if (state->stage != MESA_SHADER_FRAGMENT) {
+      YYLTYPE loc = this->get_location();
+
+      _mesa_glsl_error(& loc, state,
+                       "`demote' may only appear in a fragment shader");
+   }
+
+   instructions->push_tail(new(ctx) ir_demote);
+
+   return NULL;
+}
+
+
 ir_rvalue *
 ast_selection_statement::hir(exec_list *instructions,
                              struct _mesa_glsl_parse_state *state)
index b17f9c08f69ec06408c824410c5f31fd91e9062a..43bd2b23ec4c82efc65f2a96ad6d11f9145c6aef 100644 (file)
@@ -356,6 +356,7 @@ for         return FOR;
 if             return IF;
 discard                return DISCARD;
 return         return RETURN;
+demote         KEYWORD_WITH_ALT(0, 0, 0, 0, yyextra->EXT_demote_to_helper_invocation_enable, DEMOTE);
 
 bvec2          { yylval->type = glsl_type::bvec2_type; return BASIC_TYPE_TOK; }
 bvec3          { yylval->type = glsl_type::bvec3_type; return BASIC_TYPE_TOK; }
index d2d87166b7b381dfc858a8dc4a9b1134f7e979ba..edf421d9053ecbdd22081581aab119b5474d1b69 100644 (file)
@@ -139,7 +139,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
 
 %token ATTRIBUTE CONST_TOK
 %token <type> BASIC_TYPE_TOK
-%token BREAK BUFFER CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
+%token BREAK BUFFER CONTINUE DO ELSE FOR IF DEMOTE DISCARD RETURN SWITCH CASE DEFAULT
 %token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING SAMPLE
 %token NOPERSPECTIVE FLAT SMOOTH
 %token IMAGE1DSHADOW IMAGE2DSHADOW IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW
@@ -256,6 +256,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
 %type <node> declaration
 %type <node> declaration_statement
 %type <node> jump_statement
+%type <node> demote_statement
 %type <node> interface_block
 %type <interface_block> basic_interface_block
 %type <struct_specifier> struct_specifier
@@ -2510,6 +2511,7 @@ simple_statement:
    | switch_statement
    | iteration_statement
    | jump_statement
+   | demote_statement
    ;
 
 compound_statement:
@@ -2808,6 +2810,15 @@ jump_statement:
    }
    ;
 
+demote_statement:
+   DEMOTE ';'
+   {
+      void *ctx = state->linalloc;
+      $$ = new(ctx) ast_demote_statement();
+      $$->set_location(@1);
+   }
+   ;
+
 external_declaration:
    function_definition      { $$ = $1; }
    | declaration            { $$ = $1; }
index d16f96fb315a9138b95d64bbce9484ebfeab0fdb..3d1a31e1ff169e9cab82b431427ce55a6f92afd6 100644 (file)
@@ -1512,6 +1512,13 @@ ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
 }
 
 
+void
+ast_demote_statement::print(void) const
+{
+   printf("demote; ");
+}
+
+
 void
 ast_selection_statement::print(void) const
 {