Compare commits
	
		
			197 Commits
		
	
	
		
			mesa-10.3.
			...
			mesa_7_7_1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0c88e34049 | ||
| 
						 | 
					663642b435 | ||
| 
						 | 
					535742d75f | ||
| 
						 | 
					8fe3b3f66a | ||
| 
						 | 
					4cf14fa80b | ||
| 
						 | 
					6ec259eb17 | ||
| 
						 | 
					ca1c8a183d | ||
| 
						 | 
					3f3b1094bf | ||
| 
						 | 
					e33121b2d8 | ||
| 
						 | 
					415d0326bb | ||
| 
						 | 
					7e24ce2d9b | ||
| 
						 | 
					2ae754b7b9 | ||
| 
						 | 
					501156b36b | ||
| 
						 | 
					4ff3244457 | ||
| 
						 | 
					3889556d70 | ||
| 
						 | 
					6412046f65 | ||
| 
						 | 
					6e96cea6e2 | ||
| 
						 | 
					3a3ef3d6c9 | ||
| 
						 | 
					98aed6dc69 | ||
| 
						 | 
					d3a607f889 | ||
| 
						 | 
					00e41e007e | ||
| 
						 | 
					6624845a5d | ||
| 
						 | 
					c9c54180e4 | ||
| 
						 | 
					93e77b0028 | ||
| 
						 | 
					0c9e8e6c6e | ||
| 
						 | 
					c50477c255 | ||
| 
						 | 
					3bf13656d3 | ||
| 
						 | 
					fa4083d38b | ||
| 
						 | 
					d311ded31d | ||
| 
						 | 
					34f0207161 | ||
| 
						 | 
					8d3f629a13 | ||
| 
						 | 
					b98ef495d4 | ||
| 
						 | 
					21c91b410a | ||
| 
						 | 
					a8f3b3f88a | ||
| 
						 | 
					e8a8c5e339 | ||
| 
						 | 
					7941d31ee6 | ||
| 
						 | 
					842351dd76 | ||
| 
						 | 
					d74929702f | ||
| 
						 | 
					1e431f0454 | ||
| 
						 | 
					4cc8d1d79f | ||
| 
						 | 
					3d2bc6848a | ||
| 
						 | 
					d5327538e7 | ||
| 
						 | 
					86ac140937 | ||
| 
						 | 
					b584e780ab | ||
| 
						 | 
					981e8a2087 | ||
| 
						 | 
					72d380b363 | ||
| 
						 | 
					cf8af9bcf1 | ||
| 
						 | 
					7123f3d77a | ||
| 
						 | 
					2edb1b9534 | ||
| 
						 | 
					69334d6784 | ||
| 
						 | 
					61482ddc1c | ||
| 
						 | 
					b0e84e22d5 | ||
| 
						 | 
					c0e8d443fe | ||
| 
						 | 
					b95d4cd680 | ||
| 
						 | 
					293f4d51b4 | ||
| 
						 | 
					f0e99179bc | ||
| 
						 | 
					69a94e1452 | ||
| 
						 | 
					bc7e12e5e3 | ||
| 
						 | 
					7accf8ced6 | ||
| 
						 | 
					52d83efdbc | ||
| 
						 | 
					1702db3a35 | ||
| 
						 | 
					fa6eee135e | ||
| 
						 | 
					b5fa760972 | ||
| 
						 | 
					69cf45cdae | ||
| 
						 | 
					f5ffbe0bc3 | ||
| 
						 | 
					46d8ca023d | ||
| 
						 | 
					9bef69782d | ||
| 
						 | 
					b0e5dcb859 | ||
| 
						 | 
					bcd561c667 | ||
| 
						 | 
					c98eced9ae | ||
| 
						 | 
					13cbb5fff6 | ||
| 
						 | 
					dd8d78c908 | ||
| 
						 | 
					9d17ad2891 | ||
| 
						 | 
					d437d905e6 | ||
| 
						 | 
					551c96979e | ||
| 
						 | 
					c1a4f249f1 | ||
| 
						 | 
					18ff85e91d | ||
| 
						 | 
					12617c7e30 | ||
| 
						 | 
					5dbf44953c | ||
| 
						 | 
					a51d638ff3 | ||
| 
						 | 
					770945cff4 | ||
| 
						 | 
					eaa4066bfc | ||
| 
						 | 
					46cf606cd3 | ||
| 
						 | 
					a69a7b9688 | ||
| 
						 | 
					eb7590a0d9 | ||
| 
						 | 
					86870a691c | ||
| 
						 | 
					7c34c237a2 | ||
| 
						 | 
					13cd4298fb | ||
| 
						 | 
					3b724f91c5 | ||
| 
						 | 
					2077f375c7 | ||
| 
						 | 
					055265b0a3 | ||
| 
						 | 
					3094adb3ca | ||
| 
						 | 
					7c7247ddbf | ||
| 
						 | 
					af2023e31c | ||
| 
						 | 
					2eedbc94c2 | ||
| 
						 | 
					672f6bb545 | ||
| 
						 | 
					ab6bcef99a | ||
| 
						 | 
					c5a4cfb03f | ||
| 
						 | 
					df944efdbf | ||
| 
						 | 
					1ff9cd5079 | ||
| 
						 | 
					4a2b54cbdb | ||
| 
						 | 
					6bd6a15ab3 | ||
| 
						 | 
					c1a5c9bb4c | ||
| 
						 | 
					b3c7dc6ff2 | ||
| 
						 | 
					a1025ec041 | ||
| 
						 | 
					3a4068474c | ||
| 
						 | 
					1ae976be4a | ||
| 
						 | 
					b685927156 | ||
| 
						 | 
					df0c8d029d | ||
| 
						 | 
					3477dc4c48 | ||
| 
						 | 
					0426bccadd | ||
| 
						 | 
					841333cd21 | ||
| 
						 | 
					e541dceb67 | ||
| 
						 | 
					fea7a70a1a | ||
| 
						 | 
					426f607aaa | ||
| 
						 | 
					408f32dc16 | ||
| 
						 | 
					94028edfc5 | ||
| 
						 | 
					7fec5f88a5 | ||
| 
						 | 
					67007670bb | ||
| 
						 | 
					e8865f199d | ||
| 
						 | 
					2d3262d47d | ||
| 
						 | 
					3470d821ba | ||
| 
						 | 
					0371956d66 | ||
| 
						 | 
					45c4addea7 | ||
| 
						 | 
					1eba0eb37d | ||
| 
						 | 
					d87fb5e003 | ||
| 
						 | 
					4be7922a8e | ||
| 
						 | 
					a1cac0732b | ||
| 
						 | 
					fb32e0fcc5 | ||
| 
						 | 
					9564a6fa13 | ||
| 
						 | 
					0b9990b2fd | ||
| 
						 | 
					8ce99c85e7 | ||
| 
						 | 
					a2c402ba53 | ||
| 
						 | 
					1ceb906c12 | ||
| 
						 | 
					fb1fe8e76f | ||
| 
						 | 
					f8b05566aa | ||
| 
						 | 
					a6148b8eba | ||
| 
						 | 
					64be837b0b | ||
| 
						 | 
					e070c1d183 | ||
| 
						 | 
					e6ee4b49c4 | ||
| 
						 | 
					e65029e9b3 | ||
| 
						 | 
					3ca6cb3440 | ||
| 
						 | 
					34b36277b7 | ||
| 
						 | 
					c8ea0212fe | ||
| 
						 | 
					7d6cbcdd9a | ||
| 
						 | 
					9d9c1f17dc | ||
| 
						 | 
					f1afb352da | ||
| 
						 | 
					e4c3abbf55 | ||
| 
						 | 
					141b5775c0 | ||
| 
						 | 
					c0d5f1d3ad | ||
| 
						 | 
					70947e531e | ||
| 
						 | 
					7b92cb45b2 | ||
| 
						 | 
					43e4b58422 | ||
| 
						 | 
					e0d01c9d7f | ||
| 
						 | 
					b90b3667a1 | ||
| 
						 | 
					0123a2d042 | ||
| 
						 | 
					51a2cc5499 | ||
| 
						 | 
					f5145a6ec3 | ||
| 
						 | 
					ddedfe12d4 | ||
| 
						 | 
					cb5447f79c | ||
| 
						 | 
					9fd3c74724 | ||
| 
						 | 
					4d1234e222 | ||
| 
						 | 
					3cba779e16 | ||
| 
						 | 
					23eda89ec8 | ||
| 
						 | 
					6e68898b05 | ||
| 
						 | 
					1befcd5a2a | ||
| 
						 | 
					12ba355978 | ||
| 
						 | 
					a0907a645f | ||
| 
						 | 
					1acf7a09e7 | ||
| 
						 | 
					14dc02a1b2 | ||
| 
						 | 
					88cf87bd56 | ||
| 
						 | 
					31b3420688 | ||
| 
						 | 
					4e95983fa8 | ||
| 
						 | 
					4e506eac8f | ||
| 
						 | 
					46167149ce | ||
| 
						 | 
					96ec4eb755 | ||
| 
						 | 
					e20547042c | ||
| 
						 | 
					0451d0fd01 | ||
| 
						 | 
					aa8b23e077 | ||
| 
						 | 
					4eb48a3af7 | ||
| 
						 | 
					8db8adfd01 | ||
| 
						 | 
					8e240d7e0e | ||
| 
						 | 
					40298bf272 | ||
| 
						 | 
					a0518e66b2 | ||
| 
						 | 
					82c76cd16f | ||
| 
						 | 
					50e890bc51 | ||
| 
						 | 
					bba9557019 | ||
| 
						 | 
					2041d3e4b7 | ||
| 
						 | 
					77b7b3a1ab | ||
| 
						 | 
					0dab80fbfb | ||
| 
						 | 
					e3257912e0 | ||
| 
						 | 
					15fe491822 | ||
| 
						 | 
					ac597f5acc | ||
| 
						 | 
					5cb255f0d7 | ||
| 
						 | 
					2f28ca0a27 | ||
| 
						 | 
					0580e488da | ||
| 
						 | 
					5435f790fd | 
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@@ -182,7 +182,7 @@ ultrix-gcc:
 | 
			
		||||
 | 
			
		||||
# Rules for making release tarballs
 | 
			
		||||
 | 
			
		||||
VERSION=7.7.1-devel
 | 
			
		||||
VERSION=7.7.1
 | 
			
		||||
DIRECTORY = Mesa-$(VERSION)
 | 
			
		||||
LIB_NAME = MesaLib-$(VERSION)
 | 
			
		||||
DEMO_NAME = MesaDemos-$(VERSION)
 | 
			
		||||
 
 | 
			
		||||
@@ -920,6 +920,11 @@ case $ARCH in
 | 
			
		||||
 | 
			
		||||
            # make lib
 | 
			
		||||
            ${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS}
 | 
			
		||||
            # make build fail if link failed
 | 
			
		||||
            es=$?
 | 
			
		||||
            if [ "$es" -ne "0" ]; then
 | 
			
		||||
                exit $es
 | 
			
		||||
            fi
 | 
			
		||||
            # make usual symlinks
 | 
			
		||||
            ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a
 | 
			
		||||
            # finish up
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								configure.ac
									
									
									
									
									
								
							@@ -20,6 +20,8 @@ AC_CANONICAL_HOST
 | 
			
		||||
dnl Versions for external dependencies
 | 
			
		||||
LIBDRM_REQUIRED=2.4.15
 | 
			
		||||
LIBDRM_RADEON_REQUIRED=2.4.17
 | 
			
		||||
LIBDRM_XORG_REQUIRED=2.4.17
 | 
			
		||||
LIBKMS_XORG_REQUIRED=1.0.0
 | 
			
		||||
DRI2PROTO_REQUIRED=1.99.3
 | 
			
		||||
 | 
			
		||||
dnl Check for progs
 | 
			
		||||
@@ -91,6 +93,9 @@ linux*|*-gnu*|gnu*)
 | 
			
		||||
solaris*)
 | 
			
		||||
    DEFINES="$DEFINES -DPTHREADS -DSVR4"
 | 
			
		||||
    ;;
 | 
			
		||||
cygwin*)
 | 
			
		||||
    DEFINES="$DEFINES -DPTHREADS"
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
dnl Add flags for gcc and g++
 | 
			
		||||
@@ -1149,7 +1154,7 @@ yes)
 | 
			
		||||
            GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
 | 
			
		||||
        fi
 | 
			
		||||
        # Have only tested st/xorg on 1.6.0 servers
 | 
			
		||||
        PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0],
 | 
			
		||||
        PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0 libdrm >= $LIBDRM_XORG_REQUIRED libkms >= $LIBKMS_XORG_REQUIRED],
 | 
			
		||||
            HAVE_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg",
 | 
			
		||||
            HAVE_XORG="no")
 | 
			
		||||
        ;;
 | 
			
		||||
@@ -1166,15 +1171,21 @@ yes)
 | 
			
		||||
            AC_MSG_ERROR([cannot build egl state tracker without EGL library])
 | 
			
		||||
        fi
 | 
			
		||||
        if test "$tracker" = xorg; then
 | 
			
		||||
	    PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
 | 
			
		||||
                  HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
 | 
			
		||||
                  HAVE_XEXTPROTO_71="no")
 | 
			
		||||
            PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
 | 
			
		||||
            PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
 | 
			
		||||
            HAVE_XORG="yes"
 | 
			
		||||
        fi
 | 
			
		||||
    done
 | 
			
		||||
    GALLIUM_STATE_TRACKERS_DIRS="$state_trackers"
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
if test "x$HAVE_XORG" = xyes; then
 | 
			
		||||
    PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
 | 
			
		||||
        HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
 | 
			
		||||
        HAVE_XEXTPROTO_71="no")
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH([xorg-driver-dir],
 | 
			
		||||
    [AS_HELP_STRING([--with-xorg-driver-dir=DIR],
 | 
			
		||||
                    [Default xorg driver directory[[default=${libdir}/xorg/modules/drivers]]])],
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,15 @@
 | 
			
		||||
 | 
			
		||||
<H1>News</H1>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>March 26, 2010</h2>
 | 
			
		||||
<p>
 | 
			
		||||
<a href="relnotes-7.7.1.html">Mesa 7.7.1</a> is released.  This is a bug-fix
 | 
			
		||||
release fixing issues found in the 7.7 release.
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>December 21, 2009</h2>
 | 
			
		||||
<p>
 | 
			
		||||
<a href="relnotes-7.6.1.html">Mesa 7.6.1</a> is released.  This is a bug-fix
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ more information about the API functions.
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
There are several examples of OSMesa in the <code>progs/osdemo/</code>
 | 
			
		||||
There are several examples of OSMesa in the <code>progs/osdemos/</code>
 | 
			
		||||
directory.
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#eeeeee">
 | 
			
		||||
 | 
			
		||||
<H1>Mesa 7.7.1 Release Notes / date tbd</H1>
 | 
			
		||||
<H1>Mesa 7.7.1 Release Notes / March 28, 2010</H1>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Mesa 7.7.1 is a bug-fix release.
 | 
			
		||||
@@ -26,16 +26,18 @@ for DRI hardware acceleration.
 | 
			
		||||
 | 
			
		||||
<h2>MD5 checksums</h2>
 | 
			
		||||
<pre>
 | 
			
		||||
tbd
 | 
			
		||||
3ab0638cfa7ce8157337a229cf0db2c4  MesaLib-7.7.1.tar.gz
 | 
			
		||||
46664d99e03f1e3ac078a7fea02af115  MesaLib-7.7.1.tar.bz2
 | 
			
		||||
4e73ba8abb59aff79485eb95d7cefff7  MesaLib-7.7.1.zip
 | 
			
		||||
bf1b108983995f7a712cf3343df1c918  MesaDemos-7.7.1.tar.gz
 | 
			
		||||
aeb39645d80d656e0adebaa09e5bcd03  MesaDemos-7.7.1.tar.bz2
 | 
			
		||||
01c49b7454fd292244eaf8bdc6ed8cf0  MesaDemos-7.7.1.zip
 | 
			
		||||
37ec6386693dcb6dc770d1efd63a7a93  MesaGLUT-7.7.1.tar.gz
 | 
			
		||||
1e16c85282f843791a21f7bc7b6a1ca8  MesaGLUT-7.7.1.tar.bz2
 | 
			
		||||
d352c9e36a8e4d1059f4abc017b131e0  MesaGLUT-7.7.1.zip
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>New features</h2>
 | 
			
		||||
<ul>
 | 
			
		||||
<li>tbd
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>Bug fixes</h2>
 | 
			
		||||
<ul>
 | 
			
		||||
<li>Assorted fixes to VMware SVGA gallium driver.
 | 
			
		||||
@@ -43,6 +45,14 @@ tbd
 | 
			
		||||
<li>Allocate constants more tightly in GL_ARB_vertex/fragment parser.
 | 
			
		||||
<li>Fixed mipmap generation bug caused by invalid viewport state.
 | 
			
		||||
<li>Gallium SSE codegen for XPD didn't always work.
 | 
			
		||||
<li>Fixed Windows build.
 | 
			
		||||
<li>Fixed broken glMultiDrawElements().
 | 
			
		||||
<li>Silence bogus GL errors generated in glxinfo.
 | 
			
		||||
<li>Fixed several render to texture bugs.
 | 
			
		||||
<li>Assorted bug fixes in Mesa/Gallium state tracker including
 | 
			
		||||
    glCopy/DrawPixels() to FBOs.
 | 
			
		||||
<li>Assorted fixes to Gallium drivers.
 | 
			
		||||
<li>Fixed broken glPush/PopClientAttrib() for vertex arrays in GLX code.
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<HTML>
 | 
			
		||||
 | 
			
		||||
<TITLE>Cocd Repository</TITLE>
 | 
			
		||||
<TITLE>Code Repository</TITLE>
 | 
			
		||||
 | 
			
		||||
<link rel="stylesheet" type="text/css" href="mesa.css"></head>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -171,7 +171,7 @@ print_program_limits(GLenum target)
 | 
			
		||||
      GLenum token;
 | 
			
		||||
      const char *name;
 | 
			
		||||
   };
 | 
			
		||||
   static const struct token_name limits[] = {
 | 
			
		||||
   static const struct token_name common_limits[] = {
 | 
			
		||||
      { GL_MAX_PROGRAM_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" },
 | 
			
		||||
      { GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" },
 | 
			
		||||
      { GL_MAX_PROGRAM_TEMPORARIES_ARB, "GL_MAX_PROGRAM_TEMPORARIES_ARB" },
 | 
			
		||||
@@ -184,6 +184,9 @@ print_program_limits(GLenum target)
 | 
			
		||||
      { GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" },
 | 
			
		||||
      { GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" },
 | 
			
		||||
      { GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" },
 | 
			
		||||
      { (GLenum) 0, NULL }
 | 
			
		||||
   };
 | 
			
		||||
   static const struct token_name fragment_limits[] = {
 | 
			
		||||
      { GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" },
 | 
			
		||||
      { GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" },
 | 
			
		||||
      { GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" },
 | 
			
		||||
@@ -192,8 +195,10 @@ print_program_limits(GLenum target)
 | 
			
		||||
      { GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" },
 | 
			
		||||
      { (GLenum) 0, NULL }
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   PFNGLGETPROGRAMIVARBPROC GetProgramivARB_func = (PFNGLGETPROGRAMIVARBPROC)
 | 
			
		||||
      glXGetProcAddressARB((GLubyte *) "glGetProgramivARB");
 | 
			
		||||
 | 
			
		||||
   GLint max[1];
 | 
			
		||||
   int i;
 | 
			
		||||
 | 
			
		||||
@@ -207,10 +212,18 @@ print_program_limits(GLenum target)
 | 
			
		||||
      return; /* something's wrong */
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   for (i = 0; limits[i].token; i++) {
 | 
			
		||||
      GetProgramivARB_func(target, limits[i].token, max);
 | 
			
		||||
   for (i = 0; common_limits[i].token; i++) {
 | 
			
		||||
      GetProgramivARB_func(target, common_limits[i].token, max);
 | 
			
		||||
      if (glGetError() == GL_NO_ERROR) {
 | 
			
		||||
         printf("        %s = %d\n", limits[i].name, max[0]);
 | 
			
		||||
         printf("        %s = %d\n", common_limits[i].name, max[0]);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
   if (target == GL_FRAGMENT_PROGRAM_ARB) {
 | 
			
		||||
      for (i = 0; fragment_limits[i].token; i++) {
 | 
			
		||||
         GetProgramivARB_func(target, fragment_limits[i].token, max);
 | 
			
		||||
         if (glGetError() == GL_NO_ERROR) {
 | 
			
		||||
            printf("        %s = %d\n", fragment_limits[i].name, max[0]);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
#endif /* GL_ARB_vertex_program / GL_ARB_fragment_program */
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@ prefixes = SCons.Util.Split("""
 | 
			
		||||
    i486-mingw32msvc-
 | 
			
		||||
    i586-mingw32msvc-
 | 
			
		||||
    i686-mingw32msvc-
 | 
			
		||||
    i686-pc-mingw32-
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
def find(env):
 | 
			
		||||
 
 | 
			
		||||
@@ -235,7 +235,9 @@ def generate(env):
 | 
			
		||||
    # different scons versions building the same source file
 | 
			
		||||
    env['build'] = build_dir
 | 
			
		||||
    env.SConsignFile(os.path.join(build_dir, '.sconsign'))
 | 
			
		||||
    env.CacheDir('build/cache')
 | 
			
		||||
    if 'SCONS_CACHE_DIR' in os.environ:
 | 
			
		||||
        print 'scons: Using build cache in %s.' % (os.environ['SCONS_CACHE_DIR'],)
 | 
			
		||||
        env.CacheDir(os.environ['SCONS_CACHE_DIR'])
 | 
			
		||||
 | 
			
		||||
    # Parallel build
 | 
			
		||||
    if env.GetOption('num_jobs') <= 1:
 | 
			
		||||
@@ -255,8 +257,9 @@ def generate(env):
 | 
			
		||||
            '_WINDOWS',
 | 
			
		||||
            #'_UNICODE',
 | 
			
		||||
            #'UNICODE',
 | 
			
		||||
            ('_WIN32_WINNT', '0x0501'), # minimum required OS version
 | 
			
		||||
            ('WINVER', '0x0501'),
 | 
			
		||||
            # http://msdn.microsoft.com/en-us/library/aa383745.aspx
 | 
			
		||||
            ('_WIN32_WINNT', '0x0601'),
 | 
			
		||||
            ('WINVER', '0x0601'),
 | 
			
		||||
            # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
 | 
			
		||||
            'WIN32_LEAN_AND_MEAN',
 | 
			
		||||
        ]
 | 
			
		||||
 
 | 
			
		||||
@@ -347,7 +347,8 @@ vcache_check_run( struct draw_pt_front_end *frontend,
 | 
			
		||||
                       draw_count);
 | 
			
		||||
      
 | 
			
		||||
   if (max_index == 0xffffffff ||
 | 
			
		||||
       fetch_count > draw_count) {
 | 
			
		||||
       fetch_count > draw_count ||
 | 
			
		||||
       max_index != (max_index & ~DRAW_PIPE_FLAG_MASK)) {
 | 
			
		||||
      if (0) debug_printf("fail\n");
 | 
			
		||||
      goto fail;
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
@@ -179,7 +179,9 @@ pb_debug_buffer_check(struct pb_debug_buffer *buf)
 | 
			
		||||
{
 | 
			
		||||
   uint8_t *map;
 | 
			
		||||
   
 | 
			
		||||
   map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ);
 | 
			
		||||
   map = pb_map(buf->buffer,
 | 
			
		||||
                PIPE_BUFFER_USAGE_CPU_READ |
 | 
			
		||||
                PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
 | 
			
		||||
   assert(map);
 | 
			
		||||
   if(map) {
 | 
			
		||||
      boolean underflow, overflow;
 | 
			
		||||
 
 | 
			
		||||
@@ -133,8 +133,7 @@ static const union tgsi_exec_channel ZeroVec =
 | 
			
		||||
   { { 0.0, 0.0, 0.0, 0.0 } };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
static void
 | 
			
		||||
static INLINE void
 | 
			
		||||
check_inf_or_nan(const union tgsi_exec_channel *chan)
 | 
			
		||||
{
 | 
			
		||||
   assert(!util_is_inf_or_nan(chan->f[0]));
 | 
			
		||||
@@ -142,7 +141,6 @@ check_inf_or_nan(const union tgsi_exec_channel *chan)
 | 
			
		||||
   assert(!util_is_inf_or_nan(chan->f[2]));
 | 
			
		||||
   assert(!util_is_inf_or_nan(chan->f[3]));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
@@ -338,7 +336,9 @@ tgsi_exec_machine_bind_shader(
 | 
			
		||||
            /* XXX we only handle SOA dependencies properly for MOV/SWZ
 | 
			
		||||
             * at this time!
 | 
			
		||||
             */
 | 
			
		||||
            if (opcode != TGSI_OPCODE_MOV) {
 | 
			
		||||
            if (opcode != TGSI_OPCODE_MOV &&
 | 
			
		||||
                opcode != TGSI_OPCODE_MUL &&
 | 
			
		||||
                opcode != TGSI_OPCODE_CMP) {
 | 
			
		||||
               debug_printf("Warning: SOA dependency in instruction"
 | 
			
		||||
                            " is not handled:\n");
 | 
			
		||||
               tgsi_dump_instruction(&parse.FullToken.FullInstruction,
 | 
			
		||||
@@ -1424,9 +1424,9 @@ store_dest(
 | 
			
		||||
   int offset = 0;  /* indirection offset */
 | 
			
		||||
   int index;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
   check_inf_or_nan(chan);
 | 
			
		||||
#endif
 | 
			
		||||
   if (0) {
 | 
			
		||||
      check_inf_or_nan(chan);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* There is an extra source register that indirectly subscripts
 | 
			
		||||
    * a register file. The direct index now becomes an offset
 | 
			
		||||
@@ -1854,7 +1854,8 @@ exec_instruction(
 | 
			
		||||
   int *pc )
 | 
			
		||||
{
 | 
			
		||||
   uint chan_index;
 | 
			
		||||
   union tgsi_exec_channel r[10];
 | 
			
		||||
   union tgsi_exec_channel r[3 * NUM_CHANNELS];
 | 
			
		||||
   union tgsi_exec_channel d[8];
 | 
			
		||||
 | 
			
		||||
   (*pc)++;
 | 
			
		||||
 | 
			
		||||
@@ -1981,14 +1982,27 @@ exec_instruction(
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
   case TGSI_OPCODE_MUL:
 | 
			
		||||
      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
 | 
			
		||||
      {
 | 
			
		||||
         FETCH(&r[0], 0, chan_index);
 | 
			
		||||
         FETCH(&r[1], 1, chan_index);
 | 
			
		||||
      if (inst->Flags & SOA_DEPENDENCY_FLAG) {
 | 
			
		||||
         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
 | 
			
		||||
         {
 | 
			
		||||
            FETCH(&r[chan_index], 0, chan_index);
 | 
			
		||||
            FETCH(&r[chan_index + NUM_CHANNELS], 1, chan_index);
 | 
			
		||||
         }
 | 
			
		||||
         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
 | 
			
		||||
         {
 | 
			
		||||
            micro_mul( &r[chan_index], &r[chan_index], &r[chan_index + NUM_CHANNELS] );
 | 
			
		||||
            STORE(&r[chan_index], 0, chan_index);
 | 
			
		||||
         }
 | 
			
		||||
      } else {
 | 
			
		||||
         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
 | 
			
		||||
         {
 | 
			
		||||
            FETCH(&r[0], 0, chan_index);
 | 
			
		||||
            FETCH(&r[1], 1, chan_index);
 | 
			
		||||
 | 
			
		||||
         micro_mul( &r[0], &r[0], &r[1] );
 | 
			
		||||
            micro_mul( &r[0], &r[0], &r[1] );
 | 
			
		||||
 | 
			
		||||
         STORE(&r[0], 0, chan_index);
 | 
			
		||||
            STORE(&r[0], 0, chan_index);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
@@ -2255,11 +2269,7 @@ exec_instruction(
 | 
			
		||||
      FETCH(&r[4], 1, CHAN_Y);
 | 
			
		||||
 | 
			
		||||
      micro_mul( &r[5], &r[3], &r[4] );
 | 
			
		||||
      micro_sub( &r[2], &r[2], &r[5] );
 | 
			
		||||
 | 
			
		||||
      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
 | 
			
		||||
         STORE( &r[2], 0, CHAN_X );
 | 
			
		||||
      }
 | 
			
		||||
      micro_sub(&d[CHAN_X], &r[2], &r[5]);
 | 
			
		||||
 | 
			
		||||
      FETCH(&r[2], 1, CHAN_X);
 | 
			
		||||
 | 
			
		||||
@@ -2268,26 +2278,27 @@ exec_instruction(
 | 
			
		||||
      FETCH(&r[5], 0, CHAN_X);
 | 
			
		||||
 | 
			
		||||
      micro_mul( &r[1], &r[1], &r[5] );
 | 
			
		||||
      micro_sub( &r[3], &r[3], &r[1] );
 | 
			
		||||
 | 
			
		||||
      if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
 | 
			
		||||
         STORE( &r[3], 0, CHAN_Y );
 | 
			
		||||
      }
 | 
			
		||||
      micro_sub(&d[CHAN_Y], &r[3], &r[1]);
 | 
			
		||||
 | 
			
		||||
      micro_mul( &r[5], &r[5], &r[4] );
 | 
			
		||||
      micro_mul( &r[0], &r[0], &r[2] );
 | 
			
		||||
      micro_sub( &r[5], &r[5], &r[0] );
 | 
			
		||||
      micro_sub(&d[CHAN_Z], &r[5], &r[0]);
 | 
			
		||||
 | 
			
		||||
      if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
 | 
			
		||||
         STORE( &r[5], 0, CHAN_Z );
 | 
			
		||||
      if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) {
 | 
			
		||||
         STORE(&d[CHAN_X], 0, CHAN_X);
 | 
			
		||||
      }
 | 
			
		||||
      if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
 | 
			
		||||
         STORE(&d[CHAN_Y], 0, CHAN_Y);
 | 
			
		||||
      }
 | 
			
		||||
      if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
 | 
			
		||||
         STORE(&d[CHAN_Z], 0, CHAN_Z);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
 | 
			
		||||
         STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case TGSI_OPCODE_ABS:
 | 
			
		||||
   case TGSI_OPCODE_ABS:
 | 
			
		||||
       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
 | 
			
		||||
          FETCH(&r[0], 0, chan_index);
 | 
			
		||||
 | 
			
		||||
@@ -2667,14 +2678,28 @@ exec_instruction(
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
   case TGSI_OPCODE_CMP:
 | 
			
		||||
      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
 | 
			
		||||
         FETCH(&r[0], 0, chan_index);
 | 
			
		||||
         FETCH(&r[1], 1, chan_index);
 | 
			
		||||
         FETCH(&r[2], 2, chan_index);
 | 
			
		||||
      if (inst->Flags & SOA_DEPENDENCY_FLAG) {
 | 
			
		||||
         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
 | 
			
		||||
            FETCH(&r[chan_index], 0, chan_index);
 | 
			
		||||
            FETCH(&r[chan_index + NUM_CHANNELS], 1, chan_index);
 | 
			
		||||
            FETCH(&r[chan_index + 2 * NUM_CHANNELS], 2, chan_index);
 | 
			
		||||
         }
 | 
			
		||||
         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
 | 
			
		||||
            micro_lt( &r[chan_index], &r[chan_index],
 | 
			
		||||
                      &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[chan_index + NUM_CHANNELS],
 | 
			
		||||
                      &r[chan_index + 2*NUM_CHANNELS] );
 | 
			
		||||
            STORE(&r[chan_index], 0, chan_index);
 | 
			
		||||
         }
 | 
			
		||||
      } else {
 | 
			
		||||
         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
 | 
			
		||||
            FETCH(&r[0], 0, chan_index);
 | 
			
		||||
            FETCH(&r[1], 1, chan_index);
 | 
			
		||||
            FETCH(&r[2], 2, chan_index);
 | 
			
		||||
 | 
			
		||||
         micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
 | 
			
		||||
            micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
 | 
			
		||||
 | 
			
		||||
         STORE(&r[0], 0, chan_index);
 | 
			
		||||
            STORE(&r[0], 0, chan_index);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -216,6 +216,9 @@ iter_instruction(
 | 
			
		||||
         inst->FullDstRegisters[i].DstRegister.Index,
 | 
			
		||||
         "destination",
 | 
			
		||||
         FALSE );
 | 
			
		||||
      if (!inst->FullDstRegisters[i].DstRegister.WriteMask) {
 | 
			
		||||
         report_error(ctx, "Destination register has empty writemask");
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
   for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
 | 
			
		||||
      check_register_usage(
 | 
			
		||||
 
 | 
			
		||||
@@ -644,6 +644,57 @@ void debug_dump_image(const char *prefix,
 | 
			
		||||
   }
 | 
			
		||||
      
 | 
			
		||||
   EngUnmapFile(iFile);
 | 
			
		||||
#elif defined(PIPE_OS_UNIX)
 | 
			
		||||
   /* write a ppm file */
 | 
			
		||||
   char filename[256];
 | 
			
		||||
   FILE *f;
 | 
			
		||||
 | 
			
		||||
   util_snprintf(filename, sizeof(filename), "%s.ppm", prefix);
 | 
			
		||||
 | 
			
		||||
   f = fopen(filename, "w");
 | 
			
		||||
   if (f) {
 | 
			
		||||
      int i, x, y;
 | 
			
		||||
      int r, g, b;
 | 
			
		||||
      const uint8_t *ptr = (uint8_t *) data;
 | 
			
		||||
 | 
			
		||||
      /* XXX this is a hack */
 | 
			
		||||
      switch (format) {
 | 
			
		||||
      case PIPE_FORMAT_B8G8R8A8_UNORM:
 | 
			
		||||
         r = 2;
 | 
			
		||||
         g = 1;
 | 
			
		||||
         b = 0;
 | 
			
		||||
         break;
 | 
			
		||||
      case PIPE_FORMAT_A8R8G8B8_UNORM:
 | 
			
		||||
         b = 0;
 | 
			
		||||
         g = 1;
 | 
			
		||||
         r = 2;
 | 
			
		||||
         break;
 | 
			
		||||
      default:
 | 
			
		||||
         r = 0;
 | 
			
		||||
         g = 1;
 | 
			
		||||
         b = 2;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      fprintf(f, "P6\n");
 | 
			
		||||
      fprintf(f, "# ppm-file created by osdemo.c\n");
 | 
			
		||||
      fprintf(f, "%i %i\n", width, height);
 | 
			
		||||
      fprintf(f, "255\n");
 | 
			
		||||
      fclose(f);
 | 
			
		||||
 | 
			
		||||
      f = fopen(filename, "ab");  /* reopen in binary append mode */
 | 
			
		||||
      for (y = 0; y < height; y++) {
 | 
			
		||||
         for (x = 0; x < width; x++) {
 | 
			
		||||
            i = y * stride + x * cpp;
 | 
			
		||||
            fputc(ptr[i + r], f); /* write red */
 | 
			
		||||
            fputc(ptr[i + g], f); /* write green */
 | 
			
		||||
            fputc(ptr[i + b], f); /* write blue */
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      fclose(f);
 | 
			
		||||
   }
 | 
			
		||||
   else {
 | 
			
		||||
      fprintf(stderr, "Can't open %s for writing\n", filename);
 | 
			
		||||
   }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -628,7 +628,8 @@ lp_build_abs(struct lp_build_context *bld,
 | 
			
		||||
   if(type.floating) {
 | 
			
		||||
      /* Mask out the sign bit */
 | 
			
		||||
      LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
 | 
			
		||||
      LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long)1 << type.width) - 1);
 | 
			
		||||
      unsigned long absMask = ~(1 << (type.width - 1));
 | 
			
		||||
      LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
 | 
			
		||||
      a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
 | 
			
		||||
      a = LLVMBuildAnd(bld->builder, a, mask, "");
 | 
			
		||||
      a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
 | 
			
		||||
@@ -1082,7 +1083,7 @@ lp_build_log(struct lp_build_context *bld,
 | 
			
		||||
             LLVMValueRef x)
 | 
			
		||||
{
 | 
			
		||||
   /* log(2) */
 | 
			
		||||
   LLVMValueRef log2 = lp_build_const_scalar(bld->type, 1.4426950408889634);
 | 
			
		||||
   LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
 | 
			
		||||
 | 
			
		||||
   return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
 | 
			
		||||
}
 | 
			
		||||
@@ -1094,7 +1095,7 @@ lp_build_log(struct lp_build_context *bld,
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate polynomial.
 | 
			
		||||
 * Ex:  x^2 * coeffs[0] + x * coeffs[1] + coeffs[2].
 | 
			
		||||
 * Ex:  coeffs[0] + x * coeffs[1] + x^2 * coeffs[2].
 | 
			
		||||
 */
 | 
			
		||||
static LLVMValueRef
 | 
			
		||||
lp_build_polynomial(struct lp_build_context *bld,
 | 
			
		||||
@@ -1284,13 +1285,13 @@ lp_build_log2_approx(struct lp_build_context *bld,
 | 
			
		||||
      /* mant = (float) mantissa(x) */
 | 
			
		||||
      mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
 | 
			
		||||
      mant = LLVMBuildOr(bld->builder, mant, one, "");
 | 
			
		||||
      mant = LLVMBuildSIToFP(bld->builder, mant, vec_type, "");
 | 
			
		||||
      mant = LLVMBuildBitCast(bld->builder, mant, vec_type, "");
 | 
			
		||||
 | 
			
		||||
      logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
 | 
			
		||||
                                    Elements(lp_build_log2_polynomial));
 | 
			
		||||
 | 
			
		||||
      /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
 | 
			
		||||
      logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildMul(bld->builder, mant, bld->one, ""), "");
 | 
			
		||||
      logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
 | 
			
		||||
 | 
			
		||||
      res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
@@ -766,7 +766,7 @@ emit_instruction(
 | 
			
		||||
      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
 | 
			
		||||
         src0 = emit_fetch( bld, inst, 0, chan_index );
 | 
			
		||||
         tmp0 = lp_build_floor(&bld->base, src0);
 | 
			
		||||
         tmp0 = lp_build_sub(&bld->base, tmp0, src0);
 | 
			
		||||
         tmp0 = lp_build_sub(&bld->base, src0, tmp0);
 | 
			
		||||
         dst0[chan_index] = tmp0;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								src/gallium/drivers/llvmpipe/lp_debug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/gallium/drivers/llvmpipe/lp_debug.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
/**************************************************************************
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
 | 
			
		||||
 * 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, sub license, 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 NON-INFRINGEMENT.
 | 
			
		||||
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
 | 
			
		||||
 * 
 | 
			
		||||
 **************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef LP_DEBUG_H
 | 
			
		||||
#define LP_DEBUG_H
 | 
			
		||||
 | 
			
		||||
#include "pipe/p_compiler.h"
 | 
			
		||||
#include "util/u_debug.h"
 | 
			
		||||
 | 
			
		||||
extern void
 | 
			
		||||
st_print_current(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define DEBUG_PIPE      0x1
 | 
			
		||||
#define DEBUG_TGSI      0x2
 | 
			
		||||
#define DEBUG_TEX       0x4
 | 
			
		||||
#define DEBUG_ASM       0x8
 | 
			
		||||
#define DEBUG_SETUP     0x10
 | 
			
		||||
#define DEBUG_RAST      0x20
 | 
			
		||||
#define DEBUG_QUERY     0x40
 | 
			
		||||
#define DEBUG_SCREEN    0x80
 | 
			
		||||
#define DEBUG_JIT       0x100
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
extern int LP_DEBUG;
 | 
			
		||||
#else
 | 
			
		||||
#define LP_DEBUG 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void st_debug_init( void );
 | 
			
		||||
 | 
			
		||||
static INLINE void
 | 
			
		||||
LP_DBG( unsigned flag, const char *fmt, ... )
 | 
			
		||||
{
 | 
			
		||||
    if (LP_DEBUG & flag)
 | 
			
		||||
    {
 | 
			
		||||
        va_list args;
 | 
			
		||||
 | 
			
		||||
        va_start( args, fmt );
 | 
			
		||||
        debug_vprintf( fmt, args );
 | 
			
		||||
        va_end( args );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* LP_DEBUG_H */
 | 
			
		||||
@@ -101,7 +101,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
 | 
			
		||||
   draw_arrays(draw, mode, start, count);
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
    * unmap vertex/index buffers - will cause draw module to flush
 | 
			
		||||
    * unmap vertex/index buffers
 | 
			
		||||
    */
 | 
			
		||||
   for (i = 0; i < lp->num_vertex_buffers; i++) {
 | 
			
		||||
      draw_set_mapped_vertex_buffer(draw, i, NULL);
 | 
			
		||||
@@ -110,6 +110,12 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
 | 
			
		||||
      draw_set_mapped_element_buffer(draw, 0, NULL);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
    * TODO: Flush only when a user vertex/index buffer is present
 | 
			
		||||
    * (or even better, modify draw module to do this
 | 
			
		||||
    * internally when this condition is seen?)
 | 
			
		||||
    */
 | 
			
		||||
   draw_flush(draw);
 | 
			
		||||
 | 
			
		||||
   /* Note: leave drawing surfaces mapped */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -166,7 +166,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen)
 | 
			
		||||
   if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) {
 | 
			
		||||
      _debug_printf("%s\n", error);
 | 
			
		||||
      LLVMDisposeMessage(error);
 | 
			
		||||
      abort();
 | 
			
		||||
      assert(0);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   screen->target = LLVMGetExecutionEngineTargetData(screen->engine);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "util/u_memory.h"
 | 
			
		||||
#include "util/u_format.h"
 | 
			
		||||
#include "pipe/p_defines.h"
 | 
			
		||||
#include "pipe/p_screen.h"
 | 
			
		||||
 | 
			
		||||
@@ -35,6 +36,24 @@
 | 
			
		||||
#include "lp_winsys.h"
 | 
			
		||||
#include "lp_jit.h"
 | 
			
		||||
#include "lp_screen.h"
 | 
			
		||||
#include "lp_debug.h"
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
int LP_DEBUG = 0;
 | 
			
		||||
 | 
			
		||||
static const struct debug_named_value lp_debug_flags[] = {
 | 
			
		||||
   { "pipe",   DEBUG_PIPE },
 | 
			
		||||
   { "tgsi",   DEBUG_TGSI },
 | 
			
		||||
   { "tex",    DEBUG_TEX },
 | 
			
		||||
   { "asm",    DEBUG_ASM },
 | 
			
		||||
   { "setup",  DEBUG_SETUP },
 | 
			
		||||
   { "rast",   DEBUG_RAST },
 | 
			
		||||
   { "query",  DEBUG_QUERY },
 | 
			
		||||
   { "screen", DEBUG_SCREEN },
 | 
			
		||||
   { "jit",    DEBUG_JIT },
 | 
			
		||||
   {NULL, 0}
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
@@ -131,17 +150,17 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
 | 
			
		||||
{
 | 
			
		||||
   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
 | 
			
		||||
   struct llvmpipe_winsys *winsys = screen->winsys;
 | 
			
		||||
   const struct util_format_description *format_desc;
 | 
			
		||||
 | 
			
		||||
   format_desc = util_format_description(format);
 | 
			
		||||
   if(!format_desc)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   assert(target == PIPE_TEXTURE_1D ||
 | 
			
		||||
          target == PIPE_TEXTURE_2D ||
 | 
			
		||||
          target == PIPE_TEXTURE_3D ||
 | 
			
		||||
          target == PIPE_TEXTURE_CUBE);
 | 
			
		||||
 | 
			
		||||
   if(format == PIPE_FORMAT_Z16_UNORM)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
   if(format == PIPE_FORMAT_S8_UNORM)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   switch(format) {
 | 
			
		||||
   case PIPE_FORMAT_DXT1_RGB:
 | 
			
		||||
   case PIPE_FORMAT_DXT1_RGBA:
 | 
			
		||||
@@ -152,8 +171,51 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
 | 
			
		||||
      break;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
 | 
			
		||||
      return winsys->is_displaytarget_format_supported(winsys, format);
 | 
			
		||||
   if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
 | 
			
		||||
      if(format_desc->block.width != 1 ||
 | 
			
		||||
         format_desc->block.height != 1)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
 | 
			
		||||
         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
 | 
			
		||||
         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
 | 
			
		||||
         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
 | 
			
		||||
      if(!winsys->is_displaytarget_format_supported(winsys, format))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
 | 
			
		||||
      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      /* FIXME: Temporary restriction. See lp_state_fs.c. */
 | 
			
		||||
      if(format_desc->block.bits != 32)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */
 | 
			
		||||
   if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) {
 | 
			
		||||
      if(format_desc->block.width != 1 ||
 | 
			
		||||
         format_desc->block.height != 1)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
 | 
			
		||||
         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
 | 
			
		||||
         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
 | 
			
		||||
         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
 | 
			
		||||
         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -213,6 +275,10 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
 | 
			
		||||
{
 | 
			
		||||
   struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
   LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   if (!screen)
 | 
			
		||||
      return NULL;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@
 | 
			
		||||
#include "util/u_memory.h"
 | 
			
		||||
#include "util/u_math.h"
 | 
			
		||||
#include "util/u_debug_dump.h"
 | 
			
		||||
#include "draw/draw_context.h"
 | 
			
		||||
#include "lp_screen.h"
 | 
			
		||||
#include "lp_context.h"
 | 
			
		||||
#include "lp_state.h"
 | 
			
		||||
@@ -51,6 +52,11 @@ void llvmpipe_bind_blend_state( struct pipe_context *pipe,
 | 
			
		||||
{
 | 
			
		||||
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   if (llvmpipe->blend == blend)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   draw_flush(llvmpipe->draw);
 | 
			
		||||
 | 
			
		||||
   llvmpipe->blend = blend;
 | 
			
		||||
 | 
			
		||||
   llvmpipe->dirty |= LP_NEW_BLEND;
 | 
			
		||||
@@ -69,6 +75,11 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe,
 | 
			
		||||
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 | 
			
		||||
   unsigned i, j;
 | 
			
		||||
 | 
			
		||||
   if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   draw_flush(llvmpipe->draw);
 | 
			
		||||
 | 
			
		||||
   memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color);
 | 
			
		||||
 | 
			
		||||
   if(!llvmpipe->jit_context.blend_color)
 | 
			
		||||
@@ -99,7 +110,12 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
 | 
			
		||||
{
 | 
			
		||||
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
 | 
			
		||||
   if (llvmpipe->depth_stencil == depth_stencil)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   draw_flush(llvmpipe->draw);
 | 
			
		||||
 | 
			
		||||
   llvmpipe->depth_stencil = depth_stencil;
 | 
			
		||||
 | 
			
		||||
   if(llvmpipe->depth_stencil)
 | 
			
		||||
      llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value;
 | 
			
		||||
 
 | 
			
		||||
@@ -85,6 +85,7 @@
 | 
			
		||||
#include "lp_buffer.h"
 | 
			
		||||
#include "lp_state.h"
 | 
			
		||||
#include "lp_tex_sample.h"
 | 
			
		||||
#include "lp_debug.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
 | 
			
		||||
@@ -146,6 +147,20 @@ generate_depth(LLVMBuilderRef builder,
 | 
			
		||||
   format_desc = util_format_description(key->zsbuf_format);
 | 
			
		||||
   assert(format_desc);
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
    * Depths are expected to be between 0 and 1, even if they are stored in
 | 
			
		||||
    * floats. Setting these bits here will ensure that the lp_build_conv() call
 | 
			
		||||
    * below won't try to unnecessarily clamp the incoming values.
 | 
			
		||||
    */
 | 
			
		||||
   if(src_type.floating) {
 | 
			
		||||
      src_type.sign = FALSE;
 | 
			
		||||
      src_type.norm = TRUE;
 | 
			
		||||
   }
 | 
			
		||||
   else {
 | 
			
		||||
      assert(!src_type.sign);
 | 
			
		||||
      assert(src_type.norm);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* Pick the depth type. */
 | 
			
		||||
   dst_type = lp_depth_type(format_desc, src_type.width*src_type.length);
 | 
			
		||||
 | 
			
		||||
@@ -153,14 +168,11 @@ generate_depth(LLVMBuilderRef builder,
 | 
			
		||||
   assert(dst_type.width == src_type.width);
 | 
			
		||||
   assert(dst_type.length == src_type.length);
 | 
			
		||||
 | 
			
		||||
#if 1
 | 
			
		||||
   src = lp_build_clamped_float_to_unsigned_norm(builder,
 | 
			
		||||
                                                 src_type,
 | 
			
		||||
                                                 dst_type.width,
 | 
			
		||||
                                                 src);
 | 
			
		||||
#else
 | 
			
		||||
   lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   dst_ptr = LLVMBuildBitCast(builder,
 | 
			
		||||
                              dst_ptr,
 | 
			
		||||
                              LLVMPointerType(lp_build_vec_type(dst_type), 0), "");
 | 
			
		||||
 | 
			
		||||
   lp_build_depth_test(builder,
 | 
			
		||||
                       &key->depth,
 | 
			
		||||
@@ -395,59 +407,58 @@ generate_fragment(struct llvmpipe_context *lp,
 | 
			
		||||
   unsigned i;
 | 
			
		||||
   unsigned chan;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
   tgsi_dump(shader->base.tokens, 0);
 | 
			
		||||
   if(key->depth.enabled) {
 | 
			
		||||
      debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
 | 
			
		||||
      debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
 | 
			
		||||
      debug_printf("depth.writemask = %u\n", key->depth.writemask);
 | 
			
		||||
   }
 | 
			
		||||
   if(key->alpha.enabled) {
 | 
			
		||||
      debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
 | 
			
		||||
      debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
 | 
			
		||||
   }
 | 
			
		||||
   if(key->blend.logicop_enable) {
 | 
			
		||||
      debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
 | 
			
		||||
   }
 | 
			
		||||
   else if(key->blend.blend_enable) {
 | 
			
		||||
      debug_printf("blend.rgb_func = %s\n",   debug_dump_blend_func  (key->blend.rgb_func, TRUE));
 | 
			
		||||
      debug_printf("rgb_src_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
 | 
			
		||||
      debug_printf("rgb_dst_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
 | 
			
		||||
      debug_printf("alpha_func = %s\n",       debug_dump_blend_func  (key->blend.alpha_func, TRUE));
 | 
			
		||||
      debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
 | 
			
		||||
      debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
 | 
			
		||||
   }
 | 
			
		||||
   debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
 | 
			
		||||
   for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
 | 
			
		||||
      if(key->sampler[i].format) {
 | 
			
		||||
         debug_printf("sampler[%u] = \n", i);
 | 
			
		||||
         debug_printf("  .format = %s\n",
 | 
			
		||||
                      pf_name(key->sampler[i].format));
 | 
			
		||||
         debug_printf("  .target = %s\n",
 | 
			
		||||
                      debug_dump_tex_target(key->sampler[i].target, TRUE));
 | 
			
		||||
         debug_printf("  .pot = %u %u %u\n",
 | 
			
		||||
                      key->sampler[i].pot_width,
 | 
			
		||||
                      key->sampler[i].pot_height,
 | 
			
		||||
                      key->sampler[i].pot_depth);
 | 
			
		||||
         debug_printf("  .wrap = %s %s %s\n",
 | 
			
		||||
                      debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
 | 
			
		||||
                      debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
 | 
			
		||||
                      debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
 | 
			
		||||
         debug_printf("  .min_img_filter = %s\n",
 | 
			
		||||
                      debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
 | 
			
		||||
         debug_printf("  .min_mip_filter = %s\n",
 | 
			
		||||
                      debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
 | 
			
		||||
         debug_printf("  .mag_img_filter = %s\n",
 | 
			
		||||
                      debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
 | 
			
		||||
         if(key->sampler[i].compare_mode)
 | 
			
		||||
            debug_printf("  .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
 | 
			
		||||
         debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
 | 
			
		||||
         debug_printf("  .prefilter = %u\n", key->sampler[i].prefilter);
 | 
			
		||||
   if (LP_DEBUG & DEBUG_JIT) {
 | 
			
		||||
      tgsi_dump(shader->base.tokens, 0);
 | 
			
		||||
      if(key->depth.enabled) {
 | 
			
		||||
         debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
 | 
			
		||||
         debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
 | 
			
		||||
         debug_printf("depth.writemask = %u\n", key->depth.writemask);
 | 
			
		||||
      }
 | 
			
		||||
      if(key->alpha.enabled) {
 | 
			
		||||
         debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
 | 
			
		||||
         debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
 | 
			
		||||
      }
 | 
			
		||||
      if(key->blend.logicop_enable) {
 | 
			
		||||
         debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
 | 
			
		||||
      }
 | 
			
		||||
      else if(key->blend.blend_enable) {
 | 
			
		||||
         debug_printf("blend.rgb_func = %s\n",   debug_dump_blend_func  (key->blend.rgb_func, TRUE));
 | 
			
		||||
         debug_printf("rgb_src_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
 | 
			
		||||
         debug_printf("rgb_dst_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
 | 
			
		||||
         debug_printf("alpha_func = %s\n",       debug_dump_blend_func  (key->blend.alpha_func, TRUE));
 | 
			
		||||
         debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
 | 
			
		||||
         debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
 | 
			
		||||
      }
 | 
			
		||||
      debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
 | 
			
		||||
      for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
 | 
			
		||||
         if(key->sampler[i].format) {
 | 
			
		||||
            debug_printf("sampler[%u] = \n", i);
 | 
			
		||||
            debug_printf("  .format = %s\n",
 | 
			
		||||
                         pf_name(key->sampler[i].format));
 | 
			
		||||
            debug_printf("  .target = %s\n",
 | 
			
		||||
                         debug_dump_tex_target(key->sampler[i].target, TRUE));
 | 
			
		||||
            debug_printf("  .pot = %u %u %u\n",
 | 
			
		||||
                         key->sampler[i].pot_width,
 | 
			
		||||
                         key->sampler[i].pot_height,
 | 
			
		||||
                         key->sampler[i].pot_depth);
 | 
			
		||||
            debug_printf("  .wrap = %s %s %s\n",
 | 
			
		||||
                         debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
 | 
			
		||||
                         debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
 | 
			
		||||
                         debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
 | 
			
		||||
            debug_printf("  .min_img_filter = %s\n",
 | 
			
		||||
                         debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
 | 
			
		||||
            debug_printf("  .min_mip_filter = %s\n",
 | 
			
		||||
                         debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
 | 
			
		||||
            debug_printf("  .mag_img_filter = %s\n",
 | 
			
		||||
                         debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
 | 
			
		||||
            if(key->sampler[i].compare_mode)
 | 
			
		||||
               debug_printf("  .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
 | 
			
		||||
            debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
 | 
			
		||||
            debug_printf("  .prefilter = %u\n", key->sampler[i].prefilter);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   variant = CALLOC_STRUCT(lp_fragment_shader_variant);
 | 
			
		||||
   if(!variant)
 | 
			
		||||
      return NULL;
 | 
			
		||||
@@ -586,8 +597,8 @@ generate_fragment(struct llvmpipe_context *lp,
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   lp_build_conv_mask(builder, fs_type, blend_type,
 | 
			
		||||
                               fs_mask, num_fs,
 | 
			
		||||
                               &blend_mask, 1);
 | 
			
		||||
                      fs_mask, num_fs,
 | 
			
		||||
                      &blend_mask, 1);
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
    * Blending.
 | 
			
		||||
@@ -609,23 +620,24 @@ generate_fragment(struct llvmpipe_context *lp,
 | 
			
		||||
    * Translate the LLVM IR into machine code.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
   if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) {
 | 
			
		||||
      LLVMDumpValue(variant->function);
 | 
			
		||||
      abort();
 | 
			
		||||
      assert(0);
 | 
			
		||||
   }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   LLVMRunFunctionPassManager(screen->pass, variant->function);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
   LLVMDumpValue(variant->function);
 | 
			
		||||
   debug_printf("\n");
 | 
			
		||||
#endif
 | 
			
		||||
   if (LP_DEBUG & DEBUG_JIT) {
 | 
			
		||||
      LLVMDumpValue(variant->function);
 | 
			
		||||
      debug_printf("\n");
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
   lp_disassemble(variant->jit_function);
 | 
			
		||||
#endif
 | 
			
		||||
   if (LP_DEBUG & DEBUG_ASM)
 | 
			
		||||
      lp_disassemble(variant->jit_function);
 | 
			
		||||
 | 
			
		||||
   variant->next = shader->variants;
 | 
			
		||||
   shader->variants = variant;
 | 
			
		||||
@@ -659,7 +671,12 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
 | 
			
		||||
{
 | 
			
		||||
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   llvmpipe->fs = (struct lp_fragment_shader *) fs;
 | 
			
		||||
   if (llvmpipe->fs == fs)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   draw_flush(llvmpipe->draw);
 | 
			
		||||
 | 
			
		||||
   llvmpipe->fs = fs;
 | 
			
		||||
 | 
			
		||||
   llvmpipe->dirty |= LP_NEW_FS;
 | 
			
		||||
}
 | 
			
		||||
@@ -710,8 +727,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
 | 
			
		||||
   assert(shader < PIPE_SHADER_TYPES);
 | 
			
		||||
   assert(index == 0);
 | 
			
		||||
 | 
			
		||||
   if(shader == PIPE_SHADER_VERTEX)
 | 
			
		||||
      draw_flush(llvmpipe->draw);
 | 
			
		||||
   draw_flush(llvmpipe->draw);
 | 
			
		||||
 | 
			
		||||
   /* note: reference counting */
 | 
			
		||||
   pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer);
 | 
			
		||||
 
 | 
			
		||||
@@ -41,14 +41,17 @@ llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
 | 
			
		||||
                                    void *setup)
 | 
			
		||||
                                    void *rasterizer)
 | 
			
		||||
{
 | 
			
		||||
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   /* pass-through to draw module */
 | 
			
		||||
   draw_set_rasterizer_state(llvmpipe->draw, setup);
 | 
			
		||||
   if (llvmpipe->rasterizer == rasterizer)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   llvmpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
 | 
			
		||||
   /* pass-through to draw module */
 | 
			
		||||
   draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
 | 
			
		||||
 | 
			
		||||
   llvmpipe->rasterizer = rasterizer;
 | 
			
		||||
 | 
			
		||||
   llvmpipe->dirty |= LP_NEW_RASTERIZER;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,8 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
 | 
			
		||||
   struct llvmpipe_context *lp = llvmpipe_context(pipe);
 | 
			
		||||
   uint i;
 | 
			
		||||
 | 
			
		||||
   draw_flush(lp->draw);
 | 
			
		||||
 | 
			
		||||
   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
 | 
			
		||||
      /* check if changing cbuf */
 | 
			
		||||
      if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) {
 | 
			
		||||
 
 | 
			
		||||
@@ -70,14 +70,18 @@ fail:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
 | 
			
		||||
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
 | 
			
		||||
{
 | 
			
		||||
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 | 
			
		||||
   const struct lp_vertex_shader *vs = (const struct lp_vertex_shader *)_vs;
 | 
			
		||||
 | 
			
		||||
   llvmpipe->vs = (const struct lp_vertex_shader *)vs;
 | 
			
		||||
   if (llvmpipe->vs == vs)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   draw_bind_vertex_shader(llvmpipe->draw,
 | 
			
		||||
                           (llvmpipe->vs ? llvmpipe->vs->draw_data : NULL));
 | 
			
		||||
   draw_bind_vertex_shader(llvmpipe->draw, 
 | 
			
		||||
                           vs ? vs->draw_data : NULL);
 | 
			
		||||
 | 
			
		||||
   llvmpipe->vs = vs;
 | 
			
		||||
 | 
			
		||||
   llvmpipe->dirty |= LP_NEW_VS;
 | 
			
		||||
}
 | 
			
		||||
@@ -92,5 +96,6 @@ llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
 | 
			
		||||
      (struct lp_vertex_shader *)vs;
 | 
			
		||||
 | 
			
		||||
   draw_delete_vertex_shader(llvmpipe->draw, state->draw_data);
 | 
			
		||||
   FREE( (void *)state->shader.tokens );
 | 
			
		||||
   FREE( state );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -714,9 +714,14 @@ depth_test_quads_fallback(struct quad_stage *qs,
 | 
			
		||||
      qs->next->run(qs->next, quads, nr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* XXX: this function assumes setup function actually emits linear
 | 
			
		||||
 * spans of quads.  It seems a lot more natural to do (early)
 | 
			
		||||
 * depth-testing on spans rather than quads.
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LESS and
 | 
			
		||||
 * Z buffer writes enabled.
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: there's no guarantee that the quads are sequentially side by
 | 
			
		||||
 * side.  The fragment shader may have culled some quads, etc.  Sliver
 | 
			
		||||
 * triangles may generate non-sequential quads.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
depth_interp_z16_less_write(struct quad_stage *qs, 
 | 
			
		||||
@@ -733,25 +738,33 @@ depth_interp_z16_less_write(struct quad_stage *qs,
 | 
			
		||||
   const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
 | 
			
		||||
   struct softpipe_cached_tile *tile;
 | 
			
		||||
   ushort (*depth16)[TILE_SIZE];
 | 
			
		||||
   ushort idepth[4], depth_step;
 | 
			
		||||
   ushort init_idepth[4], idepth[4], depth_step;
 | 
			
		||||
   const float scale = 65535.0;
 | 
			
		||||
 | 
			
		||||
   idepth[0] = (ushort)((z0) * scale);
 | 
			
		||||
   idepth[1] = (ushort)((z0 + dzdx) * scale);
 | 
			
		||||
   idepth[2] = (ushort)((z0 + dzdy) * scale);
 | 
			
		||||
   idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
 | 
			
		||||
   /* compute scaled depth of the four pixels in first quad */
 | 
			
		||||
   init_idepth[0] = (ushort)((z0) * scale);
 | 
			
		||||
   init_idepth[1] = (ushort)((z0 + dzdx) * scale);
 | 
			
		||||
   init_idepth[2] = (ushort)((z0 + dzdy) * scale);
 | 
			
		||||
   init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
 | 
			
		||||
 | 
			
		||||
   depth_step = (ushort)(dzdx * 2 * scale);
 | 
			
		||||
   depth_step = (ushort)(dzdx * scale);
 | 
			
		||||
 | 
			
		||||
   tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
 | 
			
		||||
 | 
			
		||||
   depth16 = (ushort (*)[TILE_SIZE])
 | 
			
		||||
      &tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
 | 
			
		||||
 | 
			
		||||
   for (i = 0; i < nr; i++) {
 | 
			
		||||
      unsigned outmask = quads[i]->inout.mask;
 | 
			
		||||
      const unsigned outmask = quads[i]->inout.mask;
 | 
			
		||||
      const int dx = quads[i]->input.x0 - ix;
 | 
			
		||||
      unsigned mask = 0;
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      /* compute depth for this quad */
 | 
			
		||||
      idepth[0] = init_idepth[0] + dx * depth_step;
 | 
			
		||||
      idepth[1] = init_idepth[1] + dx * depth_step;
 | 
			
		||||
      idepth[2] = init_idepth[2] + dx * depth_step;
 | 
			
		||||
      idepth[3] = init_idepth[3] + dx * depth_step;
 | 
			
		||||
 | 
			
		||||
      depth16 = (ushort (*)[TILE_SIZE])
 | 
			
		||||
         &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
 | 
			
		||||
 | 
			
		||||
      if ((outmask & 1) && idepth[0] < depth16[0][0]) {
 | 
			
		||||
         depth16[0][0] = idepth[0];
 | 
			
		||||
         mask |= (1 << 0);
 | 
			
		||||
@@ -772,13 +785,6 @@ depth_interp_z16_less_write(struct quad_stage *qs,
 | 
			
		||||
         mask |= (1 << 3);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      idepth[0] += depth_step;
 | 
			
		||||
      idepth[1] += depth_step;
 | 
			
		||||
      idepth[2] += depth_step;
 | 
			
		||||
      idepth[3] += depth_step;
 | 
			
		||||
 | 
			
		||||
      depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
 | 
			
		||||
 | 
			
		||||
      quads[i]->inout.mask = mask;
 | 
			
		||||
      if (quads[i]->inout.mask)
 | 
			
		||||
         quads[pass++] = quads[i];
 | 
			
		||||
@@ -790,6 +796,14 @@ depth_interp_z16_less_write(struct quad_stage *qs,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LEQUAL and
 | 
			
		||||
 * Z buffer writes enabled.
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: there's no guarantee that the quads are sequentially side by
 | 
			
		||||
 * side.  The fragment shader may have culled some quads, etc.  Sliver
 | 
			
		||||
 * triangles may generate non-sequential quads.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
depth_interp_z16_lequal_write(struct quad_stage *qs, 
 | 
			
		||||
                            struct quad_header *quads[],
 | 
			
		||||
@@ -805,25 +819,33 @@ depth_interp_z16_lequal_write(struct quad_stage *qs,
 | 
			
		||||
   const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
 | 
			
		||||
   struct softpipe_cached_tile *tile;
 | 
			
		||||
   ushort (*depth16)[TILE_SIZE];
 | 
			
		||||
   ushort idepth[4], depth_step;
 | 
			
		||||
   ushort init_idepth[4], idepth[4], depth_step;
 | 
			
		||||
   const float scale = 65535.0;
 | 
			
		||||
 | 
			
		||||
   idepth[0] = (ushort)((z0) * scale);
 | 
			
		||||
   idepth[1] = (ushort)((z0 + dzdx) * scale);
 | 
			
		||||
   idepth[2] = (ushort)((z0 + dzdy) * scale);
 | 
			
		||||
   idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
 | 
			
		||||
   /* compute scaled depth of the four pixels in first quad */
 | 
			
		||||
   init_idepth[0] = (ushort)((z0) * scale);
 | 
			
		||||
   init_idepth[1] = (ushort)((z0 + dzdx) * scale);
 | 
			
		||||
   init_idepth[2] = (ushort)((z0 + dzdy) * scale);
 | 
			
		||||
   init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
 | 
			
		||||
 | 
			
		||||
   depth_step = (ushort)(dzdx * 2 * scale);
 | 
			
		||||
   depth_step = (ushort)(dzdx * scale);
 | 
			
		||||
 | 
			
		||||
   tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
 | 
			
		||||
 | 
			
		||||
   depth16 = (ushort (*)[TILE_SIZE])
 | 
			
		||||
      &tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
 | 
			
		||||
 | 
			
		||||
   for (i = 0; i < nr; i++) {
 | 
			
		||||
      unsigned outmask = quads[i]->inout.mask;
 | 
			
		||||
      const unsigned outmask = quads[i]->inout.mask;
 | 
			
		||||
      const int dx = quads[i]->input.x0 - ix;
 | 
			
		||||
      unsigned mask = 0;
 | 
			
		||||
      
 | 
			
		||||
      /* compute depth for this quad */
 | 
			
		||||
      idepth[0] = init_idepth[0] + dx * depth_step;
 | 
			
		||||
      idepth[1] = init_idepth[1] + dx * depth_step;
 | 
			
		||||
      idepth[2] = init_idepth[2] + dx * depth_step;
 | 
			
		||||
      idepth[3] = init_idepth[3] + dx * depth_step;
 | 
			
		||||
 | 
			
		||||
      depth16 = (ushort (*)[TILE_SIZE])
 | 
			
		||||
         &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
 | 
			
		||||
 | 
			
		||||
      if ((outmask & 1) && idepth[0] <= depth16[0][0]) {
 | 
			
		||||
         depth16[0][0] = idepth[0];
 | 
			
		||||
         mask |= (1 << 0);
 | 
			
		||||
@@ -844,11 +866,6 @@ depth_interp_z16_lequal_write(struct quad_stage *qs,
 | 
			
		||||
         mask |= (1 << 3);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      idepth[0] += depth_step;
 | 
			
		||||
      idepth[1] += depth_step;
 | 
			
		||||
      idepth[2] += depth_step;
 | 
			
		||||
      idepth[3] += depth_step;
 | 
			
		||||
 | 
			
		||||
      depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
 | 
			
		||||
 | 
			
		||||
      quads[i]->inout.mask = mask;
 | 
			
		||||
 
 | 
			
		||||
@@ -805,7 +805,6 @@ line_persp_coeff(const struct setup_context *setup,
 | 
			
		||||
                 struct tgsi_interp_coef *coef,
 | 
			
		||||
                 uint vertSlot, uint i)
 | 
			
		||||
{
 | 
			
		||||
   /* XXX double-check/verify this arithmetic */
 | 
			
		||||
   const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3];
 | 
			
		||||
   const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3];
 | 
			
		||||
   const float da = a1 - a0;
 | 
			
		||||
@@ -813,7 +812,7 @@ line_persp_coeff(const struct setup_context *setup,
 | 
			
		||||
   const float dady = da * setup->emaj.dy * setup->oneoverarea;
 | 
			
		||||
   coef->dadx[i] = dadx;
 | 
			
		||||
   coef->dady[i] = dady;
 | 
			
		||||
   coef->a0[i] = (setup->vmin[vertSlot][i] -
 | 
			
		||||
   coef->a0[i] = (a0 -
 | 
			
		||||
                  (dadx * (setup->vmin[0][0] - setup->pixel_offset) +
 | 
			
		||||
                   dady * (setup->vmin[0][1] - setup->pixel_offset)));
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "util/u_memory.h"
 | 
			
		||||
#include "draw/draw_context.h"
 | 
			
		||||
#include "sp_context.h"
 | 
			
		||||
#include "sp_state.h"
 | 
			
		||||
 | 
			
		||||
@@ -45,6 +46,8 @@ void softpipe_bind_blend_state( struct pipe_context *pipe,
 | 
			
		||||
{
 | 
			
		||||
   struct softpipe_context *softpipe = softpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   draw_flush(softpipe->draw);
 | 
			
		||||
 | 
			
		||||
   softpipe->blend = (struct pipe_blend_state *)blend;
 | 
			
		||||
 | 
			
		||||
   softpipe->dirty |= SP_NEW_BLEND;
 | 
			
		||||
@@ -62,6 +65,8 @@ void softpipe_set_blend_color( struct pipe_context *pipe,
 | 
			
		||||
{
 | 
			
		||||
   struct softpipe_context *softpipe = softpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   draw_flush(softpipe->draw);
 | 
			
		||||
 | 
			
		||||
   softpipe->blend_color = *blend_color;
 | 
			
		||||
 | 
			
		||||
   softpipe->dirty |= SP_NEW_BLEND;
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,14 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
 | 
			
		||||
{
 | 
			
		||||
   struct softpipe_context *softpipe = softpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   softpipe->fs = (struct sp_fragment_shader *) fs;
 | 
			
		||||
   draw_flush(softpipe->draw);
 | 
			
		||||
 | 
			
		||||
   if (softpipe->fs == fs)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   draw_flush(softpipe->draw);
 | 
			
		||||
 | 
			
		||||
   softpipe->fs = fs;
 | 
			
		||||
 | 
			
		||||
   softpipe->dirty |= SP_NEW_FS;
 | 
			
		||||
}
 | 
			
		||||
@@ -159,6 +166,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
 | 
			
		||||
   assert(shader < PIPE_SHADER_TYPES);
 | 
			
		||||
   assert(index == 0);
 | 
			
		||||
 | 
			
		||||
   draw_flush(softpipe->draw);
 | 
			
		||||
 | 
			
		||||
   /* note: reference counting */
 | 
			
		||||
   pipe_buffer_reference(&softpipe->constants[shader].buffer,
 | 
			
		||||
			 buf ? buf->buffer : NULL);
 | 
			
		||||
 
 | 
			
		||||
@@ -41,14 +41,17 @@ softpipe_create_rasterizer_state(struct pipe_context *pipe,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
 | 
			
		||||
                                    void *setup)
 | 
			
		||||
                                    void *rasterizer)
 | 
			
		||||
{
 | 
			
		||||
   struct softpipe_context *softpipe = softpipe_context(pipe);
 | 
			
		||||
 | 
			
		||||
   /* pass-through to draw module */
 | 
			
		||||
   draw_set_rasterizer_state(softpipe->draw, setup);
 | 
			
		||||
   if (softpipe->rasterizer == rasterizer)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   softpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
 | 
			
		||||
   /* pass-through to draw module */
 | 
			
		||||
   draw_set_rasterizer_state(softpipe->draw, rasterizer);
 | 
			
		||||
 | 
			
		||||
   softpipe->rasterizer = rasterizer;
 | 
			
		||||
 | 
			
		||||
   softpipe->dirty |= SP_NEW_RASTERIZER;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
 | 
			
		||||
   struct softpipe_context *sp = softpipe_context(pipe);
 | 
			
		||||
   uint i;
 | 
			
		||||
 | 
			
		||||
   draw_flush(sp->draw);
 | 
			
		||||
 | 
			
		||||
   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
 | 
			
		||||
      /* check if changing cbuf */
 | 
			
		||||
      if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1306,6 +1306,11 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compute nearest mipmap level from texcoords.
 | 
			
		||||
 * Then sample the texture level for four elements of a quad.
 | 
			
		||||
 * \param c0  the LOD bias factors, or absolute LODs (depending on control)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
 | 
			
		||||
                   const float s[QUAD_SIZE],
 | 
			
		||||
@@ -1500,8 +1505,8 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compute which cube face is referenced by each texcoord and put that
 | 
			
		||||
 * info into the sampler faces[] array.  Then sample the cube faces
 | 
			
		||||
 * Use 3D texcoords to choose a cube face, then sample the 2D cube faces.
 | 
			
		||||
 * Put face info into the sampler faces[] array.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
sample_cube(struct tgsi_sampler *tgsi_sampler,
 | 
			
		||||
@@ -1514,11 +1519,12 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
 | 
			
		||||
   struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
 | 
			
		||||
   unsigned j;
 | 
			
		||||
   float ssss[4], tttt[4];
 | 
			
		||||
   unsigned face;
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
     major axis
 | 
			
		||||
     direction     target                             sc     tc    ma
 | 
			
		||||
     ----------    -------------------------------    ---    ---   ---
 | 
			
		||||
     direction    target                             sc     tc    ma
 | 
			
		||||
     ----------   -------------------------------    ---    ---   ---
 | 
			
		||||
     +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
 | 
			
		||||
     -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
 | 
			
		||||
     +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
 | 
			
		||||
@@ -1526,56 +1532,93 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
 | 
			
		||||
     +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
 | 
			
		||||
     -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
 | 
			
		||||
   */
 | 
			
		||||
   for (j = 0; j < QUAD_SIZE; j++) {
 | 
			
		||||
      float rx = s[j];
 | 
			
		||||
      float ry = t[j];
 | 
			
		||||
      float rz = p[j];
 | 
			
		||||
 | 
			
		||||
   /* First choose the cube face.
 | 
			
		||||
    * Use the same cube face for all four pixels in the quad.
 | 
			
		||||
    *
 | 
			
		||||
    * This isn't ideal, but if we want to use a different cube face
 | 
			
		||||
    * per pixel in the quad, we'd have to also compute the per-face
 | 
			
		||||
    * LOD here too.  That's because the four post-face-selection
 | 
			
		||||
    * texcoords are no longer related to each other (they're
 | 
			
		||||
    * per-face!)  so we can't use subtraction to compute the partial
 | 
			
		||||
    * deriviates to compute the LOD.  Doing so (near cube edges
 | 
			
		||||
    * anyway) gives us pretty much random values.
 | 
			
		||||
    */
 | 
			
		||||
   {
 | 
			
		||||
      /* use the average of the four pixel's texcoords to choose the face */
 | 
			
		||||
      const float rx = 0.25 * (s[0] + s[1] + s[2] + s[3]);
 | 
			
		||||
      const float ry = 0.25 * (t[0] + t[1] + t[2] + t[3]);
 | 
			
		||||
      const float rz = 0.25 * (p[0] + p[1] + p[2] + p[3]);
 | 
			
		||||
      const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
 | 
			
		||||
      unsigned face;
 | 
			
		||||
      float sc, tc, ma;
 | 
			
		||||
 | 
			
		||||
      if (arx >= ary && arx >= arz) {
 | 
			
		||||
         if (rx >= 0.0F) {
 | 
			
		||||
            face = PIPE_TEX_FACE_POS_X;
 | 
			
		||||
            sc = -rz;
 | 
			
		||||
            tc = -ry;
 | 
			
		||||
            ma = arx;
 | 
			
		||||
         }
 | 
			
		||||
         else {
 | 
			
		||||
            face = PIPE_TEX_FACE_NEG_X;
 | 
			
		||||
            sc = rz;
 | 
			
		||||
            tc = -ry;
 | 
			
		||||
            ma = arx;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      else if (ary >= arx && ary >= arz) {
 | 
			
		||||
         if (ry >= 0.0F) {
 | 
			
		||||
            face = PIPE_TEX_FACE_POS_Y;
 | 
			
		||||
            sc = rx;
 | 
			
		||||
            tc = rz;
 | 
			
		||||
            ma = ary;
 | 
			
		||||
         }
 | 
			
		||||
         else {
 | 
			
		||||
            face = PIPE_TEX_FACE_NEG_Y;
 | 
			
		||||
            sc = rx;
 | 
			
		||||
            tc = -rz;
 | 
			
		||||
            ma = ary;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
         if (rz > 0.0F) {
 | 
			
		||||
            face = PIPE_TEX_FACE_POS_Z;
 | 
			
		||||
            sc = rx;
 | 
			
		||||
            tc = -ry;
 | 
			
		||||
            ma = arz;
 | 
			
		||||
         }
 | 
			
		||||
         else {
 | 
			
		||||
            face = PIPE_TEX_FACE_NEG_Z;
 | 
			
		||||
            sc = -rx;
 | 
			
		||||
            tc = -ry;
 | 
			
		||||
            ma = arz;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* Now compute the 2D _face_ texture coords from the
 | 
			
		||||
    * 3D _cube_ texture coords.
 | 
			
		||||
    */
 | 
			
		||||
   for (j = 0; j < QUAD_SIZE; j++) {
 | 
			
		||||
      const float rx = s[j], ry = t[j], rz = p[j];
 | 
			
		||||
      const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
 | 
			
		||||
      float sc, tc, ma;
 | 
			
		||||
 | 
			
		||||
      switch (face) {
 | 
			
		||||
      case PIPE_TEX_FACE_POS_X:
 | 
			
		||||
         sc = -rz;
 | 
			
		||||
         tc = -ry;
 | 
			
		||||
         ma = arx;
 | 
			
		||||
         break;
 | 
			
		||||
      case PIPE_TEX_FACE_NEG_X:
 | 
			
		||||
         sc = rz;
 | 
			
		||||
         tc = -ry;
 | 
			
		||||
         ma = arx;
 | 
			
		||||
         break;
 | 
			
		||||
      case PIPE_TEX_FACE_POS_Y:
 | 
			
		||||
         sc = rx;
 | 
			
		||||
         tc = rz;
 | 
			
		||||
         ma = ary;
 | 
			
		||||
         break;
 | 
			
		||||
      case PIPE_TEX_FACE_NEG_Y:
 | 
			
		||||
         sc = rx;
 | 
			
		||||
         tc = -rz;
 | 
			
		||||
         ma = ary;
 | 
			
		||||
         break;
 | 
			
		||||
      case PIPE_TEX_FACE_POS_Z:
 | 
			
		||||
         sc = rx;
 | 
			
		||||
         tc = -ry;
 | 
			
		||||
         ma = arz;
 | 
			
		||||
         break;
 | 
			
		||||
      case PIPE_TEX_FACE_NEG_Z:
 | 
			
		||||
         sc = -rx;
 | 
			
		||||
         tc = -ry;
 | 
			
		||||
         ma = arz;
 | 
			
		||||
         break;
 | 
			
		||||
      default:
 | 
			
		||||
         assert(0 && "bad cube face");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      {
 | 
			
		||||
	 const float ima = 1.0 / ma;
 | 
			
		||||
 
 | 
			
		||||
@@ -297,13 +297,14 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
 | 
			
		||||
                              x, y, TILE_SIZE, TILE_SIZE,
 | 
			
		||||
                              tc->tile.data.color32, 0/*STRIDE*/);
 | 
			
		||||
 | 
			
		||||
            /* do this? */
 | 
			
		||||
            clear_clear_flag(tc->clear_flags, addr);
 | 
			
		||||
 | 
			
		||||
            numCleared++;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* reset all clear flags to zero */
 | 
			
		||||
   memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
   debug_printf("num cleared: %u\n", numCleared);
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -478,7 +478,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
 | 
			
		||||
                 struct svga_winsys_surface *host,
 | 
			
		||||
                 SVGA3dTransferType transfer,      // IN
 | 
			
		||||
                 uint32 size,                      // IN
 | 
			
		||||
                 uint32 offset,                    // IN
 | 
			
		||||
                 uint32 guest_offset,              // IN
 | 
			
		||||
                 uint32 host_offset,               // IN
 | 
			
		||||
                 SVGA3dSurfaceDMAFlags flags)      // IN
 | 
			
		||||
{
 | 
			
		||||
   SVGA3dCmdSurfaceDMA *cmd;
 | 
			
		||||
@@ -517,19 +518,19 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
 | 
			
		||||
   cmd->transfer = transfer;
 | 
			
		||||
 | 
			
		||||
   box = (SVGA3dCopyBox *)&cmd[1];
 | 
			
		||||
   box->x = offset;
 | 
			
		||||
   box->x = host_offset;
 | 
			
		||||
   box->y = 0;
 | 
			
		||||
   box->z = 0;
 | 
			
		||||
   box->w = size;
 | 
			
		||||
   box->h = 1;
 | 
			
		||||
   box->d = 1;
 | 
			
		||||
   box->srcx = offset;
 | 
			
		||||
   box->srcx = guest_offset;
 | 
			
		||||
   box->srcy = 0;
 | 
			
		||||
   box->srcz = 0;
 | 
			
		||||
   
 | 
			
		||||
   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
 | 
			
		||||
   pSuffix->suffixSize = sizeof *pSuffix;
 | 
			
		||||
   pSuffix->maximumOffset = offset + size;
 | 
			
		||||
   pSuffix->maximumOffset = guest_offset + size;
 | 
			
		||||
   pSuffix->flags = flags;
 | 
			
		||||
 | 
			
		||||
   swc->commit(swc);
 | 
			
		||||
 
 | 
			
		||||
@@ -111,7 +111,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
 | 
			
		||||
                 struct svga_winsys_surface *host,
 | 
			
		||||
                 SVGA3dTransferType transfer,
 | 
			
		||||
                 uint32 size,
 | 
			
		||||
                 uint32 offset,
 | 
			
		||||
                 uint32 guest_offset,
 | 
			
		||||
                 uint32 host_offset,
 | 
			
		||||
                 SVGA3dSurfaceDMAFlags flags);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -215,7 +215,6 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen )
 | 
			
		||||
   svga->state.hw_draw.num_views = 0;
 | 
			
		||||
 | 
			
		||||
   svga->dirty = ~0;
 | 
			
		||||
   svga->state.white_fs_id = SVGA3D_INVALID_ID;
 | 
			
		||||
 | 
			
		||||
   LIST_INITHEAD(&svga->dirty_buffers);
 | 
			
		||||
 | 
			
		||||
@@ -285,3 +284,8 @@ void svga_hwtnl_flush_retry( struct svga_context *svga )
 | 
			
		||||
   assert(ret == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct svga_winsys_context *
 | 
			
		||||
svga_winsys_context( struct pipe_context *pipe )
 | 
			
		||||
{
 | 
			
		||||
   return svga_context( pipe )->swc;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -139,6 +139,7 @@ struct svga_rasterizer_state {
 | 
			
		||||
   unsigned multisampleantialias:1;
 | 
			
		||||
   unsigned antialiasedlineenable:1;
 | 
			
		||||
   unsigned lastpixel:1;
 | 
			
		||||
   unsigned pointspriteenable:1;
 | 
			
		||||
 | 
			
		||||
   unsigned linepattern;
 | 
			
		||||
 | 
			
		||||
@@ -329,10 +330,6 @@ struct svga_context
 | 
			
		||||
 | 
			
		||||
      unsigned texture_timestamp;
 | 
			
		||||
 | 
			
		||||
      /* Internally generated shaders:
 | 
			
		||||
       */
 | 
			
		||||
      unsigned white_fs_id;
 | 
			
		||||
 | 
			
		||||
      /* 
 | 
			
		||||
       */
 | 
			
		||||
      struct svga_sw_state          sw;
 | 
			
		||||
 
 | 
			
		||||
@@ -253,7 +253,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
 | 
			
		||||
         assert(index_bias >= 0);
 | 
			
		||||
         assert(min_index <= max_index);
 | 
			
		||||
         assert(offset + index_bias*stride < size);
 | 
			
		||||
         assert(offset + (index_bias + min_index)*stride < size);
 | 
			
		||||
         if (min_index != ~0) {
 | 
			
		||||
            assert(offset + (index_bias + min_index) * stride < size);
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         switch (hwtnl->cmd.vdecl[i].identity.type) {
 | 
			
		||||
         case SVGA3D_DECLTYPE_FLOAT1:
 | 
			
		||||
@@ -314,7 +316,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         assert(!stride || width <= stride);
 | 
			
		||||
         assert(offset + (index_bias + max_index)*stride + width <= size);
 | 
			
		||||
         if (max_index != ~0) {
 | 
			
		||||
            assert(offset + (index_bias + max_index) * stride + width <= size);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      assert(range->indexWidth == range->indexArray.stride);
 | 
			
		||||
 
 | 
			
		||||
@@ -92,6 +92,7 @@ svga_create_blend_state(struct pipe_context *pipe,
 | 
			
		||||
      if (templ->logicop_enable) {
 | 
			
		||||
         switch (templ->logicop_func) {
 | 
			
		||||
         case PIPE_LOGICOP_XOR:
 | 
			
		||||
         case PIPE_LOGICOP_INVERT:
 | 
			
		||||
            blend->need_white_fragments = TRUE;
 | 
			
		||||
            blend->rt[i].blend_enable = TRUE;
 | 
			
		||||
            blend->rt[i].srcblend       = SVGA3D_BLENDOP_ONE;
 | 
			
		||||
@@ -125,12 +126,6 @@ svga_create_blend_state(struct pipe_context *pipe,
 | 
			
		||||
            blend->rt[i].dstblend       = SVGA3D_BLENDOP_ONE;
 | 
			
		||||
            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
 | 
			
		||||
            break;
 | 
			
		||||
         case PIPE_LOGICOP_INVERT:
 | 
			
		||||
            blend->rt[i].blend_enable = TRUE;
 | 
			
		||||
            blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
 | 
			
		||||
            blend->rt[i].dstblend       = SVGA3D_BLENDOP_ZERO;
 | 
			
		||||
            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_ADD;
 | 
			
		||||
            break;
 | 
			
		||||
         case PIPE_LOGICOP_AND:
 | 
			
		||||
            /* Approximate with minimum - works for the 0 & anything case: */
 | 
			
		||||
            blend->rt[i].blend_enable = TRUE;
 | 
			
		||||
@@ -228,7 +223,7 @@ static void svga_set_blend_color( struct pipe_context *pipe,
 | 
			
		||||
 | 
			
		||||
   svga->curr.blend_color = *blend_color;
 | 
			
		||||
 | 
			
		||||
   svga->dirty |= SVGA_NEW_BLEND;
 | 
			
		||||
   svga->dirty |= SVGA_NEW_BLEND_COLOR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -218,9 +218,6 @@ svga_draw_range_elements( struct pipe_context *pipe,
 | 
			
		||||
   if (SVGA_DEBUG & DEBUG_FLUSH) {
 | 
			
		||||
      static unsigned id;
 | 
			
		||||
      debug_printf("%s %d\n", __FUNCTION__, id++);
 | 
			
		||||
      if (id > 1300)
 | 
			
		||||
         util_time_sleep( 2000 );
 | 
			
		||||
 | 
			
		||||
      svga_hwtnl_flush_retry( svga );
 | 
			
		||||
      svga_context_flush(svga, NULL);
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,6 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
 | 
			
		||||
   /* light_twoside          - XXX: need fragment shader varient */
 | 
			
		||||
   /* poly_smooth            - XXX: no fallback available */
 | 
			
		||||
   /* poly_stipple_enable    - draw module */
 | 
			
		||||
   /* point_sprite           - ? */
 | 
			
		||||
   /* point_size_per_vertex  - ? */
 | 
			
		||||
   /* sprite_coord_mode      - ??? */
 | 
			
		||||
   /* bypass_vs_viewport_and_clip        - handled by viewport setup */
 | 
			
		||||
@@ -86,6 +85,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
 | 
			
		||||
   rast->multisampleantialias = templ->multisample;
 | 
			
		||||
   rast->antialiasedlineenable = templ->line_smooth;
 | 
			
		||||
   rast->lastpixel = templ->line_last_pixel;
 | 
			
		||||
   rast->pointspriteenable = templ->point_sprite;
 | 
			
		||||
   rast->pointsize = templ->point_size;
 | 
			
		||||
   rast->pointsize_min = templ->point_size_min;
 | 
			
		||||
   rast->pointsize_max = templ->point_size_max;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@
 | 
			
		||||
#include "pipe/p_defines.h"
 | 
			
		||||
#include "util/u_math.h"
 | 
			
		||||
#include "util/u_memory.h"
 | 
			
		||||
#include "util/u_pack_color.h"
 | 
			
		||||
#include "tgsi/tgsi_parse.h"
 | 
			
		||||
 | 
			
		||||
#include "svga_context.h"
 | 
			
		||||
@@ -112,14 +111,12 @@ svga_create_sampler_state(struct pipe_context *pipe,
 | 
			
		||||
   cso->compare_func = sampler->compare_func;
 | 
			
		||||
 | 
			
		||||
   {
 | 
			
		||||
      ubyte r = float_to_ubyte(sampler->border_color[0]);
 | 
			
		||||
      ubyte g = float_to_ubyte(sampler->border_color[1]);
 | 
			
		||||
      ubyte b = float_to_ubyte(sampler->border_color[2]);
 | 
			
		||||
      ubyte a = float_to_ubyte(sampler->border_color[3]);
 | 
			
		||||
      uint32 r = float_to_ubyte(sampler->border_color[0]);
 | 
			
		||||
      uint32 g = float_to_ubyte(sampler->border_color[1]);
 | 
			
		||||
      uint32 b = float_to_ubyte(sampler->border_color[2]);
 | 
			
		||||
      uint32 a = float_to_ubyte(sampler->border_color[3]);
 | 
			
		||||
 | 
			
		||||
      util_pack_color_ub( r, g, b, a,
 | 
			
		||||
                          PIPE_FORMAT_B8G8R8A8_UNORM,
 | 
			
		||||
                          &cso->bordercolor );
 | 
			
		||||
      cso->bordercolor = (a << 24) | (r << 16) | (g << 8) | b;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* No SVGA3D support for:
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
 | 
			
		||||
   /* Adjust refcounts */
 | 
			
		||||
   for (i = 0; i < count; i++) {
 | 
			
		||||
      pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
 | 
			
		||||
      if (svga_buffer(buffers[i].buffer)->user)
 | 
			
		||||
      if (svga_buffer_is_user_buffer(buffers[i].buffer))
 | 
			
		||||
         any_user_buffer = TRUE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -104,7 +104,9 @@ svga_get_paramf(struct pipe_screen *screen, int param)
 | 
			
		||||
      return 80.0;
 | 
			
		||||
 | 
			
		||||
   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
 | 
			
		||||
      return 4.0;
 | 
			
		||||
      if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result))
 | 
			
		||||
         return 4.0;
 | 
			
		||||
      return result.u;
 | 
			
		||||
 | 
			
		||||
   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
 | 
			
		||||
      return 16.0;
 | 
			
		||||
@@ -131,12 +133,33 @@ svga_get_paramf(struct pipe_screen *screen, int param)
 | 
			
		||||
      return 1;
 | 
			
		||||
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
 | 
			
		||||
      return 1;
 | 
			
		||||
 | 
			
		||||
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 | 
			
		||||
      return SVGA_MAX_TEXTURE_LEVELS;
 | 
			
		||||
      {
 | 
			
		||||
         unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
 | 
			
		||||
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
 | 
			
		||||
            levels = MIN2(util_logbase2(result.u) + 1, levels);
 | 
			
		||||
         else
 | 
			
		||||
            levels = 12 /* 2048x2048 */;
 | 
			
		||||
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
 | 
			
		||||
            levels = MIN2(util_logbase2(result.u) + 1, levels);
 | 
			
		||||
         else
 | 
			
		||||
            levels = 12 /* 2048x2048 */;
 | 
			
		||||
         return levels;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
 | 
			
		||||
      return 8;  /* max 128x128x128 */
 | 
			
		||||
      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
 | 
			
		||||
         return 8;  /* max 128x128x128 */
 | 
			
		||||
      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);
 | 
			
		||||
 | 
			
		||||
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
 | 
			
		||||
      return SVGA_MAX_TEXTURE_LEVELS;
 | 
			
		||||
      /*
 | 
			
		||||
       * No mechanism to query the host, and at least limited to 2048x2048 on
 | 
			
		||||
       * certain hardware.
 | 
			
		||||
       */
 | 
			
		||||
      return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
 | 
			
		||||
                  12.0 /* 2048x2048 */);
 | 
			
		||||
 | 
			
		||||
   case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
 | 
			
		||||
      return 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -83,7 +83,7 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
 | 
			
		||||
       * as svga_screen_surface_create might have passed a recycled host
 | 
			
		||||
       * buffer.
 | 
			
		||||
       */
 | 
			
		||||
      sbuf->hw.flags.discard = TRUE;
 | 
			
		||||
      sbuf->dma.flags.discard = TRUE;
 | 
			
		||||
 | 
			
		||||
      SVGA_DBG(DEBUG_DMA, "   --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
 | 
			
		||||
   }
 | 
			
		||||
@@ -109,10 +109,10 @@ svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
 | 
			
		||||
   struct svga_winsys_screen *sws = ss->sws;
 | 
			
		||||
 | 
			
		||||
   assert(!sbuf->map.count);
 | 
			
		||||
   assert(sbuf->hw.buf);
 | 
			
		||||
   if(sbuf->hw.buf) {
 | 
			
		||||
      sws->buffer_destroy(sws, sbuf->hw.buf);
 | 
			
		||||
      sbuf->hw.buf = NULL;
 | 
			
		||||
   assert(sbuf->hwbuf);
 | 
			
		||||
   if(sbuf->hwbuf) {
 | 
			
		||||
      sws->buffer_destroy(sws, sbuf->hwbuf);
 | 
			
		||||
      sbuf->hwbuf = NULL;
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -151,16 +151,18 @@ static INLINE enum pipe_error
 | 
			
		||||
svga_buffer_create_hw_storage(struct svga_screen *ss,
 | 
			
		||||
                              struct svga_buffer *sbuf)
 | 
			
		||||
{
 | 
			
		||||
   if(!sbuf->hw.buf) {
 | 
			
		||||
   assert(!sbuf->user);
 | 
			
		||||
 | 
			
		||||
   if(!sbuf->hwbuf) {
 | 
			
		||||
      unsigned alignment = sbuf->base.alignment;
 | 
			
		||||
      unsigned usage = 0;
 | 
			
		||||
      unsigned size = sbuf->base.size;
 | 
			
		||||
      
 | 
			
		||||
      sbuf->hw.buf = svga_winsys_buffer_create(ss, alignment, usage, size);
 | 
			
		||||
      if(!sbuf->hw.buf)
 | 
			
		||||
      sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
 | 
			
		||||
      if(!sbuf->hwbuf)
 | 
			
		||||
         return PIPE_ERROR_OUT_OF_MEMORY;
 | 
			
		||||
      
 | 
			
		||||
      assert(!sbuf->needs_flush);
 | 
			
		||||
      assert(!sbuf->dma.pending);
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   return PIPE_OK;
 | 
			
		||||
@@ -175,12 +177,11 @@ svga_buffer_upload_command(struct svga_context *svga,
 | 
			
		||||
                           struct svga_buffer *sbuf)
 | 
			
		||||
{
 | 
			
		||||
   struct svga_winsys_context *swc = svga->swc;
 | 
			
		||||
   struct svga_winsys_buffer *guest = sbuf->hw.buf;
 | 
			
		||||
   struct svga_winsys_buffer *guest = sbuf->hwbuf;
 | 
			
		||||
   struct svga_winsys_surface *host = sbuf->handle;
 | 
			
		||||
   SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM;
 | 
			
		||||
   SVGA3dSurfaceDMAFlags flags = sbuf->hw.flags;
 | 
			
		||||
   SVGA3dCmdSurfaceDMA *cmd;
 | 
			
		||||
   uint32 numBoxes = sbuf->hw.num_ranges;
 | 
			
		||||
   uint32 numBoxes = sbuf->map.num_ranges;
 | 
			
		||||
   SVGA3dCopyBox *boxes;
 | 
			
		||||
   SVGA3dCmdSurfaceDMASuffix *pSuffix;
 | 
			
		||||
   unsigned region_flags;
 | 
			
		||||
@@ -218,8 +219,8 @@ svga_buffer_upload_command(struct svga_context *svga,
 | 
			
		||||
 | 
			
		||||
   cmd->transfer = transfer;
 | 
			
		||||
 | 
			
		||||
   sbuf->hw.boxes = (SVGA3dCopyBox *)&cmd[1];
 | 
			
		||||
   sbuf->hw.svga = svga;
 | 
			
		||||
   sbuf->dma.boxes = (SVGA3dCopyBox *)&cmd[1];
 | 
			
		||||
   sbuf->dma.svga = svga;
 | 
			
		||||
 | 
			
		||||
   /* Increment reference count */
 | 
			
		||||
   dummy = NULL;
 | 
			
		||||
@@ -228,9 +229,11 @@ svga_buffer_upload_command(struct svga_context *svga,
 | 
			
		||||
   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes);
 | 
			
		||||
   pSuffix->suffixSize = sizeof *pSuffix;
 | 
			
		||||
   pSuffix->maximumOffset = sbuf->base.size;
 | 
			
		||||
   pSuffix->flags = flags;
 | 
			
		||||
   pSuffix->flags = sbuf->dma.flags;
 | 
			
		||||
 | 
			
		||||
   swc->commit(swc);
 | 
			
		||||
   SVGA_FIFOCommitAll(swc);
 | 
			
		||||
 | 
			
		||||
   sbuf->dma.flags.discard = FALSE;
 | 
			
		||||
 | 
			
		||||
   return PIPE_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -248,10 +251,10 @@ svga_buffer_upload_flush(struct svga_context *svga,
 | 
			
		||||
   unsigned i;
 | 
			
		||||
 | 
			
		||||
   assert(sbuf->handle); 
 | 
			
		||||
   assert(sbuf->hw.buf);
 | 
			
		||||
   assert(sbuf->hw.num_ranges);
 | 
			
		||||
   assert(sbuf->hw.svga == svga);
 | 
			
		||||
   assert(sbuf->hw.boxes);
 | 
			
		||||
   assert(sbuf->hwbuf);
 | 
			
		||||
   assert(sbuf->map.num_ranges);
 | 
			
		||||
   assert(sbuf->dma.svga == svga);
 | 
			
		||||
   assert(sbuf->dma.boxes);
 | 
			
		||||
   
 | 
			
		||||
   /*
 | 
			
		||||
    * Patch the DMA command with the final copy box.
 | 
			
		||||
@@ -259,36 +262,33 @@ svga_buffer_upload_flush(struct svga_context *svga,
 | 
			
		||||
 | 
			
		||||
   SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
 | 
			
		||||
 | 
			
		||||
   boxes = sbuf->hw.boxes;
 | 
			
		||||
   for(i = 0; i < sbuf->hw.num_ranges; ++i) {
 | 
			
		||||
   boxes = sbuf->dma.boxes;
 | 
			
		||||
   for(i = 0; i < sbuf->map.num_ranges; ++i) {
 | 
			
		||||
      SVGA_DBG(DEBUG_DMA, "  bytes %u - %u\n",
 | 
			
		||||
               sbuf->hw.ranges[i].start, sbuf->hw.ranges[i].end);
 | 
			
		||||
               sbuf->map.ranges[i].start, sbuf->map.ranges[i].end);
 | 
			
		||||
 | 
			
		||||
      boxes[i].x = sbuf->hw.ranges[i].start;
 | 
			
		||||
      boxes[i].x = sbuf->map.ranges[i].start;
 | 
			
		||||
      boxes[i].y = 0;
 | 
			
		||||
      boxes[i].z = 0;
 | 
			
		||||
      boxes[i].w = sbuf->hw.ranges[i].end - sbuf->hw.ranges[i].start;
 | 
			
		||||
      boxes[i].w = sbuf->map.ranges[i].end - sbuf->map.ranges[i].start;
 | 
			
		||||
      boxes[i].h = 1;
 | 
			
		||||
      boxes[i].d = 1;
 | 
			
		||||
      boxes[i].srcx = sbuf->hw.ranges[i].start;
 | 
			
		||||
      boxes[i].srcx = sbuf->map.ranges[i].start;
 | 
			
		||||
      boxes[i].srcy = 0;
 | 
			
		||||
      boxes[i].srcz = 0;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   sbuf->hw.num_ranges = 0;
 | 
			
		||||
   memset(&sbuf->hw.flags, 0, sizeof sbuf->hw.flags);
 | 
			
		||||
   sbuf->map.num_ranges = 0;
 | 
			
		||||
 | 
			
		||||
   assert(sbuf->head.prev && sbuf->head.next);
 | 
			
		||||
   LIST_DEL(&sbuf->head);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
   sbuf->head.next = sbuf->head.prev = NULL; 
 | 
			
		||||
#endif
 | 
			
		||||
   sbuf->needs_flush = FALSE;
 | 
			
		||||
   sbuf->dma.pending = FALSE;
 | 
			
		||||
 | 
			
		||||
   sbuf->hw.svga = NULL;
 | 
			
		||||
   sbuf->hw.boxes = NULL;
 | 
			
		||||
 | 
			
		||||
   sbuf->host_written = TRUE;
 | 
			
		||||
   sbuf->dma.svga = NULL;
 | 
			
		||||
   sbuf->dma.boxes = NULL;
 | 
			
		||||
 | 
			
		||||
   /* Decrement reference count */
 | 
			
		||||
   pipe_buffer_reference((struct pipe_buffer **)&sbuf, NULL);
 | 
			
		||||
@@ -296,7 +296,7 @@ svga_buffer_upload_flush(struct svga_context *svga,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Queue a DMA upload of a range of this buffer to the host.
 | 
			
		||||
 * Note a dirty range.
 | 
			
		||||
 *
 | 
			
		||||
 * This function only notes the range down. It doesn't actually emit a DMA
 | 
			
		||||
 * upload command. That only happens when a context tries to refer to this
 | 
			
		||||
@@ -305,15 +305,24 @@ svga_buffer_upload_flush(struct svga_context *svga,
 | 
			
		||||
 * We try to lump as many contiguous DMA transfers together as possible.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
svga_buffer_upload_queue(struct svga_buffer *sbuf,
 | 
			
		||||
                         unsigned start,
 | 
			
		||||
                         unsigned end)
 | 
			
		||||
svga_buffer_add_range(struct svga_buffer *sbuf,
 | 
			
		||||
                      unsigned start,
 | 
			
		||||
                      unsigned end)
 | 
			
		||||
{
 | 
			
		||||
   unsigned i;
 | 
			
		||||
   unsigned nearest_range;
 | 
			
		||||
   unsigned nearest_dist;
 | 
			
		||||
 | 
			
		||||
   assert(sbuf->hw.buf);
 | 
			
		||||
   assert(end > start);
 | 
			
		||||
   
 | 
			
		||||
   if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) {
 | 
			
		||||
      nearest_range = sbuf->map.num_ranges;
 | 
			
		||||
      nearest_dist = ~0;
 | 
			
		||||
   } else {
 | 
			
		||||
      nearest_range = SVGA_BUFFER_MAX_RANGES - 1;
 | 
			
		||||
      nearest_dist = 0;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
    * Try to grow one of the ranges.
 | 
			
		||||
    *
 | 
			
		||||
@@ -324,12 +333,34 @@ svga_buffer_upload_queue(struct svga_buffer *sbuf,
 | 
			
		||||
    * buffer should be flushed.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
   for(i = 0; i < sbuf->hw.num_ranges; ++i) {
 | 
			
		||||
      if(start <= sbuf->hw.ranges[i].end && sbuf->hw.ranges[i].start <= end) {
 | 
			
		||||
         sbuf->hw.ranges[i].start = MIN2(sbuf->hw.ranges[i].start, start);
 | 
			
		||||
         sbuf->hw.ranges[i].end   = MAX2(sbuf->hw.ranges[i].end,    end);
 | 
			
		||||
   for(i = 0; i < sbuf->map.num_ranges; ++i) {
 | 
			
		||||
      int left_dist;
 | 
			
		||||
      int right_dist;
 | 
			
		||||
      int dist;
 | 
			
		||||
 | 
			
		||||
      left_dist = start - sbuf->map.ranges[i].end;
 | 
			
		||||
      right_dist = sbuf->map.ranges[i].start - end;
 | 
			
		||||
      dist = MAX2(left_dist, right_dist);
 | 
			
		||||
 | 
			
		||||
      if (dist <= 0) {
 | 
			
		||||
         /*
 | 
			
		||||
          * Ranges are contiguous or overlapping -- extend this one and return.
 | 
			
		||||
          */
 | 
			
		||||
 | 
			
		||||
         sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start);
 | 
			
		||||
         sbuf->map.ranges[i].end   = MAX2(sbuf->map.ranges[i].end,   end);
 | 
			
		||||
         return;
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
         /*
 | 
			
		||||
          * Discontiguous ranges -- keep track of the nearest range.
 | 
			
		||||
          */
 | 
			
		||||
 | 
			
		||||
         if (dist < nearest_dist) {
 | 
			
		||||
            nearest_range = i;
 | 
			
		||||
            nearest_dist = dist;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
@@ -337,20 +368,34 @@ svga_buffer_upload_queue(struct svga_buffer *sbuf,
 | 
			
		||||
    * pending DMA upload and start clean.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
   if(sbuf->needs_flush)
 | 
			
		||||
      svga_buffer_upload_flush(sbuf->hw.svga, sbuf);
 | 
			
		||||
   if(sbuf->dma.pending)
 | 
			
		||||
      svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
 | 
			
		||||
 | 
			
		||||
   assert(!sbuf->needs_flush);
 | 
			
		||||
   assert(!sbuf->hw.svga);
 | 
			
		||||
   assert(!sbuf->hw.boxes);
 | 
			
		||||
   assert(!sbuf->dma.pending);
 | 
			
		||||
   assert(!sbuf->dma.svga);
 | 
			
		||||
   assert(!sbuf->dma.boxes);
 | 
			
		||||
 | 
			
		||||
   /*
 | 
			
		||||
    * Add a new range.
 | 
			
		||||
    */
 | 
			
		||||
   if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) {
 | 
			
		||||
      /*
 | 
			
		||||
       * Add a new range.
 | 
			
		||||
       */
 | 
			
		||||
 | 
			
		||||
   sbuf->hw.ranges[sbuf->hw.num_ranges].start = start;
 | 
			
		||||
   sbuf->hw.ranges[sbuf->hw.num_ranges].end = end;
 | 
			
		||||
   ++sbuf->hw.num_ranges;
 | 
			
		||||
      sbuf->map.ranges[sbuf->map.num_ranges].start = start;
 | 
			
		||||
      sbuf->map.ranges[sbuf->map.num_ranges].end = end;
 | 
			
		||||
      ++sbuf->map.num_ranges;
 | 
			
		||||
   } else {
 | 
			
		||||
      /*
 | 
			
		||||
       * Everything else failed, so just extend the nearest range.
 | 
			
		||||
       *
 | 
			
		||||
       * It is OK to do this because we always keep a local copy of the
 | 
			
		||||
       * host buffer data, for SW TNL, and the host never modifies the buffer.
 | 
			
		||||
       */
 | 
			
		||||
 | 
			
		||||
      assert(nearest_range < SVGA_BUFFER_MAX_RANGES);
 | 
			
		||||
      assert(nearest_range < sbuf->map.num_ranges);
 | 
			
		||||
      sbuf->map.ranges[nearest_range].start = MIN2(sbuf->map.ranges[nearest_range].start, start);
 | 
			
		||||
      sbuf->map.ranges[nearest_range].end   = MAX2(sbuf->map.ranges[nearest_range].end,   end);
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -365,55 +410,30 @@ svga_buffer_map_range( struct pipe_screen *screen,
 | 
			
		||||
   struct svga_buffer *sbuf = svga_buffer( buf );
 | 
			
		||||
   void *map;
 | 
			
		||||
 | 
			
		||||
   if(sbuf->swbuf) {
 | 
			
		||||
   if (!sbuf->swbuf && !sbuf->hwbuf) {
 | 
			
		||||
      if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) {
 | 
			
		||||
         /*
 | 
			
		||||
          * We can't create a hardware buffer big enough, so create a malloc
 | 
			
		||||
          * buffer instead.
 | 
			
		||||
          */
 | 
			
		||||
 | 
			
		||||
         debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n",
 | 
			
		||||
                      __FUNCTION__,
 | 
			
		||||
                      (sbuf->base.size + 1023)/1024);
 | 
			
		||||
 | 
			
		||||
         sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (sbuf->swbuf) {
 | 
			
		||||
      /* User/malloc buffer */
 | 
			
		||||
      map = sbuf->swbuf;
 | 
			
		||||
   }
 | 
			
		||||
   else if (sbuf->hwbuf) {
 | 
			
		||||
      map = sws->buffer_map(sws, sbuf->hwbuf, usage);
 | 
			
		||||
   }
 | 
			
		||||
   else {
 | 
			
		||||
      if(!sbuf->hw.buf) {
 | 
			
		||||
         if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK)
 | 
			
		||||
            return NULL;
 | 
			
		||||
         
 | 
			
		||||
         /* Populate the hardware storage if the host surface pre-existed */
 | 
			
		||||
         if(sbuf->host_written) {
 | 
			
		||||
            SVGA3dSurfaceDMAFlags flags;
 | 
			
		||||
            enum pipe_error ret;
 | 
			
		||||
            struct pipe_fence_handle *fence = NULL;
 | 
			
		||||
            
 | 
			
		||||
            assert(sbuf->handle);
 | 
			
		||||
 | 
			
		||||
            SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n", 
 | 
			
		||||
                     sbuf->handle, 0, sbuf->base.size);
 | 
			
		||||
 | 
			
		||||
            memset(&flags, 0, sizeof flags);
 | 
			
		||||
            
 | 
			
		||||
            ret = SVGA3D_BufferDMA(ss->swc,
 | 
			
		||||
                                   sbuf->hw.buf,
 | 
			
		||||
                                   sbuf->handle,
 | 
			
		||||
                                   SVGA3D_READ_HOST_VRAM,
 | 
			
		||||
                                   sbuf->base.size,
 | 
			
		||||
                                   0,
 | 
			
		||||
                                   flags);
 | 
			
		||||
            if(ret != PIPE_OK) {
 | 
			
		||||
               ss->swc->flush(ss->swc, NULL);
 | 
			
		||||
               
 | 
			
		||||
               ret = SVGA3D_BufferDMA(ss->swc,
 | 
			
		||||
                                      sbuf->hw.buf,
 | 
			
		||||
                                      sbuf->handle,
 | 
			
		||||
                                      SVGA3D_READ_HOST_VRAM,
 | 
			
		||||
                                      sbuf->base.size,
 | 
			
		||||
                                      0,
 | 
			
		||||
                                      flags);
 | 
			
		||||
               assert(ret == PIPE_OK);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            ss->swc->flush(ss->swc, &fence);
 | 
			
		||||
            sws->fence_finish(sws, fence, 0);
 | 
			
		||||
            sws->fence_reference(sws, &fence, NULL);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
         
 | 
			
		||||
      map = sws->buffer_map(sws, sbuf->hw.buf, usage);
 | 
			
		||||
      map = NULL;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if(map) {
 | 
			
		||||
@@ -446,8 +466,7 @@ svga_buffer_flush_mapped_range( struct pipe_screen *screen,
 | 
			
		||||
   assert(sbuf->map.writing);
 | 
			
		||||
   if(sbuf->map.writing) {
 | 
			
		||||
      assert(sbuf->map.flush_explicit);
 | 
			
		||||
      if(sbuf->hw.buf)
 | 
			
		||||
         svga_buffer_upload_queue(sbuf, offset, offset + length);
 | 
			
		||||
      svga_buffer_add_range(sbuf, offset, offset + length);
 | 
			
		||||
   }
 | 
			
		||||
   pipe_mutex_unlock(ss->swc_mutex);
 | 
			
		||||
}
 | 
			
		||||
@@ -466,16 +485,15 @@ svga_buffer_unmap( struct pipe_screen *screen,
 | 
			
		||||
   if(sbuf->map.count)
 | 
			
		||||
      --sbuf->map.count;
 | 
			
		||||
 | 
			
		||||
   if(sbuf->hw.buf)
 | 
			
		||||
      sws->buffer_unmap(sws, sbuf->hw.buf);
 | 
			
		||||
   if(sbuf->hwbuf)
 | 
			
		||||
      sws->buffer_unmap(sws, sbuf->hwbuf);
 | 
			
		||||
 | 
			
		||||
   if(sbuf->map.writing) {
 | 
			
		||||
      if(!sbuf->map.flush_explicit) {
 | 
			
		||||
         /* No mapped range was flushed -- flush the whole buffer */
 | 
			
		||||
         SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
 | 
			
		||||
   
 | 
			
		||||
         if(sbuf->hw.buf)
 | 
			
		||||
            svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
 | 
			
		||||
         svga_buffer_add_range(sbuf, 0, sbuf->base.size);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      sbuf->map.writing = FALSE;
 | 
			
		||||
@@ -493,12 +511,15 @@ svga_buffer_destroy( struct pipe_buffer *buf )
 | 
			
		||||
 | 
			
		||||
   assert(!p_atomic_read(&buf->reference.count));
 | 
			
		||||
   
 | 
			
		||||
   assert(!sbuf->needs_flush);
 | 
			
		||||
   assert(!sbuf->dma.pending);
 | 
			
		||||
 | 
			
		||||
   if(sbuf->handle)
 | 
			
		||||
      svga_buffer_destroy_host_surface(ss, sbuf);
 | 
			
		||||
   
 | 
			
		||||
   if(sbuf->hw.buf)
 | 
			
		||||
   if(sbuf->uploaded.buffer)
 | 
			
		||||
      pipe_buffer_reference(&sbuf->uploaded.buffer, NULL);
 | 
			
		||||
 | 
			
		||||
   if(sbuf->hwbuf)
 | 
			
		||||
      svga_buffer_destroy_hw_storage(ss, sbuf);
 | 
			
		||||
   
 | 
			
		||||
   if(sbuf->swbuf && !sbuf->user)
 | 
			
		||||
@@ -595,13 +616,14 @@ svga_screen_init_buffer_functions(struct pipe_screen *screen)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Copy the contents of the user buffer / malloc buffer to a hardware buffer.
 | 
			
		||||
/**
 | 
			
		||||
 * Copy the contents of the malloc buffer to a hardware buffer.
 | 
			
		||||
 */
 | 
			
		||||
static INLINE enum pipe_error
 | 
			
		||||
svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
 | 
			
		||||
{
 | 
			
		||||
   if(!sbuf->hw.buf) {
 | 
			
		||||
   assert(!sbuf->user);
 | 
			
		||||
   if(!sbuf->hwbuf) {
 | 
			
		||||
      enum pipe_error ret;
 | 
			
		||||
      void *map;
 | 
			
		||||
      
 | 
			
		||||
@@ -610,20 +632,20 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
 | 
			
		||||
         return PIPE_ERROR;
 | 
			
		||||
      
 | 
			
		||||
      ret = svga_buffer_create_hw_storage(ss, sbuf);
 | 
			
		||||
      assert(ret == PIPE_OK);
 | 
			
		||||
      if(ret != PIPE_OK)
 | 
			
		||||
         return ret;
 | 
			
		||||
 | 
			
		||||
      pipe_mutex_lock(ss->swc_mutex);
 | 
			
		||||
      map = ss->sws->buffer_map(ss->sws, sbuf->hw.buf, PIPE_BUFFER_USAGE_CPU_WRITE);
 | 
			
		||||
      map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
 | 
			
		||||
      assert(map);
 | 
			
		||||
      if(!map) {
 | 
			
		||||
	 pipe_mutex_unlock(ss->swc_mutex);
 | 
			
		||||
         return PIPE_ERROR_OUT_OF_MEMORY;
 | 
			
		||||
         svga_buffer_destroy_hw_storage(ss, sbuf);
 | 
			
		||||
         return PIPE_ERROR;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      memcpy(map, sbuf->swbuf, sbuf->base.size);
 | 
			
		||||
      ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
 | 
			
		||||
      ss->sws->buffer_unmap(ss->sws, sbuf->hwbuf);
 | 
			
		||||
 | 
			
		||||
      /* This user/malloc buffer is now indistinguishable from a gpu buffer */
 | 
			
		||||
      assert(!sbuf->map.count);
 | 
			
		||||
@@ -635,10 +657,89 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
 | 
			
		||||
         sbuf->swbuf = NULL;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
 | 
			
		||||
      pipe_mutex_unlock(ss->swc_mutex);
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   pipe_mutex_unlock(ss->swc_mutex);
 | 
			
		||||
   return PIPE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Upload the buffer to the host in a piecewise fashion.
 | 
			
		||||
 *
 | 
			
		||||
 * Used when the buffer is too big to fit in the GMR aperture.
 | 
			
		||||
 */
 | 
			
		||||
static INLINE enum pipe_error
 | 
			
		||||
svga_buffer_upload_piecewise(struct svga_screen *ss,
 | 
			
		||||
                             struct svga_context *svga,
 | 
			
		||||
                             struct svga_buffer *sbuf)
 | 
			
		||||
{
 | 
			
		||||
   struct svga_winsys_screen *sws = ss->sws;
 | 
			
		||||
   const unsigned alignment = sizeof(void *);
 | 
			
		||||
   const unsigned usage = 0;
 | 
			
		||||
   unsigned i;
 | 
			
		||||
 | 
			
		||||
   assert(sbuf->map.num_ranges);
 | 
			
		||||
   assert(!sbuf->dma.pending);
 | 
			
		||||
 | 
			
		||||
   SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
 | 
			
		||||
 | 
			
		||||
   for (i = 0; i < sbuf->map.num_ranges; ++i) {
 | 
			
		||||
      struct svga_buffer_range *range = &sbuf->map.ranges[i];
 | 
			
		||||
      unsigned offset = range->start;
 | 
			
		||||
      unsigned size = range->end - range->start;
 | 
			
		||||
 | 
			
		||||
      while (offset < range->end) {
 | 
			
		||||
         struct svga_winsys_buffer *hwbuf;
 | 
			
		||||
         uint8_t *map;
 | 
			
		||||
         enum pipe_error ret;
 | 
			
		||||
 | 
			
		||||
         if (offset + size > range->end)
 | 
			
		||||
            size = range->end - offset;
 | 
			
		||||
 | 
			
		||||
         hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
 | 
			
		||||
         while (!hwbuf) {
 | 
			
		||||
            size /= 2;
 | 
			
		||||
            if (!size)
 | 
			
		||||
               return PIPE_ERROR_OUT_OF_MEMORY;
 | 
			
		||||
            hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         SVGA_DBG(DEBUG_DMA, "  bytes %u - %u\n",
 | 
			
		||||
                  offset, offset + size);
 | 
			
		||||
 | 
			
		||||
         map = sws->buffer_map(sws, hwbuf,
 | 
			
		||||
                               PIPE_BUFFER_USAGE_CPU_WRITE |
 | 
			
		||||
                               PIPE_BUFFER_USAGE_DISCARD);
 | 
			
		||||
         assert(map);
 | 
			
		||||
         if (map) {
 | 
			
		||||
            memcpy(map, sbuf->swbuf, size);
 | 
			
		||||
            sws->buffer_unmap(sws, hwbuf);
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         ret = SVGA3D_BufferDMA(svga->swc,
 | 
			
		||||
                                hwbuf, sbuf->handle,
 | 
			
		||||
                                SVGA3D_WRITE_HOST_VRAM,
 | 
			
		||||
                                size, 0, offset, sbuf->dma.flags);
 | 
			
		||||
         if(ret != PIPE_OK) {
 | 
			
		||||
            svga_context_flush(svga, NULL);
 | 
			
		||||
            ret =  SVGA3D_BufferDMA(svga->swc,
 | 
			
		||||
                                    hwbuf, sbuf->handle,
 | 
			
		||||
                                    SVGA3D_WRITE_HOST_VRAM,
 | 
			
		||||
                                    size, 0, offset, sbuf->dma.flags);
 | 
			
		||||
            assert(ret == PIPE_OK);
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         sbuf->dma.flags.discard = FALSE;
 | 
			
		||||
 | 
			
		||||
         sws->buffer_destroy(sws, hwbuf);
 | 
			
		||||
 | 
			
		||||
         offset += size;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   sbuf->map.num_ranges = 0;
 | 
			
		||||
 | 
			
		||||
   return PIPE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -658,34 +759,74 @@ svga_buffer_handle(struct svga_context *svga,
 | 
			
		||||
   sbuf = svga_buffer(buf);
 | 
			
		||||
   
 | 
			
		||||
   assert(!sbuf->map.count);
 | 
			
		||||
   assert(!sbuf->user);
 | 
			
		||||
   
 | 
			
		||||
   if(!sbuf->handle) {
 | 
			
		||||
      ret = svga_buffer_create_host_surface(ss, sbuf);
 | 
			
		||||
      if(ret != PIPE_OK)
 | 
			
		||||
	 return NULL;
 | 
			
		||||
 | 
			
		||||
      ret = svga_buffer_update_hw(ss, sbuf);
 | 
			
		||||
      if(ret != PIPE_OK)
 | 
			
		||||
	 return NULL;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if(!sbuf->needs_flush && sbuf->hw.num_ranges) {
 | 
			
		||||
      /* Queue the buffer for flushing */
 | 
			
		||||
      ret = svga_buffer_upload_command(svga, sbuf);
 | 
			
		||||
      if(ret != PIPE_OK)
 | 
			
		||||
         /* XXX: Should probably have a richer return value */
 | 
			
		||||
         return NULL;
 | 
			
		||||
   assert(sbuf->handle);
 | 
			
		||||
 | 
			
		||||
      assert(sbuf->hw.svga == svga);
 | 
			
		||||
   if (sbuf->map.num_ranges) {
 | 
			
		||||
      if (!sbuf->dma.pending) {
 | 
			
		||||
         /*
 | 
			
		||||
          * No pending DMA upload yet, so insert a DMA upload command now.
 | 
			
		||||
          */
 | 
			
		||||
 | 
			
		||||
      sbuf->needs_flush = TRUE;
 | 
			
		||||
      assert(!sbuf->head.prev && !sbuf->head.next);
 | 
			
		||||
      LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
 | 
			
		||||
         /*
 | 
			
		||||
          * Migrate the data from swbuf -> hwbuf if necessary.
 | 
			
		||||
          */
 | 
			
		||||
         ret = svga_buffer_update_hw(ss, sbuf);
 | 
			
		||||
         if (ret == PIPE_OK) {
 | 
			
		||||
            /*
 | 
			
		||||
             * Queue a dma command.
 | 
			
		||||
             */
 | 
			
		||||
 | 
			
		||||
            ret = svga_buffer_upload_command(svga, sbuf);
 | 
			
		||||
            if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
 | 
			
		||||
               svga_context_flush(svga, NULL);
 | 
			
		||||
               ret = svga_buffer_upload_command(svga, sbuf);
 | 
			
		||||
               assert(ret == PIPE_OK);
 | 
			
		||||
            }
 | 
			
		||||
            if (ret == PIPE_OK) {
 | 
			
		||||
               sbuf->dma.pending = TRUE;
 | 
			
		||||
               assert(!sbuf->head.prev && !sbuf->head.next);
 | 
			
		||||
               LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
         else if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
 | 
			
		||||
            /*
 | 
			
		||||
             * The buffer is too big to fit in the GMR aperture, so break it in
 | 
			
		||||
             * smaller pieces.
 | 
			
		||||
             */
 | 
			
		||||
            ret = svga_buffer_upload_piecewise(ss, svga, sbuf);
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         if (ret != PIPE_OK) {
 | 
			
		||||
            /*
 | 
			
		||||
             * Something unexpected happened above. There is very little that
 | 
			
		||||
             * we can do other than proceeding while ignoring the dirty ranges.
 | 
			
		||||
             */
 | 
			
		||||
            assert(0);
 | 
			
		||||
            sbuf->map.num_ranges = 0;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
         /*
 | 
			
		||||
          * There a pending dma already. Make sure it is from this context.
 | 
			
		||||
          */
 | 
			
		||||
         assert(sbuf->dma.svga == svga);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   assert(!sbuf->map.num_ranges || sbuf->dma.pending);
 | 
			
		||||
 | 
			
		||||
   return sbuf->handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct pipe_buffer *
 | 
			
		||||
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
 | 
			
		||||
				enum SVGA3dSurfaceFormat format,
 | 
			
		||||
@@ -738,7 +879,7 @@ svga_context_flush_buffers(struct svga_context *svga)
 | 
			
		||||
      sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
 | 
			
		||||
 | 
			
		||||
      assert(p_atomic_read(&sbuf->base.reference.count) != 0);
 | 
			
		||||
      assert(sbuf->needs_flush);
 | 
			
		||||
      assert(sbuf->dma.pending);
 | 
			
		||||
      
 | 
			
		||||
      svga_buffer_upload_flush(svga, sbuf);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,35 +56,6 @@ struct svga_buffer_range
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Describe a
 | 
			
		||||
 *
 | 
			
		||||
 * This holds the information to emit a SVGA3dCmdSurfaceDMA.
 | 
			
		||||
 */
 | 
			
		||||
struct svga_buffer_upload
 | 
			
		||||
{
 | 
			
		||||
   /**
 | 
			
		||||
    * Guest memory region.
 | 
			
		||||
    */
 | 
			
		||||
   struct svga_winsys_buffer *buf;
 | 
			
		||||
 | 
			
		||||
   struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
 | 
			
		||||
   unsigned num_ranges;
 | 
			
		||||
 | 
			
		||||
   SVGA3dSurfaceDMAFlags flags;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Pointer to the DMA copy box *inside* the command buffer.
 | 
			
		||||
    */
 | 
			
		||||
   SVGA3dCopyBox *boxes;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Context that has the pending DMA to this buffer.
 | 
			
		||||
    */
 | 
			
		||||
   struct svga_context *svga;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SVGA pipe buffer.
 | 
			
		||||
 */
 | 
			
		||||
@@ -110,14 +81,6 @@ struct svga_buffer
 | 
			
		||||
    */
 | 
			
		||||
   boolean user;
 | 
			
		||||
   
 | 
			
		||||
   /**
 | 
			
		||||
    * DMA'ble memory.
 | 
			
		||||
    * 
 | 
			
		||||
    * A piece of GMR memory. It is created when mapping the buffer, and will be
 | 
			
		||||
    * used to upload/download vertex data from the host.
 | 
			
		||||
    */
 | 
			
		||||
   struct svga_buffer_upload hw;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Creation key for the host surface handle.
 | 
			
		||||
    * 
 | 
			
		||||
@@ -134,19 +97,94 @@ struct svga_buffer
 | 
			
		||||
    * trying to bind
 | 
			
		||||
    */
 | 
			
		||||
   struct svga_winsys_surface *handle;
 | 
			
		||||
   
 | 
			
		||||
   /**
 | 
			
		||||
    * Whether the host has been ever written.
 | 
			
		||||
    */
 | 
			
		||||
   boolean host_written;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Information about ongoing and past map operations.
 | 
			
		||||
    */
 | 
			
		||||
   struct {
 | 
			
		||||
      /**
 | 
			
		||||
       * Number of concurrent mappings.
 | 
			
		||||
       *
 | 
			
		||||
       * XXX: It is impossible to guarantee concurrent maps work in all
 | 
			
		||||
       * circumstances -- pipe_buffers really need transfer objects too.
 | 
			
		||||
       */
 | 
			
		||||
      unsigned count;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Whether this buffer is currently mapped for writing.
 | 
			
		||||
       */
 | 
			
		||||
      boolean writing;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Whether the application will tell us explicity which ranges it touched
 | 
			
		||||
       * or not.
 | 
			
		||||
       */
 | 
			
		||||
      boolean flush_explicit;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Dirty ranges.
 | 
			
		||||
       *
 | 
			
		||||
       * Ranges that were touched by the application and need to be uploaded to
 | 
			
		||||
       * the host.
 | 
			
		||||
       *
 | 
			
		||||
       * This information will be copied into dma.boxes, when emiting the
 | 
			
		||||
       * SVGA3dCmdSurfaceDMA command.
 | 
			
		||||
       */
 | 
			
		||||
      struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
 | 
			
		||||
      unsigned num_ranges;
 | 
			
		||||
   } map;
 | 
			
		||||
   
 | 
			
		||||
   boolean needs_flush;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Information about uploaded version of user buffers.
 | 
			
		||||
    */
 | 
			
		||||
   struct {
 | 
			
		||||
      struct pipe_buffer *buffer;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * We combine multiple user buffers into the same hardware buffer. This
 | 
			
		||||
       * is the relative offset within that buffer.
 | 
			
		||||
       */
 | 
			
		||||
      unsigned offset;
 | 
			
		||||
   } uploaded;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * DMA'ble memory.
 | 
			
		||||
    *
 | 
			
		||||
    * A piece of GMR memory, with the same size of the buffer. It is created
 | 
			
		||||
    * when mapping the buffer, and will be used to upload vertex data to the
 | 
			
		||||
    * host.
 | 
			
		||||
    */
 | 
			
		||||
   struct svga_winsys_buffer *hwbuf;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Information about pending DMA uploads.
 | 
			
		||||
    *
 | 
			
		||||
    */
 | 
			
		||||
   struct {
 | 
			
		||||
      /**
 | 
			
		||||
       * Whether this buffer has an unfinished DMA upload command.
 | 
			
		||||
       *
 | 
			
		||||
       * If not set then the rest of the information is null.
 | 
			
		||||
       */
 | 
			
		||||
      boolean pending;
 | 
			
		||||
 | 
			
		||||
      SVGA3dSurfaceDMAFlags flags;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Pointer to the DMA copy box *inside* the command buffer.
 | 
			
		||||
       */
 | 
			
		||||
      SVGA3dCopyBox *boxes;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Context that has the pending DMA to this buffer.
 | 
			
		||||
       */
 | 
			
		||||
      struct svga_context *svga;
 | 
			
		||||
   } dma;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Linked list head, used to gather all buffers with pending dma uploads on
 | 
			
		||||
    * a context. It is only valid if the dma.pending is set above.
 | 
			
		||||
    */
 | 
			
		||||
   struct list_head head;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -176,6 +214,16 @@ svga_buffer_is_user_buffer( struct pipe_buffer *buffer )
 | 
			
		||||
void
 | 
			
		||||
svga_screen_init_buffer_functions(struct pipe_screen *screen);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the host surface handle for this buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * This will ensure the host surface is updated, issuing DMAs as needed.
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: This may insert new commands in the context, so it *must* be called
 | 
			
		||||
 * before reserving command buffer space. And, in order to insert commands
 | 
			
		||||
 * it may need to call svga_context_flush().
 | 
			
		||||
 */
 | 
			
		||||
struct svga_winsys_surface *
 | 
			
		||||
svga_buffer_handle(struct svga_context *svga,
 | 
			
		||||
                   struct pipe_buffer *buf);
 | 
			
		||||
 
 | 
			
		||||
@@ -203,7 +203,7 @@ svga_transfer_dma(struct svga_transfer *st,
 | 
			
		||||
      if(transfer == SVGA3D_READ_HOST_VRAM) {
 | 
			
		||||
         svga_screen_flush(screen, &fence);
 | 
			
		||||
         sws->fence_finish(sws, fence, 0);
 | 
			
		||||
         //sws->fence_reference(sws, &fence, NULL);
 | 
			
		||||
         sws->fence_reference(sws, &fence, NULL);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
   else {
 | 
			
		||||
@@ -232,7 +232,7 @@ svga_transfer_dma(struct svga_transfer *st,
 | 
			
		||||
            if(y) {
 | 
			
		||||
               svga_screen_flush(screen, &fence);
 | 
			
		||||
               sws->fence_finish(sws, fence, 0);
 | 
			
		||||
               //sws->fence_reference(sws, &fence, NULL);
 | 
			
		||||
               sws->fence_reference(sws, &fence, NULL);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ struct svga_winsys_surface;
 | 
			
		||||
enum SVGA3dSurfaceFormat;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */
 | 
			
		||||
#define SVGA_MAX_TEXTURE_LEVELS 16
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -103,70 +103,6 @@ fail:
 | 
			
		||||
   return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* The blend workaround for simulating logicop xor behaviour requires
 | 
			
		||||
 * that the incoming fragment color be white.  This change achieves
 | 
			
		||||
 * that by hooking up a hard-wired fragment shader that just emits
 | 
			
		||||
 * color 1,1,1,1
 | 
			
		||||
 *   
 | 
			
		||||
 * This is a slightly incomplete solution as it assumes that the
 | 
			
		||||
 * actual bound shader has no other effects beyond generating a
 | 
			
		||||
 * fragment color.  In particular shaders containing TEXKIL and/or
 | 
			
		||||
 * depth-write will not have the correct behaviour, nor will those
 | 
			
		||||
 * expecting to use alphatest.
 | 
			
		||||
 *   
 | 
			
		||||
 * These are avoidable issues, but they are not much worse than the
 | 
			
		||||
 * unavoidable ones associated with this technique, so it's not clear
 | 
			
		||||
 * how much effort should be expended trying to resolve them - the
 | 
			
		||||
 * ultimate result will still not be correct in most cases.
 | 
			
		||||
 *
 | 
			
		||||
 * Shader below was generated with:
 | 
			
		||||
 *   SVGA_DEBUG=tgsi ./mesa/progs/fp/fp-tri white.txt
 | 
			
		||||
 */
 | 
			
		||||
static int emit_white_fs( struct svga_context *svga )
 | 
			
		||||
{
 | 
			
		||||
   int ret = PIPE_ERROR;
 | 
			
		||||
 | 
			
		||||
   /* ps_3_0
 | 
			
		||||
    * def c0, 1.000000, 0.000000, 0.000000, 1.000000
 | 
			
		||||
    * mov oC0, c0.x
 | 
			
		||||
    * end
 | 
			
		||||
    */
 | 
			
		||||
   static const unsigned white_tokens[] = {
 | 
			
		||||
      0xffff0300,
 | 
			
		||||
      0x05000051,
 | 
			
		||||
      0xa00f0000,
 | 
			
		||||
      0x3f800000,
 | 
			
		||||
      0x00000000,
 | 
			
		||||
      0x00000000,
 | 
			
		||||
      0x3f800000,
 | 
			
		||||
      0x02000001,
 | 
			
		||||
      0x800f0800,
 | 
			
		||||
      0xa0000000,
 | 
			
		||||
      0x0000ffff,
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   assert(SVGA3D_INVALID_ID == UTIL_BITMASK_INVALID_INDEX);
 | 
			
		||||
   svga->state.white_fs_id = util_bitmask_add(svga->fs_bm);
 | 
			
		||||
   if(svga->state.white_fs_id == SVGA3D_INVALID_ID)
 | 
			
		||||
      goto no_fs_id;
 | 
			
		||||
 | 
			
		||||
   ret = SVGA3D_DefineShader(svga->swc, 
 | 
			
		||||
                             svga->state.white_fs_id,
 | 
			
		||||
                             SVGA3D_SHADERTYPE_PS,
 | 
			
		||||
                             white_tokens, 
 | 
			
		||||
                             sizeof(white_tokens));
 | 
			
		||||
   if (ret)
 | 
			
		||||
      goto no_definition;
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
 | 
			
		||||
no_definition:
 | 
			
		||||
   util_bitmask_clear(svga->fs_bm, svga->state.white_fs_id);
 | 
			
		||||
   svga->state.white_fs_id = SVGA3D_INVALID_ID;
 | 
			
		||||
no_fs_id:
 | 
			
		||||
   return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* SVGA_NEW_TEXTURE_BINDING
 | 
			
		||||
 * SVGA_NEW_RAST
 | 
			
		||||
@@ -194,6 +130,23 @@ static int make_fs_key( const struct svga_context *svga,
 | 
			
		||||
                       PIPE_WINDING_CW);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* The blend workaround for simulating logicop xor behaviour
 | 
			
		||||
    * requires that the incoming fragment color be white.  This change
 | 
			
		||||
    * achieves that by creating a varient of the current fragment
 | 
			
		||||
    * shader that overrides all output colors with 1,1,1,1
 | 
			
		||||
    *   
 | 
			
		||||
    * This will work for most shaders, including those containing
 | 
			
		||||
    * TEXKIL and/or depth-write.  However, it will break on the
 | 
			
		||||
    * combination of xor-logicop plus alphatest.
 | 
			
		||||
    *
 | 
			
		||||
    * Ultimately, we could implement alphatest in the shader using
 | 
			
		||||
    * texkil prior to overriding the outgoing fragment color.
 | 
			
		||||
    *   
 | 
			
		||||
    * SVGA_NEW_BLEND
 | 
			
		||||
    */
 | 
			
		||||
   if (svga->curr.blend->need_white_fragments) {
 | 
			
		||||
      key->white_fragments = 1;
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   /* XXX: want to limit this to the textures that the shader actually
 | 
			
		||||
    * refers to.
 | 
			
		||||
@@ -233,40 +186,29 @@ static int emit_hw_fs( struct svga_context *svga,
 | 
			
		||||
   unsigned id = SVGA3D_INVALID_ID;
 | 
			
		||||
   int ret = 0;
 | 
			
		||||
 | 
			
		||||
   /* SVGA_NEW_BLEND
 | 
			
		||||
    */
 | 
			
		||||
   if (svga->curr.blend->need_white_fragments) {
 | 
			
		||||
      if (svga->state.white_fs_id == SVGA3D_INVALID_ID) {
 | 
			
		||||
         ret = emit_white_fs( svga );
 | 
			
		||||
         if (ret)
 | 
			
		||||
            return ret;
 | 
			
		||||
      }
 | 
			
		||||
      id = svga->state.white_fs_id;
 | 
			
		||||
   }
 | 
			
		||||
   else {
 | 
			
		||||
      struct svga_fragment_shader *fs = svga->curr.fs;
 | 
			
		||||
      struct svga_fs_compile_key key;
 | 
			
		||||
   struct svga_fragment_shader *fs = svga->curr.fs;
 | 
			
		||||
   struct svga_fs_compile_key key;
 | 
			
		||||
 | 
			
		||||
      /* SVGA_NEW_TEXTURE_BINDING
 | 
			
		||||
       * SVGA_NEW_RAST
 | 
			
		||||
       * SVGA_NEW_NEED_SWTNL
 | 
			
		||||
       * SVGA_NEW_SAMPLER
 | 
			
		||||
       */
 | 
			
		||||
      ret = make_fs_key( svga, &key );
 | 
			
		||||
   /* SVGA_NEW_BLEND
 | 
			
		||||
    * SVGA_NEW_TEXTURE_BINDING
 | 
			
		||||
    * SVGA_NEW_RAST
 | 
			
		||||
    * SVGA_NEW_NEED_SWTNL
 | 
			
		||||
    * SVGA_NEW_SAMPLER
 | 
			
		||||
    */
 | 
			
		||||
   ret = make_fs_key( svga, &key );
 | 
			
		||||
   if (ret)
 | 
			
		||||
      return ret;
 | 
			
		||||
 | 
			
		||||
   result = search_fs_key( fs, &key );
 | 
			
		||||
   if (!result) {
 | 
			
		||||
      ret = compile_fs( svga, fs, &key, &result );
 | 
			
		||||
      if (ret)
 | 
			
		||||
         return ret;
 | 
			
		||||
 | 
			
		||||
      result = search_fs_key( fs, &key );
 | 
			
		||||
      if (!result) {
 | 
			
		||||
         ret = compile_fs( svga, fs, &key, &result );
 | 
			
		||||
         if (ret)
 | 
			
		||||
            return ret;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      assert (result);
 | 
			
		||||
      id = result->id;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   assert (result);
 | 
			
		||||
   id = result->id;
 | 
			
		||||
 | 
			
		||||
   assert(id != SVGA3D_INVALID_ID);
 | 
			
		||||
 | 
			
		||||
   if (result != svga->state.hw_draw.fs) {
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,19 @@ static int emit_rss( struct svga_context *svga,
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   if (dirty & SVGA_NEW_BLEND_COLOR) {
 | 
			
		||||
      uint32 color;
 | 
			
		||||
      uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
 | 
			
		||||
      uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
 | 
			
		||||
      uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
 | 
			
		||||
      uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);
 | 
			
		||||
 | 
			
		||||
      color = (a << 24) | (r << 16) | (g << 8) | b;
 | 
			
		||||
 | 
			
		||||
      EMIT_RS( svga, color, BLENDCOLOR, fail );
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
 | 
			
		||||
      const struct svga_depth_stencil_state *curr = svga->curr.depth; 
 | 
			
		||||
      const struct svga_rasterizer_state *rast = svga->curr.rast; 
 | 
			
		||||
@@ -179,18 +192,28 @@ static int emit_rss( struct svga_context *svga,
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   if (dirty & SVGA_NEW_RAST)
 | 
			
		||||
   if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
 | 
			
		||||
   {
 | 
			
		||||
      const struct svga_rasterizer_state *curr = svga->curr.rast; 
 | 
			
		||||
      unsigned cullmode = curr->cullmode;
 | 
			
		||||
 | 
			
		||||
      /* Shademode: still need to rearrange index list to move
 | 
			
		||||
       * flat-shading PV first vertex.
 | 
			
		||||
       */
 | 
			
		||||
      EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
 | 
			
		||||
      EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
 | 
			
		||||
 | 
			
		||||
      /* Don't do culling while the software pipeline is active.  It
 | 
			
		||||
       * does it for us, and additionally introduces potentially
 | 
			
		||||
       * back-facing triangles.
 | 
			
		||||
       */
 | 
			
		||||
      if (svga->state.sw.need_pipeline)
 | 
			
		||||
         cullmode = SVGA3D_FACE_NONE;
 | 
			
		||||
 | 
			
		||||
      EMIT_RS( svga, cullmode, CULLMODE, fail );
 | 
			
		||||
      EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
 | 
			
		||||
      EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
 | 
			
		||||
      EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
 | 
			
		||||
      EMIT_RS( svga, curr->pointspriteenable, POINTSPRITEENABLE, fail );
 | 
			
		||||
      EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
 | 
			
		||||
      EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
 | 
			
		||||
      EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail );
 | 
			
		||||
@@ -230,13 +253,10 @@ static int emit_rss( struct svga_context *svga,
 | 
			
		||||
      memcpy( rs,
 | 
			
		||||
              queue.rs,
 | 
			
		||||
              queue.rs_count * sizeof queue.rs[0]);
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      SVGA_FIFOCommitAll( svga->swc );
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* Also blend color:
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
@@ -256,6 +276,7 @@ struct svga_tracked_state svga_hw_rss =
 | 
			
		||||
   "hw rss state",
 | 
			
		||||
 | 
			
		||||
   (SVGA_NEW_BLEND |
 | 
			
		||||
    SVGA_NEW_BLEND_COLOR |
 | 
			
		||||
    SVGA_NEW_DEPTH_STENCIL |
 | 
			
		||||
    SVGA_NEW_RAST |
 | 
			
		||||
    SVGA_NEW_FRAME_BUFFER |
 | 
			
		||||
 
 | 
			
		||||
@@ -54,33 +54,30 @@ upload_user_buffers( struct svga_context *svga )
 | 
			
		||||
   {
 | 
			
		||||
      if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
 | 
			
		||||
      {
 | 
			
		||||
         struct pipe_buffer *upload_buffer = NULL;
 | 
			
		||||
         unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0;
 | 
			
		||||
         unsigned size = svga->curr.vb[i].buffer->size /*- offset*/;
 | 
			
		||||
         unsigned upload_offset;
 | 
			
		||||
         struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer);
 | 
			
		||||
 | 
			
		||||
         ret = u_upload_buffer( svga->upload_vb,
 | 
			
		||||
                                offset,
 | 
			
		||||
                                size,
 | 
			
		||||
                                svga->curr.vb[i].buffer,
 | 
			
		||||
                                &upload_offset,
 | 
			
		||||
                                &upload_buffer );
 | 
			
		||||
         if (ret)
 | 
			
		||||
            return ret;
 | 
			
		||||
         if (!buffer->uploaded.buffer) {
 | 
			
		||||
            ret = u_upload_buffer( svga->upload_vb,
 | 
			
		||||
                                   0,
 | 
			
		||||
                                   buffer->base.size,
 | 
			
		||||
                                   &buffer->base,
 | 
			
		||||
                                   &buffer->uploaded.offset,
 | 
			
		||||
                                   &buffer->uploaded.buffer );
 | 
			
		||||
            if (ret)
 | 
			
		||||
               return ret;
 | 
			
		||||
 | 
			
		||||
         if (0)
 | 
			
		||||
            debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", 
 | 
			
		||||
                         __FUNCTION__, 
 | 
			
		||||
                         i,
 | 
			
		||||
                         svga->curr.vb[i].buffer,
 | 
			
		||||
                         upload_buffer, upload_offset, size);
 | 
			
		||||
            if (0)
 | 
			
		||||
               debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
 | 
			
		||||
                            __FUNCTION__,
 | 
			
		||||
                            i,
 | 
			
		||||
                            buffer,
 | 
			
		||||
                            buffer->uploaded.buffer,
 | 
			
		||||
                            buffer->uploaded.offset,
 | 
			
		||||
                            buffer->base.size);
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         /* Make sure we release the old buffer and end up with the
 | 
			
		||||
          * correct refcount on the uploaded buffer.
 | 
			
		||||
          */
 | 
			
		||||
         pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL );
 | 
			
		||||
         svga->curr.vb[i].buffer = upload_buffer;
 | 
			
		||||
         svga->curr.vb[i].buffer_offset = upload_offset;
 | 
			
		||||
         pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
 | 
			
		||||
         svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@ struct svga_fs_compile_key
 | 
			
		||||
{
 | 
			
		||||
   boolean light_twoside:1;
 | 
			
		||||
   boolean front_cw:1;
 | 
			
		||||
   boolean white_fragments:1;
 | 
			
		||||
   ubyte num_textures;
 | 
			
		||||
   ubyte num_unnormalized_coords;
 | 
			
		||||
   struct {
 | 
			
		||||
 
 | 
			
		||||
@@ -194,8 +194,19 @@ static boolean ps30_output( struct svga_shader_emitter *emit,
 | 
			
		||||
 | 
			
		||||
   switch (semantic.SemanticName) {
 | 
			
		||||
   case TGSI_SEMANTIC_COLOR:
 | 
			
		||||
      emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, 
 | 
			
		||||
                                            semantic.SemanticIndex );
 | 
			
		||||
      if (emit->unit == PIPE_SHADER_FRAGMENT &&
 | 
			
		||||
          emit->key.fkey.white_fragments) {
 | 
			
		||||
 | 
			
		||||
         emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
 | 
			
		||||
                                               emit->nr_hw_temp++ );
 | 
			
		||||
         emit->temp_col[idx] = emit->output_map[idx];
 | 
			
		||||
         emit->true_col[idx] = dst_register( SVGA3DREG_COLOROUT, 
 | 
			
		||||
                                              semantic.SemanticIndex );
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
         emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, 
 | 
			
		||||
                                               semantic.SemanticIndex );
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
   case TGSI_SEMANTIC_POSITION:
 | 
			
		||||
      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,8 @@ struct svga_shader_emitter
 | 
			
		||||
 | 
			
		||||
   int ps30_input_count;
 | 
			
		||||
 | 
			
		||||
   int dynamic_branching_level;
 | 
			
		||||
 | 
			
		||||
   boolean in_main_func;
 | 
			
		||||
 | 
			
		||||
   boolean created_zero_immediate;
 | 
			
		||||
@@ -136,6 +138,7 @@ static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
 | 
			
		||||
                         SVGA3dShaderDestToken dest )
 | 
			
		||||
{
 | 
			
		||||
   assert(dest.reserved0);
 | 
			
		||||
   assert(dest.mask);
 | 
			
		||||
   return svga_shader_emit_dword( emit, dest.value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -199,6 +202,23 @@ static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static INLINE boolean emit_op4( struct svga_shader_emitter *emit,
 | 
			
		||||
                                SVGA3dShaderInstToken inst,
 | 
			
		||||
                                SVGA3dShaderDestToken dest,
 | 
			
		||||
                                struct src_register src0,
 | 
			
		||||
                                struct src_register src1,
 | 
			
		||||
                                struct src_register src2,
 | 
			
		||||
                                struct src_register src3)
 | 
			
		||||
{
 | 
			
		||||
   return (emit_instruction( emit, inst ) &&
 | 
			
		||||
           emit_dst( emit, dest ) &&
 | 
			
		||||
           emit_src( emit, src0 ) &&
 | 
			
		||||
           emit_src( emit, src1 ) &&
 | 
			
		||||
           emit_src( emit, src2 ) &&
 | 
			
		||||
           emit_src( emit, src3 ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define TRANSLATE_SWIZZLE(x,y,z,w)  ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
 | 
			
		||||
#define SWIZZLE_XYZW  \
 | 
			
		||||
 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
 | 
			
		||||
@@ -248,6 +268,7 @@ static INLINE SVGA3dShaderDestToken
 | 
			
		||||
writemask( SVGA3dShaderDestToken dest,
 | 
			
		||||
           unsigned mask )
 | 
			
		||||
{
 | 
			
		||||
   assert(dest.mask & mask);
 | 
			
		||||
   dest.mask &= mask;
 | 
			
		||||
   return dest;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -46,8 +46,6 @@ translate_opcode(
 | 
			
		||||
   case TGSI_OPCODE_ABS:        return SVGA3DOP_ABS;
 | 
			
		||||
   case TGSI_OPCODE_ADD:        return SVGA3DOP_ADD;
 | 
			
		||||
   case TGSI_OPCODE_BREAKC:     return SVGA3DOP_BREAKC;
 | 
			
		||||
   case TGSI_OPCODE_DDX:        return SVGA3DOP_DSX;
 | 
			
		||||
   case TGSI_OPCODE_DDY:        return SVGA3DOP_DSY;
 | 
			
		||||
   case TGSI_OPCODE_DP2A:       return SVGA3DOP_DP2ADD;
 | 
			
		||||
   case TGSI_OPCODE_DP3:        return SVGA3DOP_DP3;
 | 
			
		||||
   case TGSI_OPCODE_DP4:        return SVGA3DOP_DP4;
 | 
			
		||||
@@ -114,6 +112,7 @@ translate_dst_register( struct svga_shader_emitter *emit,
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   dest.mask = reg->DstRegister.WriteMask;
 | 
			
		||||
   assert(dest.mask);
 | 
			
		||||
 | 
			
		||||
   if (insn->Instruction.Saturate) 
 | 
			
		||||
      dest.dstMod = SVGA3DDSTMOD_SATURATE;
 | 
			
		||||
@@ -415,6 +414,88 @@ static boolean submit_op3( struct svga_shader_emitter *emit,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* SVGA shaders may not refer to >1 constant register in a single
 | 
			
		||||
 * instruction.  This function checks for that usage and inserts a
 | 
			
		||||
 * move to temporary if detected.
 | 
			
		||||
 */
 | 
			
		||||
static boolean submit_op4( struct svga_shader_emitter *emit,
 | 
			
		||||
                           SVGA3dShaderInstToken inst,
 | 
			
		||||
                           SVGA3dShaderDestToken dest,
 | 
			
		||||
                           struct src_register src0,
 | 
			
		||||
                           struct src_register src1,
 | 
			
		||||
                           struct src_register src2,
 | 
			
		||||
                           struct src_register src3)
 | 
			
		||||
{
 | 
			
		||||
   SVGA3dShaderDestToken temp0;
 | 
			
		||||
   SVGA3dShaderDestToken temp3;
 | 
			
		||||
   boolean need_temp0 = FALSE;
 | 
			
		||||
   boolean need_temp3 = FALSE;
 | 
			
		||||
   SVGA3dShaderRegType type0, type1, type2, type3;
 | 
			
		||||
 | 
			
		||||
   temp0.value = 0;
 | 
			
		||||
   temp3.value = 0;
 | 
			
		||||
   type0 = SVGA3dShaderGetRegType( src0.base.value );
 | 
			
		||||
   type1 = SVGA3dShaderGetRegType( src1.base.value );
 | 
			
		||||
   type2 = SVGA3dShaderGetRegType( src2.base.value );
 | 
			
		||||
   type3 = SVGA3dShaderGetRegType( src2.base.value );
 | 
			
		||||
 | 
			
		||||
   /* Make life a little easier - this is only used by the TXD
 | 
			
		||||
    * instruction which is guaranteed not to have a constant/input reg
 | 
			
		||||
    * in one slot at least:
 | 
			
		||||
    */
 | 
			
		||||
   assert(type1 == SVGA3DREG_SAMPLER);
 | 
			
		||||
 | 
			
		||||
   if (type0 == SVGA3DREG_CONST &&
 | 
			
		||||
       ((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) ||
 | 
			
		||||
        (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
 | 
			
		||||
      need_temp0 = TRUE;
 | 
			
		||||
 | 
			
		||||
   if (type3 == SVGA3DREG_CONST &&
 | 
			
		||||
       (type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num))
 | 
			
		||||
      need_temp3 = TRUE;
 | 
			
		||||
 | 
			
		||||
   if (type0 == SVGA3DREG_INPUT &&
 | 
			
		||||
       ((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) ||
 | 
			
		||||
        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
 | 
			
		||||
      need_temp0 = TRUE;
 | 
			
		||||
 | 
			
		||||
   if (type3 == SVGA3DREG_INPUT &&
 | 
			
		||||
       (type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num))
 | 
			
		||||
      need_temp3 = TRUE;
 | 
			
		||||
 | 
			
		||||
   if (need_temp0)
 | 
			
		||||
   {
 | 
			
		||||
      temp0 = get_temp( emit );
 | 
			
		||||
 
 | 
			
		||||
      if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp0, src0 ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
         
 | 
			
		||||
      src0 = src( temp0 );
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (need_temp3)
 | 
			
		||||
   {
 | 
			
		||||
      temp3 = get_temp( emit );
 | 
			
		||||
 | 
			
		||||
      if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp3, src3 ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      src3 = src( temp3 );
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 ))
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   if (need_temp3)
 | 
			
		||||
      release_temp( emit, temp3 );
 | 
			
		||||
   if (need_temp0)
 | 
			
		||||
      release_temp( emit, temp0 );
 | 
			
		||||
   return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static boolean emit_def_const( struct svga_shader_emitter *emit,
 | 
			
		||||
                               SVGA3dShaderConstType type,
 | 
			
		||||
                               unsigned idx,
 | 
			
		||||
@@ -660,6 +741,8 @@ static boolean emit_if(struct svga_shader_emitter *emit,
 | 
			
		||||
   if_token.control = SVGA3DOPCOMPC_NE;
 | 
			
		||||
   zero = scalar(zero, TGSI_SWIZZLE_X);
 | 
			
		||||
 | 
			
		||||
   emit->dynamic_branching_level++;
 | 
			
		||||
 | 
			
		||||
   return (emit_instruction( emit, if_token ) &&
 | 
			
		||||
           emit_src( emit, src ) &&
 | 
			
		||||
           emit_src( emit, zero ) );
 | 
			
		||||
@@ -668,6 +751,8 @@ static boolean emit_if(struct svga_shader_emitter *emit,
 | 
			
		||||
static boolean emit_endif(struct svga_shader_emitter *emit,
 | 
			
		||||
                       const struct tgsi_full_instruction *insn)
 | 
			
		||||
{
 | 
			
		||||
   emit->dynamic_branching_level--;
 | 
			
		||||
 | 
			
		||||
   return (emit_instruction( emit,
 | 
			
		||||
                             inst_token( SVGA3DOP_ENDIF )));
 | 
			
		||||
}
 | 
			
		||||
@@ -1011,10 +1096,10 @@ static boolean emit_kilp(struct svga_shader_emitter *emit,
 | 
			
		||||
{
 | 
			
		||||
   SVGA3dShaderInstToken inst;
 | 
			
		||||
   SVGA3dShaderDestToken temp;
 | 
			
		||||
   struct src_register one = get_zero_immediate( emit );
 | 
			
		||||
   struct src_register one = scalar( get_zero_immediate( emit ),
 | 
			
		||||
                                     TGSI_SWIZZLE_W );
 | 
			
		||||
 | 
			
		||||
   inst = inst_token( SVGA3DOP_TEXKILL );
 | 
			
		||||
   one = scalar( one, TGSI_SWIZZLE_W );
 | 
			
		||||
 | 
			
		||||
   /* texkill doesn't allow negation on the operand so lets move
 | 
			
		||||
    * negation of {1} to a temp register */
 | 
			
		||||
@@ -1169,41 +1254,79 @@ static boolean emit_tex2(struct svga_shader_emitter *emit,
 | 
			
		||||
                         SVGA3dShaderDestToken dst )
 | 
			
		||||
{
 | 
			
		||||
   SVGA3dShaderInstToken inst;
 | 
			
		||||
   struct src_register src0;
 | 
			
		||||
   struct src_register src1;
 | 
			
		||||
 | 
			
		||||
   struct src_register texcoord;
 | 
			
		||||
   struct src_register sampler;
 | 
			
		||||
   SVGA3dShaderDestToken tmp;
 | 
			
		||||
   
 | 
			
		||||
   inst.value = 0;
 | 
			
		||||
   inst.op = SVGA3DOP_TEX;
 | 
			
		||||
 | 
			
		||||
   switch (insn->Instruction.Opcode) {
 | 
			
		||||
   case TGSI_OPCODE_TEX:
 | 
			
		||||
      inst.op = SVGA3DOP_TEX;
 | 
			
		||||
      break;
 | 
			
		||||
   case TGSI_OPCODE_TXP:
 | 
			
		||||
      inst.op = SVGA3DOP_TEX;
 | 
			
		||||
      inst.control = SVGA3DOPCONT_PROJECT;
 | 
			
		||||
      break;
 | 
			
		||||
   case TGSI_OPCODE_TXB:
 | 
			
		||||
      inst.op = SVGA3DOP_TEX;
 | 
			
		||||
      inst.control = SVGA3DOPCONT_BIAS;
 | 
			
		||||
      break;
 | 
			
		||||
   case TGSI_OPCODE_TXL:
 | 
			
		||||
      inst.op = SVGA3DOP_TEXLDL;
 | 
			
		||||
      break;
 | 
			
		||||
   default:
 | 
			
		||||
      assert(0);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
 | 
			
		||||
   src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
 | 
			
		||||
   texcoord = translate_src_register( emit, &insn->FullSrcRegisters[0] );
 | 
			
		||||
   sampler = translate_src_register( emit, &insn->FullSrcRegisters[1] );
 | 
			
		||||
 | 
			
		||||
   if (emit->key.fkey.tex[src1.base.num].unnormalized) {
 | 
			
		||||
      struct src_register wh = get_tex_dimensions( emit, src1.base.num );
 | 
			
		||||
      SVGA3dShaderDestToken tmp = get_temp( emit );
 | 
			
		||||
   if (emit->key.fkey.tex[sampler.base.num].unnormalized ||
 | 
			
		||||
       emit->dynamic_branching_level > 0)
 | 
			
		||||
      tmp = get_temp( emit );
 | 
			
		||||
 | 
			
		||||
   /* Can't do mipmapping inside dynamic branch constructs.  Force LOD
 | 
			
		||||
    * zero in that case.
 | 
			
		||||
    */
 | 
			
		||||
   if (emit->dynamic_branching_level > 0 &&
 | 
			
		||||
       inst.op == SVGA3DOP_TEX &&
 | 
			
		||||
       SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) {
 | 
			
		||||
      struct src_register zero = get_zero_immediate( emit );
 | 
			
		||||
 | 
			
		||||
      /* MOV  tmp, texcoord */
 | 
			
		||||
      if (!submit_op1( emit,
 | 
			
		||||
                       inst_token( SVGA3DOP_MOV ),
 | 
			
		||||
                       tmp,
 | 
			
		||||
                       texcoord ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      /* MOV  tmp.w, zero */
 | 
			
		||||
      if (!submit_op1( emit, 
 | 
			
		||||
                       inst_token( SVGA3DOP_MOV ),
 | 
			
		||||
                       writemask( tmp, TGSI_WRITEMASK_W ), 
 | 
			
		||||
                       scalar( zero, TGSI_SWIZZLE_X )))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      
 | 
			
		||||
      texcoord = src( tmp );
 | 
			
		||||
      inst.op = SVGA3DOP_TEXLDL;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* Explicit normalization of texcoords:
 | 
			
		||||
    */
 | 
			
		||||
   if (emit->key.fkey.tex[sampler.base.num].unnormalized) {
 | 
			
		||||
      struct src_register wh = get_tex_dimensions( emit, sampler.base.num );
 | 
			
		||||
 | 
			
		||||
      /* MUL  tmp, SRC0, WH */
 | 
			
		||||
      if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
 | 
			
		||||
                       tmp, src0, wh ))
 | 
			
		||||
                       tmp, texcoord, wh ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      src0 = src( tmp );
 | 
			
		||||
 | 
			
		||||
      texcoord = src( tmp );
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   return submit_op2( emit, inst, dst, src0, src1 );
 | 
			
		||||
   return submit_op2( emit, inst, dst, texcoord, sampler );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1211,31 +1334,33 @@ static boolean emit_tex2(struct svga_shader_emitter *emit,
 | 
			
		||||
 | 
			
		||||
/* Translate texture instructions to SVGA3D representation.
 | 
			
		||||
 */
 | 
			
		||||
static boolean emit_tex3(struct svga_shader_emitter *emit,
 | 
			
		||||
static boolean emit_tex4(struct svga_shader_emitter *emit,
 | 
			
		||||
                         const struct tgsi_full_instruction *insn,
 | 
			
		||||
                         SVGA3dShaderDestToken dst )
 | 
			
		||||
{
 | 
			
		||||
   SVGA3dShaderInstToken inst;
 | 
			
		||||
   struct src_register src0;
 | 
			
		||||
   struct src_register src1;
 | 
			
		||||
   struct src_register src2;
 | 
			
		||||
   struct src_register texcoord;
 | 
			
		||||
   struct src_register ddx;
 | 
			
		||||
   struct src_register ddy;
 | 
			
		||||
   struct src_register sampler;
 | 
			
		||||
 | 
			
		||||
   texcoord = translate_src_register( emit, &insn->FullSrcRegisters[0] );
 | 
			
		||||
   ddx      = translate_src_register( emit, &insn->FullSrcRegisters[1] );
 | 
			
		||||
   ddy      = translate_src_register( emit, &insn->FullSrcRegisters[2] );
 | 
			
		||||
   sampler  = translate_src_register( emit, &insn->FullSrcRegisters[3] );
 | 
			
		||||
 | 
			
		||||
   inst.value = 0;
 | 
			
		||||
 | 
			
		||||
   switch (insn->Instruction.Opcode) {
 | 
			
		||||
   case TGSI_OPCODE_TXD: 
 | 
			
		||||
      inst.op = SVGA3DOP_TEXLDD;
 | 
			
		||||
      break;
 | 
			
		||||
   case TGSI_OPCODE_TXL:
 | 
			
		||||
      inst.op = SVGA3DOP_TEXLDL;
 | 
			
		||||
      inst.op = SVGA3DOP_TEXLDD; /* 4 args! */
 | 
			
		||||
      break;
 | 
			
		||||
   default:
 | 
			
		||||
      assert(0);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
 | 
			
		||||
   src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
 | 
			
		||||
   src2 = translate_src_register( emit, &insn->FullSrcRegisters[2] );
 | 
			
		||||
 | 
			
		||||
   return submit_op3( emit, inst, dst, src0, src1, src2 );
 | 
			
		||||
   return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1271,12 +1396,12 @@ static boolean emit_tex(struct svga_shader_emitter *emit,
 | 
			
		||||
   case TGSI_OPCODE_TEX:
 | 
			
		||||
   case TGSI_OPCODE_TXB:
 | 
			
		||||
   case TGSI_OPCODE_TXP:
 | 
			
		||||
   case TGSI_OPCODE_TXL:
 | 
			
		||||
      if (!emit_tex2( emit, insn, tex_result ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      break;
 | 
			
		||||
   case TGSI_OPCODE_TXL:
 | 
			
		||||
   case TGSI_OPCODE_TXD:
 | 
			
		||||
      if (!emit_tex3( emit, insn, tex_result ))
 | 
			
		||||
      if (!emit_tex4( emit, insn, tex_result ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      break;
 | 
			
		||||
   default:
 | 
			
		||||
@@ -1285,34 +1410,42 @@ static boolean emit_tex(struct svga_shader_emitter *emit,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   if (compare) {
 | 
			
		||||
      SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
 | 
			
		||||
      struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
 | 
			
		||||
      struct src_register one =
 | 
			
		||||
         scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
 | 
			
		||||
      if (dst.mask & TGSI_WRITEMASK_XYZ) {
 | 
			
		||||
         SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
 | 
			
		||||
         struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
 | 
			
		||||
 | 
			
		||||
      /* Divide texcoord R by Q */
 | 
			
		||||
      if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
 | 
			
		||||
                       src0_zdivw,
 | 
			
		||||
                       scalar(src0, TGSI_SWIZZLE_W) ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
         /* Divide texcoord R by Q */
 | 
			
		||||
         if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
 | 
			
		||||
                          writemask(src0_zdivw, TGSI_WRITEMASK_X),
 | 
			
		||||
                          scalar(src0, TGSI_SWIZZLE_W) ))
 | 
			
		||||
            return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
 | 
			
		||||
                       src0_zdivw,
 | 
			
		||||
                       scalar(src0, TGSI_SWIZZLE_Z),
 | 
			
		||||
                       src(src0_zdivw) ))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
 | 
			
		||||
                          writemask(src0_zdivw, TGSI_WRITEMASK_X),
 | 
			
		||||
                          scalar(src0, TGSI_SWIZZLE_Z),
 | 
			
		||||
                          scalar(src(src0_zdivw), TGSI_SWIZZLE_X) ))
 | 
			
		||||
            return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!emit_select(
 | 
			
		||||
             emit,
 | 
			
		||||
             emit->key.fkey.tex[src1.base.num].compare_func,
 | 
			
		||||
             dst,
 | 
			
		||||
             src(src0_zdivw),
 | 
			
		||||
             tex_src_x))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
         if (!emit_select(
 | 
			
		||||
                emit,
 | 
			
		||||
                emit->key.fkey.tex[src1.base.num].compare_func,
 | 
			
		||||
                writemask( dst, TGSI_WRITEMASK_XYZ ),
 | 
			
		||||
                scalar(src(src0_zdivw), TGSI_SWIZZLE_X),
 | 
			
		||||
                tex_src_x))
 | 
			
		||||
            return FALSE;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
 | 
			
		||||
                         writemask( dst, TGSI_WRITEMASK_W),
 | 
			
		||||
                         one );
 | 
			
		||||
      if (dst.mask & TGSI_WRITEMASK_W) {
 | 
			
		||||
         struct src_register one =
 | 
			
		||||
            scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
 | 
			
		||||
 | 
			
		||||
        if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
 | 
			
		||||
                         writemask( dst, TGSI_WRITEMASK_W ),
 | 
			
		||||
                         one ))
 | 
			
		||||
           return FALSE;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
   }
 | 
			
		||||
   else if (!emit->use_sm30 && dst.mask != TGSI_WRITEMASK_XYZW) 
 | 
			
		||||
   {
 | 
			
		||||
@@ -1330,6 +1463,8 @@ static boolean emit_bgnloop2( struct svga_shader_emitter *emit,
 | 
			
		||||
   struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
 | 
			
		||||
   struct src_register const_int = get_loop_const( emit );
 | 
			
		||||
 | 
			
		||||
   emit->dynamic_branching_level++;
 | 
			
		||||
 | 
			
		||||
   return (emit_instruction( emit, inst ) &&
 | 
			
		||||
           emit_src( emit, loop_reg ) &&
 | 
			
		||||
           emit_src( emit, const_int ) );
 | 
			
		||||
@@ -1339,6 +1474,9 @@ static boolean emit_endloop2( struct svga_shader_emitter *emit,
 | 
			
		||||
                              const struct tgsi_full_instruction *insn )
 | 
			
		||||
{
 | 
			
		||||
   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
 | 
			
		||||
 | 
			
		||||
   emit->dynamic_branching_level--;
 | 
			
		||||
 | 
			
		||||
   return emit_instruction( emit, inst );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1398,6 +1536,46 @@ static boolean emit_simple_instruction(struct svga_shader_emitter *emit,
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static boolean emit_deriv(struct svga_shader_emitter *emit,
 | 
			
		||||
                          const struct tgsi_full_instruction *insn )
 | 
			
		||||
{
 | 
			
		||||
   if (emit->dynamic_branching_level > 0 &&
 | 
			
		||||
       insn->FullSrcRegisters[0].SrcRegister.File == TGSI_FILE_TEMPORARY) 
 | 
			
		||||
   {
 | 
			
		||||
      struct src_register zero = get_zero_immediate( emit );
 | 
			
		||||
      SVGA3dShaderDestToken dst = 
 | 
			
		||||
         translate_dst_register( emit, insn, 0 );
 | 
			
		||||
 | 
			
		||||
      /* Deriv opcodes not valid inside dynamic branching, workaround
 | 
			
		||||
       * by zeroing out the destination.
 | 
			
		||||
       */
 | 
			
		||||
      if (!submit_op1(emit, 
 | 
			
		||||
                      inst_token( SVGA3DOP_MOV ), 
 | 
			
		||||
                      dst,
 | 
			
		||||
                      scalar(zero, TGSI_SWIZZLE_X)))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      
 | 
			
		||||
      return TRUE;
 | 
			
		||||
   }
 | 
			
		||||
   else {
 | 
			
		||||
      unsigned opcode;
 | 
			
		||||
 | 
			
		||||
      switch (insn->Instruction.Opcode) {
 | 
			
		||||
      case TGSI_OPCODE_DDX:
 | 
			
		||||
         opcode = SVGA3DOP_DSX;
 | 
			
		||||
         break;
 | 
			
		||||
      case TGSI_OPCODE_DDY:
 | 
			
		||||
         opcode = SVGA3DOP_DSY;
 | 
			
		||||
         break;
 | 
			
		||||
      default:
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return emit_simple_instruction( emit, opcode, insn );
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static boolean emit_arl(struct svga_shader_emitter *emit,
 | 
			
		||||
                        const struct tgsi_full_instruction *insn)
 | 
			
		||||
{
 | 
			
		||||
@@ -1655,13 +1833,13 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
 | 
			
		||||
    */
 | 
			
		||||
   if (dst.mask & TGSI_WRITEMASK_X) {
 | 
			
		||||
      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
 | 
			
		||||
                       writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
 | 
			
		||||
                       writemask( dst, TGSI_WRITEMASK_X ),
 | 
			
		||||
                       src0,
 | 
			
		||||
                       scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
 | 
			
		||||
                       writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
 | 
			
		||||
                       writemask( dst, TGSI_WRITEMASK_X ),
 | 
			
		||||
                       scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -1673,7 +1851,7 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
 | 
			
		||||
    */
 | 
			
		||||
   if (dst.mask & TGSI_WRITEMASK_Z) {
 | 
			
		||||
      if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
 | 
			
		||||
                       writemask( dst, dst.mask & TGSI_WRITEMASK_Z ),
 | 
			
		||||
                       writemask( dst, TGSI_WRITEMASK_Z ),
 | 
			
		||||
                       src0 ) )
 | 
			
		||||
         return FALSE;
 | 
			
		||||
   }
 | 
			
		||||
@@ -2002,6 +2180,10 @@ static boolean svga_emit_instruction( struct svga_shader_emitter *emit,
 | 
			
		||||
   case TGSI_OPCODE_TXD:
 | 
			
		||||
      return emit_tex( emit, insn );
 | 
			
		||||
 | 
			
		||||
   case TGSI_OPCODE_DDX:
 | 
			
		||||
   case TGSI_OPCODE_DDY:
 | 
			
		||||
      return emit_deriv( emit, insn );
 | 
			
		||||
 | 
			
		||||
   case TGSI_OPCODE_BGNSUB:
 | 
			
		||||
      return emit_bgnsub( emit, position, insn );
 | 
			
		||||
 | 
			
		||||
@@ -2254,11 +2436,28 @@ static boolean emit_ps_postamble( struct svga_shader_emitter *emit )
 | 
			
		||||
   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
 | 
			
		||||
      if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
 | 
			
		||||
 | 
			
		||||
         if (!submit_op1( emit,
 | 
			
		||||
                          inst_token(SVGA3DOP_MOV),
 | 
			
		||||
                          emit->true_col[i],
 | 
			
		||||
                          src(emit->temp_col[i]) ))
 | 
			
		||||
            return FALSE;
 | 
			
		||||
         /* Potentially override output colors with white for XOR
 | 
			
		||||
          * logicop workaround.
 | 
			
		||||
          */
 | 
			
		||||
         if (emit->unit == PIPE_SHADER_FRAGMENT &&
 | 
			
		||||
             emit->key.fkey.white_fragments) {
 | 
			
		||||
 | 
			
		||||
            struct src_register one = scalar( get_zero_immediate( emit ),
 | 
			
		||||
                                              TGSI_SWIZZLE_W );
 | 
			
		||||
 | 
			
		||||
            if (!submit_op1( emit,
 | 
			
		||||
                             inst_token(SVGA3DOP_MOV),
 | 
			
		||||
                             emit->true_col[i],
 | 
			
		||||
                             one ))
 | 
			
		||||
               return FALSE;
 | 
			
		||||
         }
 | 
			
		||||
         else {
 | 
			
		||||
            if (!submit_op1( emit,
 | 
			
		||||
                             inst_token(SVGA3DOP_MOV),
 | 
			
		||||
                             emit->true_col[i],
 | 
			
		||||
                             src(emit->temp_col[i]) ))
 | 
			
		||||
               return FALSE;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
@@ -2467,6 +2666,9 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
 | 
			
		||||
      if (emit->key.fkey.light_twoside)
 | 
			
		||||
         return TRUE;
 | 
			
		||||
 | 
			
		||||
      if (emit->key.fkey.white_fragments)
 | 
			
		||||
         return TRUE;
 | 
			
		||||
 | 
			
		||||
      if (emit->emit_frontface)
 | 
			
		||||
         return TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -2476,6 +2678,10 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
 | 
			
		||||
       emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
 | 
			
		||||
       emit->info.opcode_count[TGSI_OPCODE_BGNFOR] >= 1 ||
 | 
			
		||||
       emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
 | 
			
		||||
       emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
 | 
			
		||||
       emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
 | 
			
		||||
       emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
 | 
			
		||||
       emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
 | 
			
		||||
@@ -2702,6 +2908,8 @@ boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
 | 
			
		||||
         goto done;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   assert(emit->dynamic_branching_level == 0);
 | 
			
		||||
 | 
			
		||||
   /* Need to terminate the whole shader:
 | 
			
		||||
    */
 | 
			
		||||
   ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );
 | 
			
		||||
 
 | 
			
		||||
@@ -281,6 +281,9 @@ svga_screen_create(struct svga_winsys_screen *sws);
 | 
			
		||||
struct svga_winsys_screen *
 | 
			
		||||
svga_winsys_screen(struct pipe_screen *screen);
 | 
			
		||||
 | 
			
		||||
struct svga_winsys_context *
 | 
			
		||||
svga_winsys_context(struct pipe_context *context);
 | 
			
		||||
 | 
			
		||||
struct pipe_buffer *
 | 
			
		||||
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
 | 
			
		||||
				enum SVGA3dSurfaceFormat format,
 | 
			
		||||
 
 | 
			
		||||
@@ -132,14 +132,22 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
 | 
			
		||||
   boolean have_depth = FALSE;
 | 
			
		||||
   int i, count;
 | 
			
		||||
 | 
			
		||||
   buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
 | 
			
		||||
						     &dri_drawable->w,
 | 
			
		||||
						     &dri_drawable->h,
 | 
			
		||||
						     drawable->attachments,
 | 
			
		||||
						     drawable->
 | 
			
		||||
						     num_attachments, &count,
 | 
			
		||||
						     dri_drawable->
 | 
			
		||||
						     loaderPrivate);
 | 
			
		||||
   if ((dri_screen->dri2.loader
 | 
			
		||||
        && (dri_screen->dri2.loader->base.version > 2)
 | 
			
		||||
        && (dri_screen->dri2.loader->getBuffersWithFormat != NULL)))
 | 
			
		||||
      buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
 | 
			
		||||
                (dri_drawable, &dri_drawable->w, &dri_drawable->h,
 | 
			
		||||
                 drawable->attachments, drawable->num_attachments,
 | 
			
		||||
                 &count, dri_drawable->loaderPrivate);
 | 
			
		||||
   else
 | 
			
		||||
      buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
 | 
			
		||||
                                                        &dri_drawable->w,
 | 
			
		||||
                                                        &dri_drawable->h,
 | 
			
		||||
                                                        drawable->attachments,
 | 
			
		||||
                                                        drawable->
 | 
			
		||||
                                                        num_attachments, &count,
 | 
			
		||||
                                                        dri_drawable->
 | 
			
		||||
                                                        loaderPrivate);
 | 
			
		||||
 | 
			
		||||
   if (buffers == NULL) {
 | 
			
		||||
      return;
 | 
			
		||||
@@ -346,12 +354,12 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
 | 
			
		||||
   case 24:
 | 
			
		||||
      if (visual->stencilBits == 0) {
 | 
			
		||||
	 drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
 | 
			
		||||
	    PIPE_FORMAT_X8Z24_UNORM:
 | 
			
		||||
	    PIPE_FORMAT_Z24X8_UNORM;
 | 
			
		||||
                                          PIPE_FORMAT_X8Z24_UNORM:
 | 
			
		||||
                                          PIPE_FORMAT_Z24X8_UNORM;
 | 
			
		||||
      } else {
 | 
			
		||||
	 drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
 | 
			
		||||
	    PIPE_FORMAT_S8Z24_UNORM:
 | 
			
		||||
	    PIPE_FORMAT_Z24S8_UNORM;
 | 
			
		||||
                                          PIPE_FORMAT_S8Z24_UNORM:
 | 
			
		||||
                                          PIPE_FORMAT_Z24S8_UNORM;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
   case 32:
 | 
			
		||||
@@ -375,23 +383,49 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
 | 
			
		||||
   /* setup dri2 buffers information */
 | 
			
		||||
   /* TODO incase of double buffer visual, delay fake creation */
 | 
			
		||||
   i = 0;
 | 
			
		||||
   drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
 | 
			
		||||
   if (!screen->auto_fake_front)
 | 
			
		||||
      drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
 | 
			
		||||
   if (visual->doubleBufferMode)
 | 
			
		||||
      drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
 | 
			
		||||
   if (visual->depthBits && visual->stencilBits)
 | 
			
		||||
      drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
 | 
			
		||||
   else if (visual->depthBits)
 | 
			
		||||
      drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
 | 
			
		||||
   else if (visual->stencilBits)
 | 
			
		||||
      drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
 | 
			
		||||
   drawable->num_attachments = i;
 | 
			
		||||
   if (sPriv->dri2.loader
 | 
			
		||||
       && (sPriv->dri2.loader->base.version > 2)
 | 
			
		||||
       && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
 | 
			
		||||
      drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
 | 
			
		||||
      drawable->attachments[i++] = visual->rgbBits;
 | 
			
		||||
      if (!screen->auto_fake_front)  {
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
 | 
			
		||||
         drawable->attachments[i++] = visual->rgbBits;
 | 
			
		||||
      }
 | 
			
		||||
      if (visual->doubleBufferMode) {
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
 | 
			
		||||
         drawable->attachments[i++] = visual->rgbBits;
 | 
			
		||||
      }
 | 
			
		||||
      if (visual->depthBits && visual->stencilBits) {
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
 | 
			
		||||
         drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
 | 
			
		||||
      } else if (visual->depthBits) {
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
 | 
			
		||||
         drawable->attachments[i++] = visual->depthBits;
 | 
			
		||||
      } else if (visual->stencilBits) {
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
 | 
			
		||||
         drawable->attachments[i++] = visual->stencilBits;
 | 
			
		||||
      }
 | 
			
		||||
      drawable->num_attachments = i / 2;
 | 
			
		||||
   } else {
 | 
			
		||||
      drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
 | 
			
		||||
      if (!screen->auto_fake_front)
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
 | 
			
		||||
      if (visual->doubleBufferMode)
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
 | 
			
		||||
      if (visual->depthBits && visual->stencilBits)
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
 | 
			
		||||
      else if (visual->depthBits)
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
 | 
			
		||||
      else if (visual->stencilBits)
 | 
			
		||||
         drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
 | 
			
		||||
      drawable->num_attachments = i;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   drawable->desired_fences = 2;
 | 
			
		||||
 | 
			
		||||
   return GL_TRUE;
 | 
			
		||||
 fail:
 | 
			
		||||
fail:
 | 
			
		||||
   FREE(drawable);
 | 
			
		||||
   return GL_FALSE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -80,6 +80,9 @@ dri_fill_in_modes(struct dri_screen *screen,
 | 
			
		||||
		  unsigned pixel_bits)
 | 
			
		||||
{
 | 
			
		||||
   __DRIconfig **configs = NULL;
 | 
			
		||||
   __DRIconfig **configs_r5g6b5 = NULL;
 | 
			
		||||
   __DRIconfig **configs_a8r8g8b8 = NULL;
 | 
			
		||||
   __DRIconfig **configs_x8r8g8b8 = NULL;
 | 
			
		||||
   unsigned num_modes;
 | 
			
		||||
   uint8_t depth_bits_array[5];
 | 
			
		||||
   uint8_t stencil_bits_array[5];
 | 
			
		||||
@@ -99,12 +102,6 @@ dri_fill_in_modes(struct dri_screen *screen,
 | 
			
		||||
   stencil_bits_array[0] = 0;
 | 
			
		||||
   depth_buffer_factor = 1;
 | 
			
		||||
 | 
			
		||||
   pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
 | 
			
		||||
					  PIPE_TEXTURE_2D,
 | 
			
		||||
					  PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
 | 
			
		||||
   pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
 | 
			
		||||
					  PIPE_TEXTURE_2D,
 | 
			
		||||
					  PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
 | 
			
		||||
   pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
 | 
			
		||||
					    PIPE_TEXTURE_2D,
 | 
			
		||||
					    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
 | 
			
		||||
@@ -117,15 +114,30 @@ dri_fill_in_modes(struct dri_screen *screen,
 | 
			
		||||
   pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
 | 
			
		||||
					    PIPE_TEXTURE_2D,
 | 
			
		||||
					    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
 | 
			
		||||
   pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
 | 
			
		||||
					     PIPE_TEXTURE_2D,
 | 
			
		||||
					     PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
 | 
			
		||||
   pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM,
 | 
			
		||||
					       PIPE_TEXTURE_2D,
 | 
			
		||||
					       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
 | 
			
		||||
   pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM,
 | 
			
		||||
					       PIPE_TEXTURE_2D,
 | 
			
		||||
					       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
 | 
			
		||||
   pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
 | 
			
		||||
					     PIPE_TEXTURE_2D,
 | 
			
		||||
					     PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
 | 
			
		||||
 | 
			
		||||
   /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
 | 
			
		||||
   if (screen->sPriv->dri2.loader &&
 | 
			
		||||
       (screen->sPriv->dri2.loader->base.version > 2) &&
 | 
			
		||||
       (screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
 | 
			
		||||
      pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
 | 
			
		||||
                                             PIPE_TEXTURE_2D,
 | 
			
		||||
                                             PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
 | 
			
		||||
      pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
 | 
			
		||||
                                             PIPE_TEXTURE_2D,
 | 
			
		||||
                                             PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
 | 
			
		||||
   } else {
 | 
			
		||||
      pf_z16 = FALSE;
 | 
			
		||||
      pf_z32 = FALSE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (pf_z16) {
 | 
			
		||||
      depth_bits_array[depth_buffer_factor] = 16;
 | 
			
		||||
@@ -153,41 +165,43 @@ dri_fill_in_modes(struct dri_screen *screen,
 | 
			
		||||
   num_modes =
 | 
			
		||||
      depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
 | 
			
		||||
 | 
			
		||||
   if (pixel_bits == 16 && pf_r5g6b5) {
 | 
			
		||||
      configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
 | 
			
		||||
				 depth_bits_array, stencil_bits_array,
 | 
			
		||||
				 depth_buffer_factor, back_buffer_modes,
 | 
			
		||||
				 back_buffer_factor,
 | 
			
		||||
				 msaa_samples_array, 1);
 | 
			
		||||
   if (pf_r5g6b5)
 | 
			
		||||
      configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
 | 
			
		||||
                                        depth_bits_array, stencil_bits_array,
 | 
			
		||||
                                        depth_buffer_factor, back_buffer_modes,
 | 
			
		||||
                                        back_buffer_factor,
 | 
			
		||||
                                        msaa_samples_array, 1);
 | 
			
		||||
 | 
			
		||||
   if (pf_a8r8g8b8)
 | 
			
		||||
      configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
 | 
			
		||||
                                          depth_bits_array,
 | 
			
		||||
                                          stencil_bits_array,
 | 
			
		||||
                                          depth_buffer_factor,
 | 
			
		||||
                                          back_buffer_modes,
 | 
			
		||||
                                          back_buffer_factor,
 | 
			
		||||
                                          msaa_samples_array, 1);
 | 
			
		||||
 | 
			
		||||
   if (pf_x8r8g8b8)
 | 
			
		||||
      configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
 | 
			
		||||
                                          depth_bits_array,
 | 
			
		||||
                                          stencil_bits_array,
 | 
			
		||||
                                          depth_buffer_factor,
 | 
			
		||||
                                          back_buffer_modes,
 | 
			
		||||
                                          back_buffer_factor,
 | 
			
		||||
                                          msaa_samples_array, 1);
 | 
			
		||||
 | 
			
		||||
   if (pixel_bits == 16) {
 | 
			
		||||
      configs = configs_r5g6b5;
 | 
			
		||||
      if (configs_a8r8g8b8)
 | 
			
		||||
         configs = configs ? driConcatConfigs(configs, configs_a8r8g8b8) : configs_a8r8g8b8;
 | 
			
		||||
      if (configs_x8r8g8b8)
 | 
			
		||||
	 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8;
 | 
			
		||||
   } else {
 | 
			
		||||
      __DRIconfig **configs_a8r8g8b8 = NULL;
 | 
			
		||||
      __DRIconfig **configs_x8r8g8b8 = NULL;
 | 
			
		||||
 | 
			
		||||
      if (pf_a8r8g8b8)
 | 
			
		||||
	 configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
 | 
			
		||||
					     depth_bits_array,
 | 
			
		||||
					     stencil_bits_array,
 | 
			
		||||
					     depth_buffer_factor,
 | 
			
		||||
					     back_buffer_modes,
 | 
			
		||||
					     back_buffer_factor,
 | 
			
		||||
					     msaa_samples_array, 1);
 | 
			
		||||
      if (pf_x8r8g8b8)
 | 
			
		||||
	 configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
 | 
			
		||||
					     depth_bits_array,
 | 
			
		||||
					     stencil_bits_array,
 | 
			
		||||
					     depth_buffer_factor,
 | 
			
		||||
					     back_buffer_modes,
 | 
			
		||||
					     back_buffer_factor,
 | 
			
		||||
					     msaa_samples_array, 1);
 | 
			
		||||
 | 
			
		||||
      if (configs_a8r8g8b8 && configs_x8r8g8b8)
 | 
			
		||||
	 configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8);
 | 
			
		||||
      else if (configs_a8r8g8b8)
 | 
			
		||||
	 configs = configs_a8r8g8b8;
 | 
			
		||||
      else if (configs_x8r8g8b8)
 | 
			
		||||
	 configs = configs_x8r8g8b8;
 | 
			
		||||
      else
 | 
			
		||||
	 configs = NULL;
 | 
			
		||||
      configs = configs_a8r8g8b8;
 | 
			
		||||
      if (configs_x8r8g8b8)
 | 
			
		||||
	 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8;
 | 
			
		||||
      if (configs_r5g6b5)
 | 
			
		||||
         configs = configs ? driConcatConfigs(configs, configs_r5g6b5) : configs_r5g6b5;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (configs == NULL) {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ if 'python' in env['statetrackers']:
 | 
			
		||||
            'gdi32',
 | 
			
		||||
            'user32',
 | 
			
		||||
            'kernel32',
 | 
			
		||||
            'ws2_32',
 | 
			
		||||
        ])
 | 
			
		||||
    else:
 | 
			
		||||
        env.Append(LIBS = [
 | 
			
		||||
 
 | 
			
		||||
@@ -531,6 +531,8 @@ class Context(Object):
 | 
			
		||||
                    gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f',
 | 
			
		||||
                    gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f',
 | 
			
		||||
                    gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B',
 | 
			
		||||
                    gallium.PIPE_FORMAT_R8G8B8A8_UNORM: '4B',
 | 
			
		||||
                    gallium.PIPE_FORMAT_R16G16B16_SNORM: '3h',
 | 
			
		||||
                }[velem.src_format]
 | 
			
		||||
 | 
			
		||||
                data = vbuf.buffer.read()
 | 
			
		||||
@@ -557,7 +559,7 @@ class Context(Object):
 | 
			
		||||
 | 
			
		||||
        sys.stdout.write('\t{\n')
 | 
			
		||||
        for i in range(start, start + count):
 | 
			
		||||
            if i >= start + 16:
 | 
			
		||||
            if i >= start + 16 and not self.interpreter.verbosity(3):
 | 
			
		||||
                sys.stdout.write('\t...\n')
 | 
			
		||||
                break
 | 
			
		||||
            offset = i*isize
 | 
			
		||||
 
 | 
			
		||||
@@ -362,7 +362,7 @@ EXPORTS
 | 
			
		||||
	wglShareLists
 | 
			
		||||
	wglSwapBuffers
 | 
			
		||||
	wglSwapLayerBuffers
 | 
			
		||||
;	wglSwapMultipleBuffers
 | 
			
		||||
	wglSwapMultipleBuffers
 | 
			
		||||
	wglUseFontBitmapsA
 | 
			
		||||
	wglUseFontBitmapsW
 | 
			
		||||
	wglUseFontOutlinesA
 | 
			
		||||
 
 | 
			
		||||
@@ -362,7 +362,7 @@ EXPORTS
 | 
			
		||||
	wglShareLists = wglShareLists@8
 | 
			
		||||
	wglSwapBuffers = wglSwapBuffers@4
 | 
			
		||||
	wglSwapLayerBuffers = wglSwapLayerBuffers@8
 | 
			
		||||
;	wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
 | 
			
		||||
	wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
 | 
			
		||||
	wglUseFontBitmapsA = wglUseFontBitmapsA@16
 | 
			
		||||
	wglUseFontBitmapsW = wglUseFontBitmapsW@16
 | 
			
		||||
	wglUseFontOutlinesA = wglUseFontOutlinesA@32
 | 
			
		||||
 
 | 
			
		||||
@@ -80,6 +80,9 @@ DrvCopyContext(
 | 
			
		||||
   struct stw_context *dst;
 | 
			
		||||
   BOOL ret = FALSE;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   pipe_mutex_lock( stw_dev->ctx_mutex );
 | 
			
		||||
   
 | 
			
		||||
   src = stw_lookup_context_locked( dhrcSource );
 | 
			
		||||
@@ -107,13 +110,15 @@ DrvShareLists(
 | 
			
		||||
   struct stw_context *ctx2;
 | 
			
		||||
   BOOL ret = FALSE;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   pipe_mutex_lock( stw_dev->ctx_mutex );
 | 
			
		||||
   
 | 
			
		||||
   ctx1 = stw_lookup_context_locked( dhglrc1 );
 | 
			
		||||
   ctx2 = stw_lookup_context_locked( dhglrc2 );
 | 
			
		||||
 | 
			
		||||
   if (ctx1 && ctx2 &&
 | 
			
		||||
       ctx1->iPixelFormat == ctx2->iPixelFormat) { 
 | 
			
		||||
   if (ctx1 && ctx2) {
 | 
			
		||||
      ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -152,24 +152,27 @@ stw_cleanup_thread(void)
 | 
			
		||||
void
 | 
			
		||||
stw_cleanup(void)
 | 
			
		||||
{
 | 
			
		||||
   unsigned i;
 | 
			
		||||
   DHGLRC dhglrc;
 | 
			
		||||
 | 
			
		||||
   debug_printf("%s\n", __FUNCTION__);
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return;
 | 
			
		||||
   
 | 
			
		||||
   /*
 | 
			
		||||
    * Abort cleanup if there are still active contexts. In some situations
 | 
			
		||||
    * this DLL may be unloaded before the DLL that is using GL contexts is.
 | 
			
		||||
    */
 | 
			
		||||
   pipe_mutex_lock( stw_dev->ctx_mutex );
 | 
			
		||||
   {
 | 
			
		||||
      /* Ensure all contexts are destroyed */
 | 
			
		||||
      i = handle_table_get_first_handle(stw_dev->ctx_table);
 | 
			
		||||
      while (i) {
 | 
			
		||||
         DrvDeleteContext(i);
 | 
			
		||||
         i = handle_table_get_next_handle(stw_dev->ctx_table, i);
 | 
			
		||||
      }
 | 
			
		||||
      handle_table_destroy(stw_dev->ctx_table);
 | 
			
		||||
   }
 | 
			
		||||
   dhglrc = handle_table_get_first_handle(stw_dev->ctx_table);
 | 
			
		||||
   pipe_mutex_unlock( stw_dev->ctx_mutex );
 | 
			
		||||
   if (dhglrc) {
 | 
			
		||||
      debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__);
 | 
			
		||||
      stw_dev = NULL;
 | 
			
		||||
      return;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   handle_table_destroy(stw_dev->ctx_table);
 | 
			
		||||
 | 
			
		||||
   stw_framebuffer_cleanup();
 | 
			
		||||
   
 | 
			
		||||
 
 | 
			
		||||
@@ -178,7 +178,7 @@ stw_call_window_proc(
 | 
			
		||||
   if(!tls_data)
 | 
			
		||||
      return 0;
 | 
			
		||||
   
 | 
			
		||||
   if (nCode < 0)
 | 
			
		||||
   if (nCode < 0 || !stw_dev)
 | 
			
		||||
       return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
 | 
			
		||||
 | 
			
		||||
   if (pParams->message == WM_WINDOWPOSCHANGED) {
 | 
			
		||||
@@ -333,6 +333,9 @@ stw_framebuffer_cleanup( void )
 | 
			
		||||
   struct stw_framebuffer *fb;
 | 
			
		||||
   struct stw_framebuffer *next;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   pipe_mutex_lock( stw_dev->fb_mutex );
 | 
			
		||||
 | 
			
		||||
   fb = stw_dev->fb_head;
 | 
			
		||||
@@ -388,6 +391,9 @@ stw_framebuffer_from_hdc(
 | 
			
		||||
{
 | 
			
		||||
   struct stw_framebuffer *fb;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return NULL;
 | 
			
		||||
 | 
			
		||||
   pipe_mutex_lock( stw_dev->fb_mutex );
 | 
			
		||||
   fb = stw_framebuffer_from_hdc_locked(hdc);
 | 
			
		||||
   pipe_mutex_unlock( stw_dev->fb_mutex );
 | 
			
		||||
@@ -422,6 +428,9 @@ DrvSetPixelFormat(
 | 
			
		||||
   uint index;
 | 
			
		||||
   struct stw_framebuffer *fb;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   index = (uint) iPixelFormat - 1;
 | 
			
		||||
   count = stw_pixelformat_get_extended_count();
 | 
			
		||||
   if (index >= count)
 | 
			
		||||
@@ -476,6 +485,9 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
 | 
			
		||||
   struct pipe_screen *screen;
 | 
			
		||||
   struct pipe_surface *surface;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   fb = stw_framebuffer_from_hdc( hdc );
 | 
			
		||||
   if (fb == NULL)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
@@ -577,6 +589,9 @@ DrvSwapBuffers(
 | 
			
		||||
   struct stw_framebuffer *fb;
 | 
			
		||||
   struct pipe_surface *surface = NULL;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 | 
			
		||||
   fb = stw_framebuffer_from_hdc( hdc );
 | 
			
		||||
   if (fb == NULL)
 | 
			
		||||
      return FALSE;
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,8 @@
 | 
			
		||||
 | 
			
		||||
#include "glapi/glapi.h"
 | 
			
		||||
#include "stw_ext_gallium.h"
 | 
			
		||||
#include "stw_device.h"
 | 
			
		||||
#include "stw_icd.h"
 | 
			
		||||
 | 
			
		||||
struct stw_extension_entry
 | 
			
		||||
{
 | 
			
		||||
@@ -73,6 +75,9 @@ DrvGetProcAddress(
 | 
			
		||||
{
 | 
			
		||||
   const struct stw_extension_entry *entry;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return NULL;
 | 
			
		||||
 | 
			
		||||
   if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l')
 | 
			
		||||
      for (entry = stw_extension_entries; entry->name; entry++)
 | 
			
		||||
         if (strcmp( lpszProc, entry->name ) == 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -303,6 +303,9 @@ DrvDescribePixelFormat(
 | 
			
		||||
 | 
			
		||||
   (void) hdc;
 | 
			
		||||
 | 
			
		||||
   if (!stw_dev)
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
   count = stw_pixelformat_get_extended_count();
 | 
			
		||||
   index = (uint) iPixelFormat - 1;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,19 @@ wglSwapBuffers(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
WINGDIAPI DWORD WINAPI
 | 
			
		||||
wglSwapMultipleBuffers(UINT n,
 | 
			
		||||
                       CONST WGLSWAP *ps)
 | 
			
		||||
{
 | 
			
		||||
   UINT i;
 | 
			
		||||
 | 
			
		||||
   for (i =0; i < n; ++i)
 | 
			
		||||
      wglSwapBuffers(ps->hdc);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
WINGDIAPI BOOL APIENTRY
 | 
			
		||||
wglSwapLayerBuffers(
 | 
			
		||||
   HDC hdc,
 | 
			
		||||
 
 | 
			
		||||
@@ -59,5 +59,21 @@ wglSetPixelFormat(HDC hdc,
 | 
			
		||||
                  int iPixelFormat,
 | 
			
		||||
                  CONST PIXELFORMATDESCRIPTOR *ppfd);
 | 
			
		||||
 | 
			
		||||
#if defined(__MINGW32__) || (WINVER < 0x0500)
 | 
			
		||||
 | 
			
		||||
typedef struct _WGLSWAP
 | 
			
		||||
{
 | 
			
		||||
   HDC hdc;
 | 
			
		||||
   UINT uiFlags;
 | 
			
		||||
} WGLSWAP;
 | 
			
		||||
 | 
			
		||||
#define WGL_SWAPMULTIPLE_MAX 16
 | 
			
		||||
 | 
			
		||||
WINGDIAPI DWORD WINAPI
 | 
			
		||||
wglSwapMultipleBuffers(UINT n,
 | 
			
		||||
                       CONST WGLSWAP *ps);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* STW_WGL_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@
 | 
			
		||||
#include <xf86.h>
 | 
			
		||||
#include <xf86i2c.h>
 | 
			
		||||
#include <xf86Crtc.h>
 | 
			
		||||
#include <cursorstr.h>
 | 
			
		||||
#include "xorg_tracker.h"
 | 
			
		||||
#include "xf86Modes.h"
 | 
			
		||||
 | 
			
		||||
@@ -146,6 +147,7 @@ crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
 | 
			
		||||
    /* XXX: hockup */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0 /* Implement and enable to enable rotation and reflection. */
 | 
			
		||||
static void *
 | 
			
		||||
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 | 
			
		||||
{
 | 
			
		||||
@@ -168,6 +170,8 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
 | 
			
		||||
    /* ScrnInfoPtr pScrn = crtc->scrn; */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Cursor functions
 | 
			
		||||
 */
 | 
			
		||||
@@ -243,7 +247,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
 | 
			
		||||
	unsigned attr[8];
 | 
			
		||||
 | 
			
		||||
	attr[0] = KMS_BO_TYPE;
 | 
			
		||||
#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8
 | 
			
		||||
	attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
 | 
			
		||||
#else
 | 
			
		||||
	attr[1] = KMS_BO_TYPE_CURSOR;
 | 
			
		||||
#endif
 | 
			
		||||
	attr[2] = KMS_WIDTH;
 | 
			
		||||
	attr[3] = 64;
 | 
			
		||||
	attr[4] = KMS_HEIGHT;
 | 
			
		||||
@@ -272,7 +280,21 @@ err_bo_destroy:
 | 
			
		||||
static void
 | 
			
		||||
crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
 | 
			
		||||
{
 | 
			
		||||
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(crtc->scrn);
 | 
			
		||||
 | 
			
		||||
    /* Older X servers have cursor reference counting bugs leading to use of
 | 
			
		||||
     * freed memory and consequently random crashes. Should be fixed as of
 | 
			
		||||
     * xserver 1.8, but this workaround shouldn't hurt anyway.
 | 
			
		||||
     */
 | 
			
		||||
    if (config->cursor)
 | 
			
		||||
       config->cursor->refcnt++;
 | 
			
		||||
 | 
			
		||||
    if (ms->cursor)
 | 
			
		||||
       FreeCursor(ms->cursor, None);
 | 
			
		||||
 | 
			
		||||
    ms->cursor = config->cursor;
 | 
			
		||||
 | 
			
		||||
    if (ms->screen)
 | 
			
		||||
	crtc_load_cursor_argb_ga3d(crtc, image);
 | 
			
		||||
#ifdef HAVE_LIBKMS
 | 
			
		||||
@@ -344,9 +366,9 @@ static const xf86CrtcFuncsRec crtc_funcs = {
 | 
			
		||||
    .hide_cursor = crtc_hide_cursor,
 | 
			
		||||
    .load_cursor_argb = crtc_load_cursor_argb,
 | 
			
		||||
 | 
			
		||||
    .shadow_create = crtc_shadow_create,
 | 
			
		||||
    .shadow_allocate = crtc_shadow_allocate,
 | 
			
		||||
    .shadow_destroy = crtc_shadow_destroy,
 | 
			
		||||
    .shadow_create = NULL,
 | 
			
		||||
    .shadow_allocate = NULL,
 | 
			
		||||
    .shadow_destroy = NULL,
 | 
			
		||||
 | 
			
		||||
    .gamma_set = crtc_gamma_set,
 | 
			
		||||
    .destroy = crtc_destroy,
 | 
			
		||||
 
 | 
			
		||||
@@ -102,14 +102,26 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
 | 
			
		||||
	    pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
 | 
			
		||||
        else {
 | 
			
		||||
	    struct pipe_texture template;
 | 
			
		||||
            unsigned depthBits = (format != 0) ? format : pDraw->depth;
 | 
			
		||||
	    memset(&template, 0, sizeof(template));
 | 
			
		||||
	    template.target = PIPE_TEXTURE_2D;
 | 
			
		||||
	    if (buffer->attachment == DRI2BufferDepth)
 | 
			
		||||
		template.format = ms->ds_depth_bits_last ?
 | 
			
		||||
		    PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
 | 
			
		||||
	    else
 | 
			
		||||
		template.format = ms->ds_depth_bits_last ?
 | 
			
		||||
		    PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
 | 
			
		||||
	    if (buffer->attachment == DRI2BufferDepth) {
 | 
			
		||||
               switch(depthBits) {
 | 
			
		||||
               case 16:
 | 
			
		||||
                  template.format = PIPE_FORMAT_Z16_UNORM;
 | 
			
		||||
                  break;
 | 
			
		||||
               case 32:
 | 
			
		||||
                  template.format = PIPE_FORMAT_Z32_UNORM;
 | 
			
		||||
                  break;
 | 
			
		||||
               default:
 | 
			
		||||
                  template.format = ms->ds_depth_bits_last ?
 | 
			
		||||
                                    PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
 | 
			
		||||
                  break;
 | 
			
		||||
               }
 | 
			
		||||
            } else {
 | 
			
		||||
               template.format = ms->ds_depth_bits_last ?
 | 
			
		||||
                                 PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
 | 
			
		||||
            }
 | 
			
		||||
	    pf_get_block(template.format, &template.block);
 | 
			
		||||
	    template.width[0] = pDraw->width;
 | 
			
		||||
	    template.height[0] = pDraw->height;
 | 
			
		||||
@@ -283,6 +295,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
 | 
			
		||||
    GCPtr gc;
 | 
			
		||||
    RegionPtr copy_clip;
 | 
			
		||||
    Bool save_accel;
 | 
			
		||||
    CustomizerPtr cust = ms->cust;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * In driCreateBuffers we dewrap windows into the
 | 
			
		||||
@@ -336,7 +349,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
 | 
			
		||||
    ValidateGC(dst_draw, gc);
 | 
			
		||||
 | 
			
		||||
    /* If this is a full buffer swap, throttle on the previous one */
 | 
			
		||||
    if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
 | 
			
		||||
    if (ms->swapThrottling &&
 | 
			
		||||
	dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
 | 
			
		||||
	BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
 | 
			
		||||
 | 
			
		||||
	if (extents->x1 == 0 && extents->y1 == 0 &&
 | 
			
		||||
@@ -358,6 +372,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
 | 
			
		||||
    DamageRegionAppend(src_draw, pRegion);
 | 
			
		||||
    DamageRegionProcessPending(src_draw);
 | 
			
		||||
 | 
			
		||||
   if (cust && cust->winsys_context_throttle)
 | 
			
		||||
       cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP);
 | 
			
		||||
 | 
			
		||||
    (*gc->ops->CopyArea)(src_draw, dst_draw, gc,
 | 
			
		||||
			 0, 0, pDraw->width, pDraw->height, 0, 0);
 | 
			
		||||
    ms->exa->accel = save_accel;
 | 
			
		||||
@@ -365,8 +382,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
 | 
			
		||||
    FreeScratchGC(gc);
 | 
			
		||||
 | 
			
		||||
    ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
 | 
			
		||||
		   pDestBuffer->attachment == DRI2BufferFrontLeft ?
 | 
			
		||||
		   (pDestBuffer->attachment == DRI2BufferFrontLeft
 | 
			
		||||
		    && ms->swapThrottling) ?
 | 
			
		||||
		   &dst_priv->fence : NULL);
 | 
			
		||||
 | 
			
		||||
   if (cust && cust->winsys_context_throttle)
 | 
			
		||||
       cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
 
 | 
			
		||||
@@ -79,12 +79,16 @@ typedef enum
 | 
			
		||||
    OPTION_SW_CURSOR,
 | 
			
		||||
    OPTION_2D_ACCEL,
 | 
			
		||||
    OPTION_DEBUG_FALLBACK,
 | 
			
		||||
    OPTION_THROTTLE_SWAP,
 | 
			
		||||
    OPTION_THROTTLE_DIRTY
 | 
			
		||||
} drv_option_enums;
 | 
			
		||||
 | 
			
		||||
static const OptionInfoRec drv_options[] = {
 | 
			
		||||
    {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
 | 
			
		||||
    {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
 | 
			
		||||
    {OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE},
 | 
			
		||||
    {OPTION_THROTTLE_SWAP, "SwapThrottling", OPTV_BOOLEAN, {0}, FALSE},
 | 
			
		||||
    {OPTION_THROTTLE_DIRTY, "DirtyThrottling", OPTV_BOOLEAN, {0}, FALSE},
 | 
			
		||||
    {-1, NULL, OPTV_NONE, {0}, FALSE}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -155,7 +159,7 @@ drv_get_rec(ScrnInfoPtr pScrn)
 | 
			
		||||
    if (pScrn->driverPrivate)
 | 
			
		||||
	return TRUE;
 | 
			
		||||
 | 
			
		||||
    pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
 | 
			
		||||
    pScrn->driverPrivate = xnfcalloc(1, sizeof(modesettingRec));
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -183,31 +187,66 @@ drv_probe_ddc(ScrnInfoPtr pScrn, int index)
 | 
			
		||||
static Bool
 | 
			
		||||
drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
 | 
			
		||||
{
 | 
			
		||||
    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    PixmapPtr rootPixmap;
 | 
			
		||||
    ScreenPtr pScreen = pScrn->pScreen;
 | 
			
		||||
    int old_width, old_height;
 | 
			
		||||
    PixmapPtr rootPixmap;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    if (width == pScrn->virtualX && height == pScrn->virtualY)
 | 
			
		||||
	return TRUE;
 | 
			
		||||
 | 
			
		||||
    old_width = pScrn->virtualX;
 | 
			
		||||
    old_height = pScrn->virtualY;
 | 
			
		||||
    pScrn->virtualX = width;
 | 
			
		||||
    pScrn->virtualY = height;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Remove the old framebuffer & texture.
 | 
			
		||||
     */
 | 
			
		||||
    drmModeRmFB(ms->fd, ms->fb_id);
 | 
			
		||||
    if (!ms->destroy_front_buffer(pScrn))
 | 
			
		||||
	FatalError("failed to destroy front buffer\n");
 | 
			
		||||
    /* ms->create_front_buffer will remove the old front buffer */
 | 
			
		||||
 | 
			
		||||
    rootPixmap = pScreen->GetScreenPixmap(pScreen);
 | 
			
		||||
    if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
	goto error_modify;
 | 
			
		||||
 | 
			
		||||
    pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
 | 
			
		||||
 | 
			
		||||
    /* now create new frontbuffer */
 | 
			
		||||
    return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
 | 
			
		||||
    if (!ms->create_front_buffer(pScrn) || !ms->bind_front_buffer(pScrn))
 | 
			
		||||
	goto error_create;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * create && bind will turn off all crtc(s) in the kernel so we need to
 | 
			
		||||
     * re-enable all the crtcs again. For real HW we might want to do this
 | 
			
		||||
     * before destroying the old framebuffer.
 | 
			
		||||
     */
 | 
			
		||||
    for (i = 0; i < xf86_config->num_crtc; i++) {
 | 
			
		||||
	xf86CrtcPtr crtc = xf86_config->crtc[i];
 | 
			
		||||
 | 
			
		||||
	if (!crtc->enabled)
 | 
			
		||||
	    continue;
 | 
			
		||||
 | 
			
		||||
	crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * This is the error recovery path.
 | 
			
		||||
     */
 | 
			
		||||
error_create:
 | 
			
		||||
    if (!pScreen->ModifyPixmapHeader(rootPixmap, old_width, old_height, -1, -1, -1, NULL))
 | 
			
		||||
	FatalError("failed to resize rootPixmap error path\n");
 | 
			
		||||
 | 
			
		||||
    pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
 | 
			
		||||
 | 
			
		||||
error_modify:
 | 
			
		||||
    pScrn->virtualX = old_width;
 | 
			
		||||
    pScrn->virtualY = old_height;
 | 
			
		||||
 | 
			
		||||
    if (ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
 | 
			
		||||
    FatalError("failed to setup old framebuffer\n");
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
 | 
			
		||||
@@ -333,6 +372,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
 | 
			
		||||
    EntityInfoPtr pEnt;
 | 
			
		||||
    EntPtr msEnt = NULL;
 | 
			
		||||
    int max_width, max_height;
 | 
			
		||||
    CustomizerPtr cust;
 | 
			
		||||
 | 
			
		||||
    if (pScrn->numEntities != 1)
 | 
			
		||||
	return FALSE;
 | 
			
		||||
@@ -344,6 +384,9 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
 | 
			
		||||
	return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cust = (CustomizerPtr) pScrn->driverPrivate;
 | 
			
		||||
    pScrn->driverPrivate = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Allocate driverPrivate */
 | 
			
		||||
    if (!drv_get_rec(pScrn))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
@@ -351,6 +394,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
 | 
			
		||||
    ms = modesettingPTR(pScrn);
 | 
			
		||||
    ms->SaveGeneration = -1;
 | 
			
		||||
    ms->pEnt = pEnt;
 | 
			
		||||
    ms->cust = cust;
 | 
			
		||||
 | 
			
		||||
    pScrn->displayWidth = 640;	       /* default it */
 | 
			
		||||
 | 
			
		||||
@@ -423,8 +467,8 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
 | 
			
		||||
    xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
 | 
			
		||||
    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 | 
			
		||||
 | 
			
		||||
    max_width = 8192;
 | 
			
		||||
    max_height = 8192;
 | 
			
		||||
    max_width = 2048;  /* A very low default */
 | 
			
		||||
    max_height = 2048; /* see screen_init */
 | 
			
		||||
    xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
 | 
			
		||||
 | 
			
		||||
    if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
 | 
			
		||||
@@ -510,23 +554,29 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
 | 
			
		||||
    if (ms->ctx) {
 | 
			
		||||
       int j;
 | 
			
		||||
 | 
			
		||||
       ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
 | 
			
		||||
       ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
 | 
			
		||||
		      ms->dirtyThrottling ?
 | 
			
		||||
		      &ms->fence[XORG_NR_FENCES-1] :
 | 
			
		||||
		      NULL);
 | 
			
		||||
       
 | 
			
		||||
       if (ms->fence[0])
 | 
			
		||||
          ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
 | 
			
		||||
       if (ms->dirtyThrottling) {
 | 
			
		||||
	   if (ms->fence[0])
 | 
			
		||||
	       ms->ctx->screen->fence_finish(ms->ctx->screen,
 | 
			
		||||
					     ms->fence[0], 0);
 | 
			
		||||
  
 | 
			
		||||
       /* The amount of rendering generated by a block handler can be
 | 
			
		||||
        * quite small.  Let us get a fair way ahead of hardware before
 | 
			
		||||
        * throttling.
 | 
			
		||||
        */
 | 
			
		||||
       for (j = 0; j < XORG_NR_FENCES - 1; j++)
 | 
			
		||||
          ms->screen->fence_reference(ms->screen,
 | 
			
		||||
                                      &ms->fence[j],
 | 
			
		||||
                                      ms->fence[j+1]);
 | 
			
		||||
	   /* The amount of rendering generated by a block handler can be
 | 
			
		||||
	    * quite small.  Let us get a fair way ahead of hardware before
 | 
			
		||||
	    * throttling.
 | 
			
		||||
	    */
 | 
			
		||||
	   for (j = 0; j < XORG_NR_FENCES - 1; j++)
 | 
			
		||||
	       ms->screen->fence_reference(ms->screen,
 | 
			
		||||
					   &ms->fence[j],
 | 
			
		||||
					   ms->fence[j+1]);
 | 
			
		||||
 | 
			
		||||
       ms->screen->fence_reference(ms->screen,
 | 
			
		||||
                                   &ms->fence[XORG_NR_FENCES-1],
 | 
			
		||||
                                   NULL);
 | 
			
		||||
	   ms->screen->fence_reference(ms->screen,
 | 
			
		||||
				       &ms->fence[XORG_NR_FENCES-1],
 | 
			
		||||
				       NULL);
 | 
			
		||||
       }
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
@@ -607,7 +657,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    unsigned max_width, max_height;
 | 
			
		||||
    VisualPtr visual;
 | 
			
		||||
    CustomizerPtr cust = ms->cust;
 | 
			
		||||
    MessageType from_st;
 | 
			
		||||
    MessageType from_dt;
 | 
			
		||||
 | 
			
		||||
    if (!drv_init_drm(pScrn)) {
 | 
			
		||||
	FatalError("Could not init DRM");
 | 
			
		||||
@@ -624,6 +678,26 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* get max width and height */
 | 
			
		||||
    {
 | 
			
		||||
	drmModeResPtr res;
 | 
			
		||||
	res = drmModeGetResources(ms->fd);
 | 
			
		||||
	max_width = res->max_width;
 | 
			
		||||
	max_height = res->max_height;
 | 
			
		||||
	drmModeFreeResources(res);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ms->screen) {
 | 
			
		||||
	float maxf;
 | 
			
		||||
	int max;
 | 
			
		||||
	maxf = ms->screen->get_paramf(ms->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
 | 
			
		||||
	max = (1 << (int)(maxf - 1.0f));
 | 
			
		||||
	max_width = max < max_width ? max : max_width;
 | 
			
		||||
	max_height = max < max_height ? max : max_height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    xf86CrtcSetSizeRange(pScrn, 1, 1, max_width, max_height);
 | 
			
		||||
 | 
			
		||||
    pScrn->pScreen = pScreen;
 | 
			
		||||
 | 
			
		||||
    /* HW dependent - FIXME */
 | 
			
		||||
@@ -673,7 +747,20 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 | 
			
		||||
    xf86SetBlackWhitePixels(pScreen);
 | 
			
		||||
 | 
			
		||||
    ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
 | 
			
		||||
    ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE);
 | 
			
		||||
    ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
 | 
			
		||||
 | 
			
		||||
    if (cust && cust->winsys_screen_init)
 | 
			
		||||
	cust->winsys_screen_init(cust, ms->fd);
 | 
			
		||||
 | 
			
		||||
    ms->swapThrottling = cust ?  cust->swap_throttling : TRUE;
 | 
			
		||||
    from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP,
 | 
			
		||||
				&ms->swapThrottling) ?
 | 
			
		||||
	X_CONFIG : X_DEFAULT;
 | 
			
		||||
 | 
			
		||||
    ms->dirtyThrottling = cust ?  cust->dirty_throttling : TRUE;
 | 
			
		||||
    from_dt = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_DIRTY,
 | 
			
		||||
				&ms->dirtyThrottling) ?
 | 
			
		||||
	X_CONFIG : X_DEFAULT;
 | 
			
		||||
 | 
			
		||||
    if (ms->screen) {
 | 
			
		||||
	ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
 | 
			
		||||
@@ -684,6 +771,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n");
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n",
 | 
			
		||||
	       ms->screen ? "Gallium3D" : "libkms");
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n",
 | 
			
		||||
	       ms->screen && ms->accelerate_2d ? "enabled" : "disabled");
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n",
 | 
			
		||||
@@ -694,6 +786,12 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 | 
			
		||||
#else
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
 | 
			
		||||
#endif
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, from_st, "Swap Throttling is %s.\n",
 | 
			
		||||
	       ms->swapThrottling ? "enabled" : "disabled");
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, from_dt, "Dirty Throttling is %s.\n",
 | 
			
		||||
	       ms->dirtyThrottling ? "enabled" : "disabled");
 | 
			
		||||
 | 
			
		||||
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
 | 
			
		||||
 | 
			
		||||
    miInitializeBackingStore(pScreen);
 | 
			
		||||
    xf86SetBackingStore(pScreen);
 | 
			
		||||
@@ -725,9 +823,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 | 
			
		||||
    if (serverGeneration == 1)
 | 
			
		||||
	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 | 
			
		||||
 | 
			
		||||
    if (ms->winsys_screen_init)
 | 
			
		||||
	ms->winsys_screen_init(pScrn);
 | 
			
		||||
 | 
			
		||||
    return drv_enter_vt(scrnIndex, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -759,10 +854,11 @@ drv_leave_vt(int scrnIndex, int flags)
 | 
			
		||||
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 | 
			
		||||
    CustomizerPtr cust = ms->cust;
 | 
			
		||||
    int o;
 | 
			
		||||
 | 
			
		||||
    if (ms->winsys_leave_vt)
 | 
			
		||||
	ms->winsys_leave_vt(pScrn);
 | 
			
		||||
    if (cust && cust->winsys_leave_vt)
 | 
			
		||||
	cust->winsys_leave_vt(cust);
 | 
			
		||||
 | 
			
		||||
    for (o = 0; o < config->num_crtc; o++) {
 | 
			
		||||
	xf86CrtcPtr crtc = config->crtc[o];
 | 
			
		||||
@@ -778,6 +874,7 @@ drv_leave_vt(int scrnIndex, int flags)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    drmModeRmFB(ms->fd, ms->fb_id);
 | 
			
		||||
    ms->fb_id = -1;
 | 
			
		||||
 | 
			
		||||
    drv_restore_hw_state(pScrn);
 | 
			
		||||
 | 
			
		||||
@@ -796,6 +893,7 @@ drv_enter_vt(int scrnIndex, int flags)
 | 
			
		||||
{
 | 
			
		||||
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    CustomizerPtr cust = ms->cust;
 | 
			
		||||
 | 
			
		||||
    if (drmSetMaster(ms->fd)) {
 | 
			
		||||
	if (errno == EINVAL) {
 | 
			
		||||
@@ -826,8 +924,8 @@ drv_enter_vt(int scrnIndex, int flags)
 | 
			
		||||
    if (!xf86SetDesiredModes(pScrn))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
 | 
			
		||||
    if (ms->winsys_enter_vt)
 | 
			
		||||
	ms->winsys_enter_vt(pScrn);
 | 
			
		||||
    if (cust && cust->winsys_enter_vt)
 | 
			
		||||
	cust->winsys_enter_vt(cust);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -845,13 +943,19 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
 | 
			
		||||
{
 | 
			
		||||
    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    CustomizerPtr cust = ms->cust;
 | 
			
		||||
 | 
			
		||||
    if (pScrn->vtSema) {
 | 
			
		||||
	drv_leave_vt(scrnIndex, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ms->winsys_screen_close)
 | 
			
		||||
	ms->winsys_screen_close(pScrn);
 | 
			
		||||
    if (ms->cursor) {
 | 
			
		||||
       FreeCursor(ms->cursor, None);
 | 
			
		||||
       ms->cursor = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (cust && cust->winsys_screen_close)
 | 
			
		||||
	cust->winsys_screen_close(cust);
 | 
			
		||||
 | 
			
		||||
#ifdef DRI2
 | 
			
		||||
    if (ms->screen)
 | 
			
		||||
@@ -900,6 +1004,15 @@ static Bool
 | 
			
		||||
drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
 | 
			
		||||
{
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
 | 
			
		||||
    if (!ms->root_texture)
 | 
			
		||||
	return TRUE;
 | 
			
		||||
 | 
			
		||||
    if (ms->fb_id != -1) {
 | 
			
		||||
	drmModeRmFB(ms->fd, ms->fb_id);
 | 
			
		||||
	ms->fb_id = -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pipe_texture_reference(&ms->root_texture, NULL);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -908,7 +1021,7 @@ static Bool
 | 
			
		||||
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
 | 
			
		||||
{
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    unsigned handle, stride;
 | 
			
		||||
    unsigned handle, stride, fb_id;
 | 
			
		||||
    struct pipe_texture *tex;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
@@ -933,19 +1046,23 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
 | 
			
		||||
		       pScrn->bitsPerPixel,
 | 
			
		||||
		       stride,
 | 
			
		||||
		       handle,
 | 
			
		||||
		       &ms->fb_id);
 | 
			
		||||
		       &fb_id);
 | 
			
		||||
    if (ret) {
 | 
			
		||||
	debug_printf("%s: failed to create framebuffer (%i, %s)",
 | 
			
		||||
	debug_printf("%s: failed to create framebuffer (%i, %s)\n",
 | 
			
		||||
		     __func__, ret, strerror(-ret));
 | 
			
		||||
	goto err_destroy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!drv_destroy_front_buffer_ga3d(pScrn))
 | 
			
		||||
	FatalError("%s: failed to take down old framebuffer\n", __func__);
 | 
			
		||||
 | 
			
		||||
    pScrn->frameX0 = 0;
 | 
			
		||||
    pScrn->frameY0 = 0;
 | 
			
		||||
    drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 | 
			
		||||
 | 
			
		||||
    pipe_texture_reference(&ms->root_texture, tex);
 | 
			
		||||
    pipe_texture_reference(&tex, NULL);
 | 
			
		||||
    ms->fb_id = fb_id;
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -993,6 +1110,11 @@ drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
 | 
			
		||||
    if (!ms->root_bo)
 | 
			
		||||
	return TRUE;
 | 
			
		||||
 | 
			
		||||
    if (ms->fb_id != -1) {
 | 
			
		||||
	drmModeRmFB(ms->fd, ms->fb_id);
 | 
			
		||||
	ms->fb_id = -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    kms_bo_unmap(ms->root_bo);
 | 
			
		||||
    kms_bo_destroy(&ms->root_bo);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
@@ -1005,10 +1127,15 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
 | 
			
		||||
    unsigned handle, stride;
 | 
			
		||||
    struct kms_bo *bo;
 | 
			
		||||
    unsigned attr[8];
 | 
			
		||||
    unsigned fb_id;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    attr[0] = KMS_BO_TYPE;
 | 
			
		||||
#ifdef KMS_BO_TYPE_SCANOUT_X8R8G8B8
 | 
			
		||||
    attr[1] = KMS_BO_TYPE_SCANOUT_X8R8G8B8;
 | 
			
		||||
#else
 | 
			
		||||
    attr[1] = KMS_BO_TYPE_SCANOUT;
 | 
			
		||||
#endif
 | 
			
		||||
    attr[2] = KMS_WIDTH;
 | 
			
		||||
    attr[3] = pScrn->virtualX;
 | 
			
		||||
    attr[4] = KMS_HEIGHT;
 | 
			
		||||
@@ -1031,17 +1158,21 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
 | 
			
		||||
		       pScrn->bitsPerPixel,
 | 
			
		||||
		       stride,
 | 
			
		||||
		       handle,
 | 
			
		||||
		       &ms->fb_id);
 | 
			
		||||
		       &fb_id);
 | 
			
		||||
    if (ret) {
 | 
			
		||||
	debug_printf("%s: failed to create framebuffer (%i, %s)",
 | 
			
		||||
		     __func__, ret, strerror(-ret));
 | 
			
		||||
	goto err_destroy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!drv_destroy_front_buffer_kms(pScrn))
 | 
			
		||||
	FatalError("%s: could not takedown old bo", __func__);
 | 
			
		||||
 | 
			
		||||
    pScrn->frameX0 = 0;
 | 
			
		||||
    pScrn->frameY0 = 0;
 | 
			
		||||
    drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 | 
			
		||||
    ms->root_bo = bo;
 | 
			
		||||
    ms->fb_id = fb_id;
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -1109,4 +1240,14 @@ static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn)
 | 
			
		||||
{
 | 
			
		||||
    return modesettingPTR(pScrn)->cust;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Bool xorg_has_gallium(ScrnInfoPtr pScrn)
 | 
			
		||||
{
 | 
			
		||||
    return modesettingPTR(pScrn)->screen != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* vim: set sw=4 ts=8 sts=4: */
 | 
			
		||||
 
 | 
			
		||||
@@ -1035,6 +1035,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
 | 
			
		||||
   modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
   struct exa_context *exa;
 | 
			
		||||
   ExaDriverPtr pExa;
 | 
			
		||||
   CustomizerPtr cust = ms->cust;
 | 
			
		||||
 | 
			
		||||
   exa = xcalloc(1, sizeof(struct exa_context));
 | 
			
		||||
   if (!exa)
 | 
			
		||||
@@ -1093,6 +1094,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
 | 
			
		||||
   exa->pipe = ms->api->create_context(ms->api, exa->scrn);
 | 
			
		||||
   /* Share context with DRI */
 | 
			
		||||
   ms->ctx = exa->pipe;
 | 
			
		||||
   if (cust && cust->winsys_context_throttle)
 | 
			
		||||
       cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
 | 
			
		||||
 | 
			
		||||
   exa->renderer = renderer_create(exa->pipe);
 | 
			
		||||
   exa->accel = accel;
 | 
			
		||||
 
 | 
			
		||||
@@ -586,7 +586,7 @@ void renderer_copy_pixmap(struct xorg_renderer *r,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void renderer_draw_yuv(struct xorg_renderer *r,
 | 
			
		||||
                       int src_x, int src_y, int src_w, int src_h,
 | 
			
		||||
                       float src_x, float src_y, float src_w, float src_h,
 | 
			
		||||
                       int dst_x, int dst_y, int dst_w, int dst_h,
 | 
			
		||||
                       struct pipe_texture **textures)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ void renderer_set_constants(struct xorg_renderer *r,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void renderer_draw_yuv(struct xorg_renderer *r,
 | 
			
		||||
                       int src_x, int src_y, int src_w, int src_h,
 | 
			
		||||
                       float src_x, float src_y, float src_w, float src_h,
 | 
			
		||||
                       int dst_x, int dst_y, int dst_w, int dst_h,
 | 
			
		||||
                       struct pipe_texture **textures);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -65,6 +65,24 @@ typedef struct
 | 
			
		||||
 | 
			
		||||
#define XORG_NR_FENCES 3
 | 
			
		||||
 | 
			
		||||
enum xorg_throttling_reason {
 | 
			
		||||
    THROTTLE_RENDER,
 | 
			
		||||
    THROTTLE_SWAP
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _CustomizerRec
 | 
			
		||||
{
 | 
			
		||||
    Bool dirty_throttling;
 | 
			
		||||
    Bool swap_throttling;
 | 
			
		||||
    Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
 | 
			
		||||
    Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
 | 
			
		||||
    Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
 | 
			
		||||
    Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
 | 
			
		||||
    void (*winsys_context_throttle)(struct _CustomizerRec *cust,
 | 
			
		||||
				    struct pipe_context *pipe,
 | 
			
		||||
				    enum xorg_throttling_reason reason);
 | 
			
		||||
} CustomizerRec, *CustomizerPtr;
 | 
			
		||||
 | 
			
		||||
typedef struct _modesettingRec
 | 
			
		||||
{
 | 
			
		||||
    /* drm */
 | 
			
		||||
@@ -80,6 +98,9 @@ typedef struct _modesettingRec
 | 
			
		||||
 | 
			
		||||
    Bool noAccel;
 | 
			
		||||
    Bool SWCursor;
 | 
			
		||||
    CursorPtr cursor;
 | 
			
		||||
    Bool swapThrottling;
 | 
			
		||||
    Bool dirtyThrottling;
 | 
			
		||||
    CloseScreenProcPtr CloseScreen;
 | 
			
		||||
 | 
			
		||||
    /* Broken-out options. */
 | 
			
		||||
@@ -115,12 +136,7 @@ typedef struct _modesettingRec
 | 
			
		||||
    Bool accelerate_2d;
 | 
			
		||||
    Bool debug_fallback;
 | 
			
		||||
 | 
			
		||||
    /* winsys hocks */
 | 
			
		||||
    Bool (*winsys_screen_init)(ScrnInfoPtr pScr);
 | 
			
		||||
    Bool (*winsys_screen_close)(ScrnInfoPtr pScr);
 | 
			
		||||
    Bool (*winsys_enter_vt)(ScrnInfoPtr pScr);
 | 
			
		||||
    Bool (*winsys_leave_vt)(ScrnInfoPtr pScr);
 | 
			
		||||
    void *winsys_priv;
 | 
			
		||||
    CustomizerPtr cust;
 | 
			
		||||
 | 
			
		||||
#ifdef DRM_MODE_FEATURE_DIRTYFB
 | 
			
		||||
    DamagePtr damage;
 | 
			
		||||
@@ -129,6 +145,9 @@ typedef struct _modesettingRec
 | 
			
		||||
 | 
			
		||||
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
 | 
			
		||||
 | 
			
		||||
CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn);
 | 
			
		||||
 | 
			
		||||
Bool xorg_has_gallium(ScrnInfoPtr pScrn);
 | 
			
		||||
 | 
			
		||||
/***********************************************************************
 | 
			
		||||
 * xorg_exa.c
 | 
			
		||||
 
 | 
			
		||||
@@ -384,11 +384,14 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
draw_yuv(struct xorg_xv_port_priv *port,
 | 
			
		||||
         int src_x, int src_y, int src_w, int src_h,
 | 
			
		||||
         float src_x, float src_y, float src_w, float src_h,
 | 
			
		||||
         int dst_x, int dst_y, int dst_w, int dst_h)
 | 
			
		||||
{
 | 
			
		||||
   struct pipe_texture **textures = port->yuv[port->current_set];
 | 
			
		||||
 | 
			
		||||
   /*debug_printf("  draw_yuv([%d, %d, %d ,%d], [%d, %d, %d, %d])\n",
 | 
			
		||||
                src_x, src_y, src_w, src_h,
 | 
			
		||||
                dst_x, dst_y, dst_w, dst_h);*/
 | 
			
		||||
   renderer_draw_yuv(port->r,
 | 
			
		||||
                     src_x, src_y, src_w, src_h,
 | 
			
		||||
                     dst_x, dst_y, dst_w, dst_h,
 | 
			
		||||
@@ -490,6 +493,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
 | 
			
		||||
   exaMoveInPixmap(pPixmap);
 | 
			
		||||
   dst = exaGetPixmapDriverPrivate(pPixmap);
 | 
			
		||||
 | 
			
		||||
   /*debug_printf("display_video([%d, %d, %d, %d], [%d, %d, %d, %d])\n",
 | 
			
		||||
     src_x, src_y, src_w, src_h, dstX, dstY, dst_w, dst_h);*/
 | 
			
		||||
 | 
			
		||||
   if (dst && !dst->tex) {
 | 
			
		||||
	xorg_exa_set_shared_usage(pPixmap);
 | 
			
		||||
	pScrn->pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
 | 
			
		||||
@@ -527,10 +533,10 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
 | 
			
		||||
      int box_y2 = pbox->y2;
 | 
			
		||||
      float diff_x = (float)src_w / (float)dst_w;
 | 
			
		||||
      float diff_y = (float)src_h / (float)dst_h;
 | 
			
		||||
      int offset_x = box_x1 - dstX + pPixmap->screen_x;
 | 
			
		||||
      int offset_y = box_y1 - dstY + pPixmap->screen_y;
 | 
			
		||||
      int offset_w;
 | 
			
		||||
      int offset_h;
 | 
			
		||||
      float offset_x = box_x1 - dstX + pPixmap->screen_x;
 | 
			
		||||
      float offset_y = box_y1 - dstY + pPixmap->screen_y;
 | 
			
		||||
      float offset_w;
 | 
			
		||||
      float offset_h;
 | 
			
		||||
 | 
			
		||||
      x = box_x1;
 | 
			
		||||
      y = box_y1;
 | 
			
		||||
@@ -540,8 +546,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
 | 
			
		||||
      offset_w = dst_w - w;
 | 
			
		||||
      offset_h = dst_h - h;
 | 
			
		||||
 | 
			
		||||
      draw_yuv(pPriv, src_x + offset_x*diff_x, src_y + offset_y*diff_y,
 | 
			
		||||
               src_w - offset_w*diff_x, src_h - offset_h*diff_x,
 | 
			
		||||
      draw_yuv(pPriv,
 | 
			
		||||
               (float) src_x + offset_x*diff_x, (float) src_y + offset_y*diff_y,
 | 
			
		||||
               (float) src_w - offset_w*diff_x, (float) src_h - offset_h*diff_y,
 | 
			
		||||
               x, y, w, h);
 | 
			
		||||
 | 
			
		||||
      pbox++;
 | 
			
		||||
 
 | 
			
		||||
@@ -103,6 +103,9 @@ struct vmw_svga_winsys_context
 | 
			
		||||
    * referred.
 | 
			
		||||
    */
 | 
			
		||||
   boolean preemptive_flush;
 | 
			
		||||
 | 
			
		||||
   boolean throttle_set;
 | 
			
		||||
   uint32_t throttle_us;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -122,6 +125,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
 | 
			
		||||
   struct pipe_fence_handle *fence = NULL;
 | 
			
		||||
   unsigned i;
 | 
			
		||||
   enum pipe_error ret;
 | 
			
		||||
   uint32_t throttle_us;
 | 
			
		||||
 | 
			
		||||
   ret = pb_validate_validate(vswc->validate);
 | 
			
		||||
   assert(ret == PIPE_OK);
 | 
			
		||||
@@ -140,8 +144,13 @@ vmw_swc_flush(struct svga_winsys_context *swc,
 | 
			
		||||
         *reloc->where = ptr;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      throttle_us = vswc->throttle_set ?
 | 
			
		||||
	 vswc->throttle_us : vswc->vws->default_throttle_us;
 | 
			
		||||
 | 
			
		||||
      if (vswc->command.used)
 | 
			
		||||
         vmw_ioctl_command(vswc->vws,
 | 
			
		||||
			   vswc->base.cid,
 | 
			
		||||
			   throttle_us,
 | 
			
		||||
                           vswc->command.buffer,
 | 
			
		||||
                           vswc->command.used,
 | 
			
		||||
                           &vswc->last_fence);
 | 
			
		||||
@@ -385,3 +394,14 @@ vmw_svga_context_create(struct pipe_screen *screen)
 | 
			
		||||
{
 | 
			
		||||
   return svga_context_create(screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
vmw_svga_context_set_throttling(struct pipe_context *pipe,
 | 
			
		||||
				uint32_t throttle_us)
 | 
			
		||||
{
 | 
			
		||||
   struct svga_winsys_context *swc = svga_winsys_context(pipe);
 | 
			
		||||
   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
 | 
			
		||||
 | 
			
		||||
   vswc->throttle_us = throttle_us;
 | 
			
		||||
   vswc->throttle_set = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -55,5 +55,8 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
 | 
			
		||||
struct pipe_context *
 | 
			
		||||
vmw_svga_context_create(struct pipe_screen *screen);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
vmw_svga_context_set_throttling(struct pipe_context *pipe,
 | 
			
		||||
				uint32_t throttle_us);
 | 
			
		||||
 | 
			
		||||
#endif /* VMW_CONTEXT_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -37,13 +37,16 @@
 | 
			
		||||
 * module.
 | 
			
		||||
 */
 | 
			
		||||
struct vmw_winsys_screen *
 | 
			
		||||
vmw_winsys_create( int fd )
 | 
			
		||||
vmw_winsys_create( int fd, boolean use_old_scanout_flag )
 | 
			
		||||
{
 | 
			
		||||
   struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
 | 
			
		||||
   if (!vws)
 | 
			
		||||
      goto out_no_vws;
 | 
			
		||||
 | 
			
		||||
   vws->ioctl.drm_fd = fd;
 | 
			
		||||
   vws->use_old_scanout_flag = use_old_scanout_flag;
 | 
			
		||||
   debug_printf("%s: use_old_scanout_flag == %s\n", __FUNCTION__,
 | 
			
		||||
		use_old_scanout_flag ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
   if (!vmw_ioctl_init(vws))
 | 
			
		||||
      goto out_no_ioctl;
 | 
			
		||||
@@ -72,3 +75,13 @@ vmw_winsys_destroy(struct vmw_winsys_screen *vws)
 | 
			
		||||
   vmw_ioctl_cleanup(vws);
 | 
			
		||||
   FREE(vws);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
 | 
			
		||||
				 uint32_t throttle_us)
 | 
			
		||||
{
 | 
			
		||||
   struct vmw_winsys_screen  *vws =
 | 
			
		||||
      vmw_winsys_screen(svga_winsys_screen(screen));
 | 
			
		||||
 | 
			
		||||
   vws->default_throttle_us = throttle_us;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,9 @@ struct vmw_winsys_screen
 | 
			
		||||
{
 | 
			
		||||
   struct svga_winsys_screen base;
 | 
			
		||||
 | 
			
		||||
   boolean use_old_scanout_flag;
 | 
			
		||||
   uint32_t default_throttle_us;
 | 
			
		||||
 | 
			
		||||
   struct {
 | 
			
		||||
      volatile uint32_t *fifo_map;
 | 
			
		||||
      uint64_t last_fence;
 | 
			
		||||
@@ -94,9 +97,11 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
vmw_ioctl_command(struct vmw_winsys_screen *vws,
 | 
			
		||||
                       void *commands,
 | 
			
		||||
                       uint32_t size,
 | 
			
		||||
                       uint32_t *fence);
 | 
			
		||||
		  int32_t cid,
 | 
			
		||||
		  uint32_t throttle_us,
 | 
			
		||||
		  void *commands,
 | 
			
		||||
		  uint32_t size,
 | 
			
		||||
		  uint32_t *fence);
 | 
			
		||||
 | 
			
		||||
struct vmw_region *
 | 
			
		||||
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
 | 
			
		||||
@@ -131,8 +136,9 @@ boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
 | 
			
		||||
void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
 | 
			
		||||
void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
 | 
			
		||||
 | 
			
		||||
struct vmw_winsys_screen *vmw_winsys_create(int fd);
 | 
			
		||||
struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag);
 | 
			
		||||
void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
 | 
			
		||||
 | 
			
		||||
void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
 | 
			
		||||
				      uint32_t throttle_us);
 | 
			
		||||
 | 
			
		||||
#endif /* VMW_SCREEN_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -48,8 +48,9 @@ static struct dri1_api_version ddx_required = { 0, 1, 0 };
 | 
			
		||||
static struct dri1_api_version ddx_compat = { 0, 0, 0 };
 | 
			
		||||
static struct dri1_api_version dri_required = { 4, 0, 0 };
 | 
			
		||||
static struct dri1_api_version dri_compat = { 4, 0, 0 };
 | 
			
		||||
static struct dri1_api_version drm_required = { 0, 1, 0 };
 | 
			
		||||
static struct dri1_api_version drm_compat = { 0, 0, 0 };
 | 
			
		||||
static struct dri1_api_version drm_required = { 1, 0, 0 };
 | 
			
		||||
static struct dri1_api_version drm_compat = { 1, 0, 0 };
 | 
			
		||||
static struct dri1_api_version drm_scanout = { 0, 9, 0 };
 | 
			
		||||
 | 
			
		||||
static boolean
 | 
			
		||||
vmw_dri1_check_version(const struct dri1_api_version *cur,
 | 
			
		||||
@@ -84,6 +85,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
 | 
			
		||||
   struct vmw_winsys_screen *vws;
 | 
			
		||||
   struct pipe_screen *screen;
 | 
			
		||||
   struct dri1_create_screen_arg *dri1;
 | 
			
		||||
   boolean use_old_scanout_flag = FALSE;
 | 
			
		||||
 | 
			
		||||
   if (!arg || arg->mode == DRM_CREATE_NORMAL) {
 | 
			
		||||
      struct dri1_api_version drm_ver;
 | 
			
		||||
@@ -95,11 +97,16 @@ vmw_drm_create_screen(struct drm_api *drm_api,
 | 
			
		||||
 | 
			
		||||
      drm_ver.major = ver->version_major;
 | 
			
		||||
      drm_ver.minor = ver->version_minor;
 | 
			
		||||
      drm_ver.patch_level = 0; /* ??? */
 | 
			
		||||
 | 
			
		||||
      drmFreeVersion(ver);
 | 
			
		||||
      if (!vmw_dri1_check_version(&drm_ver, &drm_required,
 | 
			
		||||
				  &drm_compat, "vmwgfx drm driver"))
 | 
			
		||||
	 return NULL;
 | 
			
		||||
 | 
			
		||||
      if (!vmw_dri1_check_version(&drm_ver, &drm_scanout,
 | 
			
		||||
				  &drm_compat, "use old scanout field (not a error)"))
 | 
			
		||||
         use_old_scanout_flag = TRUE;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (arg != NULL) {
 | 
			
		||||
@@ -117,6 +124,9 @@ vmw_drm_create_screen(struct drm_api *drm_api,
 | 
			
		||||
	 if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required,
 | 
			
		||||
				     &drm_compat, "vmwgfx drm driver"))
 | 
			
		||||
	    return NULL;
 | 
			
		||||
	 if (!vmw_dri1_check_version(&dri1->drm_version, &drm_scanout,
 | 
			
		||||
				     &drm_compat, "use old scanout field (not a error)"))
 | 
			
		||||
	    use_old_scanout_flag = TRUE;
 | 
			
		||||
	 dri1->api = &dri1_api_hooks;
 | 
			
		||||
	 break;
 | 
			
		||||
      default:
 | 
			
		||||
@@ -124,7 +134,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   vws = vmw_winsys_create( fd );
 | 
			
		||||
   vws = vmw_winsys_create( fd, use_old_scanout_flag );
 | 
			
		||||
   if (!vws)
 | 
			
		||||
      goto out_no_vws;
 | 
			
		||||
 | 
			
		||||
@@ -228,7 +238,7 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
 | 
			
		||||
		   cmd.rect.y,
 | 
			
		||||
		   cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy);
 | 
			
		||||
 | 
			
		||||
      vmw_ioctl_command(vws, &cmd, sizeof cmd.header + cmd.header.size,
 | 
			
		||||
      vmw_ioctl_command(vws, -1, 0, &cmd, sizeof cmd.header + cmd.header.size,
 | 
			
		||||
                        &fence_seq);
 | 
			
		||||
      visible = TRUE;
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,12 @@ struct vmw_region
 | 
			
		||||
   uint32_t size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* XXX: This isn't a real hardware flag, but just a hack for kernel to
 | 
			
		||||
 * know about primary surfaces. In newer versions of the kernel
 | 
			
		||||
 * interface the driver uses a special field.
 | 
			
		||||
 */
 | 
			
		||||
#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
vmw_check_last_cmd(struct vmw_winsys_screen *vws)
 | 
			
		||||
{
 | 
			
		||||
@@ -169,7 +175,17 @@ vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
 | 
			
		||||
   vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
 | 
			
		||||
 | 
			
		||||
   memset(&s_arg, 0, sizeof(s_arg));
 | 
			
		||||
   req->flags = (uint32_t) flags;
 | 
			
		||||
   if (vws->use_old_scanout_flag &&
 | 
			
		||||
       (flags & SVGA3D_SURFACE_HINT_SCANOUT)) {
 | 
			
		||||
      req->flags = (uint32_t) flags;
 | 
			
		||||
      req->scanout = false;
 | 
			
		||||
   } else if (flags & SVGA3D_SURFACE_HINT_SCANOUT) {
 | 
			
		||||
      req->flags = (uint32_t) (flags & ~SVGA3D_SURFACE_HINT_SCANOUT);
 | 
			
		||||
      req->scanout = true;
 | 
			
		||||
   } else {
 | 
			
		||||
      req->flags = (uint32_t) flags;
 | 
			
		||||
      req->scanout = false;
 | 
			
		||||
   }
 | 
			
		||||
   req->format = (uint32_t) format;
 | 
			
		||||
   req->shareable = 1;
 | 
			
		||||
 | 
			
		||||
@@ -225,8 +241,9 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
 | 
			
		||||
		       uint32_t * pfence)
 | 
			
		||||
vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
 | 
			
		||||
		  uint32_t throttle_us, void *commands, uint32_t size,
 | 
			
		||||
		  uint32_t *pfence)
 | 
			
		||||
{
 | 
			
		||||
   struct drm_vmw_execbuf_arg arg;
 | 
			
		||||
   struct drm_vmw_fence_rep rep;
 | 
			
		||||
@@ -259,6 +276,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
 | 
			
		||||
   arg.fence_rep = (unsigned long)&rep;
 | 
			
		||||
   arg.commands = (unsigned long)commands;
 | 
			
		||||
   arg.command_size = size;
 | 
			
		||||
   arg.throttle_us = throttle_us;
 | 
			
		||||
 | 
			
		||||
   do {
 | 
			
		||||
       ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,8 @@
 | 
			
		||||
#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
 | 
			
		||||
#define DRM_VMW_PARAM_3D               2
 | 
			
		||||
#define DRM_VMW_PARAM_FIFO_OFFSET      3
 | 
			
		||||
 | 
			
		||||
#define DRM_VMW_PARAM_HW_CAPS          4
 | 
			
		||||
#define DRM_VMW_PARAM_FIFO_CAPS        5
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * struct drm_vmw_getparam_arg
 | 
			
		||||
@@ -85,49 +86,6 @@ struct drm_vmw_getparam_arg {
 | 
			
		||||
	uint32_t pad64;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*************************************************************************/
 | 
			
		||||
/**
 | 
			
		||||
 * DRM_VMW_EXTENSION - Query device extensions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * struct drm_vmw_extension_rep
 | 
			
		||||
 *
 | 
			
		||||
 * @exists: The queried extension exists.
 | 
			
		||||
 * @driver_ioctl_offset: Ioctl number of the first ioctl in the extension.
 | 
			
		||||
 * @driver_sarea_offset: Offset to any space in the DRI SAREA
 | 
			
		||||
 * used by the extension.
 | 
			
		||||
 * @major: Major version number of the extension.
 | 
			
		||||
 * @minor: Minor version number of the extension.
 | 
			
		||||
 * @pl: Patch level version number of the extension.
 | 
			
		||||
 *
 | 
			
		||||
 * Output argument to the DRM_VMW_EXTENSION Ioctl.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct drm_vmw_extension_rep {
 | 
			
		||||
	int32_t exists;
 | 
			
		||||
	uint32_t driver_ioctl_offset;
 | 
			
		||||
	uint32_t driver_sarea_offset;
 | 
			
		||||
	uint32_t major;
 | 
			
		||||
	uint32_t minor;
 | 
			
		||||
	uint32_t pl;
 | 
			
		||||
	uint32_t pad64;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * union drm_vmw_extension_arg
 | 
			
		||||
 *
 | 
			
		||||
 * @extension - Ascii name of the extension to be queried. //In
 | 
			
		||||
 * @rep - Reply as defined above. //Out
 | 
			
		||||
 *
 | 
			
		||||
 * Argument to the DRM_VMW_EXTENSION Ioctl.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
union drm_vmw_extension_arg {
 | 
			
		||||
	char extension[DRM_VMW_EXT_NAME_LEN];
 | 
			
		||||
	struct drm_vmw_extension_rep rep;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*************************************************************************/
 | 
			
		||||
/**
 | 
			
		||||
 * DRM_VMW_CREATE_CONTEXT - Create a host context.
 | 
			
		||||
@@ -181,6 +139,8 @@ struct drm_vmw_context_arg {
 | 
			
		||||
 * The size of the array should equal the total number of mipmap levels.
 | 
			
		||||
 * @shareable: Boolean whether other clients (as identified by file descriptors)
 | 
			
		||||
 * may reference this surface.
 | 
			
		||||
 * @scanout: Boolean whether the surface is intended to be used as a
 | 
			
		||||
 * scanout.
 | 
			
		||||
 *
 | 
			
		||||
 * Input data to the DRM_VMW_CREATE_SURFACE Ioctl.
 | 
			
		||||
 * Output data from the DRM_VMW_REF_SURFACE Ioctl.
 | 
			
		||||
@@ -192,7 +152,7 @@ struct drm_vmw_surface_create_req {
 | 
			
		||||
	uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
 | 
			
		||||
	uint64_t size_addr;
 | 
			
		||||
	int32_t shareable;
 | 
			
		||||
	uint32_t pad64;
 | 
			
		||||
	int32_t scanout;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -295,17 +255,28 @@ union drm_vmw_surface_reference_arg {
 | 
			
		||||
 *
 | 
			
		||||
 * @commands: User-space address of a command buffer cast to an uint64_t.
 | 
			
		||||
 * @command-size: Size in bytes of the command buffer.
 | 
			
		||||
 * @throttle-us: Sleep until software is less than @throttle_us
 | 
			
		||||
 * microseconds ahead of hardware. The driver may round this value
 | 
			
		||||
 * to the nearest kernel tick.
 | 
			
		||||
 * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an
 | 
			
		||||
 * uint64_t.
 | 
			
		||||
 * @version: Allows expanding the execbuf ioctl parameters without breaking
 | 
			
		||||
 * backwards compatibility, since user-space will always tell the kernel
 | 
			
		||||
 * which version it uses.
 | 
			
		||||
 * @flags: Execbuf flags. None currently.
 | 
			
		||||
 *
 | 
			
		||||
 * Argument to the DRM_VMW_EXECBUF Ioctl.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define DRM_VMW_EXECBUF_VERSION 0
 | 
			
		||||
 | 
			
		||||
struct drm_vmw_execbuf_arg {
 | 
			
		||||
	uint64_t commands;
 | 
			
		||||
	uint32_t command_size;
 | 
			
		||||
	uint32_t pad64;
 | 
			
		||||
	uint32_t throttle_us;
 | 
			
		||||
	uint64_t fence_rep;
 | 
			
		||||
	 uint32_t version;
 | 
			
		||||
	 uint32_t flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,11 @@
 | 
			
		||||
 | 
			
		||||
struct vmw_dma_buffer;
 | 
			
		||||
 | 
			
		||||
struct vmw_driver
 | 
			
		||||
struct vmw_customizer
 | 
			
		||||
{
 | 
			
		||||
    CustomizerRec base;
 | 
			
		||||
    ScrnInfoPtr pScrn;
 | 
			
		||||
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    void *cursor_priv;
 | 
			
		||||
@@ -50,11 +53,10 @@ struct vmw_driver
 | 
			
		||||
    void *video_priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static INLINE struct vmw_driver *
 | 
			
		||||
vmw_driver(ScrnInfoPtr pScrn)
 | 
			
		||||
static INLINE struct vmw_customizer *
 | 
			
		||||
vmw_customizer(CustomizerPtr cust)
 | 
			
		||||
{
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    return ms ? (struct vmw_driver *)ms->winsys_priv : NULL;
 | 
			
		||||
    return cust ? (struct vmw_customizer *) cust : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -62,40 +64,40 @@ vmw_driver(ScrnInfoPtr pScrn)
 | 
			
		||||
 * vmw_video.c
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Bool vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
 | 
			
		||||
Bool vmw_video_init(struct vmw_customizer *vmw);
 | 
			
		||||
 | 
			
		||||
Bool vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
 | 
			
		||||
Bool vmw_video_close(struct vmw_customizer *vmw);
 | 
			
		||||
 | 
			
		||||
void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
 | 
			
		||||
void vmw_video_stop_all(struct vmw_customizer *vmw);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***********************************************************************
 | 
			
		||||
 * vmw_ioctl.c
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot);
 | 
			
		||||
int vmw_ioctl_cursor_bypass(struct vmw_customizer *vmw, int xhot, int yhot);
 | 
			
		||||
 | 
			
		||||
struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_driver *vmw,
 | 
			
		||||
struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_customizer *vmw,
 | 
			
		||||
						uint32_t size,
 | 
			
		||||
						unsigned *handle);
 | 
			
		||||
 | 
			
		||||
void * vmw_ioctl_buffer_map(struct vmw_driver *vmw,
 | 
			
		||||
void * vmw_ioctl_buffer_map(struct vmw_customizer *vmw,
 | 
			
		||||
			    struct vmw_dma_buffer *buf);
 | 
			
		||||
 | 
			
		||||
void vmw_ioctl_buffer_unmap(struct vmw_driver *vmw,
 | 
			
		||||
void vmw_ioctl_buffer_unmap(struct vmw_customizer *vmw,
 | 
			
		||||
			    struct vmw_dma_buffer *buf);
 | 
			
		||||
 | 
			
		||||
void vmw_ioctl_buffer_destroy(struct vmw_driver *vmw,
 | 
			
		||||
void vmw_ioctl_buffer_destroy(struct vmw_customizer *vmw,
 | 
			
		||||
			      struct vmw_dma_buffer *buf);
 | 
			
		||||
 | 
			
		||||
int vmw_ioctl_supports_streams(struct vmw_driver *vmw);
 | 
			
		||||
int vmw_ioctl_supports_streams(struct vmw_customizer *vmw);
 | 
			
		||||
 | 
			
		||||
int vmw_ioctl_num_streams(struct vmw_driver *vmw,
 | 
			
		||||
int vmw_ioctl_num_streams(struct vmw_customizer *vmw,
 | 
			
		||||
			  uint32_t *ntot, uint32_t *nfree);
 | 
			
		||||
 | 
			
		||||
int vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id);
 | 
			
		||||
int vmw_ioctl_unref_stream(struct vmw_customizer *vmw, uint32_t stream_id);
 | 
			
		||||
 | 
			
		||||
int vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out);
 | 
			
		||||
int vmw_ioctl_claim_stream(struct vmw_customizer *vmw, uint32_t *out);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ struct vmw_dma_buffer
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out)
 | 
			
		||||
vmw_ioctl_get_param(struct vmw_customizer *vmw, uint32_t param, uint64_t *out)
 | 
			
		||||
{
 | 
			
		||||
    struct drm_vmw_getparam_arg gp_arg;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -75,7 +75,7 @@ vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
vmw_ioctl_supports_streams(struct vmw_driver *vmw)
 | 
			
		||||
vmw_ioctl_supports_streams(struct vmw_customizer *vmw)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t value;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -88,7 +88,7 @@ vmw_ioctl_supports_streams(struct vmw_driver *vmw)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
vmw_ioctl_num_streams(struct vmw_driver *vmw,
 | 
			
		||||
vmw_ioctl_num_streams(struct vmw_customizer *vmw,
 | 
			
		||||
		      uint32_t *ntot, uint32_t *nfree)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t v1, v2;
 | 
			
		||||
@@ -109,7 +109,7 @@ vmw_ioctl_num_streams(struct vmw_driver *vmw,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out)
 | 
			
		||||
vmw_ioctl_claim_stream(struct vmw_customizer *vmw, uint32_t *out)
 | 
			
		||||
{
 | 
			
		||||
    struct drm_vmw_stream_arg s_arg;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -125,7 +125,7 @@ vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id)
 | 
			
		||||
vmw_ioctl_unref_stream(struct vmw_customizer *vmw, uint32_t stream_id)
 | 
			
		||||
{
 | 
			
		||||
    struct drm_vmw_stream_arg s_arg;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -140,7 +140,7 @@ vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
 | 
			
		||||
vmw_ioctl_cursor_bypass(struct vmw_customizer *vmw, int xhot, int yhot)
 | 
			
		||||
{
 | 
			
		||||
    struct drm_vmw_cursor_bypass_arg arg;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -157,7 +157,7 @@ vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct vmw_dma_buffer *
 | 
			
		||||
vmw_ioctl_buffer_create(struct vmw_driver *vmw, uint32_t size, unsigned *handle)
 | 
			
		||||
vmw_ioctl_buffer_create(struct vmw_customizer *vmw, uint32_t size, unsigned *handle)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_dma_buffer *buf;
 | 
			
		||||
    union drm_vmw_alloc_dmabuf_arg arg;
 | 
			
		||||
@@ -198,7 +198,7 @@ err:
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf) 
 | 
			
		||||
vmw_ioctl_buffer_destroy(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
 | 
			
		||||
{ 
 | 
			
		||||
    struct drm_vmw_unref_dmabuf_arg arg; 
 | 
			
		||||
 | 
			
		||||
@@ -215,7 +215,7 @@ vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
void *
 | 
			
		||||
vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
 | 
			
		||||
vmw_ioctl_buffer_map(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
 | 
			
		||||
{
 | 
			
		||||
    void *map;
 | 
			
		||||
 | 
			
		||||
@@ -236,7 +236,7 @@ vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
vmw_ioctl_buffer_unmap(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
 | 
			
		||||
vmw_ioctl_buffer_unmap(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
 | 
			
		||||
{
 | 
			
		||||
    --buf->map_count;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,16 +32,22 @@
 | 
			
		||||
 | 
			
		||||
#include "vmw_hook.h"
 | 
			
		||||
#include "vmw_driver.h"
 | 
			
		||||
#include <pipe/p_context.h>
 | 
			
		||||
 | 
			
		||||
#include "cursorstr.h"
 | 
			
		||||
 | 
			
		||||
void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
 | 
			
		||||
				      uint32_t throttle_us);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* modified version of crtc functions */
 | 
			
		||||
xf86CrtcFuncsRec vmw_screen_crtc_funcs;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_driver *vmw = modesettingPTR(crtc->scrn)->winsys_priv;
 | 
			
		||||
    struct vmw_customizer *vmw =
 | 
			
		||||
	vmw_customizer(xorg_customizer(crtc->scrn));
 | 
			
		||||
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 | 
			
		||||
    xf86CrtcFuncsPtr funcs = vmw->cursor_priv;
 | 
			
		||||
    CursorPtr c = config->cursor;
 | 
			
		||||
@@ -53,8 +59,9 @@ vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
vmw_screen_cursor_init(struct vmw_customizer *vmw)
 | 
			
		||||
{
 | 
			
		||||
    ScrnInfoPtr pScrn = vmw->pScrn;
 | 
			
		||||
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
@@ -70,9 +77,9 @@ vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
vmw_screen_cursor_close(struct vmw_customizer *vmw)
 | 
			
		||||
{
 | 
			
		||||
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 | 
			
		||||
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(vmw->pScrn);
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    vmw_ioctl_cursor_bypass(vmw, 0, 0);
 | 
			
		||||
@@ -81,51 +88,81 @@ vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
	config->crtc[i]->funcs = vmw->cursor_priv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
vmw_screen_init(ScrnInfoPtr pScrn)
 | 
			
		||||
static void
 | 
			
		||||
vmw_context_throttle(CustomizerPtr cust,
 | 
			
		||||
		     struct pipe_context *pipe,
 | 
			
		||||
		     enum xorg_throttling_reason reason)
 | 
			
		||||
{
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    struct vmw_driver *vmw;
 | 
			
		||||
    switch (reason) {
 | 
			
		||||
    case THROTTLE_RENDER:
 | 
			
		||||
	vmw_winsys_screen_set_throttling(pipe->screen, 20000);
 | 
			
		||||
	break;
 | 
			
		||||
    default:
 | 
			
		||||
      vmw_winsys_screen_set_throttling(pipe->screen, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    vmw = xnfcalloc(sizeof(*vmw), 1);
 | 
			
		||||
    if (!vmw)
 | 
			
		||||
	return FALSE;
 | 
			
		||||
static void
 | 
			
		||||
vmw_context_no_throttle(CustomizerPtr cust,
 | 
			
		||||
		     struct pipe_context *pipe,
 | 
			
		||||
		     enum xorg_throttling_reason reason)
 | 
			
		||||
{
 | 
			
		||||
    vmw_winsys_screen_set_throttling(pipe->screen, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
vmw_screen_init(CustomizerPtr cust, int fd)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(cust);
 | 
			
		||||
    drmVersionPtr ver;
 | 
			
		||||
 | 
			
		||||
    vmw->fd = fd;
 | 
			
		||||
    ver = drmGetVersion(fd);
 | 
			
		||||
    if (ver == NULL ||
 | 
			
		||||
	(ver->version_major == 1 && ver->version_minor < 1)) {
 | 
			
		||||
	cust->swap_throttling = TRUE;
 | 
			
		||||
	cust->dirty_throttling = TRUE;
 | 
			
		||||
	cust->winsys_context_throttle = vmw_context_no_throttle;
 | 
			
		||||
    } else {
 | 
			
		||||
	cust->swap_throttling = TRUE;
 | 
			
		||||
	cust->dirty_throttling = FALSE;
 | 
			
		||||
	cust->winsys_context_throttle = vmw_context_throttle;
 | 
			
		||||
	debug_printf("%s: Enabling kernel throttling.\n", __func__);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ver)
 | 
			
		||||
	drmFreeVersion(ver);
 | 
			
		||||
 | 
			
		||||
    vmw_screen_cursor_init(vmw);
 | 
			
		||||
 | 
			
		||||
    vmw->fd = ms->fd;
 | 
			
		||||
    ms->winsys_priv = vmw;
 | 
			
		||||
 | 
			
		||||
    vmw_screen_cursor_init(pScrn, vmw);
 | 
			
		||||
 | 
			
		||||
    /* if gallium is used then we don't need to do anything more. */
 | 
			
		||||
    if (ms->screen)
 | 
			
		||||
    if (xorg_has_gallium(vmw->pScrn))
 | 
			
		||||
	return TRUE;
 | 
			
		||||
 | 
			
		||||
    vmw_video_init(pScrn, vmw);
 | 
			
		||||
    vmw_video_init(vmw);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
vmw_screen_close(ScrnInfoPtr pScrn)
 | 
			
		||||
vmw_screen_close(CustomizerPtr cust)
 | 
			
		||||
{
 | 
			
		||||
    modesettingPtr ms = modesettingPTR(pScrn);
 | 
			
		||||
    struct vmw_driver *vmw = vmw_driver(pScrn);
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(cust);
 | 
			
		||||
 | 
			
		||||
    if (!vmw)
 | 
			
		||||
	return TRUE;
 | 
			
		||||
 | 
			
		||||
    vmw_screen_cursor_close(pScrn, vmw);
 | 
			
		||||
    vmw_screen_cursor_close(vmw);
 | 
			
		||||
 | 
			
		||||
    vmw_video_close(pScrn, vmw);
 | 
			
		||||
 | 
			
		||||
    ms->winsys_priv = NULL;
 | 
			
		||||
    xfree(vmw);
 | 
			
		||||
    vmw_video_close(vmw);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
vmw_screen_enter_vt(ScrnInfoPtr pScrn)
 | 
			
		||||
vmw_screen_enter_vt(CustomizerPtr cust)
 | 
			
		||||
{
 | 
			
		||||
    debug_printf("%s: enter\n", __func__);
 | 
			
		||||
 | 
			
		||||
@@ -133,13 +170,13 @@ vmw_screen_enter_vt(ScrnInfoPtr pScrn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
vmw_screen_leave_vt(ScrnInfoPtr pScrn)
 | 
			
		||||
vmw_screen_leave_vt(CustomizerPtr cust)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_driver *vmw = vmw_driver(pScrn);
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(cust);
 | 
			
		||||
 | 
			
		||||
    debug_printf("%s: enter\n", __func__);
 | 
			
		||||
 | 
			
		||||
    vmw_video_stop_all(pScrn, vmw);
 | 
			
		||||
    vmw_video_stop_all(vmw);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -153,18 +190,27 @@ static Bool (*vmw_screen_pre_init_saved)(ScrnInfoPtr pScrn, int flags) = NULL;
 | 
			
		||||
static Bool
 | 
			
		||||
vmw_screen_pre_init(ScrnInfoPtr pScrn, int flags)
 | 
			
		||||
{
 | 
			
		||||
    modesettingPtr ms;
 | 
			
		||||
    struct vmw_customizer *vmw;
 | 
			
		||||
    CustomizerPtr cust;
 | 
			
		||||
 | 
			
		||||
    vmw = xnfcalloc(1, sizeof(*vmw));
 | 
			
		||||
    if (!vmw)
 | 
			
		||||
	return FALSE;
 | 
			
		||||
 | 
			
		||||
    cust = &vmw->base;
 | 
			
		||||
 | 
			
		||||
    cust->winsys_screen_init = vmw_screen_init;
 | 
			
		||||
    cust->winsys_screen_close = vmw_screen_close;
 | 
			
		||||
    cust->winsys_enter_vt = vmw_screen_enter_vt;
 | 
			
		||||
    cust->winsys_leave_vt = vmw_screen_leave_vt;
 | 
			
		||||
    vmw->pScrn = pScrn;
 | 
			
		||||
 | 
			
		||||
    pScrn->driverPrivate = cust;
 | 
			
		||||
 | 
			
		||||
    pScrn->PreInit = vmw_screen_pre_init_saved;
 | 
			
		||||
    if (!pScrn->PreInit(pScrn, flags))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
 | 
			
		||||
    ms = modesettingPTR(pScrn);
 | 
			
		||||
    ms->winsys_screen_init = vmw_screen_init;
 | 
			
		||||
    ms->winsys_screen_close = vmw_screen_close;
 | 
			
		||||
    ms->winsys_enter_vt = vmw_screen_enter_vt;
 | 
			
		||||
    ms->winsys_leave_vt = vmw_screen_leave_vt;
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -226,7 +226,7 @@ static void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion,
 | 
			
		||||
/*
 | 
			
		||||
 * Local functions.
 | 
			
		||||
 */
 | 
			
		||||
static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
 | 
			
		||||
static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw);
 | 
			
		||||
 | 
			
		||||
static int vmw_video_port_init(ScrnInfoPtr pScrn,
 | 
			
		||||
                               struct vmw_video_port *port,
 | 
			
		||||
@@ -243,9 +243,9 @@ static int vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
 | 
			
		||||
                               short height, RegionPtr clipBoxes);
 | 
			
		||||
static void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port);
 | 
			
		||||
 | 
			
		||||
static int vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
 | 
			
		||||
static int vmw_video_buffer_alloc(struct vmw_customizer *vmw, int size,
 | 
			
		||||
                                  struct vmw_video_buffer *out);
 | 
			
		||||
static int vmw_video_buffer_free(struct vmw_driver *vmw,
 | 
			
		||||
static int vmw_video_buffer_free(struct vmw_customizer *vmw,
 | 
			
		||||
                                 struct vmw_video_buffer *out);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -267,8 +267,9 @@ static int vmw_video_buffer_free(struct vmw_driver *vmw,
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
vmw_video_init(struct vmw_customizer *vmw)
 | 
			
		||||
{
 | 
			
		||||
    ScrnInfoPtr pScrn = vmw->pScrn;
 | 
			
		||||
    ScreenPtr pScreen = pScrn->pScreen;
 | 
			
		||||
    XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
 | 
			
		||||
    XF86VideoAdaptorPtr newAdaptor = NULL;
 | 
			
		||||
@@ -345,8 +346,9 @@ vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
vmw_video_close(struct vmw_customizer *vmw)
 | 
			
		||||
{
 | 
			
		||||
    ScrnInfoPtr pScrn = vmw->pScrn;
 | 
			
		||||
    struct vmw_video_private *video;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
@@ -387,8 +389,9 @@ vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
 *-----------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
void vmw_video_stop_all(struct vmw_customizer *vmw)
 | 
			
		||||
{
 | 
			
		||||
    ScrnInfoPtr pScrn = vmw->pScrn;
 | 
			
		||||
    struct vmw_video_private *video = vmw->video_priv;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
@@ -421,7 +424,7 @@ void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static XF86VideoAdaptorPtr
 | 
			
		||||
vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
 | 
			
		||||
vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw)
 | 
			
		||||
{
 | 
			
		||||
    XF86VideoAdaptorPtr adaptor;
 | 
			
		||||
    struct vmw_video_private *video;
 | 
			
		||||
@@ -515,7 +518,7 @@ vmw_video_port_init(ScrnInfoPtr pScrn, struct vmw_video_port *port,
 | 
			
		||||
                    unsigned char *buf, short width,
 | 
			
		||||
                    short height, RegionPtr clipBoxes)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_driver *vmw = vmw_driver(pScrn);
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
 | 
			
		||||
    unsigned short w, h;
 | 
			
		||||
    int i, ret;
 | 
			
		||||
 | 
			
		||||
@@ -583,7 +586,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
 | 
			
		||||
                    unsigned char *buf, short width,
 | 
			
		||||
                    short height, RegionPtr clipBoxes)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_driver *vmw = vmw_driver(pScrn);
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
 | 
			
		||||
    struct drm_vmw_control_stream_arg arg;
 | 
			
		||||
    unsigned short w, h;
 | 
			
		||||
    int size;
 | 
			
		||||
@@ -675,7 +678,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
 | 
			
		||||
static void
 | 
			
		||||
vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_driver *vmw = vmw_driver(pScrn);
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
 | 
			
		||||
    uint32 id, colorKey, flags;
 | 
			
		||||
    Bool isAutoPaintColorkey;
 | 
			
		||||
    int i;
 | 
			
		||||
@@ -721,7 +724,7 @@ vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
 | 
			
		||||
vmw_video_buffer_alloc(struct vmw_customizer *vmw, int size,
 | 
			
		||||
                       struct vmw_video_buffer *out)
 | 
			
		||||
{
 | 
			
		||||
    out->buf = vmw_ioctl_buffer_create(vmw, size, &out->handle);
 | 
			
		||||
@@ -764,7 +767,7 @@ vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
vmw_video_buffer_free(struct vmw_driver *vmw,
 | 
			
		||||
vmw_video_buffer_free(struct vmw_customizer *vmw,
 | 
			
		||||
                      struct vmw_video_buffer *out)
 | 
			
		||||
{
 | 
			
		||||
    if (out->size == 0)
 | 
			
		||||
@@ -814,7 +817,7 @@ vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
 | 
			
		||||
                 Bool sync, RegionPtr clipBoxes, pointer data,
 | 
			
		||||
                 DrawablePtr dst)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_driver *vmw = vmw_driver(pScrn);
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
 | 
			
		||||
    struct vmw_video_port *port = data;
 | 
			
		||||
 | 
			
		||||
    debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__,
 | 
			
		||||
@@ -852,7 +855,7 @@ vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
 | 
			
		||||
static void
 | 
			
		||||
vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
 | 
			
		||||
{
 | 
			
		||||
    struct vmw_driver *vmw = vmw_driver(pScrn);
 | 
			
		||||
    struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
 | 
			
		||||
    struct vmw_video_port *port = data;
 | 
			
		||||
    struct drm_vmw_control_stream_arg arg;
 | 
			
		||||
    int ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -33,12 +33,50 @@
 | 
			
		||||
 | 
			
		||||
#include "vmw_hook.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Defines and modinfo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define VMWGFX_DRIVER_NAME "vmwgfx"
 | 
			
		||||
 | 
			
		||||
#define VMW_STRING_INNER(s) #s
 | 
			
		||||
#define VMW_STRING(str) VMW_STRING_INNER(str)
 | 
			
		||||
 | 
			
		||||
#define VMWGFX_VERSION_MAJOR 11
 | 
			
		||||
#define VMWGFX_VERSION_MINOR 0
 | 
			
		||||
#define VMWGFX_VERSION_PATCH 0
 | 
			
		||||
#define VMWGFX_VERSION_STRING_MAJOR VMW_STRING(VMWGFX_VERSION_MAJOR)
 | 
			
		||||
#define VMWGFX_VERSION_STRING_MINOR VMW_STRING(VMWGFX_VERSION_MINOR)
 | 
			
		||||
#define VMWGFX_VERSION_STRING_PATCH VMW_STRING(VMWGFX_VERSION_PATCH)
 | 
			
		||||
 | 
			
		||||
#define VMWGFX_DRIVER_VERSION \
 | 
			
		||||
   (VMWGFX_VERSION_MAJOR * 65536 + VMWGFX_VERSION_MINOR * 256 + VMWGFX_VERSION_PATCH)
 | 
			
		||||
#define VMWGFX_DRIVER_VERSION_STRING \
 | 
			
		||||
    VMWGFX_VERSION_STRING_MAJOR "." VMWGFX_VERSION_STRING_MINOR \
 | 
			
		||||
    "." VMWGFX_VERSION_STRING_PATCH
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Standard four digit version string expected by VMware Tools installer.
 | 
			
		||||
 * As the driver's version is only  {major, minor, patchlevel}, simply append an
 | 
			
		||||
 * extra zero for the fourth digit.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
_X_EXPORT const char vmwgfx_drv_modinfo[] __attribute__((section(".modinfo"),unused)) =
 | 
			
		||||
    "version=" VMWGFX_DRIVER_VERSION_STRING ".0";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void vmw_xorg_identify(int flags);
 | 
			
		||||
_X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver,
 | 
			
		||||
				  int entity_num,
 | 
			
		||||
				  struct pci_device *device,
 | 
			
		||||
				  intptr_t match_data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Tables
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static const struct pci_id_match vmw_xorg_device_match[] = {
 | 
			
		||||
    {0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
 | 
			
		||||
    {0, 0, 0, 0, 0, 0, 0},
 | 
			
		||||
@@ -55,12 +93,12 @@ static PciChipsets vmw_xorg_pci_devices[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static XF86ModuleVersionInfo vmw_xorg_version = {
 | 
			
		||||
    "vmwgfx",
 | 
			
		||||
    VMWGFX_DRIVER_NAME,
 | 
			
		||||
    MODULEVENDORSTRING,
 | 
			
		||||
    MODINFOSTRING1,
 | 
			
		||||
    MODINFOSTRING2,
 | 
			
		||||
    XORG_VERSION_CURRENT,
 | 
			
		||||
    0, 1, 0, /* major, minor, patch */
 | 
			
		||||
    VMWGFX_VERSION_MAJOR, VMWGFX_VERSION_MINOR, VMWGFX_VERSION_PATCH,
 | 
			
		||||
    ABI_CLASS_VIDEODRV,
 | 
			
		||||
    ABI_VIDEODRV_VERSION,
 | 
			
		||||
    MOD_CLASS_VIDEODRV,
 | 
			
		||||
@@ -73,7 +111,7 @@ static XF86ModuleVersionInfo vmw_xorg_version = {
 | 
			
		||||
 | 
			
		||||
_X_EXPORT DriverRec vmwgfx = {
 | 
			
		||||
    1,
 | 
			
		||||
    "vmwgfx",
 | 
			
		||||
    VMWGFX_DRIVER_NAME,
 | 
			
		||||
    vmw_xorg_identify,
 | 
			
		||||
    NULL,
 | 
			
		||||
    xorg_tracker_available_options,
 | 
			
		||||
@@ -92,6 +130,7 @@ _X_EXPORT XF86ModuleData vmwgfxModuleData = {
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Xorg driver functions
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -267,13 +267,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
 | 
			
		||||
{
 | 
			
		||||
   switch (fdwReason) {
 | 
			
		||||
   case DLL_PROCESS_ATTACH:
 | 
			
		||||
      if (!stw_init(&stw_winsys)) {
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      }
 | 
			
		||||
      return stw_init_thread();
 | 
			
		||||
      stw_init(&stw_winsys);
 | 
			
		||||
      stw_init_thread();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
   case DLL_THREAD_ATTACH:
 | 
			
		||||
      return stw_init_thread();
 | 
			
		||||
      stw_init_thread();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
   case DLL_THREAD_DETACH:
 | 
			
		||||
      stw_cleanup_thread();
 | 
			
		||||
 
 | 
			
		||||
@@ -317,13 +317,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
 | 
			
		||||
{
 | 
			
		||||
   switch (fdwReason) {
 | 
			
		||||
   case DLL_PROCESS_ATTACH:
 | 
			
		||||
      if (!stw_init(&stw_winsys)) {
 | 
			
		||||
         return FALSE;
 | 
			
		||||
      }
 | 
			
		||||
      return stw_init_thread();
 | 
			
		||||
      stw_init(&stw_winsys);
 | 
			
		||||
      stw_init_thread();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
   case DLL_THREAD_ATTACH:
 | 
			
		||||
      return stw_init_thread();
 | 
			
		||||
      stw_init_thread();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
   case DLL_THREAD_DETACH:
 | 
			
		||||
      stw_cleanup_thread();
 | 
			
		||||
 
 | 
			
		||||
@@ -437,8 +437,10 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
 | 
			
		||||
   psc->ext_list_first_time = GL_TRUE;
 | 
			
		||||
 | 
			
		||||
   if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
 | 
			
		||||
                    &driverName, &deviceName))
 | 
			
		||||
                    &driverName, &deviceName)) {
 | 
			
		||||
      XFree(psp);
 | 
			
		||||
      return NULL;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   psc->driver = driOpenDriver(driverName);
 | 
			
		||||
   if (psc->driver == NULL) {
 | 
			
		||||
@@ -467,17 +469,17 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
 | 
			
		||||
   psc->fd = open(deviceName, O_RDWR);
 | 
			
		||||
   if (psc->fd < 0) {
 | 
			
		||||
      ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
 | 
			
		||||
      return NULL;
 | 
			
		||||
      goto handle_error;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (drmGetMagic(psc->fd, &magic)) {
 | 
			
		||||
      ErrorMessageF("failed to get magic\n");
 | 
			
		||||
      return NULL;
 | 
			
		||||
      goto handle_error;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
 | 
			
		||||
      ErrorMessageF("failed to authenticate magic %d\n", magic);
 | 
			
		||||
      return NULL;
 | 
			
		||||
      goto handle_error;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   /* If the server does not support the protocol for
 | 
			
		||||
@@ -491,7 +493,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
 | 
			
		||||
 | 
			
		||||
   if (psc->__driScreen == NULL) {
 | 
			
		||||
      ErrorMessageF("failed to create dri screen\n");
 | 
			
		||||
      return NULL;
 | 
			
		||||
      goto handle_error;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   driBindExtensions(psc, 1);
 | 
			
		||||
@@ -521,6 +523,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
 | 
			
		||||
 handle_error:
 | 
			
		||||
   Xfree(driverName);
 | 
			
		||||
   Xfree(deviceName);
 | 
			
		||||
   XFree(psp);
 | 
			
		||||
 | 
			
		||||
   /* FIXME: clean up here */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -385,7 +385,8 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig,
 | 
			
		||||
   req->glxwindow = (GLXWindow) XAllocID(dpy);
 | 
			
		||||
   req->numAttribs = (CARD32) i;
 | 
			
		||||
 | 
			
		||||
   memcpy(data, attrib_list, 8 * i);
 | 
			
		||||
   if (attrib_list)
 | 
			
		||||
      memcpy(data, attrib_list, 8 * i);
 | 
			
		||||
 | 
			
		||||
   UnlockDisplay(dpy);
 | 
			
		||||
   SyncHandle();
 | 
			
		||||
 
 | 
			
		||||
@@ -291,7 +291,8 @@ __glXInitVertexArrayState(__GLXcontext * gc)
 | 
			
		||||
 | 
			
		||||
   arrays->stack_index = 0;
 | 
			
		||||
   arrays->stack = malloc(sizeof(struct array_stack_state)
 | 
			
		||||
                          * arrays->num_arrays);
 | 
			
		||||
                          * arrays->num_arrays
 | 
			
		||||
                          * __GL_CLIENT_ATTRIB_STACK_DEPTH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -60,14 +60,6 @@ driNewRenderbuffer(gl_format format, GLvoid *addr,
 | 
			
		||||
{
 | 
			
		||||
   driRenderbuffer *drb;
 | 
			
		||||
 | 
			
		||||
   assert(format == GL_RGBA ||
 | 
			
		||||
          format == GL_RGB5 ||
 | 
			
		||||
          format == GL_RGBA8 ||
 | 
			
		||||
          format == GL_DEPTH_COMPONENT16 ||
 | 
			
		||||
          format == GL_DEPTH_COMPONENT24 ||
 | 
			
		||||
          format == GL_DEPTH_COMPONENT32 ||
 | 
			
		||||
          format == GL_STENCIL_INDEX8_EXT);
 | 
			
		||||
 | 
			
		||||
   assert(cpp > 0);
 | 
			
		||||
   assert(pitch > 0);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -254,7 +254,7 @@ void intel_flush_prim(struct intel_context *intel)
 | 
			
		||||
      BEGIN_BATCH(5, LOOP_CLIPRECTS);
 | 
			
		||||
      OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
 | 
			
		||||
		I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
 | 
			
		||||
      assert((offset & !S0_VB_OFFSET_MASK) == 0);
 | 
			
		||||
      assert((offset & ~S0_VB_OFFSET_MASK) == 0);
 | 
			
		||||
      OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, offset);
 | 
			
		||||
      OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) |
 | 
			
		||||
		(intel->vertex_size << S1_VERTEX_PITCH_SHIFT));
 | 
			
		||||
@@ -273,7 +273,7 @@ void intel_flush_prim(struct intel_context *intel)
 | 
			
		||||
      OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
 | 
			
		||||
		I1_LOAD_S(0) | I1_LOAD_S(2) | 1);
 | 
			
		||||
      /* S0 */
 | 
			
		||||
      assert((offset & !S0_VB_OFFSET_MASK_830) == 0);
 | 
			
		||||
      assert((offset & ~S0_VB_OFFSET_MASK_830) == 0);
 | 
			
		||||
      OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
 | 
			
		||||
		offset | (intel->vertex_size << S0_VB_PITCH_SHIFT_830) |
 | 
			
		||||
		S0_VB_ENABLE_830);
 | 
			
		||||
 
 | 
			
		||||
@@ -770,7 +770,13 @@ get_constant(struct brw_vs_compile *c,
 | 
			
		||||
   if (c->current_const[argIndex].index != src->Index || relAddr) {
 | 
			
		||||
      struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
 | 
			
		||||
 | 
			
		||||
      c->current_const[argIndex].index = src->Index;
 | 
			
		||||
      /* If using a non-relative-addressed constant, then keep track of it for
 | 
			
		||||
       * later use without reloading.
 | 
			
		||||
       */
 | 
			
		||||
      if (relAddr)
 | 
			
		||||
	 c->current_const[argIndex].index = -1;
 | 
			
		||||
      else
 | 
			
		||||
	 c->current_const[argIndex].index = src->Index;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
      printf("  fetch const[%d] for arg %d into reg %d\n",
 | 
			
		||||
 
 | 
			
		||||
@@ -376,6 +376,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
 | 
			
		||||
      GLint cx, cy, cw, ch;
 | 
			
		||||
      drm_clip_rect_t clear;
 | 
			
		||||
      int i;
 | 
			
		||||
      drm_intel_bo *aper_array[2];
 | 
			
		||||
 | 
			
		||||
      /* Get clear bounds after locking */
 | 
			
		||||
      cx = fb->_Xmin;
 | 
			
		||||
@@ -526,6 +527,15 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
 | 
			
		||||
               assert(x1 < x2);
 | 
			
		||||
               assert(y1 < y2);
 | 
			
		||||
 | 
			
		||||
	       /* do space check before going any further */
 | 
			
		||||
	       aper_array[0] = intel->batch->buf;
 | 
			
		||||
	       aper_array[1] = write_buffer;
 | 
			
		||||
 | 
			
		||||
	       if (drm_intel_bufmgr_check_aperture_space(aper_array,
 | 
			
		||||
							 ARRAY_SIZE(aper_array)) != 0) {
 | 
			
		||||
		  intel_batchbuffer_flush(intel->batch);
 | 
			
		||||
	       }
 | 
			
		||||
 | 
			
		||||
               BEGIN_BATCH(6, REFERENCES_CLIPRECTS);
 | 
			
		||||
               OUT_BATCH(CMD);
 | 
			
		||||
               OUT_BATCH(BR13);
 | 
			
		||||
 
 | 
			
		||||
@@ -172,6 +172,8 @@ do_blit_readpixels(GLcontext * ctx,
 | 
			
		||||
   struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
 | 
			
		||||
   GLuint dst_offset;
 | 
			
		||||
   GLuint rowLength;
 | 
			
		||||
   drm_intel_bo *dst_buffer;
 | 
			
		||||
   drm_clip_rect_t read_bounds, rect, src_rect;
 | 
			
		||||
 | 
			
		||||
   if (INTEL_DEBUG & DEBUG_PIXEL)
 | 
			
		||||
      _mesa_printf("%s\n", __FUNCTION__);
 | 
			
		||||
@@ -212,58 +214,47 @@ do_blit_readpixels(GLcontext * ctx,
 | 
			
		||||
      return GL_FALSE;
 | 
			
		||||
   }
 | 
			
		||||
   else {
 | 
			
		||||
      rowLength = -rowLength;
 | 
			
		||||
      if (ctx->ReadBuffer->Name == 0)
 | 
			
		||||
	 rowLength = -rowLength;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height,
 | 
			
		||||
					       format, type, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
   GLboolean all = (width * height * src->cpp == dst->Base.Size &&
 | 
			
		||||
		    x == 0 && dst_offset == 0);
 | 
			
		||||
 | 
			
		||||
   /* Although the blits go on the command buffer, need to do this and
 | 
			
		||||
    * fire with lock held to guarentee cliprects are correct.
 | 
			
		||||
    */
 | 
			
		||||
   intelFlush(&intel->ctx);
 | 
			
		||||
   LOCK_HARDWARE(intel);
 | 
			
		||||
   dst_buffer = intel_bufferobj_buffer(intel, dst,
 | 
			
		||||
					       all ? INTEL_WRITE_FULL :
 | 
			
		||||
					       INTEL_WRITE_PART);
 | 
			
		||||
 | 
			
		||||
   if (intel->driReadDrawable->numClipRects) {
 | 
			
		||||
      GLboolean all = (width * height * src->cpp == dst->Base.Size &&
 | 
			
		||||
                       x == 0 && dst_offset == 0);
 | 
			
		||||
   src_rect.x1 = x;
 | 
			
		||||
   if (ctx->ReadBuffer->Name == 0)
 | 
			
		||||
      src_rect.y1 = ctx->ReadBuffer->Height - (y + height);
 | 
			
		||||
   else
 | 
			
		||||
      src_rect.y1 = y;
 | 
			
		||||
   src_rect.x2 = src_rect.x1 + width;
 | 
			
		||||
   src_rect.y2 = src_rect.y1 + height;
 | 
			
		||||
 | 
			
		||||
      dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst,
 | 
			
		||||
						  all ? INTEL_WRITE_FULL :
 | 
			
		||||
						  INTEL_WRITE_PART);
 | 
			
		||||
      __DRIdrawablePrivate *dPriv = intel->driReadDrawable;
 | 
			
		||||
      int nbox = dPriv->numClipRects;
 | 
			
		||||
      drm_clip_rect_t *box = dPriv->pClipRects;
 | 
			
		||||
      drm_clip_rect_t rect;
 | 
			
		||||
      drm_clip_rect_t src_rect;
 | 
			
		||||
      int i;
 | 
			
		||||
   read_bounds.x1 = 0;
 | 
			
		||||
   read_bounds.y1 = 0;
 | 
			
		||||
   read_bounds.x2 = ctx->ReadBuffer->Width;
 | 
			
		||||
   read_bounds.y2 = ctx->ReadBuffer->Height;
 | 
			
		||||
 | 
			
		||||
      src_rect.x1 = dPriv->x + x;
 | 
			
		||||
      src_rect.y1 = dPriv->y + dPriv->h - (y + height);
 | 
			
		||||
      src_rect.x2 = src_rect.x1 + width;
 | 
			
		||||
      src_rect.y2 = src_rect.y1 + height;
 | 
			
		||||
   if (!intel_intersect_cliprects(&rect, &src_rect, &read_bounds))
 | 
			
		||||
      return GL_TRUE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < nbox; i++) {
 | 
			
		||||
         if (!intel_intersect_cliprects(&rect, &src_rect, &box[i]))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
         if (!intelEmitCopyBlit(intel,
 | 
			
		||||
				src->cpp,
 | 
			
		||||
				src->pitch, src->buffer, 0, src->tiling,
 | 
			
		||||
				rowLength, dst_buffer, dst_offset, GL_FALSE,
 | 
			
		||||
				rect.x1,
 | 
			
		||||
				rect.y1,
 | 
			
		||||
				rect.x1 - src_rect.x1,
 | 
			
		||||
				rect.y2 - src_rect.y2,
 | 
			
		||||
				rect.x2 - rect.x1, rect.y2 - rect.y1,
 | 
			
		||||
				GL_COPY)) {
 | 
			
		||||
	    UNLOCK_HARDWARE(intel);
 | 
			
		||||
	    return GL_FALSE;
 | 
			
		||||
	 }
 | 
			
		||||
      }
 | 
			
		||||
   if (!intelEmitCopyBlit(intel,
 | 
			
		||||
			  src->cpp,
 | 
			
		||||
			  src->pitch, src->buffer, 0, src->tiling,
 | 
			
		||||
			  rowLength, dst_buffer, dst_offset, GL_FALSE,
 | 
			
		||||
			  rect.x1,
 | 
			
		||||
			  rect.y1,
 | 
			
		||||
			  rect.x1 - src_rect.x1,
 | 
			
		||||
			  rect.y2 - src_rect.y2,
 | 
			
		||||
			  rect.x2 - rect.x1, rect.y2 - rect.y1,
 | 
			
		||||
			  GL_COPY)) {
 | 
			
		||||
      return GL_FALSE;
 | 
			
		||||
   }
 | 
			
		||||
   UNLOCK_HARDWARE(intel);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user