diff options
Diffstat (limited to 'mesalib')
26 files changed, 726 insertions, 228 deletions
| diff --git a/mesalib/configure.ac b/mesalib/configure.ac index dfa35b41b..91b9871d7 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -711,8 +711,6 @@ fi  AM_CONDITIONAL(HAVE_DRI_GLX, test "x$enable_glx" = xyes -a \                                    "x$enable_dri" = xyes)  AM_CONDITIONAL(HAVE_DRI, test "x$enable_dri" = xyes) -AM_CONDITIONAL(NEED_LIBMESA, test "x$enable_xlib_glx" = xyes -o \ -                                  "x$enable_osmesa" = xyes)  AC_ARG_ENABLE([shared-glapi],      [AS_HELP_STRING([--enable-shared-glapi], @@ -864,8 +862,6 @@ AC_SUBST([GLESv1_CM_PC_LIB_PRIV])  AC_SUBST([GLESv2_LIB_DEPS])  AC_SUBST([GLESv2_PC_LIB_PRIV]) -DRI_LIB_DEPS="\$(top_builddir)/src/mesa/libdricore/libdricore${VERSION}.la" -  AC_SUBST([HAVE_XF86VIDMODE])  dnl @@ -1026,10 +1022,15 @@ if test "x$enable_dri" = xyes; then      LIBS="$save_LIBS"      # If we are building any DRI driver other than swrast. -    if test -n "$DRI_DIRS" -a x"$DRI_DIRS" != xswrast; then -        # ... libdrm is required -        if test "x$have_libdrm" != xyes; then -            AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED]) +    if test -n "$DRI_DIRS"; then +        if test x"$DRI_DIRS" != xswrast; then +            # ... libdrm is required +            if test "x$have_libdrm" != xyes; then +                AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED]) +            fi +            DRICOMMON_NEED_LIBDRM=yes +        else +            DRICOMMON_NEED_LIBDRM=no          fi      fi @@ -1039,7 +1040,11 @@ if test "x$enable_dri" = xyes; then      DRI_DRIVER_LDFLAGS="-module -avoid-version -shared -Wl,-Bsymbolic"  fi -AM_CONDITIONAL(NEED_LIBDRICORE, test -n "$DRI_DIRS") + +AM_CONDITIONAL(NEED_MEGADRIVER, test -n "$DRI_DIRS") +AM_CONDITIONAL(NEED_LIBMESA, test "x$enable_xlib_glx" = xyes -o \ +                                  "x$enable_osmesa" = xyes -o \ +                                  -n "$DRI_DIRS")  AC_SUBST([EXPAT_INCLUDES])  AC_SUBST([DRI_LIB_DEPS])  AC_SUBST([DRI_DRIVER_LDFLAGS]) @@ -1759,6 +1764,7 @@ if test "x$with_gallium_drivers" != x; then              fi              GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"              gallium_check_st "i915/drm" "dri-i915" "xorg-i915" +            DRICOMMON_NEED_LIBDRM=yes              ;;          xilo)              HAVE_GALLIUM_ILO=yes @@ -1766,6 +1772,7 @@ if test "x$with_gallium_drivers" != x; then              gallium_require_drm_loader              GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS ilo"              gallium_check_st "intel/drm" "dri-ilo" +            DRICOMMON_NEED_LIBDRM=yes              ;;          xr300)              HAVE_GALLIUM_R300=yes @@ -1773,6 +1780,7 @@ if test "x$with_gallium_drivers" != x; then              gallium_require_llvm "Gallium R300"              GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"              gallium_check_st "radeon/drm" "r300/dri" "" "" "r300/xvmc" "r300/vdpau" +            DRICOMMON_NEED_LIBDRM=yes              ;;          xr600)              HAVE_GALLIUM_R600=yes @@ -1790,6 +1798,7 @@ if test "x$with_gallium_drivers" != x; then                  LLVM_COMPONENTS="${LLVM_COMPONENTS} bitreader asmparser"              fi              gallium_check_st "radeon/drm" "r600/dri" "r600/xorg" "" "r600/xvmc" "r600/vdpau" +            DRICOMMON_NEED_LIBDRM=yes              ;;          xradeonsi)              HAVE_GALLIUM_RADEONSI=yes @@ -1798,6 +1807,7 @@ if test "x$with_gallium_drivers" != x; then              GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi"              radeon_llvm_check              gallium_check_st "radeon/drm" "radeonsi/dri" "radeonsi/xorg" "" "" "radeonsi/vdpau" "" +            DRICOMMON_NEED_LIBDRM=yes              ;;          xnouveau)              HAVE_GALLIUM_NOUVEAU=yes @@ -1805,6 +1815,7 @@ if test "x$with_gallium_drivers" != x; then              gallium_require_drm_loader              GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau"              gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau" "vdpau-nouveau" +            DRICOMMON_NEED_LIBDRM=yes              ;;          xfreedreno)              HAVE_GALLIUM_FREEDRENO=yes @@ -1812,6 +1823,7 @@ if test "x$with_gallium_drivers" != x; then              gallium_require_drm_loader              GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS freedreno"              gallium_check_st "freedreno/drm" "dri-freedreno" "" "" "" "" +            DRICOMMON_NEED_LIBDRM=yes              ;;          xswrast)              HAVE_GALLIUM_SOFTPIPE=yes @@ -1943,10 +1955,7 @@ AM_CONDITIONAL(HAVE_MESA_LLVM, test x$MESA_LLVM = x1)  AC_SUBST([ELF_LIB]) -AM_CONDITIONAL(NEED_LIBPROGRAM, test "x$with_gallium_drivers" != x -o \ -                                     "x$enable_xlib_glx" = xyes -o \ -                                     "x$enable_osmesa" = xyes -o \ -                                     "x$enable_gallium_osmesa" = xyes) +AM_CONDITIONAL(DRICOMMON_NEED_LIBDRM, test "x$DRICOMMON_NEED_LIBDRM" = xyes)  AM_CONDITIONAL(HAVE_X11_DRIVER, test "x$enable_xlib_glx" = xyes)  AM_CONDITIONAL(HAVE_OSMESA, test "x$enable_osmesa" = xyes)  AM_CONDITIONAL(HAVE_GALLIUM_OSMESA, test "x$enable_gallium_osmesa" = xyes) @@ -2109,7 +2118,6 @@ AC_CONFIG_FILES([Makefile  		src/mesa/drivers/osmesa/Makefile  		src/mesa/drivers/osmesa/osmesa.pc  		src/mesa/drivers/x11/Makefile -		src/mesa/libdricore/Makefile  		src/mesa/main/tests/Makefile  		src/mesa/main/tests/hash_table/Makefile  		src/mesa/program/Makefile diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h index 33b41ea3b..48993b939 100644 --- a/mesalib/include/GL/internal/dri_interface.h +++ b/mesalib/include/GL/internal/dri_interface.h @@ -330,12 +330,6 @@ struct __DRI2throttleExtensionRec {  		    enum __DRI2throttleReason reason);  }; -/** - * XML document describing the configuration options supported by the - * driver. - */ -extern const char __driConfigOptions[]; -  /*@}*/  /** @@ -494,6 +488,19 @@ struct __DRIuseInvalidateExtensionRec {  #define __DRI_DRIVER_EXTENSIONS "__driDriverExtensions"  /** + * This symbol replaces the __DRI_DRIVER_EXTENSIONS symbol, and will be + * suffixed by "_drivername", allowing multiple drivers to be built into one + * library, and also giving the driver the chance to return a variable driver + * extensions struct depending on the driver name being loaded or any other + * system state. + * + * The function prototype is: + * + * const __DRIextension **__driDriverGetExtensions_drivername(void); + */ +#define __DRI_DRIVER_GET_EXTENSIONS "__driDriverGetExtensions" + +/**   * Tokens for __DRIconfig attribs.  A number of attributes defined by   * GLX or EGL standards are not in the table, as they must be provided   * by the loader.  For example, FBConfig ID or visual ID, drawable type. @@ -706,7 +713,7 @@ struct __DRIlegacyExtensionRec {   * conjunction with the core extension.   */  #define __DRI_SWRAST "DRI_SWRast" -#define __DRI_SWRAST_VERSION 3 +#define __DRI_SWRAST_VERSION 4  struct __DRIswrastExtensionRec {      __DRIextension base; @@ -742,6 +749,18 @@ struct __DRIswrastExtensionRec {  					 const uint32_t *attribs,  					 unsigned *error,  					 void *loaderPrivate); + +   /** +    * createNewScreen() with the driver extensions passed in. +    * +    * \since version 4 +    */ +   __DRIscreen *(*createNewScreen2)(int screen, +                                    const __DRIextension **loader_extensions, +                                    const __DRIextension **driver_extensions, +                                    const __DRIconfig ***driver_configs, +                                    void *loaderPrivate); +  };  /** @@ -824,7 +843,7 @@ struct __DRIdri2LoaderExtensionRec {   * constructors for DRI2.   */  #define __DRI_DRI2 "DRI_DRI2" -#define __DRI_DRI2_VERSION 3 +#define __DRI_DRI2_VERSION 4  #define __DRI_API_OPENGL	0	/**< OpenGL compatibility profile */  #define __DRI_API_GLES		1	/**< OpenGL ES 1.x */ @@ -932,6 +951,17 @@ struct __DRIdri2ExtensionRec {  					 const uint32_t *attribs,  					 unsigned *error,  					 void *loaderPrivate); + +   /** +    * createNewScreen with the driver's extension list passed in. +    * +    * \since version 4 +    */ +    __DRIscreen *(*createNewScreen2)(int screen, int fd, +                                     const __DRIextension **loader_extensions, +                                     const __DRIextension **driver_extensions, +                                     const __DRIconfig ***driver_configs, +                                     void *loaderPrivate);  }; @@ -1226,4 +1256,35 @@ struct __DRIrobustnessExtensionRec {     __DRIextension base;  }; +/** + * DRI config options extension. + * + * This extension provides the XML string containing driver options for use by + * the loader in supporting the driconf application. + */ +#define __DRI_CONFIG_OPTIONS "DRI_ConfigOptions" +#define __DRI_CONFIG_OPTIONS_VERSION 1 + +typedef struct __DRIconfigOptionsExtensionRec { +   __DRIextension base; +   const char *xml; +} __DRIconfigOptionsExtension; + +/** + * This extension provides a driver vtable to a set of common driver helper + * functions (driCoreExtension, driDRI2Extension) within the driver + * implementation, as opposed to having to pass them through a global + * variable. + * + * It is not intended to be public API to the actual loader, and the vtable + * layout may change at any time. + */ +#define __DRI_DRIVER_VTABLE "DRI_DriverVtable" +#define __DRI_DRIVER_VTABLE_VERSION 1 + +typedef struct __DRIDriverVtableExtensionRec { +    __DRIextension base; +    const struct __DriverAPIRec *vtable; +} __DRIDriverVtableExtension; +  #endif diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index b644b22c7..3551a5956 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -60,6 +60,10 @@  static void  detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,  			       exec_list *instructions); +static void +remove_per_vertex_blocks(exec_list *instructions, +                         _mesa_glsl_parse_state *state, ir_variable_mode mode); +  void  _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -114,6 +118,40 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)        var->remove();        instructions->push_head(var);     } + +   /* From section 7.1 (Built-In Language Variables) of the GLSL 4.10 spec: +    * +    *     If multiple shaders using members of a built-in block belonging to +    *     the same interface are linked together in the same program, they +    *     must all redeclare the built-in block in the same way, as described +    *     in section 4.3.7 "Interface Blocks" for interface block matching, or +    *     a link error will result. +    * +    * The phrase "using members of a built-in block" implies that if two +    * shaders are linked together and one of them *does not use* any members +    * of the built-in block, then that shader does not need to have a matching +    * redeclaration of the built-in block. +    * +    * This appears to be a clarification to the behaviour established for +    * gl_PerVertex by GLSL 1.50, therefore implement it regardless of GLSL +    * version. +    * +    * The definition of "interface" in section 4.3.7 that applies here is as +    * follows: +    * +    *     The boundary between adjacent programmable pipeline stages: This +    *     spans all the outputs in all compilation units of the first stage +    *     and all the inputs in all compilation units of the second stage. +    * +    * Therefore this rule applies to both inter- and intra-stage linking. +    * +    * The easiest way to implement this is to check whether the shader uses +    * gl_PerVertex right after ast-to-ir conversion, and if it doesn't, simply +    * remove all the relevant variable declaration from the IR, so that the +    * linker won't see them and complain about mismatches. +    */ +   remove_per_vertex_blocks(instructions, state, ir_var_shader_in); +   remove_per_vertex_blocks(instructions, state, ir_var_shader_out);  } @@ -1961,6 +1999,45 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,     return true;  } + +static glsl_interp_qualifier +interpret_interpolation_qualifier(const struct ast_type_qualifier *qual, +                                  ir_variable_mode mode, +                                  struct _mesa_glsl_parse_state *state, +                                  YYLTYPE *loc) +{ +   glsl_interp_qualifier interpolation; +   if (qual->flags.q.flat) +      interpolation = INTERP_QUALIFIER_FLAT; +   else if (qual->flags.q.noperspective) +      interpolation = INTERP_QUALIFIER_NOPERSPECTIVE; +   else if (qual->flags.q.smooth) +      interpolation = INTERP_QUALIFIER_SMOOTH; +   else +      interpolation = INTERP_QUALIFIER_NONE; + +   if (interpolation != INTERP_QUALIFIER_NONE) { +      if (mode != ir_var_shader_in && mode != ir_var_shader_out) { +         _mesa_glsl_error(loc, state, +                          "interpolation qualifier `%s' can only be applied to " +                          "shader inputs or outputs.", +                          interpolation_string(interpolation)); + +      } + +      if ((state->target == vertex_shader && mode == ir_var_shader_in) || +          (state->target == fragment_shader && mode == ir_var_shader_out)) { +         _mesa_glsl_error(loc, state, +                          "interpolation qualifier `%s' cannot be applied to " +                          "vertex shader inputs or fragment shader outputs", +                          interpolation_string(interpolation)); +      } +   } + +   return interpolation; +} + +  static void  apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,  				 ir_variable *var, @@ -2095,34 +2172,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,        }     } -   if (qual->flags.q.flat) -      var->interpolation = INTERP_QUALIFIER_FLAT; -   else if (qual->flags.q.noperspective) -      var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE; -   else if (qual->flags.q.smooth) -      var->interpolation = INTERP_QUALIFIER_SMOOTH; -   else -      var->interpolation = INTERP_QUALIFIER_NONE; - -   if (var->interpolation != INTERP_QUALIFIER_NONE) { -      ir_variable_mode mode = (ir_variable_mode) var->mode; - -      if (mode != ir_var_shader_in && mode != ir_var_shader_out) { -         _mesa_glsl_error(loc, state, -                          "interpolation qualifier `%s' can only be applied to " -                          "shader inputs or outputs.", -                          var->interpolation_string()); - -      } - -      if ((state->target == vertex_shader && mode == ir_var_shader_in) || -          (state->target == fragment_shader && mode == ir_var_shader_out)) { -         _mesa_glsl_error(loc, state, -                          "interpolation qualifier `%s' cannot be applied to " -                          "vertex shader inputs or fragment shader outputs", -                          var->interpolation_string()); -      } -   } +   var->interpolation = +      interpret_interpolation_qualifier(qual, (ir_variable_mode) var->mode, +                                        state, loc);     var->pixel_center_integer = qual->flags.q.pixel_center_integer;     var->origin_upper_left = qual->flags.q.origin_upper_left; @@ -4410,6 +4462,10 @@ ast_type_specifier::hir(exec_list *instructions,   * AST for each can be processed the same way into a set of   * \c glsl_struct_field to describe the members.   * + * If we're processing an interface block, var_mode should be the type of the + * interface block (ir_var_shader_in, ir_var_shader_out, or ir_var_uniform). + * If we're processing a structure, var_mode should be ir_var_auto. + *   * \return   * The number of fields processed.  A pointer to the array structure fields is   * stored in \c *fields_ret. @@ -4422,7 +4478,8 @@ ast_process_structure_or_interface_block(exec_list *instructions,  					 glsl_struct_field **fields_ret,                                           bool is_interface,                                           bool block_row_major, -                                         bool allow_reserved_names) +                                         bool allow_reserved_names, +                                         ir_variable_mode var_mode)  {     unsigned decl_count = 0; @@ -4506,6 +4563,9 @@ ast_process_structure_or_interface_block(exec_list *instructions,           fields[i].type = field_type;  	 fields[i].name = decl->identifier;           fields[i].location = -1; +         fields[i].interpolation = +            interpret_interpolation_qualifier(qual, var_mode, state, &loc); +         fields[i].centroid = qual->flags.q.centroid ? 1 : 0;           if (qual->flags.q.row_major || qual->flags.q.column_major) {              if (!qual->flags.q.uniform) { @@ -4584,7 +4644,8 @@ ast_struct_specifier::hir(exec_list *instructions,  					       &fields,                                                 false,                                                 false, -                                               false /* allow_reserved_names */); +                                               false /* allow_reserved_names */, +                                               ir_var_auto);     validate_identifier(this->name, loc, state); @@ -4665,20 +4726,6 @@ ast_interface_block::hir(exec_list *instructions,        packing = GLSL_INTERFACE_PACKING_STD140;     } -   bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0; -   bool block_row_major = this->layout.flags.q.row_major; -   exec_list declared_variables; -   glsl_struct_field *fields; -   unsigned int num_variables = -      ast_process_structure_or_interface_block(&declared_variables, -                                               state, -                                               &this->declarations, -                                               loc, -                                               &fields, -                                               true, -                                               block_row_major, -                                               redeclaring_per_vertex); -     ir_variable_mode var_mode;     const char *iface_type_name;     if (this->layout.flags.q.in) { @@ -4696,6 +4743,21 @@ ast_interface_block::hir(exec_list *instructions,        assert(!"interface block layout qualifier not found!");     } +   bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0; +   bool block_row_major = this->layout.flags.q.row_major; +   exec_list declared_variables; +   glsl_struct_field *fields; +   unsigned int num_variables = +      ast_process_structure_or_interface_block(&declared_variables, +                                               state, +                                               &this->declarations, +                                               loc, +                                               &fields, +                                               true, +                                               block_row_major, +                                               redeclaring_per_vertex, +                                               var_mode); +     if (!redeclaring_per_vertex)        validate_identifier(this->block_name, loc, state); @@ -4768,6 +4830,10 @@ ast_interface_block::hir(exec_list *instructions,           } else {              fields[i].location =                 earlier_per_vertex->fields.structure[j].location; +            fields[i].interpolation = +               earlier_per_vertex->fields.structure[j].interpolation; +            fields[i].centroid = +               earlier_per_vertex->fields.structure[j].centroid;           }        } @@ -4831,8 +4897,24 @@ ast_interface_block::hir(exec_list *instructions,      *     field selector ( . ) operator (analogously to structures)."      */     if (this->instance_name) { -      if (!redeclaring_per_vertex) +      if (redeclaring_per_vertex) { +         /* When a built-in in an unnamed interface block is redeclared, +          * get_variable_being_redeclared() calls +          * check_builtin_array_max_size() to make sure that built-in array +          * variables aren't redeclared to illegal sizes.  But we're looking +          * at a redeclaration of a named built-in interface block.  So we +          * have to manually call check_builtin_array_max_size() for all parts +          * of the interface that are arrays. +          */ +         for (unsigned i = 0; i < num_variables; i++) { +            if (fields[i].type->is_array()) { +               const unsigned size = fields[i].type->array_size(); +               check_builtin_array_max_size(fields[i].name, size, loc, state); +            } +         } +      } else {           validate_identifier(this->instance_name, loc, state); +      }        ir_variable *var; @@ -4903,6 +4985,8 @@ ast_interface_block::hir(exec_list *instructions,              new(state) ir_variable(fields[i].type,                                     ralloc_strdup(state, fields[i].name),                                     var_mode); +         var->interpolation = fields[i].interpolation; +         var->centroid = fields[i].centroid;           var->init_interface_type(block_type);           if (redeclaring_per_vertex) { @@ -4958,7 +5042,8 @@ ast_interface_block::hir(exec_list *instructions,           foreach_list_safe(node, instructions) {              ir_variable *const var = ((ir_instruction *) node)->as_variable();              if (var != NULL && -                var->get_interface_type() == earlier_per_vertex) { +                var->get_interface_type() == earlier_per_vertex && +                var->mode == var_mode) {                 state->symbols->disable_variable(var->name);                 var->remove();              } @@ -5095,3 +5180,55 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,  		       user_defined_fs_output->name);     }  } + + +static void +remove_per_vertex_blocks(exec_list *instructions, +                         _mesa_glsl_parse_state *state, ir_variable_mode mode) +{ +   /* Find the gl_PerVertex interface block of the appropriate (in/out) mode, +    * if it exists in this shader type. +    */ +   const glsl_type *per_vertex = NULL; +   switch (mode) { +   case ir_var_shader_in: +      if (ir_variable *gl_in = state->symbols->get_variable("gl_in")) +         per_vertex = gl_in->get_interface_type(); +      break; +   case ir_var_shader_out: +      if (ir_variable *gl_Position = +          state->symbols->get_variable("gl_Position")) { +         per_vertex = gl_Position->get_interface_type(); +      } +      break; +   default: +      assert(!"Unexpected mode"); +      break; +   } + +   /* If we didn't find a built-in gl_PerVertex interface block, then we don't +    * need to do anything. +    */ +   if (per_vertex == NULL) +      return; + +   /* If the interface block is used by the shader, then we don't need to do +    * anything. +    */ +   interface_block_usage_visitor v(mode, per_vertex); +   v.run(instructions); +   if (v.usage_found()) +      return; + +   /* Remove any ir_variable declarations that refer to the interface block +    * we're removing. +    */ +   foreach_list_safe(node, instructions) { +      ir_variable *const var = ((ir_instruction *) node)->as_variable(); +      if (var != NULL && var->get_interface_type() == per_vertex && +          var->mode == mode) { +         state->symbols->disable_variable(var->name); +         var->remove(); +      } +   } +} diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index fc1115bc4..018daf67f 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -326,6 +326,8 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type,     this->fields[this->num_fields].name = name;     this->fields[this->num_fields].row_major = false;     this->fields[this->num_fields].location = slot; +   this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE; +   this->fields[this->num_fields].centroid = 0;     this->num_fields++;  } @@ -888,8 +890,8 @@ builtin_variable_generator::generate_varyings()     if (state->target == geometry_shader) {        const glsl_type *per_vertex_in_type =           this->per_vertex_in.construct_interface_instance(); -      ir_variable *var = add_variable("gl_in", array(per_vertex_in_type, 0), -                                      ir_var_shader_in, -1); +      add_variable("gl_in", array(per_vertex_in_type, 0), +                   ir_var_shader_in, -1);     }     if (state->target == vertex_shader || state->target == geometry_shader) {        const glsl_type *per_vertex_out_type = @@ -899,6 +901,8 @@ builtin_variable_generator::generate_varyings()           ir_variable *var =              add_variable(fields[i].name, fields[i].type, ir_var_shader_out,                           fields[i].location); +         var->interpolation = fields[i].interpolation; +         var->centroid = fields[i].centroid;           var->init_interface_type(per_vertex_out_type);        }     } diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 80a6e71a7..bc8d87f5f 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -101,6 +101,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,        this->fields.structure[i].name = ralloc_strdup(this->fields.structure,  						     fields[i].name);        this->fields.structure[i].location = fields[i].location; +      this->fields.structure[i].interpolation = fields[i].interpolation; +      this->fields.structure[i].centroid = fields[i].centroid;        this->fields.structure[i].row_major = fields[i].row_major;     }  } @@ -126,6 +128,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,        this->fields.structure[i].name = ralloc_strdup(this->fields.structure,  						     fields[i].name);        this->fields.structure[i].location = fields[i].location; +      this->fields.structure[i].interpolation = fields[i].interpolation; +      this->fields.structure[i].centroid = fields[i].centroid;        this->fields.structure[i].row_major = fields[i].row_major;     }  } @@ -455,6 +459,12 @@ glsl_type::record_key_compare(const void *a, const void *b)        if (key1->fields.structure[i].location            != key2->fields.structure[i].location)           return 1; +      if (key1->fields.structure[i].interpolation +          != key2->fields.structure[i].interpolation) +         return 1; +      if (key1->fields.structure[i].centroid +          != key2->fields.structure[i].centroid) +         return 1;     }     return 0; diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index e60c19132..4b5b6efb3 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -590,6 +590,18 @@ struct glsl_struct_field {      * Ignored for structs.      */     int location; + +   /** +    * For interface blocks, the interpolation mode (as in +    * ir_variable::interpolation).  0 otherwise. +    */ +   unsigned interpolation:2; + +   /** +    * For interface blocks, 1 if this variable uses centroid interpolation (as +    * in ir_variable::centroid).  0 otherwise. +    */ +   unsigned centroid:1;  };  static inline unsigned int diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 54a8e400c..c682e3ed5 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1616,9 +1616,9 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,  const char * -ir_variable::interpolation_string() const +interpolation_string(unsigned interpolation)  { -   switch (this->interpolation) { +   switch (interpolation) {     case INTERP_QUALIFIER_NONE:          return "no";     case INTERP_QUALIFIER_SMOOTH:        return "smooth";     case INTERP_QUALIFIER_FLAT:          return "flat"; diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index aac8cbb7d..8d5bec9c1 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -312,6 +312,22 @@ struct ir_state_slot {     int swizzle;  }; + +/** + * Get the string value for an interpolation qualifier + * + * \return The string that would be used in a shader to specify \c + * mode will be returned. + * + * This function is used to generate error messages of the form "shader + * uses %s interpolation qualifier", so in the case where there is no + * interpolation qualifier, it returns "no". + * + * This function should only be used on a shader input or output variable. + */ +const char *interpolation_string(unsigned interpolation); + +  class ir_variable : public ir_instruction {  public:     ir_variable(const struct glsl_type *, const char *, ir_variable_mode); @@ -332,20 +348,6 @@ public:     /** -    * Get the string value for the interpolation qualifier -    * -    * \return The string that would be used in a shader to specify \c -    * mode will be returned. -    * -    * This function is used to generate error messages of the form "shader -    * uses %s interpolation qualifier", so in the case where there is no -    * interpolation qualifier, it returns "no". -    * -    * This function should only be used on a shader input or output variable. -    */ -   const char *interpolation_string() const; - -   /**      * Determine how this variable should be interpolated based on its      * interpolation qualifier (if present), whether it is gl_Color or      * gl_SecondaryColor, and whether flatshading is enabled in the current GL @@ -579,6 +581,24 @@ public:     unsigned location_frac:2;     /** +    * Non-zero if this variable was created by lowering a named interface +    * block which was not an array. +    * +    * Note that this variable and \c from_named_ifc_block_array will never +    * both be non-zero. +    */ +   unsigned from_named_ifc_block_nonarray:1; + +   /** +    * Non-zero if this variable was created by lowering a named interface +    * block which was an array. +    * +    * Note that this variable and \c from_named_ifc_block_nonarray will never +    * both be non-zero. +    */ +   unsigned from_named_ifc_block_array:1; + +   /**      * \brief Layout qualifier for gl_FragDepth.      *      * This is not equal to \c ir_depth_layout_none if and only if this diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 4bd4034a0..ea71b3063 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -75,7 +75,63 @@ program_resource_visitor::process(ir_variable *var)      */     /* Only strdup the name if we actually will need to modify it. */ -   if (t->is_record() || (t->is_array() && t->fields.array->is_record())) { +   if (var->from_named_ifc_block_array) { +      /* lower_named_interface_blocks created this variable by lowering an +       * interface block array to an array variable.  For example if the +       * original source code was: +       * +       *     out Blk { vec4 bar } foo[3]; +       * +       * Then the variable is now: +       * +       *     out vec4 bar[3]; +       * +       * We need to visit each array element using the names constructed like +       * so: +       * +       *     Blk[0].bar +       *     Blk[1].bar +       *     Blk[2].bar +       */ +      assert(t->is_array()); +      const glsl_type *ifc_type = var->get_interface_type(); +      char *name = ralloc_strdup(NULL, ifc_type->name); +      size_t name_length = strlen(name); +      for (unsigned i = 0; i < t->length; i++) { +         size_t new_length = name_length; +         ralloc_asprintf_rewrite_tail(&name, &new_length, "[%u].%s", i, +                                      var->name); +         /* Note: row_major is only meaningful for uniform blocks, and +          * lowering is only applied to non-uniform interface blocks, so we +          * can safely pass false for row_major. +          */ +         recursion(var->type, &name, new_length, false, NULL); +      } +      ralloc_free(name); +   } else if (var->from_named_ifc_block_nonarray) { +      /* lower_named_interface_blocks created this variable by lowering a +       * named interface block (non-array) to an ordinary variable.  For +       * example if the original source code was: +       * +       *     out Blk { vec4 bar } foo; +       * +       * Then the variable is now: +       * +       *     out vec4 bar; +       * +       * We need to visit this variable using the name: +       * +       *     Blk.bar +       */ +      const glsl_type *ifc_type = var->get_interface_type(); +      char *name = ralloc_asprintf(NULL, "%s.%s", ifc_type->name, var->name); +      /* Note: row_major is only meaningful for uniform blocks, and lowering +       * is only applied to non-uniform interface blocks, so we can safely +       * pass false for row_major. +       */ +      recursion(var->type, &name, strlen(name), false, NULL); +      ralloc_free(name); +   } else if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {        char *name = ralloc_strdup(NULL, var->name);        recursion(var->type, &name, strlen(name), false, NULL);        ralloc_free(name); diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp index 4ba6d8a20..be36b5f8f 100644 --- a/mesalib/src/glsl/link_varyings.cpp +++ b/mesalib/src/glsl/link_varyings.cpp @@ -125,9 +125,9 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,                     "interpolation qualifier\n",                     _mesa_glsl_shader_target_name(producer_type),                     output->name, -                   output->interpolation_string(), +                   interpolation_string(output->interpolation),                     _mesa_glsl_shader_target_name(consumer_type), -                   input->interpolation_string()); +                   interpolation_string(input->interpolation));        return;     }  } @@ -328,7 +328,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx,        const unsigned vector_elements =           this->matched_candidate->type->fields.array->vector_elements;        unsigned actual_array_size = this->is_clip_distance_mesa ? -         prog->Vert.ClipDistanceArraySize : +         prog->LastClipDistanceArraySize :           this->matched_candidate->type->array_size();        if (this->is_subscripted) { diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index b23c31a16..d8f655c39 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -2100,6 +2100,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)        validate_vertex_shader_executable(prog, sh);        if (!prog->LinkStatus)  	 goto done; +      prog->LastClipDistanceArraySize = prog->Vert.ClipDistanceArraySize;        _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX],  			     sh); @@ -2132,6 +2133,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)        validate_geometry_shader_executable(prog, sh);        if (!prog->LinkStatus)  	 goto done; +      prog->LastClipDistanceArraySize = prog->Geom.ClipDistanceArraySize;        _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_GEOMETRY],  			     sh); diff --git a/mesalib/src/glsl/lower_named_interface_blocks.cpp b/mesalib/src/glsl/lower_named_interface_blocks.cpp index f415252ba..d59d11150 100644 --- a/mesalib/src/glsl/lower_named_interface_blocks.cpp +++ b/mesalib/src/glsl/lower_named_interface_blocks.cpp @@ -140,6 +140,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)                    new(mem_ctx) ir_variable(iface_t->fields.structure[i].type,                                             var_name,                                             (ir_variable_mode) var->mode); +               new_var->from_named_ifc_block_nonarray = 1;              } else {                 const glsl_type *new_array_type =                    glsl_type::get_array_instance( @@ -149,8 +150,13 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)                    new(mem_ctx) ir_variable(new_array_type,                                             var_name,                                             (ir_variable_mode) var->mode); +               new_var->from_named_ifc_block_array = 1;              }              new_var->location = iface_t->fields.structure[i].location; +            new_var->explicit_location = (new_var->location >= 0); +            new_var->interpolation = +               iface_t->fields.structure[i].interpolation; +            new_var->centroid = iface_t->fields.structure[i].centroid;              new_var->init_interface_type(iface_t);              hash_table_insert(interface_namespace, new_var, diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am index e9c16e78e..f86caee35 100644 --- a/mesalib/src/mesa/Makefile.am +++ b/mesalib/src/mesa/Makefile.am @@ -19,11 +19,7 @@  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS  # IN THE SOFTWARE. -if NEED_LIBDRICORE -DRICORE_SUBDIR = libdricore -endif - -SUBDIRS = program x86 x86-64 . $(DRICORE_SUBDIR) main/tests +SUBDIRS = program x86 x86-64 . main/tests  if HAVE_X11_DRIVER  SUBDIRS += drivers/x11 diff --git a/mesalib/src/mesa/drivers/dri/Makefile.am b/mesalib/src/mesa/drivers/dri/Makefile.am index 7fa0ad73d..a85a5aa91 100644 --- a/mesalib/src/mesa/drivers/dri/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/Makefile.am @@ -1,29 +1,45 @@ +dridir = $(DRI_DRIVER_INSTALL_DIR) +  SUBDIRS = +MEGADRIVERS = +MEGADRIVERS_DEPS =  SUBDIRS+=common  if HAVE_I915_DRI -SUBDIRS+=i915 +SUBDIRS += i915 +MEGADRIVERS_DEPS += i915/libi915_dri.la +MEGADRIVERS += i915_dri.so  endif  if HAVE_I965_DRI -SUBDIRS+=i965 +SUBDIRS += i965 +MEGADRIVERS_DEPS += i965/libi965_dri.la +MEGADRIVERS += i965_dri.so  endif  if HAVE_NOUVEAU_DRI -SUBDIRS+=nouveau +SUBDIRS += nouveau +MEGADRIVERS_DEPS += nouveau/libnouveau_dri.la +MEGADRIVERS += nouveau_vieux_dri.so  endif  if HAVE_R200_DRI -SUBDIRS+=r200 +SUBDIRS += r200 +MEGADRIVERS_DEPS += r200/libr200_dri.la +MEGADRIVERS += r200_dri.so  endif  if HAVE_RADEON_DRI -SUBDIRS+=radeon +SUBDIRS += radeon +MEGADRIVERS_DEPS += radeon/libradeon_dri.la +MEGADRIVERS += radeon_dri.so  endif  if HAVE_SWRAST_DRI -SUBDIRS+=swrast +SUBDIRS += swrast +MEGADRIVERS_DEPS += swrast/libswrast_dri.la +MEGADRIVERS += swrast_dri.so  endif  pkgconfigdir = $(libdir)/pkgconfig @@ -31,3 +47,42 @@ pkgconfig_DATA = dri.pc  driincludedir = $(includedir)/GL/internal  driinclude_HEADERS = $(top_srcdir)/include/GL/internal/dri_interface.h + +nodist_EXTRA_mesa_dri_drivers_la_SOURCES = dummy.cpp +mesa_dri_drivers_la_SOURCES = +mesa_dri_drivers_la_LDFLAGS = \ +        -module -avoid-version -shared \ +        -Wl,-Bsymbolic \ +        $() +mesa_dri_drivers_la_LIBADD = \ +        ../../libmesa.la \ +        common/libmegadriver_stub.la \ +        common/libdricommon.la \ +        $(MEGADRIVERS_DEPS) \ +        $(DRI_LIB_DEPS) \ +        $() + +if NEED_MEGADRIVER +dri_LTLIBRARIES = mesa_dri_drivers.la + +# Add a link to allow setting LD_LIBRARY_PATH/LIBGL_DRIVERS_PATH to /lib of the build tree. +all-local: mesa_dri_drivers.la +	$(MKDIR_P) $(top_builddir)/$(LIB_DIR); +	$(AM_V_GEN)ln -f .libs/mesa_dri_drivers.so \ +			 $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so; +	$(AM_V_GEN)for i in $(MEGADRIVERS); do \ +		ln -f $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so \ +		      $(top_builddir)/$(LIB_DIR)/$$i; \ +	done; + +# hardlink each megadriver instance, but don't actually have +# mesa_dri_drivers.so in the set of final installed files. +install-data-hook: +	for i in $(MEGADRIVERS); do \ +		ln -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so \ +		      $(DESTDIR)$(dridir)/$$i; \ +	done; +	$(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so +	$(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.la + +endif diff --git a/mesalib/src/mesa/drivers/dri/common/Makefile.am b/mesalib/src/mesa/drivers/dri/common/Makefile.am index ce4119d0f..9f49ff3ae 100644 --- a/mesalib/src/mesa/drivers/dri/common/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/common/Makefile.am @@ -27,11 +27,11 @@ AM_CFLAGS = \  	-I$(top_srcdir)/src/mapi \  	-I$(top_srcdir)/src/mesa/ \  	$(DEFINES) \ -	$(LIBDRM_CFLAGS) \  	$(VISIBILITY_CFLAGS)  noinst_LTLIBRARIES = \  	libdricommon.la \ +	libmegadriver_stub.la \  	libdri_test_stubs.la  libdricommon_la_SOURCES = \ @@ -43,4 +43,13 @@ libdri_test_stubs_la_SOURCES = \  	dri_test.c  libdri_test_stubs_la_CFLAGS = $(AM_CFLAGS) -DNO_MAIN +libmegadriver_stub_la_SOURCES = megadriver_stub.c +  sysconf_DATA = drirc + +if DRICOMMON_NEED_LIBDRM +AM_CFLAGS += $(LIBDRM_CFLAGS) +libdricommon_la_LDFLAGS = $(LIBDRM_LIBS) +else +AM_CFLAGS += -D__NOT_HAVE_DRM_H +endif diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index db44eede6..c28b0fc41 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -82,6 +82,23 @@ setupLoaderExtensions(__DRIscreen *psp,  }  /** + * This pointer determines which driver API we'll use in the case of the + * loader not passing us an explicit driver extensions list (that would, + * itself, contain a pointer to a driver API.) + * + * A driver's driDriverGetExtensions_drivername() can update this pointer to + * what it's returning, and a loader that is ignorant of createNewScreen2() + * will get the correct driver screen created, as long as no other + * driDriverGetExtensions() happened in between the first one and the + * createNewScreen(). + * + * This allows the X Server to not require the significant dri_interface.h + * updates for doing createNewScreen2(), which would discourage backporting of + * the X Server patches to support the new loader interface. + */ +const struct __DriverAPIRec *globalDriverAPI = &driDriverAPI; + +/**   * This is the first entrypoint in the driver called by the DRI driver loader   * after dlopen()ing it.   * @@ -89,9 +106,10 @@ setupLoaderExtensions(__DRIscreen *psp,   * Display.   */  static __DRIscreen * -dri2CreateNewScreen(int scrn, int fd, -		    const __DRIextension **extensions, -		    const __DRIconfig ***driver_configs, void *data) +dri2CreateNewScreen2(int scrn, int fd, +                     const __DRIextension **extensions, +                     const __DRIextension **driver_extensions, +                     const __DRIconfig ***driver_configs, void *data)  {      static const __DRIextension *emptyExtensionList[] = { NULL };      __DRIscreen *psp; @@ -100,7 +118,20 @@ dri2CreateNewScreen(int scrn, int fd,      if (!psp)  	return NULL; -    psp->driver = &driDriverAPI; +    /* By default, use the global driDriverAPI symbol (non-megadrivers). */ +    psp->driver = globalDriverAPI; + +    /* If the driver exposes its vtable through its extensions list +     * (megadrivers), use that instead. +     */ +    if (driver_extensions) { +       for (int i = 0; driver_extensions[i]; i++) { +          if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) { +             psp->driver = +                ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable; +          } +       } +    }      setupLoaderExtensions(psp, extensions); @@ -154,12 +185,31 @@ dri2CreateNewScreen(int scrn, int fd,      return psp;  } +static __DRIscreen * +dri2CreateNewScreen(int scrn, int fd, +		    const __DRIextension **extensions, +		    const __DRIconfig ***driver_configs, void *data) +{ +   return dri2CreateNewScreen2(scrn, fd, extensions, NULL, +                               driver_configs, data); +} +  /** swrast driver createNewScreen entrypoint. */  static __DRIscreen * -driCreateNewScreen(int scrn, const __DRIextension **extensions, -		   const __DRIconfig ***driver_configs, void *data) +driSWRastCreateNewScreen(int scrn, const __DRIextension **extensions, +                         const __DRIconfig ***driver_configs, void *data) +{ +   return dri2CreateNewScreen2(scrn, -1, extensions, NULL, +                               driver_configs, data); +} + +static __DRIscreen * +driSWRastCreateNewScreen2(int scrn, const __DRIextension **extensions, +                          const __DRIextension **driver_extensions, +                          const __DRIconfig ***driver_configs, void *data)  { -   return dri2CreateNewScreen(scrn, -1, extensions, driver_configs, data); +   return dri2CreateNewScreen2(scrn, -1, extensions, driver_extensions, +                               driver_configs, data);  }  /** @@ -688,7 +738,7 @@ const __DRIcoreExtension driCoreExtension = {  /** DRI2 interface */  const __DRIdri2Extension driDRI2Extension = { -    .base = { __DRI_DRI2, 3 }, +    .base = { __DRI_DRI2, 4 },      .createNewScreen            = dri2CreateNewScreen,      .createNewDrawable          = dri2CreateNewDrawable, @@ -697,15 +747,17 @@ const __DRIdri2Extension driDRI2Extension = {      .createNewContextForAPI     = dri2CreateNewContextForAPI,      .allocateBuffer             = dri2AllocateBuffer,      .releaseBuffer              = dri2ReleaseBuffer, -    .createContextAttribs       = dri2CreateContextAttribs +    .createContextAttribs       = dri2CreateContextAttribs, +    .createNewScreen2           = dri2CreateNewScreen2,  };  const __DRIswrastExtension driSWRastExtension = { -    { __DRI_SWRAST, __DRI_SWRAST_VERSION }, -    driCreateNewScreen, +    { __DRI_SWRAST, 4 }, +    driSWRastCreateNewScreen,      dri2CreateNewDrawable,      dri2CreateNewContextForAPI, -    dri2CreateContextAttribs +    dri2CreateContextAttribs, +    driSWRastCreateNewScreen2,  };  const __DRI2configQueryExtension dri2ConfigQueryExtension = { diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h index 61c80bc45..5b56061e2 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.h +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h @@ -116,7 +116,7 @@ struct __DriverAPIRec {  };  extern const struct __DriverAPIRec driDriverAPI; - +extern const struct __DriverAPIRec *globalDriverAPI;  /**   * Per-screen private driver information. diff --git a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c new file mode 100644 index 000000000..6bf5d7327 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c @@ -0,0 +1,41 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <stdio.h> +#include "dri_util.h" + +static const +__DRIconfig **stub_error_init_screen(__DRIscreen *psp) +{ +   fprintf(stderr, "An updated DRI driver loader (libGL.so or X Server) is " +           "required for this Mesa driver.\n"); +   return NULL; +} + +/** + * This is a stub driDriverAPI that is referenced by dri_util.c but should + * never be used. + */ +const struct __DriverAPIRec driDriverAPI = { +   .InitScreen = stub_error_init_screen, +}; diff --git a/mesalib/src/mesa/drivers/dri/gen-symbol-redefs.py b/mesalib/src/mesa/drivers/dri/gen-symbol-redefs.py new file mode 100644 index 000000000..ebe4aaa65 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/gen-symbol-redefs.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright © 2013 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +import sys +import argparse +import re +import subprocess + +# Example usages: +# ./gen-symbol-redefs.py i915/.libs/libi915_dri.a old_ i915 i830 +# ./gen-symbol-redefs.py r200/.libs/libr200_dri.a r200_ r200 + +argparser = argparse.ArgumentParser(description="Generates #defines to hide driver global symbols outside of a driver's namespace.") +argparser.add_argument("file", +                    metavar = 'file', +                    help='libdrivername.a file to read') +argparser.add_argument("newprefix", +                    metavar = 'newprefix', +                    help='New prefix to give non-driver global symbols') +argparser.add_argument('prefixes', +                       metavar='prefix', +                       nargs='*', +                       help='driver-specific prefixes') +args = argparser.parse_args() + +stdout = subprocess.check_output(['nm', args.file]) + +for line in stdout.splitlines(): +    m = re.match("[0-9a-z]+ [BT] (.*)", line) +    if not m: +        continue + +    symbol = m.group(1) + +    has_good_prefix = re.match(args.newprefix, symbol) != None +    for prefix in args.prefixes: +        if re.match(prefix, symbol): +            has_good_prefix = True +            break +    if has_good_prefix: +        continue + +    # This is the single public entrypoint. +    if re.match("__driDriverGetExtensions", symbol): +        continue + +    print '#define {0:35} {1}{0}'.format(symbol, args.newprefix) diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am index c51ad2d87..0837b4518 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am @@ -34,19 +34,5 @@ AM_CFLAGS = \  	$(DEFINES) \  	$(VISIBILITY_CFLAGS) -dridir = $(DRI_DRIVER_INSTALL_DIR) -dri_LTLIBRARIES = swrast_dri.la - -swrast_dri_la_SOURCES = \ -	$(SWRAST_C_FILES) - -swrast_dri_la_LDFLAGS = $(DRI_DRIVER_LDFLAGS) - -swrast_dri_la_LIBADD = \ -	$(DRI_LIB_DEPS) - -# Provide compatibility with scripts for the old Mesa build system for -# a while by putting a link to the driver into /lib of the build tree. -all-local: swrast_dri.la -	$(MKDIR_P) $(top_builddir)/$(LIB_DIR); -	ln -f .libs/swrast_dri.so $(top_builddir)/$(LIB_DIR)/swrast_dri.so; +noinst_LTLIBRARIES = libswrast_dri.la +libswrast_dri_la_SOURCES = $(SWRAST_C_FILES) diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources index fc7ef32db..70e432feb 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources +++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources @@ -1,11 +1,5 @@  SWRAST_DRIVER_FILES = \  	swrast.c  -SWRAST_COMMON_FILES = \ -	../common/utils.c \ -	../common/dri_util.c \ -	../common/xmlconfig.c -  SWRAST_C_FILES = \ -	$(SWRAST_COMMON_FILES) \  	$(SWRAST_DRIVER_FILES) diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index 4725a7f42..bfa2efd21 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -59,6 +59,7 @@  #include "swrast_priv.h"  #include "swrast/s_context.h" +const __DRIextension **__driDriverGetExtensions_swrast(void);  /**   * Screen and config-related functions @@ -819,7 +820,7 @@ dri_unbind_context(__DRIcontext * cPriv)  } -const struct __DriverAPIRec driDriverAPI = { +static const struct __DriverAPIRec swrast_driver_api = {      .InitScreen = dri_init_screen,      .DestroyScreen = dri_destroy_screen,      .CreateContext = dri_create_context, @@ -831,9 +832,21 @@ const struct __DriverAPIRec driDriverAPI = {      .UnbindContext = dri_unbind_context,  }; -/* This is the table of extensions that the loader will dlsym() for. */ -PUBLIC const __DRIextension *__driDriverExtensions[] = { +static const struct __DRIDriverVtableExtensionRec swrast_vtable = { +   .base = { __DRI_DRIVER_VTABLE, 1 }, +   .vtable = &swrast_driver_api, +}; + +static const __DRIextension *swrast_driver_extensions[] = {      &driCoreExtension.base,      &driSWRastExtension.base, +    &swrast_vtable.base,      NULL  }; + +PUBLIC const __DRIextension **__driDriverGetExtensions_swrast(void) +{ +   globalDriverAPI = &swrast_driver_api; + +   return swrast_driver_extensions; +} diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 6374e8c0d..97ed1bd6a 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1965,6 +1965,12 @@ struct gl_program     GLboolean UsesGather; /**< Does this program use gather4 at all? */ +   /** +    * For vertex and geometry shaders, true if the program uses the +    * gl_ClipDistance output.  Ignored for fragment shaders. +    */ +   GLboolean UsesClipDistanceOut; +     /** Named parameters, constants, etc. from program text */     struct gl_program_parameter_list *Parameters; @@ -2009,7 +2015,6 @@ struct gl_vertex_program  {     struct gl_program Base;   /**< base class */     GLboolean IsPositionInvariant; -   GLboolean UsesClipDistance;  }; @@ -2023,7 +2028,6 @@ struct gl_geometry_program     GLenum InputType;  /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,                             GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */     GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ -   GLboolean UsesClipDistance;     GLboolean UsesEndPrimitive;  }; @@ -2476,6 +2480,12 @@ struct gl_shader_program     unsigned NumUserUniformStorage;     struct gl_uniform_storage *UniformStorage; +   /** +    * Size of the gl_ClipDistance array that is output from the last pipeline +    * stage before the fragment shader. +    */ +   unsigned LastClipDistanceArraySize; +     struct gl_uniform_block *UniformBlocks;     unsigned NumUniformBlocks; diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index d3677c851..f5c04b9f3 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -460,6 +460,31 @@ get_handle(struct gl_context *ctx, GLenum pname)  /** + * Check if a geometry shader query is valid at this time.  If not, report an + * error and return false. + * + * From GL 3.2 section 6.1.16 (Shader and Program Queries): + * + *     "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE + *     are queried for a program which has not been linked successfully, or + *     which does not contain objects to form a geometry shader, then an + *     INVALID_OPERATION error is generated." + */ +static bool +check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg) +{ +   if (shProg->LinkStatus && +       shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { +      return true; +   } + +   _mesa_error(ctx, GL_INVALID_OPERATION, +               "glGetProgramv(linked geometry shader required)"); +   return false; +} + + +/**   * glGetProgramiv() - get shader program state.   * Note that this is for GLSL shader programs, not ARB vertex/fragment   * programs (see glGetProgramivARB). @@ -477,9 +502,10 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param        || ctx->API == API_OPENGL_CORE        || _mesa_is_gles3(ctx); -   /* Are geometry shaders available in this context? +   /* True if geometry shaders (of the form that was adopted into GLSL 1.50 +    * and GL 3.2) are available in this context      */ -   const bool has_gs = _mesa_has_geometry_shaders(ctx); +   const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32;     /* Are uniform buffer objects available in this context?      */ @@ -564,20 +590,23 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param           break;        *params = shProg->TransformFeedback.BufferMode;        return; -   case GL_GEOMETRY_VERTICES_OUT_ARB: -      if (!has_gs) +   case GL_GEOMETRY_VERTICES_OUT: +      if (!has_core_gs)           break; -      *params = shProg->Geom.VerticesOut; +      if (check_gs_query(ctx, shProg)) +         *params = shProg->Geom.VerticesOut;        return; -   case GL_GEOMETRY_INPUT_TYPE_ARB: -      if (!has_gs) +   case GL_GEOMETRY_INPUT_TYPE: +      if (!has_core_gs)           break; -      *params = shProg->Geom.InputType; +      if (check_gs_query(ctx, shProg)) +         *params = shProg->Geom.InputType;        return; -   case GL_GEOMETRY_OUTPUT_TYPE_ARB: -      if (!has_gs) +   case GL_GEOMETRY_OUTPUT_TYPE: +      if (!has_core_gs)           break; -      *params = shProg->Geom.OutputType; +      if (check_gs_query(ctx, shProg)) +         *params = shProg->Geom.OutputType;        return;     case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {        unsigned i; @@ -1631,55 +1660,6 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)        return;     switch (pname) { -   case GL_GEOMETRY_VERTICES_OUT_ARB: -      if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4) -         break; - -      if (value < 0 || -          (unsigned) value > ctx->Const.MaxGeometryOutputVertices) { -         _mesa_error(ctx, GL_INVALID_VALUE, -                     "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d)", -                     value); -         return; -      } -      shProg->Geom.VerticesOut = value; -      return; -   case GL_GEOMETRY_INPUT_TYPE_ARB: -      if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4) -         break; - -      switch (value) { -      case GL_POINTS: -      case GL_LINES: -      case GL_LINES_ADJACENCY_ARB: -      case GL_TRIANGLES: -      case GL_TRIANGLES_ADJACENCY_ARB: -         shProg->Geom.InputType = value; -         break; -      default: -         _mesa_error(ctx, GL_INVALID_VALUE, -                     "glProgramParameteri(geometry input type = %s)", -                     _mesa_lookup_enum_by_nr(value)); -         return; -      } -      return; -   case GL_GEOMETRY_OUTPUT_TYPE_ARB: -      if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4) -         break; - -      switch (value) { -      case GL_POINTS: -      case GL_LINE_STRIP: -      case GL_TRIANGLE_STRIP: -         shProg->Geom.OutputType = value; -         break; -      default: -         _mesa_error(ctx, GL_INVALID_VALUE, -                     "glProgramParameteri(geometry output type = %s)", -                     _mesa_lookup_enum_by_nr(value)); -         return; -      } -      return;     case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:        /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it         * is part of OpenGL ES 3.0.  For the ES2 case, this function shouldn't @@ -1855,10 +1835,8 @@ _mesa_copy_linked_program_data(gl_shader_type type,                                 struct gl_program *dst)  {     switch (type) { -   case MESA_SHADER_VERTEX: { -      struct gl_vertex_program *dst_vp = (struct gl_vertex_program *) dst; -      dst_vp->UsesClipDistance = src->Vert.UsesClipDistance; -   } +   case MESA_SHADER_VERTEX: +      dst->UsesClipDistanceOut = src->Vert.UsesClipDistance;        break;     case MESA_SHADER_GEOMETRY: {        struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst; @@ -1866,7 +1844,7 @@ _mesa_copy_linked_program_data(gl_shader_type type,        dst_gp->VerticesOut = src->Geom.VerticesOut;        dst_gp->InputType = src->Geom.InputType;        dst_gp->OutputType = src->Geom.OutputType; -      dst_gp->UsesClipDistance = src->Geom.UsesClipDistance; +      dst->UsesClipDistanceOut = src->Geom.UsesClipDistance;        dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;     }        break; diff --git a/mesalib/src/mesa/program/Makefile.am b/mesalib/src/mesa/program/Makefile.am index ab565e251..5e05782fb 100644 --- a/mesalib/src/mesa/program/Makefile.am +++ b/mesalib/src/mesa/program/Makefile.am @@ -24,25 +24,13 @@ include ../Makefile.sources  AM_CPPFLAGS = $(DEFINES) $(INCLUDE_DIRS)  AM_CFLAGS = $(VISIBILITY_CFLAGS)  AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS) -libdricore_program_la_CFLAGS = $(NOVISIBILITY_CFLAGS) -libdricore_program_la_CXXFLAGS = $(NOVISIBILITY_CXXFLAGS)  SRCDIR = $(top_srcdir)/src/mesa/  BUILDDIR = $(top_builddir)/src/mesa/ -if NEED_LIBDRICORE -DRICORE_LIB = libdricore_program.la -endif - -noinst_LTLIBRARIES = $(DRICORE_LIB) -if NEED_LIBPROGRAM -noinst_LTLIBRARIES += libprogram.la -else -check_LTLIBRARIES = libprogram.la -endif +noinst_LTLIBRARIES = libprogram.la  libprogram_la_SOURCES = $(PROGRAM_FILES) -libdricore_program_la_SOURCES = $(PROGRAM_FILES)  lex.yy.c: program_lexer.l  	$(AM_V_GEN) $(LEX) --never-interactive --outfile=$@ $< diff --git a/mesalib/src/mesa/x86/read_rgba_span_x86.S b/mesalib/src/mesa/x86/read_rgba_span_x86.S index 3be4515b1..817729973 100644 --- a/mesalib/src/mesa/x86/read_rgba_span_x86.S +++ b/mesalib/src/mesa/x86/read_rgba_span_x86.S @@ -77,9 +77,7 @@   */  .globl _generic_read_RGBA_span_BGRA8888_REV_MMX -#ifndef USE_DRICORE  .hidden _generic_read_RGBA_span_BGRA8888_REV_MMX -#endif  	.type	_generic_read_RGBA_span_BGRA8888_REV_MMX, @function  _generic_read_RGBA_span_BGRA8888_REV_MMX:  	pushl	%ebx @@ -174,9 +172,7 @@ _generic_read_RGBA_span_BGRA8888_REV_MMX:   */  .globl _generic_read_RGBA_span_BGRA8888_REV_SSE -#ifndef USE_DRICORE  .hidden _generic_read_RGBA_span_BGRA8888_REV_SSE -#endif  	.type	_generic_read_RGBA_span_BGRA8888_REV_SSE, @function  _generic_read_RGBA_span_BGRA8888_REV_SSE:  	pushl	%esi @@ -339,9 +335,7 @@ _generic_read_RGBA_span_BGRA8888_REV_SSE:  	.text  .globl _generic_read_RGBA_span_BGRA8888_REV_SSE2 -#ifndef USE_DRICORE  .hidden _generic_read_RGBA_span_BGRA8888_REV_SSE2 -#endif  	.type	_generic_read_RGBA_span_BGRA8888_REV_SSE2, @function  _generic_read_RGBA_span_BGRA8888_REV_SSE2:  	pushl	%esi @@ -500,9 +494,7 @@ _generic_read_RGBA_span_BGRA8888_REV_SSE2:  	.text  	.globl	_generic_read_RGBA_span_RGB565_MMX -#ifndef USE_DRICORE          .hidden _generic_read_RGBA_span_RGB565_MMX -#endif  	.type	_generic_read_RGBA_span_RGB565_MMX, @function  _generic_read_RGBA_span_RGB565_MMX: | 
