diff options
Diffstat (limited to 'mesalib')
26 files changed, 729 insertions, 231 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 1fd02ebf5..f074dbe44 100644 --- a/mesalib/include/GL/internal/dri_interface.h +++ b/mesalib/include/GL/internal/dri_interface.h @@ -332,12 +332,6 @@ struct __DRI2throttleExtensionRec { enum __DRI2throttleReason reason); }; -/** - * XML document describing the configuration options supported by the - * driver. - */ -extern const char __driConfigOptions[]; - /*@}*/ /** @@ -498,6 +492,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. @@ -710,7 +717,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; @@ -746,6 +753,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); + }; /** @@ -828,7 +847,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 */ @@ -936,6 +955,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); }; @@ -1230,4 +1260,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 baea837b5..51ca593ff 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 74f3a5d99..7f84e6496 100644..100755 --- 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,19 +106,33 @@ 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; - int gl_version_override; + int gl_version_override; psp = calloc(1, sizeof(*psp)); 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); @@ -155,12 +186,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); } /** @@ -257,8 +307,8 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, unsigned major_version = 1; unsigned minor_version = 0; uint32_t flags = 0; - unsigned i; - struct gl_context *ctx; + unsigned i; + struct gl_context *ctx; assert((num_attribs == 0) || (attribs != NULL)); @@ -691,7 +741,7 @@ const __DRIcoreExtension driCoreExtension = { /** DRI2 interface */ const __DRIdri2Extension driDRI2Extension = { - /*.base =*/ { __DRI_DRI2, 3 }, + /*.base =*/ { __DRI_DRI2, 4 }, /*.createNewScreen =*/ dri2CreateNewScreen, /*.createNewDrawable =*/ dri2CreateNewDrawable, @@ -700,15 +750,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 dde868864..fa7d695ab 100644..100755 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -64,6 +64,7 @@ #include "swrast_priv.h" #include "swrast/s_context.h" +const __DRIextension **__driDriverGetExtensions_swrast(void); /** * Screen and config-related functions @@ -824,7 +825,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, @@ -836,9 +837,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: |