diff options
Diffstat (limited to 'mesalib')
28 files changed, 413 insertions, 124 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac index 0dcd2a51f..40e052c62 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -580,6 +580,11 @@ AC_ARG_ENABLE([osmesa], [enable OSMesa library @<:@default=disabled@:>@])], [enable_osmesa="$enableval"], [enable_osmesa=no]) +AC_ARG_ENABLE([gallium-osmesa], + [AS_HELP_STRING([--enable-gallium-osmesa], + [enable Gallium implementation of the OSMesa library @<:@default=disabled@:>@])], + [enable_gallium_osmesa="$enableval"], + [enable_gallium_osmesa=no]) AC_ARG_ENABLE([egl], [AS_HELP_STRING([--disable-egl], [disable EGL library @<:@default=enabled@:>@])], @@ -770,7 +775,13 @@ if test "x$enable_dri" = xyes; then GALLIUM_STATE_TRACKERS_DIRS="dri $GALLIUM_STATE_TRACKERS_DIRS" fi -if test "x$enable_osmesa" = xyes; then +if test "x$enable_gallium_osmesa" = xyes; then + if test -z "$with_gallium_drivers"; then + AC_MSG_ERROR([Cannot enable gallium_osmesa without Gallium]) + fi + if test "x$enable_osmesa" = xyes; then + AC_MSG_ERROR([Cannot enable both classic and Gallium OSMesa implementations]) + fi GALLIUM_STATE_TRACKERS_DIRS="osmesa $GALLIUM_STATE_TRACKERS_DIRS" GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS osmesa" fi @@ -1136,7 +1147,7 @@ x16|x32) ;; esac -if test "x$enable_osmesa" = xyes; then +if test "x$enable_osmesa" = xyes -o "x$enable_gallium_osmesa" = xyes; then # only link libraries with osmesa if shared if test "$enable_static" = no; then OSMESA_LIB_DEPS="-lm $PTHREAD_LIBS $SELINUX_LIBS $DLOPEN_LIBS" @@ -1962,9 +1973,11 @@ 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) + "x$enable_osmesa" = xyes -o \ + "x$enable_gallium_osmesa" = 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) AM_CONDITIONAL(HAVE_X86_ASM, echo "$DEFINES" | grep 'X86_ASM' >/dev/null 2>&1) AM_CONDITIONAL(HAVE_X86_64_ASM, echo "$DEFINES" | grep 'X86_64_ASM' >/dev/null 2>&1) @@ -2053,6 +2066,7 @@ AC_CONFIG_FILES([Makefile src/gallium/targets/gbm/Makefile src/gallium/targets/opencl/Makefile src/gallium/targets/osmesa/Makefile + src/gallium/targets/osmesa/osmesa.pc src/gallium/targets/pipe-loader/Makefile src/gallium/targets/libgl-xlib/Makefile src/gallium/targets/vdpau-nouveau/Makefile @@ -2151,11 +2165,17 @@ echo " OpenVG: $enable_openvg" dnl Driver info echo "" -if test "x$enable_osmesa" != xno; then +case "x$enable_osmesa$enable_gallium_osmesa" in +xnoyes) + echo " OSMesa: lib$OSMESA_LIB (Gallium)" + ;; +xyesno) echo " OSMesa: lib$OSMESA_LIB" -else + ;; +xnono) echo " OSMesa: no" -fi + ;; +esac if test "x$enable_dri" != xno; then # cleanup the drivers var diff --git a/mesalib/src/gallium/auxiliary/Makefile.am b/mesalib/src/gallium/auxiliary/Makefile.am index f14279b4f..670e1248d 100644 --- a/mesalib/src/gallium/auxiliary/Makefile.am +++ b/mesalib/src/gallium/auxiliary/Makefile.am @@ -38,13 +38,17 @@ libgallium_la_SOURCES += \ endif indices/u_indices_gen.c: $(srcdir)/indices/u_indices_gen.py + $(MKDIR_P) indices $(AM_V_GEN) $(PYTHON2) $< > $@ indices/u_unfilled_gen.c: $(srcdir)/indices/u_unfilled_gen.py + $(MKDIR_P) indices $(AM_V_GEN) $(PYTHON2) $< > $@ util/u_format_srgb.c: $(srcdir)/util/u_format_srgb.py + $(MKDIR_P) util $(AM_V_GEN) $(PYTHON2) $< > $@ util/u_format_table.c: $(srcdir)/util/u_format_table.py $(srcdir)/util/u_format_pack.py $(srcdir)/util/u_format_parse.py $(srcdir)/util/u_format.csv + $(MKDIR_P) util $(AM_V_GEN) $(PYTHON2) $(srcdir)/util/u_format_table.py $(srcdir)/util/u_format.csv > $@ diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c index 87ad78095..2ff40bb00 100644 --- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c +++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c @@ -212,6 +212,44 @@ cpuid(uint32_t ax, uint32_t *p) #endif } +/** + * @sa cpuid.h included in gcc-4.4 onwards. + * @sa http://msdn.microsoft.com/en-us/library/hskdteyh%28v=vs.90%29.aspx + */ +static INLINE void +cpuid_count(uint32_t ax, uint32_t cx, uint32_t *p) +{ +#if (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86) + __asm __volatile ( + "xchgl %%ebx, %1\n\t" + "cpuid\n\t" + "xchgl %%ebx, %1" + : "=a" (p[0]), + "=S" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax), "2" (cx) + ); +#elif (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86_64) + __asm __volatile ( + "cpuid\n\t" + : "=a" (p[0]), + "=b" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax), "2" (cx) + ); +#elif defined(PIPE_CC_MSVC) + __cpuidex(p, ax, cx); +#else + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; +#endif +} + + static INLINE uint64_t xgetbv(void) { #if defined(PIPE_CC_GCC) @@ -341,6 +379,11 @@ util_cpu_detect(void) if (cacheline > 0) util_cpu_caps.cacheline = cacheline; } + if (util_cpu_caps.has_avx && regs[0] >= 0x00000007) { + uint32_t regs7[4]; + cpuid_count(0x00000007, 0x00000000, regs7); + util_cpu_caps.has_avx2 = (regs7[1] >> 5) & 1; + } if (regs[1] == 0x756e6547 && regs[2] == 0x6c65746e && regs[3] == 0x49656e69) { /* GenuineIntel */ @@ -357,6 +400,9 @@ util_cpu_detect(void) util_cpu_caps.has_mmx2 |= (regs2[3] >> 22) & 1; util_cpu_caps.has_3dnow = (regs2[3] >> 31) & 1; util_cpu_caps.has_3dnow_ext = (regs2[3] >> 30) & 1; + + util_cpu_caps.has_xop = util_cpu_caps.has_avx && + ((regs2[2] >> 11) & 1); } if (regs[0] >= 0x80000006) { @@ -394,10 +440,12 @@ util_cpu_detect(void) debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); debug_printf("util_cpu_caps.has_sse4_2 = %u\n", util_cpu_caps.has_sse4_2); debug_printf("util_cpu_caps.has_avx = %u\n", util_cpu_caps.has_avx); + debug_printf("util_cpu_caps.has_avx2 = %u\n", util_cpu_caps.has_avx2); debug_printf("util_cpu_caps.has_f16c = %u\n", util_cpu_caps.has_f16c); debug_printf("util_cpu_caps.has_popcnt = %u\n", util_cpu_caps.has_popcnt); debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); + debug_printf("util_cpu_caps.has_xop = %u\n", util_cpu_caps.has_xop); debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); debug_printf("util_cpu_caps.has_daz = %u\n", util_cpu_caps.has_daz); } diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h index cc3e0ce03..5ccfc9316 100644 --- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h +++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h @@ -64,9 +64,11 @@ struct util_cpu_caps { unsigned has_sse4_2:1; unsigned has_popcnt:1; unsigned has_avx:1; + unsigned has_avx2:1; unsigned has_f16c:1; unsigned has_3dnow:1; unsigned has_3dnow_ext:1; + unsigned has_xop:1; unsigned has_altivec:1; unsigned has_daz:1; }; diff --git a/mesalib/src/gallium/auxiliary/util/u_format.csv b/mesalib/src/gallium/auxiliary/util/u_format.csv index f3925bb3c..8d04b00c4 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.csv +++ b/mesalib/src/gallium/auxiliary/util/u_format.csv @@ -372,3 +372,4 @@ PIPE_FORMAT_R16A16_UINT , plain, 1, 1, up16 , up16 , , , x00 PIPE_FORMAT_R16A16_SINT , plain, 1, 1, sp16 , sp16 , , , x00y, rgb PIPE_FORMAT_R32A32_UINT , plain, 1, 1, up32 , up32 , , , x00y, rgb PIPE_FORMAT_R32A32_SINT , plain, 1, 1, sp32 , sp32 , , , x00y, rgb +PIPE_FORMAT_R10G10B10A2_UINT , plain, 1, 1, up10 , up10 , up10, up2 , xyzw, rgb diff --git a/mesalib/src/gallium/auxiliary/util/u_video.h b/mesalib/src/gallium/auxiliary/util/u_video.h index e575947d4..276e46097 100644 --- a/mesalib/src/gallium/auxiliary/util/u_video.h +++ b/mesalib/src/gallium/auxiliary/util/u_video.h @@ -39,7 +39,7 @@ extern "C" { #include "pipe/p_compiler.h" #include "util/u_debug.h" -static INLINE enum pipe_video_codec +static INLINE enum pipe_video_format u_reduce_video_profile(enum pipe_video_profile profile) { switch (profile) @@ -47,24 +47,24 @@ u_reduce_video_profile(enum pipe_video_profile profile) case PIPE_VIDEO_PROFILE_MPEG1: case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE: case PIPE_VIDEO_PROFILE_MPEG2_MAIN: - return PIPE_VIDEO_CODEC_MPEG12; + return PIPE_VIDEO_FORMAT_MPEG12; case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE: case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE: - return PIPE_VIDEO_CODEC_MPEG4; + return PIPE_VIDEO_FORMAT_MPEG4; case PIPE_VIDEO_PROFILE_VC1_SIMPLE: case PIPE_VIDEO_PROFILE_VC1_MAIN: case PIPE_VIDEO_PROFILE_VC1_ADVANCED: - return PIPE_VIDEO_CODEC_VC1; + return PIPE_VIDEO_FORMAT_VC1; case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: - return PIPE_VIDEO_CODEC_MPEG4_AVC; + return PIPE_VIDEO_FORMAT_MPEG4_AVC; default: - return PIPE_VIDEO_CODEC_UNKNOWN; + return PIPE_VIDEO_FORMAT_UNKNOWN; } } diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h index 9b194dbd0..1c7fc63ac 100644 --- a/mesalib/src/glsl/ast.h +++ b/mesalib/src/glsl/ast.h @@ -610,6 +610,10 @@ public: virtual void print(void) const; bool has_qualifiers() const; + const struct glsl_type *glsl_type(const char **name, + struct _mesa_glsl_parse_state *state) + const; + ast_type_qualifier qualifier; ast_type_specifier *specifier; }; @@ -635,12 +639,6 @@ public: * is used to note these cases when no type is specified. */ int invariant; - - /** - * Flag indicating that these declarators are in a uniform block, - * allowing UBO type qualifiers. - */ - bool ubo_qualifiers_valid; }; diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 04b16c8aa..feff5865a 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -1797,6 +1797,28 @@ ast_type_specifier::glsl_type(const char **name, return type; } +const glsl_type * +ast_fully_specified_type::glsl_type(const char **name, + struct _mesa_glsl_parse_state *state) const +{ + const struct glsl_type *type = this->specifier->glsl_type(name, state); + + if (type == NULL) + return NULL; + + if (type->base_type == GLSL_TYPE_FLOAT + && state->es_shader + && state->target == fragment_shader + && this->qualifier.precision == ast_precision_none + && state->symbols->get_variable("#default precision") == NULL) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(&loc, state, + "no precision specified this scope for type `%s'", + type->name); + } + + return type; +} /** * Determine whether a toplevel variable declaration declares a varying. This @@ -1829,11 +1851,17 @@ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state, YYLTYPE *loc, const glsl_type *type) { - if (!type->is_matrix() && !type->is_record()) { - _mesa_glsl_error(loc, state, - "uniform block layout qualifiers row_major and " - "column_major can only be applied to matrix and " - "structure types"); + if (!type->is_matrix()) { + /* The OpenGL ES 3.0 conformance tests did not originally allow + * matrix layout qualifiers on non-matrices. However, the OpenGL + * 4.4 and OpenGL ES 3.0 (revision TBD) specifications were + * amended to specifically allow these layouts on all types. Emit + * a warning so that people know their code may not be portable. + */ + _mesa_glsl_warning(loc, state, + "uniform block layout qualifiers row_major and " + "column_major applied to non-matrix types may " + "be rejected by older compilers"); } else if (type->is_record()) { /* We allow 'layout(row_major)' on structure types because it's the only * way to get row-major layouts on matrices contained in structures. @@ -1841,7 +1869,7 @@ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state, _mesa_glsl_warning(loc, state, "uniform block layout qualifiers row_major and " "column_major applied to structure types is not " - "strictly conformant and my be rejected by other " + "strictly conformant and may be rejected by other " "compilers"); } } @@ -1929,7 +1957,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, ir_variable *var, struct _mesa_glsl_parse_state *state, YYLTYPE *loc, - bool ubo_qualifiers_valid, bool is_parameter) { STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i)); @@ -2275,13 +2302,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } if (qual->flags.q.row_major || qual->flags.q.column_major) { - if (!ubo_qualifiers_valid) { - _mesa_glsl_error(loc, state, - "uniform block layout qualifiers row_major and " - "column_major can only be applied to uniform block " - "members"); - } else - validate_matrix_layout_for_type(state, loc, var->type); + validate_matrix_layout_for_type(state, loc, var->type); } } @@ -2693,7 +2714,7 @@ ast_declarator_list::hir(exec_list *instructions, */ (void) this->type->specifier->hir(instructions, state); - decl_type = this->type->specifier->glsl_type(& type_name, state); + decl_type = this->type->glsl_type(& type_name, state); if (this->declarations.is_empty()) { /* If there is no structure involved in the program text, there are two * possible scenarios: @@ -2830,7 +2851,7 @@ ast_declarator_list::hir(exec_list *instructions, } apply_type_qualifier_to_variable(& this->type->qualifier, var, state, - & loc, this->ubo_qualifiers_valid, false); + & loc, false); if (this->type->qualifier.flags.q.invariant) { if ((state->target == vertex_shader) && @@ -3277,7 +3298,7 @@ ast_parameter_declarator::hir(exec_list *instructions, const char *name = NULL; YYLTYPE loc = this->get_location(); - type = this->type->specifier->glsl_type(& name, state); + type = this->type->glsl_type(& name, state); if (type == NULL) { if (name != NULL) { @@ -3340,7 +3361,7 @@ ast_parameter_declarator::hir(exec_list *instructions, * for function parameters the default mode is 'in'. */ apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc, - false, true); + true); /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: * @@ -3484,7 +3505,7 @@ ast_function::hir(exec_list *instructions, const char *return_type_name; const glsl_type *return_type = - this->return_type->specifier->glsl_type(& return_type_name, state); + this->return_type->glsl_type(& return_type_name, state); if (!return_type) { YYLTYPE loc = this->get_location(); @@ -4225,10 +4246,8 @@ ast_iteration_statement::hir(exec_list *instructions, * version. */ static bool -is_valid_default_precision_type(const struct _mesa_glsl_parse_state *state, - const char *type_name) +is_valid_default_precision_type(const struct glsl_type *const type) { - const struct glsl_type *type = state->symbols->get_type(type_name); if (type == NULL) return false; @@ -4280,13 +4299,54 @@ ast_type_specifier::hir(exec_list *instructions, "arrays"); return NULL; } - if (!is_valid_default_precision_type(state, this->type_name)) { + + const struct glsl_type *const type = + state->symbols->get_type(this->type_name); + if (!is_valid_default_precision_type(type)) { _mesa_glsl_error(&loc, state, - "default precision statements apply only to types " + "default precision statements apply only to " "float, int, and sampler types"); return NULL; } + if (type->base_type == GLSL_TYPE_FLOAT + && state->es_shader + && state->target == fragment_shader) { + /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00 + * spec says: + * + * "The fragment language has no default precision qualifier for + * floating point types." + * + * As a result, we have to track whether or not default precision has + * been specified for float in GLSL ES fragment shaders. + * + * Earlier in that same section, the spec says: + * + * "Non-precision qualified declarations will use the precision + * qualifier specified in the most recent precision statement + * that is still in scope. The precision statement has the same + * scoping rules as variable declarations. If it is declared + * inside a compound statement, its effect stops at the end of + * the innermost statement it was declared in. Precision + * statements in nested scopes override precision statements in + * outer scopes. Multiple precision statements for the same basic + * type can appear inside the same scope, with later statements + * overriding earlier statements within that scope." + * + * Default precision specifications follow the same scope rules as + * variables. So, we can track the state of the default float + * precision in the symbol table, and the rules will just work. This + * is a slight abuse of the symbol table, but it has the semantics + * that we want. + */ + ir_variable *const junk = + new(state) ir_variable(type, "#default precision", + ir_var_temporary); + + state->symbols->add_variable(junk); + } + /* FINISHME: Translate precision statements into IR. */ return NULL; } @@ -4367,7 +4427,7 @@ ast_process_structure_or_interface_block(exec_list *instructions, } const glsl_type *decl_type = - decl_list->type->specifier->glsl_type(& type_name, state); + decl_list->type->glsl_type(& type_name, state); foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) { @@ -4415,11 +4475,6 @@ ast_process_structure_or_interface_block(exec_list *instructions, _mesa_glsl_error(&loc, state, "row_major and column_major can only be " "applied to uniform interface blocks"); - } else if (!field_type->is_matrix() && !field_type->is_record()) { - _mesa_glsl_error(&loc, state, - "uniform block layout qualifiers row_major and " - "column_major can only be applied to matrix and " - "structure types"); } else validate_matrix_layout_for_type(state, &loc, field_type); } @@ -4455,6 +4510,34 @@ ast_struct_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { YYLTYPE loc = this->get_location(); + + /* Section 4.1.8 (Structures) of the GLSL 1.10 spec says: + * + * "Anonymous structures are not supported; so embedded structures must + * have a declarator. A name given to an embedded struct is scoped at + * the same level as the struct it is embedded in." + * + * The same section of the GLSL 1.20 spec says: + * + * "Anonymous structures are not supported. Embedded structures are not + * supported. + * + * struct S { float f; }; + * struct T { + * S; // Error: anonymous structures disallowed + * struct { ... }; // Error: embedded structures disallowed + * S s; // Okay: nested structures with name are allowed + * };" + * + * The GLSL ES 1.00 and 3.00 specs have similar langauge and examples. So, + * we allow embedded structures in 1.10 only. + */ + if (state->language_version != 110 && state->struct_specifier_depth != 0) + _mesa_glsl_error(&loc, state, + "embedded structure declartions are not allowed"); + + state->struct_specifier_depth++; + glsl_struct_field *fields; unsigned decl_count = ast_process_structure_or_interface_block(instructions, @@ -4481,6 +4564,8 @@ ast_struct_specifier::hir(exec_list *instructions, } } + state->struct_specifier_depth--; + /* Structure type definitions do not have r-values. */ return NULL; diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp index ce6b6a771..8aabd95f9 100644 --- a/mesalib/src/glsl/ast_type.cpp +++ b/mesalib/src/glsl/ast_type.cpp @@ -168,6 +168,9 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc, if (q.flags.q.explicit_binding) this->binding = q.binding; + if (q.precision != ast_precision_none) + this->precision = q.precision; + return true; } diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index e3a57ea02..d8e589d49 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -2295,7 +2295,6 @@ member_declaration: $$ = new(ctx) ast_declarator_list(type); $$->set_location(yylloc); - $$->ubo_qualifiers_valid = true; $$->declarations.push_degenerate_list_at_head(& $2->link); } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 88f048365..8669b7762 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -71,6 +71,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->loop_nesting_ast = NULL; this->switch_state.switch_nesting_ast = NULL; + this->struct_specifier_depth = 0; this->num_builtins_to_link = 0; /* Set default language version and extensions */ @@ -1170,7 +1171,6 @@ ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) { this->type = type; this->invariant = false; - this->ubo_qualifiers_valid = false; } void diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index b9ca4e3a4..440c15bb8 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -159,6 +159,13 @@ struct _mesa_glsl_parse_state { enum _mesa_glsl_parser_targets target; /** + * Number of nested struct_specifier levels + * + * Outside a struct_specifer, this is zero. + */ + unsigned struct_specifier_depth; + + /** * Default uniform layout qualifiers tracked during parsing. * Currently affects uniform blocks and uniform buffer variables in * those blocks. diff --git a/mesalib/src/glsl/link_uniform_blocks.cpp b/mesalib/src/glsl/link_uniform_blocks.cpp index 1083653c7..d96075849 100644 --- a/mesalib/src/glsl/link_uniform_blocks.cpp +++ b/mesalib/src/glsl/link_uniform_blocks.cpp @@ -59,6 +59,15 @@ private: virtual void visit_field(const glsl_type *type, const char *name, bool row_major) { + (void) type; + (void) name; + (void) row_major; + assert(!"Should not get here."); + } + + virtual void visit_field(const glsl_type *type, const char *name, + bool row_major, const glsl_type *record_type) + { assert(this->index < this->num_variables); gl_uniform_buffer_variable *v = &this->variables[this->index++]; @@ -85,7 +94,9 @@ private: v->IndexName = v->Name; } - unsigned alignment = type->std140_base_alignment(v->RowMajor); + const unsigned alignment = record_type + ? record_type->std140_base_alignment(v->RowMajor) + : type->std140_base_alignment(v->RowMajor); unsigned size = type->std140_size(v->RowMajor); this->offset = glsl_align(this->offset, alignment); @@ -107,6 +118,10 @@ private: virtual void visit_field(const glsl_struct_field *field) { + /* FINISHME: When support for doubles (dvec4, etc.) is added to the + * FINISHME: compiler, this may be incorrect for a structure in a UBO + * FINISHME: like struct s { struct { float f } s1; dvec4 v; };. + */ this->offset = glsl_align(this->offset, field->type->std140_base_alignment(false)); } diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 35ace1ec3..fa77157f7 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -60,7 +60,7 @@ program_resource_visitor::process(const glsl_type *type, const char *name) || (type->is_array() && type->fields.array->is_interface())); char *name_copy = ralloc_strdup(NULL, name); - recursion(type, &name_copy, strlen(name), false); + recursion(type, &name_copy, strlen(name), false, NULL); ralloc_free(name_copy); } @@ -77,24 +77,25 @@ 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())) { char *name = ralloc_strdup(NULL, var->name); - recursion(var->type, &name, strlen(name), false); + recursion(var->type, &name, strlen(name), false, NULL); ralloc_free(name); } else if (t->is_interface()) { char *name = ralloc_strdup(NULL, var->type->name); - recursion(var->type, &name, strlen(name), false); + recursion(var->type, &name, strlen(name), false, NULL); ralloc_free(name); } else if (t->is_array() && t->fields.array->is_interface()) { char *name = ralloc_strdup(NULL, var->type->fields.array->name); - recursion(var->type, &name, strlen(name), false); + recursion(var->type, &name, strlen(name), false, NULL); ralloc_free(name); } else { - this->visit_field(t, var->name, false); + this->visit_field(t, var->name, false, NULL); } } void program_resource_visitor::recursion(const glsl_type *t, char **name, - size_t name_length, bool row_major) + size_t name_length, bool row_major, + const glsl_type *record_type) { /* Records need to have each field processed individually. * @@ -103,6 +104,9 @@ program_resource_visitor::recursion(const glsl_type *t, char **name, * individually. */ if (t->is_record() || t->is_interface()) { + if (record_type == NULL && t->is_record()) + record_type = t; + for (unsigned i = 0; i < t->length; i++) { const char *field = t->fields.structure[i].name; size_t new_length = name_length; @@ -118,10 +122,18 @@ program_resource_visitor::recursion(const glsl_type *t, char **name, } recursion(t->fields.structure[i].type, name, new_length, - t->fields.structure[i].row_major); + t->fields.structure[i].row_major, record_type); + + /* Only the first leaf-field of the record gets called with the + * record type pointer. + */ + record_type = NULL; } } else if (t->is_array() && (t->fields.array->is_record() || t->fields.array->is_interface())) { + if (record_type == NULL && t->fields.array->is_record()) + record_type = t->fields.array; + for (unsigned i = 0; i < t->length; i++) { size_t new_length = name_length; @@ -129,14 +141,27 @@ program_resource_visitor::recursion(const glsl_type *t, char **name, ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); recursion(t->fields.array, name, new_length, - t->fields.structure[i].row_major); + t->fields.structure[i].row_major, record_type); + + /* Only the first leaf-field of the record gets called with the + * record type pointer. + */ + record_type = NULL; } } else { - this->visit_field(t, *name, row_major); + this->visit_field(t, *name, row_major, record_type); } } void +program_resource_visitor::visit_field(const glsl_type *type, const char *name, + bool row_major, + const glsl_type *record_type) +{ + visit_field(type, name, row_major); +} + +void program_resource_visitor::visit_field(const glsl_struct_field *field) { (void) field; @@ -377,6 +402,15 @@ private: virtual void visit_field(const glsl_type *type, const char *name, bool row_major) { + (void) type; + (void) name; + (void) row_major; + assert(!"Should not get here."); + } + + virtual void visit_field(const glsl_type *type, const char *name, + bool row_major, const glsl_type *record_type) + { assert(!type->is_record()); assert(!(type->is_array() && type->fields.array->is_record())); assert(!type->is_interface()); @@ -421,7 +455,9 @@ private: if (this->ubo_block_index != -1) { this->uniforms[id].block_index = this->ubo_block_index; - unsigned alignment = type->std140_base_alignment(ubo_row_major); + const unsigned alignment = record_type + ? record_type->std140_base_alignment(ubo_row_major) + : type->std140_base_alignment(ubo_row_major); this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment); this->uniforms[id].offset = this->ubo_byte_offset; this->ubo_byte_offset += type->std140_size(ubo_row_major); diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index f87ae0eec..8430096ac 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -373,6 +373,52 @@ link_invalidate_variable_locations(gl_shader *sh, int input_base, /** + * Set UsesClipDistance and ClipDistanceArraySize based on the given shader. + * + * Also check for errors based on incorrect usage of gl_ClipVertex and + * gl_ClipDistance. + * + * Return false if an error was reported. + */ +static void +analyze_clip_usage(const char *shader_type, struct gl_shader_program *prog, + struct gl_shader *shader, GLboolean *UsesClipDistance, + GLuint *ClipDistanceArraySize) +{ + *ClipDistanceArraySize = 0; + + if (!prog->IsES && prog->Version >= 130) { + /* From section 7.1 (Vertex Shader Special Variables) of the + * GLSL 1.30 spec: + * + * "It is an error for a shader to statically write both + * gl_ClipVertex and gl_ClipDistance." + * + * This does not apply to GLSL ES shaders, since GLSL ES defines neither + * gl_ClipVertex nor gl_ClipDistance. + */ + find_assignment_visitor clip_vertex("gl_ClipVertex"); + find_assignment_visitor clip_distance("gl_ClipDistance"); + + clip_vertex.run(shader->ir); + clip_distance.run(shader->ir); + if (clip_vertex.variable_found() && clip_distance.variable_found()) { + linker_error(prog, "%s shader writes to both `gl_ClipVertex' " + "and `gl_ClipDistance'\n", shader_type); + return; + } + *UsesClipDistance = clip_distance.variable_found(); + ir_variable *clip_distance_var = + shader->symbols->get_variable("gl_ClipDistance"); + if (clip_distance_var) + *ClipDistanceArraySize = clip_distance_var->type->length; + } else { + *UsesClipDistance = false; + } +} + + +/** * Verify that a vertex shader executable meets all semantic requirements. * * Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize @@ -422,34 +468,8 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, } } - prog->Vert.ClipDistanceArraySize = 0; - - if (!prog->IsES && prog->Version >= 130) { - /* From section 7.1 (Vertex Shader Special Variables) of the - * GLSL 1.30 spec: - * - * "It is an error for a shader to statically write both - * gl_ClipVertex and gl_ClipDistance." - * - * This does not apply to GLSL ES shaders, since GLSL ES defines neither - * gl_ClipVertex nor gl_ClipDistance. - */ - find_assignment_visitor clip_vertex("gl_ClipVertex"); - find_assignment_visitor clip_distance("gl_ClipDistance"); - - clip_vertex.run(shader->ir); - clip_distance.run(shader->ir); - if (clip_vertex.variable_found() && clip_distance.variable_found()) { - linker_error(prog, "vertex shader writes to both `gl_ClipVertex' " - "and `gl_ClipDistance'\n"); - return; - } - prog->Vert.UsesClipDistance = clip_distance.variable_found(); - ir_variable *clip_distance_var = - shader->symbols->get_variable("gl_ClipDistance"); - if (clip_distance_var) - prog->Vert.ClipDistanceArraySize = clip_distance_var->type->length; - } + analyze_clip_usage("vertex", prog, shader, &prog->Vert.UsesClipDistance, + &prog->Vert.ClipDistanceArraySize); } @@ -480,7 +500,8 @@ validate_fragment_shader_executable(struct gl_shader_program *prog, /** * Verify that a geometry shader executable meets all semantic requirements * - * Also sets prog->Geom.VerticesIn as a side effect. + * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipDistance, and + * prog->Geom.ClipDistanceArraySize as a side effect. * * \param shader Geometry shader executable to be verified */ @@ -493,6 +514,9 @@ validate_geometry_shader_executable(struct gl_shader_program *prog, unsigned num_vertices = vertices_per_prim(prog->Geom.InputType); prog->Geom.VerticesIn = num_vertices; + + analyze_clip_usage("geometry", prog, shader, &prog->Geom.UsesClipDistance, + &prog->Geom.ClipDistanceArraySize); } diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h index 64a683d15..8a0027d2b 100644 --- a/mesalib/src/glsl/linker.h +++ b/mesalib/src/glsl/linker.h @@ -126,6 +126,19 @@ protected: * \param type Type of the field. * \param name Fully qualified name of the field. * \param row_major For a matrix type, is it stored row-major. + * \param record_type Type of the record containing the field. + * + * The default implementation just calls the other \c visit_field method. + */ + virtual void visit_field(const glsl_type *type, const char *name, + bool row_major, const glsl_type *record_type); + + /** + * Method invoked for each leaf of the variable + * + * \param type Type of the field. + * \param name Fully qualified name of the field. + * \param row_major For a matrix type, is it stored row-major. */ virtual void visit_field(const glsl_type *type, const char *name, bool row_major) = 0; @@ -146,7 +159,7 @@ private: * terminating \c NUL character. */ void recursion(const glsl_type *t, char **name, size_t name_length, - bool row_major); + bool row_major, const glsl_type *record_type); }; void diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index 60bc62827..e13d5c452 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -46,7 +46,7 @@ initialize_context(struct gl_context *ctx, gl_api api) /* The standalone compiler needs to claim support for almost * everything in order to compile the built-in functions. */ - ctx->Const.GLSLVersion = 150; + ctx->Const.GLSLVersion = 330; ctx->Extensions.ARB_ES3_compatibility = true; ctx->Const.MaxClipPlanes = 8; diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am index 97200598e..d4fbd3511 100644 --- a/mesalib/src/mapi/glapi/gen/Makefile.am +++ b/mesalib/src/mapi/glapi/gen/Makefile.am @@ -18,10 +18,10 @@ XORG_INDENT_FLAGS = -linux -bad -bap -blf -bli0 -cbi0 -cdw -nce -cs -i4 -lc80 -p -T _XFUNCPROTOBEGIN -T _XFUNCPROTOEND -T _X_EXPORT -MESA_DIR = $(top_srcdir)/src/mesa -MESA_GLAPI_DIR = $(top_srcdir)/src/mapi/glapi -MESA_MAPI_DIR = $(top_srcdir)/src/mapi -MESA_GLX_DIR = $(top_srcdir)/src/glx +MESA_DIR = $(top_builddir)/src/mesa +MESA_GLAPI_DIR = $(top_builddir)/src/mapi/glapi +MESA_MAPI_DIR = $(top_builddir)/src/mapi +MESA_GLX_DIR = $(top_builddir)/src/glx MESA_GLAPI_OUTPUTS = \ $(MESA_GLAPI_DIR)/glapi_mapi_tmp.h \ diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 60157af98..798efa680 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -1537,6 +1537,9 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx, "}\n"; fs_source = ralloc_asprintf(mem_ctx, + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" "uniform %s texSampler;\n" "varying vec2 texCoords;\n" "void main()\n" @@ -1561,6 +1564,9 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx, _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); fs_source = ralloc_asprintf(mem_ctx, "#version %s\n" + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" "uniform %s texSampler;\n" "in vec2 texCoords;\n" "out vec4 out_color;\n" @@ -2139,6 +2145,9 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) " gl_Position = position;\n" "}\n"; const char *fs_source = + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" "uniform vec4 color;\n" "void main()\n" "{\n" @@ -2198,6 +2207,9 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) const char *fs_int_source = ralloc_asprintf(shader_source_mem_ctx, "#version %s\n" + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" "uniform ivec4 color;\n" "out ivec4 out_color;\n" "\n" @@ -3426,6 +3438,9 @@ setup_glsl_generate_mipmap(struct gl_context *ctx, fs_source = ralloc_asprintf(mem_ctx, "#extension GL_EXT_texture_array : enable\n" + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" "uniform %s texSampler;\n" "varying vec3 texCoords;\n" "void main()\n" @@ -3449,6 +3464,9 @@ setup_glsl_generate_mipmap(struct gl_context *ctx, _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); fs_source = ralloc_asprintf(mem_ctx, "#version %s\n" + "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" "uniform %s texSampler;\n" "in vec3 texCoords;\n" "out vec4 out_color;\n" @@ -4004,6 +4022,11 @@ decompress_texture_image(struct gl_context *ctx, verts[3].x = 0.0F; verts[3].y = height; + _mesa_MatrixMode(GL_PROJECTION); + _mesa_LoadIdentity(); + _mesa_Ortho(0.0, width, 0.0, height, -1.0, 1.0); + _mesa_set_viewport(ctx, 0, 0, width, height); + /* upload new vertex data */ _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index d687fb7c0..d726d117b 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -622,7 +622,7 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxSamples = 0; /* GL_ARB_sync */ - ctx->Const.MaxServerWaitTimeout = (GLuint64) ~0; + ctx->Const.MaxServerWaitTimeout = 0x1fff7fffffffULL; /* GL_ATI_envmap_bumpmap */ ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS; diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index 5a0758d0b..cc93d3bd6 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -609,11 +609,6 @@ control_app_messages(struct gl_context *ctx, GLenum esource, GLenum etype, enum mesa_debug_type type = gl_enum_to_debug_type(etype); enum mesa_debug_severity severity = gl_enum_to_debug_severity(eseverity); - if (count) - assert(severity == MESA_DEBUG_SEVERITY_COUNT - && type != MESA_DEBUG_TYPE_COUNT - && source != MESA_DEBUG_SOURCE_COUNT); - for (i = 0; i < count; i++) set_message_state(ctx, source, type, ids[i], enabled); @@ -629,9 +624,6 @@ _mesa_DebugMessageControlARB(GLenum gl_source, GLenum gl_type, GLsizei count, const GLuint *ids, GLboolean enabled) { - enum mesa_debug_source source; - enum mesa_debug_type type; - enum mesa_debug_severity severity; GET_CURRENT_CONTEXT(ctx); if (count < 0) { @@ -651,11 +643,8 @@ _mesa_DebugMessageControlARB(GLenum gl_source, GLenum gl_type, return; } - source = gl_enum_to_debug_source(gl_source); - type = gl_enum_to_debug_type(gl_type); - severity = gl_enum_to_debug_severity(gl_severity); - - control_app_messages(ctx, source, type, severity, count, ids, enabled); + control_app_messages(ctx, gl_source, gl_type, gl_severity, + count, ids, enabled); } void GLAPIENTRY diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 09b008a07..4f6f59ae6 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -709,7 +709,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu case GL_COMPRESSED_TEXTURE_FORMATS_ARB: v->value_int_n.n = _mesa_get_compressed_formats(ctx, v->value_int_n.ints); - ASSERT(v->value_int_n.n <= 100); + ASSERT(v->value_int_n.n <= ARRAY_SIZE(v->value_int_n.ints)); break; case GL_MAX_VARYING_FLOATS_ARB: diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 5f9b7f983..22bb58c5f 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1924,6 +1924,7 @@ 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; }; @@ -2348,6 +2349,13 @@ struct gl_shader_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 */ + /** + * True if gl_ClipDistance is written to. Copied into + * gl_geometry_program by _mesa_copy_linked_program_data(). + */ + GLboolean UsesClipDistance; + GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or + 0 if not present. */ } Geom; /** Vertex shader state */ diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c index b74898cee..60356b85d 100644 --- a/mesalib/src/mesa/main/queryobj.c +++ b/mesalib/src/mesa/main/queryobj.c @@ -485,6 +485,7 @@ _mesa_QueryCounter(GLuint id, GLenum target) q->Target = target; q->Result = 0; q->Ready = GL_FALSE; + q->EverBound = GL_TRUE; if (ctx->Driver.QueryCounter) { ctx->Driver.QueryCounter(ctx, q); diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index d184b114c..4fe9d9ca2 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -1871,6 +1871,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; } break; default: diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c index 58859440c..e71d0c411 100644 --- a/mesalib/src/mesa/main/texcompress.c +++ b/mesalib/src/mesa/main/texcompress.c @@ -264,20 +264,16 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats) n += 3; } } - if (_mesa_is_desktop_gl(ctx) - && ctx->Extensions.ANGLE_texture_compression_dxt) { - if (formats) { - formats[n++] = GL_RGB_S3TC; - formats[n++] = GL_RGB4_S3TC; - formats[n++] = GL_RGBA_S3TC; - formats[n++] = GL_RGBA4_S3TC; - } - else { - n += 4; - } - } - if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { + /* The GL_OES_compressed_ETC1_RGB8_texture spec says: + * + * "New State + * + * The queries for NUM_COMPRESSED_TEXTURE_FORMATS and + * COMPRESSED_TEXTURE_FORMATS include ETC1_RGB8_OES." + */ + if (_mesa_is_gles(ctx) + && ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { if (formats) { formats[n++] = GL_ETC1_RGB8_OES; } diff --git a/mesalib/src/mesa/program/prog_instruction.h b/mesalib/src/mesa/program/prog_instruction.h index be221819f..b9604e50d 100644 --- a/mesalib/src/mesa/program/prog_instruction.h +++ b/mesalib/src/mesa/program/prog_instruction.h @@ -386,6 +386,10 @@ struct prog_instruction }; +#ifdef __cplusplus +extern "C" { +#endif + extern void _mesa_init_instructions(struct prog_instruction *inst, GLuint count); @@ -419,4 +423,8 @@ extern const char * _mesa_opcode_string(gl_inst_opcode opcode); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* PROG_INSTRUCTION_H */ diff --git a/mesalib/src/mesa/program/program.h b/mesalib/src/mesa/program/program.h index f28983894..34965ab99 100644 --- a/mesalib/src/mesa/program/program.h +++ b/mesalib/src/mesa/program/program.h @@ -44,6 +44,10 @@ #include "main/mtypes.h" +#ifdef __cplusplus +extern "C" { +#endif + extern struct gl_program _mesa_DummyProgram; @@ -256,4 +260,8 @@ gl_geometry_program_const(const struct gl_program *prog) } +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* PROGRAM_H */ |