Merge branch 'master' of ../mesa into vulkan
[mesa.git] / src / mesa / program / ir_to_mesa.cpp
index b2776da45d95243ba01a9bcfeb7a7eb1d60aa5a1..1cfcf9119f97c2508219a0fc7508b826a05d1b92 100644 (file)
@@ -262,6 +262,7 @@ public:
    virtual void visit(ir_if *);
    virtual void visit(ir_emit_vertex *);
    virtual void visit(ir_end_primitive *);
+   virtual void visit(ir_barrier *);
    /*@}*/
 
    src_reg result;
@@ -303,9 +304,6 @@ public:
    void emit_scalar(ir_instruction *ir, enum prog_opcode op,
                    dst_reg dst, src_reg src0, src_reg src1);
 
-   void emit_scs(ir_instruction *ir, enum prog_opcode op,
-                dst_reg dst, const src_reg &src);
-
    bool try_emit_mad(ir_expression *ir,
                          int mul_operand);
    bool try_emit_mad_for_and_not(ir_expression *ir,
@@ -408,7 +406,7 @@ ir_to_mesa_visitor::emit_dp(ir_instruction *ir,
                            dst_reg dst, src_reg src0, src_reg src1,
                            unsigned elements)
 {
-   static const gl_inst_opcode dot_opcodes[] = {
+   static const enum prog_opcode dot_opcodes[] = {
       OPCODE_DP2, OPCODE_DP3, OPCODE_DP4
    };
 
@@ -479,101 +477,6 @@ ir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op,
    emit_scalar(ir, op, dst, src0, undef);
 }
 
-/**
- * Emit an OPCODE_SCS instruction
- *
- * The \c SCS opcode functions a bit differently than the other Mesa (or
- * ARB_fragment_program) opcodes.  Instead of splatting its result across all
- * four components of the destination, it writes one value to the \c x
- * component and another value to the \c y component.
- *
- * \param ir        IR instruction being processed
- * \param op        Either \c OPCODE_SIN or \c OPCODE_COS depending on which
- *                  value is desired.
- * \param dst       Destination register
- * \param src       Source register
- */
-void
-ir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op,
-                            dst_reg dst,
-                            const src_reg &src)
-{
-   /* Vertex programs cannot use the SCS opcode.
-    */
-   if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) {
-      emit_scalar(ir, op, dst, src);
-      return;
-   }
-
-   const unsigned component = (op == OPCODE_SIN) ? 0 : 1;
-   const unsigned scs_mask = (1U << component);
-   int done_mask = ~dst.writemask;
-   src_reg tmp;
-
-   assert(op == OPCODE_SIN || op == OPCODE_COS);
-
-   /* If there are compnents in the destination that differ from the component
-    * that will be written by the SCS instrution, we'll need a temporary.
-    */
-   if (scs_mask != unsigned(dst.writemask)) {
-      tmp = get_temp(glsl_type::vec4_type);
-   }
-
-   for (unsigned i = 0; i < 4; i++) {
-      unsigned this_mask = (1U << i);
-      src_reg src0 = src;
-
-      if ((done_mask & this_mask) != 0)
-        continue;
-
-      /* The source swizzle specified which component of the source generates
-       * sine / cosine for the current component in the destination.  The SCS
-       * instruction requires that this value be swizzle to the X component.
-       * Replace the current swizzle with a swizzle that puts the source in
-       * the X component.
-       */
-      unsigned src0_swiz = GET_SWZ(src.swizzle, i);
-
-      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
-                                  src0_swiz, src0_swiz);
-      for (unsigned j = i + 1; j < 4; j++) {
-        /* If there is another enabled component in the destination that is
-         * derived from the same inputs, generate its value on this pass as
-         * well.
-         */
-        if (!(done_mask & (1 << j)) &&
-            GET_SWZ(src0.swizzle, j) == src0_swiz) {
-           this_mask |= (1 << j);
-        }
-      }
-
-      if (this_mask != scs_mask) {
-        ir_to_mesa_instruction *inst;
-        dst_reg tmp_dst = dst_reg(tmp);
-
-        /* Emit the SCS instruction.
-         */
-        inst = emit(ir, OPCODE_SCS, tmp_dst, src0);
-        inst->dst.writemask = scs_mask;
-
-        /* Move the result of the SCS instruction to the desired location in
-         * the destination.
-         */
-        tmp.swizzle = MAKE_SWIZZLE4(component, component,
-                                    component, component);
-        inst = emit(ir, OPCODE_SCS, dst, tmp);
-        inst->dst.writemask = this_mask;
-      } else {
-        /* Emit the SCS instruction to write directly to the destination.
-         */
-        ir_to_mesa_instruction *inst = emit(ir, OPCODE_SCS, dst, src0);
-        inst->dst.writemask = scs_mask;
-      }
-
-      done_mask |= this_mask;
-   }
-}
-
 src_reg
 ir_to_mesa_visitor::src_reg_for_float(float val)
 {
@@ -631,6 +534,7 @@ type_size(const struct glsl_type *type)
       return size;
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_IMAGE:
+   case GLSL_TYPE_SUBROUTINE:
       /* Samplers take up one slot in UNIFORMS[], but they're baked in
        * at link time.
        */
@@ -639,6 +543,7 @@ type_size(const struct glsl_type *type)
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
+   case GLSL_TYPE_FUNCTION:
       assert(!"Invalid type in type_size");
       break;
    }
@@ -1018,7 +923,7 @@ void
 ir_to_mesa_visitor::visit(ir_expression *ir)
 {
    unsigned int operand;
-   src_reg op[Elements(ir->operands)];
+   src_reg op[ARRAY_SIZE(ir->operands)];
    src_reg result_src;
    dst_reg result_dst;
 
@@ -1122,12 +1027,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
    case ir_unop_cos:
       emit_scalar(ir, OPCODE_COS, result_dst, op[0]);
       break;
-   case ir_unop_sin_reduced:
-      emit_scs(ir, OPCODE_SIN, result_dst, op[0]);
-      break;
-   case ir_unop_cos_reduced:
-      emit_scs(ir, OPCODE_COS, result_dst, op[0]);
-      break;
 
    case ir_unop_dFdx:
       emit(ir, OPCODE_DDX, result_dst, op[0]);
@@ -1445,9 +1344,12 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
    case ir_unop_dFdx_fine:
    case ir_unop_dFdy_coarse:
    case ir_unop_dFdy_fine:
+   case ir_unop_subroutine_to_int:
+   case ir_unop_get_buffer_size:
       assert(!"not supported");
       break;
 
+   case ir_unop_ssbo_unsized_array_length:
    case ir_quadop_vector:
       /* This operation should have already been handled.
        */
@@ -2020,6 +1922,8 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
    case ir_query_levels:
       assert(!"Unexpected ir_query_levels opcode");
       break;
+   case ir_texture_samples:
+      unreachable("Unexpected ir_texture_samples opcode");
    }
 
    const glsl_type *sampler_type = ir->sampler->type;
@@ -2221,6 +2125,12 @@ ir_to_mesa_visitor::visit(ir_end_primitive *)
    assert(!"Geometry shaders not supported.");
 }
 
+void
+ir_to_mesa_visitor::visit(ir_barrier *)
+{
+   unreachable("GLSL barrier() not supported.");
+}
+
 ir_to_mesa_visitor::ir_to_mesa_visitor()
 {
    result.file = PROGRAM_UNDEFINED;
@@ -2481,7 +2391,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
       ir_variable *var = node->as_variable();
 
       if ((var == NULL) || (var->data.mode != ir_var_uniform)
-         || var->is_in_uniform_block() || (strncmp(var->name, "gl_", 3) == 0))
+         || var->is_in_buffer_block() || (strncmp(var->name, "gl_", 3) == 0))
         continue;
 
       add.process(var);
@@ -2510,9 +2420,14 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
       if (!found)
         continue;
 
+      struct gl_uniform_storage *storage =
+         &shader_program->UniformStorage[location];
+
+      /* Do not associate any uniform storage to built-in uniforms */
+      if (storage->builtin)
+         continue;
+
       if (location != last_location) {
-        struct gl_uniform_storage *storage =
-           &shader_program->UniformStorage[location];
         enum gl_uniform_driver_format format = uniform_native;
 
         unsigned columns = 0;
@@ -2543,6 +2458,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
            break;
         case GLSL_TYPE_SAMPLER:
         case GLSL_TYPE_IMAGE:
+         case GLSL_TYPE_SUBROUTINE:
            format = uniform_native;
            columns = 1;
            break;
@@ -2552,6 +2468,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
          case GLSL_TYPE_STRUCT:
          case GLSL_TYPE_ERROR:
          case GLSL_TYPE_INTERFACE:
+         case GLSL_TYPE_FUNCTION:
            assert(!"Should not get here.");
            break;
         }
@@ -2824,7 +2741,7 @@ get_mesa_program(struct gl_context *ctx,
       mesa_inst->Opcode = inst->op;
       mesa_inst->CondUpdate = inst->cond_update;
       if (inst->saturate)
-        mesa_inst->SaturateMode = SATURATE_ZERO_ONE;
+        mesa_inst->Saturate = GL_TRUE;
       mesa_inst->DstReg.File = inst->dst.file;
       mesa_inst->DstReg.Index = inst->dst.index;
       mesa_inst->DstReg.CondMask = inst->dst.cond_mask;
@@ -3002,7 +2919,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
         if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput
             || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform)
           progress =
-            lower_variable_index_to_cond_assign(ir,
+            lower_variable_index_to_cond_assign(prog->_LinkedShaders[i]->Stage, ir,
                                                 options->EmitNoIndirectInput,
                                                 options->EmitNoIndirectOutput,
                                                 options->EmitNoIndirectTemp,
@@ -3067,6 +2984,8 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
    if (prog->LinkStatus) {
       if (!ctx->Driver.LinkShader(ctx, prog)) {
         prog->LinkStatus = GL_FALSE;
+      } else {
+         build_program_resource_list(prog);
       }
    }