Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / shader / slang / slang_compile.c
index 19fec53877f40a0d535bc56546e3b9119804895e..19b8e5172598eca7fd6d5f53bbbe12e9b1371ff6 100644 (file)
 #include "shader/prog_optimize.h"
 #include "shader/prog_print.h"
 #include "shader/prog_parameter.h"
-#include "shader/grammar/grammar_mesa.h"
-#include "../../glsl/pp/sl_pp_context.h"
-#include "../../glsl/pp/sl_pp_purify.h"
-#include "../../glsl/pp/sl_pp_version.h"
-#include "../../glsl/pp/sl_pp_process.h"
+#include "../../glsl/pp/sl_pp_public.h"
+#include "../../glsl/cl/sl_cl_parse.h"
 #include "slang_codegen.h"
 #include "slang_compile.h"
 #include "slang_storage.h"
@@ -131,7 +128,7 @@ _slang_code_object_dtr(slang_code_object * self)
 
 typedef struct slang_parse_ctx_
 {
-   const byte *I;
+   const unsigned char *I;
    slang_info_log *L;
    int parsing_builtin;
    GLboolean global_scope;   /**< Is object being declared a global? */
@@ -199,7 +196,7 @@ parse_general_number(slang_parse_ctx *ctx, float *number)
 
    if (*ctx->I == '0') {
       int value = 0;
-      const byte *pi;
+      const unsigned char *pi;
 
       if (ctx->I[1] == 'x' || ctx->I[1] == 'X') {
          ctx->I += 2;
@@ -2543,7 +2540,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
 }
 
 static GLboolean
-compile_binary(const byte * prod, slang_code_unit * unit,
+compile_binary(const unsigned char * prod, slang_code_unit * unit,
                GLuint version,
                slang_unit_type type, slang_info_log * infolog,
                slang_code_unit * builtin, slang_code_unit * downlink,
@@ -2576,127 +2573,56 @@ compile_binary(const byte * prod, slang_code_unit * unit,
 }
 
 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,
+compile_with_grammar(const char *source,
+                     slang_code_unit *unit,
+                     slang_unit_type type,
+                     slang_info_log *infolog,
+                     slang_code_unit *builtin,
                      struct gl_shader *shader,
                      const struct gl_extensions *extensions,
-                     struct gl_sl_pragmas *pragmas)
+                     struct gl_sl_pragmas *pragmas,
+                     unsigned int shader_type,
+                     unsigned int parsing_builtin)
 {
-   struct sl_pp_context context;
-   struct sl_pp_token_info *tokens;
-   byte *prod;
+   struct sl_pp_purify_options options;
+   struct sl_pp_context *context;
+   unsigned char *prod;
    GLuint size;
    unsigned int version;
    unsigned int maxVersion;
    int result;
-   struct sl_pp_purify_options options;
-   char *outbuf;
-   struct sl_pp_token_info *intokens;
-   unsigned int tokens_eaten;
+   char errmsg[200] = "";
+   unsigned int errline = 0;
 
    memset(&options, 0, sizeof(options));
-   if (sl_pp_purify(source, &options, &outbuf)) {
-      slang_info_log_error(infolog, "unable to preprocess the source");
-      return GL_FALSE;
-   }
 
-   if (sl_pp_context_init(&context)) {
+   context = sl_pp_context_create(source, &options);
+   if (!context) {
       slang_info_log_error(infolog, "out of memory");
-      free(outbuf);
       return GL_FALSE;
    }
 
-   if (sl_pp_tokenise(&context, outbuf, &intokens)) {
-      slang_info_log_error(infolog, "%s", context.error_msg);
-      sl_pp_context_destroy(&context);
-      free(outbuf);
+   if (sl_pp_version(context, &version)) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
       return GL_FALSE;
    }
 
-   free(outbuf);
-
-   if (sl_pp_version(&context, intokens, &version, &tokens_eaten)) {
-      slang_info_log_error(infolog, "%s", context.error_msg);
-      sl_pp_context_destroy(&context);
-      free(intokens);
+   if (sl_pp_context_add_extension(context, "ARB_draw_buffers", "GL_ARB_draw_buffers") ||
+       sl_pp_context_add_extension(context, "ARB_texture_rectangle", "GL_ARB_texture_rectangle")) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
       return GL_FALSE;
    }
 
-   if (sl_pp_process(&context, &intokens[tokens_eaten], &tokens)) {
-      slang_info_log_error(infolog, "%s", context.error_msg);
-      sl_pp_context_destroy(&context);
-      free(intokens);
+#if FEATURE_es2_glsl
+   if (sl_pp_context_add_predefined(context, "GL_ES", "1") ||
+       sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
       return GL_FALSE;
    }
-
-   free(intokens);
-
-   /* For the time being we care about only a handful of tokens. */
-   {
-      const struct sl_pp_token_info *src = tokens;
-      struct sl_pp_token_info *dst = tokens;
-
-      while (src->token != SL_PP_EOF) {
-         switch (src->token) {
-         case SL_PP_COMMA:
-         case SL_PP_SEMICOLON:
-         case SL_PP_LBRACE:
-         case SL_PP_RBRACE:
-         case SL_PP_LPAREN:
-         case SL_PP_RPAREN:
-         case SL_PP_LBRACKET:
-         case SL_PP_RBRACKET:
-         case SL_PP_DOT:
-         case SL_PP_INCREMENT:
-         case SL_PP_ADDASSIGN:
-         case SL_PP_PLUS:
-         case SL_PP_DECREMENT:
-         case SL_PP_SUBASSIGN:
-         case SL_PP_MINUS:
-         case SL_PP_BITNOT:
-         case SL_PP_NOTEQUAL:
-         case SL_PP_NOT:
-         case SL_PP_MULASSIGN:
-         case SL_PP_STAR:
-         case SL_PP_DIVASSIGN:
-         case SL_PP_SLASH:
-         case SL_PP_MODASSIGN:
-         case SL_PP_MODULO:
-         case SL_PP_LSHIFTASSIGN:
-         case SL_PP_LSHIFT:
-         case SL_PP_LESSEQUAL:
-         case SL_PP_LESS:
-         case SL_PP_RSHIFTASSIGN:
-         case SL_PP_RSHIFT:
-         case SL_PP_GREATEREQUAL:
-         case SL_PP_GREATER:
-         case SL_PP_EQUAL:
-         case SL_PP_ASSIGN:
-         case SL_PP_AND:
-         case SL_PP_BITANDASSIGN:
-         case SL_PP_BITAND:
-         case SL_PP_XOR:
-         case SL_PP_BITXORASSIGN:
-         case SL_PP_BITXOR:
-         case SL_PP_OR:
-         case SL_PP_BITORASSIGN:
-         case SL_PP_BITOR:
-         case SL_PP_QUESTION:
-         case SL_PP_COLON:
-         case SL_PP_IDENTIFIER:
-         case SL_PP_NUMBER:
-            *dst++ = *src++;
-            break;
-
-         default:
-            src++;
-         }
-      }
-
-      /* The end of stream token. */
-      *dst = *src;
-   }
+#endif
 
 #if FEATURE_ARB_shading_language_120
    maxVersion = 120;
@@ -2711,23 +2637,25 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
       slang_info_log_error(infolog,
                            "language version %.2f is not supported.",
                            version * 0.01);
-      sl_pp_context_destroy(&context);
-      free(tokens);
+      sl_pp_context_destroy(context);
       return GL_FALSE;
    }
 
    /* Finally check the syntax and generate its binary representation. */
-   result = grammar_fast_check(id, &context, tokens, &prod, &size, 65536);
+   result = sl_cl_compile(context,
+                          shader_type,
+                          parsing_builtin,
+                          &prod,
+                          &size,
+                          errmsg,
+                          sizeof(errmsg));
 
-   sl_pp_context_destroy(&context);
-   free(tokens);
+   sl_pp_context_destroy(context);
 
-   if (!result) {
-      char buf[1024];
-      GLint pos;
+   if (result) {
+      /*GLint pos;*/
 
-      grammar_get_last_error((byte *) (buf), sizeof(buf), &pos);
-      slang_info_log_error(infolog, buf);
+      slang_info_log_error(infolog, errmsg);
       /* syntax error (possibly in library code) */
 #if 0
       {
@@ -2746,71 +2674,60 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
    if (!compile_binary(prod, unit, version, type, infolog, builtin,
                        &builtin[SLANG_BUILTIN_TOTAL - 1],
                        shader)) {
-      grammar_alloc_free(prod);
+      free(prod);
       return GL_FALSE;
    }
-   grammar_alloc_free(prod);
+   free(prod);
    return GL_TRUE;
 }
 
-LONGSTRING static const char *slang_shader_syn =
-#include "library/slang_shader_syn.h"
-   ;
-
-static const byte slang_core_gc[] = {
+static const unsigned char slang_core_gc[] = {
 #include "library/slang_core_gc.h"
 };
 
-static const byte slang_120_core_gc[] = {
+static const unsigned char slang_120_core_gc[] = {
 #include "library/slang_120_core_gc.h"
 };
 
-static const byte slang_120_fragment_gc[] = {
+static const unsigned char slang_120_fragment_gc[] = {
 #include "library/slang_builtin_120_fragment_gc.h"
 };
 
-static const byte slang_common_builtin_gc[] = {
+static const unsigned char slang_common_builtin_gc[] = {
 #include "library/slang_common_builtin_gc.h"
 };
 
-static const byte slang_fragment_builtin_gc[] = {
+static const unsigned char slang_fragment_builtin_gc[] = {
 #include "library/slang_fragment_builtin_gc.h"
 };
 
-static const byte slang_vertex_builtin_gc[] = {
+static const unsigned char slang_vertex_builtin_gc[] = {
 #include "library/slang_vertex_builtin_gc.h"
 };
 
 static GLboolean
-compile_object(grammar * id, const char *source, slang_code_object * object,
-               slang_unit_type type, slang_info_log * infolog,
+compile_object(const char *source,
+               slang_code_object *object,
+               slang_unit_type type,
+               slang_info_log *infolog,
                struct gl_shader *shader,
                const struct gl_extensions *extensions,
                struct gl_sl_pragmas *pragmas)
 {
    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;
-   }
+   unsigned int shader_type;
+   unsigned int parsing_builtin;
 
    /* 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);
+   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) {
+      shader_type = 1;
+   } else {
+      shader_type = 2;
+   }
 
    /* enable language extensions */
-   grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
+   parsing_builtin = 1;
 
    /* if parsing user-specified shader, load built-in library */
    if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER) {
@@ -2876,16 +2793,24 @@ compile_object(grammar * id, const char *source, slang_code_object * object,
 
       /* disable language extensions */
 #if NEW_SLANG /* allow-built-ins */
-      grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
+      parsing_builtin = 1;
 #else
-      grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0);
+      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, shader, extensions, pragmas);
+   return compile_with_grammar(source,
+                               &object->unit,
+                               type,
+                               infolog,
+                               builtins,
+                               shader,
+                               extensions,
+                               pragmas,
+                               shader_type,
+                               parsing_builtin);
 }
 
 
@@ -2894,9 +2819,6 @@ compile_shader(GLcontext *ctx, slang_code_object * object,
                slang_unit_type type, slang_info_log * infolog,
                struct gl_shader *shader)
 {
-   GLboolean success;
-   grammar id = 0;
-
 #if 0 /* for debug */
    _mesa_printf("********* COMPILE SHADER ***********\n");
    _mesa_printf("%s\n", shader->Source);
@@ -2908,14 +2830,13 @@ compile_shader(GLcontext *ctx, slang_code_object * object,
    _slang_code_object_dtr(object);
    _slang_code_object_ctr(object);
 
-   success = compile_object(&id, shader->Source, object, type, infolog, shader,
-                            &ctx->Extensions, &shader->Pragmas);
-   if (id != 0)
-      grammar_destroy(id);
-   if (!success)
-      return GL_FALSE;
-
-   return GL_TRUE;
+   return compile_object(shader->Source,
+                         object,
+                         type,
+                         infolog,
+                         shader,
+                         &ctx->Extensions,
+                         &shader->Pragmas);
 }
 
 
@@ -2927,6 +2848,7 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
    slang_info_log info_log;
    slang_code_object obj;
    slang_unit_type type;
+   GLenum progTarget;
 
    if (shader->Type == GL_VERTEX_SHADER) {
       type = SLANG_UNIT_VERTEX_SHADER;
@@ -2943,17 +2865,18 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
 
    shader->Main = GL_FALSE;
 
-   if (!shader->Program) {
-      GLenum progTarget;
-      if (shader->Type == GL_VERTEX_SHADER)
-         progTarget = GL_VERTEX_PROGRAM_ARB;
-      else
-         progTarget = GL_FRAGMENT_PROGRAM_ARB;
-      shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
-      shader->Program->Parameters = _mesa_new_parameter_list();
-      shader->Program->Varying = _mesa_new_parameter_list();
-      shader->Program->Attributes = _mesa_new_parameter_list();
-   }
+   /* free the shader's old instructions, etc */
+   _mesa_reference_program(ctx, &shader->Program, NULL);
+
+   /* allocate new GPU program, parameter lists, etc. */
+   if (shader->Type == GL_VERTEX_SHADER)
+      progTarget = GL_VERTEX_PROGRAM_ARB;
+   else
+      progTarget = GL_FRAGMENT_PROGRAM_ARB;
+   shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
+   shader->Program->Parameters = _mesa_new_parameter_list();
+   shader->Program->Varying = _mesa_new_parameter_list();
+   shader->Program->Attributes = _mesa_new_parameter_list();
 
    slang_info_log_construct(&info_log);
    _slang_code_object_ctr(&obj);
@@ -3003,6 +2926,16 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
           (ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
          _mesa_optimize_program(ctx, shader->Program);
       }
+      if ((ctx->Shader.Flags & GLSL_NOP_VERT) &&
+          shader->Program->Target == GL_VERTEX_PROGRAM_ARB) {
+         _mesa_nop_vertex_program(ctx,
+                                  (struct gl_vertex_program *) shader->Program);
+      }
+      if ((ctx->Shader.Flags & GLSL_NOP_FRAG) &&
+          shader->Program->Target == GL_FRAGMENT_PROGRAM_ARB) {
+         _mesa_nop_fragment_program(ctx,
+                                (struct gl_fragment_program *) shader->Program);
+      }
    }
 
    if (ctx->Shader.Flags & GLSL_LOG) {