egl: Add Haiku code and support
[mesa.git] / src / glsl / link_varyings.cpp
index 3d5a6807cdd044a19f7d8279ec222eb5871f0145..22617990fdbdd8ca438b455062b11175946c671c 100644 (file)
@@ -116,7 +116,7 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
       return;
    }
 
-   if (input->data.invariant != output->data.invariant) {
+   if (!prog->IsES && input->data.invariant != output->data.invariant) {
       linker_error(prog,
                    "%s shader output `%s' %s invariant qualifier, "
                    "but %s shader input %s invariant qualifier\n",
@@ -175,8 +175,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
 
    /* Find all shader outputs in the "producer" stage.
     */
-   foreach_list(node, producer->ir) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+   foreach_in_list(ir_instruction, node, producer->ir) {
+      ir_variable *const var = node->as_variable();
 
       if ((var == NULL) || (var->data.mode != ir_var_shader_out))
         continue;
@@ -212,8 +212,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
     * should be arrays and the type of the array element should match the type
     * of the corresponding producer output.
     */
-   foreach_list(node, consumer->ir) {
-      ir_variable *const input = ((ir_instruction *) node)->as_variable();
+   foreach_in_list(ir_instruction, node, consumer->ir) {
+      ir_variable *const input = node->as_variable();
 
       if ((input == NULL) || (input->data.mode != ir_var_shader_in))
         continue;
@@ -318,6 +318,11 @@ tfeedback_decl::init(struct gl_context *ctx, const void *mem_ctx,
    const char *base_name_end;
    long subscript = parse_program_resource_name(input, &base_name_end);
    this->var_name = ralloc_strndup(mem_ctx, input, base_name_end - input);
+   if (this->var_name == NULL) {
+      _mesa_error_no_memory(__func__);
+      return;
+   }
+
    if (subscript >= 0) {
       this->array_subscript = subscript;
       this->is_subscripted = true;
@@ -329,7 +334,7 @@ tfeedback_decl::init(struct gl_context *ctx, const void *mem_ctx,
     * class must behave specially to account for the fact that gl_ClipDistance
     * is converted from a float[8] to a vec4[2].
     */
-   if (ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].LowerClipDistance &&
+   if (ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].LowerClipDistance &&
        strcmp(this->var_name, "gl_ClipDistance") == 0) {
       this->is_clip_distance_mesa = true;
    }
@@ -830,9 +835,11 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
        * regardless of where they appear.  We can trivially satisfy that
        * requirement by changing the interpolation type to flat here.
        */
-      producer_var->data.centroid = false;
-      producer_var->data.sample = false;
-      producer_var->data.interpolation = INTERP_QUALIFIER_FLAT;
+      if (producer_var) {
+         producer_var->data.centroid = false;
+         producer_var->data.sample = false;
+         producer_var->data.interpolation = INTERP_QUALIFIER_FLAT;
+      }
 
       if (consumer_var) {
          consumer_var->data.centroid = false;
@@ -1068,10 +1075,8 @@ private:
    virtual void visit_field(const glsl_type *type, const char *name,
                             bool row_major)
    {
-      assert(!type->is_record());
-      assert(!(type->is_array() && type->fields.array->is_record()));
-      assert(!type->is_interface());
-      assert(!(type->is_array() && type->fields.array->is_interface()));
+      assert(!type->without_array()->is_record());
+      assert(!type->without_array()->is_interface());
 
       (void) row_major;
 
@@ -1121,8 +1126,8 @@ populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
           0,
           sizeof(consumer_inputs_with_locations[0]) * VARYING_SLOT_MAX);
 
-   foreach_list(node, ir) {
-      ir_variable *const input_var = ((ir_instruction *) node)->as_variable();
+   foreach_in_list(ir_instruction, node, ir) {
+      ir_variable *const input_var = node->as_variable();
 
       if ((input_var != NULL) && (input_var->data.mode == ir_var_shader_in)) {
          if (input_var->type->is_interface())
@@ -1227,8 +1232,8 @@ canonicalize_shader_io(exec_list *ir, enum ir_variable_mode io_mode)
    ir_variable *var_table[MAX_PROGRAM_OUTPUTS * 4];
    unsigned num_variables = 0;
 
-   foreach_list(node, ir) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+   foreach_in_list(ir_instruction, node, ir) {
+      ir_variable *const var = node->as_variable();
 
       if (var == NULL || var->data.mode != io_mode)
          continue;
@@ -1339,14 +1344,18 @@ assign_varying_locations(struct gl_context *ctx,
    }
 
    if (producer) {
-      foreach_list(node, producer->ir) {
-         ir_variable *const output_var =
-            ((ir_instruction *) node)->as_variable();
+      foreach_in_list(ir_instruction, node, producer->ir) {
+         ir_variable *const output_var = node->as_variable();
 
          if ((output_var == NULL) ||
              (output_var->data.mode != ir_var_shader_out))
             continue;
 
+         /* Only geometry shaders can use non-zero streams */
+         assert(output_var->data.stream == 0 ||
+                (output_var->data.stream < MAX_VERTEX_STREAMS &&
+                 producer->Stage == MESA_SHADER_GEOMETRY));
+
          tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
          g.process(output_var);
 
@@ -1378,9 +1387,8 @@ assign_varying_locations(struct gl_context *ctx,
        * geometry) shader program.  This means that locations must be assigned
        * for all the inputs.
        */
-      foreach_list(node, consumer->ir) {
-         ir_variable *const input_var =
-            ((ir_instruction *) node)->as_variable();
+      foreach_in_list(ir_instruction, node, consumer->ir) {
+         ir_variable *const input_var = node->as_variable();
 
          if ((input_var == NULL) ||
              (input_var->data.mode != ir_var_shader_in))
@@ -1445,12 +1453,27 @@ assign_varying_locations(struct gl_context *ctx,
    }
 
    if (consumer && producer) {
-      foreach_list(node, consumer->ir) {
-         ir_variable *const var = ((ir_instruction *) node)->as_variable();
+      foreach_in_list(ir_instruction, node, consumer->ir) {
+         ir_variable *const var = node->as_variable();
 
          if (var && var->data.mode == ir_var_shader_in &&
              var->data.is_unmatched_generic_inout) {
-            if (prog->Version <= 120) {
+            if (prog->IsES) {
+               /*
+                * On Page 91 (Page 97 of the PDF) of the GLSL ES 1.0 spec:
+                *
+                *     If the vertex shader declares but doesn't write to a
+                *     varying and the fragment shader declares and reads it,
+                *     is this an error?
+                *
+                *     RESOLUTION: No.
+                */
+               linker_warning(prog, "%s shader varying %s not written "
+                              "by %s shader\n.",
+                              _mesa_shader_stage_to_string(consumer->Stage),
+                              var->name,
+                              _mesa_shader_stage_to_string(producer->Stage));
+            } else if (prog->Version <= 120) {
                /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
                 *
                 *     Only those varying variables used (i.e. read) in
@@ -1463,7 +1486,6 @@ assign_varying_locations(struct gl_context *ctx,
                 * write the variable for the FS to read it.  See
                 * "glsl1-varying read but not written" in piglit.
                 */
-
                linker_error(prog, "%s shader varying %s not written "
                             "by %s shader\n.",
                             _mesa_shader_stage_to_string(consumer->Stage),
@@ -1489,8 +1511,8 @@ check_against_output_limit(struct gl_context *ctx,
 {
    unsigned output_vectors = 0;
 
-   foreach_list(node, producer->ir) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+   foreach_in_list(ir_instruction, node, producer->ir) {
+      ir_variable *const var = node->as_variable();
 
       if (var && var->data.mode == ir_var_shader_out &&
           var_counts_against_varying_limit(producer->Stage, var)) {
@@ -1528,8 +1550,8 @@ check_against_input_limit(struct gl_context *ctx,
 {
    unsigned input_vectors = 0;
 
-   foreach_list(node, consumer->ir) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+   foreach_in_list(ir_instruction, node, consumer->ir) {
+      ir_variable *const var = node->as_variable();
 
       if (var && var->data.mode == ir_var_shader_in &&
           var_counts_against_varying_limit(consumer->Stage, var)) {