diff options
author | marha <marha@users.sourceforge.net> | 2014-06-08 15:05:49 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-06-08 15:05:49 +0200 |
commit | 71cc8d9b7dc729934a29445cbd6d1f7a6d9ecbec (patch) | |
tree | ea689cdd51f395980ddc37dc33781635976f3a16 /mesalib | |
parent | aec798fb4dc72d616732d0fa711faffaa8cd7590 (diff) | |
parent | 2acb86c9b086bdb9a3897db0b93820652e07cb59 (diff) | |
download | vcxsrv-71cc8d9b7dc729934a29445cbd6d1f7a6d9ecbec.tar.gz vcxsrv-71cc8d9b7dc729934a29445cbd6d1f7a6d9ecbec.tar.bz2 vcxsrv-71cc8d9b7dc729934a29445cbd6d1f7a6d9ecbec.zip |
Merge remote-tracking branch 'origin/released'
Conflicts:
apps/xwininfo/xwininfo.c
xorg-server/hw/xwin/glx/indirect.c
Diffstat (limited to 'mesalib')
39 files changed, 956 insertions, 325 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac index bee85a131..a12f27ac2 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -552,7 +552,13 @@ dnl See if posix_memalign is available AC_CHECK_FUNC([posix_memalign], [DEFINES="$DEFINES -DHAVE_POSIX_MEMALIGN"]) dnl Check for pthreads -AX_PTHREAD +case "$host_os" in +mingw*) + ;; +*) + AX_PTHREAD + ;; +esac dnl AX_PTHREADS leaves PTHREAD_LIBS empty for gcc and sets PTHREAD_CFLAGS dnl to -pthread, which causes problems if we need -lpthread to appear in dnl pkgconfig files. @@ -870,14 +876,21 @@ fi case "$host_os" in linux*) - need_libudev=yes ;; + need_pci_id=yes ;; *) - need_libudev=no ;; + need_pci_id=no ;; esac PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED], have_libudev=yes, have_libudev=no) +AC_ARG_ENABLE([sysfs], + [AS_HELP_STRING([--enable-sysfs], + [enable /sys PCI identification @<:@default=disabled@:>@])], + [have_sysfs="$enableval"], + [have_sysfs=no] +) + if test "x$enable_dri" = xyes; then if test "$enable_static" = yes; then AC_MSG_ERROR([Cannot use static libraries for DRI drivers]) @@ -973,8 +986,15 @@ xyesno) ;; esac +have_pci_id=no if test "$have_libudev" = yes; then DEFINES="$DEFINES -DHAVE_LIBUDEV" + have_pci_id=yes +fi + +if test "$have_sysfs" = yes; then + DEFINES="$DEFINES -DHAVE_SYSFS" + have_pci_id=yes fi # This is outside the case (above) so that it is invoked even for non-GLX @@ -1076,8 +1096,8 @@ 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]) + if test "x$have_pci_id" != xyes; then + AC_MSG_ERROR([libudev-dev or sysfs required for building DRI]) fi case "$host_cpu" in @@ -1252,8 +1272,8 @@ if test "x$enable_gbm" = xauto; then esac fi if test "x$enable_gbm" = xyes; then - if test "x$need_libudev$have_libudev" = xyesno; then - AC_MSG_ERROR([gbm requires udev >= $LIBUDEV_REQUIRED]) + if test "x$need_pci_id$have_pci_id" = xyesno; then + AC_MSG_ERROR([gbm requires udev >= $LIBUDEV_REQUIRED or sysfs]) fi if test "x$enable_dri" = xyes; then @@ -1271,7 +1291,7 @@ if test "x$enable_gbm" = xyes; then fi fi AM_CONDITIONAL(HAVE_GBM, test "x$enable_gbm" = xyes) -if test "x$need_libudev" = xyes; then +if test "x$need_pci_id$have_libudev" = xyesyes; then GBM_PC_REQ_PRIV="libudev >= $LIBUDEV_REQUIRED" else GBM_PC_REQ_PRIV="" @@ -1560,9 +1580,9 @@ for plat in $egl_platforms; do ;; esac - case "$plat$need_libudev$have_libudev" in + case "$plat$need_pci_id$have_pci_id" in waylandyesno|drmyesno) - AC_MSG_ERROR([cannot build $plat platform without udev >= $LIBUDEV_REQUIRED]) ;; + AC_MSG_ERROR([cannot build $plat platform without udev >= $LIBUDEV_REQUIRED or sysfs]) ;; esac done @@ -1843,8 +1863,8 @@ gallium_require_llvm() { gallium_require_drm_loader() { if test "x$enable_gallium_loader" = xyes; then - if test "x$need_libudev$have_libudev" = xyesno; then - AC_MSG_ERROR([Gallium drm loader requires libudev >= $LIBUDEV_REQUIRED]) + if test "x$need_pci_id$have_pci_id" = xyesno; then + AC_MSG_ERROR([Gallium drm loader requires libudev >= $LIBUDEV_REQUIRED or sysfs]) fi if test "x$have_libdrm" != xyes; then AC_MSG_ERROR([Gallium drm loader requires libdrm >= $LIBDRM_REQUIRED]) diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt index c360f2cb7..d26c8124d 100644 --- a/mesalib/docs/GL3.txt +++ b/mesalib/docs/GL3.txt @@ -101,10 +101,10 @@ GL 4.0: GL_ARB_draw_buffers_blend DONE (i965, nv50, nvc0, r600, radeonsi, softpipe) GL_ARB_draw_indirect DONE (i965) GL_ARB_gpu_shader5 started - - 'precise' qualifier not started + - 'precise' qualifier DONE - Dynamically uniform sampler array indices not started - Dynamically uniform UBO array indices not started - - Implicit signed -> unsigned conversions not started + - Implicit signed -> unsigned conversions DONE - Fused multiply-add DONE - Packing/bitfield/conversion functions DONE - Enhanced textureGather DONE @@ -112,9 +112,9 @@ GL 4.0: - Geometry shader multiple streams not started - Enhanced per-sample shading DONE - Interpolation functions started - - New overload resolution rules not started + - New overload resolution rules DONE GL_ARB_gpu_shader_fp64 not started - GL_ARB_sample_shading DONE (i965, nv50, nvc0) + GL_ARB_sample_shading DONE (i965, nv50, nvc0, radeonsi) GL_ARB_shader_subroutine not started GL_ARB_tessellation_shader not started GL_ARB_texture_buffer_object_rgb32 DONE (i965, nvc0, r600, radeonsi, softpipe) diff --git a/mesalib/docs/index.html b/mesalib/docs/index.html index 28a70467d..2e78343de 100644 --- a/mesalib/docs/index.html +++ b/mesalib/docs/index.html @@ -16,6 +16,20 @@ <h1>News</h1> +<h2>June 6, 2014</h2> +<p> +<a href="relnotes/10.2.1.html">Mesa 10.2.1</a> is released. This release +only fixes a build error in the radeonsi driver that was introduced between +10.2-rc5 and the 10.2 final release. +</p> + +<h2>June 6, 2014</h2> +<p> +<a href="relnotes/10.2.html">Mesa 10.2</a> is released. This is a new +development release. See the release notes for more information about +the release. +</p> + <h2>May 20, 2014</h2> <p> <a href="relnotes/10.1.4.html">Mesa 10.1.4</a> is released. diff --git a/mesalib/docs/llvmpipe.html b/mesalib/docs/llvmpipe.html index 74f0c67d8..291527be8 100644 --- a/mesalib/docs/llvmpipe.html +++ b/mesalib/docs/llvmpipe.html @@ -43,11 +43,7 @@ It's the fastest software rasterizer for Mesa. </p> </li> <li> - <p>LLVM: version 2.9 recommended; 2.6 or later required.</p> - <p><b>NOTE</b>: LLVM 2.8 and earlier will not work on systems that support the - Intel AVX extensions (e.g. Sandybridge). LLVM's code generator will - fail when trying to emit AVX instructions. This was fixed in LLVM 2.9. - </p> + <p>LLVM: version 3.4 recommended; 3.1 or later required.</p> <p> For Linux, on a recent Debian based distribution do: </p> @@ -101,13 +97,15 @@ but the rest of these instructions assume that scons is used. For Windows the procedure is similar except the target: <pre> - scons build=debug libgl-gdi + scons platform=windows build=debug libgl-gdi </pre> <h1>Using</h1> -On Linux, building will create a drop-in alternative for libGL.so into +<h2>Linux</h2> + +<p>On Linux, building will create a drop-in alternative for libGL.so into</p> <pre> build/foo/gallium/targets/libgl-xlib/libGL.so @@ -117,15 +115,45 @@ or lib/gallium/libGL.so </pre> -To use it set the LD_LIBRARY_PATH environment variable accordingly. +<p>To use it set the LD_LIBRARY_PATH environment variable accordingly.</p> + +<p>For performance evaluation pass build=release to scons, and use the corresponding +lib directory without the "-debug" suffix.</p> + -For performance evaluation pass debug=no to scons, and use the corresponding -lib directory without the "-debug" suffix. +<h2>Windows</h2> -On Windows, building will create a drop-in alternative for opengl32.dll. To use -it put it in the same directory as the application. It can also be used by +<p> +On Windows, building will create +<code>build/windows-x86-debug/gallium/targets/libgl-gdi/opengl32.dll</code> +which is a drop-in alternative for system's <code>opengl32.dll</code>. To use +it put it in the same directory as your application. It can also be used by replacing the native ICD driver, but it's quite an advanced usage, so if you need to ask, don't even try it. +</p> + +<p> +There is however an easy way to replace the OpenGL software renderer that comes +with Microsoft Windows 7 (or later) with llvmpipe (that is, on systems without +any OpenGL drivers): +</p> + +<ul> + <li><p>copy build/windows-x86-debug/gallium/targets/libgl-gdi/opengl32.dll to C:\Windows\SysWOW64\mesadrv.dll</p></li> + <li><p>load this registry settings:</p> + <pre>REGEDIT4 + +; http://technet.microsoft.com/en-us/library/cc749368.aspx +; http://www.msfn.org/board/topic/143241-portable-windows-7-build-from-winpe-30/page-5#entry942596 +[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL] +"DLL"="mesadrv.dll" +"DriverVersion"=dword:00000001 +"Flags"=dword:00000001 +"Version"=dword:00000002 +</pre> + </li> + <li>Ditto for 64 bits drivers if you need them.</li> +</ul> <h1>Profiling</h1> diff --git a/mesalib/docs/relnotes.html b/mesalib/docs/relnotes.html index 7437e9b5b..60d007326 100644 --- a/mesalib/docs/relnotes.html +++ b/mesalib/docs/relnotes.html @@ -21,6 +21,8 @@ The release notes summarize what's new or changed in each Mesa release. </p> <ul> +<li><a href="relnotes/10.2.1.html">10.2.1 release notes</a> +<li><a href="relnotes/10.2.html">10.2 release notes</a> <li><a href="relnotes/10.1.4.html">10.1.4 release notes</a> <li><a href="relnotes/10.1.3.html">10.1.3 release notes</a> <li><a href="relnotes/10.1.2.html">10.1.2 release notes</a> diff --git a/mesalib/docs/relnotes/10.2.1.html b/mesalib/docs/relnotes/10.2.1.html new file mode 100644 index 000000000..81c2acc02 --- /dev/null +++ b/mesalib/docs/relnotes/10.2.1.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html lang="en"> +<head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Mesa Release Notes</title> + <link rel="stylesheet" type="text/css" href="../mesa.css"> +</head> +<body> + +<div class="header"> + <h1>The Mesa 3D Graphics Library</h1> +</div> + +<iframe src="../contents.html"></iframe> +<div class="content"> + +<h1>Mesa 10.2.1 Release Notes / June 6, 2014</h1> + +<p> +Mesa 10.2.1 is a bug fix release which fixes bugs found since the 10.1 release. +</p> +<p> +Mesa 10.2.1 implements the OpenGL 3.3 API, but the version reported by +glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) / +glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used. +Some drivers don't support all the features required in OpenGL 3.3. OpenGL +3.3 is <strong>only</strong> available if requested at context creation +because compatibility contexts are not supported. +</p> + + +<h2>MD5 checksums</h2> +<pre> +96f892dae2d0bb14ac9c2113f586c909 MesaLib-10.2.1.tar.gz +093f9b5d077e5f6061dcd7b01b7aa51a MesaLib-10.2.1.tar.bz2 +6ab76c1608e5deed1eb8b54c62d7a48a MesaLib-10.2.1.zip +</pre> + + +<h2>New features</h2> +<p>None</p> + +<h2>Bug fixes</h2> + +<p> +Mesa 10.2 had a build problem in the radeonsi driver due to an error resolving +conflicts in a patch cherry-pick from master. The build error is fixed. +</p> + +<h2>Changes</h2> + +<p>Ian Romanick (3):</p> +<ul> + <li>docs: Add MD5 checksum, etc. for 10.1 release</li> + <li>radeonsi: Fix build error introduced in 5ab9a9c</li> + <li>Bump version to 10.2.1</li> +</ul> + +</div> +</body> +</html> diff --git a/mesalib/docs/relnotes/10.2.html b/mesalib/docs/relnotes/10.2.html index af44ca107..f17bfcc28 100644 --- a/mesalib/docs/relnotes/10.2.html +++ b/mesalib/docs/relnotes/10.2.html @@ -14,7 +14,7 @@ <iframe src="../contents.html"></iframe> <div class="content"> -<h1>Mesa 10.2 Release Notes / TBD</h1> +<h1>Mesa 10.2 Release Notes / June 6, 2014</h1> <p> Mesa 10.2 is a new development release. @@ -33,7 +33,9 @@ because compatibility contexts are not supported. <h2>MD5 checksums</h2> <pre> -TBD. +c87bfb6dd5cbcf1fdef42e5ccd972581 MesaLib-10.2.0.tar.gz +7aaba90bd7169a94ae2fe83febdec963 MesaLib-10.2.0.tar.bz2 +58b203aca15dadc25ab4d1126db1052b MesaLib-10.2.0.zip </pre> diff --git a/mesalib/docs/relnotes/10.3.html b/mesalib/docs/relnotes/10.3.html index 6bb9e7989..0c8114bf2 100644 --- a/mesalib/docs/relnotes/10.3.html +++ b/mesalib/docs/relnotes/10.3.html @@ -44,6 +44,7 @@ Note: some of the new features are only available with certain drivers. </p> <ul> +<li>GL_ARB_sample_shading on radeonsi</li> <li>GL_ARB_stencil_texturing on nv50, nvc0, r600, and radeonsi</li> <li>GL_ARB_texture_cube_map_array on radeonsi</li> </ul> diff --git a/mesalib/scons/crossmingw.py b/mesalib/scons/crossmingw.py index 1287e0ec8..34129450a 100644 --- a/mesalib/scons/crossmingw.py +++ b/mesalib/scons/crossmingw.py @@ -41,26 +41,13 @@ import SCons.Builder import SCons.Tool import SCons.Util -# This is what we search for to find mingw: +# These are the mingw toolchain prefixes we search for: +# (We only search for the mingw-w64 toolchain, and not the mingw.org one.) prefixes32 = SCons.Util.Split(""" - mingw32- - mingw32msvc- - i386-mingw32- - i486-mingw32- - i586-mingw32- - i686-mingw32- - i386-mingw32msvc- - i486-mingw32msvc- - i586-mingw32msvc- - i686-mingw32msvc- - i686-pc-mingw32- i686-w64-mingw32- """) prefixes64 = SCons.Util.Split(""" x86_64-w64-mingw32- - amd64-mingw32- - amd64-mingw32msvc- - amd64-pc-mingw32- """) def find(env): diff --git a/mesalib/src/gallium/auxiliary/util/u_debug.c b/mesalib/src/gallium/auxiliary/util/u_debug.c index dc840e856..d79f31ea9 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug.c @@ -46,6 +46,12 @@ #include <limits.h> /* CHAR_BIT */ #include <ctype.h> /* isalnum */ +#ifdef _WIN32 +#include <windows.h> +#include <stdlib.h> +#endif + + void _debug_vprintf(const char *format, va_list ap) { static char buf[4096] = {'\0'}; @@ -64,6 +70,32 @@ void _debug_vprintf(const char *format, va_list ap) } +void +debug_disable_error_message_boxes(void) +{ +#ifdef _WIN32 + /* When Windows' error message boxes are disabled for this process (as is + * typically the case when running tests in an automated fashion) we disable + * CRT message boxes too. + */ + UINT uMode = SetErrorMode(0); + SetErrorMode(uMode); + if (uMode & SEM_FAILCRITICALERRORS) { + /* Disable assertion failure message box. + * http://msdn.microsoft.com/en-us/library/sas1dkb2.aspx + */ + _set_error_mode(_OUT_TO_STDERR); +#ifdef _MSC_VER + /* Disable abort message box. + * http://msdn.microsoft.com/en-us/library/e631wekh.aspx + */ + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif + } +#endif /* _WIN32 */ +} + + #ifdef DEBUG void debug_print_blob( const char *name, const void *blob, diff --git a/mesalib/src/gallium/auxiliary/util/u_debug.h b/mesalib/src/gallium/auxiliary/util/u_debug.h index 9c414211b..badd5e296 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug.h +++ b/mesalib/src/gallium/auxiliary/util/u_debug.h @@ -139,6 +139,15 @@ void debug_print_format(const char *msg, unsigned fmt ); /** + * Disable interactive error message boxes. + * + * Should be called as soon as possible for effectiveness. + */ +void +debug_disable_error_message_boxes(void); + + +/** * Hard-coded breakpoint. */ #ifdef DEBUG diff --git a/mesalib/src/gallium/auxiliary/util/u_math.h b/mesalib/src/gallium/auxiliary/util/u_math.h index 2ade64af4..b9ed197d7 100644 --- a/mesalib/src/gallium/auxiliary/util/u_math.h +++ b/mesalib/src/gallium/auxiliary/util/u_math.h @@ -579,7 +579,7 @@ static INLINE unsigned util_last_bit(unsigned u) */ static INLINE unsigned util_last_bit_signed(int i) { -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) && !defined(__INTEL_COMPILER) return 31 - __builtin_clrsb(i); #else if (i >= 0) diff --git a/mesalib/src/gallium/auxiliary/util/u_video.h b/mesalib/src/gallium/auxiliary/util/u_video.h index da65a5861..d1ca7362b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_video.h +++ b/mesalib/src/gallium/auxiliary/util/u_video.h @@ -60,7 +60,11 @@ u_reduce_video_profile(enum pipe_video_profile profile) case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED: case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444: return PIPE_VIDEO_FORMAT_MPEG4_AVC; default: diff --git a/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am index fd0e837d1..00261fd0d 100644 --- a/mesalib/src/glsl/Makefile.am +++ b/mesalib/src/glsl/Makefile.am @@ -114,6 +114,7 @@ libglcpp_la_SOURCES = \ glcpp_glcpp_SOURCES = \ glcpp/glcpp.c \ + tests/common.c \ $(top_srcdir)/src/mesa/program/prog_hash_table.c glcpp_glcpp_LDADD = \ libglcpp.la \ diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript index fe9d50732..dc354775a 100644 --- a/mesalib/src/glsl/SConscript +++ b/mesalib/src/glsl/SConscript @@ -106,6 +106,6 @@ env.Alias('glsl_compiler', glsl_compiler) glcpp = env.Program( target = 'glcpp/glcpp', - source = ['glcpp/glcpp.c'] + mesa_objs, + source = ['glcpp/glcpp.c', 'tests/common.c'] + mesa_objs, ) env.Alias('glcpp', glcpp) diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h index a59ebcb9f..fc80e780e 100644 --- a/mesalib/src/glsl/ast.h +++ b/mesalib/src/glsl/ast.h @@ -428,6 +428,7 @@ struct ast_type_qualifier { union { struct { unsigned invariant:1; + unsigned precise:1; unsigned constant:1; unsigned attribute:1; unsigned varying:1; @@ -749,13 +750,11 @@ public: exec_list declarations; /** - * Special flag for vertex shader "invariant" declarations. - * - * Vertex shaders can contain "invariant" variable redeclarations that do - * not include a type. For example, "invariant gl_Position;". This flag - * is used to note these cases when no type is specified. + * Flags for redeclarations. In these cases, no type is specified, to + * `type` is allowed to be NULL. In all other cases, this would be an error. */ - int invariant; + int invariant; /** < `invariant` redeclaration */ + int precise; /** < `precise` redeclaration */ }; diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 4b8447067..8e91a1e67 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -701,7 +701,7 @@ process_vec_mat_constructor(exec_list *instructions, glsl_type::get_instance(GLSL_TYPE_FLOAT, ir->type->vector_elements, ir->type->matrix_columns); - if (result->type->can_implicitly_convert_to(desired_type)) { + if (result->type->can_implicitly_convert_to(desired_type, state)) { /* Even though convert_component() implements the constructor * conversion rules (not the implicit conversion rules), its safe * to use it here because we already checked that the implicit @@ -830,7 +830,7 @@ process_array_constructor(exec_list *instructions, glsl_type::get_instance(GLSL_TYPE_FLOAT, ir->type->vector_elements, ir->type->matrix_columns); - if (result->type->can_implicitly_convert_to(desired_type)) { + if (result->type->can_implicitly_convert_to(desired_type, state)) { /* Even though convert_component() implements the constructor * conversion rules (not the implicit conversion rules), its safe * to use it here because we already checked that the implicit @@ -1560,7 +1560,7 @@ ast_function_expression::hir(exec_list *instructions, foreach_list (n, &this->expressions) { ast_node *ast = exec_node_data(ast_node, n, link); - ir_rvalue *result = ast->hir(instructions, state)->as_rvalue(); + ir_rvalue *result = ast->hir(instructions, state); /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: * diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index f230a70a3..d1c77f1ec 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -164,6 +164,31 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) } +static ir_expression_operation +get_conversion_operation(const glsl_type *to, const glsl_type *from, + struct _mesa_glsl_parse_state *state) +{ + switch (to->base_type) { + case GLSL_TYPE_FLOAT: + switch (from->base_type) { + case GLSL_TYPE_INT: return ir_unop_i2f; + case GLSL_TYPE_UINT: return ir_unop_u2f; + default: return (ir_expression_operation)0; + } + + case GLSL_TYPE_UINT: + if (!state->is_version(400, 0) && !state->ARB_gpu_shader5_enable) + return (ir_expression_operation)0; + switch (from->base_type) { + case GLSL_TYPE_INT: return ir_unop_i2u; + default: return (ir_expression_operation)0; + } + + default: return (ir_expression_operation)0; + } +} + + /** * If a conversion is available, convert one operand to a different type * @@ -185,9 +210,7 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, if (to->base_type == from->type->base_type) return true; - /* This conversion was added in GLSL 1.20. If the compilation mode is - * GLSL 1.10, the conversion is skipped. - */ + /* Prior to GLSL 1.20, there are no implicit conversions */ if (!state->is_version(120, 0)) return false; @@ -195,36 +218,25 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, * * "There are no implicit array or structure conversions. For * example, an array of int cannot be implicitly converted to an - * array of float. There are no implicit conversions between - * signed and unsigned integers." - */ - /* FINISHME: The above comment is partially a lie. There is int/uint - * FINISHME: conversion for immediate constants. + * array of float. */ - if (!to->is_float() || !from->type->is_numeric()) + if (!to->is_numeric() || !from->type->is_numeric()) return false; - /* Convert to a floating point type with the same number of components - * as the original type - i.e. int to float, not int to vec4. + /* We don't actually want the specific type `to`, we want a type + * with the same base type as `to`, but the same vector width as + * `from`. */ - to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements, - from->type->matrix_columns); + to = glsl_type::get_instance(to->base_type, from->type->vector_elements, + from->type->matrix_columns); - switch (from->type->base_type) { - case GLSL_TYPE_INT: - from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL); - break; - case GLSL_TYPE_UINT: - from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL); - break; - case GLSL_TYPE_BOOL: - from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL); - break; - default: - assert(0); + ir_expression_operation op = get_conversion_operation(to, from->type, state); + if (op) { + from = new(ctx) ir_expression(op, to, from, NULL); + return true; + } else { + return false; } - - return true; } @@ -2393,6 +2405,17 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } } + if (qual->flags.q.precise) { + if (var->data.used) { + _mesa_glsl_error(loc, state, + "variable `%s' may not be redeclared " + "`precise' after being used", + var->name); + } else { + var->data.precise = 1; + } + } + if (qual->flags.q.constant || qual->flags.q.attribute || qual->flags.q.uniform || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) @@ -3163,8 +3186,45 @@ ast_declarator_list::hir(exec_list *instructions, return NULL; } + if (this->precise) { + assert(this->type == NULL); + + foreach_list_typed (ast_declaration, decl, link, &this->declarations) { + assert(decl->array_specifier == NULL); + assert(decl->initializer == NULL); + + ir_variable *const earlier = + state->symbols->get_variable(decl->identifier); + if (earlier == NULL) { + _mesa_glsl_error(& loc, state, + "undeclared variable `%s' cannot be marked " + "precise", decl->identifier); + } else if (state->current_function != NULL && + !state->symbols->name_declared_this_scope(decl->identifier)) { + /* Note: we have to check if we're in a function, since + * builtins are treated as having come from another scope. + */ + _mesa_glsl_error(& loc, state, + "variable `%s' from an outer scope may not be " + "redeclared `precise' in this scope", + earlier->name); + } else if (earlier->data.used) { + _mesa_glsl_error(& loc, state, + "variable `%s' may not be redeclared " + "`precise' after being used", + earlier->name); + } else { + earlier->data.precise = true; + } + } + + /* Precise redeclarations do not have r-values either. */ + return NULL; + } + assert(this->type != NULL); assert(!this->invariant); + assert(!this->precise); /* The type specifier may contain a structure definition. Process that * before any of the variable declarations. diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll index 760235127..6c3f9b692 100644 --- a/mesalib/src/glsl/glsl_lexer.ll +++ b/mesalib/src/glsl/glsl_lexer.ll @@ -338,6 +338,9 @@ samplerExternalOES { return IDENTIFIER; } + /* keywords available with ARB_gpu_shader5 */ +precise KEYWORD_WITH_ALT(400, 0, 400, 0, yyextra->ARB_gpu_shader5_enable, PRECISE); + /* keywords available with ARB_shader_image_load_store */ image1D KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE1D); image2D KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE2D); diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index b71b240de..b69802ddb 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -129,7 +129,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK %token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT %token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 -%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING +%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING SAMPLE %token NOPERSPECTIVE FLAT SMOOTH %token MAT2X2 MAT2X3 MAT2X4 %token MAT3X2 MAT3X3 MAT3X4 @@ -167,7 +167,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN %token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN %token SUB_ASSIGN -%token INVARIANT +%token INVARIANT PRECISE %token LOWP MEDIUMP HIGHP SUPERP PRECISION %token VERSION_TOK EXTENSION LINE COLON EOL INTERFACE OUTPUT @@ -184,7 +184,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 %token SAMPLER3DRECT %token SIZEOF CAST NAMESPACE USING -%token RESOURCE PATCH SAMPLE +%token RESOURCE PATCH %token SUBROUTINE %token ERROR_TOK @@ -932,14 +932,22 @@ parameter_qualifier: $$ = $2; $$.flags.q.constant = 1; } + | PRECISE parameter_qualifier + { + if ($2.flags.q.precise) + _mesa_glsl_error(&@1, state, "duplicate precise qualifier"); + + $$ = $2; + $$.flags.q.precise = 1; + } | parameter_direction_qualifier parameter_qualifier { if (($1.flags.q.in || $1.flags.q.out) && ($2.flags.q.in || $2.flags.q.out)) _mesa_glsl_error(&@1, state, "duplicate in/out/inout qualifier"); if (!state->ARB_shading_language_420pack_enable && $2.flags.q.constant) - _mesa_glsl_error(&@1, state, "const must be specified before " - "in/out/inout"); + _mesa_glsl_error(&@1, state, "in/out/inout must come after const " + "or precise"); $$ = $1; $$.merge_qualifier(&@1, state, $2); @@ -1072,7 +1080,7 @@ single_declaration: $$->set_location_range(@1, @2); $$->declarations.push_tail(&decl->link); } - | INVARIANT variable_identifier // Vertex only. + | INVARIANT variable_identifier { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, NULL); @@ -1084,6 +1092,18 @@ single_declaration: $$->declarations.push_tail(&decl->link); } + | PRECISE variable_identifier + { + 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_range(@1, @2); + $$->precise = true; + + $$->declarations.push_tail(&decl->link); + } ; fully_specified_type: @@ -1499,6 +1519,11 @@ type_qualifier: memset(& $$, 0, sizeof($$)); $$.flags.q.invariant = 1; } + | PRECISE + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.precise = 1; + } | auxiliary_storage_qualifier | storage_qualifier | interpolation_qualifier @@ -1519,8 +1544,16 @@ type_qualifier: * Each qualifier's rule ensures that the accumulated qualifiers on the right * side don't contain any that must appear on the left hand side. * For example, when processing a storage qualifier, we check that there are - * no auxiliary, interpolation, layout, or invariant qualifiers to the right. + * no auxiliary, interpolation, layout, invariant, or precise qualifiers to the right. */ + | PRECISE type_qualifier + { + if ($2.flags.q.precise) + _mesa_glsl_error(&@1, state, "duplicate \"precise\" qualifier"); + + $$ = $2; + $$.flags.q.precise = 1; + } | INVARIANT type_qualifier { if ($2.flags.q.invariant) @@ -1531,6 +1564,10 @@ type_qualifier: "\"invariant\" cannot be used with layout(...)"); } + if (!state->ARB_shading_language_420pack_enable && $2.flags.q.precise) + _mesa_glsl_error(&@1, state, + "\"invariant\" must come after \"precise\""); + $$ = $2; $$.flags.q.invariant = 1; } @@ -1554,9 +1591,10 @@ type_qualifier: "with layout(...)"); } - if (!state->ARB_shading_language_420pack_enable && $2.flags.q.invariant) { + if (!state->ARB_shading_language_420pack_enable && + ($2.flags.q.precise || $2.flags.q.invariant)) { _mesa_glsl_error(&@1, state, "interpolation qualifiers must come " - "after \"invariant\""); + "after \"precise\" or \"invariant\""); } $$ = $1; @@ -1577,6 +1615,10 @@ type_qualifier: _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " "the \"invariant\" qualifier"); + if ($2.flags.q.precise) + _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " + "the \"precise\" qualifier"); + if ($2.has_interpolation()) { _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " "interpolation qualifiers"); @@ -1593,7 +1635,8 @@ type_qualifier: } if (!state->ARB_shading_language_420pack_enable && - ($2.flags.q.invariant || $2.has_interpolation() || $2.has_layout())) { + ($2.flags.q.precise || $2.flags.q.invariant || + $2.has_interpolation() || $2.has_layout())) { _mesa_glsl_error(&@1, state, "auxiliary storage qualifiers must come " "just before storage qualifiers"); } @@ -1610,10 +1653,10 @@ type_qualifier: _mesa_glsl_error(&@1, state, "duplicate storage qualifier"); if (!state->ARB_shading_language_420pack_enable && - ($2.flags.q.invariant || $2.has_interpolation() || $2.has_layout() || - $2.has_auxiliary_storage())) { + ($2.flags.q.precise || $2.flags.q.invariant || $2.has_interpolation() || + $2.has_layout() || $2.has_auxiliary_storage())) { _mesa_glsl_error(&@1, state, "storage qualifiers must come after " - "invariant, interpolation, layout and auxiliary " + "precise, invariant, interpolation, layout and auxiliary " "storage qualifiers"); } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index d3339e779..f3c5bd049 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -1098,8 +1098,10 @@ ast_declarator_list::print(void) const if (type) type->print(); - else + else if (invariant) printf("invariant "); + else + printf("precise "); foreach_list_const (ptr, & this->declarations) { if (ptr != this->declarations.get_head()) @@ -1117,6 +1119,7 @@ ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) { this->type = type; this->invariant = false; + this->precise = false; } void diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 849a79af4..e77146cdf 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -678,7 +678,8 @@ glsl_type::component_slots() const } bool -glsl_type::can_implicitly_convert_to(const glsl_type *desired) const +glsl_type::can_implicitly_convert_to(const glsl_type *desired, + _mesa_glsl_parse_state *state) const { if (this == desired) return true; @@ -687,10 +688,23 @@ glsl_type::can_implicitly_convert_to(const glsl_type *desired) const if (this->matrix_columns > 1 || desired->matrix_columns > 1) return false; + /* Vector size must match. */ + if (this->vector_elements != desired->vector_elements) + return false; + /* int and uint can be converted to float. */ - return desired->is_float() - && this->is_integer() - && this->vector_elements == desired->vector_elements; + if (desired->is_float() && this->is_integer()) + return true; + + /* With GLSL 4.0 / ARB_gpu_shader5, int can be converted to uint. + * Note that state may be NULL here, when resolving function calls in the + * linker. By this time, all the state-dependent checks have already + * happened though, so allow anything that's allowed in any shader version. */ + if ((!state || state->is_version(400, 0) || state->ARB_gpu_shader5_enable) && + desired->base_type == GLSL_TYPE_UINT && this->base_type == GLSL_TYPE_INT) + return true; + + return false; } unsigned diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index dca5492ac..35a4e6acc 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -314,7 +314,8 @@ struct glsl_type { * integers. * \endverbatim */ - bool can_implicitly_convert_to(const glsl_type *desired) const; + bool can_implicitly_convert_to(const glsl_type *desired, + _mesa_glsl_parse_state *state) const; /** * Query whether or not a type is a scalar (non-vector and non-matrix). diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index dec49bd64..2f4a0bec8 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -26,7 +26,8 @@ #include "ir_visitor.h" #include "glsl_types.h" -ir_rvalue::ir_rvalue() +ir_rvalue::ir_rvalue(enum ir_node_type t) + : ir_instruction(t) { this->type = glsl_type::error_type; } @@ -153,8 +154,8 @@ ir_assignment::whole_variable_written() ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition, unsigned write_mask) + : ir_instruction(ir_type_assignment) { - this->ir_type = ir_type_assignment; this->condition = condition; this->rhs = rhs; this->lhs = lhs; @@ -173,8 +174,8 @@ ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition) + : ir_instruction(ir_type_assignment) { - this->ir_type = ir_type_assignment; this->condition = condition; this->rhs = rhs; @@ -198,8 +199,8 @@ ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_expression::ir_expression(int op, const struct glsl_type *type, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2, ir_rvalue *op3) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; this->type = type; this->operation = ir_expression_operation(op); this->operands[0] = op0; @@ -215,9 +216,8 @@ ir_expression::ir_expression(int op, const struct glsl_type *type, } ir_expression::ir_expression(int op, ir_rvalue *op0) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; - this->operation = ir_expression_operation(op); this->operands[0] = op0; this->operands[1] = NULL; @@ -324,9 +324,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) } ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; - this->operation = ir_expression_operation(op); this->operands[0] = op0; this->operands[1] = op1; @@ -420,9 +419,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; - this->operation = ir_expression_operation(op); this->operands[0] = op0; this->operands[1] = op1; @@ -610,25 +608,25 @@ ir_expression::get_operator(const char *str) } ir_constant::ir_constant() + : ir_rvalue(ir_type_constant) { - this->ir_type = ir_type_constant; } ir_constant::ir_constant(const struct glsl_type *type, const ir_constant_data *data) + : ir_rvalue(ir_type_constant) { assert((type->base_type >= GLSL_TYPE_UINT) && (type->base_type <= GLSL_TYPE_BOOL)); - this->ir_type = ir_type_constant; this->type = type; memcpy(& this->value, data, sizeof(this->value)); } ir_constant::ir_constant(float f, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.f[i] = f; @@ -639,9 +637,9 @@ ir_constant::ir_constant(float f, unsigned vector_elements) } ir_constant::ir_constant(unsigned int u, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_UINT, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.u[i] = u; @@ -652,9 +650,9 @@ ir_constant::ir_constant(unsigned int u, unsigned vector_elements) } ir_constant::ir_constant(int integer, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_INT, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.i[i] = integer; @@ -665,9 +663,9 @@ ir_constant::ir_constant(int integer, unsigned vector_elements) } ir_constant::ir_constant(bool b, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.b[i] = b; @@ -678,8 +676,8 @@ ir_constant::ir_constant(bool b, unsigned vector_elements) } ir_constant::ir_constant(const ir_constant *c, unsigned i) + : ir_rvalue(ir_type_constant) { - this->ir_type = ir_type_constant; this->type = c->type->get_base_type(); switch (this->type->base_type) { @@ -692,8 +690,8 @@ ir_constant::ir_constant(const ir_constant *c, unsigned i) } ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) + : ir_rvalue(ir_type_constant) { - this->ir_type = ir_type_constant; this->type = type; assert(type->is_scalar() || type->is_vector() || type->is_matrix() @@ -1233,16 +1231,16 @@ ir_constant::is_uint16_constant() const } ir_loop::ir_loop() + : ir_instruction(ir_type_loop) { - this->ir_type = ir_type_loop; } ir_dereference_variable::ir_dereference_variable(ir_variable *var) + : ir_dereference(ir_type_dereference_variable) { assert(var != NULL); - this->ir_type = ir_type_dereference_variable; this->var = var; this->type = var->type; } @@ -1250,8 +1248,8 @@ ir_dereference_variable::ir_dereference_variable(ir_variable *var) ir_dereference_array::ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index) + : ir_dereference(ir_type_dereference_array) { - this->ir_type = ir_type_dereference_array; this->array_index = array_index; this->set_array(value); } @@ -1259,10 +1257,10 @@ ir_dereference_array::ir_dereference_array(ir_rvalue *value, ir_dereference_array::ir_dereference_array(ir_variable *var, ir_rvalue *array_index) + : ir_dereference(ir_type_dereference_array) { void *ctx = ralloc_parent(var); - this->ir_type = ir_type_dereference_array; this->array_index = array_index; this->set_array(new(ctx) ir_dereference_variable(var)); } @@ -1289,10 +1287,10 @@ ir_dereference_array::set_array(ir_rvalue *value) ir_dereference_record::ir_dereference_record(ir_rvalue *value, const char *field) + : ir_dereference(ir_type_dereference_record) { assert(value != NULL); - this->ir_type = ir_type_dereference_record; this->record = value; this->field = ralloc_strdup(this, field); this->type = this->record->type->field_type(field); @@ -1301,10 +1299,10 @@ ir_dereference_record::ir_dereference_record(ir_rvalue *value, ir_dereference_record::ir_dereference_record(ir_variable *var, const char *field) + : ir_dereference(ir_type_dereference_record) { void *ctx = ralloc_parent(var); - this->ir_type = ir_type_dereference_record; this->record = new(ctx) ir_dereference_variable(var); this->field = ralloc_strdup(this, field); this->type = this->record->type->field_type(field); @@ -1421,24 +1419,22 @@ ir_swizzle::init_mask(const unsigned *comp, unsigned count) ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z, unsigned w, unsigned count) - : val(val) + : ir_rvalue(ir_type_swizzle), val(val) { const unsigned components[4] = { x, y, z, w }; - this->ir_type = ir_type_swizzle; this->init_mask(components, count); } ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp, unsigned count) - : val(val) + : ir_rvalue(ir_type_swizzle), val(val) { - this->ir_type = ir_type_swizzle; this->init_mask(comp, count); } ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) + : ir_rvalue(ir_type_swizzle) { - this->ir_type = ir_type_swizzle; this->val = val; this->mask = mask; this->type = glsl_type::get_instance(val->type->base_type, @@ -1537,9 +1533,8 @@ ir_swizzle::variable_referenced() const ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) - : max_ifc_array_access(NULL) + : ir_instruction(ir_type_variable), max_ifc_array_access(NULL) { - this->ir_type = ir_type_variable; this->type = type; this->name = ralloc_strdup(this, name); this->data.explicit_location = false; @@ -1613,10 +1608,10 @@ ir_variable::determine_interpolation_mode(bool flat_shade) ir_function_signature::ir_function_signature(const glsl_type *return_type, builtin_available_predicate b) - : return_type(return_type), is_defined(false), is_intrinsic(false), + : ir_instruction(ir_type_function_signature), + return_type(return_type), is_defined(false), is_intrinsic(false), builtin_avail(b), _function(NULL) { - this->ir_type = ir_type_function_signature; this->origin = NULL; } @@ -1699,8 +1694,8 @@ ir_function_signature::replace_parameters(exec_list *new_params) ir_function::ir_function(const char *name) + : ir_instruction(ir_type_function) { - this->ir_type = ir_type_function; this->name = ralloc_strdup(this, name); } @@ -1720,7 +1715,7 @@ ir_function::has_user_signature() ir_rvalue * ir_rvalue::error_value(void *mem_ctx) { - ir_rvalue *v = new(mem_ctx) ir_rvalue; + ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_unset); v->type = glsl_type::error_type; return v; diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 80609829e..b4e52d3d0 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -59,31 +59,27 @@ * types, this allows writing very straightforward, readable code. */ enum ir_node_type { - /** - * Zero is unused so that the IR validator can detect cases where - * \c ir_instruction::ir_type has not been initialized. - */ - ir_type_unset, - ir_type_variable, - ir_type_assignment, - ir_type_call, - ir_type_constant, ir_type_dereference_array, ir_type_dereference_record, ir_type_dereference_variable, - ir_type_discard, + ir_type_constant, ir_type_expression, + ir_type_swizzle, + ir_type_texture, + ir_type_variable, + ir_type_assignment, + ir_type_call, ir_type_function, ir_type_function_signature, ir_type_if, ir_type_loop, ir_type_loop_jump, ir_type_return, - ir_type_swizzle, - ir_type_texture, + ir_type_discard, ir_type_emit_vertex, ir_type_end_primitive, - ir_type_max /**< maximum ir_type enum number, for validation */ + ir_type_max, /**< maximum ir_type enum number, for validation */ + ir_type_unset = ir_type_max }; @@ -121,24 +117,58 @@ public: * Additional downcast functions will be added as needed. */ /*@{*/ - virtual class ir_variable * as_variable() { return NULL; } - virtual class ir_function * as_function() { return NULL; } - virtual class ir_dereference * as_dereference() { return NULL; } - virtual class ir_dereference_array * as_dereference_array() { return NULL; } - virtual class ir_dereference_variable *as_dereference_variable() { return NULL; } - virtual class ir_dereference_record *as_dereference_record() { return NULL; } - virtual class ir_expression * as_expression() { return NULL; } - virtual class ir_rvalue * as_rvalue() { return NULL; } - virtual class ir_loop * as_loop() { return NULL; } - virtual class ir_assignment * as_assignment() { return NULL; } - virtual class ir_call * as_call() { return NULL; } - virtual class ir_return * as_return() { return NULL; } - virtual class ir_if * as_if() { return NULL; } - virtual class ir_swizzle * as_swizzle() { return NULL; } - virtual class ir_texture * as_texture() { return NULL; } - virtual class ir_constant * as_constant() { return NULL; } - virtual class ir_discard * as_discard() { return NULL; } - virtual class ir_jump * as_jump() { return NULL; } + class ir_rvalue *as_rvalue() + { + if (ir_type == ir_type_dereference_array || + ir_type == ir_type_dereference_record || + ir_type == ir_type_dereference_variable || + ir_type == ir_type_constant || + ir_type == ir_type_expression || + ir_type == ir_type_swizzle || + ir_type == ir_type_texture) + return (class ir_rvalue *) this; + return NULL; + } + + class ir_dereference *as_dereference() + { + if (ir_type == ir_type_dereference_array || + ir_type == ir_type_dereference_record || + ir_type == ir_type_dereference_variable) + return (class ir_dereference *) this; + return NULL; + } + + class ir_jump *as_jump() + { + if (ir_type == ir_type_loop_jump || + ir_type == ir_type_return || + ir_type == ir_type_discard) + return (class ir_jump *) this; + return NULL; + } + + #define AS_CHILD(TYPE) \ + class ir_##TYPE * as_##TYPE() \ + { \ + return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL; \ + } + AS_CHILD(variable) + AS_CHILD(function) + AS_CHILD(dereference_array) + AS_CHILD(dereference_variable) + AS_CHILD(dereference_record) + AS_CHILD(expression) + AS_CHILD(loop) + AS_CHILD(assignment) + AS_CHILD(call) + AS_CHILD(return) + AS_CHILD(if) + AS_CHILD(swizzle) + AS_CHILD(texture) + AS_CHILD(constant) + AS_CHILD(discard) + #undef AS_CHILD /*@}*/ /** @@ -152,9 +182,15 @@ public: virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); protected: + ir_instruction(enum ir_node_type t) + : ir_type(t) + { + } + +private: ir_instruction() { - ir_type = ir_type_unset; + assert(!"Should not get here."); } }; @@ -177,11 +213,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_rvalue * as_rvalue() - { - return this; - } - ir_rvalue *as_rvalue_to_saturate(); virtual bool is_lvalue() const @@ -281,7 +312,7 @@ public: static ir_rvalue *error_value(void *mem_ctx); protected: - ir_rvalue(); + ir_rvalue(enum ir_node_type t); }; @@ -382,11 +413,6 @@ public: virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_variable *as_variable() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -535,6 +561,7 @@ public: unsigned centroid:1; unsigned sample:1; unsigned invariant:1; + unsigned precise:1; /** * Has this variable been used for reading or writing? @@ -917,11 +944,6 @@ public: virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_function *as_function() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -984,18 +1006,12 @@ inline const char *ir_function_signature::function_name() const class ir_if : public ir_instruction { public: ir_if(ir_rvalue *condition) - : condition(condition) + : ir_instruction(ir_type_if), condition(condition) { - ir_type = ir_type_if; } virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_if *as_if() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -1027,11 +1043,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_loop *as_loop() - { - return this; - } - /** List of ir_instruction that make up the body of the loop. */ exec_list body_instructions; }; @@ -1062,11 +1073,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_assignment * as_assignment() - { - return this; - } - /** * Get a whole variable written by an assignment * @@ -1430,11 +1436,6 @@ public: */ ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2); - virtual ir_expression *as_expression() - { - return this; - } - virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; @@ -1514,9 +1515,8 @@ public: ir_call(ir_function_signature *callee, ir_dereference_variable *return_deref, exec_list *actual_parameters) - : return_deref(return_deref), callee(callee) + : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee) { - ir_type = ir_type_call; assert(callee->return_type != NULL); actual_parameters->move_nodes_to(& this->actual_parameters); this->use_builtin = callee->is_builtin(); @@ -1526,11 +1526,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_call *as_call() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -1579,39 +1574,26 @@ public: /*@{*/ class ir_jump : public ir_instruction { protected: - ir_jump() + ir_jump(enum ir_node_type t) + : ir_instruction(t) { - ir_type = ir_type_unset; - } - -public: - virtual ir_jump *as_jump() - { - return this; } }; class ir_return : public ir_jump { public: ir_return() - : value(NULL) + : ir_jump(ir_type_return), value(NULL) { - this->ir_type = ir_type_return; } ir_return(ir_rvalue *value) - : value(value) + : ir_jump(ir_type_return), value(value) { - this->ir_type = ir_type_return; } virtual ir_return *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_return *as_return() - { - return this; - } - ir_rvalue *get_value() const { return value; @@ -1644,8 +1626,8 @@ public: }; ir_loop_jump(jump_mode mode) + : ir_jump(ir_type_loop_jump) { - this->ir_type = ir_type_loop_jump; this->mode = mode; } @@ -1678,14 +1660,14 @@ public: class ir_discard : public ir_jump { public: ir_discard() + : ir_jump(ir_type_discard) { - this->ir_type = ir_type_discard; this->condition = NULL; } ir_discard(ir_rvalue *cond) + : ir_jump(ir_type_discard) { - this->ir_type = ir_type_discard; this->condition = cond; } @@ -1698,11 +1680,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_discard *as_discard() - { - return this; - } - ir_rvalue *condition; }; /*@}*/ @@ -1752,10 +1729,10 @@ enum ir_texture_opcode { class ir_texture : public ir_rvalue { public: ir_texture(enum ir_texture_opcode op) - : op(op), sampler(NULL), coordinate(NULL), projector(NULL), + : ir_rvalue(ir_type_texture), + op(op), sampler(NULL), coordinate(NULL), projector(NULL), shadow_comparitor(NULL), offset(NULL) { - this->ir_type = ir_type_texture; memset(&lod_info, 0, sizeof(lod_info)); } @@ -1768,11 +1745,6 @@ public: v->visit(this); } - virtual ir_texture *as_texture() - { - return this; - } - virtual ir_visitor_status accept(ir_hierarchical_visitor *); virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); @@ -1864,11 +1836,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_swizzle *as_swizzle() - { - return this; - } - /** * Construct an ir_swizzle from the textual representation. Can fail. */ @@ -1910,17 +1877,18 @@ class ir_dereference : public ir_rvalue { public: virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; - virtual ir_dereference *as_dereference() - { - return this; - } - bool is_lvalue() const; /** * Get the variable that is ultimately referenced by an r-value */ virtual ir_variable *variable_referenced() const = 0; + +protected: + ir_dereference(enum ir_node_type t) + : ir_rvalue(t) + { + } }; @@ -1933,11 +1901,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_dereference_variable *as_dereference_variable() - { - return this; - } - virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); /** @@ -1984,11 +1947,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_dereference_array *as_dereference_array() - { - return this; - } - virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); /** @@ -2025,11 +1983,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_dereference_record *as_dereference_record() - { - return this; - } - /** * Get the variable that is ultimately referenced by an r-value */ @@ -2095,11 +2048,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_constant *as_constant() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -2207,8 +2155,8 @@ private: class ir_emit_vertex : public ir_instruction { public: ir_emit_vertex() + : ir_instruction(ir_type_emit_vertex) { - ir_type = ir_type_emit_vertex; } virtual void accept(ir_visitor *v) @@ -2231,8 +2179,8 @@ public: class ir_end_primitive : public ir_instruction { public: ir_end_primitive() + : ir_instruction(ir_type_end_primitive) { - ir_type = ir_type_end_primitive; } virtual void accept(ir_visitor *v) diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index 40cf5894a..deec1dfe8 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -23,6 +23,7 @@ #include "glsl_types.h" #include "ir.h" +#include "glsl_parser_extras.h" typedef enum { PARAMETER_LIST_NO_MATCH, @@ -38,7 +39,8 @@ typedef enum { * \see matching_signature() */ static parameter_list_match_t -parameter_lists_match(const exec_list *list_a, const exec_list *list_b) +parameter_lists_match(_mesa_glsl_parse_state *state, + const exec_list *list_a, const exec_list *list_b) { const exec_node *node_a = list_a->head; const exec_node *node_b = list_b->head; @@ -79,12 +81,12 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) case ir_var_const_in: case ir_var_function_in: - if (!actual->type->can_implicitly_convert_to(param->type)) + if (!actual->type->can_implicitly_convert_to(param->type, state)) return PARAMETER_LIST_NO_MATCH; break; case ir_var_function_out: - if (!param->type->can_implicitly_convert_to(actual->type)) + if (!param->type->can_implicitly_convert_to(actual->type, state)) return PARAMETER_LIST_NO_MATCH; break; @@ -115,6 +117,168 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) } +/* Classes of parameter match, sorted (mostly) best matches first. + * See is_better_parameter_match() below for the exceptions. + * */ +typedef enum { + PARAMETER_EXACT_MATCH, + PARAMETER_FLOAT_TO_DOUBLE, + PARAMETER_INT_TO_FLOAT, + PARAMETER_INT_TO_DOUBLE, + PARAMETER_OTHER_CONVERSION, +} parameter_match_t; + + +static parameter_match_t +get_parameter_match_type(const ir_variable *param, + const ir_rvalue *actual) +{ + const glsl_type *from_type; + const glsl_type *to_type; + + if (param->data.mode == ir_var_function_out) { + from_type = param->type; + to_type = actual->type; + } else { + from_type = actual->type; + to_type = param->type; + } + + if (from_type == to_type) + return PARAMETER_EXACT_MATCH; + + /* XXX: When ARB_gpu_shader_fp64 support is added, check for float->double, + * and int/uint->double conversions + */ + + if (to_type->base_type == GLSL_TYPE_FLOAT) + return PARAMETER_INT_TO_FLOAT; + + /* int -> uint and any other oddball conversions */ + return PARAMETER_OTHER_CONVERSION; +} + + +static bool +is_better_parameter_match(parameter_match_t a_match, + parameter_match_t b_match) +{ + /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec): + * + * 1. An exact match is better than a match involving any implicit + * conversion. + * + * 2. A match involving an implicit conversion from float to double + * is better than match involving any other implicit conversion. + * + * [XXX: Not in GLSL 4.0: Only in ARB_gpu_shader5: + * 3. A match involving an implicit conversion from either int or uint + * to float is better than a match involving an implicit conversion + * from either int or uint to double.] + * + * If none of the rules above apply to a particular pair of conversions, + * neither conversion is considered better than the other. + * + * -- + * + * Notably, the int->uint conversion is *not* considered to be better + * or worse than int/uint->float or int/uint->double. + */ + + if (a_match >= PARAMETER_INT_TO_FLOAT && b_match == PARAMETER_OTHER_CONVERSION) + return false; + + return a_match < b_match; +} + + +static bool +is_best_inexact_overload(const exec_list *actual_parameters, + ir_function_signature **matches, + int num_matches, + ir_function_signature *sig) +{ + /* From section 6.1 of the GLSL 4.00 spec (and the ARB_gpu_shader5 spec): + * + * "A function definition A is considered a better + * match than function definition B if: + * + * * for at least one function argument, the conversion for that argument + * in A is better than the corresponding conversion in B; and + * + * * there is no function argument for which the conversion in B is better + * than the corresponding conversion in A. + * + * If a single function definition is considered a better match than every + * other matching function definition, it will be used. Otherwise, a + * semantic error occurs and the shader will fail to compile." + */ + for (ir_function_signature **other = matches; + other < matches + num_matches; other++) { + if (*other == sig) + continue; + + const exec_node *node_a = sig->parameters.head; + const exec_node *node_b = (*other)->parameters.head; + const exec_node *node_p = actual_parameters->head; + + bool better_for_some_parameter = false; + + for (/* empty */ + ; !node_a->is_tail_sentinel() + ; node_a = node_a->next, + node_b = node_b->next, + node_p = node_p->next) { + parameter_match_t a_match = get_parameter_match_type( + (const ir_variable *)node_a, + (const ir_rvalue *)node_p); + parameter_match_t b_match = get_parameter_match_type( + (const ir_variable *)node_b, + (const ir_rvalue *)node_p); + + if (is_better_parameter_match(a_match, b_match)) + better_for_some_parameter = true; + + if (is_better_parameter_match(b_match, a_match)) + return false; /* B is better for this parameter */ + } + + if (!better_for_some_parameter) + return false; /* A must be better than B for some parameter */ + + } + + return true; +} + + +static ir_function_signature * +choose_best_inexact_overload(_mesa_glsl_parse_state *state, + const exec_list *actual_parameters, + ir_function_signature **matches, + int num_matches) +{ + if (num_matches == 0) + return NULL; + + if (num_matches == 1) + return *matches; + + /* Without GLSL 4.0 / ARB_gpu_shader5, there is no overload resolution + * among multiple inexact matches. Note that state may be NULL here if + * called from the linker; in that case we assume everything supported in + * any GLSL version is available. */ + if (!state || state->is_version(400, 0) || state->ARB_gpu_shader5_enable) { + for (ir_function_signature **sig = matches; sig < matches + num_matches; sig++) { + if (is_best_inexact_overload(actual_parameters, matches, num_matches, *sig)) + return *sig; + } + } + + return NULL; /* no best candidate */ +} + + ir_function_signature * ir_function::matching_signature(_mesa_glsl_parse_state *state, const exec_list *actual_parameters) @@ -126,10 +290,11 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state, ir_function_signature * ir_function::matching_signature(_mesa_glsl_parse_state *state, const exec_list *actual_parameters, - bool *is_exact) + bool *is_exact) { + ir_function_signature **inexact_matches = NULL; ir_function_signature *match = NULL; - bool multiple_inexact_matches = false; + int num_inexact_matches = 0; /* From page 42 (page 49 of the PDF) of the GLSL 1.20 spec: * @@ -148,16 +313,19 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state, if (sig->is_builtin() && !sig->is_builtin_available(state)) continue; - switch (parameter_lists_match(& sig->parameters, actual_parameters)) { + switch (parameter_lists_match(state, & sig->parameters, actual_parameters)) { case PARAMETER_LIST_EXACT_MATCH: - *is_exact = true; - return sig; + *is_exact = true; + free(inexact_matches); + return sig; case PARAMETER_LIST_INEXACT_MATCH: - if (match == NULL) - match = sig; - else - multiple_inexact_matches = true; - continue; + inexact_matches = (ir_function_signature **) + realloc(inexact_matches, + sizeof(*inexact_matches) * + (num_inexact_matches + 1)); + assert(inexact_matches); + inexact_matches[num_inexact_matches++] = sig; + continue; case PARAMETER_LIST_NO_MATCH: continue; default: @@ -175,9 +343,10 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state, */ *is_exact = false; - if (multiple_inexact_matches) - return NULL; + match = choose_best_inexact_overload(state, actual_parameters, + inexact_matches, num_inexact_matches); + free(inexact_matches); return match; } diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 71defc815..17a74ea55 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -795,7 +795,7 @@ check_node_type(ir_instruction *ir, void *data) { (void) data; - if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) { + if (ir->ir_type >= ir_type_max) { printf("Instruction node with unset type\n"); ir->print(); printf("\n"); } diff --git a/mesalib/src/glsl/loop_analysis.cpp b/mesalib/src/glsl/loop_analysis.cpp index d6a9ac775..78ac30044 100644 --- a/mesalib/src/glsl/loop_analysis.cpp +++ b/mesalib/src/glsl/loop_analysis.cpp @@ -589,8 +589,10 @@ get_basic_induction_increment(ir_assignment *ir, hash_table *var_hash) loop_variable *lv = (loop_variable *) hash_table_find(var_hash, inc_var); - if (!lv->is_loop_constant()) - inc = NULL; + if (lv == NULL || !lv->is_loop_constant()) { + assert(lv != NULL); + inc = NULL; + } } else inc = NULL; } diff --git a/mesalib/src/loader/loader.c b/mesalib/src/loader/loader.c index 666d0158a..0f262653b 100644 --- a/mesalib/src/loader/loader.c +++ b/mesalib/src/loader/loader.c @@ -71,6 +71,10 @@ #include <assert.h> #include <dlfcn.h> #endif +#ifdef HAVE_SYSFS +#include <sys/stat.h> +#include <sys/types.h> +#endif #include "loader.h" #ifndef __NOT_HAVE_DRM_H @@ -113,8 +117,8 @@ udev_dlopen_handle(void) udev_handle = dlopen("libudev.so.0", RTLD_LOCAL | RTLD_LAZY); if (!udev_handle) { - log_(_LOADER_FATAL, "Couldn't dlopen libudev.so.1 or libudev.so.0, " - "driver detection may be broken.\n"); + log_(_LOADER_WARNING, "Couldn't dlopen libudev.so.1 or " + "libudev.so.0, driver detection may be broken.\n"); } } } @@ -122,16 +126,19 @@ udev_dlopen_handle(void) return udev_handle; } +static int dlsym_failed = 0; + static void * -asserted_dlsym(void *dlopen_handle, const char *name) +checked_dlsym(void *dlopen_handle, const char *name) { void *result = dlsym(dlopen_handle, name); - assert(result); + if (!result) + dlsym_failed = 1; return result; } #define UDEV_SYMBOL(ret, name, args) \ - ret (*name) args = asserted_dlsym(udev_dlopen_handle(), #name); + ret (*name) args = checked_dlsym(udev_dlopen_handle(), #name); static inline struct udev_device * @@ -142,6 +149,9 @@ udev_device_new_from_fd(struct udev *udev, int fd) UDEV_SYMBOL(struct udev_device *, udev_device_new_from_devnum, (struct udev *udev, char type, dev_t devnum)); + if (dlsym_failed) + return NULL; + if (fstat(fd, &buf) < 0) { log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d\n", fd); return NULL; @@ -157,8 +167,8 @@ udev_device_new_from_fd(struct udev *udev, int fd) return device; } -int -loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) +static int +libudev_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) { struct udev *udev = NULL; struct udev_device *device = NULL, *parent; @@ -174,6 +184,9 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) *chip_id = -1; + if (dlsym_failed) + return 0; + udev = udev_new(); device = udev_device_new_from_fd(udev, fd); if (!device) @@ -201,16 +214,76 @@ out: return (*chip_id >= 0); } +#endif + +#if defined(HAVE_SYSFS) +static int +dev_node_from_fd(int fd, unsigned int *maj, unsigned int *min) +{ + struct stat buf; + + if (fstat(fd, &buf) < 0) { + log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d\n", fd); + return -1; + } + + if (!S_ISCHR(buf.st_mode)) { + log_(_LOADER_WARNING, "MESA-LOADER: fd %d not a character device\n", fd); + return -1; + } + + *maj = major(buf.st_rdev); + *min = minor(buf.st_rdev); + + return 0; +} + +static int +sysfs_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) +{ + unsigned int maj, min; + FILE *f; + char buf[0x40]; + + if (dev_node_from_fd(fd, &maj, &min) < 0) { + *chip_id = -1; + return 0; + } -#elif !defined(__NOT_HAVE_DRM_H) + snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/vendor", maj, min); + if (!(f = fopen(buf, "r"))) { + *chip_id = -1; + return 0; + } + if (fscanf(f, "%x", vendor_id) != 1) { + *chip_id = -1; + fclose(f); + return 0; + } + fclose(f); + snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/device", maj, min); + if (!(f = fopen(buf, "r"))) { + *chip_id = -1; + return 0; + } + if (fscanf(f, "%x", chip_id) != 1) { + *chip_id = -1; + fclose(f); + return 0; + } + fclose(f); + return 1; +} +#endif +#if !defined(__NOT_HAVE_DRM_H) /* for i915 */ #include <i915_drm.h> /* for radeon */ #include <radeon_drm.h> -int -loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) +static int +drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) { drmVersionPtr version; @@ -272,23 +345,33 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) return (*chip_id >= 0); } +#endif -#else int loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) { +#if HAVE_LIBUDEV + if (libudev_get_pci_id_for_fd(fd, vendor_id, chip_id)) + return 1; +#endif +#if HAVE_SYSFS + if (sysfs_get_pci_id_for_fd(fd, vendor_id, chip_id)) + return 1; +#endif +#if !defined(__NOT_HAVE_DRM_H) + if (drm_get_pci_id_for_fd(fd, vendor_id, chip_id)) + return 1; +#endif return 0; } -#endif - -char * -loader_get_device_name_for_fd(int fd) +#ifdef HAVE_LIBUDEV +static char * +libudev_get_device_name_for_fd(int fd) { char *device_name = NULL; -#ifdef HAVE_LIBUDEV struct udev *udev; struct udev_device *device; const char *const_device_name; @@ -312,9 +395,66 @@ loader_get_device_name_for_fd(int fd) out: udev_device_unref(device); udev_unref(udev); + return device_name; +} #endif + + +#if HAVE_SYSFS +static char * +sysfs_get_device_name_for_fd(int fd) +{ + char *device_name = NULL; + unsigned int maj, min; + FILE *f; + char buf[0x40]; + static const char match[9] = "\0DEVNAME="; + int expected = 1; + + if (dev_node_from_fd(fd, &maj, &min) < 0) + return NULL; + + snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/uevent", maj, min); + if (!(f = fopen(buf, "r"))) + return NULL; + + while (expected < sizeof(match)) { + int c = getc(f); + + if (c == EOF) { + fclose(f); + return NULL; + } else if (c == match[expected] ) + expected++; + else + expected = 0; + } + + strcpy(buf, "/dev/"); + if (fgets(buf + 5, sizeof(buf) - 5, f)) + device_name = strdup(buf); + + fclose(f); return device_name; } +#endif + + +char * +loader_get_device_name_for_fd(int fd) +{ + char *result = NULL; + +#if HAVE_LIBUDEV + if ((result = libudev_get_device_name_for_fd(fd))) + return result; +#endif +#if HAVE_SYSFS + if ((result = sysfs_get_device_name_for_fd(fd))) + return result; +#endif + return result; +} char * loader_get_driver_for_fd(int fd, unsigned driver_types) diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml index 4e430fda5..58aed8e6f 100755 --- a/mesalib/src/mapi/glapi/gen/gl_API.xml +++ b/mesalib/src/mapi/glapi/gen/gl_API.xml @@ -8314,6 +8314,9 @@ <xi:include href="ARB_invalidate_subdata.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> +<!-- ARB extension #133 is ARB_multi_draw_indirect, defined in the same + file as ARB_draw_indirect --> + <!-- ARB extensions #134...#138 --> <xi:include href="ARB_texture_buffer_range.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> diff --git a/mesalib/src/mapi/glapi/glapi_dispatch.c b/mesalib/src/mapi/glapi/glapi_dispatch.c index b4c8c7773..d2dd9654a 100644 --- a/mesalib/src/mapi/glapi/glapi_dispatch.c +++ b/mesalib/src/mapi/glapi/glapi_dispatch.c @@ -87,6 +87,63 @@ /* those link to libglapi.a should provide the entry points */ #define _GLAPI_SKIP_PROTO_ENTRY_POINTS #endif + +/* These prototypes are necessary because GLES1 library builds will create + * dispatch functions for them. We can't directly include GLES/gl.h because + * it would conflict the previously-included GL/gl.h. Since GLES1 ABI is not + * expected to every add more functions, the path of least resistance is to + * just duplicate the prototypes for the functions that aren't already in + * desktop OpenGL. + */ +#include <GLES/glplatform.h> + +GL_API void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_API void GL_APIENTRY glClipPlanef (GLenum plane, const GLfloat *equation); +GL_API void GL_APIENTRY glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); +GL_API void GL_APIENTRY glGetClipPlanef (GLenum pname, GLfloat eqn[4]); +GL_API void GL_APIENTRY glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); + +GL_API void GL_APIENTRY glAlphaFuncx (GLenum func, GLclampx ref); +GL_API void GL_APIENTRY glClearColorx (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha); +GL_API void GL_APIENTRY glClearDepthx (GLclampx depth); +GL_API void GL_APIENTRY glClipPlanex (GLenum plane, const GLfixed *equation); +GL_API void GL_APIENTRY glColor4x (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GL_API void GL_APIENTRY glDepthRangex (GLclampx zNear, GLclampx zFar); +GL_API void GL_APIENTRY glFogx (GLenum pname, GLfixed param); +GL_API void GL_APIENTRY glFogxv (GLenum pname, const GLfixed *params); +GL_API void GL_APIENTRY glFrustumx (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); +GL_API void GL_APIENTRY glGetClipPlanex (GLenum pname, GLfixed eqn[4]); +GL_API void GL_APIENTRY glGetFixedv (GLenum pname, GLfixed *params); +GL_API void GL_APIENTRY glGetLightxv (GLenum light, GLenum pname, GLfixed *params); +GL_API void GL_APIENTRY glGetMaterialxv (GLenum face, GLenum pname, GLfixed *params); +GL_API void GL_APIENTRY glGetTexEnvxv (GLenum env, GLenum pname, GLfixed *params); +GL_API void GL_APIENTRY glGetTexParameterxv (GLenum target, GLenum pname, GLfixed *params); +GL_API void GL_APIENTRY glLightModelx (GLenum pname, GLfixed param); +GL_API void GL_APIENTRY glLightModelxv (GLenum pname, const GLfixed *params); +GL_API void GL_APIENTRY glLightx (GLenum light, GLenum pname, GLfixed param); +GL_API void GL_APIENTRY glLightxv (GLenum light, GLenum pname, const GLfixed *params); +GL_API void GL_APIENTRY glLineWidthx (GLfixed width); +GL_API void GL_APIENTRY glLoadMatrixx (const GLfixed *m); +GL_API void GL_APIENTRY glMaterialx (GLenum face, GLenum pname, GLfixed param); +GL_API void GL_APIENTRY glMaterialxv (GLenum face, GLenum pname, const GLfixed *params); +GL_API void GL_APIENTRY glMultMatrixx (const GLfixed *m); +GL_API void GL_APIENTRY glMultiTexCoord4x (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +GL_API void GL_APIENTRY glNormal3x (GLfixed nx, GLfixed ny, GLfixed nz); +GL_API void GL_APIENTRY glOrthox (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); +GL_API void GL_APIENTRY glPointParameterx (GLenum pname, GLfixed param); +GL_API void GL_APIENTRY glPointParameterxv (GLenum pname, const GLfixed *params); +GL_API void GL_APIENTRY glPointSizex (GLfixed size); +GL_API void GL_APIENTRY glPolygonOffsetx (GLfixed factor, GLfixed units); +GL_API void GL_APIENTRY glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +GL_API void GL_APIENTRY glSampleCoveragex (GLclampx value, GLboolean invert); +GL_API void GL_APIENTRY glScalex (GLfixed x, GLfixed y, GLfixed z); +GL_API void GL_APIENTRY glTexEnvx (GLenum target, GLenum pname, GLfixed param); +GL_API void GL_APIENTRY glTexEnvxv (GLenum target, GLenum pname, const GLfixed *params); +GL_API void GL_APIENTRY glTexParameterx (GLenum target, GLenum pname, GLfixed param); +GL_API void GL_APIENTRY glTexParameterxv (GLenum target, GLenum pname, const GLfixed *params); +GL_API void GL_APIENTRY glTranslatex (GLfixed x, GLfixed y, GLfixed z); +GL_API void GL_APIENTRY glPointSizePointerOES (GLenum type, GLsizei stride, const GLvoid *pointer); + #include "glapi/glapitemp.h" #endif /* USE_X86_ASM */ diff --git a/mesalib/src/mesa/drivers/common/meta_blit.c b/mesalib/src/mesa/drivers/common/meta_blit.c index 5929619f3..f26ef93c1 100644 --- a/mesalib/src/mesa/drivers/common/meta_blit.c +++ b/mesalib/src/mesa/drivers/common/meta_blit.c @@ -430,6 +430,9 @@ blitframebuffer_texture(struct gl_context *ctx, srcLevel = 0; target = meta_temp_texture->Target; texObj = _mesa_lookup_texture(ctx, meta_temp_texture->TexObj); + if (texObj == NULL) { + return false; + } _mesa_meta_setup_copypix_texture(ctx, meta_temp_texture, srcX0, srcY0, diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 80a5839b5..9b56edb74 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -847,6 +847,16 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu v->value_int = ctx->Array.VAO->IndexBufferObj->Name; break; + /* ARB_vertex_array_bgra */ + case GL_COLOR_ARRAY_SIZE: + array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR0]; + v->value_int = array->Format == GL_BGRA ? GL_BGRA : array->Size; + break; + case GL_SECONDARY_COLOR_ARRAY_SIZE: + array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR1]; + v->value_int = array->Format == GL_BGRA ? GL_BGRA : array->Size; + break; + /* ARB_copy_buffer */ case GL_COPY_READ_BUFFER: v->value_int = ctx->CopyReadBuffer->Name; @@ -995,7 +1005,11 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu break; /* GL_ARB_shader_atomic_counters */ case GL_ATOMIC_COUNTER_BUFFER_BINDING: - v->value_int = ctx->AtomicBuffer->Name; + if (ctx->AtomicBuffer) { + v->value_int = ctx->AtomicBuffer->Name; + } else { + v->value_int = 0; + } break; /* GL_ARB_draw_indirect */ case GL_DRAW_INDIRECT_BUFFER_BINDING: diff --git a/mesalib/src/mesa/main/get_hash_generator.py b/mesalib/src/mesa/main/get_hash_generator.py index 96bc49587..b200d1973 100644 --- a/mesalib/src/mesa/main/get_hash_generator.py +++ b/mesalib/src/mesa/main/get_hash_generator.py @@ -52,7 +52,7 @@ def print_header(): (prime_factor, prime_step) def print_params(params): - print "static struct value_desc values[] = {" + print "static const struct value_desc values[] = {" for p in params: print " { %s, %s }," % (p[0], p[1]) diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index d40fa0778..c7a6e02af 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -199,7 +199,7 @@ descriptor=[ [ "NORMAL_ARRAY_TYPE", "ARRAY_ENUM(VertexAttrib[VERT_ATTRIB_NORMAL].Type), NO_EXTRA" ], [ "NORMAL_ARRAY_STRIDE", "ARRAY_INT(VertexAttrib[VERT_ATTRIB_NORMAL].Stride), NO_EXTRA" ], [ "COLOR_ARRAY", "ARRAY_BOOL(VertexAttrib[VERT_ATTRIB_COLOR0].Enabled), NO_EXTRA" ], - [ "COLOR_ARRAY_SIZE", "ARRAY_INT(VertexAttrib[VERT_ATTRIB_COLOR0].Size), NO_EXTRA" ], + [ "COLOR_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], [ "COLOR_ARRAY_TYPE", "ARRAY_ENUM(VertexAttrib[VERT_ATTRIB_COLOR0].Type), NO_EXTRA" ], [ "COLOR_ARRAY_STRIDE", "ARRAY_INT(VertexAttrib[VERT_ATTRIB_COLOR0].Stride), NO_EXTRA" ], [ "TEXTURE_COORD_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, offsetof(struct gl_client_array, Enabled), NO_EXTRA" ], @@ -552,7 +552,7 @@ descriptor=[ [ "SECONDARY_COLOR_ARRAY", "ARRAY_BOOL(VertexAttrib[VERT_ATTRIB_COLOR1].Enabled), NO_EXTRA" ], [ "SECONDARY_COLOR_ARRAY_TYPE", "ARRAY_ENUM(VertexAttrib[VERT_ATTRIB_COLOR1].Type), NO_EXTRA" ], [ "SECONDARY_COLOR_ARRAY_STRIDE", "ARRAY_INT(VertexAttrib[VERT_ATTRIB_COLOR1].Stride), NO_EXTRA" ], - [ "SECONDARY_COLOR_ARRAY_SIZE", "ARRAY_INT(VertexAttrib[VERT_ATTRIB_COLOR1].Size), NO_EXTRA" ], + [ "SECONDARY_COLOR_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], # GL_EXT_fog_coord [ "CURRENT_FOG_COORDINATE", "CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_FOG][0]), extra_flush_current" ], diff --git a/mesalib/src/mesa/main/hash.c b/mesalib/src/mesa/main/hash.c index 23018e9da..674c29d65 100644 --- a/mesalib/src/mesa/main/hash.c +++ b/mesalib/src/mesa/main/hash.c @@ -115,10 +115,20 @@ _mesa_NewHashTable(void) if (table) { table->ht = _mesa_hash_table_create(NULL, uint_key_compare); + if (table->ht == NULL) { + free(table); + _mesa_error_no_memory(__func__); + return NULL; + } + _mesa_hash_table_set_deleted_key(table->ht, uint_key(DELETED_KEY_VALUE)); mtx_init(&table->Mutex, mtx_plain); mtx_init(&table->WalkMutex, mtx_plain); } + else { + _mesa_error_no_memory(__func__); + } + return table; } diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c index 21b9423e0..9d1a6b4d8 100644 --- a/mesalib/src/mesa/main/performance_monitor.c +++ b/mesalib/src/mesa/main/performance_monitor.c @@ -1036,6 +1036,11 @@ _mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle) } m = new_performance_monitor(ctx, first); + if (m == NULL) { + _mesa_error_no_memory(__func__); + return; + } + _mesa_HashInsert(ctx->PerfMonitor.Monitors, first, m); *queryHandle = first; diff --git a/mesalib/src/mesa/program/prog_hash_table.c b/mesalib/src/mesa/program/prog_hash_table.c index f45ed46af..2445d8434 100644 --- a/mesalib/src/mesa/program/prog_hash_table.c +++ b/mesalib/src/mesa/program/prog_hash_table.c @@ -142,6 +142,10 @@ hash_table_insert(struct hash_table *ht, void *data, const void *key) struct hash_node *node; node = calloc(1, sizeof(*node)); + if (node == NULL) { + _mesa_error_no_memory(__func__); + return; + } node->data = data; node->key = key; @@ -167,6 +171,10 @@ hash_table_replace(struct hash_table *ht, void *data, const void *key) } hn = calloc(1, sizeof(*hn)); + if (hn == NULL) { + _mesa_error_no_memory(__func__); + return false; + } hn->data = data; hn->key = key; diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c index 928a4ffd2..e2d26ee24 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_texture.c +++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c @@ -358,7 +358,7 @@ update_textures(struct st_context *st, { const GLuint old_max = *num_textures; GLbitfield samplers_used = prog->SamplersUsed; - GLuint unit, new_count; + GLuint unit; if (samplers_used == 0x0 && old_max == 0) return; @@ -387,16 +387,9 @@ update_textures(struct st_context *st, pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view); } - /* Ex: if old_max = 3 and *num_textures = 1, we need to pass an - * array of views={X, NULL, NULL} to unref the old texture views - * at positions [1] and [2]. - */ - new_count = MAX2(*num_textures, old_max); - assert(new_count <= max_units); - cso_set_sampler_views(st->cso_context, shader_stage, - new_count, + *num_textures, sampler_views); } |