diff options
107 files changed, 3192 insertions, 1156 deletions
diff --git a/fontconfig/doc/fccache.fncs b/fontconfig/doc/fccache.fncs index ca8ffa03c..34ce63f27 100644 --- a/fontconfig/doc/fccache.fncs +++ b/fontconfig/doc/fccache.fncs @@ -74,6 +74,7 @@ FcCacheCopySet. @PURPOSE@ This tries to clean up the cache directory of <parameter>cache_dir</parameter>. This returns FcTrue if the operation is successfully complete. otherwise FcFalse. +@SINCE@ 2.9.91 @@ @RET@ void @@ -83,4 +84,5 @@ This returns FcTrue if the operation is successfully complete. otherwise FcFalse @DESC@ This tries to create CACHEDIR.TAG file at the cache directory registered to <parameter>config</parameter>. +@SINCE@ 2.9.91 @@ diff --git a/fontconfig/doc/fccharset.fncs b/fontconfig/doc/fccharset.fncs index efcd0ccf1..7245a2a0e 100644 --- a/fontconfig/doc/fccharset.fncs +++ b/fontconfig/doc/fccharset.fncs @@ -60,6 +60,7 @@ running out of memory. <function>FcCharSetDelChar</function> deletes a single Unicode char from the set, returning FcFalse on failure, either as a result of a constant set or from running out of memory. +@SINCE@ 2.9.0 @@ @RET@ FcCharSet * diff --git a/fontconfig/doc/fcconfig.fncs b/fontconfig/doc/fcconfig.fncs index 0491a566f..24d7121e4 100644 --- a/fontconfig/doc/fcconfig.fncs +++ b/fontconfig/doc/fcconfig.fncs @@ -378,6 +378,7 @@ parse error, semantic error or allocation failure. Otherwise returns FcTrue. @PURPOSE@ Obtain the system root directory @DESC@ Obtrains the system root directory in 'config' if available. +@SINCE@ 2.10.92 @@ @RET@ void @@ -390,5 +391,6 @@ Set 'sysroot' as the system root directory. fontconfig prepend 'sysroot' to the cache directories in order to allow people to generate caches at the build time. Note that this causes changing current config. i.e. this function calls FcConfigSetCurrent() internally. +@SINCE@ 2.10.92 @@ diff --git a/fontconfig/doc/fcdircache.fncs b/fontconfig/doc/fcdircache.fncs index ab5e3d9a0..faeba2928 100644 --- a/fontconfig/doc/fcdircache.fncs +++ b/fontconfig/doc/fcdircache.fncs @@ -62,6 +62,7 @@ FcDirCacheRead. @DESC@ Re-scan directories only at <parameter>dir</parameter> and update the cache. returns NULL if failed. +@SINCE@ 2.11.1 @@ @RET@ FcCache * diff --git a/fontconfig/doc/fcformat.fncs b/fontconfig/doc/fcformat.fncs index c136e8cf2..71b866b88 100644 --- a/fontconfig/doc/fcformat.fncs +++ b/fontconfig/doc/fcformat.fncs @@ -305,4 +305,5 @@ For example, the format "%{family|downcase|delete( )}\n" will expand to the values of the family element in <parameter>pattern</parameter>, lower-cased and with spaces removed. +@SINCE@ 2.9.0 @@ diff --git a/fontconfig/doc/fclangset.fncs b/fontconfig/doc/fclangset.fncs index c08d60c70..c7ed83b34 100644 --- a/fontconfig/doc/fclangset.fncs +++ b/fontconfig/doc/fclangset.fncs @@ -68,6 +68,7 @@ two or three letter language from ISO 639 and Tt is a territory from ISO <parameter>lang</parameter> should be of the form Ll-Tt where Ll is a two or three letter language from ISO 639 and Tt is a territory from ISO 3166. +@SINCE@ 2.9.0 @@ @RET@ FcLangSet * @@ -77,6 +78,7 @@ two or three letter language from ISO 639 and Tt is a territory from ISO @PURPOSE@ Add langsets @DESC@ Returns a set including only those languages found in either <parameter>ls_a</parameter> or <parameter>ls_b</parameter>. +@SINCE@ 2.9.0 @@ @RET@ FcLangSet * @@ -86,6 +88,7 @@ Returns a set including only those languages found in either <parameter>ls_a</pa @PURPOSE@ Subtract langsets @DESC@ Returns a set including only those languages found in <parameter>ls_a</parameter> but not in <parameter>ls_b</parameter>. +@SINCE@ 2.9.0 @@ @RET@ FcLangResult @@ -161,6 +164,8 @@ has no matching language, this function returns FcLangDifferentLang. Returns a string set of the default languages according to the environment variables on the system. This function looks for them in order of FC_LANG, LC_ALL, LC_CTYPE and LANG then. If there are no valid values in those environment variables, "en" will be set as fallback. +@SINCE@ 2.9.91 +@@ @RET@ FcStrSet * @FUNC@ FcLangSetGetLangs @@ -184,6 +189,7 @@ Returns a string set of all known languages. @PURPOSE@ Normalize the language string @DESC@ Returns a string to make <parameter>lang</parameter> suitable on fontconfig. +@SINCE@ 2.10.91 @@ @RET@ const FcCharSet * diff --git a/fontconfig/doc/fcstrset.fncs b/fontconfig/doc/fcstrset.fncs index b96489a43..67aa61ac0 100644 --- a/fontconfig/doc/fcstrset.fncs +++ b/fontconfig/doc/fcstrset.fncs @@ -104,6 +104,7 @@ Creates an iterator to list the strings in <parameter>set</parameter>. @PURPOSE@ get first string in iteration @DESC@ Returns the first string in <parameter>list</parameter>. +@SINCE@ 2.11.0 @@ @RET@ FcChar8 * diff --git a/fontconfig/doc/func.sgml b/fontconfig/doc/func.sgml index 73e7761ce..f076baff2 100644 --- a/fontconfig/doc/func.sgml +++ b/fontconfig/doc/func.sgml @@ -33,6 +33,7 @@ <refentrytitle>@FUNC@</refentrytitle> @;@ <manvolnum>3</manvolnum> + <refmiscinfo class="software">Fontconfig &version;</refmiscinfo> </refmeta> <refnamediv> @{PROTOTYPE@ @@ -82,9 +83,9 @@ @DESC@ </para> </refsect1> - <refsect1><title>Version</title> - <para> -Fontconfig version &version; - </para> +@?SINCE@ + <refsect1><title>Since</title> + <para>version @SINCE@</para> </refsect1> +@;@ </refentry> diff --git a/fontconfig/src/fcstat.c b/fontconfig/src/fcstat.c index f384767cc..0a880975a 100644 --- a/fontconfig/src/fcstat.c +++ b/fontconfig/src/fcstat.c @@ -186,10 +186,8 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum) struct Adler32 ctx; struct dirent **files; int n; -#ifndef HAVE_STRUCT_DIRENT_D_TYPE int ret = 0; size_t len = strlen ((const char *)dir); -#endif Adler32Init (&ctx); @@ -210,7 +208,9 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum) #ifdef HAVE_STRUCT_DIRENT_D_TYPE dtype = files[n]->d_type; -#else + if (dtype == DT_UNKNOWN) + { +#endif struct stat statb; char f[PATH_MAX + 1]; @@ -227,20 +227,18 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum) goto bail; dtype = statb.st_mode; +#ifdef HAVE_STRUCT_DIRENT_D_TYPE + } #endif Adler32Update (&ctx, files[n]->d_name, dlen + 1); Adler32Update (&ctx, (char *)&dtype, sizeof (int)); -#ifndef HAVE_STRUCT_DIRENT_D_TYPE bail: -#endif free (files[n]); } free (files); -#ifndef HAVE_STRUCT_DIRENT_D_TYPE if (ret == -1) return -1; -#endif *checksum = Adler32Finish (&ctx); diff --git a/mesalib/configure.ac b/mesalib/configure.ac index d54cba36d..3f752664b 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -611,7 +611,7 @@ AC_ARG_ENABLE([omx], AC_ARG_ENABLE([opencl], [AS_HELP_STRING([--enable-opencl], [enable OpenCL library NOTE: Enabling this option will also enable - --with-llvm-shared-libs + --enable-llvm-shared-libs @<:@default=no@:>@])], [], [enable_opencl=no]) @@ -994,6 +994,10 @@ if test "x$enable_dri" = xyes; then DEFINES="$DEFINES -DHAVE_DRI3" fi + if test "x$have_libudev" != xyes; then + AC_MSG_ERROR([libudev-dev required for building DRI]) + fi + case "$host_cpu" in powerpc* | sparc*) # Build only the drivers for cards that exist on PowerPC/sparc @@ -1068,7 +1072,7 @@ if test -n "$with_dri_drivers"; then dri_drivers=`IFS=', '; echo $with_dri_drivers` for driver in $dri_drivers; do - DRI_DIRS+="$driver " + DRI_DIRS="$DRI_DIRS $driver" case "x$driver" in xi915) HAVE_I915_DRI=yes; @@ -1888,7 +1892,7 @@ if test "x$MESA_LLVM" != x0; then can use the --with-llvm-prefix= configure flag to specify this directory. NOTE: Mesa is attempting to use llvm shared libraries because you have passed one of the following options to configure: - --with-llvm-shared-libs + --enable-llvm-shared-libs --enable-opencl If you do not want to build with llvm shared libraries and instead want to use llvm static libraries then remove these options from your configure diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt index 755a89c0f..9758dcca2 100644 --- a/mesalib/docs/GL3.txt +++ b/mesalib/docs/GL3.txt @@ -158,7 +158,7 @@ GL 4.3: GL_ARB_robust_buffer_access_behavior not started GL_ARB_shader_image_size not started GL_ARB_shader_storage_buffer_object not started - GL_ARB_stencil_texturing not started + GL_ARB_stencil_texturing DONE (i965/gen8+) GL_ARB_texture_buffer_range DONE (nv50, nvc0, i965, r600, radeonsi) GL_ARB_texture_query_levels DONE (i965) GL_ARB_texture_storage_multisample DONE (all drivers that support GL_ARB_texture_multisample) @@ -177,7 +177,7 @@ GL 4.4: GL_ARB_query_buffer_object not started GL_ARB_texture_mirror_clamp_to_edge DONE (i965, nv30, nv50, nvc0, r300, r600, radeonsi, swrast) GL_ARB_texture_stencil8 not started - GL_ARB_vertex_type_10f_11f_11f_rev DONE (i965, r600) + GL_ARB_vertex_type_10f_11f_11f_rev DONE (i965, nv50, nvc0, r600) More info about these features and the work involved can be found at diff --git a/mesalib/docs/index.html b/mesalib/docs/index.html index 4f92801b5..925c22cd4 100644 --- a/mesalib/docs/index.html +++ b/mesalib/docs/index.html @@ -16,6 +16,13 @@ <h1>News</h1> +<h2>March 4, 2014</h2> +<p> +<a href="relnotes/10.1.html">Mesa 10.1</a> is released. +This is a new development release. +See the release notes for more information about the release. +</p> + <h2>February 3, 2014</h2> <p> <a href="relnotes/10.0.3.html">Mesa 10.0.3</a> is released. diff --git a/mesalib/docs/relnotes/10.1.html b/mesalib/docs/relnotes/10.1.html index 8626b65fd..991388238 100644 --- a/mesalib/docs/relnotes/10.1.html +++ b/mesalib/docs/relnotes/10.1.html @@ -14,7 +14,7 @@ <iframe src="../contents.html"></iframe> <div class="content"> -<h1>Mesa 10.1 Release Notes / TBD</h1> +<h1>Mesa 10.1 Release Notes / March 4, 2014</h1> <p> Mesa 10.1 is a new development release. @@ -33,7 +33,9 @@ because compatibility contexts are not supported. <h2>MD5 checksums</h2> <pre> -TBD. +3ec43f79dbcd9aa2a4a27bf1f51655b6 MesaLib-10.1.0.tar.bz2 +08e796ec7122aa299d32d4f67a254315 MesaLib-10.1.0.tar.gz +bd365356543f4b38e57c1ddf7a317c40 MesaLib-10.1.0.zip </pre> @@ -44,7 +46,6 @@ Note: some of the new features are only available with certain drivers. </p> <ul> -<li>GL_ARB_buffer_storage on r300, r600, and radeonsi</li> <li>GL_ARB_draw_indirect on i965.</li> <li>GL_ARB_clear_buffer_object</li> <li>GL_ARB_viewport_array on i965.</li> diff --git a/mesalib/docs/relnotes/10.2.html b/mesalib/docs/relnotes/10.2.html index 332c33a3f..da79e7d80 100644 --- a/mesalib/docs/relnotes/10.2.html +++ b/mesalib/docs/relnotes/10.2.html @@ -44,6 +44,8 @@ Note: some of the new features are only available with certain drivers. </p> <ul> +<li>GL_ARB_buffer_storage on r300, r600, and radeonsi</li> +<li>GL_ARB_stencil_texturing on i965/gen8+</li> </ul> diff --git a/mesalib/include/GL/glxext.h b/mesalib/include/GL/glxext.h index 8c642f354..826fda5b5 100644 --- a/mesalib/include/GL/glxext.h +++ b/mesalib/include/GL/glxext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013 The Khronos Group Inc. +** Copyright (c) 2013-2014 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -33,10 +33,10 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.opengl.org/registry/ ** -** Khronos $Revision: 24777 $ on $Date: 2014-01-14 14:02:32 -0800 (Tue, 14 Jan 2014) $ +** Khronos $Revision: 25407 $ on $Date: 2014-02-18 16:51:56 -0800 (Tue, 18 Feb 2014) $ */ -#define GLX_GLXEXT_VERSION 20140114 +#define GLX_GLXEXT_VERSION 20140218 /* Generated C header for: * API: glx @@ -407,6 +407,32 @@ GLXPixmap glXCreateGLXPixmapMESA (Display *dpy, XVisualInfo *visual, Pixmap pixm #endif #endif /* GLX_MESA_pixmap_colormap */ +#ifndef GLX_MESA_query_renderer +#define GLX_MESA_query_renderer 1 +#define GLX_RENDERER_VENDOR_ID_MESA 0x8183 +#define GLX_RENDERER_DEVICE_ID_MESA 0x8184 +#define GLX_RENDERER_VERSION_MESA 0x8185 +#define GLX_RENDERER_ACCELERATED_MESA 0x8186 +#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187 +#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188 +#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189 +#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A +#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B +#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C +#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D +#define GLX_RENDERER_ID_MESA 0x818E +typedef Bool ( *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value); +typedef const char *( *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute); +typedef Bool ( *PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display *dpy, int screen, int renderer, int attribute, unsigned int *value); +typedef const char *( *PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute); +#ifdef GLX_GLXEXT_PROTOTYPES +Bool glXQueryCurrentRendererIntegerMESA (int attribute, unsigned int *value); +const char *glXQueryCurrentRendererStringMESA (int attribute); +Bool glXQueryRendererIntegerMESA (Display *dpy, int screen, int renderer, int attribute, unsigned int *value); +const char *glXQueryRendererStringMESA (Display *dpy, int screen, int renderer, int attribute); +#endif +#endif /* GLX_MESA_query_renderer */ + #ifndef GLX_MESA_release_buffers #define GLX_MESA_release_buffers 1 typedef Bool ( *PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable); diff --git a/mesalib/include/c11/threads_win32.h b/mesalib/include/c11/threads_win32.h index be1a38957..d4c2a72d2 100644 --- a/mesalib/include/c11/threads_win32.h +++ b/mesalib/include/c11/threads_win32.h @@ -146,7 +146,7 @@ static unsigned __stdcall impl_thrd_routine(void *p) static DWORD impl_xtime2msec(const xtime *xt) { - return (DWORD)((xt->sec * 1000u) + (xt->nsec / 1000)); + return (DWORD)((xt->sec * 1000U) + (xt->nsec / 1000000L)); } #ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE @@ -492,12 +492,42 @@ thrd_create(thrd_t *thr, thrd_start_t func, void *arg) return thrd_success; } +#if 0 // 7.25.5.2 static inline thrd_t thrd_current(void) { - return GetCurrentThread(); + HANDLE hCurrentThread; + BOOL bRet; + + /* GetCurrentThread() returns a pseudo-handle, which is useless. We need + * to call DuplicateHandle to get a real handle. However the handle value + * will not match the one returned by thread_create. + * + * Other potential solutions would be: + * - define thrd_t as a thread Ids, but this would mean we'd need to OpenThread for many operations + * - use malloc'ed memory for thrd_t. This would imply using TLS for current thread. + * + * Neither is particularly nice. + * + * Life would be much easier if C11 threads had different abstractions for + * threads and thread IDs, just like C++11 threads does... + */ + + bRet = DuplicateHandle(GetCurrentProcess(), // source process (pseudo) handle + GetCurrentThread(), // source (pseudo) handle + GetCurrentProcess(), // target process + &hCurrentThread, // target handle + 0, + FALSE, + DUPLICATE_SAME_ACCESS); + assert(bRet); + if (!bRet) { + hCurrentThread = GetCurrentThread(); + } + return hCurrentThread; } +#endif // 7.25.5.3 static inline int @@ -511,7 +541,7 @@ thrd_detach(thrd_t thr) static inline int thrd_equal(thrd_t thr0, thrd_t thr1) { - return (thr0 == thr1); + return GetThreadId(thr0) == GetThreadId(thr1); } // 7.25.5.5 diff --git a/mesalib/scons/llvm.py b/mesalib/scons/llvm.py index 6282cb538..134a0728e 100644 --- a/mesalib/scons/llvm.py +++ b/mesalib/scons/llvm.py @@ -204,6 +204,7 @@ def generate(env): env.ParseConfig('llvm-config --ldflags') if llvm_version >= distutils.version.LooseVersion('3.5'): env.ParseConfig('llvm-config --system-libs') + env.Append(CXXFLAGS = ['-std=c++11']) except OSError: print 'scons: llvm-config version %s failed' % llvm_version return diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index 95e7fb631..66b511eb5 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -364,6 +364,8 @@ void util_blitter_destroy(struct blitter_context *blitter) pipe->delete_vs_state(pipe, ctx->vs); if (ctx->vs_pos_only) pipe->delete_vs_state(pipe, ctx->vs_pos_only); + if (ctx->vs_layered) + pipe->delete_vs_state(pipe, ctx->vs_layered); pipe->delete_vertex_elements_state(pipe, ctx->velem_state); for (i = 0; i < 4; i++) { if (ctx->velem_state_readbuf[i]) { diff --git a/mesalib/src/gallium/auxiliary/util/u_format.csv b/mesalib/src/gallium/auxiliary/util/u_format.csv index 8d04b00c4..8fb068b81 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.csv +++ b/mesalib/src/gallium/auxiliary/util/u_format.csv @@ -272,8 +272,8 @@ PIPE_FORMAT_NV12 , other, 1, 1, x8 , x8 , x8 , x8 , xyzw, y PIPE_FORMAT_NV21 , other, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv # Usually used to implement IA44 and AI44 formats in video decoding -PIPE_FORMAT_R4A4_UNORM , plain, 1, 1, un4 , un4 , , , y00x, rgb -PIPE_FORMAT_A4R4_UNORM , plain, 1, 1, un4 , un4 , , , x00y, rgb +PIPE_FORMAT_A4R4_UNORM , plain, 1, 1, un4 , un4 , , , y00x, rgb +PIPE_FORMAT_R4A4_UNORM , plain, 1, 1, un4 , un4 , , , x00y, rgb PIPE_FORMAT_R8A8_UNORM , plain, 1, 1, un8 , un8 , , , x00y, rgb PIPE_FORMAT_A8R8_UNORM , plain, 1, 1, un8 , un8 , , , y00x, rgb diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h index e36a9e237..747e1429d 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.h +++ b/mesalib/src/gallium/auxiliary/util/u_format.h @@ -1060,8 +1060,7 @@ util_format_luminance_to_red(enum pipe_format format) return PIPE_FORMAT_RGTC1_SNORM; case PIPE_FORMAT_L4A4_UNORM: - /* XXX A4R4 is defined as x00y in u_format.csv */ - return PIPE_FORMAT_A4R4_UNORM; + return PIPE_FORMAT_R4A4_UNORM; case PIPE_FORMAT_L8A8_UNORM: return PIPE_FORMAT_R8A8_UNORM; diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h index 1efb30679..ae70b003c 100644 --- a/mesalib/src/glsl/ast.h +++ b/mesalib/src/glsl/ast.h @@ -75,10 +75,10 @@ public: struct YYLTYPE locp; locp.source = this->location.source; - locp.first_line = this->location.line; - locp.first_column = this->location.column; - locp.last_line = locp.first_line; - locp.last_column = locp.first_column; + locp.first_line = this->location.first_line; + locp.first_column = this->location.first_column; + locp.last_line = this->location.last_line; + locp.last_column = this->location.last_column; return locp; } @@ -91,17 +91,35 @@ public: void set_location(const struct YYLTYPE &locp) { this->location.source = locp.source; - this->location.line = locp.first_line; - this->location.column = locp.first_column; + this->location.first_line = locp.first_line; + this->location.first_column = locp.first_column; + this->location.last_line = locp.last_line; + this->location.last_column = locp.last_column; + } + + /** + * Set the source location range of an AST node using two location nodes + * + * \sa ast_node::set_location + */ + void set_location_range(const struct YYLTYPE &begin, const struct YYLTYPE &end) + { + this->location.source = begin.source; + this->location.first_line = begin.first_line; + this->location.last_line = end.last_line; + this->location.first_column = begin.first_column; + this->location.last_column = end.last_column; } /** * Source location of the AST node. */ struct { - unsigned source; /**< GLSL source number. */ - unsigned line; /**< Line number within the source string. */ - unsigned column; /**< Column in the line. */ + unsigned source; /**< GLSL source number. */ + unsigned first_line; /**< First line number within the source string. */ + unsigned first_column; /**< First column in the first line. */ + unsigned last_line; /**< Last line number within the source string. */ + unsigned last_column; /**< Last column in the last line. */ } location; exec_node link; diff --git a/mesalib/src/glsl/glcpp/glcpp-lex.l b/mesalib/src/glsl/glcpp/glcpp-lex.l index ea3b862e4..188e45466 100644 --- a/mesalib/src/glsl/glcpp/glcpp-lex.l +++ b/mesalib/src/glsl/glcpp/glcpp-lex.l @@ -47,8 +47,9 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner); if (parser->has_new_source_number) \ yylloc->source = parser->new_source_number; \ yylloc->first_column = yycolumn + 1; \ - yylloc->first_line = yylineno; \ + yylloc->first_line = yylloc->last_line = yylineno; \ yycolumn += yyleng; \ + yylloc->last_column = yycolumn + 1; \ parser->has_new_line_number = 0; \ parser->has_new_source_number = 0; \ } while(0); @@ -337,7 +338,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? return OTHER; } -{HSPACE}+ { +{HSPACE} { if (yyextra->space_tokens) { return SPACE; } diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll index 9fd9b80d3..760235127 100644 --- a/mesalib/src/glsl/glsl_lexer.ll +++ b/mesalib/src/glsl/glsl_lexer.ll @@ -38,8 +38,9 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *); do { \ yylloc->source = 0; \ yylloc->first_column = yycolumn + 1; \ - yylloc->first_line = yylineno + 1; \ + yylloc->first_line = yylloc->last_line = yylineno + 1; \ yycolumn += yyleng; \ + yylloc->last_column = yycolumn + 1; \ } while(0); #define YY_USER_INIT yylineno = 0; yycolumn = 0; diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 1df572254..faaf4388c 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -388,35 +388,35 @@ primary_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); $$->primary_expression.identifier = $1; } | INTCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); $$->primary_expression.int_constant = $1; } | UINTCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); $$->primary_expression.uint_constant = $1; } | FLOATCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); $$->primary_expression.float_constant = $1; } | BOOLCONSTANT { void *ctx = state; $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); $$->primary_expression.bool_constant = $1; } | '(' expression ')' @@ -431,7 +431,7 @@ postfix_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @4); } | function_call { @@ -441,20 +441,20 @@ postfix_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); $$->primary_expression.identifier = $3; } | postfix_expression INC_OP { void *ctx = state; $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } | postfix_expression DEC_OP { void *ctx = state; $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } ; @@ -472,7 +472,7 @@ function_call_or_method: { void *ctx = state; $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -490,13 +490,13 @@ function_call_header_with_parameters: function_call_header assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(@1); $$->expressions.push_tail(& $2->link); } | function_call_header_with_parameters ',' assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(@1); $$->expressions.push_tail(& $3->link); } ; @@ -513,21 +513,23 @@ function_identifier: { void *ctx = state; $$ = new(ctx) ast_function_expression($1); - $$->set_location(yylloc); + $$->set_location(@1); } | variable_identifier { void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); + callee->set_location(@1); $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); + $$->set_location(@1); } | FIELD_SELECTION { void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); + callee->set_location(@1); $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); + $$->set_location(@1); } ; @@ -545,13 +547,13 @@ method_call_header_with_parameters: method_call_header assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(@1); $$->expressions.push_tail(& $2->link); } | method_call_header_with_parameters ',' assignment_expression { $$ = $1; - $$->set_location(yylloc); + $$->set_location(@1); $$->expressions.push_tail(& $3->link); } ; @@ -564,8 +566,9 @@ method_call_header: { void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); + callee->set_location(@1); $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); + $$->set_location(@1); } ; @@ -576,19 +579,19 @@ unary_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); } | DEC_OP unary_expression { void *ctx = state; $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); } | unary_operator unary_expression { void *ctx = state; $$ = new(ctx) ast_expression($1, $2, NULL, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } ; @@ -606,19 +609,19 @@ multiplicative_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | multiplicative_expression '/' unary_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | multiplicative_expression '%' unary_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -628,13 +631,13 @@ additive_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | additive_expression '-' multiplicative_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -644,13 +647,13 @@ shift_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | shift_expression RIGHT_OP additive_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -660,25 +663,25 @@ relational_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | relational_expression '>' shift_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | relational_expression LE_OP shift_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | relational_expression GE_OP shift_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -688,13 +691,13 @@ equality_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } | equality_expression NE_OP relational_expression { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -704,7 +707,7 @@ and_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -714,7 +717,7 @@ exclusive_or_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -724,7 +727,7 @@ inclusive_or_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -734,7 +737,7 @@ logical_and_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -744,7 +747,7 @@ logical_xor_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -754,7 +757,7 @@ logical_or_expression: { void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -764,7 +767,7 @@ conditional_expression: { void *ctx = state; $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); - $$->set_location(yylloc); + $$->set_location_range(@1, @5); } ; @@ -774,7 +777,7 @@ assignment_expression: { void *ctx = state; $$ = new(ctx) ast_expression($2, $1, $3, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -802,7 +805,7 @@ expression: void *ctx = state; if ($1->oper != ast_sequence) { $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); $$->expressions.push_tail(& $1->link); } else { $$ = $1; @@ -864,7 +867,7 @@ function_header: { void *ctx = state; $$ = new(ctx) ast_function(); - $$->set_location(yylloc); + $$->set_location(@2); $$->return_type = $1; $$->identifier = $2; @@ -878,9 +881,9 @@ parameter_declarator: { void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); + $$->type->set_location(@1); $$->type->specifier = $1; $$->identifier = $2; } @@ -888,9 +891,9 @@ parameter_declarator: { void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); + $$->type->set_location(@1); $$->type->specifier = $1; $$->identifier = $2; $$->array_specifier = $3; @@ -907,8 +910,9 @@ parameter_declaration: { void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); + $$->set_location(@2); $$->type = new(ctx) ast_fully_specified_type(); + $$->type->set_location_range(@1, @2); $$->type->qualifier = $1; $$->type->specifier = $2; } @@ -980,7 +984,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, NULL, NULL); - decl->set_location(yylloc); + decl->set_location(@3); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -990,7 +994,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, $4, NULL); - decl->set_location(yylloc); + decl->set_location_range(@3, @4); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -1000,7 +1004,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, $4, $6); - decl->set_location(yylloc); + decl->set_location_range(@3, @4); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -1010,7 +1014,7 @@ init_declarator_list: { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, NULL, $5); - decl->set_location(yylloc); + decl->set_location(@3); $$ = $1; $$->declarations.push_tail(&decl->link); @@ -1025,51 +1029,56 @@ single_declaration: void *ctx = state; /* Empty declaration list is valid. */ $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location(@1); } | fully_specified_type any_identifier { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, NULL); + decl->set_location(@2); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier array_specifier { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, $3, NULL); + decl->set_location_range(@2, @3); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier array_specifier '=' initializer { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, $3, $5); + decl->set_location_range(@2, @3); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); $$->declarations.push_tail(&decl->link); } | fully_specified_type any_identifier '=' initializer { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, $4); + decl->set_location(@2); $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); $$->declarations.push_tail(&decl->link); } | INVARIANT variable_identifier // Vertex only. { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, NULL); + decl->set_location(@2); $$ = new(ctx) ast_declarator_list(NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); $$->invariant = true; $$->declarations.push_tail(&decl->link); @@ -1081,14 +1090,14 @@ fully_specified_type: { void *ctx = state; $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); + $$->set_location(@1); $$->specifier = $1; } | type_qualifier type_specifier { void *ctx = state; $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); $$->qualifier = $1; $$->specifier = $2; } @@ -1696,12 +1705,14 @@ array_specifier: '[' ']' { void *ctx = state; - $$ = new(ctx) ast_array_specifier(yylloc); + $$ = new(ctx) ast_array_specifier(@1); + $$->set_location_range(@1, @2); } | '[' constant_expression ']' { void *ctx = state; - $$ = new(ctx) ast_array_specifier(yylloc, $2); + $$ = new(ctx) ast_array_specifier(@1, $2); + $$->set_location_range(@1, @3); } | array_specifier '[' ']' { @@ -1745,19 +1756,19 @@ type_specifier_nonarray: { void *ctx = state; $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); + $$->set_location(@1); } | struct_specifier { void *ctx = state; $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); + $$->set_location(@1); } | TYPE_IDENTIFIER { void *ctx = state; $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); + $$->set_location(@1); } ; @@ -1888,7 +1899,7 @@ struct_specifier: { void *ctx = state; $$ = new(ctx) ast_struct_specifier($2, $4); - $$->set_location(yylloc); + $$->set_location_range(@2, @5); state->symbols->add_type($2, glsl_type::void_type); state->symbols->add_type_ast($2, new(ctx) ast_type_specifier($$)); } @@ -1896,7 +1907,7 @@ struct_specifier: { void *ctx = state; $$ = new(ctx) ast_struct_specifier(NULL, $3); - $$->set_location(yylloc); + $$->set_location_range(@2, @4); } ; @@ -1918,7 +1929,7 @@ struct_declaration: { void *ctx = state; ast_fully_specified_type *const type = $1; - type->set_location(yylloc); + type->set_location(@1); if (type->qualifier.flags.i != 0) _mesa_glsl_error(&@1, state, @@ -1926,7 +1937,7 @@ struct_declaration: "structure members"); $$ = new(ctx) ast_declarator_list(type); - $$->set_location(yylloc); + $$->set_location(@2); $$->declarations.push_degenerate_list_at_head(& $2->link); } @@ -1950,13 +1961,13 @@ struct_declarator: { void *ctx = state; $$ = new(ctx) ast_declaration($1, NULL, NULL); - $$->set_location(yylloc); + $$->set_location(@1); } | any_identifier array_specifier { void *ctx = state; $$ = new(ctx) ast_declaration($1, $2, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } ; @@ -1977,7 +1988,7 @@ initializer_list: { void *ctx = state; $$ = new(ctx) ast_aggregate_initializer(); - $$->set_location(yylloc); + $$->set_location(@1); $$->expressions.push_tail(& $1->link); } | initializer_list ',' initializer @@ -2011,7 +2022,7 @@ compound_statement: { void *ctx = state; $$ = new(ctx) ast_compound_statement(true, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } | '{' { @@ -2021,7 +2032,7 @@ compound_statement: { void *ctx = state; $$ = new(ctx) ast_compound_statement(true, $3); - $$->set_location(yylloc); + $$->set_location_range(@1, @4); state->symbols->pop_scope(); } ; @@ -2036,13 +2047,13 @@ compound_statement_no_new_scope: { void *ctx = state; $$ = new(ctx) ast_compound_statement(false, NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } | '{' statement_list '}' { void *ctx = state; $$ = new(ctx) ast_compound_statement(false, $2); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -2073,13 +2084,13 @@ expression_statement: { void *ctx = state; $$ = new(ctx) ast_expression_statement(NULL); - $$->set_location(yylloc); + $$->set_location(@1); } | expression ';' { void *ctx = state; $$ = new(ctx) ast_expression_statement($1); - $$->set_location(yylloc); + $$->set_location(@1); } ; @@ -2088,7 +2099,7 @@ selection_statement: { $$ = new(state) ast_selection_statement($3, $5.then_statement, $5.else_statement); - $$->set_location(yylloc); + $$->set_location_range(@1, @5); } ; @@ -2115,8 +2126,8 @@ condition: void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, $4); ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); - decl->set_location(yylloc); - declarator->set_location(yylloc); + decl->set_location_range(@2, @4); + declarator->set_location(@1); declarator->declarations.push_tail(&decl->link); $$ = declarator; @@ -2131,7 +2142,7 @@ switch_statement: SWITCH '(' expression ')' switch_body { $$ = new(state) ast_switch_statement($3, $5); - $$->set_location(yylloc); + $$->set_location_range(@1, @5); } ; @@ -2139,12 +2150,12 @@ switch_body: '{' '}' { $$ = new(state) ast_switch_body(NULL); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } | '{' case_statement_list '}' { $$ = new(state) ast_switch_body($2); - $$->set_location(yylloc); + $$->set_location_range(@1, @3); } ; @@ -2152,12 +2163,12 @@ case_label: CASE expression ':' { $$ = new(state) ast_case_label($2); - $$->set_location(yylloc); + $$->set_location(@2); } | DEFAULT ':' { $$ = new(state) ast_case_label(NULL); - $$->set_location(yylloc); + $$->set_location(@2); } ; @@ -2168,7 +2179,7 @@ case_label_list: labels->labels.push_tail(& $1->link); $$ = labels; - $$->set_location(yylloc); + $$->set_location(@1); } | case_label_list case_label { @@ -2181,7 +2192,7 @@ case_statement: case_label_list statement { ast_case_statement *stmts = new(state) ast_case_statement($1); - stmts->set_location(yylloc); + stmts->set_location(@2); stmts->stmts.push_tail(& $2->link); $$ = stmts; @@ -2197,7 +2208,7 @@ case_statement_list: case_statement { ast_case_statement_list *cases= new(state) ast_case_statement_list(); - cases->set_location(yylloc); + cases->set_location(@1); cases->cases.push_tail(& $1->link); $$ = cases; @@ -2215,21 +2226,21 @@ iteration_statement: void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, NULL, $3, NULL, $5); - $$->set_location(yylloc); + $$->set_location_range(@1, @4); } | DO statement WHILE '(' expression ')' ';' { void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, NULL, $5, NULL, $2); - $$->set_location(yylloc); + $$->set_location_range(@1, @6); } | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope { void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, $3, $4.cond, $4.rest, $6); - $$->set_location(yylloc); + $$->set_location_range(@1, @6); } ; @@ -2265,31 +2276,31 @@ jump_statement: { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); - $$->set_location(yylloc); + $$->set_location(@1); } | BREAK ';' { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); - $$->set_location(yylloc); + $$->set_location(@1); } | RETURN ';' { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); - $$->set_location(yylloc); + $$->set_location(@1); } | RETURN expression ';' { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); } | DISCARD ';' // Fragment shader only. { void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); - $$->set_location(yylloc); + $$->set_location(@1); } ; @@ -2305,7 +2316,7 @@ function_definition: { void *ctx = state; $$ = new(ctx) ast_function_definition(); - $$->set_location(yylloc); + $$->set_location_range(@1, @2); $$->prototype = $1; $$->body = $2; @@ -2454,11 +2465,13 @@ instance_name_opt: { $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, $1, NULL); + $$->set_location(@1); } | NEW_IDENTIFIER array_specifier { $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, $1, $2); + $$->set_location_range(@1, @2); } ; @@ -2480,7 +2493,7 @@ member_declaration: { void *ctx = state; ast_fully_specified_type *type = $1; - type->set_location(yylloc); + type->set_location(@1); if (type->qualifier.flags.q.attribute) { _mesa_glsl_error(& @1, state, @@ -2493,7 +2506,7 @@ member_declaration: } $$ = new(ctx) ast_declarator_list(type); - $$->set_location(yylloc); + $$->set_location(@2); $$->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 d7f5202fe..61ae62150 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -807,8 +807,10 @@ ast_node::print(void) const ast_node::ast_node(void) { this->location.source = 0; - this->location.line = 0; - this->location.column = 0; + this->location.first_line = 0; + this->location.first_column = 0; + this->location.last_line = 0; + this->location.last_column = 0; } diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 1cf376d5d..1c451e7f5 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -775,9 +775,10 @@ link_set_image_access_qualifiers(struct gl_shader_program *prog) if (var && var->data.mode == ir_var_uniform && var->type->contains_image()) { - unsigned id; + unsigned id = 0; bool found = prog->UniformHash->get(id, var->name); assert(found); + (void) found; const gl_uniform_storage *storage = &prog->UniformStorage[id]; const unsigned index = storage->image[i].index; const GLenum access = (var->data.image.read_only ? GL_READ_ONLY : diff --git a/mesalib/src/mapi/entry.c b/mesalib/src/mapi/entry.c index 128f0115d..b6e8db28d 100644 --- a/mesalib/src/mapi/entry.c +++ b/mesalib/src/mapi/entry.c @@ -36,7 +36,7 @@ #ifdef MAPI_MODE_BRIDGE #define ENTRY_CURRENT_TABLE_GET "_glapi_get_dispatch" #else -#define ENTRY_CURRENT_TABLE_GET U_STRINGIFY(u_current_get_internal) +#define ENTRY_CURRENT_TABLE_GET U_STRINGIFY(u_current_get_table_internal) #endif #if defined(USE_X86_ASM) && defined(__GNUC__) @@ -57,7 +57,7 @@ entry_current_get(void) #ifdef MAPI_MODE_BRIDGE return GET_DISPATCH(); #else - return u_current_get(); + return u_current_get_table(); #endif } diff --git a/mesalib/src/mapi/glapi/gen/ARB_debug_output.xml b/mesalib/src/mapi/glapi/gen/ARB_debug_output.xml index 11f268dc6..0468d570c 100644 --- a/mesalib/src/mapi/glapi/gen/ARB_debug_output.xml +++ b/mesalib/src/mapi/glapi/gen/ARB_debug_output.xml @@ -52,7 +52,7 @@ <enum name="DEBUG_SEVERITY_LOW_ARB" value="0x9148"/> - <function name="DebugMessageControlARB" offset="assign"> + <function name="DebugMessageControlARB" alias="DebugMessageControl"> <param name="source" type="GLenum"/> <param name="type" type="GLenum"/> <param name="severity" type="GLenum"/> @@ -61,7 +61,7 @@ <param name="enabled" type="GLboolean"/> </function> - <function name="DebugMessageInsertARB" offset="assign"> + <function name="DebugMessageInsertARB" alias="DebugMessageInsert"> <param name="source" type="GLenum"/> <param name="type" type="GLenum"/> <param name="id" type="GLuint"/> @@ -70,12 +70,12 @@ <param name="buf" type="const GLcharARB *"/> </function> - <function name="DebugMessageCallbackARB" offset="assign"> + <function name="DebugMessageCallbackARB" alias="DebugMessageCallback"> <param name="callback" type="GLDEBUGPROCARB"/> <param name="userParam" type="const GLvoid *"/> </function> - <function name="GetDebugMessageLogARB" offset="assign"> + <function name="GetDebugMessageLogARB" alias="GetDebugMessageLog"> <return type="GLuint"/> <param name="count" type="GLuint"/> <param name="bufsize" type="GLsizei"/> diff --git a/mesalib/src/mapi/glapi/gen/GL4x.xml b/mesalib/src/mapi/glapi/gen/GL4x.xml index 6706278ce..8efef0b91 100644 --- a/mesalib/src/mapi/glapi/gen/GL4x.xml +++ b/mesalib/src/mapi/glapi/gen/GL4x.xml @@ -15,7 +15,7 @@ </category> <category name="4.3"> - + <enum name="DEPTH_STENCIL_TEXTURE_MODE" value="0x90EA"/> </category> </OpenGLAPI> diff --git a/mesalib/src/mapi/glapi/gen/KHR_debug.xml b/mesalib/src/mapi/glapi/gen/KHR_debug.xml new file mode 100644 index 000000000..48f7fa762 --- /dev/null +++ b/mesalib/src/mapi/glapi/gen/KHR_debug.xml @@ -0,0 +1,150 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> + +<OpenGLAPI> + +<category name="GL_KHR_debug" number="119"> + <enum name="DEBUG_OUTPUT" value="0x92E0"/> + <enum name="DEBUG_OUTPUT_SYNCHRONOUS" value="0x8242"/> + + <enum name="CONTEXT_FLAG_DEBUG_BIT" value="0x00000002"/> + + <enum name="MAX_DEBUG_MESSAGE_LENGTH" count="1" value="0x9143"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_DEBUG_LOGGED_MESSAGES" count="1" value="0x9144"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEBUG_LOGGED_MESSAGES" count="1" value="0x9145"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEBUG_NEXT_LOGGED_MESSAGE_LENGTH" count="1" value="0x8243"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_DEBUG_GROUP_STACK_DEPTH" count="1" value="0x826C"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEBUG_GROUP_STACK_DEPTH" count="1" value="0x826D"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_LABEL_LENGTH" count="1" value="0x82E8"> + <size name="Get" mode="get"/> + </enum> + + <enum name="DEBUG_CALLBACK_FUNCTION" count="1" value="0x8244"> + <size name="GetPointerv" mode="get"/> + </enum> + <enum name="DEBUG_CALLBACK_USER_PARAM" count="1" value="0x8245"> + <size name="GetPointerv" mode="get"/> + </enum> + + <enum name="DEBUG_SOURCE_API" value="0x8246"/> + <enum name="DEBUG_SOURCE_WINDOW_SYSTEM" value="0x8247"/> + <enum name="DEBUG_SOURCE_SHADER_COMPILER" value="0x8248"/> + <enum name="DEBUG_SOURCE_THIRD_PARTY" value="0x8249"/> + <enum name="DEBUG_SOURCE_APPLICATION" value="0x824A"/> + <enum name="DEBUG_SOURCE_OTHER" value="0x824B"/> + + <enum name="DEBUG_TYPE_ERROR" value="0x824C"/> + <enum name="DEBUG_TYPE_DEPRECATED_BEHAVIOR" value="0x824D"/> + <enum name="DEBUG_TYPE_UNDEFINED_BEHAVIOR" value="0x824E"/> + <enum name="DEBUG_TYPE_PORTABILITY" value="0x824F"/> + <enum name="DEBUG_TYPE_PERFORMANCE" value="0x8250"/> + <enum name="DEBUG_TYPE_OTHER" value="0x8251"/> + <enum name="DEBUG_TYPE_MARKER" value="0x8268"/> + + <enum name="DEBUG_TYPE_PUSH_GROUP" value="0x8269"/> + <enum name="DEBUG_TYPE_POP_GROUP" value="0x826A"/> + + <enum name="DEBUG_SEVERITY_HIGH" value="0x9146"/> + <enum name="DEBUG_SEVERITY_MEDIUM" value="0x9147"/> + <enum name="DEBUG_SEVERITY_LOW" value="0x9148"/> + <enum name="DEBUG_SEVERITY_NOTIFICATION" value="0x826B"/> + + <enum name="STACK_UNDERFLOW" value="0x0504"/> + <enum name="STACK_OVERFLOW" value="0x0503"/> + + <enum name="BUFFER" value="0x82E0"/> + <enum name="SHADER" value="0x82E1"/> + <enum name="PROGRAM" value="0x82E2"/> + <enum name="QUERY" value="0x82E3"/> + <enum name="PROGRAM_PIPELINE" value="0x82E4"/> + <enum name="SAMPLER" value="0x82E6"/> + <!-- Compatibility Profile --> + <enum name="DISPLAY_LIST" value="0x82E7"/> + + <function name="DebugMessageControl" offset="assign"> + <param name="source" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="severity" type="GLenum"/> + <param name="count" type="GLsizei" counter="true"/> + <param name="ids" type="const GLuint *" count="count"/> + <param name="enabled" type="GLboolean"/> + </function> + + <function name="DebugMessageInsert" offset="assign"> + <param name="source" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="id" type="GLuint"/> + <param name="severity" type="GLenum"/> + <param name="length" type="GLsizei"/> + <param name="buf" type="const GLchar *"/> + </function> + + <function name="DebugMessageCallback" offset="assign"> + <param name="callback" type="GLDEBUGPROC"/> + <param name="userParam" type="const GLvoid *"/> + </function> + + <function name="GetDebugMessageLog" offset="assign"> + <return type="GLuint"/> + <param name="count" type="GLuint"/> + <param name="bufsize" type="GLsizei"/> + <param name="sources" type="GLenum *" output="true"/> + <param name="types" type="GLenum *" output="true"/> + <param name="ids" type="GLuint *" output="true"/> + <param name="severities" type="GLenum *" output="true"/> + <param name="lengths" type="GLsizei *" output="true"/> + <param name="messageLog" type="GLchar *" output="true"/> + </function> + + <function name="PushDebugGroup" offset="assign"> + <param name="source" type="GLenum"/> + <param name="id" type="GLuint"/> + <param name="length" type="GLsizei"/> + <param name="message" type="const GLchar *"/> + </function> + + <function name="PopDebugGroup" offset="assign"/> + + <function name="ObjectLabel" offset="assign"> + <param name="identifier" type="GLenum"/> + <param name="name" type="GLuint"/> + <param name="length" type="GLsizei"/> + <param name="label" type="const GLchar *"/> + </function> + + <function name="GetObjectLabel" offset="assign"> + <param name="identifier" type="GLenum"/> + <param name="name" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="label" type="GLchar *"/> + </function> + + <function name="ObjectPtrLabel" offset="assign"> + <param name="ptr" type="const GLvoid *"/> + <param name="length" type="GLsizei"/> + <param name="label" type="const GLchar *"/> + </function> + + <function name="GetObjectPtrLabel" offset="assign"> + <param name="ptr" type="const GLvoid *"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="label" type="GLchar *"/> + </function> + +</category> + +</OpenGLAPI> diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml index 7e1946e22..9129d5790 100644 --- a/mesalib/src/mapi/glapi/gen/gl_API.xml +++ b/mesalib/src/mapi/glapi/gen/gl_API.xml @@ -8324,149 +8324,7 @@ <!-- ARB extension #118 --> -<category name="GL_KHR_debug" number="119"> - <enum name="DEBUG_OUTPUT" value="0x92E0"/> - <enum name="DEBUG_OUTPUT_SYNCHRONOUS" value="0x8242"/> - - <enum name="CONTEXT_FLAG_DEBUG_BIT" value="0x00000002"/> - - <enum name="MAX_DEBUG_MESSAGE_LENGTH" count="1" value="0x9143"> - <size name="Get" mode="get"/> - </enum> - <enum name="MAX_DEBUG_LOGGED_MESSAGES" count="1" value="0x9144"> - <size name="Get" mode="get"/> - </enum> - <enum name="DEBUG_LOGGED_MESSAGES" count="1" value="0x9145"> - <size name="Get" mode="get"/> - </enum> - <enum name="DEBUG_NEXT_LOGGED_MESSAGE_LENGTH" count="1" value="0x8243"> - <size name="Get" mode="get"/> - </enum> - <enum name="MAX_DEBUG_GROUP_STACK_DEPTH" count="1" value="0x826C"> - <size name="Get" mode="get"/> - </enum> - <enum name="DEBUG_GROUP_STACK_DEPTH" count="1" value="0x826D"> - <size name="Get" mode="get"/> - </enum> - <enum name="MAX_LABEL_LENGTH" count="1" value="0x82E8"> - <size name="Get" mode="get"/> - </enum> - - <enum name="DEBUG_CALLBACK_FUNCTION" count="1" value="0x8244"> - <size name="GetPointerv" mode="get"/> - </enum> - <enum name="DEBUG_CALLBACK_USER_PARAM" count="1" value="0x8245"> - <size name="GetPointerv" mode="get"/> - </enum> - - <enum name="DEBUG_SOURCE_API" value="0x8246"/> - <enum name="DEBUG_SOURCE_WINDOW_SYSTEM" value="0x8247"/> - <enum name="DEBUG_SOURCE_SHADER_COMPILER" value="0x8248"/> - <enum name="DEBUG_SOURCE_THIRD_PARTY" value="0x8249"/> - <enum name="DEBUG_SOURCE_APPLICATION" value="0x824A"/> - <enum name="DEBUG_SOURCE_OTHER" value="0x824B"/> - - <enum name="DEBUG_TYPE_ERROR" value="0x824C"/> - <enum name="DEBUG_TYPE_DEPRECATED_BEHAVIOR" value="0x824D"/> - <enum name="DEBUG_TYPE_UNDEFINED_BEHAVIOR" value="0x824E"/> - <enum name="DEBUG_TYPE_PORTABILITY" value="0x824F"/> - <enum name="DEBUG_TYPE_PERFORMANCE" value="0x8250"/> - <enum name="DEBUG_TYPE_OTHER" value="0x8251"/> - <enum name="DEBUG_TYPE_MARKER" value="0x8268"/> - - <enum name="DEBUG_TYPE_PUSH_GROUP" value="0x8269"/> - <enum name="DEBUG_TYPE_POP_GROUP" value="0x826A"/> - - <enum name="DEBUG_SEVERITY_HIGH" value="0x9146"/> - <enum name="DEBUG_SEVERITY_MEDIUM" value="0x9147"/> - <enum name="DEBUG_SEVERITY_LOW" value="0x9148"/> - <enum name="DEBUG_SEVERITY_NOTIFICATION" value="0x826B"/> - - <enum name="STACK_UNDERFLOW" value="0x0504"/> - <enum name="STACK_OVERFLOW" value="0x0503"/> - - <enum name="BUFFER" value="0x82E0"/> - <enum name="SHADER" value="0x82E1"/> - <enum name="PROGRAM" value="0x82E2"/> - <enum name="QUERY" value="0x82E3"/> - <enum name="PROGRAM_PIPELINE" value="0x82E4"/> - <enum name="SAMPLER" value="0x82E6"/> - <!-- Compatibility Profile --> - <enum name="DISPLAY_LIST" value="0x82E7"/> - - <function name="DebugMessageControl" offset="assign"> - <param name="source" type="GLenum"/> - <param name="type" type="GLenum"/> - <param name="severity" type="GLenum"/> - <param name="count" type="GLsizei" counter="true"/> - <param name="ids" type="const GLuint *" count="count"/> - <param name="enabled" type="GLboolean"/> - </function> - - <function name="DebugMessageInsert" offset="assign"> - <param name="source" type="GLenum"/> - <param name="type" type="GLenum"/> - <param name="id" type="GLuint"/> - <param name="severity" type="GLenum"/> - <param name="length" type="GLsizei"/> - <param name="buf" type="const GLchar *"/> - </function> - - <function name="DebugMessageCallback" offset="assign"> - <param name="callback" type="GLDEBUGPROC"/> - <param name="userParam" type="const GLvoid *"/> - </function> - - <function name="GetDebugMessageLog" offset="assign"> - <return type="GLuint"/> - <param name="count" type="GLuint"/> - <param name="bufsize" type="GLsizei"/> - <param name="sources" type="GLenum *" output="true"/> - <param name="types" type="GLenum *" output="true"/> - <param name="ids" type="GLuint *" output="true"/> - <param name="severities" type="GLenum *" output="true"/> - <param name="lengths" type="GLsizei *" output="true"/> - <param name="messageLog" type="GLchar *" output="true"/> - </function> - - <function name="PushDebugGroup" offset="assign"> - <param name="source" type="GLenum"/> - <param name="id" type="GLuint"/> - <param name="length" type="GLsizei"/> - <param name="message" type="const GLchar *"/> - </function> - - <function name="PopDebugGroup" offset="assign"/> - - <function name="ObjectLabel" offset="assign"> - <param name="identifier" type="GLenum"/> - <param name="name" type="GLuint"/> - <param name="length" type="GLsizei"/> - <param name="label" type="const GLchar *"/> - </function> - - <function name="GetObjectLabel" offset="assign"> - <param name="identifier" type="GLenum"/> - <param name="name" type="GLuint"/> - <param name="bufSize" type="GLsizei"/> - <param name="length" type="GLsizei *"/> - <param name="label" type="GLchar *"/> - </function> - - <function name="ObjectPtrLabel" offset="assign"> - <param name="ptr" type="const GLvoid *"/> - <param name="length" type="GLsizei"/> - <param name="label" type="const GLchar *"/> - </function> - - <function name="GetObjectPtrLabel" offset="assign"> - <param name="ptr" type="const GLvoid *"/> - <param name="bufSize" type="GLsizei"/> - <param name="length" type="GLsizei *"/> - <param name="label" type="GLchar *"/> - </function> - -</category> +<xi:include href="KHR_debug.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> <!-- ARB extension #120 --> diff --git a/mesalib/src/mapi/glapi/glapi.c b/mesalib/src/mapi/glapi/glapi.c index 3a0b638f7..194b9ee86 100644 --- a/mesalib/src/mapi/glapi/glapi.c +++ b/mesalib/src/mapi/glapi/glapi.c @@ -54,11 +54,11 @@ _glapi_check_multithread(void) void _glapi_set_context(void *context) { - u_current_set_user((const void *) context); + u_current_set_context((const void *) context); } void _glapi_set_dispatch(struct _glapi_table *dispatch) { - u_current_set((const struct mapi_table *) dispatch); + u_current_set_table((const struct mapi_table *) dispatch); } diff --git a/mesalib/src/mapi/glapi/glapi.h b/mesalib/src/mapi/glapi/glapi.h index dcf91a7f3..7c22985ec 100644 --- a/mesalib/src/mapi/glapi/glapi.h +++ b/mesalib/src/mapi/glapi/glapi.h @@ -168,10 +168,6 @@ _GLAPI_EXPORT struct _glapi_table * _glapi_create_table_from_handle(void *handle, const char *symbol_prefix); -_GLAPI_EXPORT unsigned long -_glthread_GetID(void); - - /* * These stubs are kept so that the old DRI drivers still load. */ diff --git a/mesalib/src/mapi/mapi.c b/mesalib/src/mapi/mapi.c index 56f209bfa..aa6b91b42 100644 --- a/mesalib/src/mapi/mapi.c +++ b/mesalib/src/mapi/mapi.c @@ -72,15 +72,15 @@ get_stub(const char *name, const struct mapi_stub *alias) void mapi_init(const char *spec) { - u_mutex_declare_static(mutex); + static mtx_t mutex = _MTX_INITIALIZER_NP; const char *p; int ver, count; - u_mutex_lock(mutex); + mtx_lock(&mutex); /* already initialized */ if (mapi_num_stubs) { - u_mutex_unlock(mutex); + mtx_unlock(&mutex); return; } @@ -90,7 +90,7 @@ mapi_init(const char *spec) /* parse version string */ ver = atoi(p); if (ver != 1) { - u_mutex_unlock(mutex); + mtx_unlock(&mutex); return; } p += strlen(p) + 1; @@ -115,7 +115,7 @@ mapi_init(const char *spec) mapi_num_stubs = count; - u_mutex_unlock(mutex); + mtx_unlock(&mutex); } /** @@ -186,5 +186,5 @@ mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs) void mapi_table_make_current(const struct mapi_table *tbl) { - u_current_set(tbl); + u_current_set_table(tbl); } diff --git a/mesalib/src/mapi/mapi_glapi.c b/mesalib/src/mapi/mapi_glapi.c index 7b9f1aee4..7b0903be9 100644 --- a/mesalib/src/mapi/mapi_glapi.c +++ b/mesalib/src/mapi/mapi_glapi.c @@ -58,13 +58,13 @@ _glapi_check_multithread(void) void _glapi_set_context(void *context) { - u_current_set_user((const void *) context); + u_current_set_context((const void *) context); } void _glapi_set_dispatch(struct _glapi_table *dispatch) { - u_current_set((const struct mapi_table *) dispatch); + u_current_set_table((const struct mapi_table *) dispatch); } /** @@ -222,12 +222,6 @@ _glapi_get_proc_name(unsigned int offset) return stub ? stub_get_name(stub) : NULL; } -unsigned long -_glthread_GetID(void) -{ - return u_thread_self(); -} - void _glapi_noop_enable_warnings(unsigned char enable) { diff --git a/mesalib/src/mapi/stub.c b/mesalib/src/mapi/stub.c index acd2c0a79..dfadbe1a5 100644 --- a/mesalib/src/mapi/stub.c +++ b/mesalib/src/mapi/stub.c @@ -126,11 +126,11 @@ stub_add_dynamic(const char *name) struct mapi_stub * stub_find_dynamic(const char *name, int generate) { - u_mutex_declare_static(dynamic_mutex); + static mtx_t dynamic_mutex = _MTX_INITIALIZER_NP; struct mapi_stub *stub = NULL; int count, i; - u_mutex_lock(dynamic_mutex); + mtx_lock(&dynamic_mutex); if (generate) assert(!stub_find_public(name)); @@ -147,7 +147,7 @@ stub_find_dynamic(const char *name, int generate) if (generate && !stub) stub = stub_add_dynamic(name); - u_mutex_unlock(dynamic_mutex); + mtx_unlock(&dynamic_mutex); return stub; } diff --git a/mesalib/src/mapi/u_current.c b/mesalib/src/mapi/u_current.c index 07213380d..afa887e06 100644 --- a/mesalib/src/mapi/u_current.c +++ b/mesalib/src/mapi/u_current.c @@ -103,18 +103,18 @@ __thread struct mapi_table *u_current_table __attribute__((tls_model("initial-exec"))) = (struct mapi_table *) table_noop_array; -__thread void *u_current_user +__thread void *u_current_context __attribute__((tls_model("initial-exec"))); #else struct mapi_table *u_current_table = (struct mapi_table *) table_noop_array; -void *u_current_user; +void *u_current_context; #ifdef THREADS struct u_tsd u_current_table_tsd; -static struct u_tsd u_current_user_tsd; +static struct u_tsd u_current_context_tsd; static int ThreadSafe; #endif /* THREADS */ @@ -127,7 +127,7 @@ u_current_destroy(void) { #if defined(THREADS) && defined(_WIN32) u_tsd_destroy(&u_current_table_tsd); - u_tsd_destroy(&u_current_user_tsd); + u_tsd_destroy(&u_current_context_tsd); #endif } @@ -138,13 +138,13 @@ static void u_current_init_tsd(void) { u_tsd_init(&u_current_table_tsd); - u_tsd_init(&u_current_user_tsd); + u_tsd_init(&u_current_context_tsd); } /** * Mutex for multithread check. */ -u_mutex_declare_static(ThreadCheckMutex); +static mtx_t ThreadCheckMutex = _MTX_INITIALIZER_NP; /** * We should call this periodically from a function such as glXMakeCurrent @@ -159,7 +159,7 @@ u_current_init(void) if (ThreadSafe) return; - u_mutex_lock(ThreadCheckMutex); + mtx_lock(&ThreadCheckMutex); if (firstCall) { u_current_init_tsd(); @@ -168,10 +168,10 @@ u_current_init(void) } else if (knownID != u_thread_self()) { ThreadSafe = 1; - u_current_set(NULL); - u_current_set_user(NULL); + u_current_set_table(NULL); + u_current_set_context(NULL); } - u_mutex_unlock(ThreadCheckMutex); + mtx_unlock(&ThreadCheckMutex); } #else @@ -191,17 +191,17 @@ u_current_init(void) * void from the real context pointer type. */ void -u_current_set_user(const void *ptr) +u_current_set_context(const void *ptr) { u_current_init(); #if defined(GLX_USE_TLS) - u_current_user = (void *) ptr; + u_current_context = (void *) ptr; #elif defined(THREADS) - u_tsd_set(&u_current_user_tsd, (void *) ptr); - u_current_user = (ThreadSafe) ? NULL : (void *) ptr; + u_tsd_set(&u_current_context_tsd, (void *) ptr); + u_current_context = (ThreadSafe) ? NULL : (void *) ptr; #else - u_current_user = (void *) ptr; + u_current_context = (void *) ptr; #endif } @@ -211,16 +211,16 @@ u_current_set_user(const void *ptr) * void to the real context pointer type. */ void * -u_current_get_user_internal(void) +u_current_get_context_internal(void) { #if defined(GLX_USE_TLS) - return u_current_user; + return u_current_context; #elif defined(THREADS) return (ThreadSafe) - ? u_tsd_get(&u_current_user_tsd) - : u_current_user; + ? u_tsd_get(&u_current_context_tsd) + : u_current_context; #else - return u_current_user; + return u_current_context; #endif } @@ -230,7 +230,7 @@ u_current_get_user_internal(void) * table (__glapi_noop_table). */ void -u_current_set(const struct mapi_table *tbl) +u_current_set_table(const struct mapi_table *tbl) { u_current_init(); @@ -253,7 +253,7 @@ u_current_set(const struct mapi_table *tbl) * Return pointer to current dispatch table for calling thread. */ struct mapi_table * -u_current_get_internal(void) +u_current_get_table_internal(void) { #if defined(GLX_USE_TLS) return u_current_table; diff --git a/mesalib/src/mapi/u_current.h b/mesalib/src/mapi/u_current.h index f9cffd8c3..72708d433 100644 --- a/mesalib/src/mapi/u_current.h +++ b/mesalib/src/mapi/u_current.h @@ -11,14 +11,14 @@ #ifdef GLX_USE_TLS #define u_current_table _glapi_tls_Dispatch -#define u_current_user _glapi_tls_Context +#define u_current_context _glapi_tls_Context #else #define u_current_table _glapi_Dispatch -#define u_current_user _glapi_Context +#define u_current_context _glapi_Context #endif -#define u_current_get_internal _glapi_get_dispatch -#define u_current_get_user_internal _glapi_get_context +#define u_current_get_table_internal _glapi_get_dispatch +#define u_current_get_context_internal _glapi_get_context #define u_current_table_tsd _gl_DispatchTSD @@ -33,13 +33,13 @@ struct mapi_table; extern __thread struct mapi_table *u_current_table __attribute__((tls_model("initial-exec"))); -extern __thread void *u_current_user +extern __thread void *u_current_context __attribute__((tls_model("initial-exec"))); #else /* GLX_USE_TLS */ extern struct mapi_table *u_current_table; -extern void *u_current_user; +extern void *u_current_context; #endif /* GLX_USE_TLS */ @@ -52,35 +52,35 @@ void u_current_destroy(void); void -u_current_set(const struct mapi_table *tbl); +u_current_set_table(const struct mapi_table *tbl); struct mapi_table * -u_current_get_internal(void); +u_current_get_table_internal(void); void -u_current_set_user(const void *ptr); +u_current_set_context(const void *ptr); void * -u_current_get_user_internal(void); +u_current_get_context_internal(void); static INLINE const struct mapi_table * -u_current_get(void) +u_current_get_table(void) { #ifdef GLX_USE_TLS return u_current_table; #else return (likely(u_current_table) ? - u_current_table : u_current_get_internal()); + u_current_table : u_current_get_table_internal()); #endif } static INLINE const void * -u_current_get_user(void) +u_current_get_context(void) { #ifdef GLX_USE_TLS - return u_current_user; + return u_current_context; #else - return likely(u_current_user) ? u_current_user : u_current_get_user_internal(); + return likely(u_current_context) ? u_current_context : u_current_get_context_internal(); #endif } diff --git a/mesalib/src/mapi/u_execmem.c b/mesalib/src/mapi/u_execmem.c index 357365263..ac1cae093 100644 --- a/mesalib/src/mapi/u_execmem.c +++ b/mesalib/src/mapi/u_execmem.c @@ -39,7 +39,7 @@ #define EXEC_MAP_SIZE (4*1024) -u_mutex_declare_static(exec_mutex); +static mtx_t exec_mutex = _MTX_INITIALIZER_NP; static unsigned int head = 0; @@ -123,7 +123,7 @@ u_execmem_alloc(unsigned int size) { void *addr = NULL; - u_mutex_lock(exec_mutex); + mtx_lock(&exec_mutex); if (!init_map()) goto bail; @@ -137,7 +137,7 @@ u_execmem_alloc(unsigned int size) head += size; bail: - u_mutex_unlock(exec_mutex); + mtx_unlock(&exec_mutex); return addr; } diff --git a/mesalib/src/mapi/u_thread.h b/mesalib/src/mapi/u_thread.h index ba5d98ea9..57c3b076a 100644 --- a/mesalib/src/mapi/u_thread.h +++ b/mesalib/src/mapi/u_thread.h @@ -57,9 +57,9 @@ /* * Error messages */ -#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data" -#define GET_TSD_ERROR "_glthread_: failed to get thread specific data" -#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data" +#define INIT_TSD_ERROR "Mesa: failed to allocate key for thread specific data" +#define GET_TSD_ERROR "Mesa: failed to get thread specific data" +#define SET_TSD_ERROR "Mesa: thread failed to set thread specific data" /* @@ -79,20 +79,28 @@ struct u_tsd { unsigned initMagic; }; -typedef mtx_t u_mutex; - -#define u_mutex_declare_static(name) \ - static u_mutex name = _MTX_INITIALIZER_NP - -#define u_mutex_init(name) mtx_init(&(name), mtx_plain) -#define u_mutex_destroy(name) mtx_destroy(&(name)) -#define u_mutex_lock(name) (void) mtx_lock(&(name)) -#define u_mutex_unlock(name) (void) mtx_unlock(&(name)) static INLINE unsigned long u_thread_self(void) { + /* + * XXX: Callers of u_thread_self assume it is a lightweight function, + * returning a numeric value. But unfortunately C11's thrd_current() gives + * no such guarantees. In fact, it's pretty hard to have a compliant + * implementation of thrd_current() on Windows with such characteristics. + * So for now, we side-step this mess and use Windows thread primitives + * directly here. + * + * FIXME: On the other hand, u_thread_self() is a bad + * abstraction. Even with pthreads, there is no guarantee that + * pthread_self() will return numeric IDs -- we should be using + * pthread_equal() instead of assuming we can compare thread ids... + */ +#ifdef _WIN32 + return GetCurrentThreadId(); +#else return (unsigned long) (uintptr_t) thrd_current(); +#endif } diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am index ffe65990d..16ac148af 100644 --- a/mesalib/src/mesa/Makefile.am +++ b/mesalib/src/mesa/Makefile.am @@ -70,7 +70,7 @@ BUILT_SOURCES = \ CLEANFILES = \ $(BUILT_SOURCES) \ $(BUILDDIR)program/program_parse.tab.h \ - git_sha1.h.tmp + $(BUILDDIR)main/git_sha1.h.tmp GET_HASH_GEN = main/get_hash_generator.py diff --git a/mesalib/src/mesa/Makefile.sources b/mesalib/src/mesa/Makefile.sources index f6f4062a4..f4904fbbd 100644 --- a/mesalib/src/mesa/Makefile.sources +++ b/mesalib/src/mesa/Makefile.sources @@ -321,6 +321,7 @@ SPARC_FILES = \ COMMON_DRIVER_FILES = \ $(SRCDIR)drivers/common/driverfuncs.c \ $(SRCDIR)drivers/common/meta_blit.c \ + $(SRCDIR)drivers/common/meta_generate_mipmap.c \ $(SRCDIR)drivers/common/meta.c diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index 7f4e41983..cd959be65 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -326,7 +326,8 @@ program_sources = [ common_driver_sources = [ 'drivers/common/driverfuncs.c', 'drivers/common/meta.c', - 'drivers/common/meta_blit.c' + 'drivers/common/meta_blit.c', + 'drivers/common/meta_generate_mipmap.c' ] mesa_sources = ( diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index cde34f99f..030e1116e 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -89,7 +89,6 @@ choose_blit_shader(GLenum target, struct blit_shader_table *table); static void cleanup_temp_texture(struct temp_texture *tex); static void meta_glsl_clear_cleanup(struct clear_state *clear); -static void meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap); static void meta_decompress_cleanup(struct decompress_state *decompress); static void meta_drawpix_cleanup(struct drawpix_state *drawpix); @@ -361,7 +360,7 @@ _mesa_meta_free(struct gl_context *ctx) _mesa_make_current(ctx, NULL, NULL); _mesa_meta_glsl_blit_cleanup(&ctx->Meta->Blit); meta_glsl_clear_cleanup(&ctx->Meta->Clear); - meta_glsl_generate_mipmap_cleanup(&ctx->Meta->Mipmap); + _mesa_meta_glsl_generate_mipmap_cleanup(&ctx->Meta->Mipmap); cleanup_temp_texture(&ctx->Meta->TempTex); meta_decompress_cleanup(&ctx->Meta->Decompress); meta_drawpix_cleanup(&ctx->Meta->DrawPix); @@ -2360,102 +2359,6 @@ _mesa_meta_Bitmap(struct gl_context *ctx, _mesa_meta_end(ctx); } - -/** - * Check if the call to _mesa_meta_GenerateMipmap() will require a - * software fallback. The fallback path will require that the texture - * images are mapped. - * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise - */ -GLboolean -_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - const GLuint fboSave = ctx->DrawBuffer->Name; - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct gl_texture_image *baseImage; - GLuint srcLevel; - GLenum status; - - /* check for fallbacks */ - if (target == GL_TEXTURE_3D || - target == GL_TEXTURE_1D_ARRAY || - target == GL_TEXTURE_2D_ARRAY) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() to %s target\n", - _mesa_lookup_enum_by_nr(target)); - return GL_TRUE; - } - - srcLevel = texObj->BaseLevel; - baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel); - if (!baseImage) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() couldn't find base teximage\n"); - return GL_TRUE; - } - - if (_mesa_is_format_compressed(baseImage->TexFormat)) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() with %s format\n", - _mesa_get_format_name(baseImage->TexFormat)); - return GL_TRUE; - } - - if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB && - !ctx->Extensions.EXT_texture_sRGB_decode) { - /* The texture format is sRGB but we can't turn off sRGB->linear - * texture sample conversion. So we won't be able to generate the - * right colors when rendering. Need to use a fallback. - */ - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() of sRGB texture without " - "sRGB decode\n"); - return GL_TRUE; - } - - /* - * Test that we can actually render in the texture's format. - */ - if (!mipmap->FBO) - _mesa_GenFramebuffers(1, &mipmap->FBO); - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); - - if (target == GL_TEXTURE_1D) { - _mesa_FramebufferTexture1D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel); - } -#if 0 - /* other work is needed to enable 3D mipmap generation */ - else if (target == GL_TEXTURE_3D) { - GLint zoffset = 0; - _mesa_FramebufferTexture3D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel, zoffset); - } -#endif - else { - /* 2D / cube */ - _mesa_FramebufferTexture2D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel); - } - - status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); - - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() got incomplete FBO\n"); - return GL_TRUE; - } - - return GL_FALSE; -} - - /** * Compute the texture coordinates for the four vertices of a quad for * drawing a 2D texture image or slice of a cube/3D texture. @@ -2465,16 +2368,16 @@ _mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target, * \param height height of the texture image * \param coords0/1/2/3 returns the computed texcoords */ -static void -setup_texture_coords(GLenum faceTarget, - GLint slice, - GLint width, - GLint height, - GLint depth, - GLfloat coords0[4], - GLfloat coords1[4], - GLfloat coords2[4], - GLfloat coords3[4]) +void +_mesa_meta_setup_texture_coords(GLenum faceTarget, + GLint slice, + GLint width, + GLint height, + GLint depth, + GLfloat coords0[4], + GLfloat coords1[4], + GLfloat coords2[4], + GLfloat coords3[4]) { static const GLfloat st[4][2] = { {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} @@ -2618,7 +2521,7 @@ setup_texture_coords(GLenum faceTarget, } break; default: - assert(0 && "unexpected target in meta setup_texture_coords()"); + assert(!"unexpected target in _mesa_meta_setup_texture_coords()"); } } @@ -2698,245 +2601,6 @@ _mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table) table->sampler_cubemap_array.shader_prog = 0; } -static void -meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap) -{ - if (mipmap->VAO == 0) - return; - _mesa_DeleteVertexArrays(1, &mipmap->VAO); - mipmap->VAO = 0; - _mesa_DeleteBuffers(1, &mipmap->VBO); - mipmap->VBO = 0; - - _mesa_meta_blit_shader_table_cleanup(&mipmap->shaders); -} - - -/** - * Called via ctx->Driver.GenerateMipmap() - * Note: We don't yet support 3D textures, 1D/2D array textures or texture - * borders. - */ -void -_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct vertex verts[4]; - const GLuint baseLevel = texObj->BaseLevel; - const GLuint maxLevel = texObj->MaxLevel; - const GLint maxLevelSave = texObj->MaxLevel; - const GLboolean genMipmapSave = texObj->GenerateMipmap; - const GLuint fboSave = ctx->DrawBuffer->Name; - const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit; - const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader; - GLenum faceTarget; - GLuint dstLevel; - const GLint slice = 0; - GLuint samplerSave; - - if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { - _mesa_generate_mipmap(ctx, target, texObj); - return; - } - - if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { - faceTarget = target; - target = GL_TEXTURE_CUBE_MAP; - } - else { - faceTarget = target; - } - - _mesa_meta_begin(ctx, MESA_META_ALL); - - /* Choose between glsl version and fixed function version of - * GenerateMipmap function. - */ - if (use_glsl_version) { - _mesa_meta_setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true, - 2, 3, 0); - _mesa_meta_setup_blit_shader(ctx, target, &mipmap->shaders); - } - else { - _mesa_meta_setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3); - _mesa_set_enable(ctx, target, GL_TRUE); - } - - samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; - - if (currentTexUnitSave != 0) - _mesa_BindTexture(target, texObj->Name); - - if (!mipmap->FBO) { - _mesa_GenFramebuffers(1, &mipmap->FBO); - } - - if (!mipmap->Sampler) { - _mesa_GenSamplers(1, &mipmap->Sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); - - _mesa_SamplerParameteri(mipmap->Sampler, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - /* We don't want to encode or decode sRGB values; treat them as linear. - * This is not technically correct for GLES3 but we don't get any API - * error at the moment. - */ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); - } - - } else { - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); - } - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); - - _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - /* Setup texture coordinates */ - setup_texture_coords(faceTarget, - slice, - 0, 0, 1, /* width, height never used here */ - verts[0].tex, - verts[1].tex, - verts[2].tex, - verts[3].tex); - - /* setup vertex positions */ - verts[0].x = -1.0F; - verts[0].y = -1.0F; - verts[1].x = 1.0F; - verts[1].y = -1.0F; - verts[2].x = 1.0F; - verts[2].y = 1.0F; - verts[3].x = -1.0F; - verts[3].y = 1.0F; - - /* upload vertex data */ - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - verts, GL_DYNAMIC_DRAW_ARB); - - /* texture is already locked, unlock now */ - _mesa_unlock_texture(ctx, texObj); - - for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { - const struct gl_texture_image *srcImage; - const GLuint srcLevel = dstLevel - 1; - GLsizei srcWidth, srcHeight, srcDepth; - GLsizei dstWidth, dstHeight, dstDepth; - GLenum status; - - srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel); - assert(srcImage->Border == 0); - - /* src size */ - srcWidth = srcImage->Width; - srcHeight = srcImage->Height; - srcDepth = srcImage->Depth; - - /* new dst size */ - dstWidth = MAX2(1, srcWidth / 2); - dstHeight = MAX2(1, srcHeight / 2); - dstDepth = MAX2(1, srcDepth / 2); - - if (dstWidth == srcImage->Width && - dstHeight == srcImage->Height && - dstDepth == srcImage->Depth) { - /* all done */ - break; - } - - /* Allocate storage for the destination mipmap image(s) */ - - /* Set MaxLevel large enough to hold the new level when we allocate it */ - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); - - if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel, - dstWidth, dstHeight, dstDepth, - srcImage->Border, - srcImage->InternalFormat, - srcImage->TexFormat)) { - /* All done. We either ran out of memory or we would go beyond the - * last valid level of an immutable texture if we continued. - */ - break; - } - - /* limit minification to src level */ - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); - - /* Set to draw into the current dstLevel */ - if (target == GL_TEXTURE_1D) { - _mesa_FramebufferTexture1D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texObj->Name, - dstLevel); - } - else if (target == GL_TEXTURE_3D) { - GLint zoffset = 0; /* XXX unfinished */ - _mesa_FramebufferTexture3D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texObj->Name, - dstLevel, zoffset); - } - else { - /* 2D / cube */ - _mesa_FramebufferTexture2D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - faceTarget, - texObj->Name, - dstLevel); - } - - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - /* sanity check */ - status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_problem(ctx, "Unexpected incomplete framebuffer in " - "_mesa_meta_GenerateMipmap()"); - break; - } - - assert(dstWidth == ctx->DrawBuffer->Width); - assert(dstHeight == ctx->DrawBuffer->Height); - - /* setup viewport */ - _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - _mesa_lock_texture(ctx, texObj); /* relock */ - - _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); - - _mesa_meta_end(ctx); - - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); - if (genMipmapSave) - _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); -} - - /** * Determine the GL data type to use for the temporary image read with * ReadPixels() and passed to Tex[Sub]Image(). @@ -3219,11 +2883,11 @@ decompress_texture_image(struct gl_context *ctx, /* Silence valgrind warnings about reading uninitialized stack. */ memset(verts, 0, sizeof(verts)); - setup_texture_coords(faceTarget, slice, width, height, depth, - verts[0].tex, - verts[1].tex, - verts[2].tex, - verts[3].tex); + _mesa_meta_setup_texture_coords(faceTarget, slice, width, height, depth, + verts[0].tex, + verts[1].tex, + verts[2].tex, + verts[3].tex); /* setup vertex positions */ verts[0].x = -1.0F; diff --git a/mesalib/src/mesa/drivers/common/meta.h b/mesalib/src/mesa/drivers/common/meta.h index fcf45c403..6029a775c 100644 --- a/mesalib/src/mesa/drivers/common/meta.h +++ b/mesalib/src/mesa/drivers/common/meta.h @@ -410,10 +410,6 @@ _mesa_meta_Bitmap(struct gl_context *ctx, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap); -extern GLboolean -_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj); - extern void _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj); @@ -448,6 +444,17 @@ GLboolean _mesa_meta_alloc_texture(struct temp_texture *tex, GLsizei width, GLsizei height, GLenum intFormat); +void +_mesa_meta_setup_texture_coords(GLenum faceTarget, + GLint slice, + GLint width, + GLint height, + GLint depth, + GLfloat coords0[4], + GLfloat coords1[4], + GLfloat coords2[4], + GLfloat coords3[4]); + struct temp_texture * _mesa_meta_get_temp_texture(struct gl_context *ctx); @@ -491,4 +498,7 @@ _mesa_meta_glsl_blit_cleanup(struct blit_state *blit); void _mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table); +void +_mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap); + #endif /* META_H */ diff --git a/mesalib/src/mesa/drivers/common/meta_generate_mipmap.c b/mesalib/src/mesa/drivers/common/meta_generate_mipmap.c new file mode 100644 index 000000000..3db073ab1 --- /dev/null +++ b/mesalib/src/mesa/drivers/common/meta_generate_mipmap.c @@ -0,0 +1,383 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * 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 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. + */ + +/** + * Meta operations. Some GL operations can be expressed in terms of + * other GL operations. For example, glBlitFramebuffer() can be done + * with texture mapping and glClear() can be done with polygon rendering. + * + * \author Brian Paul + */ + +#include "main/arrayobj.h" +#include "main/buffers.h" +#include "main/enums.h" +#include "main/enable.h" +#include "main/fbobject.h" +#include "main/macros.h" +#include "main/mipmap.h" +#include "main/teximage.h" +#include "main/texobj.h" +#include "main/texparam.h" +#include "main/varray.h" +#include "main/viewport.h" +#include "drivers/common/meta.h" + +/** + * Bind a particular texture level/layer to mipmap->FBO's GL_COLOR_ATTACHMENT0. + */ +static void +bind_fbo_image(struct gl_texture_object *texObj, GLenum target, + GLuint level, GLuint layer) +{ + switch (target) { + case GL_TEXTURE_1D: + _mesa_FramebufferTexture1D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + target, + texObj->Name, + level); + break; + case GL_TEXTURE_1D_ARRAY: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_3D: + _mesa_FramebufferTextureLayer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + texObj->Name, + level, + layer); + break; + default: /* 2D / cube */ + _mesa_FramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + target, + texObj->Name, + level); + } +} + +/** + * Check if the call to _mesa_meta_GenerateMipmap() will require a + * software fallback. The fallback path will require that the texture + * images are mapped. + * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise + */ +static bool +fallback_required(struct gl_context *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + const GLuint fboSave = ctx->DrawBuffer->Name; + struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; + struct gl_texture_image *baseImage; + GLuint srcLevel; + GLenum status; + + /* check for fallbacks */ + if (target == GL_TEXTURE_3D) { + _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, + "glGenerateMipmap() to %s target\n", + _mesa_lookup_enum_by_nr(target)); + return true; + } + + srcLevel = texObj->BaseLevel; + baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel); + if (!baseImage) { + _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, + "glGenerateMipmap() couldn't find base teximage\n"); + return true; + } + + if (_mesa_is_format_compressed(baseImage->TexFormat)) { + _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, + "glGenerateMipmap() with %s format\n", + _mesa_get_format_name(baseImage->TexFormat)); + return true; + } + + if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB && + !ctx->Extensions.EXT_texture_sRGB_decode) { + /* The texture format is sRGB but we can't turn off sRGB->linear + * texture sample conversion. So we won't be able to generate the + * right colors when rendering. Need to use a fallback. + */ + _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, + "glGenerateMipmap() of sRGB texture without " + "sRGB decode\n"); + return true; + } + + /* + * Test that we can actually render in the texture's format. + */ + if (!mipmap->FBO) + _mesa_GenFramebuffers(1, &mipmap->FBO); + _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); + + bind_fbo_image(texObj, target, srcLevel, 0); + + status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT); + + _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); + + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, + "glGenerateMipmap() got incomplete FBO\n"); + return true; + } + + return false; +} + +void +_mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap) +{ + if (mipmap->VAO == 0) + return; + _mesa_DeleteVertexArrays(1, &mipmap->VAO); + mipmap->VAO = 0; + _mesa_DeleteBuffers(1, &mipmap->VBO); + mipmap->VBO = 0; + + _mesa_meta_blit_shader_table_cleanup(&mipmap->shaders); +} + +static GLboolean +prepare_mipmap_level(struct gl_context *ctx, + struct gl_texture_object *texObj, GLuint level, + GLsizei width, GLsizei height, GLsizei depth, + GLenum intFormat, mesa_format format) +{ + if (texObj->Target == GL_TEXTURE_1D_ARRAY) { + /* Work around Mesa expecting the number of array slices in "height". */ + height = depth; + depth = 1; + } + + return _mesa_prepare_mipmap_level(ctx, texObj, level, width, height, depth, + 0, intFormat, format); +} + +/** + * Called via ctx->Driver.GenerateMipmap() + * Note: We don't yet support 3D textures, 1D/2D array textures or texture + * borders. + */ +void +_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; + struct vertex verts[4]; + const GLuint baseLevel = texObj->BaseLevel; + const GLuint maxLevel = texObj->MaxLevel; + const GLint maxLevelSave = texObj->MaxLevel; + const GLboolean genMipmapSave = texObj->GenerateMipmap; + const GLuint fboSave = ctx->DrawBuffer->Name; + const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit; + const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && + ctx->Extensions.ARB_fragment_shader; + GLenum faceTarget; + GLuint dstLevel; + GLuint samplerSave; + + if (fallback_required(ctx, target, texObj)) { + _mesa_generate_mipmap(ctx, target, texObj); + return; + } + + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { + faceTarget = target; + target = GL_TEXTURE_CUBE_MAP; + } else { + faceTarget = target; + } + + _mesa_meta_begin(ctx, MESA_META_ALL); + + /* Choose between glsl version and fixed function version of + * GenerateMipmap function. + */ + if (use_glsl_version) { + _mesa_meta_setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true, + 2, 3, 0); + _mesa_meta_setup_blit_shader(ctx, target, &mipmap->shaders); + } else { + _mesa_meta_setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3); + _mesa_set_enable(ctx, target, GL_TRUE); + } + + samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? + ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; + + if (currentTexUnitSave != 0) + _mesa_BindTexture(target, texObj->Name); + + if (!mipmap->Sampler) { + _mesa_GenSamplers(1, &mipmap->Sampler); + _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); + + _mesa_SamplerParameteri(mipmap->Sampler, + GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + /* We don't want to encode or decode sRGB values; treat them as linear. + * This is not technically correct for GLES3 but we don't get any API + * error at the moment. + */ + if (ctx->Extensions.EXT_texture_sRGB_decode) { + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, + GL_SKIP_DECODE_EXT); + } + } else { + _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); + } + + assert(mipmap->FBO != 0); + _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); + + _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); + + /* Silence valgrind warnings about reading uninitialized stack. */ + memset(verts, 0, sizeof(verts)); + + /* setup vertex positions */ + verts[0].x = -1.0F; + verts[0].y = -1.0F; + verts[1].x = 1.0F; + verts[1].y = -1.0F; + verts[2].x = 1.0F; + verts[2].y = 1.0F; + verts[3].x = -1.0F; + verts[3].y = 1.0F; + + /* texture is already locked, unlock now */ + _mesa_unlock_texture(ctx, texObj); + + for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { + const struct gl_texture_image *srcImage; + const GLuint srcLevel = dstLevel - 1; + GLuint layer; + GLsizei srcWidth, srcHeight, srcDepth; + GLsizei dstWidth, dstHeight, dstDepth; + + srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel); + assert(srcImage->Border == 0); + + /* src size */ + srcWidth = srcImage->Width; + if (target == GL_TEXTURE_1D_ARRAY) { + srcHeight = 1; + srcDepth = srcImage->Height; + } else { + srcHeight = srcImage->Height; + srcDepth = srcImage->Depth; + } + + /* new dst size */ + dstWidth = minify(srcWidth, 1); + dstHeight = minify(srcHeight, 1); + dstDepth = target == GL_TEXTURE_3D ? minify(srcDepth, 1) : srcDepth; + + if (dstWidth == srcWidth && + dstHeight == srcHeight && + dstDepth == srcDepth) { + /* all done */ + break; + } + + /* Allocate storage for the destination mipmap image(s) */ + + /* Set MaxLevel large enough to hold the new level when we allocate it */ + _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); + + if (!prepare_mipmap_level(ctx, texObj, dstLevel, + dstWidth, dstHeight, dstDepth, + srcImage->InternalFormat, + srcImage->TexFormat)) { + /* All done. We either ran out of memory or we would go beyond the + * last valid level of an immutable texture if we continued. + */ + break; + } + + /* limit minification to src level */ + _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); + + /* setup viewport */ + _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight); + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0); + + for (layer = 0; layer < dstDepth; ++layer) { + /* Setup texture coordinates */ + _mesa_meta_setup_texture_coords(faceTarget, + layer, + 0, 0, 1, /* width, height never used here */ + verts[0].tex, + verts[1].tex, + verts[2].tex, + verts[3].tex); + + /* upload vertex data */ + _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), + verts, GL_DYNAMIC_DRAW_ARB); + + bind_fbo_image(texObj, faceTarget, dstLevel, layer); + + /* sanity check */ + if (_mesa_CheckFramebufferStatus(GL_FRAMEBUFFER) != + GL_FRAMEBUFFER_COMPLETE) { + _mesa_problem(ctx, "Unexpected incomplete framebuffer in " + "_mesa_meta_GenerateMipmap()"); + break; + } + + assert(dstWidth == ctx->DrawBuffer->Width); + if (target == GL_TEXTURE_1D_ARRAY) { + assert(dstHeight == 1); + } else { + assert(dstHeight == ctx->DrawBuffer->Height); + } + + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + } + + _mesa_lock_texture(ctx, texObj); /* relock */ + + _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); + + _mesa_meta_end(ctx); + + _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); + if (genMipmapSave) + _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); + + _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); +} diff --git a/mesalib/src/mesa/drivers/dri/common/dri_test.c b/mesalib/src/mesa/drivers/dri/common/dri_test.c index 35732857d..7ab50d923 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_test.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_test.c @@ -76,12 +76,6 @@ _glapi_get_dispatch_table_size(void) return 0; } -PUBLIC unsigned long -_glthread_GetID(void) -{ - return 0; -} - #ifndef NO_MAIN int main(int argc, char** argv) { diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index ca73a6686..8ec6a8c33 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -38,9 +38,6 @@ #include "version.h" #include "hash_table.h" -#define MESSAGE_LOG 1 -#define MESSAGE_LOG_ARB 2 - static mtx_t DynamicIDMutex = _MTX_INITIALIZER_NP; static GLuint NextDynamicID = 1; @@ -373,40 +370,6 @@ store_message_details(struct gl_debug_msg *emptySlot, /** - * Remap any type exclusive to KHR_debug to something suitable - * for ARB_debug_output - */ -inline static int -remap_type(GLenum type) { - - switch(type) { - case GL_DEBUG_TYPE_MARKER: - case GL_DEBUG_TYPE_PUSH_GROUP: - case GL_DEBUG_TYPE_POP_GROUP: - type = GL_DEBUG_TYPE_OTHER; - default: - ; - } - - return type; -} - - -/** - * Remap severity exclusive to KHR_debug to something suitable - * for ARB_debug_output - */ -inline static int -remap_severity(GLenum severity) { - - if (GL_DEBUG_SEVERITY_NOTIFICATION == severity) - severity = GL_DEBUG_SEVERITY_LOW; - - return severity; -} - - -/** * 'buf' is not necessarily a null-terminated string. When logging, copy * 'len' characters from it, store them in a new, null-terminated string, * and remember the number of bytes used by that string, *including* @@ -433,10 +396,6 @@ log_msg(struct gl_context *ctx, enum mesa_debug_source source, GLenum gl_type = debug_type_enums[type]; GLenum gl_severity = debug_severity_enums[severity]; - if (debug->ARBCallback) { - gl_severity = remap_severity(gl_severity); - gl_type = remap_type(gl_type); - } debug->Callback(debug_source_enums[source], gl_type, id, gl_severity, len, buf, debug->CallbackData); return; @@ -470,8 +429,7 @@ log_msg(struct gl_context *ctx, enum mesa_debug_source source, */ static GLsizei get_msg(struct gl_context *ctx, GLenum *source, GLenum *type, - GLuint *id, GLenum *severity, GLsizei bufSize, char *buf, - unsigned caller) + GLuint *id, GLenum *severity, GLsizei bufSize, char *buf) { struct gl_debug_state *debug = _mesa_get_debug_state(ctx); struct gl_debug_msg *msg; @@ -490,8 +448,6 @@ get_msg(struct gl_context *ctx, GLenum *source, GLenum *type, if (severity) { *severity = debug_severity_enums[msg->severity]; - if (caller == MESSAGE_LOG_ARB) - *severity = remap_severity(*severity); } if (source) { @@ -500,8 +456,6 @@ get_msg(struct gl_context *ctx, GLenum *source, GLenum *type, if (type) { *type = debug_type_enums[msg->type]; - if (caller == MESSAGE_LOG_ARB) - *type = remap_type(*type); } if (id) { @@ -529,12 +483,9 @@ get_msg(struct gl_context *ctx, GLenum *source, GLenum *type, /** * Verify that source, type, and severity are valid enums. - * glDebugMessageInsertARB only accepts two values for 'source', - * and glDebugMessageControlARB will additionally accept GL_DONT_CARE - * in any parameter, so handle those cases specially. * - * There is also special cases for handling values available in - * GL_KHR_debug that are not avaliable in GL_ARB_debug_output + * The 'caller' param is used for handling values available + * only in glDebugMessageInsert or glDebugMessageControl */ static GLboolean validate_params(struct gl_context *ctx, unsigned caller, @@ -543,8 +494,6 @@ validate_params(struct gl_context *ctx, unsigned caller, { #define INSERT 1 #define CONTROL 2 -#define INSERT_ARB 3 -#define CONTROL_ARB 4 switch(source) { case GL_DEBUG_SOURCE_APPLICATION_ARB: case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: @@ -553,11 +502,15 @@ validate_params(struct gl_context *ctx, unsigned caller, case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: case GL_DEBUG_SOURCE_OTHER_ARB: - if (caller != INSERT || caller == INSERT_ARB) + if (caller != INSERT) break; + else + goto error; case GL_DONT_CARE: - if (caller == CONTROL || caller == CONTROL_ARB) + if (caller == CONTROL) break; + else + goto error; default: goto error; } @@ -569,14 +522,15 @@ validate_params(struct gl_context *ctx, unsigned caller, case GL_DEBUG_TYPE_PERFORMANCE_ARB: case GL_DEBUG_TYPE_PORTABILITY_ARB: case GL_DEBUG_TYPE_OTHER_ARB: - break; case GL_DEBUG_TYPE_MARKER: - /* this value is only valid for GL_KHR_debug functions */ - if (caller == CONTROL || caller == INSERT) - break; + break; + case GL_DEBUG_TYPE_PUSH_GROUP: + case GL_DEBUG_TYPE_POP_GROUP: case GL_DONT_CARE: - if (caller == CONTROL || caller == CONTROL_ARB) + if (caller == CONTROL) break; + else + goto error; default: goto error; } @@ -585,14 +539,13 @@ validate_params(struct gl_context *ctx, unsigned caller, case GL_DEBUG_SEVERITY_HIGH_ARB: case GL_DEBUG_SEVERITY_MEDIUM_ARB: case GL_DEBUG_SEVERITY_LOW_ARB: - break; case GL_DEBUG_SEVERITY_NOTIFICATION: - /* this value is only valid for GL_KHR_debug functions */ - if (caller == CONTROL || caller == INSERT) - break; + break; case GL_DONT_CARE: - if (caller == CONTROL || caller == CONTROL_ARB) + if (caller == CONTROL) break; + else + goto error; default: goto error; } @@ -706,44 +659,6 @@ control_app_messages(struct gl_context *ctx, GLenum esource, GLenum etype, /** - * This is a generic message control function for use by both - * glDebugMessageControlARB and glDebugMessageControl. - */ -static void -message_control(GLenum gl_source, GLenum gl_type, - GLenum gl_severity, - GLsizei count, const GLuint *ids, - GLboolean enabled, - unsigned caller, const char *callerstr) -{ - GET_CURRENT_CONTEXT(ctx); - - if (count < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "%s(count=%d : count must not be negative)", callerstr, - count); - return; - } - - if (!validate_params(ctx, caller, callerstr, gl_source, gl_type, - gl_severity)) - return; /* GL_INVALID_ENUM */ - - if (count && (gl_severity != GL_DONT_CARE || gl_type == GL_DONT_CARE - || gl_source == GL_DONT_CARE)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(When passing an array of ids, severity must be" - " GL_DONT_CARE, and source and type must not be GL_DONT_CARE.", - callerstr); - return; - } - - control_app_messages(ctx, gl_source, gl_type, gl_severity, - count, ids, enabled); -} - - -/** * This is a generic message insert function. * Validation of source, type and severity parameters should be done * before calling this funtion. @@ -773,58 +688,6 @@ message_insert(GLenum source, GLenum type, GLuint id, } -/** - * This is a generic message insert function for use by both - * glGetDebugMessageLogARB and glGetDebugMessageLog. - */ -static GLuint -get_message_log(GLuint count, GLsizei logSize, GLenum *sources, - GLenum *types, GLenum *ids, GLenum *severities, - GLsizei *lengths, GLchar *messageLog, - unsigned caller, const char *callerstr) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint ret; - - if (!messageLog) - logSize = 0; - - if (logSize < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "%s(logSize=%d : logSize must not be negative)", callerstr, - logSize); - return 0; - } - - for (ret = 0; ret < count; ret++) { - GLsizei written = get_msg(ctx, sources, types, ids, severities, - logSize, messageLog, caller); - if (!written) - break; - - if (messageLog) { - messageLog += written; - logSize -= written; - } - if (lengths) { - *lengths = written; - lengths++; - } - - if (severities) - severities++; - if (sources) - sources++; - if (types) - types++; - if (ids) - ids++; - } - - return ret; -} - - static void do_nothing(GLuint key, void *data, void *userData) { @@ -887,22 +750,79 @@ _mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum *sources, GLenum *types, GLenum *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog) { - const char *callerstr = "glGetDebugMessageLog"; + GET_CURRENT_CONTEXT(ctx); + GLuint ret; + + if (!messageLog) + logSize = 0; + + if (logSize < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetDebugMessageLog(logSize=%d : logSize must not be" + " negative)", logSize); + return 0; + } + + for (ret = 0; ret < count; ret++) { + GLsizei written = get_msg(ctx, sources, types, ids, severities, + logSize, messageLog); + if (!written) + break; + + if (messageLog) { + messageLog += written; + logSize -= written; + } + if (lengths) { + *lengths = written; + lengths++; + } - return get_message_log(count, logSize, sources, types, ids, severities, - lengths, messageLog, MESSAGE_LOG, callerstr); + if (severities) + severities++; + if (sources) + sources++; + if (types) + types++; + if (ids) + ids++; + } + + return ret; } void GLAPIENTRY -_mesa_DebugMessageControl(GLenum source, GLenum type, GLenum severity, - GLsizei count, const GLuint *ids, - GLboolean enabled) +_mesa_DebugMessageControl(GLenum gl_source, GLenum gl_type, + GLenum gl_severity, GLsizei count, + const GLuint *ids, GLboolean enabled) { const char *callerstr = "glDebugMessageControl"; - message_control(source, type, severity, count, ids, - enabled, CONTROL, callerstr); + GET_CURRENT_CONTEXT(ctx); + + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "%s(count=%d : count must not be negative)", callerstr, + count); + return; + } + + if (!validate_params(ctx, CONTROL, callerstr, gl_source, gl_type, + gl_severity)) + return; /* GL_INVALID_ENUM */ + + if (count && (gl_severity != GL_DONT_CARE || gl_type == GL_DONT_CARE + || gl_source == GL_DONT_CARE)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(When passing an array of ids, severity must be" + " GL_DONT_CARE, and source and type must not be GL_DONT_CARE.", + callerstr); + return; + } + + control_app_messages(ctx, gl_source, gl_type, gl_severity, + count, ids, enabled); } @@ -914,7 +834,6 @@ _mesa_DebugMessageCallback(GLDEBUGPROC callback, const void *userParam) if (debug) { debug->Callback = callback; debug->CallbackData = userParam; - debug->ARBCallback = GL_FALSE; } } @@ -1041,60 +960,6 @@ _mesa_PopDebugGroup(void) } -void GLAPIENTRY -_mesa_DebugMessageInsertARB(GLenum source, GLenum type, GLuint id, - GLenum severity, GLint length, - const GLcharARB *buf) -{ - const char *callerstr = "glDebugMessageInsertARB"; - - GET_CURRENT_CONTEXT(ctx); - - if (!validate_params(ctx, INSERT_ARB, callerstr, source, type, severity)) - return; /* GL_INVALID_ENUM */ - - message_insert(source, type, id, severity, length, buf, callerstr); -} - - -GLuint GLAPIENTRY -_mesa_GetDebugMessageLogARB(GLuint count, GLsizei logSize, GLenum *sources, - GLenum *types, GLenum *ids, GLenum *severities, - GLsizei *lengths, GLcharARB *messageLog) -{ - const char *callerstr = "glGetDebugMessageLogARB"; - - return get_message_log(count, logSize, sources, types, ids, severities, - lengths, messageLog, MESSAGE_LOG_ARB, callerstr); -} - - -void GLAPIENTRY -_mesa_DebugMessageControlARB(GLenum gl_source, GLenum gl_type, - GLenum gl_severity, - GLsizei count, const GLuint *ids, - GLboolean enabled) -{ - const char *callerstr = "glDebugMessageControlARB"; - - message_control(gl_source, gl_type, gl_severity, count, ids, - enabled, CONTROL_ARB, callerstr); -} - - -void GLAPIENTRY -_mesa_DebugMessageCallbackARB(GLDEBUGPROCARB callback, const void *userParam) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_debug_state *debug = _mesa_get_debug_state(ctx); - if (debug) { - debug->Callback = callback; - debug->CallbackData = userParam; - debug->ARBCallback = GL_TRUE; - } -} - - void _mesa_init_errors(struct gl_context *ctx) { diff --git a/mesalib/src/mesa/main/errors.h b/mesalib/src/mesa/main/errors.h index cd414e6b6..e0706e5b9 100644 --- a/mesalib/src/mesa/main/errors.h +++ b/mesalib/src/mesa/main/errors.h @@ -91,21 +91,6 @@ _mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id, const char *msg, int len); void GLAPIENTRY -_mesa_DebugMessageInsertARB(GLenum source, GLenum type, GLuint id, - GLenum severity, GLint length, - const GLcharARB* buf); -GLuint GLAPIENTRY -_mesa_GetDebugMessageLogARB(GLuint count, GLsizei logSize, GLenum* sources, - GLenum* types, GLenum* ids, GLenum* severities, - GLsizei* lengths, GLcharARB* messageLog); -void GLAPIENTRY -_mesa_DebugMessageControlARB(GLenum source, GLenum type, GLenum severity, - GLsizei count, const GLuint *ids, - GLboolean enabled); -void GLAPIENTRY -_mesa_DebugMessageCallbackARB(GLDEBUGPROCARB callback, - const void *userParam); -void GLAPIENTRY _mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLint length, const GLchar* buf); diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index c46d70b20..a72284c9a 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -138,6 +138,7 @@ static const struct extension extension_table[] = { { "GL_ARB_shading_language_packing", o(ARB_shading_language_packing), GL, 2011 }, { "GL_ARB_shading_language_420pack", o(ARB_shading_language_420pack), GL, 2011 }, { "GL_ARB_shadow", o(ARB_shadow), GLL, 2001 }, + { "GL_ARB_stencil_texturing", o(ARB_stencil_texturing), GL, 2012 }, { "GL_ARB_sync", o(ARB_sync), GL, 2003 }, { "GL_ARB_texture_border_clamp", o(ARB_texture_border_clamp), GLL, 2000 }, { "GL_ARB_texture_buffer_object", o(ARB_texture_buffer_object), GLC, 2008 }, diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c index 2772ff2d3..acab6cb8d 100644 --- a/mesalib/src/mesa/main/format_pack.c +++ b/mesalib/src/mesa/main/format_pack.c @@ -567,7 +567,7 @@ static void pack_ubyte_ARGB4444_REV(const GLubyte src[4], void *dst) { GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_4444(src[GCOMP], src[BCOMP], src[ACOMP], src[RCOMP]); + *d = PACK_COLOR_4444(src[BCOMP], src[GCOMP], src[RCOMP], src[ACOMP]); } static void @@ -1044,8 +1044,8 @@ pack_ubyte_SRGB8(const GLubyte src[4], void *dst) { GLubyte *d = ((GLubyte *) dst); d[2] = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - d[1] = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - d[0] = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + d[1] = linear_ubyte_to_srgb_ubyte(src[GCOMP]); + d[0] = linear_ubyte_to_srgb_ubyte(src[BCOMP]); } static void @@ -1090,8 +1090,8 @@ pack_ubyte_SARGB8(const GLubyte src[4], void *dst) { GLuint *d = ((GLuint *) dst); GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - GLubyte g = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - GLubyte b = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]); + GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]); *d = PACK_COLOR_8888(src[ACOMP], r, g, b); } @@ -1108,6 +1108,31 @@ pack_float_SARGB8(const GLfloat src[4], void *dst) } +/* MESA_FORMAT_R8G8B8A8_SRGB */ + +static void +pack_ubyte_SABGR8(const GLubyte src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]); + GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]); + *d = PACK_COLOR_8888(src[ACOMP], b, g, r); +} + +static void +pack_float_SABGR8(const GLfloat src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLubyte r, g, b, a; + r = linear_float_to_srgb_ubyte(src[RCOMP]); + g = linear_float_to_srgb_ubyte(src[GCOMP]); + b = linear_float_to_srgb_ubyte(src[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); + *d = PACK_COLOR_8888(a, b, g, r); +} + + /* MESA_FORMAT_L_SRGB8 */ static void @@ -1880,6 +1905,20 @@ pack_float_SIGNED_RG1616(const GLfloat src[4], void *dst) *d = (r << 16) | (g & 0xffff); } +/* + * MESA_FORMAT_B8G8R8X8_SRGB + */ + +static void +pack_float_XRGB8888_SRGB(const GLfloat src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + GLubyte r = linear_float_to_srgb_ubyte(src[RCOMP]); + GLubyte g = linear_float_to_srgb_ubyte(src[GCOMP]); + GLubyte b = linear_float_to_srgb_ubyte(src[BCOMP]); + *d = PACK_COLOR_8888(127, r, g, b); +} + /** * Return a function that can pack a GLubyte rgba[4] color. */ @@ -1947,6 +1986,7 @@ _mesa_get_pack_ubyte_rgba_function(mesa_format format) table[MESA_FORMAT_BGR_SRGB8] = pack_ubyte_SRGB8; table[MESA_FORMAT_A8B8G8R8_SRGB] = pack_ubyte_SRGBA8; table[MESA_FORMAT_B8G8R8A8_SRGB] = pack_ubyte_SARGB8; + table[MESA_FORMAT_R8G8B8A8_SRGB] = pack_ubyte_SABGR8; table[MESA_FORMAT_L_SRGB8] = pack_ubyte_SL8; table[MESA_FORMAT_L8A8_SRGB] = pack_ubyte_SLA8; /* n/a */ @@ -2034,6 +2074,8 @@ _mesa_get_pack_ubyte_rgba_function(mesa_format format) table[MESA_FORMAT_R10G10B10A2_UNORM] = pack_ubyte_ABGR2101010; + table[MESA_FORMAT_B8G8R8X8_SRGB] = NULL; + initialized = GL_TRUE; } @@ -2109,6 +2151,7 @@ _mesa_get_pack_float_rgba_function(mesa_format format) table[MESA_FORMAT_BGR_SRGB8] = pack_float_SRGB8; table[MESA_FORMAT_A8B8G8R8_SRGB] = pack_float_SRGBA8; table[MESA_FORMAT_B8G8R8A8_SRGB] = pack_float_SARGB8; + table[MESA_FORMAT_R8G8B8A8_SRGB] = pack_float_SABGR8; table[MESA_FORMAT_L_SRGB8] = pack_float_SL8; table[MESA_FORMAT_L8A8_SRGB] = pack_float_SLA8; @@ -2197,6 +2240,8 @@ _mesa_get_pack_float_rgba_function(mesa_format format) table[MESA_FORMAT_G8R8_SNORM] = pack_float_SIGNED_RG88; table[MESA_FORMAT_G16R16_SNORM] = pack_float_SIGNED_RG1616; + table[MESA_FORMAT_B8G8R8X8_SRGB] = pack_float_XRGB8888_SRGB; + initialized = GL_TRUE; } diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index 276ba556a..2348ef605 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -267,10 +267,10 @@ unpack_ARGB4444_REV(const void *src, GLfloat dst[][4], GLuint n) const GLushort *s = ((const GLushort *) src); GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); - dst[i][GCOMP] = ((s[i] >> 12) & 0xf) * (1.0F / 15.0F); - dst[i][BCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); + dst[i][RCOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); + dst[i][GCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); + dst[i][BCOMP] = ((s[i] >> 12) & 0xf) * (1.0F / 15.0F); + dst[i][ACOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); } } @@ -797,6 +797,19 @@ unpack_SARGB8(const void *src, GLfloat dst[][4], GLuint n) } static void +unpack_SABGR8(const void *src, GLfloat dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] ) & 0xff ); + dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff ); + dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff ); + dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */ + } +} + +static void unpack_SL8(const void *src, GLfloat dst[][4], GLuint n) { const GLubyte *s = ((const GLubyte *) src); @@ -2313,6 +2326,19 @@ unpack_SIGNED_RG1616(const void *src, GLfloat dst[][4], GLuint n) } } +static void +unpack_XRGB8888_SRGB(const void *src, GLfloat dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff ); + dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff ); + dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] ) & 0xff ); + dst[i][ACOMP] = 1.0F; + } +} + /** * Return the unpacker function for the given format. */ @@ -2375,6 +2401,7 @@ get_unpack_rgba_function(mesa_format format) table[MESA_FORMAT_BGR_SRGB8] = unpack_SRGB8; table[MESA_FORMAT_A8B8G8R8_SRGB] = unpack_SRGBA8; table[MESA_FORMAT_B8G8R8A8_SRGB] = unpack_SARGB8; + table[MESA_FORMAT_R8G8B8A8_SRGB] = unpack_SABGR8; table[MESA_FORMAT_L_SRGB8] = unpack_SL8; table[MESA_FORMAT_L8A8_SRGB] = unpack_SLA8; table[MESA_FORMAT_SRGB_DXT1] = unpack_SRGB_DXT1; @@ -2530,6 +2557,8 @@ get_unpack_rgba_function(mesa_format format) table[MESA_FORMAT_G8R8_SNORM] = unpack_SIGNED_RG88; table[MESA_FORMAT_G16R16_SNORM] = unpack_SIGNED_RG1616; + table[MESA_FORMAT_B8G8R8X8_SRGB] = unpack_XRGB8888_SRGB; + initialized = GL_TRUE; } @@ -2738,10 +2767,10 @@ unpack_ubyte_ARGB4444_REV(const void *src, GLubyte dst[][4], GLuint n) const GLushort *s = ((const GLushort *) src); GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_4_8((s[i] ) & 0xf); - dst[i][GCOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); - dst[i][BCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); - dst[i][ACOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); + dst[i][RCOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); + dst[i][GCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); + dst[i][BCOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); + dst[i][ACOMP] = EXPAND_4_8((s[i] ) & 0xf); } } diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index f6c399ede..0cf97fa31 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -520,6 +520,15 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = 1, 1, 4 }, { + MESA_FORMAT_R8G8B8A8_SRGB, + "MESA_FORMAT_R8G8B8A8_SRGB", + GL_RGBA, + GL_UNSIGNED_NORMALIZED, + 8, 8, 8, 8, + 0, 0, 0, 0, 0, + 1, 1, 4 + }, + { MESA_FORMAT_L_SRGB8, "MESA_FORMAT_L_SRGB8", GL_LUMINANCE, @@ -1790,6 +1799,15 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = 0, 0, 0, 0, 0, 1, 1, 4 }, + { + MESA_FORMAT_B8G8R8X8_SRGB, + "MESA_FORMAT_B8G8R8X8_SRGB", + GL_RGB, + GL_UNSIGNED_NORMALIZED, + 8, 8, 8, 0, + 0, 0, 0, 0, 0, + 1, 1, 4 + }, }; @@ -2025,6 +2043,7 @@ _mesa_get_format_color_encoding(mesa_format format) case MESA_FORMAT_BGR_SRGB8: case MESA_FORMAT_A8B8G8R8_SRGB: case MESA_FORMAT_B8G8R8A8_SRGB: + case MESA_FORMAT_R8G8B8A8_SRGB: case MESA_FORMAT_L_SRGB8: case MESA_FORMAT_L8A8_SRGB: case MESA_FORMAT_SRGB_DXT1: @@ -2035,6 +2054,7 @@ _mesa_get_format_color_encoding(mesa_format format) case MESA_FORMAT_ETC2_SRGB8: case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + case MESA_FORMAT_B8G8R8X8_SRGB: return GL_SRGB; default: return GL_LINEAR; @@ -2059,6 +2079,9 @@ _mesa_get_srgb_format_linear(mesa_format format) case MESA_FORMAT_B8G8R8A8_SRGB: format = MESA_FORMAT_B8G8R8A8_UNORM; break; + case MESA_FORMAT_R8G8B8A8_SRGB: + format = MESA_FORMAT_R8G8B8A8_UNORM; + break; case MESA_FORMAT_L_SRGB8: format = MESA_FORMAT_L_UNORM8; break; @@ -2089,6 +2112,9 @@ _mesa_get_srgb_format_linear(mesa_format format) case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: format = MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1; break; + case MESA_FORMAT_B8G8R8X8_SRGB: + format = MESA_FORMAT_B8G8R8X8_UNORM; + break; default: break; } @@ -2563,6 +2589,7 @@ _mesa_format_to_type_and_comps(mesa_format format, return; case MESA_FORMAT_A8B8G8R8_SRGB: case MESA_FORMAT_B8G8R8A8_SRGB: + case MESA_FORMAT_R8G8B8A8_SRGB: *datatype = GL_UNSIGNED_BYTE; *comps = 4; return; @@ -2895,6 +2922,11 @@ _mesa_format_to_type_and_comps(mesa_format format, *comps = 2; return; + case MESA_FORMAT_B8G8R8X8_SRGB: + *datatype = GL_UNSIGNED_BYTE; + *comps = 4; + return; + case MESA_FORMAT_COUNT: assert(0); return; @@ -2967,6 +2999,7 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, return GL_FALSE; case MESA_FORMAT_R8G8B8A8_UNORM: + case MESA_FORMAT_R8G8B8A8_SRGB: if (format == GL_RGBA && type == GL_UNSIGNED_INT_8_8_8_8_REV && !swapBytes) return GL_TRUE; @@ -3448,6 +3481,9 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, case MESA_FORMAT_G16R16_SNORM: return format == GL_RG && type == GL_SHORT && !littleEndian && !swapBytes; + + case MESA_FORMAT_B8G8R8X8_SRGB: + return GL_FALSE; } return GL_FALSE; diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h index 3102584b6..a12fe4f08 100644 --- a/mesalib/src/mesa/main/formats.h +++ b/mesalib/src/mesa/main/formats.h @@ -333,6 +333,7 @@ typedef enum * R10G10B10A2_UNORM * G8R8_SINT * G16R16_SINT + * B8G8R8X8_SRGB * */ /*@{*/ @@ -418,6 +419,7 @@ typedef enum /* Type P formats */ MESA_FORMAT_A8B8G8R8_SRGB, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */ MESA_FORMAT_B8G8R8A8_SRGB, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */ + MESA_FORMAT_R8G8B8A8_SRGB, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */ /* Type A format(s) */ MESA_FORMAT_L_SRGB8, /* uchar[i] = L */ @@ -647,6 +649,8 @@ typedef enum MESA_FORMAT_G8R8_SNORM, /* RRRR RRRR GGGG GGGG */ MESA_FORMAT_G16R16_SNORM, /* RRRR RRRR RRRR RRRR GGGG GGGG GGGG GGGG */ + MESA_FORMAT_B8G8R8X8_SRGB, /* xxxx xxxx RRRR RRRR GGGG GGGG BBBB BBBB */ + MESA_FORMAT_COUNT } mesa_format; diff --git a/mesalib/src/mesa/main/hash_table.c b/mesalib/src/mesa/main/hash_table.c index 008b4cdbc..ad8f89852 100644 --- a/mesalib/src/mesa/main/hash_table.c +++ b/mesalib/src/mesa/main/hash_table.c @@ -119,7 +119,6 @@ _mesa_hash_table_create(void *mem_ctx, if (ht == NULL) return NULL; - ht->mem_ctx = mem_ctx; ht->size_index = 0; ht->size = hash_sizes[ht->size_index].size; ht->rehash = hash_sizes[ht->size_index].rehash; diff --git a/mesalib/src/mesa/main/hash_table.h b/mesalib/src/mesa/main/hash_table.h index ad1dae478..f51131aee 100644 --- a/mesalib/src/mesa/main/hash_table.h +++ b/mesalib/src/mesa/main/hash_table.h @@ -44,7 +44,6 @@ struct hash_entry { }; struct hash_table { - void *mem_ctx; struct hash_entry *table; bool (*key_equals_function)(const void *a, const void *b); const void *deleted_key; diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index bbc377280..e5f10baab 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1199,6 +1199,7 @@ struct gl_texture_object struct gl_sampler_object Sampler; GLenum DepthMode; /**< GL_ARB_depth_texture */ + bool StencilSampling; /**< Should we sample stencil instead of depth? */ GLfloat Priority; /**< in [0,1] */ GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ @@ -3526,6 +3527,7 @@ struct gl_extensions GLboolean ARB_shading_language_packing; GLboolean ARB_shading_language_420pack; GLboolean ARB_shadow; + GLboolean ARB_stencil_texturing; GLboolean ARB_sync; GLboolean ARB_texture_border_clamp; GLboolean ARB_texture_buffer_object; @@ -3843,7 +3845,6 @@ struct gl_debug_state const void *CallbackData; GLboolean SyncOutput; GLboolean DebugOutput; - GLboolean ARBCallback; /* Used to track if current callback is of type ARB_debug_output or KHR_debug */ GLboolean Defaults[MAX_DEBUG_GROUP_STACK_DEPTH][MESA_DEBUG_SEVERITY_COUNT][MESA_DEBUG_SOURCE_COUNT][MESA_DEBUG_TYPE_COUNT]; struct gl_debug_namespace Namespaces[MAX_DEBUG_GROUP_STACK_DEPTH][MESA_DEBUG_SOURCE_COUNT][MESA_DEBUG_TYPE_COUNT]; struct gl_debug_msg Log[MAX_DEBUG_LOGGED_MESSAGES]; diff --git a/mesalib/src/mesa/main/set.c b/mesalib/src/mesa/main/set.c index dc3550c76..989e5dece 100644 --- a/mesalib/src/mesa/main/set.c +++ b/mesalib/src/mesa/main/set.c @@ -112,7 +112,6 @@ _mesa_set_create(void *mem_ctx, if (ht == NULL) return NULL; - ht->mem_ctx = mem_ctx; ht->size_index = 0; ht->size = hash_sizes[ht->size_index].size; ht->rehash = hash_sizes[ht->size_index].rehash; diff --git a/mesalib/src/mesa/main/streaming-load-memcpy.c b/mesalib/src/mesa/main/streaming-load-memcpy.c index d7147afdc..8427149c5 100644 --- a/mesalib/src/mesa/main/streaming-load-memcpy.c +++ b/mesalib/src/mesa/main/streaming-load-memcpy.c @@ -26,6 +26,7 @@ * */ +#ifdef __SSE4_1__ #include "main/macros.h" #include "main/streaming-load-memcpy.h" #include <smmintrin.h> @@ -83,3 +84,5 @@ _mesa_streaming_load_memcpy(void *restrict dst, void *restrict src, size_t len) memcpy(d, s, len); } } + +#endif diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 0519d221f..a6c3581bf 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -1290,16 +1290,19 @@ clear_teximage_fields(struct gl_texture_image *img) * \param border image border. * \param internalFormat internal format. * \param format the actual hardware format (one of MESA_FORMAT_*) + * \param numSamples number of samples per texel, or zero for non-MS. + * \param fixedSampleLocations are sample locations fixed? * * Fills in the fields of \p img with the given information. * Note: width, height and depth include the border. */ -void -_mesa_init_teximage_fields(struct gl_context *ctx, - struct gl_texture_image *img, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum internalFormat, - mesa_format format) +static void +init_teximage_fields_ms(struct gl_context *ctx, + struct gl_texture_image *img, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum internalFormat, + mesa_format format, + GLuint numSamples, GLboolean fixedSampleLocations) { GLenum target; ASSERT(img); @@ -1397,6 +1400,20 @@ _mesa_init_teximage_fields(struct gl_context *ctx, _mesa_get_tex_max_num_levels(target, img->Width2, img->Height2, img->Depth2); img->TexFormat = format; + img->NumSamples = numSamples; + img->FixedSampleLocations = fixedSampleLocations; +} + + +void +_mesa_init_teximage_fields(struct gl_context *ctx, + struct gl_texture_image *img, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum internalFormat, + mesa_format format) +{ + init_teximage_fields_ms(ctx, img, width, height, depth, border, + internalFormat, format, 0, GL_TRUE); } @@ -2039,6 +2056,8 @@ texture_error_check( struct gl_context *ctx, GLint depth, GLint border ) { GLboolean colorFormat; + GLboolean is_format_depth_or_depthstencil; + GLboolean is_internalFormat_depth_or_depthstencil; GLenum err; /* Even though there are no color-index textures, we still have to support @@ -2129,11 +2148,18 @@ texture_error_check( struct gl_context *ctx, } /* make sure internal format and format basically agree */ + is_internalFormat_depth_or_depthstencil = + _mesa_is_depth_format(internalFormat) || + _mesa_is_depthstencil_format(internalFormat); + + is_format_depth_or_depthstencil = + _mesa_is_depth_format(format) || + _mesa_is_depthstencil_format(format); + colorFormat = _mesa_is_color_format(format); if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || - (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) || + (is_internalFormat_depth_or_depthstencil != is_format_depth_or_depthstencil) || (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) || - (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) || (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%dD(incompatible internalFormat = %s, format = %s)", @@ -4420,15 +4446,13 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, if (_mesa_is_proxy_texture(target)) { if (dimensionsOK && sizeOK) { - _mesa_init_teximage_fields(ctx, texImage, - width, height, depth, 0, internalformat, texFormat); - texImage->NumSamples = samples; - texImage->FixedSampleLocations = fixedsamplelocations; + init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, + internalformat, texFormat, + samples, fixedsamplelocations); } else { /* clear all image fields */ - _mesa_init_teximage_fields(ctx, texImage, - 0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE); + clear_teximage_fields(texImage); } } else { @@ -4452,11 +4476,9 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, ctx->Driver.FreeTextureImageBuffer(ctx, texImage); - _mesa_init_teximage_fields(ctx, texImage, - width, height, depth, 0, internalformat, texFormat); - - texImage->NumSamples = samples; - texImage->FixedSampleLocations = fixedsamplelocations; + init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, + internalformat, texFormat, + samples, fixedsamplelocations); if (width > 0 && height > 0 && depth > 0) { if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1, diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 3375fe36b..8bdbb08c8 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -148,6 +148,7 @@ _mesa_initialize_texture_object( struct gl_context *ctx, obj->Sampler.CompareMode = GL_NONE; /* ARB_shadow */ obj->Sampler.CompareFunc = GL_LEQUAL; /* ARB_shadow */ obj->DepthMode = ctx->API == API_OPENGL_CORE ? GL_RED : GL_LUMINANCE; + obj->StencilSampling = false; obj->Sampler.CubeMapSeamless = GL_FALSE; obj->Swizzle[0] = GL_RED; obj->Swizzle[1] = GL_GREEN; @@ -280,6 +281,7 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, dest->Sampler.CompareFunc = src->Sampler.CompareFunc; dest->Sampler.CubeMapSeamless = src->Sampler.CubeMapSeamless; dest->DepthMode = src->DepthMode; + dest->StencilSampling = src->StencilSampling; dest->Sampler.sRGBDecode = src->Sampler.sRGBDecode; dest->_MaxLevel = src->_MaxLevel; dest->_MaxLambda = src->_MaxLambda; diff --git a/mesalib/src/mesa/main/texobj.h b/mesalib/src/mesa/main/texobj.h index a4573b399..a9de73fff 100644 --- a/mesalib/src/mesa/main/texobj.h +++ b/mesalib/src/mesa/main/texobj.h @@ -114,6 +114,20 @@ _mesa_is_texture_complete(const struct gl_texture_object *texObj, return GL_FALSE; } + /* From the ARB_stencil_texturing specification: + * "Add a new bullet point for the conditions that cause the texture + * to not be complete: + * + * * The internal format of the texture is DEPTH_STENCIL, the + * DEPTH_STENCIL_TEXTURE_MODE for the texture is STENCIL_INDEX and either + * the magnification filter or the minification filter is not NEAREST." + */ + if (texObj->StencilSampling && + texObj->Image[0][texObj->BaseLevel]->_BaseFormat == GL_DEPTH_STENCIL && + (sampler->MagFilter != GL_NEAREST || sampler->MinFilter != GL_NEAREST)) { + return GL_FALSE; + } + if (_mesa_is_mipmap_filter(sampler)) return texObj->_MipmapComplete; else diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index bbdbc2763..bfb2e1b9f 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -451,6 +451,20 @@ set_tex_parameteri(struct gl_context *ctx, } goto invalid_pname; + case GL_DEPTH_STENCIL_TEXTURE_MODE: + if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_stencil_texturing) { + bool stencil = params[0] == GL_STENCIL_INDEX; + if (!stencil && params[0] != GL_DEPTH_COMPONENT) + goto invalid_param; + + if (texObj->StencilSampling == stencil) + return GL_FALSE; + + texObj->StencilSampling = stencil; + return GL_TRUE; + } + goto invalid_pname; + case GL_TEXTURE_CROP_RECT_OES: if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) goto invalid_pname; @@ -707,6 +721,7 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) case GL_TEXTURE_COMPARE_MODE_ARB: case GL_TEXTURE_COMPARE_FUNC_ARB: case GL_DEPTH_TEXTURE_MODE_ARB: + case GL_DEPTH_STENCIL_TEXTURE_MODE: case GL_TEXTURE_SRGB_DECODE_EXT: case GL_TEXTURE_CUBE_MAP_SEAMLESS: case GL_TEXTURE_SWIZZLE_R_EXT: @@ -762,6 +777,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) case GL_TEXTURE_COMPARE_MODE_ARB: case GL_TEXTURE_COMPARE_FUNC_ARB: case GL_DEPTH_TEXTURE_MODE_ARB: + case GL_DEPTH_STENCIL_TEXTURE_MODE: case GL_TEXTURE_SRGB_DECODE_EXT: case GL_TEXTURE_CUBE_MAP_SEAMLESS: { @@ -1038,9 +1054,16 @@ get_tex_level_parameter_image(struct gl_context *ctx, img = _mesa_select_tex_image(ctx, texObj, target, level); if (!img || img->TexFormat == MESA_FORMAT_NONE) { - /* undefined texture image */ - if (pname == GL_TEXTURE_COMPONENTS) - *params = 1; + /* In case of undefined texture image return the default values. + * + * From OpenGL 4.0 spec, page 398: + * "The initial internal format of a texel array is RGBA + * instead of 1. TEXTURE_COMPONENTS is deprecated; always + * use TEXTURE_INTERNAL_FORMAT." + */ + + if (pname == GL_TEXTURE_INTERNAL_FORMAT) + *params = GL_RGBA; else *params = 0; return; @@ -1452,6 +1475,12 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) goto invalid_pname; *params = (GLfloat) obj->DepthMode; break; + case GL_DEPTH_STENCIL_TEXTURE_MODE: + if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing) + goto invalid_pname; + *params = (GLfloat) + (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); + break; case GL_TEXTURE_LOD_BIAS: if (_mesa_is_gles(ctx)) goto invalid_pname; @@ -1666,6 +1695,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) goto invalid_pname; *params = (GLint) obj->DepthMode; break; + case GL_DEPTH_STENCIL_TEXTURE_MODE: + if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing) + goto invalid_pname; + *params = (GLint) + (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); + break; case GL_TEXTURE_LOD_BIAS: if (_mesa_is_gles(ctx)) goto invalid_pname; diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 3e22a0b46..557703d01 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -3290,10 +3290,20 @@ _mesa_texstore_sargb8(TEXSTORE_PARAMS) mesa_format newDstFormat; GLboolean k; - ASSERT(dstFormat == MESA_FORMAT_B8G8R8A8_SRGB); - - /* reuse normal rgba texstore code */ - newDstFormat = MESA_FORMAT_B8G8R8A8_UNORM; + switch (dstFormat) { + case MESA_FORMAT_B8G8R8A8_SRGB: + newDstFormat = MESA_FORMAT_B8G8R8A8_UNORM; + break; + case MESA_FORMAT_R8G8B8A8_SRGB: + newDstFormat = MESA_FORMAT_R8G8B8A8_UNORM; + break; + case MESA_FORMAT_B8G8R8X8_SRGB: + newDstFormat = MESA_FORMAT_B8G8R8X8_UNORM; + break; + default: + ASSERT(0); + return GL_FALSE; + } k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat, newDstFormat, @@ -3859,6 +3869,8 @@ _mesa_get_texstore_func(mesa_format format) table[MESA_FORMAT_G8R8_SNORM] = _mesa_texstore_snorm88; table[MESA_FORMAT_G16R16_SNORM] = _mesa_texstore_snorm1616; + table[MESA_FORMAT_B8G8R8X8_SRGB] = _mesa_texstore_sargb8; + initialized = GL_TRUE; } diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 44db2cbcd..b4b6fa9be 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -569,8 +569,8 @@ void GLAPIENTRY _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) { const GLbitfield legalTypes = UNSIGNED_BYTE_BIT; - /* see table 2.4 edits in GL_EXT_gpu_shader4 spec: */ - const GLboolean integer = GL_TRUE; + /* this is the same type that glEdgeFlag uses */ + const GLboolean integer = GL_FALSE; GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); diff --git a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c index c08d91297..4c4f839d1 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c @@ -73,8 +73,8 @@ update_framebuffer_state( struct st_context *st ) strb = st_renderbuffer(fb->_ColorDrawBuffers[i]); if (strb) { - if (strb->is_rtt || - (strb->texture && util_format_is_srgb(strb->texture->format))) { + if (strb->is_rtt || (strb->texture && + _mesa_get_format_color_encoding(strb->Base.Format) == GL_SRGB)) { /* rendering to a GL texture, may have to update surface */ st_update_renderbuffer_surface(st, strb); } diff --git a/mesalib/src/mesa/state_tracker/st_atom_scissor.c b/mesalib/src/mesa/state_tracker/st_atom_scissor.c index a19ade1fa..b72030944 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_scissor.c +++ b/mesalib/src/mesa/state_tracker/st_atom_scissor.c @@ -85,7 +85,7 @@ update_scissor( struct st_context *st ) scissor[i].maxy = maxy; } - if (memcmp(&scissor[i], &st->state.scissor[i], sizeof(scissor)) != 0) { + if (memcmp(&scissor[i], &st->state.scissor[i], sizeof(scissor[0])) != 0) { /* state has changed */ st->state.scissor[i] = scissor[i]; /* struct copy */ changed = true; diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index 6449c62a8..ce8d91514 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -295,7 +295,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw) strb->Base.Format = st_pipe_format_to_mesa_format(format); strb->Base._BaseFormat = _mesa_get_format_base_format(strb->Base.Format); strb->software = sw; - + switch (format) { case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: @@ -307,6 +307,16 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw) case PIPE_FORMAT_X8R8G8B8_UNORM: strb->Base.InternalFormat = GL_RGB8; break; + case PIPE_FORMAT_R8G8B8A8_SRGB: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_A8R8G8B8_SRGB: + strb->Base.InternalFormat = GL_SRGB8_ALPHA8; + break; + case PIPE_FORMAT_R8G8B8X8_SRGB: + case PIPE_FORMAT_B8G8R8X8_SRGB: + case PIPE_FORMAT_X8R8G8B8_SRGB: + strb->Base.InternalFormat = GL_SRGB8; + break; case PIPE_FORMAT_B5G5R5A1_UNORM: strb->Base.InternalFormat = GL_RGB5_A1; break; @@ -401,8 +411,17 @@ st_update_renderbuffer_surface(struct st_context *st, int rtt_width = strb->Base.Width; int rtt_height = strb->Base.Height; int rtt_depth = strb->Base.Depth; - enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : - util_format_linear(resource->format); + /* + * For winsys fbo, it is possible that the renderbuffer is sRGB-capable but + * the format of strb->texture is linear (because we have no control over + * the format). Check strb->Base.Format instead of strb->texture->format + * to determine if the rb is sRGB-capable. + */ + boolean enable_srgb = (st->ctx->Color.sRGBEnabled && + _mesa_get_format_color_encoding(strb->Base.Format) == GL_SRGB); + enum pipe_format format = (enable_srgb) ? + util_format_srgb(resource->format) : + util_format_linear(resource->format); unsigned first_layer, last_layer, level; if (resource->target == PIPE_TEXTURE_1D_ARRAY) { diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 5f951eb02..a55ee3079 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -121,6 +121,8 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat) return PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; case MESA_FORMAT_YCBCR: return PIPE_FORMAT_UYVY; + case MESA_FORMAT_YCBCR_REV: + return PIPE_FORMAT_YUYV; case MESA_FORMAT_RGB_DXT1: return PIPE_FORMAT_DXT1_RGB; case MESA_FORMAT_RGBA_DXT1: @@ -147,6 +149,8 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat) return PIPE_FORMAT_A8B8G8R8_SRGB; case MESA_FORMAT_B8G8R8A8_SRGB: return PIPE_FORMAT_B8G8R8A8_SRGB; + case MESA_FORMAT_R8G8B8A8_SRGB: + return PIPE_FORMAT_R8G8B8A8_SRGB; case MESA_FORMAT_RGBA_FLOAT32: return PIPE_FORMAT_R32G32B32A32_FLOAT; case MESA_FORMAT_RGBA_FLOAT16: @@ -393,6 +397,9 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat) case MESA_FORMAT_RGBX_SINT32: return PIPE_FORMAT_R32G32B32X32_SINT; + case MESA_FORMAT_B8G8R8X8_SRGB: + return PIPE_FORMAT_B8G8R8X8_SRGB; + default: return PIPE_FORMAT_NONE; } @@ -748,14 +755,47 @@ st_pipe_format_to_mesa_format(enum pipe_format format) case PIPE_FORMAT_R32G32B32X32_SINT: return MESA_FORMAT_RGBX_SINT32; + case PIPE_FORMAT_B8G8R8X8_SRGB: + return MESA_FORMAT_B8G8R8X8_SRGB; + case PIPE_FORMAT_R8G8B8A8_SRGB: + return MESA_FORMAT_R8G8B8A8_SRGB; + default: - assert(0); return MESA_FORMAT_NONE; } } /** + * Debug only: check that the two functions above correctly map + * Mesa formats to Gallium formats and back again. + */ +static void +test_format_conversion(void) +{ + GLuint i; + + /* test all Mesa formats */ + for (i = 1; i < MESA_FORMAT_COUNT; i++) { + enum pipe_format pf = st_mesa_format_to_pipe_format(i); + if (pf != PIPE_FORMAT_NONE) { + mesa_format mf = st_pipe_format_to_mesa_format(pf); + assert(mf == i); + } + } + + /* Test all Gallium formats */ + for (i = 1; i < PIPE_FORMAT_COUNT; i++) { + mesa_format mf = st_pipe_format_to_mesa_format(i); + if (mf != MESA_FORMAT_NONE) { + enum pipe_format pf = st_mesa_format_to_pipe_format(mf); + assert(pf == i); + } + } +} + + +/** * Map GL texture formats to Gallium pipe formats. */ struct format_mapping @@ -1006,7 +1046,8 @@ static const struct format_mapping format_map[] = { /* sRGB formats */ { { GL_SRGB_EXT, GL_SRGB8_EXT, 0 }, - { PIPE_FORMAT_R8G8B8X8_SRGB, DEFAULT_SRGBA_FORMATS } + { PIPE_FORMAT_R8G8B8X8_SRGB, PIPE_FORMAT_B8G8R8X8_SRGB, + DEFAULT_SRGBA_FORMATS } }, { { GL_SRGB_ALPHA_EXT, GL_SRGB8_ALPHA8_EXT, 0 }, @@ -1015,7 +1056,7 @@ static const struct format_mapping format_map[] = { { { GL_COMPRESSED_SRGB_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 0 }, { PIPE_FORMAT_DXT1_SRGB, PIPE_FORMAT_R8G8B8X8_SRGB, - DEFAULT_SRGBA_FORMATS } + PIPE_FORMAT_B8G8R8X8_SRGB, DEFAULT_SRGBA_FORMATS } }, { { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0 }, @@ -1630,6 +1671,18 @@ st_choose_format(struct st_context *st, GLenum internalFormat, int i, j; enum pipe_format pf; +#ifdef DEBUG + { + static boolean firstCall = TRUE; + if (firstCall) { + test_format_conversion(); + firstCall = FALSE; + } + } +#else + (void) test_format_conversion; +#endif + /* can't render to compressed formats at this time */ if (_mesa_is_compressed_format(st->ctx, internalFormat) && (bindings & ~PIPE_BIND_SAMPLER_VIEW)) { diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 6a776a8a2..314d34232 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -302,6 +302,8 @@ st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, break; default: format = stfb->iface->visual->color_format; + if (stfb->Base.Visual.sRGBCapable) + format = util_format_srgb(format); sw = FALSE; break; } @@ -400,7 +402,8 @@ st_visual_to_context_mode(const struct st_visual *visual, * Create a framebuffer from a manager interface. */ static struct st_framebuffer * -st_framebuffer_create(struct st_framebuffer_iface *stfbi) +st_framebuffer_create(struct st_context *st, + struct st_framebuffer_iface *stfbi) { struct st_framebuffer *stfb; struct gl_config mode; @@ -414,6 +417,38 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) return NULL; st_visual_to_context_mode(stfbi->visual, &mode); + + /* + * For desktop GL, sRGB framebuffer write is controlled by both the + * capability of the framebuffer and GL_FRAMEBUFFER_SRGB. We should + * advertise the capability when the pipe driver (and core Mesa) supports + * it so that applications can enable sRGB write when they want to. + * + * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB. When + * the attribute is GLX_TRUE, it tells the st manager to pick a color + * format such that util_format_srgb(visual->color_format) can be supported + * by the pipe driver. We still need to advertise the capability here. + * + * For GLES, however, sRGB framebuffer write is controlled only by the + * capability of the framebuffer. There is GL_EXT_sRGB_write_control to + * give applications the control back, but sRGB write is still enabled by + * default. To avoid unexpected results, we should not advertise the + * capability. This could change when we add support for + * EGL_KHR_gl_colorspace. + */ + if (_mesa_is_desktop_gl(st->ctx)) { + struct pipe_screen *screen = st->pipe->screen; + const enum pipe_format srgb_format = + util_format_srgb(stfbi->visual->color_format); + + if (srgb_format != PIPE_FORMAT_NONE && + st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE && + screen->is_format_supported(screen, srgb_format, + PIPE_TEXTURE_2D, stfbi->visual->samples, + PIPE_BIND_RENDER_TARGET)) + mode.sRGBCapable = GL_TRUE; + } + _mesa_initialize_window_framebuffer(&stfb->Base, &mode); stfb->iface = stfbi; @@ -677,7 +712,8 @@ st_api_get_current(struct st_api *stapi) } static struct st_framebuffer * -st_framebuffer_reuse_or_create(struct gl_framebuffer *fb, +st_framebuffer_reuse_or_create(struct st_context *st, + struct gl_framebuffer *fb, struct st_framebuffer_iface *stfbi) { struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL; @@ -690,7 +726,7 @@ st_framebuffer_reuse_or_create(struct gl_framebuffer *fb, } else { /* create a new one */ - stfb = st_framebuffer_create(stfbi); + stfb = st_framebuffer_create(st, stfbi); } return stfb; @@ -709,12 +745,12 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, if (st) { /* reuse or create the draw fb */ - stdraw = st_framebuffer_reuse_or_create(st->ctx->WinSysDrawBuffer, - stdrawi); + stdraw = st_framebuffer_reuse_or_create(st, + st->ctx->WinSysDrawBuffer, stdrawi); if (streadi != stdrawi) { /* do the same for the read fb */ - stread = st_framebuffer_reuse_or_create(st->ctx->WinSysReadBuffer, - streadi); + stread = st_framebuffer_reuse_or_create(st, + st->ctx->WinSysReadBuffer, streadi); } else { stread = NULL; diff --git a/mesalib/src/mesa/swrast/s_texfetch.c b/mesalib/src/mesa/swrast/s_texfetch.c index b620748c9..8ba75348f 100644 --- a/mesalib/src/mesa/swrast/s_texfetch.c +++ b/mesalib/src/mesa/swrast/s_texfetch.c @@ -437,6 +437,12 @@ texfetch_funcs[] = fetch_texel_3d_sargb8 }, { + MESA_FORMAT_R8G8B8A8_SRGB, + fetch_texel_1d_sabgr8, + fetch_texel_2d_sabgr8, + fetch_texel_3d_sabgr8 + }, + { MESA_FORMAT_L_SRGB8, fetch_texel_1d_sl8, fetch_texel_2d_sl8, @@ -1304,6 +1310,12 @@ texfetch_funcs[] = NULL, NULL }, + { + MESA_FORMAT_B8G8R8X8_SRGB, + NULL, + NULL, + NULL + }, }; diff --git a/mesalib/src/mesa/swrast/s_texfetch_tmp.h b/mesalib/src/mesa/swrast/s_texfetch_tmp.h index 806f0fd1a..8821125a0 100644 --- a/mesalib/src/mesa/swrast/s_texfetch_tmp.h +++ b/mesalib/src/mesa/swrast/s_texfetch_tmp.h @@ -611,10 +611,10 @@ static void FETCH(f_argb4444_rev)( const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = ((s ) & 0xf) * (1.0F / 15.0F); - texel[GCOMP] = ((s >> 12) & 0xf) * (1.0F / 15.0F); - texel[BCOMP] = ((s >> 8) & 0xf) * (1.0F / 15.0F); - texel[ACOMP] = ((s >> 4) & 0xf) * (1.0F / 15.0F); + texel[RCOMP] = ((s >> 4) & 0xf) * (1.0F / 15.0F); + texel[GCOMP] = ((s >> 8) & 0xf) * (1.0F / 15.0F); + texel[BCOMP] = ((s >> 12) & 0xf) * (1.0F / 15.0F); + texel[ACOMP] = ((s ) & 0xf) * (1.0F / 15.0F); } @@ -1015,6 +1015,19 @@ static void FETCH(sargb8)(const struct swrast_texture_image *texImage, +/* Fetch texel from 1D, 2D or 3D sabgr8 texture, return 4 GLfloats */ +static void FETCH(sabgr8)(const struct swrast_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); + texel[RCOMP] = nonlinear_to_linear( (s ) & 0xff ); + texel[GCOMP] = nonlinear_to_linear( (s >> 8) & 0xff ); + texel[BCOMP] = nonlinear_to_linear( (s >> 16) & 0xff ); + texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); /* linear! */ +} + + + /* Fetch texel from 1D, 2D or 3D sl8 texture, return 4 GLfloats */ static void FETCH(sl8)(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) diff --git a/xorg-server/config/config.c b/xorg-server/config/config.c index 760cf193a..7971b8740 100644 --- a/xorg-server/config/config.c +++ b/xorg-server/config/config.c @@ -27,10 +27,12 @@ #include <dix-config.h> #endif +#include <unistd.h> #include "os.h" #include "inputstr.h" #include "hotplug.h" #include "config-backends.h" +#include "systemd-logind.h" void config_pre_init(void) @@ -145,30 +147,111 @@ config_odev_free_attribute_list(struct OdevAttributes *attribs) free(attribs); } +static struct OdevAttribute * +config_odev_find_attribute(struct OdevAttributes *attribs, int attrib_id) +{ + struct OdevAttribute *oa; + + xorg_list_for_each_entry(oa, &attribs->list, member) { + if (oa->attrib_id == attrib_id) + return oa; + } + return NULL; +} + Bool config_odev_add_attribute(struct OdevAttributes *attribs, int attrib, const char *attrib_name) { struct OdevAttribute *oa; - oa = malloc(sizeof(struct OdevAttribute)); + oa = config_odev_find_attribute(attribs, attrib); + if (!oa) + oa = calloc(1, sizeof(struct OdevAttribute)); if (!oa) return FALSE; oa->attrib_id = attrib; + free(oa->attrib_name); oa->attrib_name = strdup(attrib_name); + oa->attrib_type = ODEV_ATTRIB_STRING; xorg_list_append(&oa->member, &attribs->list); return TRUE; } +Bool +config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib, + int attrib_value) +{ + struct OdevAttribute *oa; + + oa = config_odev_find_attribute(attribs, attrib); + if (!oa) + oa = calloc(1, sizeof(struct OdevAttribute)); + if (!oa) + return FALSE; + + oa->attrib_id = attrib; + oa->attrib_value = attrib_value; + oa->attrib_type = ODEV_ATTRIB_INT; + xorg_list_append(&oa->member, &attribs->list); + return TRUE; +} + +char * +config_odev_get_attribute(struct OdevAttributes *attribs, int attrib_id) +{ + struct OdevAttribute *oa; + + oa = config_odev_find_attribute(attribs, attrib_id); + if (!oa) + return NULL; + + if (oa->attrib_type != ODEV_ATTRIB_STRING) { + LogMessage(X_ERROR, "Error %s called for non string attrib %d\n", + __func__, attrib_id); + return NULL; + } + return oa->attrib_name; +} + +int +config_odev_get_int_attribute(struct OdevAttributes *attribs, int attrib_id, int def) +{ + struct OdevAttribute *oa; + + oa = config_odev_find_attribute(attribs, attrib_id); + if (!oa) + return def; + + if (oa->attrib_type != ODEV_ATTRIB_INT) { + LogMessage(X_ERROR, "Error %s called for non integer attrib %d\n", + __func__, attrib_id); + return def; + } + + return oa->attrib_value; +} + void config_odev_free_attributes(struct OdevAttributes *attribs) { struct OdevAttribute *iter, *safe; + int major = 0, minor = 0, fd = -1; xorg_list_for_each_entry_safe(iter, safe, &attribs->list, member) { + switch (iter->attrib_id) { + case ODEV_ATTRIB_MAJOR: major = iter->attrib_value; break; + case ODEV_ATTRIB_MINOR: minor = iter->attrib_value; break; + case ODEV_ATTRIB_FD: fd = iter->attrib_value; break; + } xorg_list_del(&iter->member); free(iter->attrib_name); free(iter); } + + if (fd != -1) { + systemd_logind_release_fd(major, minor); + close(fd); + } } diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c index 68ed34843..d70eeb48c 100644 --- a/xorg-server/config/udev.c +++ b/xorg-server/config/udev.c @@ -29,6 +29,7 @@ #include <libudev.h> #include <ctype.h> +#include <unistd.h> #include "input.h" #include "inputstr.h" @@ -36,6 +37,7 @@ #include "config-backends.h" #include "os.h" #include "globals.h" +#include "systemd-logind.h" #define UDEV_XKB_PROP_KEY "xkb" @@ -55,9 +57,18 @@ static struct udev_monitor *udev_monitor; #ifdef CONFIG_UDEV_KMS static Bool config_udev_odev_setup_attribs(const char *path, const char *syspath, + int major, int minor, config_odev_probe_proc_ptr probe_callback); #endif +static char itoa_buf[16]; + +static const char *itoa(int i) +{ + snprintf(itoa_buf, sizeof(itoa_buf), "%d", i); + return itoa_buf; +} + static void device_added(struct udev_device *udev_device) { @@ -73,6 +84,7 @@ device_added(struct udev_device *udev_device) struct udev_device *parent; int rc; const char *dev_seat; + dev_t devnum; path = udev_device_get_devnode(udev_device); @@ -91,6 +103,8 @@ device_added(struct udev_device *udev_device) if (!SeatId && strcmp(dev_seat, "seat0")) return; + devnum = udev_device_get_devnum(udev_device); + #ifdef CONFIG_UDEV_KMS if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) { const char *sysname = udev_device_get_sysname(udev_device); @@ -98,9 +112,14 @@ device_added(struct udev_device *udev_device) if (strncmp(sysname, "card", 4) != 0) return; + /* Check for devices already added through xf86platformProbe() */ + if (xf86_find_platform_device_by_devnum(major(devnum), minor(devnum))) + return; + LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path); - config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest); + config_udev_odev_setup_attribs(path, syspath, major(devnum), + minor(devnum), NewGPUDeviceRequest); return; } #endif @@ -153,6 +172,8 @@ device_added(struct udev_device *udev_device) input_options = input_option_new(input_options, "name", name); input_options = input_option_new(input_options, "path", path); input_options = input_option_new(input_options, "device", path); + input_options = input_option_new(input_options, "major", itoa(major(devnum))); + input_options = input_option_new(input_options, "minor", itoa(minor(devnum))); if (path) attrs.device = strdup(path); @@ -270,6 +291,7 @@ device_removed(struct udev_device *device) if (!strcmp(udev_device_get_subsystem(device), "drm")) { const char *sysname = udev_device_get_sysname(device); const char *path = udev_device_get_devnode(device); + dev_t devnum = udev_device_get_devnum(device); if (strncmp(sysname,"card", 4) != 0) return; @@ -277,7 +299,10 @@ device_removed(struct udev_device *device) if (!path) return; - config_udev_odev_setup_attribs(path, syspath, DeleteGPUDeviceRequest); + config_udev_odev_setup_attribs(path, syspath, major(devnum), + minor(devnum), DeleteGPUDeviceRequest); + /* Retry vtenter after a drm node removal */ + systemd_logind_vtenter(); return; } #endif @@ -427,6 +452,7 @@ config_udev_fini(void) static Bool config_udev_odev_setup_attribs(const char *path, const char *syspath, + int major, int minor, config_odev_probe_proc_ptr probe_callback) { struct OdevAttributes *attribs = config_odev_allocate_attribute_list(); @@ -443,6 +469,14 @@ config_udev_odev_setup_attribs(const char *path, const char *syspath, if (ret == FALSE) goto fail; + ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MAJOR, major); + if (ret == FALSE) + goto fail; + + ret = config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MINOR, minor); + if (ret == FALSE) + goto fail; + /* ownership of attribs is passed to probe layer */ probe_callback(attribs); return TRUE; @@ -477,6 +511,7 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback) struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath); const char *path = udev_device_get_devnode(udev_device); const char *sysname = udev_device_get_sysname(udev_device); + dev_t devnum = udev_device_get_devnum(udev_device); if (!path || !syspath) goto no_probe; @@ -485,8 +520,8 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback) else if (strncmp(sysname, "card", 4) != 0) goto no_probe; - config_udev_odev_setup_attribs(path, syspath, probe_callback); - + config_udev_odev_setup_attribs(path, syspath, major(devnum), + minor(devnum), probe_callback); no_probe: udev_device_unref(udev_device); } diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 0fb2fc375..162c0cf3c 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -626,6 +626,7 @@ AC_ARG_ENABLE(clientids, AS_HELP_STRING([--disable-clientids], [Build Xorg AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes]) AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes]) AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes]) +AC_ARG_ENABLE(systemd-logind, AC_HELP_STRING([--enable-systemd-logind], [Build systemd-logind support (default: auto)]), [SYSTEMD_LOGIND=$enableval], [SYSTEMD_LOGIND=auto]) dnl DDXes. AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto]) @@ -806,6 +807,8 @@ LIBAPPLEWM="applewm >= 1.4" LIBDMX="dmx >= 1.0.99.1" LIBDRI="dri >= 7.8.0" LIBDRM="libdrm >= 2.3.0" +LIBEGL="egl" +LIBGBM="gbm >= 9" LIBGL="gl >= 7.1.0" LIBXEXT="xext >= 1.0.99.4" LIBXFONT="xfont >= 1.4.2" @@ -901,6 +904,26 @@ if test "x$CONFIG_HAL" = xyes; then fi AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes]) +if test "x$SYSTEMD_LOGIND" = xauto; then + if test "x$HAVE_DBUS" = xyes -a "x$CONFIG_UDEV" = xyes ; then + SYSTEMD_LOGIND=yes + else + SYSTEMD_LOGIND=no + fi +fi +if test "x$SYSTEMD_LOGIND" = xyes; then + if ! test "x$HAVE_DBUS" = xyes; then + AC_MSG_ERROR([systemd-logind requested, but D-Bus is not installed.]) + fi + if ! test "x$CONFIG_UDEV" = xyes ; then + AC_MSG_ERROR([systemd-logind is only supported in combination with udev configuration.]) + fi + + AC_DEFINE(SYSTEMD_LOGIND, 1, [Enable systemd-logind integration]) + NEED_DBUS="yes" +fi +AM_CONDITIONAL(SYSTEMD_LOGIND, [test "x$SYSTEMD_LOGIND" = xyes]) + if test "x$NEED_DBUS" = xyes; then AC_DEFINE(NEED_DBUS, 1, [Enable D-Bus core]) fi @@ -2070,7 +2093,15 @@ AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes]) if test "x$GLAMOR" = xyes; then AC_DEFINE(GLAMOR, 1, [Build glamor]) PKG_CHECK_MODULES([GLAMOR], [epoxy]) + + PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no]) + if test "x$GBM" = xyes; then + AC_DEFINE(GLAMOR_HAS_GBM, 1, + [Build glamor with GBM-based EGL support]) + fi + fi +AM_CONDITIONAL([GLAMOR_EGL], [test "x$GBM" = xyes]) dnl XWin DDX @@ -2319,6 +2350,9 @@ if test "$KDRIVE" = yes; then if test "x$DRI" = xyes && test "x$GLX" = xyes; then XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS libdrm xcb-glx xcb-xf86dri > 1.6" fi + if test "x$GLAMOR" = xyes; then + XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS x11-xcb" + fi if test "x$XEPHYR" = xauto; then PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [XEPHYR="yes"], [XEPHYR="no"]) @@ -2476,6 +2510,7 @@ hw/xfree86/exa/Makefile hw/xfree86/exa/man/Makefile hw/xfree86/fbdevhw/Makefile hw/xfree86/fbdevhw/man/Makefile +hw/xfree86/glamor_egl/Makefile hw/xfree86/i2c/Makefile hw/xfree86/int10/Makefile hw/xfree86/loader/Makefile diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c index fcc1ad30a..7427e08ca 100644 --- a/xorg-server/dix/main.c +++ b/xorg-server/dix/main.c @@ -175,6 +175,9 @@ dix_main(int argc, char *argv[], char *envp[]) clients[0] = serverClient; currentMaxClients = 1; + /* clear any existing selections */ + InitSelections(); + /* Initialize privates before first allocation */ dixResetPrivates(); @@ -192,7 +195,6 @@ dix_main(int argc, char *argv[], char *envp[]) InitAtoms(); InitEvents(); - InitSelections(); InitGlyphCaching(); dixResetRegistry(); ResetFontPrivateIndex(); diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am index 12a57c441..77492bcaa 100644 --- a/xorg-server/glamor/Makefile.am +++ b/xorg-server/glamor/Makefile.am @@ -37,7 +37,6 @@ libglamor_la_SOURCES = \ glamor_window.c\ glamor_fbo.c\ glamor_compositerects.c\ - glamor_xv.c\ glamor_utils.h\ glamor.h diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c index 7d8228cdd..fa753bb1a 100644 --- a/xorg-server/glamor/glamor.c +++ b/xorg-server/glamor/glamor.c @@ -123,6 +123,17 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap) glamor_priv->back_pixmap = back_pixmap; } +uint32_t +glamor_get_pixmap_texture(PixmapPtr pixmap) +{ + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY) + return 0; + + return pixmap_priv->base.fbo->tex; +} + PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) @@ -556,16 +567,16 @@ glamor_enable_dri3(ScreenPtr screen) } Bool -glamor_is_dri3_support_enabled(ScreenPtr screen) +glamor_supports_pixmap_import_export(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); return glamor_priv->dri3_enabled; } -int -glamor_dri3_fd_from_pixmap(ScreenPtr screen, - PixmapPtr pixmap, CARD16 *stride, CARD32 *size) +_X_EXPORT int +glamor_fd_from_pixmap(ScreenPtr screen, + PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = @@ -589,7 +600,7 @@ glamor_dri3_fd_from_pixmap(ScreenPtr screen, } int -glamor_dri3_name_from_pixmap(PixmapPtr pixmap) +glamor_name_from_pixmap(PixmapPtr pixmap) { glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h index eec687256..e12f497cb 100644 --- a/xorg-server/glamor/glamor.h +++ b/xorg-server/glamor/glamor.h @@ -35,6 +35,9 @@ #include <picturestr.h> #include <fb.h> #include <fbpict.h> +#ifdef GLAMOR_FOR_XORG +#include <xf86xv.h> +#endif struct glamor_context; @@ -64,10 +67,12 @@ typedef enum glamor_pixmap_type { #define GLAMOR_USE_SCREEN (1 << 1) #define GLAMOR_USE_PICTURE_SCREEN (1 << 2) #define GLAMOR_USE_EGL_SCREEN (1 << 3) +#define GLAMOR_NO_DRI3 (1 << 4) #define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \ | GLAMOR_USE_SCREEN \ | GLAMOR_USE_PICTURE_SCREEN \ - | GLAMOR_USE_EGL_SCREEN) + | GLAMOR_USE_EGL_SCREEN \ + | GLAMOR_NO_DRI3) /* @glamor_init: Initialize glamor internal data structure. * @@ -124,6 +129,8 @@ extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen); extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap); +extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap); + /* @glamor_glyphs_init: Initialize glyphs internal data structures. * * @pScreen: Current screen pointer. @@ -168,21 +175,23 @@ extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr, unsigned int, Bool, CARD16 *, CARD32 *); -/* @glamor_is_dri3_support_enabled: Returns if DRI3 support is enabled. +/* @glamor_supports_pixmap_import_export: Returns whether + * glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and + * glamor_pixmap_from_fd() are supported. * * @screen: Current screen pointer. * - * To have DRI3 support enabled, glamor and glamor_egl need to be initialized, - * and glamor_egl_init_textured_pixmap need to be called. glamor also - * has to be compiled with gbm support. - * The EGL layer need to have the following extensions working: + * To have DRI3 support enabled, glamor and glamor_egl need to be + * initialized. glamor also has to be compiled with gbm support. + * + * The EGL layer needs to have the following extensions working: + * * .EGL_KHR_gl_texture_2D_image * .EGL_EXT_image_dma_buf_import - * If DRI3 support is not enabled, the following helpers will return an error. * */ -extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen); +extern _X_EXPORT Bool glamor_supports_pixmap_import_export(ScreenPtr screen); -/* @glamor_dri3_fd_from_pixmap: DRI3 helper to get a dma-buf fd from a pixmap. +/* @glamor_fd_from_pixmap: Get a dma-buf fd from a pixmap. * * @screen: Current screen pointer. * @pixmap: The pixmap from which we want the fd. @@ -193,22 +202,25 @@ extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen); * content. * Returns the fd on success, -1 on error. * */ -extern _X_EXPORT int glamor_dri3_fd_from_pixmap(ScreenPtr screen, - PixmapPtr pixmap, - CARD16 *stride, CARD32 *size); +extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen, + PixmapPtr pixmap, + CARD16 *stride, CARD32 *size); -/* @glamor_dri3_name_from_pixmap: helper to get an gem name from a pixmap. +/** + * @glamor_name_from_pixmap: Gets a gem name from a pixmap. * * @pixmap: The pixmap from which we want the gem name. * - * the pixmap and the buffer associated by the gem name will share the same - * content. This function can be used by the DDX to support DRI2, but needs - * glamor DRI3 support to be activated. + * the pixmap and the buffer associated by the gem name will share the + * same content. This function can be used by the DDX to support DRI2, + * and needs the same set of buffer export GL extensions as DRI3 + * support. + * * Returns the name on success, -1 on error. * */ -extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap); +extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap); -/* @glamor_egl_dri3_pixmap_from_fd: DRI3 helper to get a pixmap from a dma-buf fd. +/* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd. * * @screen: Current screen pointer. * @fd: The dma-buf fd to import. @@ -220,13 +232,13 @@ extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap); * * Returns a valid pixmap if the import succeeded, else NULL. * */ -extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, - int fd, - CARD16 width, - CARD16 height, - CARD16 stride, - CARD8 depth, - CARD8 bpp); +extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen, + int fd, + CARD16 width, + CARD16 height, + CARD16 stride, + CARD8 depth, + CARD8 bpp); #ifdef GLAMOR_FOR_XORG @@ -432,7 +444,7 @@ extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points); -#if 0 +#ifdef GLAMOR_FOR_XORG extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen, int num_texture_ports); #endif diff --git a/xorg-server/glamor/glamor_egl.c b/xorg-server/glamor/glamor_egl.c index 9dcba71ce..05e6bd02e 100644 --- a/xorg-server/glamor/glamor_egl.c +++ b/xorg-server/glamor/glamor_egl.c @@ -50,6 +50,7 @@ #include "glamor.h" #include "glamor_priv.h" +#include "dri3.h" static const char glamor_name[] = "glamor"; @@ -68,6 +69,7 @@ struct glamor_egl_screen_private { EGLDisplay display; EGLContext context; EGLint major, minor; + char *device_path; CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; @@ -453,12 +455,12 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, #endif } -PixmapPtr -glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, - int fd, - CARD16 width, - CARD16 height, - CARD16 stride, CARD8 depth, CARD8 bpp) +_X_EXPORT PixmapPtr +glamor_pixmap_from_fd(ScreenPtr screen, + int fd, + CARD16 width, + CARD16 height, + CARD16 stride, CARD8 depth, CARD8 bpp) { #ifdef GLAMOR_HAS_GBM ScrnInfoPtr scrn = xf86ScreenToScrn(screen); @@ -627,10 +629,67 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, return FALSE; } +static int +glamor_dri3_open(ScreenPtr screen, + RRProviderPtr provider, + int *fdp) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + int fd; + drm_magic_t magic; + + fd = open(glamor_egl->device_path, O_RDWR|O_CLOEXEC); + if (fd < 0) + return BadAlloc; + + /* Before FD passing in the X protocol with DRI3 (and increased + * security of rendering with per-process address spaces on the + * GPU), the kernel had to come up with a way to have the server + * decide which clients got to access the GPU, which was done by + * each client getting a unique (magic) number from the kernel, + * passing it to the server, and the server then telling the + * kernel which clients were authenticated for using the device. + * + * Now that we have FD passing, the server can just set up the + * authentication on its own and hand the prepared FD off to the + * client. + */ + if (drmGetMagic(fd, &magic) < 0) { + if (errno == EACCES) { + /* Assume that we're on a render node, and the fd is + * already as authenticated as it should be. + */ + *fdp = fd; + return Success; + } else { + close(fd); + return BadMatch; + } + } + + if (drmAuthMagic(glamor_egl->fd, magic) < 0) { + close(fd); + return BadMatch; + } + + *fdp = fd; + return Success; +} + +static dri3_screen_info_rec glamor_dri3_info = { + .version = 0, + .open = glamor_dri3_open, + .pixmap_from_fd = glamor_pixmap_from_fd, + .fd_from_pixmap = glamor_fd_from_pixmap, +}; + void glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); @@ -642,6 +701,30 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) glamor_ctx->get_context = glamor_egl_get_context; glamor_ctx->put_context = glamor_egl_put_context; + + if (glamor_egl->dri3_capable) { + /* Tell the core that we have the interfaces for import/export + * of pixmaps. + */ + glamor_enable_dri3(screen); + + /* If the driver wants to do its own auth dance (e.g. Xwayland + * on pre-3.15 kernels that don't have render nodes and thus + * has the wayland compositor as a master), then it needs us + * to stay out of the way and let it init DRI3 on its own. + */ + if (!(glamor_priv->flags & GLAMOR_NO_DRI3)) { + /* To do DRI3 device FD generation, we need to open a new fd + * to the same device we were handed in originally. + */ + glamor_egl->device_path = drmGetDeviceNameFromFd(glamor_egl->fd); + + if (!dri3_screen_init(screen, &glamor_dri3_info)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to initialize DRI3.\n"); + } + } + } } static void @@ -658,6 +741,8 @@ glamor_egl_free_screen(ScrnInfoPtr scrn) if (glamor_egl->gbm) gbm_device_destroy(glamor_egl->gbm); #endif + free(glamor_egl->device_path); + scrn->FreeScreen = glamor_egl->saved_free_screen; free(glamor_egl); scrn->FreeScreen(scrn); diff --git a/xorg-server/glamor/glamor_eglmodule.c b/xorg-server/glamor/glamor_eglmodule.c index 5ddd60235..d7e183649 100644 --- a/xorg-server/glamor/glamor_eglmodule.c +++ b/xorg-server/glamor/glamor_eglmodule.c @@ -30,6 +30,7 @@ #include "dix-config.h" #include <xorg-server.h> +#include <xf86.h> #define GLAMOR_FOR_XORG #include <xf86Module.h> #include "glamor.h" @@ -40,7 +41,7 @@ static XF86ModuleVersionInfo VersRec = { MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, - PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, + 1, 0, 0, /* version */ ABI_CLASS_ANSIC, /* Only need the ansic layer */ ABI_ANSIC_VERSION, MOD_CLASS_NONE, diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c index dc39476b5..fb9045747 100644 --- a/xorg-server/glamor/glamor_xv.c +++ b/xorg-server/glamor/glamor_xv.c @@ -32,10 +32,14 @@ * Xv acceleration implementation */ -#include "glamor_priv.h" +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif -#ifdef GLAMOR_XV #include "xf86xv.h" +#define GLAMOR_FOR_XORG +#include "glamor_priv.h" + #include <X11/extensions/Xv.h> #include "fourcc.h" /* Reference color space transform data */ @@ -430,7 +434,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn, Bool sync, RegionPtr clipBoxes, void *data, DrawablePtr pDrawable) { - ScreenPtr screen = xf86ScrnToScreen(pScrn); + ScreenPtr screen = pDrawable->pScreen; glamor_port_private *port_priv = (glamor_port_private *) data; INT32 x1, x2, y1, y2; int srcPitch, srcPitch2; @@ -614,12 +618,3 @@ glamor_xv_init(ScreenPtr screen, int num_texture_ports) } return adapt; } -#else -#if 0 -XF86VideoAdaptorPtr -glamor_xv_init(ScreenPtr screen, int num_texture_ports) -{ - return NULL; -} -#endif -#endif diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.am b/xorg-server/hw/kdrive/ephyr/Makefile.am index 6b790fddd..040993ce0 100644 --- a/xorg-server/hw/kdrive/ephyr/Makefile.am +++ b/xorg-server/hw/kdrive/ephyr/Makefile.am @@ -27,12 +27,20 @@ AM_CPPFLAGS = \ @XEPHYR_INCS@ \ @XEPHYR_CFLAGS@ \ -I$(top_srcdir) \ + -I$(top_srcdir)/glamor \ -I$(top_srcdir)/exa if XV XV_SRCS = ephyrvideo.c endif +if GLAMOR +GLAMOR_SRCS = \ + ephyr_glamor_glx.c \ + ephyr_glamor_glx.h \ + () +endif + if DRI DRI_SRCS = \ ephyrdriext.c \ @@ -59,14 +67,24 @@ Xephyr_SOURCES = \ hostx.h \ $(XV_SRCS) \ $(DRI_SRCS) \ + $(GLAMOR_SRCS) \ $() +if GLAMOR +AM_CPPFLAGS += $(XLIB_CFLAGS) +XEPHYR_GLAMOR_LIB = \ + $(top_builddir)/glamor/libglamor.la \ + $(top_builddir)/glamor/libglamor_egl_stubs.la \ + $() +endif + Xephyr_LDADD = \ $(top_builddir)/exa/libexa.la \ + $(XEPHYR_GLAMOR_LIB) \ @KDRIVE_LIBS@ \ @XEPHYR_LIBS@ -Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@ +Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@ $(XEPHYR_GLAMOR_LIB) Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c index 968127308..def50d8d8 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr.c @@ -43,9 +43,15 @@ #include "ephyrglxext.h" #endif /* XF86DRI */ +#ifdef GLAMOR +#include "glamor.h" +#endif +#include "ephyr_glamor_glx.h" + #include "xkbsrv.h" extern int KdTsPhyScreen; +extern Bool ephyr_glamor; KdKeyboardInfo *ephyrKbd; KdPointerInfo *ephyrMouse; @@ -326,15 +332,19 @@ ephyrInternalDamageRedisplay(ScreenPtr pScreen) int nbox; BoxPtr pbox; - nbox = RegionNumRects(pRegion); - pbox = RegionRects(pRegion); - - while (nbox--) { - hostx_paint_rect(screen, - pbox->x1, pbox->y1, - pbox->x1, pbox->y1, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - pbox++; + if (ephyr_glamor) { + ephyr_glamor_damage_redisplay(scrpriv->glamor, pRegion); + } else { + nbox = RegionNumRects(pRegion); + pbox = RegionRects(pRegion); + + while (nbox--) { + hostx_paint_rect(screen, + pbox->x1, pbox->y1, + pbox->x1, pbox->y1, + pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + pbox++; + } } DamageEmpty(scrpriv->pDamage); } @@ -662,6 +672,7 @@ ephyrInitScreen(ScreenPtr pScreen) return TRUE; } + Bool ephyrFinishInitScreen(ScreenPtr pScreen) { @@ -679,6 +690,12 @@ ephyrFinishInitScreen(ScreenPtr pScreen) return TRUE; } +/** + * Called by kdrive after calling down the + * pScreen->CreateScreenResources() chain, this gives us a chance to + * make any pixmaps after the screen and all extensions have been + * initialized. + */ Bool ephyrCreateResources(ScreenPtr pScreen) { @@ -693,8 +710,13 @@ ephyrCreateResources(ScreenPtr pScreen) return KdShadowSet(pScreen, scrpriv->randr, ephyrShadowUpdate, ephyrWindowLinear); - else + else { +#ifdef GLAMOR + if (ephyr_glamor) + ephyr_glamor_create_screen_resources(pScreen); +#endif return ephyrSetInternalDamage(pScreen); + } } void @@ -1201,6 +1223,9 @@ ephyrPoll(void) break; } + if (ephyr_glamor) + ephyr_glamor_process_event(xev); + free(xev); } } diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h index 73fdb59e6..34ce4601b 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.h +++ b/xorg-server/hw/kdrive/ephyr/ephyr.h @@ -80,6 +80,12 @@ typedef struct _ephyrScrPriv { KdScreenInfo *screen; int mynum; /* Screen number */ + + /** + * Per-screen Xlib-using state for glamor (private to + * ephyr_glamor_glx.c) + */ + struct ephyr_glamor *glamor; } EphyrScrPriv; extern KdCardFuncs ephyrFuncs; @@ -203,6 +209,14 @@ void void ephyrDrawFini(ScreenPtr pScreen); +/* hostx.c glamor support */ +Bool ephyr_glamor_init(ScreenPtr pScreen); +Bool ephyr_glamor_create_screen_resources(ScreenPtr pScreen); +void ephyr_glamor_enable(ScreenPtr pScreen); +void ephyr_glamor_disable(ScreenPtr pScreen); +void ephyr_glamor_fini(ScreenPtr pScreen); +void ephyr_glamor_host_paint_rect(ScreenPtr pScreen); + /*ephyvideo.c*/ Bool ephyrInitVideo(ScreenPtr pScreen); diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c new file mode 100644 index 000000000..d56907fe7 --- /dev/null +++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -0,0 +1,331 @@ +/* + * 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. + */ + +/** @file ephyr_glamor_glx.c + * + * Separate file for hiding Xlib and GLX-using parts of xephyr from + * the rest of the server-struct-aware build. + */ + +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Xlibint.h> +#undef Xcalloc +#undef Xrealloc +#undef Xfree +#include <X11/Xlib-xcb.h> +#include <xcb/xcb_aux.h> +#include <pixman.h> +#include <epoxy/glx.h> +#include "ephyr_glamor_glx.h" +#include "os.h" +#include <X11/Xproto.h> + +/** @{ + * + * global state for Xephyr with glamor. + * + * Xephyr can render with multiple windows, but all the windows have + * to be on the same X connection and all have to have the same + * visual. + */ +static Display *dpy; +static XVisualInfo *visual_info; +static GLXFBConfig fb_config; +/** @} */ + +/** + * Per-screen state for Xephyr with glamor. + */ +struct ephyr_glamor { + GLXContext ctx; + Window win; + GLXWindow glx_win; + + GLuint tex; + + GLuint texture_shader; + GLuint texture_shader_position_loc; + GLuint texture_shader_texcoord_loc; +}; + +static GLint +ephyr_glamor_compile_glsl_prog(GLenum type, const char *source) +{ + GLint ok; + GLint prog; + + prog = glCreateShader(type); + glShaderSource(prog, 1, (const GLchar **) &source, NULL); + glCompileShader(prog); + glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); + if (!ok) { + GLchar *info; + GLint size; + + glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); + if (info) { + glGetShaderInfoLog(prog, size, NULL, info); + ErrorF("Failed to compile %s: %s\n", + type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); + ErrorF("Program source:\n%s", source); + free(info); + } + else + ErrorF("Failed to get shader compilation info.\n"); + FatalError("GLSL compile failure\n"); + } + + return prog; +} + +static GLuint +ephyr_glamor_build_glsl_prog(GLuint vs, GLuint fs) +{ + GLint ok; + GLuint prog; + + prog = glCreateProgram(); + glAttachShader(prog, vs); + glAttachShader(prog, fs); + + glLinkProgram(prog); + glGetProgramiv(prog, GL_LINK_STATUS, &ok); + if (!ok) { + GLchar *info; + GLint size; + + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); + + glGetProgramInfoLog(prog, size, NULL, info); + ErrorF("Failed to link: %s\n", info); + FatalError("GLSL link failure\n"); + } + + return prog; +} + +static void +ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor) +{ + const char *vs_source = + "attribute vec2 texcoord;\n" + "attribute vec2 position;\n" + "varying vec2 t;\n" + "\n" + "void main()\n" + "{\n" + " t = texcoord;\n" + " gl_Position = vec4(position, 0, 1);\n" + "}\n"; + + const char *fs_source = + "varying vec2 t;\n" + "uniform sampler2D s; /* initially 0 */\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(s, t);\n" + "}\n"; + + GLuint fs, vs, prog; + + vs = ephyr_glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); + fs = ephyr_glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); + prog = ephyr_glamor_build_glsl_prog(vs, fs); + + glamor->texture_shader = prog; + glamor->texture_shader_position_loc = glGetAttribLocation(prog, "position"); + assert(glamor->texture_shader_position_loc != -1); + glamor->texture_shader_texcoord_loc = glGetAttribLocation(prog, "texcoord"); + assert(glamor->texture_shader_texcoord_loc != -1); +} + +xcb_connection_t * +ephyr_glamor_connect(void) +{ + dpy = XOpenDisplay(NULL); + if (!dpy) + return NULL; + + XSetEventQueueOwner(dpy, XCBOwnsEventQueue); + + return XGetXCBConnection(dpy); +} + +void +ephyr_glamor_set_texture(struct ephyr_glamor *glamor, uint32_t tex) +{ + glamor->tex = tex; +} + +void +ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, + struct pixman_region16 *damage) +{ + /* Redraw the whole screen, since glXSwapBuffers leaves the back + * buffer undefined. + */ + static const float position[] = { + -1, -1, + 1, -1, + 1, 1, + -1, 1, + }; + static const float texcoords[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0, + }; + + glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glUseProgram(glamor->texture_shader); + + glVertexAttribPointer(glamor->texture_shader_position_loc, + 2, GL_FLOAT, FALSE, 0, position); + glVertexAttribPointer(glamor->texture_shader_texcoord_loc, + 2, GL_FLOAT, FALSE, 0, texcoords); + glEnableVertexAttribArray(glamor->texture_shader_position_loc); + glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, glamor->tex); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(glamor->texture_shader_position_loc); + glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc); + + glXSwapBuffers(dpy, glamor->glx_win); +} + +/** + * Xlib-based handling of xcb events for glamor. + * + * We need to let the Xlib event filtering run on the event so that + * Mesa's dri2_glx.c userspace event mangling gets run, and we + * correctly get our invalidate events propagated into the driver. + */ +void +ephyr_glamor_process_event(xcb_generic_event_t *xev) +{ + + uint32_t response_type = xev->response_type & 0x7f; + /* Note the types on wire_to_event: there's an Xlib XEvent (with + * the broken types) that it returns, and a protocol xEvent that + * it inspects. + */ + Bool (*wire_to_event)(Display *dpy, XEvent *ret, xEvent *event); + + XLockDisplay(dpy); + /* Set the event handler to NULL to get access to the current one. */ + wire_to_event = XESetWireToEvent(dpy, response_type, NULL); + if (wire_to_event) { + XEvent processed_event; + + /* OK they had an event handler. Plug it back in, and call + * through to it. + */ + XESetWireToEvent(dpy, response_type, wire_to_event); + xev->sequence = LastKnownRequestProcessed(dpy); + wire_to_event(dpy, &processed_event, (xEvent *)xev); + } + XUnlockDisplay(dpy); +} + +struct ephyr_glamor * +ephyr_glamor_glx_screen_init(xcb_window_t win) +{ + GLXContext ctx; + struct ephyr_glamor *glamor; + GLXWindow glx_win; + + glamor = calloc(1, sizeof(struct ephyr_glamor)); + if (!glamor) { + FatalError("malloc"); + return NULL; + } + + glx_win = glXCreateWindow(dpy, fb_config, win, NULL); + + ctx = glXCreateContext(dpy, visual_info, NULL, True); + if (ctx == NULL) + FatalError("glXCreateContext failed\n"); + + if (!glXMakeCurrent(dpy, glx_win, ctx)) + FatalError("glXMakeCurrent failed\n"); + + glamor->ctx = ctx; + glamor->win = win; + glamor->glx_win = glx_win; + ephyr_glamor_setup_texturing_shader(glamor); + + return glamor; +} + +void +ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor) +{ + glXMakeCurrent(dpy, None, NULL); + glXDestroyContext(dpy, glamor->ctx); + glXDestroyWindow(dpy, glamor->glx_win); + + free(glamor); +} + +xcb_visualtype_t * +ephyr_glamor_get_visual(void) +{ + xcb_screen_t *xscreen = + xcb_aux_get_screen(XGetXCBConnection(dpy), DefaultScreen(dpy)); + int attribs[] = { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, 1, + None + }; + int event_base = 0, error_base = 0, nelements; + GLXFBConfig *fbconfigs; + + if (!glXQueryExtension (dpy, &error_base, &event_base)) + FatalError("Couldn't find GLX extension\n"); + + fbconfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &nelements); + if (!nelements) + FatalError("Couldn't choose an FBConfig\n"); + fb_config = fbconfigs[0]; + free(fbconfigs); + + visual_info = glXGetVisualFromFBConfig(dpy, fb_config); + if (visual_info == NULL) + FatalError("Couldn't get RGB visual\n"); + + return xcb_aux_find_visual_by_id(xscreen, visual_info->visualid); +} diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h new file mode 100644 index 000000000..8995e1eca --- /dev/null +++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h @@ -0,0 +1,73 @@ +/* + * 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. + */ + +/** + * ephyr_glamor_glx.h + * + * Prototypes exposed by ephyr_glamor_glx.c, without including any + * server headers. + */ + +#include <xcb/xcb.h> +#include "dix-config.h" + +struct ephyr_glamor; +struct pixman_region16; + +xcb_connection_t * +ephyr_glamor_connect(void); + +void +ephyr_glamor_set_texture(struct ephyr_glamor *ephyr_glamor, uint32_t tex); + +xcb_visualtype_t * +ephyr_glamor_get_visual(void); + +struct ephyr_glamor * +ephyr_glamor_glx_screen_init(xcb_window_t win); + +void +ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor); + +#ifdef GLAMOR +void +ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, + struct pixman_region16 *damage); + +void +ephyr_glamor_process_event(xcb_generic_event_t *xev); + +#else /* !GLAMOR */ + +static inline void +ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, + struct pixman_region16 *damage) +{ +} + +static inline void +ephyr_glamor_process_event(xcb_generic_event_t *xev) +{ +} + +#endif /* !GLAMOR */ diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 3230e707e..807e717b1 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -35,6 +35,7 @@ extern Bool EphyrWantGrayScale; extern Bool EphyrWantResize; extern Bool kdHasPointer; extern Bool kdHasKbd; +extern Bool ephyr_glamor; #ifdef GLXEXT extern Bool ephyrNoDRI; @@ -138,6 +139,9 @@ ddxUseMsg(void) ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); ErrorF("-grayscale Simulate 8bit grayscale\n"); ErrorF("-resizeable Make Xephyr windows resizeable\n"); +#ifdef GLAMOR + ErrorF("-glamor Enable 2D acceleration using glamor\n"); +#endif ErrorF ("-fakexa Simulate acceleration using software rendering\n"); ErrorF("-verbosity <level> Set log verbosity level\n"); @@ -241,6 +245,16 @@ ddxProcessArgument(int argc, char **argv, int i) EphyrWantResize = 1; return 1; } +#ifdef GLAMOR + else if (!strcmp (argv[i], "-glamor")) { + ephyr_glamor = TRUE; + ephyrFuncs.initAccel = ephyr_glamor_init; + ephyrFuncs.enableAccel = ephyr_glamor_enable; + ephyrFuncs.disableAccel = ephyr_glamor_disable; + ephyrFuncs.finiAccel = ephyr_glamor_fini; + return 1; + } +#endif else if (!strcmp(argv[i], "-fakexa")) { ephyrFuncs.initAccel = ephyrDrawInit; ephyrFuncs.enableAccel = ephyrDrawEnable; diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index 44ad8e28f..859becaa6 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -36,6 +36,7 @@ #include <string.h> /* for memset */ #include <errno.h> #include <time.h> +#include <err.h> #include <sys/ipc.h> #include <sys/shm.h> @@ -54,6 +55,11 @@ #include <xcb/xf86dri.h> #include <xcb/glx.h> #endif /* XF86DRI */ +#ifdef GLAMOR +#include <epoxy/gl.h> +#include "glamor.h" +#include "ephyr_glamor_glx.h" +#endif #include "ephyrlog.h" #include "ephyr.h" @@ -90,6 +96,7 @@ extern Bool EphyrWantResize; char *ephyrResName = NULL; int ephyrResNameFromCmd = 0; char *ephyrTitle = NULL; +Bool ephyr_glamor = FALSE; static void hostx_set_fullscreen_hint(void); @@ -302,7 +309,12 @@ hostx_init(void) | XCB_EVENT_MASK_STRUCTURE_NOTIFY; EPHYR_DBG("mark"); - HostX.conn = xcb_connect(NULL, &HostX.screen); +#ifdef GLAMOR + if (ephyr_glamor) + HostX.conn = ephyr_glamor_connect(); + else +#endif + HostX.conn = xcb_connect(NULL, &HostX.screen); if (xcb_connection_has_error(HostX.conn)) { fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n"); exit(1); @@ -312,7 +324,12 @@ hostx_init(void) HostX.winroot = xscreen->root; HostX.gc = xcb_generate_id(HostX.conn); HostX.depth = xscreen->root_depth; - HostX.visual = xcb_aux_find_visual_by_id(xscreen, xscreen->root_visual); +#ifdef GLAMOR + if (ephyr_glamor) + HostX.visual = ephyr_glamor_get_visual(); + else +#endif + HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual); xcb_create_gc(HostX.conn, HostX.gc, HostX.winroot, 0, NULL); cookie_WINDOW_STATE = xcb_intern_atom(HostX.conn, FALSE, @@ -642,7 +659,7 @@ hostx_screen_init(KdScreenInfo *screen, } } - if (HostX.have_shm) { + if (!ephyr_glamor && HostX.have_shm) { scrpriv->ximg = xcb_image_create_native(HostX.conn, width, buffer_height, @@ -677,7 +694,7 @@ hostx_screen_init(KdScreenInfo *screen, } } - if (!shm_success) { + if (!ephyr_glamor && !shm_success) { EPHYR_DBG("Creating image %dx%d for screen scrpriv=%p\n", width, buffer_height, scrpriv); scrpriv->ximg = xcb_image_create_native(HostX.conn, @@ -711,7 +728,11 @@ hostx_screen_init(KdScreenInfo *screen, scrpriv->win_width = width; scrpriv->win_height = height; - if (host_depth_matches_server(scrpriv)) { + if (ephyr_glamor) { + *bytes_per_line = 0; + *bits_per_pixel = 0; + return NULL; + } else if (host_depth_matches_server(scrpriv)) { *bytes_per_line = scrpriv->ximg->stride; *bits_per_pixel = scrpriv->ximg->bpp; @@ -742,6 +763,23 @@ hostx_paint_rect(KdScreenInfo *screen, EPHYR_DBG("painting in screen %d\n", scrpriv->mynum); +#ifdef GLAMOR + if (ephyr_glamor) { + BoxRec box; + RegionRec region; + + box.x1 = dx; + box.y1 = dy; + box.x2 = dx + width; + box.y2 = dy + height; + + RegionInit(®ion, &box, 1); + ephyr_glamor_damage_redisplay(scrpriv->glamor, ®ion); + RegionUninit(®ion); + return; + } +#endif + /* * Copy the image data updated by the shadow layer * on to the window @@ -1170,3 +1208,86 @@ hostx_get_resource_id_peer(int a_local_resource_id, int *a_remote_resource_id) } #endif /* XF86DRI */ + +#ifdef GLAMOR +Bool +ephyr_glamor_init(ScreenPtr screen) +{ + KdScreenPriv(screen); + KdScreenInfo *kd_screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = kd_screen->driver; + + scrpriv->glamor = ephyr_glamor_glx_screen_init(scrpriv->win); + + glamor_init(screen, + GLAMOR_USE_SCREEN | + GLAMOR_USE_PICTURE_SCREEN | + GLAMOR_INVERTED_Y_AXIS); + + return TRUE; +} + +Bool +ephyr_glamor_create_screen_resources(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *kd_screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = kd_screen->driver; + PixmapPtr screen_pixmap; + uint32_t tex; + + if (!ephyr_glamor) + return TRUE; + + if (!glamor_glyphs_init(pScreen)) + return FALSE; + + /* kdrive's fbSetupScreen() told mi to have + * miCreateScreenResources() (which is called before this) make a + * scratch pixmap wrapping ephyr-glamor's NULL + * KdScreenInfo->fb.framebuffer. + * + * We want a real (texture-based) screen pixmap at this point. + * This is what glamor will render into, and we'll then texture + * out of that into the host's window to present the results. + * + * Thus, delete the current screen pixmap, and put a fresh one in. + */ + screen_pixmap = pScreen->GetScreenPixmap(pScreen); + pScreen->DestroyPixmap(screen_pixmap); + + screen_pixmap = pScreen->CreatePixmap(pScreen, + pScreen->width, + pScreen->height, + pScreen->rootDepth, 0); + pScreen->SetScreenPixmap(screen_pixmap); + + /* Tell the GLX code what to GL texture to read from. */ + tex = glamor_get_pixmap_texture(screen_pixmap); + ephyr_glamor_set_texture(scrpriv->glamor, tex); + + return TRUE; +} + +void +ephyr_glamor_enable(ScreenPtr screen) +{ +} + +void +ephyr_glamor_disable(ScreenPtr screen) +{ +} + +void +ephyr_glamor_fini(ScreenPtr screen) +{ + KdScreenPriv(screen); + KdScreenInfo *kd_screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = kd_screen->driver; + + glamor_fini(screen); + ephyr_glamor_glx_screen_fini(scrpriv->glamor); + scrpriv->glamor = NULL; +} +#endif diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index 96729043d..73e1b4c1f 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -14,6 +14,10 @@ DRI3_BUILDDIR = $(top_builddir)/dri3 DRI3_LIB = $(DRI3_BUILDDIR)/libdri3.la endif +if GLAMOR_EGL +GLAMOR_EGL_SUBDIR = glamor_egl +endif + if XF86UTILS XF86UTILS_SUBDIR = utils endif @@ -33,7 +37,8 @@ endif SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \ ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \ $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \ - fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man + fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man \ + $(GLAMOR_EGL_SUBDIR) DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ parser ramdac shadowfb vbe vgahw \ diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c index 7b53949fa..06af73903 100644 --- a/xorg-server/hw/xfree86/common/xf86Events.c +++ b/xorg-server/hw/xfree86/common/xf86Events.c @@ -85,6 +85,8 @@ #endif #include "xf86platformBus.h" +#include "systemd-logind.h" + /* * This is a toggling variable: * FALSE = No VT switching keys have been pressed last time around @@ -556,8 +558,11 @@ xf86VTEnter(void) /* Turn screen saver off when switching back */ dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); - for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) - xf86EnableInputDeviceForVTSwitch(pInfo); + /* If we use systemd-logind it will enable input devices for us */ + if (!systemd_logind_controls_session()) + for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) + xf86EnableInputDeviceForVTSwitch(pInfo); + for (ih = InputHandlers; ih; ih = ih->next) { if (ih->is_input) xf86EnableInputHandler(ih); @@ -589,10 +594,14 @@ xf86VTSwitch(void) /* * Since all screens are currently all in the same state it is sufficient * check the first. This might change in future. + * + * VTLeave is always handled here (VT_PROCESS guarantees this is safe), + * if we use systemd_logind xf86VTEnter() gets called by systemd-logind.c + * once it has resumed all drm nodes. */ if (xf86VTOwner()) xf86VTLeave(); - else + else if (!systemd_logind_controls_session()) xf86VTEnter(); } diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c index ff4d38f28..4579ff591 100644 --- a/xorg-server/hw/xfree86/common/xf86Init.c +++ b/xorg-server/hw/xfree86/common/xf86Init.c @@ -54,6 +54,7 @@ #include "site.h" #include "mi.h" #include "dbus-core.h" +#include "systemd-logind.h" #include "compiler.h" @@ -458,6 +459,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) DoShowOptions(); dbus_core_init(); + systemd_logind_init(); /* Do a general bus probe. This will be a PCI probe for x86 platforms */ xf86BusProbe(); @@ -1062,6 +1064,7 @@ ddxGiveUp(enum ExitCode error) if (xorgHWOpenConsole) xf86CloseConsole(); + systemd_logind_fini(); dbus_core_fini(); xf86CloseLog(error); diff --git a/xorg-server/hw/xfree86/common/xf86Module.h b/xorg-server/hw/xfree86/common/xf86Module.h index b6ec19d13..e8c24f26c 100644 --- a/xorg-server/hw/xfree86/common/xf86Module.h +++ b/xorg-server/hw/xfree86/common/xf86Module.h @@ -80,8 +80,8 @@ typedef enum { * mask is 0xFFFF0000. */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) -#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(15, 0) -#define ABI_XINPUT_VERSION SET_ABI_VERSION(20, 0) +#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(16, 0) +#define ABI_XINPUT_VERSION SET_ABI_VERSION(21, 0) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(8, 0) #define ABI_FONT_VERSION SET_ABI_VERSION(0, 6) diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index f6f2b90dd..7c3e479e5 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -63,6 +63,7 @@ #include "mipointer.h" #include "extinit.h" #include "loaderProcs.h" +#include "systemd-logind.h" #include "exevents.h" /* AddInputDevice */ #include "exglobals.h" @@ -80,6 +81,7 @@ #include <stdarg.h> #include <stdint.h> /* for int64_t */ +#include <unistd.h> #include "mi.h" @@ -103,6 +105,9 @@ static int xf86InputDevicePostInit(DeviceIntPtr dev); +static InputInfoPtr *new_input_devices; +static int new_input_devices_count; + /** * Eval config and modify DeviceVelocityRec accordingly */ @@ -773,6 +778,11 @@ xf86DeleteInput(InputInfoPtr pInp, int flags) /* Else the entry wasn't in the xf86InputDevs list (ignore this). */ } + if (pInp->flags & XI86_SERVER_FD) { + systemd_logind_release_fd(pInp->major, pInp->minor); + close(pInp->fd); + } + free((void *) pInp->driver); free((void *) pInp->name); xf86optionListFree(pInp->options); @@ -816,6 +826,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) { InputDriverPtr drv = NULL; DeviceIntPtr dev = NULL; + Bool paused; int rval; /* Memory leak for every attached device if we don't @@ -830,6 +841,26 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) goto unwind; } + if (drv->capabilities & XI86_DRV_CAP_SERVER_FD) { + int fd = systemd_logind_take_fd(pInfo->major, pInfo->minor, + pInfo->attrs->device, &paused); + if (fd != -1) { + if (paused) { + /* Put on new_input_devices list for delayed probe */ + new_input_devices = xnfrealloc(new_input_devices, + sizeof(pInfo) * (new_input_devices_count + 1)); + new_input_devices[new_input_devices_count] = pInfo; + new_input_devices_count++; + systemd_logind_release_fd(pInfo->major, pInfo->minor); + close(fd); + return BadMatch; + } + pInfo->fd = fd; + pInfo->flags |= XI86_SERVER_FD; + pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd); + } + } + xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName, pInfo->name); @@ -949,6 +980,12 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs, goto unwind; } } + + if (strcmp(key, "major") == 0) + pInfo->major = atoi(value); + + if (strcmp(key, "minor") == 0) + pInfo->minor = atoi(value); } nt_list_for_each_entry(option, options, list.next) { @@ -1469,4 +1506,32 @@ xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid, uint16_t type, QueueTouchEvents(dev, type, touchid, flags, mask); } +void +xf86InputEnableVTProbe(void) +{ + int i, is_auto = 0; + InputOption *option = NULL; + DeviceIntPtr pdev; + + for (i = 0; i < new_input_devices_count; i++) { + InputInfoPtr pInfo = new_input_devices[i]; + + is_auto = 0; + nt_list_for_each_entry(option, pInfo->options, list.next) { + const char *key = input_option_get_key(option); + const char *value = input_option_get_value(option); + + if (strcmp(key, "_source") == 0 && + (strcmp(value, "server/hal") == 0 || + strcmp(value, "server/udev") == 0 || + strcmp(value, "server/wscons") == 0)) + is_auto = 1; + } + xf86NewInputDevice(pInfo, &pdev, + (!is_auto || + (is_auto && xf86Info.autoEnableDevices))); + } + new_input_devices_count = 0; +} + /* end of xf86Xinput.c */ diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.h b/xorg-server/hw/xfree86/common/xf86Xinput.h index b6d125128..9fe8c87b6 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.h +++ b/xorg-server/hw/xfree86/common/xf86Xinput.h @@ -64,6 +64,10 @@ /* 0x08 is reserved for legacy XI86_SEND_DRAG_EVENTS, do not use for now */ /* server-internal only */ #define XI86_DEVICE_DISABLED 0x10 /* device was disabled before vt switch */ +#define XI86_SERVER_FD 0x20 /* fd is managed by xserver */ + +/* Input device driver capabilities */ +#define XI86_DRV_CAP_SERVER_FD 0x01 /* This holds the input driver entry and module information. */ typedef struct _InputDriverRec { @@ -76,6 +80,7 @@ typedef struct _InputDriverRec { struct _InputInfoRec * pInfo, int flags); void *module; const char **default_options; + int capabilities; } InputDriverRec, *InputDriverPtr; /* This is to input devices what the ScrnInfoRec is to screens. */ @@ -96,6 +101,8 @@ typedef struct _InputInfoRec { int *valuators, int first_valuator, int num_valuators); int fd; + int major; + int minor; DeviceIntPtr dev; void *private; const char *type_name; @@ -172,6 +179,7 @@ extern _X_EXPORT void xf86AddEnabledDevice(InputInfoPtr pInfo); extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo); extern _X_EXPORT void xf86DisableDevice(DeviceIntPtr dev, Bool panic); extern _X_EXPORT void xf86EnableDevice(DeviceIntPtr dev); +extern _X_EXPORT void xf86InputEnableVTProbe(void); /* not exported */ int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto); diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.c b/xorg-server/hw/xfree86/common/xf86platformBus.c index 5875a9136..4447e19df 100644 --- a/xorg-server/hw/xfree86/common/xf86platformBus.c +++ b/xorg-server/hw/xfree86/common/xf86platformBus.c @@ -52,10 +52,10 @@ int platformSlotClaimed; int xf86_num_platform_devices; -static struct xf86_platform_device *xf86_platform_devices; +struct xf86_platform_device *xf86_platform_devices; int -xf86_add_platform_device(struct OdevAttributes *attribs) +xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned) { xf86_platform_devices = xnfrealloc(xf86_platform_devices, (sizeof(struct xf86_platform_device) @@ -63,6 +63,8 @@ xf86_add_platform_device(struct OdevAttributes *attribs) xf86_platform_devices[xf86_num_platform_devices].attribs = attribs; xf86_platform_devices[xf86_num_platform_devices].pdev = NULL; + xf86_platform_devices[xf86_num_platform_devices].flags = + unowned ? XF86_PDEV_UNOWNED : 0; xf86_num_platform_devices++; return 0; @@ -89,35 +91,55 @@ xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_name) return config_odev_add_attribute(device->attribs, attrib_id, attrib_name); } +Bool +xf86_add_platform_device_int_attrib(int index, int attrib_id, int attrib_value) +{ + return config_odev_add_int_attribute(xf86_platform_devices[index].attribs, attrib_id, attrib_value); +} + char * xf86_get_platform_attrib(int index, int attrib_id) { - struct xf86_platform_device *device = &xf86_platform_devices[index]; - struct OdevAttribute *oa; - - xorg_list_for_each_entry(oa, &device->attribs->list, member) { - if (oa->attrib_id == attrib_id) - return oa->attrib_name; - } - return NULL; + return config_odev_get_attribute(xf86_platform_devices[index].attribs, attrib_id); } char * xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id) { - struct OdevAttribute *oa; + return config_odev_get_attribute(device->attribs, attrib_id); +} - xorg_list_for_each_entry(oa, &device->attribs->list, member) { - if (oa->attrib_id == attrib_id) - return oa->attrib_name; - } - return NULL; +int +xf86_get_platform_int_attrib(int index, int attrib_id, int def) +{ + return config_odev_get_int_attribute(xf86_platform_devices[index].attribs, attrib_id, def); +} + +int +xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int attrib_id, int def) +{ + return config_odev_get_int_attribute(device->attribs, attrib_id, def); } Bool xf86_get_platform_device_unowned(int index) { - return xf86_platform_devices[index].attribs->unowned; + return (xf86_platform_devices[index].flags & XF86_PDEV_UNOWNED) ? + TRUE : FALSE; +} + +struct xf86_platform_device * +xf86_find_platform_device_by_devnum(int major, int minor) +{ + int i, attr_major, attr_minor; + + for (i = 0; i < xf86_num_platform_devices; i++) { + attr_major = xf86_get_platform_int_attrib(i, ODEV_ATTRIB_MAJOR, 0); + attr_minor = xf86_get_platform_int_attrib(i, ODEV_ATTRIB_MINOR, 0); + if (attr_major == major && attr_minor == minor) + return &xf86_platform_devices[i]; + } + return NULL; } /* @@ -524,10 +546,10 @@ void xf86platformVTProbe(void) int i; for (i = 0; i < xf86_num_platform_devices; i++) { - if (xf86_platform_devices[i].attribs->unowned == FALSE) + if (!(xf86_platform_devices[i].flags & XF86_PDEV_UNOWNED)) continue; - xf86_platform_devices[i].attribs->unowned = FALSE; + xf86_platform_devices[i].flags &= ~XF86_PDEV_UNOWNED; xf86PlatformReprobeDevice(i, xf86_platform_devices[i].attribs); } } diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.h b/xorg-server/hw/xfree86/common/xf86platformBus.h index 4e1757854..78b5a5bea 100644 --- a/xorg-server/hw/xfree86/common/xf86platformBus.h +++ b/xorg-server/hw/xfree86/common/xf86platformBus.h @@ -30,23 +30,34 @@ struct xf86_platform_device { struct OdevAttributes *attribs; /* for PCI devices */ struct pci_device *pdev; + int flags; }; +/* xf86_platform_device flags */ +#define XF86_PDEV_UNOWNED 0x01 +#define XF86_PDEV_SERVER_FD 0x02 +#define XF86_PDEV_PAUSED 0x04 + #ifdef XSERVER_PLATFORM_BUS int xf86platformProbe(void); int xf86platformProbeDev(DriverPtr drvp); extern int xf86_num_platform_devices; +extern struct xf86_platform_device *xf86_platform_devices; extern char * xf86_get_platform_attrib(int index, int attrib_id); extern int -xf86_add_platform_device(struct OdevAttributes *attribs); +xf86_get_platform_int_attrib(int index, int attrib_id, int def); +extern int +xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned); extern int xf86_remove_platform_device(int dev_index); extern Bool xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str); extern Bool +xf86_add_platform_device_int_attrib(int index, int attrib_id, int attrib_value); +extern Bool xf86_get_platform_device_unowned(int index); extern int @@ -56,6 +67,8 @@ xf86platformRemoveDevice(int index); extern _X_EXPORT char * xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id); +extern _X_EXPORT int +xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int attrib_id, int def); extern _X_EXPORT Bool xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid); diff --git a/xorg-server/hw/xfree86/glamor_egl/Makefile.am b/xorg-server/hw/xfree86/glamor_egl/Makefile.am new file mode 100644 index 000000000..85e1c0c06 --- /dev/null +++ b/xorg-server/hw/xfree86/glamor_egl/Makefile.am @@ -0,0 +1,43 @@ +# 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. + +module_LTLIBRARIES = libglamoregl.la + +libglamoregl_la_SOURCES = \ + $(top_srcdir)/glamor/glamor_egl.c \ + $(top_srcdir)/glamor/glamor_eglmodule.c \ + $(top_srcdir)/glamor/glamor_xv.c \ + $() + +libglamoregl_la_LDFLAGS = \ + -avoid-version \ + $(GBM_LIBS) \ + $() + +libglamoregl_la_LIBADD = \ + $(top_builddir)/glamor/libglamor.la \ + $() + +AM_CPPFLAGS = $(XORG_INCS) \ + -I$(top_srcdir)/dri3 \ + $() + +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS) diff --git a/xorg-server/hw/xfree86/os-support/linux/Makefile.am b/xorg-server/hw/xfree86/os-support/linux/Makefile.am index 83e7e0027..1686dc2c1 100644 --- a/xorg-server/hw/xfree86/os-support/linux/Makefile.am +++ b/xorg-server/hw/xfree86/os-support/linux/Makefile.am @@ -21,6 +21,11 @@ APM_SRCS = lnx_apm.c XORG_CFLAGS += -DHAVE_APM endif +if SYSTEMD_LOGIND +LOGIND_SRCS = systemd-logind.c +XORG_CFLAGS += $(DBUS_CFLAGS) +endif + liblinux_la_SOURCES = lnx_init.c lnx_video.c \ lnx_agp.c lnx_kmod.c lnx_bell.c lnx_platform.c \ $(srcdir)/../shared/bios_mmap.c \ @@ -30,6 +35,7 @@ liblinux_la_SOURCES = lnx_init.c lnx_video.c \ $(srcdir)/../shared/sigio.c \ $(ACPI_SRCS) \ $(APM_SRCS) \ + $(LOGIND_SRCS) \ $(PLATFORM_PCI_SUPPORT) AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES) diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c index 46438e655..85709c629 100644 --- a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c +++ b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c @@ -79,20 +79,15 @@ switch_to(int vt, const char *from) void xf86OpenConsole(void) { - int i, fd = -1, ret; + int i, fd = -1, ret, current_vt = -1; struct vt_mode VT; struct vt_stat vts; + struct stat st; MessageType from = X_PROBED; const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; if (serverGeneration == 1) { - - /* when KeepTty check if we're run with euid==0 */ - if (KeepTty && geteuid() != 0) - FatalError("xf86OpenConsole:" - " Server must be suid root for option \"KeepTTY\"\n"); - /* * setup the virtual terminal manager */ @@ -132,6 +127,22 @@ xf86OpenConsole(void) xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno); + /* Some of stdin / stdout / stderr maybe redirected to a file */ + for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) { + ret = fstat(i, &st); + if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) { + current_vt = minor(st.st_rdev); + break; + } + } + + if (!KeepTty && current_vt == xf86Info.vtno) { + xf86Msg(X_PROBED, + "controlling tty is VT number %d, auto-enabling KeepTty\n", + current_vt); + KeepTty = TRUE; + } + if (!KeepTty) { pid_t ppid = getppid(); pid_t ppgid; diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c index 1865b31b9..109a9a774 100644 --- a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c +++ b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c @@ -18,16 +18,38 @@ #include "xf86Bus.h" #include "hotplug.h" +#include "systemd-logind.h" static Bool get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) { drmSetVersion sv; char *buf; - int fd; + int major, minor, fd; int err = 0; + Bool paused, server_fd = FALSE; + + major = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MAJOR, 0); + minor = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MINOR, 0); + + fd = systemd_logind_take_fd(major, minor, path, &paused); + if (fd != -1) { + if (paused) { + LogMessage(X_ERROR, + "Error systemd-logind returned paused fd for drm node\n"); + systemd_logind_release_fd(major, minor); + return FALSE; + } + if (!config_odev_add_int_attribute(attribs, ODEV_ATTRIB_FD, fd)) { + systemd_logind_release_fd(major, minor); + return FALSE; + } + server_fd = TRUE; + } + + if (fd == -1) + fd = open(path, O_RDWR, O_CLOEXEC); - fd = open(path, O_RDWR, O_CLOEXEC); if (fd == -1) return FALSE; @@ -44,16 +66,20 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) /* for a delayed probe we've already added the device */ if (delayed_index == -1) { - xf86_add_platform_device(attribs); + xf86_add_platform_device(attribs, FALSE); delayed_index = xf86_num_platform_devices - 1; } + if (server_fd) + xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD; + buf = drmGetBusid(fd); xf86_add_platform_device_attrib(delayed_index, ODEV_ATTRIB_BUSID, buf); drmFreeBusid(buf); out: - close(fd); + if (!server_fd) + close(fd); return (err == 0); } @@ -118,17 +144,11 @@ xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs) void xf86PlatformDeviceProbe(struct OdevAttributes *attribs) { - struct OdevAttribute *attrib; int i; char *path = NULL; Bool ret; - xorg_list_for_each_entry(attrib, &attribs->list, member) { - if (attrib->attrib_id == ODEV_ATTRIB_PATH) { - path = attrib->attrib_name; - break; - } - } + path = config_odev_get_attribute(attribs, ODEV_ATTRIB_PATH); if (!path) goto out_free; @@ -148,8 +168,7 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs) if (!xf86VTOwner()) { /* if we don't currently own the VT then don't probe the device, just mark it as unowned for later use */ - attribs->unowned = TRUE; - xf86_add_platform_device(attribs); + xf86_add_platform_device(attribs, TRUE); return; } diff --git a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c new file mode 100644 index 000000000..abb8e44d9 --- /dev/null +++ b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c @@ -0,0 +1,532 @@ +/* + * Copyright © 2013 Red Hat Inc. + * + * 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. + * + * Author: Hans de Goede <hdegoede@redhat.com> + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <dbus/dbus.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +#include "os.h" +#include "dbus-core.h" +#include "xf86.h" +#include "xf86platformBus.h" +#include "xf86Xinput.h" + +#include "systemd-logind.h" + +#define DBUS_TIMEOUT 500 /* Wait max 0.5 seconds */ + +struct systemd_logind_info { + DBusConnection *conn; + char *session; + Bool active; + Bool vt_active; +}; + +static struct systemd_logind_info logind_info; + +int +systemd_logind_take_fd(int _major, int _minor, const char *path, + Bool *paused_ret) +{ + struct systemd_logind_info *info = &logind_info; + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + dbus_int32_t major = _major; + dbus_int32_t minor = _minor; + dbus_bool_t paused; + int fd = -1; + + if (!info->session || major == 0) + return -1; + + /* logind does not support mouse devs (with evdev we don't need them) */ + if (strstr(path, "mouse")) + return -1; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, + "org.freedesktop.login1.Session", "TakeDevice"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, + DBUS_TIMEOUT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: failed to take device %s: %s\n", + path, error.message); + goto cleanup; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_UNIX_FD, &fd, + DBUS_TYPE_BOOLEAN, &paused, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: TakeDevice %s: %s\n", + path, error.message); + goto cleanup; + } + + *paused_ret = paused; + + LogMessage(X_INFO, "systemd-logind: got fd for %s %u:%u fd %d paused %d\n", + path, major, minor, fd, paused); + +cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); + + return fd; +} + +void +systemd_logind_release_fd(int _major, int _minor) +{ + struct systemd_logind_info *info = &logind_info; + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + dbus_int32_t major = _major; + dbus_int32_t minor = _minor; + + if (!info->session || major == 0) + return; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, + "org.freedesktop.login1.Session", "ReleaseDevice"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, + DBUS_TIMEOUT, &error); + if (!reply) + LogMessage(X_ERROR, "systemd-logind: failed to release device: %s\n", + error.message); + +cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); +} + +int +systemd_logind_controls_session(void) +{ + return logind_info.session ? 1 : 0; +} + +void +systemd_logind_vtenter(void) +{ + struct systemd_logind_info *info = &logind_info; + InputInfoPtr pInfo; + int i; + + if (!info->session) + return; /* Not using systemd-logind */ + + if (!info->active) + return; /* Session not active */ + + if (info->vt_active) + return; /* Already did vtenter */ + + for (i = 0; i < xf86_num_platform_devices; i++) { + if (xf86_platform_devices[i].flags & XF86_PDEV_PAUSED) + break; + } + if (i != xf86_num_platform_devices) + return; /* Some drm nodes are still paused wait for resume */ + + xf86VTEnter(); + info->vt_active = TRUE; + + /* Activate any input devices which were resumed before the drm nodes */ + for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) + if ((pInfo->flags & XI86_SERVER_FD) && pInfo->fd != -1) + xf86EnableInputDeviceForVTSwitch(pInfo); + + /* Do delayed input probing, this must be done after the above enabling */ + xf86InputEnableVTProbe(); +} + +static InputInfoPtr +systemd_logind_find_info_ptr_by_devnum(int major, int minor) +{ + InputInfoPtr pInfo; + + for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) + if (pInfo->major == major && pInfo->minor == minor && + (pInfo->flags & XI86_SERVER_FD)) + return pInfo; + + return NULL; +} + +static void +systemd_logind_ack_pause(struct systemd_logind_info *info, + dbus_int32_t minor, dbus_int32_t major) +{ + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", info->session, + "org.freedesktop.login1.Session", "PauseDeviceComplete"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, + DBUS_TIMEOUT, &error); + if (!reply) + LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n", + error.message); + +cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static DBusHandlerResult +message_filter(DBusConnection * connection, DBusMessage * message, void *data) +{ + struct systemd_logind_info *info = data; + struct xf86_platform_device *pdev = NULL; + InputInfoPtr pInfo = NULL; + int ack = 0, pause = 0, fd = -1; + DBusError error; + dbus_int32_t major, minor; + char *pause_str; + + if (strcmp(dbus_message_get_path(message), info->session) != 0) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + dbus_error_init(&error); + + if (dbus_message_is_signal(message, "org.freedesktop.login1.Session", + "PauseDevice")) { + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_STRING, &pause_str, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: PauseDevice: %s\n", + error.message); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (strcmp(pause_str, "pause") == 0) { + pause = 1; + ack = 1; + } + else if (strcmp(pause_str, "force") == 0) { + pause = 1; + } + else if (strcmp(pause_str, "gone") == 0) { + /* Device removal is handled through udev */ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + else { + LogMessage(X_WARNING, "systemd-logind: unknown pause type: %s\n", + pause_str); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + } + else if (dbus_message_is_signal(message, "org.freedesktop.login1.Session", + "ResumeDevice")) { + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &major, + DBUS_TYPE_UINT32, &minor, + DBUS_TYPE_UNIX_FD, &fd, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: ResumeDevice: %s\n", + error.message); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + } else + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + LogMessage(X_INFO, "systemd-logind: got %s for %u:%u\n", + pause ? "pause" : "resume", major, minor); + + pdev = xf86_find_platform_device_by_devnum(major, minor); + if (!pdev) + pInfo = systemd_logind_find_info_ptr_by_devnum(major, minor); + if (!pdev && !pInfo) { + LogMessage(X_WARNING, "systemd-logind: could not find dev %u:%u\n", + major, minor); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (pause) { + /* Our VT_PROCESS usage guarantees we've already given up the vt */ + info->active = info->vt_active = FALSE; + /* Note the actual vtleave has already been handled by xf86Events.c */ + if (pdev) + pdev->flags |= XF86_PDEV_PAUSED; + else { + close(pInfo->fd); + pInfo->fd = -1; + pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", -1); + } + if (ack) + systemd_logind_ack_pause(info, major, minor); + } + else { + /* info->vt_active gets set by systemd_logind_vtenter() */ + info->active = TRUE; + + if (pdev) { + pdev->flags &= ~XF86_PDEV_PAUSED; + systemd_logind_vtenter(); + } + else { + pInfo->fd = fd; + pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd); + if (info->vt_active) + xf86EnableInputDeviceForVTSwitch(pInfo); + } + } + return DBUS_HANDLER_RESULT_HANDLED; +} + +static void +connect_hook(DBusConnection *connection, void *data) +{ + struct systemd_logind_info *info = data; + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + dbus_int32_t arg; + char *session = NULL; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", + "/org/freedesktop/login1", "org.freedesktop.login1.Manager", + "GetSessionByPID"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + arg = getpid(); + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &arg, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(connection, msg, + DBUS_TIMEOUT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: failed to get session: %s\n", + error.message); + goto cleanup; + } + dbus_message_unref(msg); + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &session, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: GetSessionByPID: %s\n", + error.message); + goto cleanup; + } + session = XNFstrdup(session); + + dbus_message_unref(reply); + reply = NULL; + + + msg = dbus_message_new_method_call("org.freedesktop.login1", + session, "org.freedesktop.login1.Session", "TakeControl"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + arg = FALSE; /* Don't forcibly take over over the session */ + if (!dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg, + DBUS_TYPE_INVALID)) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(connection, msg, + DBUS_TIMEOUT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: TakeControl failed: %s\n", + error.message); + goto cleanup; + } + + /* + * HdG: This is not useful with systemd <= 208 since the signal only + * contains invalidated property names there, rather than property, val + * pairs as it should. Instead we just use the first resume / pause now. + */ +#if 0 + snprintf(match, sizeof(match), + "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='%s'", + session); + dbus_bus_add_match(connection, match, &error); + if (dbus_error_is_set(&error)) { + LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n", + error.message); + goto cleanup; + } +#endif + + if (!dbus_connection_add_filter(connection, message_filter, info, NULL)) { + LogMessage(X_ERROR, "systemd-logind: could not add filter: %s\n", + error.message); + goto cleanup; + } + + LogMessage(X_INFO, "systemd-logind: took control of session %s\n", + session); + info->conn = connection; + info->session = session; + info->vt_active = info->active = TRUE; /* The server owns the vt during init */ + session = NULL; + +cleanup: + free(session); + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static void +systemd_logind_release_control(struct systemd_logind_info *info) +{ + DBusError error; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + + dbus_error_init(&error); + + msg = dbus_message_new_method_call("org.freedesktop.login1", + info->session, "org.freedesktop.login1.Session", "ReleaseControl"); + if (!msg) { + LogMessage(X_ERROR, "systemd-logind: out of memory\n"); + goto cleanup; + } + + reply = dbus_connection_send_with_reply_and_block(info->conn, msg, + DBUS_TIMEOUT, &error); + if (!reply) { + LogMessage(X_ERROR, "systemd-logind: ReleaseControl failed: %s\n", + error.message); + goto cleanup; + } + +cleanup: + if (msg) + dbus_message_unref(msg); + if (reply) + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static void +disconnect_hook(void *data) +{ + struct systemd_logind_info *info = data; + + free(info->session); + info->session = NULL; + info->conn = NULL; +} + +static struct dbus_core_hook core_hook = { + .connect = connect_hook, + .disconnect = disconnect_hook, + .data = &logind_info, +}; + +int +systemd_logind_init(void) +{ + return dbus_core_add_hook(&core_hook); +} + +void +systemd_logind_fini(void) +{ + if (logind_info.session) + systemd_logind_release_control(&logind_info); + + dbus_core_remove_hook(&core_hook); +} diff --git a/xorg-server/hw/xfree86/os-support/shared/posix_tty.c b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c index 4d08c1e85..6e2af001a 100644 --- a/xorg-server/hw/xfree86/os-support/shared/posix_tty.c +++ b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c @@ -124,7 +124,11 @@ xf86OpenSerial(XF86OptionPtr options) return -1; } - SYSCALL(fd = open(dev, O_RDWR | O_NONBLOCK)); + fd = xf86CheckIntOption(options, "fd", -1); + + if (fd == -1) + SYSCALL(fd = open(dev, O_RDWR | O_NONBLOCK)); + if (fd == -1) { xf86Msg(X_ERROR, "xf86OpenSerial: Cannot open device %s\n\t%s.\n", diff --git a/xorg-server/include/Makefile.am b/xorg-server/include/Makefile.am index fa6da00ec..6578038a5 100644 --- a/xorg-server/include/Makefile.am +++ b/xorg-server/include/Makefile.am @@ -72,4 +72,5 @@ EXTRA_DIST = \ dix-config-apple-verbatim.h \ dixfontstubs.h eventconvert.h eventstr.h inpututils.h \ protocol-versions.h \ + systemd-logind.h \ xsha1.h diff --git a/xorg-server/include/dix-config.h.in b/xorg-server/include/dix-config.h.in index 7c77956b1..06455a837 100644 --- a/xorg-server/include/dix-config.h.in +++ b/xorg-server/include/dix-config.h.in @@ -420,6 +420,9 @@ /* Support HAL for hotplug */ #undef CONFIG_HAL +/* Enable systemd-logind integration */ +#undef SYSTEMD_LOGIND 1 + /* Have a monotonic clock from clock_gettime() */ #undef MONOTONIC_CLOCK @@ -481,4 +484,7 @@ /* Build GLAMOR */ #undef GLAMOR +/* Build glamor's GBM-based EGL support */ +#undef GLAMOR_HAS_GBM + #endif /* _DIX_CONFIG_H_ */ diff --git a/xorg-server/include/hotplug.h b/xorg-server/include/hotplug.h index 29a22c4da..1d9364eee 100644 --- a/xorg-server/include/hotplug.h +++ b/xorg-server/include/hotplug.h @@ -32,15 +32,20 @@ extern _X_EXPORT void config_pre_init(void); extern _X_EXPORT void config_init(void); extern _X_EXPORT void config_fini(void); +enum { ODEV_ATTRIB_STRING, ODEV_ATTRIB_INT }; + struct OdevAttribute { struct xorg_list member; int attrib_id; - char *attrib_name; + union { + char *attrib_name; + int attrib_value; + }; + int attrib_type; }; struct OdevAttributes { struct xorg_list list; - Bool unowned; }; struct OdevAttributes * @@ -53,6 +58,17 @@ Bool config_odev_add_attribute(struct OdevAttributes *attribs, int attrib, const char *attrib_name); +char * +config_odev_get_attribute(struct OdevAttributes *attribs, int attrib_id); + +Bool +config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib, + int attrib_value); + +int +config_odev_get_int_attribute(struct OdevAttributes *attribs, int attrib, + int def); + void config_odev_free_attributes(struct OdevAttributes *attribs); @@ -62,6 +78,12 @@ config_odev_free_attributes(struct OdevAttributes *attribs); #define ODEV_ATTRIB_SYSPATH 2 /* DRI-style bus id */ #define ODEV_ATTRIB_BUSID 3 +/* Server managed FD */ +#define ODEV_ATTRIB_FD 4 +/* Major number of the device node pointed to by ODEV_ATTRIB_PATH */ +#define ODEV_ATTRIB_MAJOR 5 +/* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */ +#define ODEV_ATTRIB_MINOR 6 typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs); void config_odev_probe(config_odev_probe_proc_ptr probe_callback); @@ -72,4 +94,8 @@ void DeleteGPUDeviceRequest(struct OdevAttributes *attribs); #endif #define ServerIsNotSeat0() (SeatId && strcmp(SeatId, "seat0")) + +struct xf86_platform_device * +xf86_find_platform_device_by_devnum(int major, int minor); + #endif /* HOTPLUG_H */ diff --git a/xorg-server/include/systemd-logind.h b/xorg-server/include/systemd-logind.h new file mode 100644 index 000000000..8b0908186 --- /dev/null +++ b/xorg-server/include/systemd-logind.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2013 Red Hat, Inc. + * + * 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. + * + * Author: Hans de Goede <hdegoede@redhat.com> + */ + +#ifndef SYSTEMD_LOGIND_H +#define SYSTEMD_LOGIND_H + +#ifdef SYSTEMD_LOGIND +int systemd_logind_init(void); +void systemd_logind_fini(void); +int systemd_logind_take_fd(int major, int minor, const char *path, Bool *paus); +void systemd_logind_release_fd(int major, int minor); +int systemd_logind_controls_session(void); +void systemd_logind_vtenter(void); +#else +#define systemd_logind_init() +#define systemd_logind_fini() +#define systemd_logind_take_fd(major, minor, path) -1 +#define systemd_logind_release_fd(dev) +#define systemd_logind_controls_session() 0 +#define systemd_logind_vtenter() +#endif + +#endif |