mesa: fix empty program log length
[mesa.git] / src / mesa / main / shaderapi.c
index 1af1c3f57948caf7c520de0fd6dd3da6de9d7518..cedcfa3a04cb9a9b696d73d276b6aa6bdfd1de5d 100644 (file)
 #include "util/hash_table.h"
 #include "util/mesa-sha1.h"
 
-#ifdef _MSC_VER
-#include <stdlib.h>
-#define PATH_MAX _MAX_PATH
-#endif
-
 /**
  * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
  */
@@ -112,13 +107,6 @@ _mesa_get_shader_capture_path(void)
    if (!read_env_var) {
       path = getenv("MESA_SHADER_CAPTURE_PATH");
       read_env_var = true;
-      if (path &&
-          strlen(path) > PATH_MAX - strlen("/fp-4294967295.shader_test")) {
-         GET_CURRENT_CONTEXT(ctx);
-         _mesa_warning(ctx, "MESA_SHADER_CAPTURE_PATH too long; ignoring "
-                            "request to capture shaders");
-         path = NULL;
-      }
    }
 
    return path;
@@ -654,7 +642,8 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
       *params = shProg->Validated;
       return;
    case GL_INFO_LOG_LENGTH:
-      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
+      *params = (shProg->InfoLog && shProg->InfoLog[0] != '\0') ?
+         strlen(shProg->InfoLog) + 1 : 0;
       return;
    case GL_ATTACHED_SHADERS:
       *params = shProg->NumShaders;
@@ -902,7 +891,8 @@ get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
       *params = shader->CompileStatus;
       break;
    case GL_INFO_LOG_LENGTH:
-      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
+      *params = (shader->InfoLog && shader->InfoLog[0] != '\0') ?
+         strlen(shader->InfoLog) + 1 : 0;
       break;
    case GL_SHADER_SOURCE_LENGTH:
       *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
@@ -1101,11 +1091,8 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
    const char *capture_path = _mesa_get_shader_capture_path();
    if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
       FILE *file;
-      char filename[PATH_MAX];
-
-      _mesa_snprintf(filename, sizeof(filename), "%s/%u.shader_test",
-                     capture_path, shProg->Name);
-
+      char *filename = ralloc_asprintf(NULL, "%s/%u.shader_test",
+                                       capture_path, shProg->Name);
       file = fopen(filename, "w");
       if (file) {
          fprintf(file, "[require]\nGLSL%s >= %u.%02u\n",
@@ -1124,6 +1111,8 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
       } else {
          _mesa_warning(ctx, "Failed to open %s", filename);
       }
+
+      ralloc_free(filename);
    }
 
    if (shProg->LinkStatus == GL_FALSE &&
@@ -1618,9 +1607,9 @@ generate_sha1(const char *source, char sha_str[64])
  *
  * <path>/<stage prefix>_<CHECKSUM>.glsl
  */
-static void
+static char *
 construct_name(const gl_shader_stage stage, const char *source,
-               const char *path, char *name, unsigned length)
+               const char *path)
 {
    char sha[64];
    static const char *types[] = {
@@ -1628,8 +1617,7 @@ construct_name(const gl_shader_stage stage, const char *source,
    };
 
    generate_sha1(source, sha);
-   _mesa_snprintf(name, length, "%s/%s_%s.glsl", path, types[stage],
-                  sha);
+   return ralloc_asprintf(NULL, "%s/%s_%s.glsl", path, types[stage], sha);
 }
 
 /**
@@ -1638,7 +1626,6 @@ construct_name(const gl_shader_stage stage, const char *source,
 static void
 dump_shader(const gl_shader_stage stage, const char *source)
 {
-   char name[PATH_MAX];
    static bool path_exists = true;
    char *dump_path;
    FILE *f;
@@ -1652,7 +1639,7 @@ dump_shader(const gl_shader_stage stage, const char *source)
       return;
    }
 
-   construct_name(stage, source, dump_path, name, PATH_MAX);
+   char *name = construct_name(stage, source, dump_path);
 
    f = fopen(name, "w");
    if (f) {
@@ -1663,6 +1650,7 @@ dump_shader(const gl_shader_stage stage, const char *source)
       _mesa_warning(ctx, "could not open %s for dumping shader (%s)", name,
                     strerror(errno));
    }
+   ralloc_free(name);
 }
 
 /**
@@ -1672,7 +1660,6 @@ dump_shader(const gl_shader_stage stage, const char *source)
 static GLcharARB *
 read_shader(const gl_shader_stage stage, const char *source)
 {
-   char name[PATH_MAX];
    char *read_path;
    static bool path_exists = true;
    int len, shader_size = 0;
@@ -1688,9 +1675,9 @@ read_shader(const gl_shader_stage stage, const char *source)
       return NULL;
    }
 
-   construct_name(stage, source, read_path, name, PATH_MAX);
-
+   char *name = construct_name(stage, source, read_path);
    f = fopen(name, "r");
+   ralloc_free(name);
    if (!f)
       return NULL;
 
@@ -2152,66 +2139,61 @@ _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
 
 /**
  * Copy program-specific data generated by linking from the gl_shader_program
- * object to a specific gl_program object.
+ * object to the gl_program object referred to by the gl_linked_shader.
+ *
+ * This function expects _mesa_reference_program() to have been previously
+ * called setting the gl_linked_shaders program reference.
  */
 void
-_mesa_copy_linked_program_data(gl_shader_stage type,
-                               const struct gl_shader_program *src,
-                               struct gl_program *dst)
+_mesa_copy_linked_program_data(const struct gl_shader_program *src,
+                               struct gl_linked_shader *dst_sh)
 {
-   switch (type) {
+   assert(dst_sh->Program);
+
+   struct gl_program *dst = dst_sh->Program;
+
+   dst->info.num_abos = dst_sh->NumAtomicBuffers;
+   dst->info.num_images = dst_sh->NumImages;
+
+   switch (dst_sh->Stage) {
    case MESA_SHADER_VERTEX:
       dst->ClipDistanceArraySize = src->Vert.ClipDistanceArraySize;
       dst->CullDistanceArraySize = src->Vert.CullDistanceArraySize;
       break;
    case MESA_SHADER_TESS_CTRL: {
-      struct gl_tess_ctrl_program *dst_tcp =
-         (struct gl_tess_ctrl_program *) dst;
-      dst_tcp->VerticesOut = src->_LinkedShaders[MESA_SHADER_TESS_CTRL]->
-         info.TessCtrl.VerticesOut;
+      dst->info.tcs.vertices_out = dst_sh->info.TessCtrl.VerticesOut;
       break;
    }
    case MESA_SHADER_TESS_EVAL: {
-      struct gl_tess_eval_program *dst_tep =
-         (struct gl_tess_eval_program *) dst;
-      struct gl_linked_shader *tes_sh =
-         src->_LinkedShaders[MESA_SHADER_TESS_EVAL];
-
-      dst_tep->PrimitiveMode = tes_sh->info.TessEval.PrimitiveMode;
-      dst_tep->Spacing = tes_sh->info.TessEval.Spacing;
-      dst_tep->VertexOrder = tes_sh->info.TessEval.VertexOrder;
-      dst_tep->PointMode = tes_sh->info.TessEval.PointMode;
+      dst->info.tes.primitive_mode = dst_sh->info.TessEval.PrimitiveMode;
+      dst->info.tes.spacing = dst_sh->info.TessEval.Spacing;
+      dst->info.tes.vertex_order = dst_sh->info.TessEval.VertexOrder;
+      dst->info.tes.point_mode = dst_sh->info.TessEval.PointMode;
       dst->ClipDistanceArraySize = src->TessEval.ClipDistanceArraySize;
       dst->CullDistanceArraySize = src->TessEval.CullDistanceArraySize;
       break;
    }
    case MESA_SHADER_GEOMETRY: {
-      struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
-      struct gl_linked_shader *geom_sh =
-         src->_LinkedShaders[MESA_SHADER_GEOMETRY];
-
-      dst_gp->VerticesIn = src->Geom.VerticesIn;
-      dst_gp->VerticesOut = geom_sh->info.Geom.VerticesOut;
-      dst_gp->Invocations = geom_sh->info.Geom.Invocations;
-      dst_gp->InputType = geom_sh->info.Geom.InputType;
-      dst_gp->OutputType = geom_sh->info.Geom.OutputType;
+      dst->info.gs.vertices_in = src->Geom.VerticesIn;
+      dst->info.gs.vertices_out = dst_sh->info.Geom.VerticesOut;
+      dst->info.gs.invocations = dst_sh->info.Geom.Invocations;
+      dst->info.gs.input_primitive = dst_sh->info.Geom.InputType;
+      dst->info.gs.output_primitive = dst_sh->info.Geom.OutputType;
       dst->ClipDistanceArraySize = src->Geom.ClipDistanceArraySize;
       dst->CullDistanceArraySize = src->Geom.CullDistanceArraySize;
-      dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;
-      dst_gp->UsesStreams = src->Geom.UsesStreams;
+      dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive;
+      dst->info.gs.uses_streams = src->Geom.UsesStreams;
       break;
    }
    case MESA_SHADER_FRAGMENT: {
-      struct gl_fragment_program *dst_fp = (struct gl_fragment_program *) dst;
-      dst_fp->FragDepthLayout = src->FragDepthLayout;
+      dst->info.fs.depth_layout = src->FragDepthLayout;
+      dst->info.fs.early_fragment_tests = dst_sh->info.EarlyFragmentTests;
       break;
    }
    case MESA_SHADER_COMPUTE: {
-      struct gl_compute_program *dst_cp = (struct gl_compute_program *) dst;
-      int i;
-      for (i = 0; i < 3; i++)
-         dst_cp->LocalSize[i] = src->Comp.LocalSize[i];
-      dst_cp->SharedSize = src->Comp.SharedSize;
+      for (int i = 0; i < 3; i++)
+         dst->info.cs.local_size[i] = src->Comp.LocalSize[i];
+      dst->info.cs.shared_size = src->Comp.SharedSize;
       break;
    }
    default: